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, }, )