205 строки
5.8 KiB
Python
205 строки
5.8 KiB
Python
|
import config
|
||
|
from models import User, Pixel, RequestsFrequency
|
||
|
from psycopg import AsyncConnection
|
||
|
|
||
|
|
||
|
conninfo = 'host=%(host)s user=%(user)s password=%(password)s dbname=%(dbname)s' % {
|
||
|
'host': config.Database.host,
|
||
|
'user': config.Database.user,
|
||
|
'password': config.Database.password,
|
||
|
'dbname': config.Database.dbname,
|
||
|
}
|
||
|
|
||
|
|
||
|
async def get_user(
|
||
|
ip_address: str,
|
||
|
) -> list[Pixel]:
|
||
|
async with await AsyncConnection.connect(conninfo) as connection:
|
||
|
async with connection.cursor() as cursor:
|
||
|
sql = '''
|
||
|
select
|
||
|
users.id,
|
||
|
users.ip_address,
|
||
|
users.created,
|
||
|
count(history),
|
||
|
unnest(user_colors.color)
|
||
|
from
|
||
|
users
|
||
|
left outer join history on
|
||
|
users.id = history.user_id
|
||
|
left outer join user_colors on
|
||
|
users.id = user_colors.user_id
|
||
|
group by
|
||
|
users.id,
|
||
|
users.ip_address,
|
||
|
users.created;
|
||
|
'''
|
||
|
await cursor.execute(sql)
|
||
|
records = await cursor.fetchall()
|
||
|
return list(
|
||
|
Pixel(
|
||
|
x=pixel_x,
|
||
|
y=pixel_y,
|
||
|
color=pixel_color,
|
||
|
user=User(
|
||
|
id=user_id,
|
||
|
ip_address=user_ip_address,
|
||
|
progress=user_progress,
|
||
|
created=user_created,
|
||
|
),
|
||
|
last_update=pixel_last_update,
|
||
|
)
|
||
|
for
|
||
|
pixel_x,
|
||
|
pixel_y,
|
||
|
pixel_color,
|
||
|
user_id,
|
||
|
user_ip_address,
|
||
|
user_progress,
|
||
|
user_created,
|
||
|
pixel_last_update,
|
||
|
in
|
||
|
records
|
||
|
)
|
||
|
|
||
|
|
||
|
async def get_pixels() -> list[Pixel]:
|
||
|
async with await AsyncConnection.connect(conninfo) as connection:
|
||
|
async with connection.cursor() as cursor:
|
||
|
sql = '''
|
||
|
select
|
||
|
pixels.x,
|
||
|
pixels.y,
|
||
|
pixels.color,
|
||
|
pixels.last_update
|
||
|
from
|
||
|
pixels;
|
||
|
'''
|
||
|
await cursor.execute(sql)
|
||
|
records = await cursor.fetchall()
|
||
|
return list(
|
||
|
Pixel(
|
||
|
x=pixel_x,
|
||
|
y=pixel_y,
|
||
|
color=pixel_color,
|
||
|
last_update=pixel_last_update,
|
||
|
)
|
||
|
for
|
||
|
pixel_x,
|
||
|
pixel_y,
|
||
|
pixel_color,
|
||
|
pixel_last_update,
|
||
|
in
|
||
|
records
|
||
|
)
|
||
|
|
||
|
|
||
|
async def put_pixel(
|
||
|
x: int,
|
||
|
y: int,
|
||
|
color: int,
|
||
|
ip_address,
|
||
|
):
|
||
|
async with await AsyncConnection.connect(conninfo) as connection:
|
||
|
async with connection.cursor() as cursor:
|
||
|
sql = '''
|
||
|
call put_pixel(
|
||
|
%(x)s,
|
||
|
%(y)s,
|
||
|
%(color)s,
|
||
|
%(ip_address)s
|
||
|
);
|
||
|
'''
|
||
|
await cursor.execute(
|
||
|
sql,
|
||
|
{
|
||
|
'x': x,
|
||
|
'y': y,
|
||
|
'color': color,
|
||
|
'ip_address': ip_address,
|
||
|
},
|
||
|
)
|
||
|
|
||
|
|
||
|
async def get_requests_frequency(
|
||
|
ip_address: str,
|
||
|
) -> RequestsFrequency:
|
||
|
async with await AsyncConnection.connect(conninfo) as connection:
|
||
|
async with connection.cursor() as cursor:
|
||
|
sql = '''
|
||
|
select
|
||
|
count(requests_per_second),
|
||
|
count(requests_per_minute),
|
||
|
count(requests_per_hour),
|
||
|
count(requests_per_day)
|
||
|
from
|
||
|
requests
|
||
|
left join requests requests_per_second on
|
||
|
requests.id = requests_per_second.id and
|
||
|
requests_per_second.time > now() - '1 second'::interval
|
||
|
left join requests requests_per_minute on
|
||
|
requests.id = requests_per_minute.id and
|
||
|
requests_per_minute.time > now() - '1 minute'::interval
|
||
|
left join requests requests_per_hour on
|
||
|
requests.id = requests_per_hour.id and
|
||
|
requests_per_hour.time > now() - '1 hour'::interval
|
||
|
left join requests requests_per_day on
|
||
|
requests.id = requests_per_day.id and
|
||
|
requests_per_day.time > now() - '1 day'::interval
|
||
|
where
|
||
|
requests.ip_address = '91.195.204.120/32'::cidr;
|
||
|
'''
|
||
|
await cursor.execute(
|
||
|
sql,
|
||
|
{
|
||
|
'ip_address': ip_address,
|
||
|
},
|
||
|
)
|
||
|
requests_per_second, requests_per_minute, requests_per_hour, requests_per_day, = await cursor.fetchone()
|
||
|
return RequestsFrequency(
|
||
|
per_second=requests_per_second,
|
||
|
per_minute=requests_per_minute,
|
||
|
per_hour=requests_per_hour,
|
||
|
per_day=requests_per_day,
|
||
|
)
|
||
|
|
||
|
|
||
|
async def put_request(
|
||
|
ip_address: str,
|
||
|
method: str,
|
||
|
url: str,
|
||
|
is_secure: bool,
|
||
|
user_agent: str = None,
|
||
|
referer: str = None,
|
||
|
):
|
||
|
async with await AsyncConnection.connect(conninfo) as connection:
|
||
|
async with connection.cursor() as cursor:
|
||
|
sql = '''
|
||
|
insert into requests (
|
||
|
ip_address,
|
||
|
method,
|
||
|
url,
|
||
|
is_secure,
|
||
|
user_agent,
|
||
|
referer
|
||
|
) values (
|
||
|
%(ip_address)s,
|
||
|
%(method)s,
|
||
|
%(url)s,
|
||
|
%(is_secure)s,
|
||
|
%(user_agent)s,
|
||
|
%(referer)s
|
||
|
);
|
||
|
'''
|
||
|
await cursor.execute(
|
||
|
sql,
|
||
|
{
|
||
|
'ip_address': ip_address,
|
||
|
'method': method,
|
||
|
'url': url,
|
||
|
'is_secure': is_secure,
|
||
|
'user_agent': user_agent,
|
||
|
'referer': referer,
|
||
|
},
|
||
|
)
|