This commit is contained in:
filimonov 2024-02-20 16:43:56 +07:00
parent f79efa2951
commit a086f94798
28 changed files with 1469 additions and 144 deletions

View File

@ -15,6 +15,12 @@ services:
- phone - phone
volumes: volumes:
- rabbitmq:/var/lib/rabbitmq - rabbitmq:/var/lib/rabbitmq
redis:
image: redis/redis-stack:latest
ports:
- 8001:8001
networks:
- phone
reciever: reciever:
build: ./reciever build: ./reciever
restart: always restart: always

75
web-dev/app.py Normal file
View File

@ -0,0 +1,75 @@
from urllib import request
from flask import Flask, jsonify, render_template, url_for, request, redirect
import json
import datetime
from pymongo import MongoClient
CONNECTION_STRING = "mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo"
db_connection = MongoClient(CONNECTION_STRING)
db_base = db_connection["phone-dev"]
coll = db_base["phone"]
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")
IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951252791', '83919865589',
'84951183750', '89919237009', '89919241441', '89919863883', '89919505445', '89919398228', '89919500798']
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")
# API
@app.route("/api/v1/call/set/", methods=["POST"])
def call_put():
print(request.form)
if request.form["act"] == "delete":
coll.update_one({"uuid": request.form["uuid"]}, {
"$set": {"status": "DELETED"}})
return redirect("/falserecall")
if __name__ == "__main__":
app.debug = True
app.run(host="0.0.0.0", port=6001)

16
web-dev/dockerfile Normal file
View 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"]

10
web-dev/requirements.txt Normal file
View File

@ -0,0 +1,10 @@
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

51
web-dev/static/main.css Normal file
View 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;
}

View 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>

View File

@ -0,0 +1,43 @@
<!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">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}">
<title>Lost Calls</title>
</head>
<header>
<a href="/web/call/status/0">Входящий вызов принят</a>
<a href="/web/call/status/1">Входящий вызов не принят</a>
<a href="/web/call/status/2">Перезвонили</a>
</header>
<table>
<tr>
<td>Номер клиента</td>
<!-- <td>Номер оператора</td> -->
<td>Дата время</td>
<td>Ссылка на запись</td>
</tr>
<body>
{% for entry in call %}
<tr>
<!-- <td>{{ entry.client }}</td> -->
<td><a href="tel:{{ entry.client }}">{{ "%s %s %s %s"|format(entry.client[0:1], entry.client[1:4], entry.client[4:7], entry.client[7:11]) }}</a></td>
<!-- <td>{{ entry.Operator }}</td> -->
<td>{{ entry.time }}</td>
<td>
{% if entry.recordUrl|length > 1 %}
<audio src="{{ entry.recordUrl }}" type="audio/mp3" preload="none" controls>Запись</audio>
{% endif %}
</td>
</tr>
{% endfor %}
</body>
</table>
</html>

View File

@ -0,0 +1,79 @@
<!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">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}">
<title>Lost Calls</title>
</head>
<header>
<a href="/web/call/status/0">Входящий вызов принят</a>
<a href="/web/call/status/1">Входящий вызов не принят</a>
<<<<<<< HEAD
<a href="/web/call/status/2">Перезвонили успешно</a>
<a href="/web/call/status/4">Перезвонили безуспешно</a>
<p>
<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>
</p>
=======
<a href="/web/call/status/2">Перезвонили</a>
>>>>>>> parent of c52dc73 (Добавил поиск)
</header>
<table>
<tr>
<td>Номер клиента</td>
<!-- <td>Номер оператора</td> -->
<td>Дата время</td>
<td>Ссылка на запись</td>
</tr>
<body>
{% for entry in call %}
<tr>
<!-- <td>{{ entry.client }}</td> -->
{% if entry.important == True %}
<td>
<font color="#C30000">{{ "%s %s %s %s"|format(entry.client[0:1], entry.client[1:4], entry.client[4:7],
entry.client[7:11]) }}</font>
</td>
{% else %}
<td>{{ "%s %s %s %s"|format(entry.client[0:1], entry.client[1:4], entry.client[4:7], entry.client[7:11]) }}
</td>
{% endif %}
<!-- <td>{{ entry.Operator }}</td> -->
<td>{{ entry.time }}</td>
<td>
<<<<<<< HEAD
{% if entry.status == 0 %}
Вызов принят
{% elif entry.status == 1 %}
Вызов не принят
{% elif entry.status == 2 %}
Перезвонили
{% elif entry.status == 2 %}
Абонент не взял трубку
{% elif entry.status == 9 %}
Абонент заблокирован
{% endif %}
</td>
<td>
=======
>>>>>>> parent of c52dc73 (Добавил поиск)
{% if entry.recordUrl|length > 1 %}
<audio src="{{ entry.recordUrl }}" type="audio/mp3" preload="none" controls>Запись</audio>
{% endif %}
</td>
</tr>
{% endfor %}
</body>
</table>
</html>

View File

@ -0,0 +1,109 @@
<!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>{{ "%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>

View File

@ -0,0 +1,128 @@
<!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>
<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>

View File

@ -0,0 +1,126 @@
<!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: 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>
<!-- <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/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;" />
</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> -->
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>

View 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>

View File

View File

@ -0,0 +1,112 @@
<!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>
<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>

View File

@ -0,0 +1,79 @@
<!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">
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='main.css') }}">
<title>Lost Calls</title>
</head>
<header>
<a href="/web/call/status/0">Входящий вызов принят</a>
<a href="/web/call/status/1">Входящий вызов не принят</a>
<<<<<<< HEAD
<a href="/web/call/status/2">Перезвонили успешно</a>
<a href="/web/call/status/4">Перезвонили безуспешно</a>
<p>
<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>
</p>
=======
<a href="/web/call/status/2">Перезвонили</a>
>>>>>>> parent of c52dc73 (Добавил поиск)
</header>
<table>
<tr>
<td>Номер клиента</td>
<!-- <td>Номер оператора</td> -->
<td>Дата время</td>
<td>Ссылка на запись</td>
</tr>
<body>
{% for entry in call %}
<tr>
<!-- <td>{{ entry.client }}</td> -->
{% if entry.important == True %}
<td>
<font color="#C30000">{{ "%s %s %s %s"|format(entry.client[0:1], entry.client[1:4], entry.client[4:7],
entry.client[7:11]) }}</font>
</td>
{% else %}
<td>{{ "%s %s %s %s"|format(entry.client[0:1], entry.client[1:4], entry.client[4:7], entry.client[7:11]) }}
</td>
{% endif %}
<!-- <td>{{ entry.Operator }}</td> -->
<td>{{ entry.time }}</td>
<td>
<<<<<<< HEAD
{% if entry.status == 0 %}
Вызов принят
{% elif entry.status == 1 %}
Вызов не принят
{% elif entry.status == 2 %}
Перезвонили
{% elif entry.status == 2 %}
Абонент не взял трубку
{% elif entry.status == 9 %}
Абонент заблокирован
{% endif %}
</td>
<td>
=======
>>>>>>> parent of c52dc73 (Добавил поиск)
{% if entry.recordUrl|length > 1 %}
<audio src="{{ entry.recordUrl }}" type="audio/mp3" preload="none" controls>Запись</audio>
{% endif %}
</td>
</tr>
{% endfor %}
</body>
</table>
</html>

Binary file not shown.

Binary file not shown.

44
worker-dev-backup/app.py Normal file
View File

@ -0,0 +1,44 @@
import pika
import sys
import os
import json
import datetime
import re
import config
from pymongo import MongoClient
from msg import msg
import requests
import time
def main():
connection = pika.BlockingConnection(pika.ConnectionParameters(
"192.168.0.20", 5672, "mkt", pika.PlainCredentials(
"rabbit", "mrl2X0jwnYuCCiKFTshG7WKyOAhfDo")
))
channel = connection.channel()
def callback(ch, method, properties, body: bytearray):
srcJson = json.loads(str(body.decode('utf-8')).replace("\'", "\""))
# if srcJson['state'] == 'HANGUP' and srcJson['direction'] == 'incoming' and srcJson['from'] == '89135853246':
try:
if srcJson['callstatus'] != 'ANSWER':
print(srcJson)
except:
pass
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)

View File

@ -0,0 +1,16 @@
IMPORTANT_LINE = ['83912051045']
IGNORE_LIST = ['83912051045',
'83912051046',
'83919865589',
'83919865589',
'84950213944',
'84951183750',
'84951252791',
'89919237009',
'89919241441',
'89919398228',
'89919500798',
'89919505445',
'89919863883']

View File

@ -0,0 +1,14 @@
FROM alpine
RUN apk update && apk upgrade && apk add python3 && apk add -U tzdata
WORKDIR /app
COPY requirements.txt requirements.txt
ADD *.py /app
RUN python3 -m venv .venv
RUN /app/.venv/bin/pip3 install -r /app/requirements.txt
EXPOSE 5000
CMD [".venv/bin/python3", "app.py"]

View File

@ -0,0 +1,94 @@
import pika
import sys
import os
import json
import datetime
import re
import config
from pymongo import MongoClient
from msg import msg
import requests
import time
CONNECTION_STRING = "mongodb://mongodb:Cc03Wz5XX3iI3uY3@192.168.0.20"
db_connection = MongoClient(CONNECTION_STRING)
db_base = db_connection["phone"]
coll_call = db_base["phone_dev"]
from_api = db_base["from_api"]
def main():
connection = pika.BlockingConnection(pika.ConnectionParameters(
"192.168.0.20", 5672, "mkt", pika.PlainCredentials(
"rabbit", "mrl2X0jwnYuCCiKFTshG7WKyOAhfDo")
))
channel = connection.channel()
def callback(ch, method, properties, body: bytearray):
m = msg(body)
# Разбираем входящие звонки
if m.isIncoming():
# Если статус START
if m.getState() == "START":
insert_value = {
"uuid": m.getUUID(),
"status": -1,
"canClose": 0
}
coll_call.update_one(
filter={"client": m.getClient(), "status": -1},
update={"$set": insert_value},
upsert=True
)
#print("НАЧАТ:", m.dict)
# Если Статус END
if m.getState() == "END":
coll_call.update_one(
filter={"uuid": m.getUUID()},
update={"$set": {"canClose": 1}}
)
#print("ЗАКОНЧЕН:", m.dict)
time.sleep(5)
resp = requests.get("https://callinfo.services.mobilon.ru/api/call/info/1e86a98e026578eb5f6bf8c092c0c4a2/" + m.getUUID())
j = json.loads(resp.content.decode('utf-8'))
d = dict(j)
from_api.insert_one(d)
# Если статус HANGUP
if m.getState() == "HANGUP":
if m.isAnswered():
insert_value = {
"status": 0,
"duration": m.getDuration(),
"recordUrl": m.getRecordUrl()
}
else:
insert_value = {
"status": 1
}
coll_call.update_one(
filter={"uuid": m.getUUID(), "canClose": 1},
update={"$set": insert_value}
)
#print("Положена трубка:", m.dict)
channel.basic_consume(
queue='test', 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)

68
worker-dev-backup/msg.py Normal file
View File

@ -0,0 +1,68 @@
import os
import json
import datetime
import re
import config
class msg:
def __init__(self, body):
self.body: bytearray = body
self.decode: str = self.body.decode('utf-8')
self.json: json = json.loads(self.decode.replace("\'", "\""))
self.dict: dict = dict(self.json)
def getDirection(self):
try:
return self.dict["direction"]
except:
pass
def isIncoming(self) -> bool:
return True if self.dict["direction"] == "incoming" else False
def isExternal(self) -> bool:
return not self.isIncoming()
def getState(self) -> str:
try:
return self.dict["state"]
except:
pass
def getClient(self) -> str:
return self.dict["from"] if self.isIncoming() else self.dict["to"]
def getTime(self) -> str:
try:
return datetime.datetime.fromtimestamp(self.dict["time"]).strftime('%Y-%m-%d %H:%M:%S')
except:
return None
def getStatus(self) -> int:
pass
def getRecordUrl(self) -> str:
return self.dict["recordUrl"]
def getDuration(self) -> int:
return self.dict["duration"]
def getUUID(self) -> str:
try:
return self.dict["uuid"]
except:
pass
def isAnswered(self) -> bool:
try:
self.dict["callstatus"]
return True
except:
return False
def isImportant(self):
try:
return True if self.getState() == "START" and self.isIncoming() and self.dict["to"] in config.IMPORTANT_LINE else False
except:
pass

View File

@ -0,0 +1,8 @@
dnspython==2.3.0
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

213
worker-dev/app copy.py Normal file
View File

@ -0,0 +1,213 @@
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)

View File

@ -3,26 +3,26 @@ import sys
import os import os
import json import json
import datetime import datetime
import requests
from pymongo import MongoClient from pymongo import MongoClient
import time import time
from phone import phone
import requests
db_connection = MongoClient("mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo") db_connection = MongoClient("mongodb://mongodb:Cc03Wz5XX3iI3uY3@mongo")
db_base = db_connection["phone-dev"] db_base = db_connection["phone-dev"]
coll_source = db_base["source"] coll = db_base["phone"]
phoneAnswer = db_base["phone-answer"] coll_all = db_base["phone-all"]
phoneNAnswer = db_base["phone-n-answer"] err = db_base["err"]
phoneRecallTrue = db_base["phone-recall-true"]
phoneRecallFalse = db_base["phone-recall-false"]
phoneLog = db_base["phone-log"]
phoneDebug = db_base["phone-debug"] phoneDebug = db_base["phone-debug"]
coll_userkey = db_base['userkey'] coll_userkey = db_base['userkey']
mkt_phones = ['83912051046', '83912051045'] mkt_phones = ['83912051046', '83912051045']
IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951252791', '83919865589', IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951252791', '83919865589',
'84951183750', '89919237009', '89919241441', '89919863883', '89919505445', '89919398228', '89919500798'] '84951183750', '89919237009', '89919241441', '89919863883', '89919505445', '89919398228', '89919500798']
mobilon_wait = 3 # Время ожидания необходимо чтобы на стороне мобилона все улеглось
# Stats: # Stats:
# 0 - ответили # 0 - ответили
# 1 - не приняли # 1 - не приняли
@ -30,6 +30,10 @@ IgnoreList = ['83919865589', '83912051046', '83912051045', '84950213944', '84951
# 4 - Перезвонили неуспешно # 4 - Перезвонили неуспешно
# LOG
# 0 - выходящий вызов закончен
# 1 - Вызов не принят
# 2 - Перезвонили и дозвонились
def main(): def main():
connection = pika.BlockingConnection(pika.ConnectionParameters( connection = pika.BlockingConnection(pika.ConnectionParameters(
@ -38,78 +42,70 @@ def main():
channel.queue_declare(queue='incoming-dev') channel.queue_declare(queue='incoming-dev')
print("RUN")
def callback(ch, method, properties, body: bytearray): def callback(ch, method, properties, body: bytearray):
try:
# Парсим строку # Парсим строку
srcJson = json.loads(str(body.decode('utf-8')).replace("\'", "\"")) ph = phone(body)
srcJson["time"] = datetime.datetime.fromtimestamp( # Определяем тип соединения
srcJson["time"]).strftime('%Y-%m-%d %H:%M:%S') # Если входящий
# Определяем направление соединения print(ph.ConvertToJSON())
# Отсекаем лишние события по признаку длиины номера
if srcJson['to'] in mkt_phones and srcJson['direction'] == "incoming" and srcJson['state'] == "HANGUP" and srcJson not in IgnoreList and int(srcJson['duration']) > 30: phoneDebug.insert_one(ph.ConvertToJSON())
# Формируем словарь для загрузки
upd = {
"_id": srcJson['uuid'],
"client": srcJson['from'],
"operator": srcJson['to'],
"time": srcJson['time']
}
if srcJson.get("recordUrl", False): if ph.GetState() == "START":
# Запись бывает только у принятых вызовов, поэтому сразу добавляем в базу ph.addStart()
try:
upd["recordUrl"] = srcJson["recordUrl"]
phoneAnswer.insert_one(upd)
phoneNAnswer.delete_many({"client": srcJson["from"]})
except Exception as e:
pass
else:
# Добавляем запись только в том случае если ранее номер отсутствовал,
# В противном случае обновляем запись
try:
phoneNAnswer.update_one(filter={'client': srcJson['from']}, update={
'$set': upd}, upsert=True)
except Exception as e:
pass
if srcJson['direction'] == "external" and srcJson['state'] == "START": if ph.GetState() == "END":
phoneNAnswer.update_one({"client": srcJson["to"]}, {"currstate": "calling"}) ph.addEnd()
# Парсим исходящие звонки только в том случае если продолжительность разговора более 40 секунд if ph.GetState() == "HANGUP" and ph.isCanClose() == 1:
if srcJson['state'] == "HANGUP" and srcJson['direction'] == "external" and int(srcJson['duration']) > 30: # Ждем
# Обработка запускается только в том случае если в базе пропущенных есть записи time.sleep(mobilon_wait)
if phoneNAnswer.count_documents({"client": srcJson["to"]}) > 0:
# Удаляем запись из списка пропушеных t_req = "https://callinfo.services.mobilon.ru/api/call/info/1e86a98e026578eb5f6bf8c092c0c4a2/" + ph.GetUUID()
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: try:
# Добавляем в таблицу дозвонились успешно и удаляем по маске из недозвонившихся res: dict = json.loads(requests.get(t_req).content)
phoneRecallTrue.insert_one(ins)
phoneRecallFalse.delete_one(
filter={"client": {'$regex': srcJson["to"]}})
except Exception as e:
print(2, e)
else:
try:
phoneRecallFalse.insert_one(ins)
except: except:
print(2, e) print("Get data from Mobilon", t_req)
except Exception as e:
print("!!!!!!!", e) try:
coll_all.insert_one(res)
except:
print("coll_all:", res)
# В этом месте описывается логика работы программы исходя основываясь на данных мобилона
if res["direction"] == "incoming":
# Подмена полей
res["client"] = res.pop("from")
res["mkt_phone"] = res.pop("to")
# 2. Удаляем пропущенные если есть
coll.delete_many(
{"client": {'$regex': res["client"]}, "status": "NOT_ANSWERED"})
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_one({
"client": res["client"],
"status": {'$in': ["NOT_ANSWERED", "RECALL_FALSE"]}
}, {'$set': res, '$inc': {"count_try": 1}})
coll.update_many({"count_try": {"$gt": 2}}, {"$set": {"status": "DELETED"}})
# -------------------------------
res.clear()
channel.basic_consume( channel.basic_consume(
queue='incoming-dev', on_message_callback=callback, auto_ack=True) queue='incoming-dev', on_message_callback=callback, auto_ack=True)
@ -118,74 +114,6 @@ def main():
channel.start_consuming() 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__': if __name__ == '__main__':
try: try:
main() main()

View File

@ -7,7 +7,7 @@ WORKDIR /app
COPY requirements.txt requirements.txt COPY requirements.txt requirements.txt
RUN python3 -m venv .venv RUN python3 -m venv .venv
RUN /app/.venv/bin/pip3 install -r /app/requirements.txt RUN /app/.venv/bin/pip3 install -r /app/requirements.txt
ADD app.py /app ADD *.py /app
EXPOSE 5000 EXPOSE 5000
CMD [".venv/bin/python3", "app.py"] CMD [".venv/bin/python3", "app.py"]

60
worker-dev/phone.py Normal file
View 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"
})

View File

@ -1,4 +1,11 @@
async-timeout==4.0.3
click==8.1.3
dnspython==2.3.0 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 pika==1.3.1
pymongo==4.3.3 pymongo==4.3.3
certifi==2022.12.7 certifi==2022.12.7
@ -6,3 +13,6 @@ charset-normalizer==3.1.0
idna==3.4 idna==3.4
requests==2.28.2 requests==2.28.2
urllib3==1.26.15 urllib3==1.26.15
redis==5.0.1
Werkzeug==2.2.3
zipp==3.15.0