This repository has been archived by the owner on Jul 6, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.py
92 lines (68 loc) · 2.69 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from aiofile import async_open
from aiopath import AsyncPath
import asyncio
from datetime import datetime
import logging
from re import Match, search
import websockets
import names
from websockets import WebSocketServerProtocol
from websockets.exceptions import ConnectionClosedOK
from main import main as exchange
logging.basicConfig(level=logging.INFO)
class Server:
clients = set()
async def __alter(self, sender: str, message: str) -> str:
await asyncio.sleep(0)
command = search(r'^exchange\s*(\d*)$', message.strip())
if not isinstance(command, Match):
return message
path = AsyncPath('logs')
if not await path.exists():
await path.mkdir()
async with async_open(path / 'calls.log', 'a', encoding='utf-8') as f:
await f.write(f'{datetime.now()}\t{sender}\t{message}\n')
days = int(command.group(1) or 1)
message = ''
for day_currencies in await exchange(days, []):
for date, currencies in day_currencies.items():
message += f'\n{date}:'
for currency, rates in currencies.items():
records = []
for key, value in rates.items():
if value is not None:
records.append(f'{key}: {value} UAH')
if records:
message += '\n\t{}:\n\t\t{}'.format(
currency,
'\n\t\t'.join(records)
)
return message
async def register(self, ws: WebSocketServerProtocol):
ws.name = names.get_full_name()
self.clients.add(ws)
logging.info(f'{ws.remote_address} connects')
async def unregister(self, ws: WebSocketServerProtocol):
self.clients.remove(ws)
logging.info(f'{ws.remote_address} disconnects')
async def send_to_clients(self, message: str):
if self.clients:
[await client.send(message) for client in self.clients]
async def ws_handler(self, ws: WebSocketServerProtocol):
await self.register(ws)
try:
await self.distrubute(ws)
except ConnectionClosedOK:
pass
finally:
await self.unregister(ws)
async def distrubute(self, ws: WebSocketServerProtocol):
async for message in ws:
message = await self.__alter(ws.name, message)
await self.send_to_clients(f"{ws.name}: {message}")
async def main():
server = Server()
async with websockets.serve(server.ws_handler, 'localhost', 8080):
await asyncio.Future() # run forever
if __name__ == '__main__':
asyncio.run(main())