forked from PerchunPak/pinger-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatabase.py
More file actions
186 lines (165 loc) · 6.66 KB
/
Copy pathdatabase.py
File metadata and controls
186 lines (165 loc) · 6.66 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
"""
Вся работа с дата базой здесь.
Взято и изменено под свои нужды с https://github.com/dashwav/nano-chan
"""
from datetime import datetime
from typing import Optional
from asyncpg import Record, create_pool
from asyncpg.pool import Pool
from config import POSTGRES
def parse_record(record: Record) -> Optional[tuple]:
"""
Парсит asyncpg Record обьект в формат tuple
:param record: asyncpg Record обьект
:return: tuple значений, если это не None, иначе None
"""
try: return tuple(record.values())
except AttributeError: return None
class PostgresController: # TODO обновить коментарии
"""
Класс для управления датабазой,
только тут все взаимодействия с ней
"""
__slots__ = 'pool'
def __init__(self, pool: Pool):
self.pool = pool
@classmethod
async def get_instance(cls, connect_kwargs: str = POSTGRES, pool: Pool = None):
"""
Создает обьект класса `PostgresController`
Этот метод создаст необходимые таблицы
:param connect_kwargs:
Аргументы для
:func:`asyncpg.connection.connect` функции
:param pool: существующий пул подключений
`pool` или `connect_kwargs` должны быть None
:return: новый обьект класса `PostgresController`
"""
assert connect_kwargs or pool, (
'Предоставьте либо пул подключений, либо данные о '
'подключении для создания нового пула подключений.'
)
if not pool:
pool = await create_pool(connect_kwargs)
return cls(pool)
async def make_tables(self):
"""
Создает таблицы в дата базе если их ещё нет.
"""
sunpings = """
CREATE TABLE IF NOT EXISTS sunpings (
ip CIDR NOT NULL,
port SMALLINT NOT NULL DEFAULT 25565,
time TIMESTAMP UNIQUE,
players INTEGER NOT NULL
);
"""
sunservers = """
CREATE TABLE IF NOT EXISTS sunservers (
numip CIDR NOT NULL,
port SMALLINT NOT NULL DEFAULT 25565,
record SMALLINT NOT NULL DEFAULT 0,
alias TEXT,
owner BIGSERIAL NOT NULL,
UNIQUE (numip, port)
);
"""
db_entries = (sunpings, sunservers)
for db_entry in db_entries:
await self.pool.execute(db_entry)
async def add_server(self, numip: str, ownerId: str, port: int = 25565):
"""
Добавляет в дата базу новый сервер
:param numip: цифровое айпи IPv4 сервера
:param ownerId: айди владельца сервера
:param port: порт сервера (необязательный аргумент)
"""
sql = """
INSERT INTO sunservers (numip, port, owner) VALUES ($1, $2, $3);
"""
await self.pool.execute(sql, numip, port, ownerId)
async def add_ping(self, ip: str, port: int, players: int):
"""
Добавляет данные о пинге в дата базу
:param ip: цифровое айпи IPv4 сервера
:param port: порт сервера
:param players: количество игроков на сервере в момент пинга
"""
tmF = datetime.now()
tm = datetime(tmF.year, tmF.month, tmF.day-1, tmF.hour, tmF.minute, tmF.second)
sql = """
INSERT INTO sunpings VALUES ($1, $2, $3, $4)
"""
await self.pool.execute(sql, ip, port, tm, players)
async def add_alias(self, alias: str, ip: str, port: int):
"""
Добавляет данные о пинге в дата базу
:param alias: новый алиас сервера
:param ip: цифровое айпи IPv4 сервера
:param port: порт сервера
"""
sql = """
UPDATE sunservers
SET alias = $1
WHERE numip = $2 AND port = $3;
"""
await self.pool.execute(sql, alias, ip, port)
async def add_record(self, numip: str, port: int = 25565, online: int = 0):
"""
Добавляет данные о пинге в дата базу
:param alias: новый алиас сервера
:param ip: цифровое айпи IPv4 сервера
:param port: порт сервера
"""
sql = """
UPDATE sunservers
SET record = $1
WHERE numip = $2 AND port = $3;
"""
await self.pool.execute(sql, online, numip, port)
async def get_server(self, numip: str, port: int = 25565):
"""
Возвращает всю информацию сервера
"""
sql = """
SELECT * FROM sunservers
WHERE numip=$1 AND port=$2;
"""
return await self.pool.fetch(sql, numip, port)
async def get_servers(self):
"""
Возвращает все сервера
"""
sql = """
SELECT * FROM sunservers;
"""
return await self.pool.fetch(sql)
async def get_ip_alias(self, alias: str):
"""
Возвращает айпи и порт сервера через алиас
"""
sql = """
SELECT numip, port FROM sunservers
WHERE alias=$1;
"""
return await self.pool.fetch(sql, alias)
async def get_pings(self, numip: str, port: int = 25565):
"""
Возвращает пинги сервера
"""
sql = """
SELECT * FROM sunpings
WHERE ip=$1 AND port=$2;
"""
return await self.pool.fetch(sql, numip, port)
async def get_ping_yest(self, numip: str, port: int = 25565):
"""
Возвращает пинг сервера сутки назад через FETCH
"""
tmF = datetime.now()
tm = datetime(tmF.year, tmF.month, tmF.day-1, tmF.hour, tmF.minute, tmF.second)
sql = """
SELECT players FROM sunpings
WHERE ip=$1 AND port=$2 AND time=$3;
"""
return await self.pool.fetch(sql, numip, port, tm)