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