diff --git a/web-dev backup-2024.03.22/app.py b/web-dev backup-2024.03.22/app.py new file mode 100644 index 0000000..c70eefe --- /dev/null +++ b/web-dev backup-2024.03.22/app.py @@ -0,0 +1,117 @@ +from urllib import request +from flask import Flask, jsonify, render_template, url_for, request, redirect +import json +import datetime +from pymongo import MongoClient +import requests + +CONNECTION_STRING = "mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo" + +db_connection = MongoClient(CONNECTION_STRING) +db_base = db_connection["phone-dev"] +coll = db_base["phone"] +bl = db_base["blacklist"] + +rep = False +# coll_call = db_base["phone"] +# coll_history = db_base["history"] + +app = Flask(__name__) + +internal = {} +external = {} +State = "" +Findlimit = 100 + + +@app.route("/") +def root(): + return redirect("/notanswer") + + +ImportantNumber = ['839122051045'] + + +@app.route("/answer") +def answer(): + call = coll.find({"status": "ANSWERED"}).sort('time', -1).limit(Findlimit) + return render_template("answer.html", call=call) if rep == False else render_template("repair.html") + + +@app.route("/notanswer") +def notanswer(): + call = coll.find({"status": "NOT_ANSWERED"}).sort( + 'time', -1).limit(Findlimit) + return render_template("notanswer.html", call=call) if rep == False else render_template("repair.html") + + +@app.route("/truerecall") +def recallTrue(): + call = coll.find({"status": "RECALL_TRUE"}).sort( + 'time', -1).limit(Findlimit) + return render_template("truerecall.html", call=call) if rep == False else render_template("repair.html") + + +@app.route("/falserecall") +def rcallFalse(): + call = coll.find({"status": "RECALL_FALSE"}).sort( + 'time', -1).limit(Findlimit) + return render_template("falserecall.html", call=call) if rep == False else render_template("repair.html") + + +@app.route("/blacklist") +def blacklist(): + call = bl.find().sort('_id') + return render_template("blacklist.html", call=call) if rep == False else render_template("repair.html") + +# API + + +@app.route("/api/v1/call/set/", methods=["POST"]) +def call_put(): + print(request.form) + if request.form["act"] == "delete": + coll.update_many({"uuid": request.form["uuid"], "status": "RECALL_FALSE"}, { + "$set": {"status": "DELETED"}}) + return redirect("/falserecall") + + +@app.route("/api/v1/blacklist/add/", methods=["POST"]) +def blacklist_put(number): + insdict = {"_id": number, "desc": datetime.datetime.now()} + bl.update_one({"_id": number}, {"$set": insdict}, True) + coll.update_many({"client": number, "status": { + "$in": ["RECALL_TRUE", "RECALL_FALSE", "NOT_ANSWERED"]}}, {"$set": {"status": "IGNORED"}}) + return redirect("/blacklist") + + +@app.route("/api/v1/blacklist/delete/", methods=["POST"]) +def blacklist_delete(number): + bl.delete_many({"_id": number}) + return redirect("/blacklist") + + +@app.route("/api/v1/blacklist/get/") +def blacklist_get(number): + try: + return [i for i in bl.find({"_id": number})][0] + except: + return {} + + +@app.route("/api/v1/sync") +def sync(): + j = [] + for x in coll.find({"status": "NOT_ANSWERED"}): + t_req = "https://callinfo.services.mobilon.ru/api/call/info/1e86a98e026578eb5f6bf8c092c0c4a2/" + \ + x["uuid"] + res: dict = json.loads(requests.get(t_req).content) + + j.append(res) + coll.update_one({"uuid": x["uuid"]}, {"$set": res}) + return j + + +if __name__ == "__main__": + app.debug = True + app.run(host="0.0.0.0", port=6001) diff --git a/web-dev backup-2024.03.22/dockerfile b/web-dev backup-2024.03.22/dockerfile new file mode 100644 index 0000000..d7339d4 --- /dev/null +++ b/web-dev backup-2024.03.22/dockerfile @@ -0,0 +1,16 @@ +FROM alpine + +RUN apk update && apk upgrade && apk add python3 && apk add -U tzdata + +WORKDIR /app + +COPY requirements.txt requirements.txt +RUN python3 -m venv .venv +RUN /app/.venv/bin/pip3 install -r /app/requirements.txt +COPY app.py /app +COPY static /app/static +COPY templates /app/templates + +EXPOSE 5001 + +CMD [".venv/bin/python3", "app.py"] \ No newline at end of file diff --git a/web-dev backup-2024.03.22/requirements.txt b/web-dev backup-2024.03.22/requirements.txt new file mode 100644 index 0000000..bc69331 --- /dev/null +++ b/web-dev backup-2024.03.22/requirements.txt @@ -0,0 +1,11 @@ +click==8.1.3 +dnspython==2.3.0 +Flask==2.2.3 +importlib-metadata==6.2.0 +itsdangerous==2.1.2 +Jinja2==3.1.2 +MarkupSafe==2.1.2 +pymongo==4.3.3 +Werkzeug==2.2.3 +zipp==3.15.0 +requests==2.28.2 diff --git a/web-dev backup-2024.03.22/static/main.css b/web-dev backup-2024.03.22/static/main.css new file mode 100644 index 0000000..0ab7019 --- /dev/null +++ b/web-dev backup-2024.03.22/static/main.css @@ -0,0 +1,51 @@ +table { + width: 100%; + margin-bottom: 20px; + border: 5px solid #fff; + border-top: 5px solid #fff; + border-bottom: 3px solid #fff; + border-collapse: collapse; + outline: 3px solid #ffd300; + font-size: 15px; + background: #fff !important; + font-family: Verdana, Geneva, Tahoma, sans-serif; +} + +table th { + font-weight: bold; + padding: 7px; + background: #ffd300; + border: none; + text-align: left; + font-size: 15px; + border-top: 3px solid #fff; + border-bottom: 3px solid #ffd300; +} + +table td { + padding: 7px; + border: none; + border-top: 3px solid #fff; + border-bottom: 3px solid #fff; + font-size: 15px; +} + +table tbody tr:nth-child(even) { + background: #f8f8f8 !important; +} + +a { + font-size: large; + font-family: Verdana, Geneva, Tahoma, sans-serif; + color: chocolate; + padding-right: 50px; +} + +header { + height: 50px; + vertical-align: middle; +} + +form { + height: 40px; +} \ No newline at end of file diff --git a/web-dev backup-2024.03.22/templates/DeleteCall.html b/web-dev backup-2024.03.22/templates/DeleteCall.html new file mode 100644 index 0000000..760664f --- /dev/null +++ b/web-dev backup-2024.03.22/templates/DeleteCall.html @@ -0,0 +1,22 @@ + + + + + + + + Удаление документа + + + +

Вы действительно хотите удалить номер: {{ id }}?

+ Причина удаления? +
+ + + +
+ + + + \ No newline at end of file diff --git a/web-dev/templates/TestCall.html b/web-dev backup-2024.03.22/templates/TestCall.html similarity index 100% rename from web-dev/templates/TestCall.html rename to web-dev backup-2024.03.22/templates/TestCall.html diff --git a/web-dev/templates/WebCall.html b/web-dev backup-2024.03.22/templates/WebCall.html similarity index 100% rename from web-dev/templates/WebCall.html rename to web-dev backup-2024.03.22/templates/WebCall.html diff --git a/web-dev backup-2024.03.22/templates/answer.html b/web-dev backup-2024.03.22/templates/answer.html new file mode 100644 index 0000000..536663e --- /dev/null +++ b/web-dev backup-2024.03.22/templates/answer.html @@ -0,0 +1,115 @@ + + + + + + + + Принятые вызовы + + + + + +
+ + + + +
+ + + + + + + + + + + + {% for c in call %} + + + {% if c.mkt_phone == "83912051045": %} + + {% else %} + + {% endif %} + + + + + {% endfor %} + +
Номер клиентаДата и времяЗапись разговора
+ {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], + c.client[7:11]) }} + {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}{{ c.time }}
+ + + \ No newline at end of file diff --git a/web-dev backup-2024.03.22/templates/blacklist.html b/web-dev backup-2024.03.22/templates/blacklist.html new file mode 100644 index 0000000..7f3a19b --- /dev/null +++ b/web-dev backup-2024.03.22/templates/blacklist.html @@ -0,0 +1,104 @@ + + + + + + + + Черный список + + + + + +
+ Входящий вызов принят + Входящий вызов не принят + Перезвонили успешно + Перезвонили безуспешно +
+ + + + + + + + + + + + {% for c in call %} + + + + + + {% endfor %} + +
Номер клиентаКомментарийДействие
{{ c._id }}{{ c.desc }} +
+ +
+
+ + + \ No newline at end of file diff --git a/web-dev backup-2024.03.22/templates/falserecall.html b/web-dev backup-2024.03.22/templates/falserecall.html new file mode 100644 index 0000000..d498767 --- /dev/null +++ b/web-dev backup-2024.03.22/templates/falserecall.html @@ -0,0 +1,134 @@ + + + + + + + + Перезвонили безуспешно + + + + + +
+ + + + +
+ + + + + + + + + + + + + + + {% for c in call %} + + {% if c.mkt_phone == "83912051045": %} + + {% else %} + + {% endif %} + + + + + + + + {% endfor %} + +
Номер клиентаКол-во попытокДата и времяПродолжительностьОператорЗаписьДействие
+ {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], + c.client[7:11]) }} + {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}{{ c.count_try }}{{ c.time }}{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}{{ c.operator }} + {% if c.has_record == true: %} + + {% else %} + Отсутствует + {% endif %} + +
+
+ + + +
+
+
+ + + \ No newline at end of file diff --git a/web-dev backup-2024.03.22/templates/notanswer.html b/web-dev backup-2024.03.22/templates/notanswer.html new file mode 100644 index 0000000..0786950 --- /dev/null +++ b/web-dev backup-2024.03.22/templates/notanswer.html @@ -0,0 +1,125 @@ + + + + + + + + + Непринятые + + + + + +
+ + + + +
+
+ + +
+ + + + + + + + + + + + + {% for c in call %} + + {% if c.mkt_phone == "83912051045": %} + + + {% else %} + + {% endif %} + + + + + + {% endfor %} + +
Номер клиентаДата и времяПродолжительностьДействие
+ {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], + c.client[7:11]) }} + {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}{{ c.time }} {{ c.important }}{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }} +
+ +
+
+ + + \ No newline at end of file diff --git a/web-dev backup-2024.03.22/templates/repair.html b/web-dev backup-2024.03.22/templates/repair.html new file mode 100644 index 0000000..8c2648d --- /dev/null +++ b/web-dev backup-2024.03.22/templates/repair.html @@ -0,0 +1,14 @@ + + + + + + + Document + + + +

Ведутся работы, скоро все заработает

+ + + \ No newline at end of file diff --git a/web-dev/templates/test.html b/web-dev backup-2024.03.22/templates/test.html similarity index 100% rename from web-dev/templates/test.html rename to web-dev backup-2024.03.22/templates/test.html diff --git a/web-dev backup-2024.03.22/templates/truerecall.html b/web-dev backup-2024.03.22/templates/truerecall.html new file mode 100644 index 0000000..b91e900 --- /dev/null +++ b/web-dev backup-2024.03.22/templates/truerecall.html @@ -0,0 +1,118 @@ + + + + + + + + Перезвонили успешно + + + + + +
+ + + + +
+ + + + + + + + + + + + + + {% for c in call %} + + {% if c.mkt_phone == "83912051045": %} + + {% else %} + + {% endif %} + + + + + + + {% endfor %} + +
Номер клиентаДата и времяПродолжительностьОператорЗапись разговора
+ {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], + c.client[7:11]) }} + {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}{{ c.time }}{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}{{ c.operator }}
+ + + \ No newline at end of file diff --git a/web-dev/app.py b/web-dev/app.py index 43dd92f..e02dc83 100644 --- a/web-dev/app.py +++ b/web-dev/app.py @@ -3,12 +3,14 @@ from flask import Flask, jsonify, render_template, url_for, request, redirect import json import datetime from pymongo import MongoClient +import requests CONNECTION_STRING = "mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo" db_connection = MongoClient(CONNECTION_STRING) db_base = db_connection["phone-dev"] coll = db_base["phone"] +bl = db_base["blacklist"] rep = False # coll_call = db_base["phone"] @@ -27,8 +29,6 @@ def root(): return redirect("/notanswer") -IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951252791', '83919865589', - '84951183750', '89919237009', '89919241441', '89919863883', '89919505445', '89919398228', '89919500798'] ImportantNumber = ['839122051045'] @@ -58,18 +58,83 @@ def rcallFalse(): 'time', -1).limit(Findlimit) return render_template("falserecall.html", call=call) if rep == False else render_template("repair.html") + +@app.route("/blacklist") +def blacklist(): + call = bl.find().sort('_id') + return render_template("blacklist.html", call=call) if rep == False else render_template("repair.html") + +@app.route("/test") +def ttt(): + res = [] + for p in request.environ: + try: + res.append(p + " = " + request.environ[p]) + except: + pass + # #"
".join(request.environ) + return str(res) + +@app.route("/work/") +def work_uuid(uuid): + coll.update_one({"uuid": uuid}, {"$set": {"status": "INWORK"}}) + call = coll.find({"uuid": uuid}) + return render_template("work.html", call=call) if rep == False else render_template("repair.html") + # API @app.route("/api/v1/call/set/", methods=["POST"]) def call_put(): - print(request.form) + # print(request.form) if request.form["act"] == "delete": - coll.update_one({"uuid": request.form["uuid"]}, { - "$set": {"status": "DELETED"}}) + coll.update_many({"uuid": request.form["uuid"], "status": "RECALL_FALSE"}, { + "$set": {"status": "DELETED"}}) return redirect("/falserecall") +@app.route("/api/v1/work/", methods=["POST"]) +def work(): + dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + coll.update_one({"uuid": request.form["uuid"]}, {"$set": {"status": "RECALL_" + str(request.form["recall"]).upper(), "dt": dt}}) + return redirect("/") + +@app.route("/api/v1/blacklist/add/", methods=["POST"]) +def blacklist_put(number): + insdict = {"_id": number, "desc": datetime.datetime.now()} + bl.update_one({"_id": number}, {"$set": insdict}, True) + coll.update_many({"client": number, "status": { + "$in": ["RECALL_TRUE", "RECALL_FALSE", "NOT_ANSWERED"]}}, {"$set": {"status": "IGNORED"}}) + return redirect("/blacklist") + + +@app.route("/api/v1/blacklist/delete/", methods=["POST"]) +def blacklist_delete(number): + bl.delete_many({"_id": number}) + return redirect("/blacklist") + + +@app.route("/api/v1/blacklist/get/") +def blacklist_get(number): + try: + return [i for i in bl.find({"_id": number})][0] + except: + return {} + + +@app.route("/api/v1/sync") +def sync(): + j = [] + for x in coll.find({"status": "NOT_ANSWERED"}): + t_req = "https://callinfo.services.mobilon.ru/api/call/info/1e86a98e026578eb5f6bf8c092c0c4a2/" + \ + x["uuid"] + res: dict = json.loads(requests.get(t_req).content) + + j.append(res) + coll.update_one({"uuid": x["uuid"]}, {"$set": res}) + return j + + if __name__ == "__main__": app.debug = True app.run(host="0.0.0.0", port=6001) diff --git a/web-dev/requirements.txt b/web-dev/requirements.txt index 65581cf..bc69331 100644 --- a/web-dev/requirements.txt +++ b/web-dev/requirements.txt @@ -8,3 +8,4 @@ MarkupSafe==2.1.2 pymongo==4.3.3 Werkzeug==2.2.3 zipp==3.15.0 +requests==2.28.2 diff --git a/web-dev/templates/answer.html b/web-dev/templates/answer.html index 32ec926..536663e 100644 --- a/web-dev/templates/answer.html +++ b/web-dev/templates/answer.html @@ -48,7 +48,7 @@ a { font-size: large; font-family: Verdana, Geneva, Tahoma, sans-serif; - color: chocolate; + color: #7A1E99; padding-right: 50px; } @@ -60,14 +60,20 @@ form { height: 40px; } + + .inl {display: inline;} + .inl-active { + display: inline; + background-color: #FFD300; + } + Черный список + + + + + + + + + + + + + + + + + {% for c in call %} + + + + + + {% endfor %} + +
Номер клиентаКомментарийДействие
{{ c._id }}{{ c.desc }} +
+ +
+
+ + + \ No newline at end of file diff --git a/web-dev/templates/falserecall.html b/web-dev/templates/falserecall.html index 190b78a..d36b84a 100644 --- a/web-dev/templates/falserecall.html +++ b/web-dev/templates/falserecall.html @@ -48,7 +48,7 @@ a { font-size: large; font-family: Verdana, Geneva, Tahoma, sans-serif; - color: chocolate; + color: #7A1E99; padding-right: 50px; } @@ -60,31 +60,26 @@ form { height: 40px; } + + .inl {display: inline;} + .inl-active { + display: inline; + background-color: #FFD300; + } - - - - - @@ -99,16 +94,7 @@ {% else %} {% endif %} - - - - - - + @@ -95,28 +100,27 @@ {% if c.mkt_phone == "83912051045": %} {% else %} - + {% endif %} - + {% endfor %} diff --git a/web-dev/templates/truerecall.html b/web-dev/templates/truerecall.html index 08825cb..49e7b23 100644 --- a/web-dev/templates/truerecall.html +++ b/web-dev/templates/truerecall.html @@ -48,7 +48,7 @@ a { font-size: large; font-family: Verdana, Geneva, Tahoma, sans-serif; - color: chocolate; + color: #7A1E99; padding-right: 50px; } @@ -60,30 +60,26 @@ form { height: 40px; } + + .inl {display: inline;} + .inl-active { + display: inline; + background-color: #FFD300; + } -
Номер клиентаКол-во попыток Дата и времяПродолжительностьОператорЗапись Действие
{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}{{ c.count_try }}{{ c.time }}{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}{{ c.operator }} - {% if c.has_record == true: %} - - {% else %} - Отсутствует - {% endif %} + {{ c.dt }}
diff --git a/web-dev/templates/notanswer.html b/web-dev/templates/notanswer.html index 77f29b4..46bc0c4 100644 --- a/web-dev/templates/notanswer.html +++ b/web-dev/templates/notanswer.html @@ -49,7 +49,7 @@ a { font-size: large; font-family: Verdana, Geneva, Tahoma, sans-serif; - color: chocolate; + color: #7A1E99; padding-right: 50px; } @@ -61,22 +61,27 @@ form { height: 40px; } + + + .inl { + display: inline; + } + + .inl-active { + display: inline; + background-color: #FFD300; + }
-
@@ -86,7 +91,7 @@
Номер клиента Дата и время ПродолжительностьДействие
- {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], - c.client[7:11]) }} + + + {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }} + + {{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }} + + {{ "%s %s %s %s" |format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }} + + {{ c.time }} {{ c.important }} {{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}
- - - @@ -98,11 +94,7 @@ {% else %} {% endif %} - - - - - + {% endfor %} diff --git a/web-dev/templates/work.html b/web-dev/templates/work.html new file mode 100644 index 0000000..40ff0f1 --- /dev/null +++ b/web-dev/templates/work.html @@ -0,0 +1,55 @@ + + + + + + + В работе + + + + {% for c in call %} +

{{ c.client }}

+ +
Номер клиента Дата и времяПродолжительностьОператорЗапись разговора
{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}{{ c.time }}{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}{{ c.operator }}{{ c.dt }}
+ + + + + + + + + + + + + + + + +
Направление: {{ c.direction }}
Продолжительность: {{ c.answered_duration }}
Время события:{{ c.time }}
Вызываемый номер:{{ c.mkt_phone }}
+ + +
+ Результат +
+ + +
+
+ + +
+ +

+

+ +
+
+ + + {% endfor %} + + + \ No newline at end of file diff --git a/worker-dev backup-2024.03.22/app.py b/worker-dev backup-2024.03.22/app.py new file mode 100644 index 0000000..df32310 --- /dev/null +++ b/worker-dev backup-2024.03.22/app.py @@ -0,0 +1,129 @@ +import pika +import sys +import os +import json +import datetime +from pymongo import MongoClient +import time +from phone import phone +import requests + +db_connection = MongoClient("mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo") +db_base = db_connection["phone-dev"] +coll = db_base["phone"] +coll_all = db_base["phone-all"] +err = db_base["err"] +blacklist = db_base["blacklist"] +phoneDebug = db_base["phone-debug"] +coll_userkey = db_base['userkey'] + +mkt_phones = ['83912051046', '83912051045'] + +mobilon_wait = 5 # Время ожидания необходимо чтобы на стороне мобилона все улеглось +min_recall_len_in_sec = 8 + + +def isBlack(number: str) -> bool: + return True if blacklist.count_documents({"_id": number}) > 0 else False + + +# Stats: +# 0 - ответили +# 1 - не приняли +# 2 - перезвонили успешно +# 4 - Перезвонили неуспешно + + +# LOG +# 0 - выходящий вызов закончен +# 1 - Вызов не принят +# 2 - Перезвонили и дозвонились +def main(): + + connection = pika.BlockingConnection(pika.ConnectionParameters( + 'rabbitmq', 5672, 'mkt', pika.PlainCredentials('rabbit', 'mrl2X0jwnYuCCiKFTshG7WKyOAhfDo'))) + channel = connection.channel() + + channel.queue_declare(queue='incoming-dev') + + def callback(ch, method, properties, body: bytearray): + # Парсим строку + ph = phone(body) + # Определяем тип соединения + # Если входящий + print(ph.ConvertToJSON()) + + phoneDebug.insert_one(ph.ConvertToJSON()) + + if ph.GetState() == "START": + ph.addStart() + + if ph.GetState() == "END": + ph.addEnd() + + if ph.GetState() == "HANGUP" and ph.isCanClose() == 1: + # Ждем + time.sleep(mobilon_wait) + + t_req = "https://callinfo.services.mobilon.ru/api/call/info/1e86a98e026578eb5f6bf8c092c0c4a2/" + ph.GetUUID() + try: + res: dict = json.loads(requests.get(t_req).content) + except: + print("Get data from Mobilon", t_req) + + try: + coll_all.insert_one(res) + except: + print("coll_all:", res) + + # В этом месте описывается логика работы программы исходя основываясь на данных мобилона + if res["direction"] == "incoming" and isBlack(res["from"]) == False: + # Подмена полей + + res["client"] = res.pop("from") + res["mkt_phone"] = res.pop("to") + + # 2. Удаляем пропущенные если есть + coll.delete_many( + {"client": {'$regex': res["client"]}, "status": {"$in": ["NOT_ANSWERED", "RECALL_FALSE"]}}) + coll.insert_one(res) + + if res["direction"] == "external": + res["client"] = res.pop("to") + res["operator"] = res.pop("from") + + # Совершенно непонятный костыль, откуда берется загадка + res.pop("_id") + + if res["has_record"] == True and res["answered_duration"] > min_recall_len_in_sec: + res["status"] = "RECALL_TRUE" + else: + res["status"] = "RECALL_FALSE" + + t = coll.update_many({ + "client": {'$regex': res["client"]}, + "status": {'$in': ["NOT_ANSWERED", "RECALL_FALSE"]} + }, {'$set': res, '$inc': {"count_try": 1}}) + + coll.update_many({"count_try": {"$gt": 2}, "client": res["client"]}, { + "$set": {"status": "DELETED"}}) + + # ------------------------------- + res.clear() + + channel.basic_consume( + queue='incoming-dev', on_message_callback=callback, auto_ack=True) + + print(' [*] Waiting for messages. To exit press CTRL+C') + channel.start_consuming() + + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + print('Interrupted') + try: + sys.exit(0) + except SystemExit: + os._exit(0) diff --git a/worker-dev backup-2024.03.22/dockerfile b/worker-dev backup-2024.03.22/dockerfile new file mode 100644 index 0000000..5ca5662 --- /dev/null +++ b/worker-dev backup-2024.03.22/dockerfile @@ -0,0 +1,13 @@ +FROM alpine + +RUN apk update && apk upgrade && apk add python3 && apk add -U tzdata + +WORKDIR /app + +COPY requirements.txt requirements.txt +RUN python3 -m venv .venv +RUN /app/.venv/bin/pip3 install -r /app/requirements.txt +ADD *.py /app +EXPOSE 5000 + +CMD [".venv/bin/python3", "app.py"] \ No newline at end of file diff --git a/worker-dev backup-2024.03.22/phone.py b/worker-dev backup-2024.03.22/phone.py new file mode 100644 index 0000000..4677213 --- /dev/null +++ b/worker-dev backup-2024.03.22/phone.py @@ -0,0 +1,60 @@ +import json +import redis + + +r = redis.Redis(host="redis") + + +class phone: + def __init__(self, message: bytearray): + self.msg = message + self.dict = self.ConvertToJSON() + + def ConvertToJSON(self): + try: + return json.loads(str(self.msg.decode('utf-8')).replace("\'", "\"")) + except: + return {} + + # def GetDirection(self) -> str: + # return self.dict["direction"] + + def GetUUID(self) -> str: + return self.dict["uuid"] + + # def GetClient(self) -> str: + # return self.dict["from"] if self.GetDirection() == "incoming" else self.dict["to"] + + # def GetOperator(self) -> str: + # return self.dict["to"] if self.GetDirection() == "incoming" else self.dict["from"] + + # def GetTimestamp(self) -> int: + # """Return int timestamp""" + # return self.dict["time"] + + def GetState(self) -> str: + return self.dict["state"] + + # def isIncoming(self) -> bool: + # """True Если входящий, иначе False""" + # return True if self.GetDirection() == "incoming" else False + + # def isExternal(self) -> bool: + # """True если исходящий, иначе False""" + # return True if self.GetDirection() == "external" else False + + def isCanClose(self) -> int: + try: + return int(r.hget(self.GetUUID(), "canClose")) + except: + return 0 + + def addStart(self): + r.hset(self.GetUUID(), mapping={ + "canClose": "0" + }) + + def addEnd(self): + r.hset(self.GetUUID(), mapping={ + "canClose": "1" + }) diff --git a/worker-dev backup-2024.03.22/requirements.txt b/worker-dev backup-2024.03.22/requirements.txt new file mode 100644 index 0000000..7479d1b --- /dev/null +++ b/worker-dev backup-2024.03.22/requirements.txt @@ -0,0 +1,18 @@ +async-timeout==4.0.3 +click==8.1.3 +dnspython==2.3.0 +Flask==2.2.3 +importlib-metadata==6.2.0 +itsdangerous==2.1.2 +Jinja2==3.1.2 +MarkupSafe==2.1.2 +pika==1.3.1 +pymongo==4.3.3 +certifi==2022.12.7 +charset-normalizer==3.1.0 +idna==3.4 +requests==2.28.2 +urllib3==1.26.15 +redis==5.0.1 +Werkzeug==2.2.3 +zipp==3.15.0 \ No newline at end of file diff --git a/worker-dev/app copy.py b/worker-dev/app copy.py deleted file mode 100644 index a57e9d8..0000000 --- a/worker-dev/app copy.py +++ /dev/null @@ -1,213 +0,0 @@ -import pika -import sys -import os -import json -import datetime -import requests -from pymongo import MongoClient -import time -from phone import phone - - -db_connection = MongoClient("mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo") -db_base = db_connection["phone-dev"] -coll_source = db_base["source"] -phoneAnswer = db_base["phone-answer"] -phoneNAnswer = db_base["phone-n-answer"] -phoneRecallTrue = db_base["phone-recall-true"] -phoneRecallFalse = db_base["phone-recall-false"] -phoneLog = db_base["phone-log"] -phoneDebug = db_base["phone-debug"] -coll_userkey = db_base['userkey'] - -mkt_phones = ['83912051046', '83912051045'] -IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951252791', '83919865589', - '84951183750', '89919237009', '89919241441', '89919863883', '89919505445', '89919398228', '89919500798'] - -# Stats: -# 0 - ответили -# 1 - не приняли -# 2 - перезвонили успешно -# 4 - Перезвонили неуспешно - - -# LOG -# 0 - выходящий вызов закончен -# 1 - Вызов не принят -# 2 - Перезвонили и дозвонились -def main(): - - connection = pika.BlockingConnection(pika.ConnectionParameters( - 'rabbitmq', 5672, 'mkt', pika.PlainCredentials('rabbit', 'mrl2X0jwnYuCCiKFTshG7WKyOAhfDo'))) - channel = connection.channel() - - channel.queue_declare(queue='incoming-dev') - - def callback(ch, method, properties, body: bytearray): - try: - # Парсим строку - srcJson = json.loads(str(body.decode('utf-8')).replace("\'", "\"")) - srcJson["time"] = datetime.datetime.fromtimestamp( - srcJson["time"]).strftime('%Y-%m-%d %H:%M:%S') - # Определяем направление соединения - # Отсекаем лишние события по признаку длиины номера - - if srcJson['to'] in mkt_phones and srcJson['direction'] == "incoming" and srcJson['state'] == "HANGUP" and srcJson not in IgnoreList and int(srcJson['duration']) > 15: - # Формируем словарь для загрузки - upd = { - "_id": srcJson['uuid'], - "client": srcJson['from'], - "operator": srcJson['to'], - "time": srcJson['time'] - } - - if srcJson.get("recordUrl", False): - # Запись бывает только у принятых вызовов, поэтому сразу добавляем в базу - try: - upd["recordUrl"] = srcJson["recordUrl"] - phoneAnswer.insert_one(upd) - phoneNAnswer.delete_many({"client": srcJson["from"]}) - try: - print("0", upd) - except: - pass - except Exception as e: - pass - else: - # Добавляем запись только в том случае если ранее номер отсутствовал, - # В противном случае обновляем запись - try: - phoneNAnswer.update_one(filter={'client': srcJson['from']}, update={ - '$set': upd}, upsert=True) - try: - print("1", upd) - except: - pass - except Exception as e: - pass - - if srcJson['direction'] == "external" and srcJson['state'] == "START": - phoneNAnswer.update_one({"client": srcJson["to"]}, { - "currstate": "calling"}) - - # Парсим исходящие звонки только в том случае если продолжительность разговора более 40 секунд - if srcJson['state'] == "HANGUP" and srcJson['direction'] == "external" and int(srcJson['duration']) > 30: - # Обработка запускается только в том случае если в базе пропущенных есть записи - if phoneNAnswer.count_documents({"client": srcJson["to"]}) > 0: - # Удаляем запись из списка пропушеных - phoneNAnswer.delete_many( - filter={"client": {'$regex': srcJson["to"]}}) - # формируем данные для загрузки - ins = { - "_id": srcJson["uuid"], - "client": srcJson["to"], - "operator": srcJson["from"], - "time": srcJson["time"], - "currstate": srcJson["from"] - } - # Если запись разговора есть то записываем считаем что дозвонились - if srcJson.get("recordUrl", False): - ins["recordUrl"] = srcJson["recordUrl"] - try: - # Добавляем в таблицу дозвонились успешно и удаляем по маске из недозвонившихся - phoneRecallTrue.insert_one(ins) - phoneNAnswer.delete_many( - filter={"client": {'$regex': srcJson["to"]}}) - try: - print("3", ins) - except: - pass - except Exception as e: - print(2, e) - else: - try: - phoneRecallFalse.insert_one(ins) - except: - print(2, e) - except Exception as e: - print("!!!!!!!", e) - - channel.basic_consume( - queue='incoming-dev', on_message_callback=callback, auto_ack=True) - - print(' [*] Waiting for messages. To exit press CTRL+C') - channel.start_consuming() - - -# # Определяем направление соединения -# if srcJson['direction'] == 'incoming': -# # Определяем начальный статус -# if srcJson['state'] == 'START': -# # Создаем переменную. Ответ = false, можно закрывать = false, Приоритетная линия -# if srcJson['to'] == '83912051045': -# tmpIncoming[srcJson['uuid']] = [False, False, True] -# else: -# tmpIncoming[srcJson['uuid']] = [False, False, False] -# # Обновление статуса при входящем звонке -# coll_phone.delete_one({'$and': [{'client': srcJson['from']}, {'status': 1}]}) -# if srcJson['state'] == 'ANSWER' and srcJson['uuid'] in tmpIncoming: -# tmpIncoming[srcJson['uuid']][0] = True -# if srcJson['state'] == 'END' and srcJson['uuid'] in tmpIncoming: -# tmpIncoming[srcJson['uuid']][1] = True -# if srcJson['state'] == 'HANGUP' and srcJson['uuid'] in tmpIncoming and tmpIncoming[srcJson['uuid']][1] == True: -# try: -# srcJson['callstatus'] -# insDict = {"client": srcJson['from'], "time": srcJson['time'], "status": 0, -# "recordUrl": srcJson["recordUrl"], "duration": srcJson["duration"], "important": tmpIncoming[srcJson['uuid']][2]} -# except Exception as e: -# print(e) -# insDict = { -# "client": srcJson['from'], "time": srcJson['time'], "status": 1, "important": tmpIncoming[srcJson['uuid']][2], "uuid": srcJson['uuid']} -# finally: -# coll_phone.insert_one(insDict) -# tmpIncoming.pop(srcJson['uuid']) -# try: -# insUserKey = {'userkey': srcJson['userkey']} -# coll_userkey.update_one( -# filter={ -# 'operator': srcJson['to'], -# }, -# update={ -# '$set': insUserKey, -# }, -# upsert=True -# ) -# except Exception as e: -# print(e) - -# if srcJson['direction'] == 'external': -# # coll_phone.update_one({'$and': [{'client': {'$regex': srcJson['to']}}, {'status': 1}}]}, {'$set': {'status': 2, 'callid': srcJson['uuid']}}) -# coll_phone.update_one({'$and': [{'client': {'$regex': srcJson['to']}}, {'status': 1}]}, {'$set': {'status': 2, 'callid': srcJson['uuid']}}) -# if srcJson['state'] == 'HANGUP': -# try: -# # Проверяем заполнено ли поле recordURL, если нет то меняем статус на 4 -# if len(srcJson['recordUrl']) > 4: -# print(srcJson['uuid'], srcJson['recordUrl']) -# coll_phone.update_one({'callid':srcJson['uuid']}, {'$set': {'recordUrl': srcJson['recordUrl'], 'status': 2}}) -# else: -# print(srcJson['uuid']) -# coll_phone.update_one({'callid':srcJson['uuid']}, {'$set': {'status': 4}}) -# except Exception as e: -# print(e) - - # except Exception as e: - # print(e.with_traceback) - # print(e) - # exit() - - # channel.basic_consume( - # queue='incoming-dev', on_message_callback=callback, auto_ack=False) - - # print(' [*] Waiting for messages. To exit press CTRL+C') - # channel.start_consuming() - - -if __name__ == '__main__': - try: - main() - except KeyboardInterrupt: - print('Interrupted') - try: - sys.exit(0) - except SystemExit: - os._exit(0) diff --git a/worker-dev/app.py b/worker-dev/app.py index 46e97b8..9d1e6e8 100644 --- a/worker-dev/app.py +++ b/worker-dev/app.py @@ -13,15 +13,19 @@ db_base = db_connection["phone-dev"] coll = db_base["phone"] coll_all = db_base["phone-all"] err = db_base["err"] +blacklist = db_base["blacklist"] phoneDebug = db_base["phone-debug"] coll_userkey = db_base['userkey'] mkt_phones = ['83912051046', '83912051045'] -IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951252791', '83919865589', - '84951183750', '89919237009', '89919241441', '89919863883', '89919505445', '89919398228', '89919500798'] +mobilon_wait = 5 # Время ожидания необходимо чтобы на стороне мобилона все улеглось +min_recall_len_in_sec = 8 + + +def isBlack(number: str) -> bool: + return True if blacklist.count_documents({"_id": number}) > 0 else False -mobilon_wait = 3 # Время ожидания необходимо чтобы на стороне мобилона все улеглось # Stats: # 0 - ответили @@ -73,37 +77,15 @@ def main(): print("coll_all:", res) # В этом месте описывается логика работы программы исходя основываясь на данных мобилона - if res["direction"] == "incoming": + if res["direction"] == "incoming" and isBlack(res["from"]) == False: # Подмена полей - res["client"] = res.pop("from") res["mkt_phone"] = res.pop("to") # 2. Удаляем пропущенные если есть coll.delete_many( - {"client": {'$regex': res["client"]}, "status": "NOT_ANSWERED"}) + {"client": {'$regex': res["client"]}, "status": {"$in": ["NOT_ANSWERED", "RECALL_FALSE"]}}) coll.insert_one(res) - - if res["direction"] == "external": - res["client"] = res.pop("to") - res["operator"] = res.pop("from") - - # Совершенно непонятный костыль, откуда берется загадка - res.pop("_id") - - if res["has_record"] == True and res["answered_duration"] > 8: - res["status"] = "RECALL_TRUE" - else: - res["status"] = "RECALL_FALSE" - - - t = coll.update_many({ - "client": {'$regex': res["client"]}, - "status": {'$in': ["NOT_ANSWERED", "RECALL_FALSE"]} - }, {'$set': res, '$inc': {"count_try": 1}}) - - coll.update_many({"count_try": {"$gt": 2}, "client": res["client"]}, {"$set": {"status": "DELETED"}}) - # ------------------------------- res.clear()