This commit is contained in:
Dev PC
2025-07-03 20:32:00 +03:00
parent 670a2acbe3
commit 3b535c6786
7 changed files with 189 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
AMI_HOST=127.0.0.1
AMI_PORT=5038
AMI_USER=medods
AMI_PASSWORD=2H4x9#87A%D3
+1
View File
@@ -0,0 +1 @@
.venv
+1
View File
@@ -0,0 +1 @@
3.13
+29
View File
@@ -0,0 +1,29 @@
[loggers]
keys=root
[handlers]
keys=logconsole,logfile
[formatters]
keys=formatter
encoding=utf-8
[logger_root]
level=INFO
handlers=logconsole,logfile
[formatter_formatter]
format=%(asctime)s: [%(levelname)s] %(message)s [%(module)s.%(funcName)s():%(lineno)d]
datefmt=%Y-%m-%d %H:%M:%S
[handler_logconsole]
class=logging.StreamHandler
level=INFO
args=(sys.stdout,)
formatter=formatter
[handler_logfile]
class=logging.FileHandler
level=INFO
formatter=formatter
args=("log/medods.log", "a")
+108
View File
@@ -0,0 +1,108 @@
import logging
import logging.config
import os
import asyncio
from datetime import datetime
import socket
import aiofiles
from dotenv import load_dotenv
load_dotenv()
AMI_HOST = os.environ.get("AMI_HOST")
AMI_PORT = int(os.environ.get("AMI_PORT"))
AMI_USER = os.environ.get("AMI_USER")
AMI_PASSWORD = os.environ.get("AMI_PASSWORD")
def send_action(s, action):
s.send(action.encode())
response = ""
while True:
chunk = s.recv(4096)
try:
response += chunk.decode()
except UnicodeDecodeError:
pass
if "\r\n\r\n" in response:
break
response_parts = response.split("\r\n\r\n", 1)
body = response_parts[1]
body_dict = {
line.split(":")[0].strip(): line.split(":")[1].strip()
for line in body.split("\n")
if len(line.split(":")) > 1
}
return body_dict
async def full_log(event):
file_name = f"log/{datetime.now().strftime('%Y-%m-%d')}.log"
async with aiofiles.open(file_name, "a") as f:
await f.write("\n\n" + datetime.now().strftime("%H:%M:%S") + "\n\n")
for key, value in event.items():
await f.write(f"{key}: {value}\n")
async def ami_listening():
# процедура регулярной проверки соединения
async def check_connection():
while True:
try:
await asyncio.sleep(3600)
s.send(b"Action: Ping\r\n\r\n")
await asyncio.sleep(1)
except (ConnectionError, ConnectionResetError):
logging.warning("Connection lost. Restarting...")
await asyncio.sleep(1)
return True # возвращаемся в начало функции ami_listening
# проверка соединения каждые 5 секунд
conn_check_task = asyncio.create_task(check_connection())
conn_check_task.add_done_callback(lambda t: ami_listening() if t.result() else None)
while True:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
logging.info("Connecting to Asterisk...")
s.connect((AMI_HOST, AMI_PORT))
break
except ConnectionRefusedError:
logging.warning("Connection refused. Retrying...")
await asyncio.sleep(1)
logging.info("Connected to Asterisk")
logging.info("Logging in...")
login_action = f"Action: Login\r\nUsername: {AMI_USER}\r\nSecret: {AMI_PASSWORD}\r\n\r\n"
send_action(s, login_action)
logging.info("Logged in")
logging.info("Listening for events...")
events_action = "Action: Events\r\nEventMask: on\r\n\r\n"
send_action(s, events_action)
try:
while True:
event = send_action(s, "")
if event:
await full_log(event)
except (KeyboardInterrupt, SystemExit):
logging.info("Exiting...")
s.close()
except ConnectionResetError:
logging.warning("Connection reset. Restarting...")
await ami_listening()
async def main():
if not os.path.exists("log"):
os.makedirs("log")
logging.config.fileConfig("logging.conf")
await ami_listening()
if __name__ == "__main__":
asyncio.run(main())
+10
View File
@@ -0,0 +1,10 @@
[project]
name = "freepbx-logger"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"aiofiles>=24.1.0",
"python-dotenv>=1.1.1",
]
Generated
+36
View File
@@ -0,0 +1,36 @@
version = 1
revision = 1
requires-python = ">=3.13"
[[package]]
name = "aiofiles"
version = "24.1.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896 },
]
[[package]]
name = "freepbx-logger"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "aiofiles" },
{ name = "python-dotenv" },
]
[package.metadata]
requires-dist = [
{ name = "aiofiles", specifier = ">=24.1.0" },
{ name = "python-dotenv", specifier = ">=1.1.1" },
]
[[package]]
name = "python-dotenv"
version = "1.1.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556 },
]