update 0
This commit is contained in:
parent
4f85cd81de
commit
e03a34c47a
117
web-dev backup-2024.03.22/app.py
Normal file
117
web-dev backup-2024.03.22/app.py
Normal file
@ -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/<number>", 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/<number>", methods=["POST"])
|
||||
def blacklist_delete(number):
|
||||
bl.delete_many({"_id": number})
|
||||
return redirect("/blacklist")
|
||||
|
||||
|
||||
@app.route("/api/v1/blacklist/get/<number>")
|
||||
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)
|
16
web-dev backup-2024.03.22/dockerfile
Normal file
16
web-dev backup-2024.03.22/dockerfile
Normal file
@ -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"]
|
11
web-dev backup-2024.03.22/requirements.txt
Normal file
11
web-dev backup-2024.03.22/requirements.txt
Normal file
@ -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
|
51
web-dev backup-2024.03.22/static/main.css
Normal file
51
web-dev backup-2024.03.22/static/main.css
Normal file
@ -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;
|
||||
}
|
22
web-dev backup-2024.03.22/templates/DeleteCall.html
Normal file
22
web-dev backup-2024.03.22/templates/DeleteCall.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Удаление документа</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Вы действительно хотите удалить номер: {{ id }}?</h2>
|
||||
Причина удаления?
|
||||
<form action="/web/call/delete/confirm" method="post">
|
||||
<textarea name="reason"></textarea>
|
||||
<input type="hidden" name="id" value="{{id}}">
|
||||
<button type="submit">Удалить</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
115
web-dev backup-2024.03.22/templates/answer.html
Normal file
115
web-dev backup-2024.03.22/templates/answer.html
Normal file
@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}"> -->
|
||||
<title> Принятые вызовы</title>
|
||||
</head>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
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: #7A1E99;
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
header {
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
form {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.inl {display: inline;}
|
||||
.inl-active {
|
||||
display: inline;
|
||||
background-color: #FFD300;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div class="inl-active"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form>
|
||||
</div> -->
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Запись разговора</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in call %}
|
||||
<tr>
|
||||
<!-- <td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td> -->
|
||||
{% if c.mkt_phone == "83912051045": %}
|
||||
<td>
|
||||
<font color="#C30000">{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7],
|
||||
c.client[7:11]) }}</font>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
{% endif %}
|
||||
|
||||
<td>{{ c.time }}</td>
|
||||
<td><audio src="{{ c.record_url }}" type="audio/mp3" preload="none" controls>Запись</audio></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
104
web-dev backup-2024.03.22/templates/blacklist.html
Normal file
104
web-dev backup-2024.03.22/templates/blacklist.html
Normal file
@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}"> -->
|
||||
<title>Черный список</title>
|
||||
</head>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<a href="/answer">Входящий вызов принят</a>
|
||||
<a href="/notanswer">Входящий вызов не принят</a>
|
||||
<a href="/truerecall">Перезвонили успешно</a>
|
||||
<a href="/falserecall">Перезвонили безуспешно</a>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form>
|
||||
</div> -->
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Комментарий</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in call %}
|
||||
<tr>
|
||||
<td>{{ c._id }}</td>
|
||||
<td>{{ c.desc }}</td>
|
||||
<td>
|
||||
<form method="post" action="/api/v1/blacklist/delete/{{ c._id }}">
|
||||
<input type="submit" value="Удалить" />
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
134
web-dev backup-2024.03.22/templates/falserecall.html
Normal file
134
web-dev backup-2024.03.22/templates/falserecall.html
Normal file
@ -0,0 +1,134 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}">
|
||||
<title>Перезвонили безуспешно</title>
|
||||
</head>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
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: #7A1E99;
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
header {
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
form {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.inl {display: inline;}
|
||||
.inl-active {
|
||||
display: inline;
|
||||
background-color: #FFD300;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div class="inl"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl-active"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form>
|
||||
</div> -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Кол-во попыток</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Продолжительность</th>
|
||||
<th>Оператор</th>
|
||||
<th>Запись</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in call %}
|
||||
<tr>
|
||||
{% if c.mkt_phone == "83912051045": %}
|
||||
<td>
|
||||
<font color="#C30000">{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7],
|
||||
c.client[7:11]) }}</font>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
{% endif %}
|
||||
<td>{{ c.count_try }}</td>
|
||||
<td>{{ c.time }}</td>
|
||||
<td>{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}</td>
|
||||
<td>{{ c.operator }}</td>
|
||||
<td>
|
||||
{% if c.has_record == true: %}
|
||||
<audio src="{{ c.record_url }}" type="audio/mp3" preload="none" controls>Запись</audio>
|
||||
{% else %}
|
||||
Отсутствует
|
||||
{% endif %}
|
||||
<td style="vertical-align: middle;">
|
||||
<div>
|
||||
<form action="/api/v1/call/set/" method="post" style="border: 0;">
|
||||
<input type="hidden" name="uuid" value="{{ c.uuid }}" />
|
||||
<input type="hidden" name="act" value="delete" />
|
||||
<input type="submit" value="Удалить" style="background-color: firebrick; color: #f8f8f8;" />
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
125
web-dev backup-2024.03.22/templates/notanswer.html
Normal file
125
web-dev backup-2024.03.22/templates/notanswer.html
Normal file
@ -0,0 +1,125 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}"> -->
|
||||
<!-- <link rel="stylesheet" type="text/css" href="http://dev-call.mkt.local/static/main.css"> -->
|
||||
<title>Непринятые</title>
|
||||
</head>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
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: #7A1E99;
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
header {
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
form {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
|
||||
.inl {display: inline;}
|
||||
.inl-active {
|
||||
display: inline;
|
||||
background-color: #FFD300;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div class="inl"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl-active"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<!-- <form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form> -->
|
||||
</div>
|
||||
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Продолжительность</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in call %}
|
||||
<tr>
|
||||
{% if c.mkt_phone == "83912051045": %}
|
||||
|
||||
<td>
|
||||
<font color="#C30000">{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7],
|
||||
c.client[7:11]) }}</font>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
{% endif %}
|
||||
<td>{{ c.time }} {{ c.important }}</td>
|
||||
<td>{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}</td>
|
||||
|
||||
<td>
|
||||
<form action="/api/v1/blacklist/add/{{ c.client }}" method="post" style="border: 0;" />
|
||||
<input type="submit" value="В черный список" style="background-color: dimgray; color: #fff;" />
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
14
web-dev backup-2024.03.22/templates/repair.html
Normal file
14
web-dev backup-2024.03.22/templates/repair.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Ведутся работы, скоро все заработает</h1>
|
||||
</body>
|
||||
|
||||
</html>
|
118
web-dev backup-2024.03.22/templates/truerecall.html
Normal file
118
web-dev backup-2024.03.22/templates/truerecall.html
Normal file
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}">
|
||||
<title>Перезвонили успешно</title>
|
||||
</head>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
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: #7A1E99;
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
header {
|
||||
height: 50px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
form {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.inl {display: inline;}
|
||||
.inl-active {
|
||||
display: inline;
|
||||
background-color: #FFD300;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<div class="inl"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl-active"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form>
|
||||
</div> -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Продолжительность</th>
|
||||
<th>Оператор</th>
|
||||
<th>Запись разговора</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
{% for c in call %}
|
||||
<!-- <td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td> -->
|
||||
{% if c.mkt_phone == "83912051045": %}
|
||||
<td>
|
||||
<font color="#C30000">{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7],
|
||||
c.client[7:11]) }}</font>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
{% endif %}
|
||||
|
||||
<td>{{ c.time }}</td>
|
||||
<td>{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}</td>
|
||||
<td>{{ c.operator }}</td>
|
||||
<td><audio src="{{ c.record_url }}" type="audio/mp3" preload="none" controls>Запись</audio></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -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
|
||||
# #"<br>".join(request.environ)
|
||||
return str(res)
|
||||
|
||||
@app.route("/work/<uuid>")
|
||||
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/<number>", 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/<number>", methods=["POST"])
|
||||
def blacklist_delete(number):
|
||||
bl.delete_many({"_id": number})
|
||||
return redirect("/blacklist")
|
||||
|
||||
|
||||
@app.route("/api/v1/blacklist/get/<number>")
|
||||
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)
|
||||
|
@ -8,3 +8,4 @@ MarkupSafe==2.1.2
|
||||
pymongo==4.3.3
|
||||
Werkzeug==2.2.3
|
||||
zipp==3.15.0
|
||||
requests==2.28.2
|
||||
|
@ -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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<a href="/answer">Входящий вызов принят</a>
|
||||
<a href="/notanswer">Входящий вызов не принят</a>
|
||||
<a href="/truerecall">Перезвонили успешно</a>
|
||||
<a href="/falserecall">Перезвонили безуспешно</a>
|
||||
<div class="inl-active"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
|
97
web-dev/templates/blacklist.html
Normal file
97
web-dev/templates/blacklist.html
Normal file
@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- <link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}"> -->
|
||||
<title>Черный список</title>
|
||||
</head>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<a href="/answer">Входящий вызов принят</a>
|
||||
<a href="/notanswer">Входящий вызов не принят</a>
|
||||
<a href="/truerecall">Перезвонили успешно</a>
|
||||
<a href="/falserecall">Перезвонили безуспешно</a>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Комментарий</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for c in call %}
|
||||
<tr>
|
||||
<td>{{ c._id }}</td>
|
||||
<td>{{ c.desc }}</td>
|
||||
<td>
|
||||
<form method="post" action="/api/v1/blacklist/delete/{{ c._id }}">
|
||||
<input type="submit" value="Удалить" />
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<a href="/answer">Входящий вызов принят</a>
|
||||
<a href="/notanswer">Входящий вызов не принят</a>
|
||||
<a href="/truerecall">Перезвонили успешно</a>
|
||||
<a href="/falserecall">Перезвонили безуспешно</a>
|
||||
<div class="inl"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl-active"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form>
|
||||
</div> -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Кол-во попыток</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Продолжительность</th>
|
||||
<th>Оператор</th>
|
||||
<th>Запись</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -99,16 +94,7 @@
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
{% endif %}
|
||||
<td>{{ c.count_try }}</td>
|
||||
<td>{{ c.time }}</td>
|
||||
<td>{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}</td>
|
||||
<td>{{ c.operator }}</td>
|
||||
<td>
|
||||
{% if c.has_record == true: %}
|
||||
<audio src="{{ c.record_url }}" type="audio/mp3" preload="none" controls>Запись</audio>
|
||||
{% else %}
|
||||
Отсутствует
|
||||
{% endif %}
|
||||
<td>{{ c.dt }}</td>
|
||||
<td style="vertical-align: middle;">
|
||||
<div>
|
||||
<form action="/api/v1/call/set/" method="post" style="border: 0;">
|
||||
|
@ -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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<a href="/answer">Входящий вызов принят</a>
|
||||
<a href="/notanswer">Входящий вызов не принят</a>
|
||||
<a href="/truerecall">Перезвонили успешно</a>
|
||||
<a href="/falserecall">Перезвонили безуспешно</a>
|
||||
<div class="inl"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl-active"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<!-- <form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form> -->
|
||||
</div>
|
||||
|
||||
|
||||
@ -86,7 +91,7 @@
|
||||
<th>Номер клиента</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Продолжительность</th>
|
||||
<!-- <th>Смена статуса</th> -->
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -95,28 +100,27 @@
|
||||
{% if c.mkt_phone == "83912051045": %}
|
||||
|
||||
<td>
|
||||
<font color="#C30000">{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7],
|
||||
c.client[7:11]) }}</font>
|
||||
<font color="#C30000">
|
||||
<a href="/work/{{ c.uuid }}">
|
||||
{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}
|
||||
</a>
|
||||
</font>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
<td>
|
||||
<a href="/work/{{ c.uuid }}">
|
||||
{{ "%s %s %s %s" |format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}
|
||||
</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td>{{ c.time }} {{ c.important }}</td>
|
||||
<td>{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}</td>
|
||||
|
||||
<!-- <td>
|
||||
<form action="/api/v1/call/set/" method="post" style="border: 0;">
|
||||
<input type="hidden" name="uuid" value="{{ c._id }}" />
|
||||
<input type="hidden" name="res" value="truerecall" />
|
||||
<input type="submit" value="Дозвонились" style="background-color: chartreuse;" />
|
||||
<td>
|
||||
<form action="/api/v1/blacklist/add/{{ c.client }}" method="post" style="border: 0;" />
|
||||
<input type="submit" value="В черный список" style="background-color: dimgray; color: #fff;" />
|
||||
</form>
|
||||
<form action="/api/v1/call/set/" method="post">
|
||||
<input type="hidden" name="uuid" value="{{ c._id }}" />
|
||||
<input type="hidden" name="res" value="falserecall" />
|
||||
<input type="submit" value="Не дозвонились" style="background-color: #FFAAAA;" />
|
||||
</form>
|
||||
|
||||
</td> -->
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -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;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<a href="/answer">Входящий вызов принят</a>
|
||||
<a href="/notanswer">Входящий вызов не принят</a>
|
||||
<a href="/truerecall">Перезвонили успешно</a>
|
||||
<a href="/falserecall">Перезвонили безуспешно</a>
|
||||
<div class="inl"><a href="/answer">Входящий вызов принят</a></div>
|
||||
<div class="inl"><a href="/notanswer">Входящий вызов не принят</a></div>
|
||||
<div class="inl-active"><a href="/truerecall">Перезвонили успешно</a></div>
|
||||
<div class="inl"><a href="/falserecall">Перезвонили безуспешно</a></div>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<form name="search" action="/web/call/find/" method="get" class="search">
|
||||
<label class="search_label">Поиск</label>
|
||||
<input class="search_text" type="text" name="client">
|
||||
<input class="search_btn" type="submit" title="Найти">
|
||||
</form>
|
||||
</div> -->
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Номер клиента</th>
|
||||
<th>Дата и время</th>
|
||||
<th>Продолжительность</th>
|
||||
<th>Оператор</th>
|
||||
<th>Запись разговора</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -98,11 +94,7 @@
|
||||
{% else %}
|
||||
<td>{{ "%s %s %s %s"|format(c.client[0:1], c.client[1:4], c.client[4:7], c.client[7:11]) }}</td>
|
||||
{% endif %}
|
||||
|
||||
<td>{{ c.time }}</td>
|
||||
<td>{{ c.answered_duration // 60 }}:{{ "{:02}".format(c.answered_duration % 60) }}</td>
|
||||
<td>{{ c.operator }}</td>
|
||||
<td><audio src="{{ c.record_url }}" type="audio/mp3" preload="none" controls>Запись</audio></td>
|
||||
<td>{{ c.dt }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
55
web-dev/templates/work.html
Normal file
55
web-dev/templates/work.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>В работе</title>
|
||||
</head>
|
||||
|
||||
<body style="font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;">
|
||||
{% for c in call %}
|
||||
<h3>{{ c.client }}</h3>
|
||||
|
||||
<table style="width: 500px; border: 1px; border-radius: 5px;">
|
||||
<tr>
|
||||
<td>Направление:</td>
|
||||
<td> {{ c.direction }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Продолжительность:</td>
|
||||
<td> {{ c.answered_duration }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Время события:</td>
|
||||
<td>{{ c.time }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Вызываемый номер:</td>
|
||||
<td>{{ c.mkt_phone }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<form action="/api/v1/work/" method="post">
|
||||
<fieldset style="width: 500px;">
|
||||
<legend>Результат</legend>
|
||||
<div>
|
||||
<input type="radio" name="recall" value="true" />
|
||||
<label for="true">Дозвонились</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="recall" value="false" checked />
|
||||
<label for="false">Не дозвонились</label>
|
||||
</div>
|
||||
<input type="hidden" name="uuid" value="{{ c.uuid }}" />
|
||||
<p>
|
||||
<div>
|
||||
<input type="submit" value="Принять">
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
</form>
|
||||
{% endfor %}
|
||||
</body>
|
||||
|
||||
</html>
|
129
worker-dev backup-2024.03.22/app.py
Normal file
129
worker-dev backup-2024.03.22/app.py
Normal file
@ -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)
|
13
worker-dev backup-2024.03.22/dockerfile
Normal file
13
worker-dev backup-2024.03.22/dockerfile
Normal file
@ -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"]
|
60
worker-dev backup-2024.03.22/phone.py
Normal file
60
worker-dev backup-2024.03.22/phone.py
Normal file
@ -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"
|
||||
})
|
18
worker-dev backup-2024.03.22/requirements.txt
Normal file
18
worker-dev backup-2024.03.22/requirements.txt
Normal file
@ -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
|
@ -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)
|
@ -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()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user