feature: now using uv + moved to asyncpg from psycopg2
This commit is contained in:
+13
-13
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.accounts as db
|
||||
import settings.settings as settings
|
||||
@@ -17,22 +17,22 @@ accounts_router = APIRouter(prefix="/api/accounts", tags=["accounts"])
|
||||
@accounts_router.post("/group")
|
||||
async def read_accounts_by_group(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_group_author(conn, groupname, current_user.username) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_group_author(conn, groupname, current_user.username) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
return db.get_accounts_by_group(conn, groupname)
|
||||
return await db.get_accounts_by_group(conn, groupname)
|
||||
|
||||
|
||||
@accounts_router.post("/group/platform")
|
||||
async def read_accounts_by_group_platform(
|
||||
groupname: str,
|
||||
platform: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
@@ -40,7 +40,7 @@ async def read_accounts_by_group_platform(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
account_data = db.get_accounts_by_group_platform(conn, groupname, platform.lower())
|
||||
account_data = await db.get_accounts_by_group_platform(conn, groupname, platform.lower())
|
||||
if account_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -56,21 +56,21 @@ async def add_account(
|
||||
login: str,
|
||||
password: str,
|
||||
metadata: dict,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_group_author(conn, groupname, current_user.username) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_group_author(conn, groupname, current_user.username) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_account_existence(conn, groupname, platform.lower()):
|
||||
if await db.check_account_existence(conn, groupname, platform.lower()):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Account already exists",
|
||||
)
|
||||
hashed_password = encode_str(password)
|
||||
return db.create_account(conn, groupname, current_user.username, platform.lower(), login, hashed_password, metadata)
|
||||
return await db.create_account(conn, groupname, current_user.username, platform.lower(), login, hashed_password, metadata)
|
||||
|
||||
|
||||
@accounts_router.post("/update")
|
||||
@@ -81,10 +81,10 @@ async def update_account(
|
||||
login: str,
|
||||
password: str,
|
||||
metadata: dict,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
account_data = db.get_accounts_by_group_platform(conn, groupname, platform.lower())
|
||||
account_data = await db.get_accounts_by_group_platform(conn, groupname, platform.lower())
|
||||
if account_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -97,4 +97,4 @@ async def update_account(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
return db.update_account(conn, groupname, author, platform.lower(), login, password, metadata)
|
||||
return await db.update_account(conn, groupname, author, platform.lower(), login, password, metadata)
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.users as db
|
||||
import settings.settings as settings
|
||||
@@ -15,36 +15,36 @@ anon_router = APIRouter(prefix="/api/anon", tags=["anon"])
|
||||
async def add_admin(
|
||||
username: str,
|
||||
password: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)]
|
||||
conn: Annotated[Connection, Depends(get_db_connection)]
|
||||
):
|
||||
if not settings.settings.allow_create_admins:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
if await db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "admin")
|
||||
return await db.create_user(conn, username, hashed_password, "admin")
|
||||
|
||||
@anon_router.post("/add/user")
|
||||
async def add_user(
|
||||
username: str,
|
||||
password: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)]
|
||||
conn: Annotated[Connection, Depends(get_db_connection)]
|
||||
):
|
||||
if not settings.settings.allow_create_users:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
if await db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "user")
|
||||
return await db.create_user(conn, username, hashed_password, "user")
|
||||
|
||||
+4
-4
@@ -1,9 +1,9 @@
|
||||
from datetime import timedelta
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
from api.models import Token
|
||||
from api.utils import authenticate_user, create_access_token
|
||||
@@ -17,9 +17,9 @@ auth_router = APIRouter(prefix="/api", tags=["auth"])
|
||||
@auth_router.post("/token")
|
||||
async def login(
|
||||
form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
|
||||
conn: Annotated[connection, Depends(get_db_connection)]
|
||||
conn: Annotated[Connection, Depends(get_db_connection)]
|
||||
) -> Token:
|
||||
password_correct = authenticate_user(conn, form_data.username, form_data.password)
|
||||
password_correct = await authenticate_user(conn, form_data.username, form_data.password)
|
||||
if not password_correct:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
@@ -27,7 +27,7 @@ async def login(
|
||||
headers={"WWW-Authenticate": "Bearer"},
|
||||
)
|
||||
|
||||
user_disabled = check_user_disabled(conn, form_data.username)
|
||||
user_disabled = await check_user_disabled(conn, form_data.username)
|
||||
if user_disabled:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.feeds as db
|
||||
import settings.settings as settings
|
||||
@@ -20,10 +20,10 @@ feeds_router = APIRouter(prefix="/api/feeds", tags=["feeds"])
|
||||
@feeds_router.post("/feed")
|
||||
async def read_feed(
|
||||
feed_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
feed_data = db.get_feed(conn, feed_id)
|
||||
feed_data = await db.get_feed(conn, feed_id)
|
||||
if feed_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -31,14 +31,14 @@ async def read_feed(
|
||||
)
|
||||
feed = Feed().fill(feed_data)
|
||||
|
||||
groupname = get_groupname_by_feed_id(conn, feed_id)
|
||||
groupname = await get_groupname_by_feed_id(conn, feed_id)
|
||||
if groupname is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such feed",
|
||||
)
|
||||
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
@@ -51,19 +51,19 @@ async def read_feed(
|
||||
@feeds_router.post("/new")
|
||||
async def new_feed(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_group_author(conn, groupname, current_user.username) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_group_author(conn, groupname, current_user.username) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
accounts = get_accounts_by_group(conn, groupname)
|
||||
feed = generate_feed(conn, accounts)
|
||||
accounts = await get_accounts_by_group(conn, groupname)
|
||||
feed = await generate_feed(conn, accounts)
|
||||
if feed:
|
||||
return db.create_feed(conn, groupname, feed)
|
||||
return await db.create_feed(conn, groupname, feed)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_424_FAILED_DEPENDENCY,
|
||||
@@ -75,11 +75,11 @@ async def new_feed(
|
||||
@feeds_router.post("/delete")
|
||||
async def delete_feed(
|
||||
feed_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_feed(conn, feed_id)
|
||||
return await db.delete_feed(conn, feed_id)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
+39
-39
@@ -1,8 +1,8 @@
|
||||
import secrets
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.groups as db
|
||||
import settings.settings as settings
|
||||
@@ -19,7 +19,7 @@ groups_router = APIRouter(prefix="/api/groups", tags=["groups"])
|
||||
@groups_router.post("/group")
|
||||
async def read_any_group(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
@@ -27,7 +27,7 @@ async def read_any_group(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
group_data = db.get_group(conn, groupname)
|
||||
group_data = await db.get_group(conn, groupname)
|
||||
if group_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -38,15 +38,15 @@ async def read_any_group(
|
||||
@groups_router.post("/invite_code")
|
||||
async def read_group_invite_code(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
invite_code = db.get_group_invite_code(conn, groupname)
|
||||
invite_code = await db.get_group_invite_code(conn, groupname)
|
||||
if invite_code is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -57,20 +57,20 @@ async def read_group_invite_code(
|
||||
@groups_router.post("/last_feed")
|
||||
async def read_group_last_feed_id(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
return db.get_group_last_feed_id(conn, groupname)
|
||||
return await db.get_group_last_feed_id(conn, groupname)
|
||||
|
||||
|
||||
@groups_router.post("/add")
|
||||
async def add_group(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)],
|
||||
groupname: str,
|
||||
allow_skips: bool = True,
|
||||
@@ -82,30 +82,30 @@ async def add_group(
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
if db.check_group_existence(conn, groupname):
|
||||
if await db.check_group_existence(conn, groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Group already exists",
|
||||
)
|
||||
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
while db.check_invite_code(conn, invite_code):
|
||||
while await db.check_invite_code(conn, invite_code):
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
return {
|
||||
"result": db.create_group(conn, groupname, invite_code, current_user.username, allow_skips, feed_interval_minutes),
|
||||
"result": await db.create_group(conn, groupname, invite_code, current_user.username, allow_skips, feed_interval_minutes),
|
||||
"invite code": invite_code
|
||||
}
|
||||
|
||||
@groups_router.post("/delete")
|
||||
async def delete_group(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_group(conn, groupname)
|
||||
if db.check_group_author(conn, groupname, current_user.username):
|
||||
return db.delete_group(conn, groupname)
|
||||
return await db.delete_group(conn, groupname)
|
||||
if await db.check_group_author(conn, groupname, current_user.username):
|
||||
return await db.delete_group(conn, groupname)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -117,19 +117,19 @@ async def delete_group(
|
||||
async def update_groupname(
|
||||
groupname: str,
|
||||
new_groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if db.check_group_existence(conn, new_groupname):
|
||||
if await db.check_group_existence(conn, new_groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Groupname is already taken",
|
||||
)
|
||||
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_groupname(conn, groupname, new_groupname)
|
||||
if db.check_group_author(conn, groupname, current_user.username):
|
||||
return db.update_group_groupname(conn, groupname, new_groupname)
|
||||
return await db.update_group_groupname(conn, groupname, new_groupname)
|
||||
if await db.check_group_author(conn, groupname, current_user.username):
|
||||
return await db.update_group_groupname(conn, groupname, new_groupname)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -140,13 +140,13 @@ async def update_groupname(
|
||||
async def update_author(
|
||||
groupname: str,
|
||||
new_author: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_author(conn, groupname, new_author)
|
||||
if db.check_group_author(conn, groupname, current_user.username):
|
||||
return db.update_group_author(conn, groupname, new_author)
|
||||
return await db.update_group_author(conn, groupname, new_author)
|
||||
if await db.check_group_author(conn, groupname, current_user.username):
|
||||
return await db.update_group_author(conn, groupname, new_author)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -156,21 +156,21 @@ async def update_author(
|
||||
@groups_router.get("/update/invite_code")
|
||||
async def update_invite_code(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
while db.check_invite_code(conn, invite_code):
|
||||
while await db.check_invite_code(conn, invite_code):
|
||||
invite_code = "".join(secrets.choice(JOIN_CODE_SYMBOLS) for _ in range(startup_settings.join_code_length))
|
||||
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return {
|
||||
"result": db.update_group_invite_code(conn, groupname, invite_code),
|
||||
"result": await db.update_group_invite_code(conn, groupname, invite_code),
|
||||
"invite code": invite_code
|
||||
}
|
||||
if db.check_group_author(conn, groupname, current_user.username):
|
||||
if await db.check_group_author(conn, groupname, current_user.username):
|
||||
return {
|
||||
"result": db.update_group_invite_code(conn, groupname, invite_code),
|
||||
"result": await db.update_group_invite_code(conn, groupname, invite_code),
|
||||
"invite code": invite_code
|
||||
}
|
||||
else:
|
||||
@@ -184,13 +184,13 @@ async def update_invite_code(
|
||||
async def update_allow_skips(
|
||||
groupname: str,
|
||||
allow_skips: bool,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_allow_skips(conn, groupname, allow_skips)
|
||||
if db.check_group_author(conn, groupname, current_user.username):
|
||||
return db.update_group_allow_skips(conn, groupname, allow_skips)
|
||||
return await db.update_group_allow_skips(conn, groupname, allow_skips)
|
||||
if await db.check_group_author(conn, groupname, current_user.username):
|
||||
return await db.update_group_allow_skips(conn, groupname, allow_skips)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -202,13 +202,13 @@ async def update_allow_skips(
|
||||
async def update_feed_interval(
|
||||
groupname: str,
|
||||
feed_interval: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_group_feed_interval(conn, groupname, feed_interval)
|
||||
if db.check_group_author(conn, groupname, current_user.username):
|
||||
return db.update_group_feed_interval(conn, groupname, feed_interval)
|
||||
return await db.update_group_feed_interval(conn, groupname, feed_interval)
|
||||
if await db.check_group_author(conn, groupname, current_user.username):
|
||||
return await db.update_group_feed_interval(conn, groupname, feed_interval)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
+19
-19
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.memberships as db
|
||||
import settings.settings as settings
|
||||
@@ -20,18 +20,18 @@ memberships_router = APIRouter(prefix="/api/membership", tags=["memberships"])
|
||||
|
||||
@memberships_router.get("/me")
|
||||
async def read_users_groups(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
return db.get_memberships_by_username(conn, current_user.username)
|
||||
return await db.get_memberships_by_username(conn, current_user.username)
|
||||
|
||||
@memberships_router.post("/user")
|
||||
async def read_users_any_memberships(
|
||||
username: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not check_user_existence(conn, username):
|
||||
if not await check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User does not exist",
|
||||
@@ -43,35 +43,35 @@ async def read_users_any_memberships(
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
return db.get_memberships_by_username(conn, username)
|
||||
return await db.get_memberships_by_username(conn, username)
|
||||
|
||||
@memberships_router.post("/group")
|
||||
async def read_any_group_members(
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
user_is_in_group = db.check_membership_exists(conn, current_user.username, groupname)
|
||||
user_is_in_group = await db.check_membership_exists(conn, current_user.username, groupname)
|
||||
if not user_is_in_group and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
if not check_group_existence(conn, groupname):
|
||||
if not await check_group_existence(conn, groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such group",
|
||||
)
|
||||
|
||||
return db.get_memberships_by_groupname(conn, groupname)
|
||||
return await db.get_memberships_by_groupname(conn, groupname)
|
||||
|
||||
|
||||
@memberships_router.post("/add")
|
||||
async def add_membership(
|
||||
username: str,
|
||||
invite_code: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if username != current_user.username and current_user.role not in settings.settings.admin_roles:
|
||||
@@ -80,39 +80,39 @@ async def add_membership(
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
groupname = get_groupname_by_invite_code(conn, invite_code)
|
||||
groupname = await get_groupname_by_invite_code(conn, invite_code)
|
||||
if groupname is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Invite code is incorrect",
|
||||
)
|
||||
|
||||
if not check_user_existence(conn, username):
|
||||
if not await check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="User does not exist",
|
||||
)
|
||||
|
||||
if db.check_membership_exists(conn, username, groupname):
|
||||
if await db.check_membership_exists(conn, username, groupname):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User is already a member",
|
||||
)
|
||||
|
||||
return db.create_membership(conn, username, groupname)
|
||||
return await db.create_membership(conn, username, groupname)
|
||||
|
||||
@memberships_router.post("/delete")
|
||||
async def delete_membership(
|
||||
username: str,
|
||||
groupname: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_membership(conn, username, groupname)
|
||||
return await db.delete_membership(conn, username, groupname)
|
||||
|
||||
if check_group_author(conn, groupname, current_user.username):
|
||||
return db.delete_membership(conn, username, groupname)
|
||||
if await check_group_author(conn, groupname, current_user.username):
|
||||
return await db.delete_membership(conn, username, groupname)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.pictures as db
|
||||
import settings.settings as settings
|
||||
@@ -15,10 +15,10 @@ pictures_router = APIRouter(prefix="/api/pictures", tags=["pictures"])
|
||||
@pictures_router.post("/picture")
|
||||
async def read_picture(
|
||||
id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
picture_data = db.get_picture(conn, id)
|
||||
picture_data = await db.get_picture(conn, id)
|
||||
if picture_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -29,7 +29,7 @@ async def read_picture(
|
||||
|
||||
@pictures_router.post("/add")
|
||||
async def add_picture(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)],
|
||||
source: str,
|
||||
external_id: str,
|
||||
@@ -43,18 +43,18 @@ async def add_picture(
|
||||
)
|
||||
|
||||
return {
|
||||
"id": db.create_picture(conn, source, external_id, url, metadata)
|
||||
"id": await db.create_picture(conn, source, external_id, url, metadata)
|
||||
}
|
||||
|
||||
|
||||
@pictures_router.post("/delete")
|
||||
async def delete_picture(
|
||||
picture_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_picture(conn, picture_id)
|
||||
return await db.delete_picture(conn, picture_id)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
+19
-19
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.swipes as db
|
||||
import settings.settings as settings
|
||||
@@ -23,22 +23,22 @@ async def read_swipe(
|
||||
username: str,
|
||||
feed_id: int,
|
||||
picture_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
groupname = get_groupname_by_feed_id(conn, feed_id)
|
||||
groupname = await get_groupname_by_feed_id(conn, feed_id)
|
||||
if groupname is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such feed or feed is not linked to group",
|
||||
)
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
|
||||
swipe_data = db.get_swipe(conn, username, feed_id, picture_id)
|
||||
swipe_data = await db.get_swipe(conn, username, feed_id, picture_id)
|
||||
if swipe_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -51,42 +51,42 @@ async def read_swipe(
|
||||
async def read_swipes_by_picture_id(
|
||||
feed_id: int,
|
||||
picture_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
groupname = get_groupname_by_feed_id(conn, feed_id)
|
||||
groupname = await get_groupname_by_feed_id(conn, feed_id)
|
||||
if groupname is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such feed or feed is not linked to group",
|
||||
)
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
return db.get_swipes_by_picture_id(conn, picture_id, feed_id)
|
||||
return await db.get_swipes_by_picture_id(conn, picture_id, feed_id)
|
||||
|
||||
|
||||
@swipes_router.post("/swipe/user")
|
||||
async def read_user_swipes(
|
||||
username: str,
|
||||
feed_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
groupname = get_groupname_by_feed_id(conn, feed_id)
|
||||
groupname = await get_groupname_by_feed_id(conn, feed_id)
|
||||
if groupname is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such feed or feed is not linked to group",
|
||||
)
|
||||
if not check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
if not await check_membership_exists(conn, current_user.username, groupname) and current_user.role not in settings.settings.admin_roles:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
return db.get_swipes_by_user(conn, username, feed_id)
|
||||
return await db.get_swipes_by_user(conn, username, feed_id)
|
||||
|
||||
|
||||
@swipes_router.post("/add")
|
||||
@@ -94,17 +94,17 @@ async def add_swipe(
|
||||
feed_id: int,
|
||||
picture_id: int,
|
||||
value: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
groupname = get_groupname_by_feed_id(conn, feed_id)
|
||||
groupname = await get_groupname_by_feed_id(conn, feed_id)
|
||||
if groupname is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such feed or feed is not linked to group",
|
||||
)
|
||||
|
||||
group_data = get_group(conn, groupname)
|
||||
group_data = await get_group(conn, groupname)
|
||||
if group_data is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -120,7 +120,7 @@ async def add_swipe(
|
||||
detail="Skips are disallowed in the group",
|
||||
)
|
||||
|
||||
result = db.create_swipe(conn, current_user.username, feed_id, picture_id, value)
|
||||
result = await db.create_swipe(conn, current_user.username, feed_id, picture_id, value)
|
||||
if result:
|
||||
# TODO: call function to like picture on the platform
|
||||
pass
|
||||
@@ -132,11 +132,11 @@ async def delete_swipe(
|
||||
username: str,
|
||||
feed_id: int,
|
||||
picture_id: int,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_swipe(conn, username, feed_id, picture_id)
|
||||
return await db.delete_swipe(conn, username, feed_id, picture_id)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
|
||||
+22
-22
@@ -1,7 +1,7 @@
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.users as db
|
||||
import settings.settings as settings
|
||||
@@ -19,7 +19,7 @@ async def read_users_me(current_user: Annotated[User, Depends(get_current_user)]
|
||||
@users_router.post("/user")
|
||||
async def read_users_any(
|
||||
username: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role not in settings.settings.admin_roles:
|
||||
@@ -27,7 +27,7 @@ async def read_users_any(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
user_data = db.get_user(conn, username)
|
||||
user_data = await db.get_user(conn, username)
|
||||
if user_data is None:
|
||||
return HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
@@ -41,7 +41,7 @@ async def read_users_any(
|
||||
async def add_admin(
|
||||
username: str,
|
||||
password: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not settings.settings.allow_create_admins_by_admins:
|
||||
@@ -54,19 +54,19 @@ async def add_admin(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
if await db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "admin")
|
||||
return await db.create_user(conn, username, hashed_password, "admin")
|
||||
|
||||
@users_router.post("/add/user")
|
||||
async def add_user(
|
||||
username: str,
|
||||
password: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if not settings.settings.allow_create_users and current_user.role not in settings.settings.admin_roles:
|
||||
@@ -74,23 +74,23 @@ async def add_user(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Not allowed",
|
||||
)
|
||||
if db.check_user_existence(conn, username):
|
||||
if await db.check_user_existence(conn, username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="User already exists",
|
||||
)
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.create_user(conn, username, hashed_password, "user")
|
||||
return await db.create_user(conn, username, hashed_password, "user")
|
||||
|
||||
|
||||
@users_router.post("/delete")
|
||||
async def delete_user(
|
||||
username: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.username == username or current_user.role in settings.settings.admin_roles:
|
||||
return db.delete_user(conn, username)
|
||||
return await db.delete_user(conn, username)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -102,11 +102,11 @@ async def delete_user(
|
||||
async def update_disabled(
|
||||
username: str,
|
||||
disabled: bool,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_user_disabled(conn, username, disabled)
|
||||
return await db.update_user_disabled(conn, username, disabled)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -117,11 +117,11 @@ async def update_disabled(
|
||||
async def update_role(
|
||||
username: str,
|
||||
role: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.role in settings.settings.admin_roles:
|
||||
return db.update_user_role(conn, username, role)
|
||||
return await db.update_user_role(conn, username, role)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -133,16 +133,16 @@ async def update_role(
|
||||
async def update_username(
|
||||
username: str,
|
||||
new_username: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if db.check_user_existence(conn, new_username):
|
||||
if await db.check_user_existence(conn, new_username):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_409_CONFLICT,
|
||||
detail="Username is already taken",
|
||||
)
|
||||
if current_user.username == username or current_user.role in settings.settings.admin_roles:
|
||||
return db.update_user_username(conn, username, new_username)
|
||||
return await db.update_user_username(conn, username, new_username)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -153,12 +153,12 @@ async def update_username(
|
||||
async def update_password(
|
||||
username: str,
|
||||
password: str,
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
if current_user.username == username or current_user.role in settings.settings.admin_roles:
|
||||
hashed_password = get_password_hash(password)
|
||||
return db.update_user_password(conn, username, hashed_password)
|
||||
return await db.update_user_password(conn, username, hashed_password)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
@@ -168,7 +168,7 @@ async def update_password(
|
||||
|
||||
@users_router.get("/update/last_seen")
|
||||
async def update_last_seen(
|
||||
conn: Annotated[connection, Depends(get_db_connection)],
|
||||
conn: Annotated[Connection, Depends(get_db_connection)],
|
||||
current_user: Annotated[User, Depends(get_current_user)]
|
||||
):
|
||||
return db.update_user_last_seen(conn, current_user.username)
|
||||
return await db.update_user_last_seen(conn, current_user.username)
|
||||
|
||||
+9
-9
@@ -1,12 +1,12 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Annotated
|
||||
|
||||
from asyncpg import Connection
|
||||
import bcrypt
|
||||
import jwt
|
||||
from fastapi import Depends, HTTPException, status
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
from jwt.exceptions import InvalidTokenError
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.groups
|
||||
import db.users
|
||||
@@ -30,15 +30,15 @@ def encode_token(payload):
|
||||
return jwt.encode(payload, startup_settings.secret_key, algorithm=startup_settings.algorithm)
|
||||
|
||||
|
||||
def authenticate_user(
|
||||
conn: connection,
|
||||
async def authenticate_user(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
user_password: str
|
||||
):
|
||||
if not user_password:
|
||||
return False
|
||||
|
||||
db_user_password = db.users.get_user_password(conn, username)
|
||||
db_user_password = await db.users.get_user_password(conn, username)
|
||||
if db_user_password is None:
|
||||
return False
|
||||
|
||||
@@ -60,7 +60,7 @@ def create_access_token(
|
||||
|
||||
async def get_current_user(
|
||||
token: Annotated[str, Depends(oauth2_scheme)],
|
||||
conn: Annotated[connection, Depends(get_db_connection)]
|
||||
conn: Annotated[Connection, Depends(get_db_connection)]
|
||||
):
|
||||
credentials_exception = HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
@@ -77,7 +77,7 @@ async def get_current_user(
|
||||
except InvalidTokenError:
|
||||
raise credentials_exception
|
||||
|
||||
user_data = db.users.get_user(conn, token_data.username)
|
||||
user_data = await db.users.get_user(conn, token_data.username)
|
||||
if user_data is None:
|
||||
raise credentials_exception
|
||||
|
||||
@@ -92,15 +92,15 @@ async def get_current_user(
|
||||
return user
|
||||
|
||||
|
||||
def get_group_by_name(
|
||||
conn: connection,
|
||||
async def get_group_by_name(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
group_exception = HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="No such group"
|
||||
)
|
||||
group_data = db.groups.get_group(conn, groupname)
|
||||
group_data = await db.groups.get_group(conn, groupname)
|
||||
if group_data is None:
|
||||
raise group_exception
|
||||
|
||||
|
||||
+2
-1
@@ -13,7 +13,7 @@ from api.memberships import memberships_router
|
||||
from api.pictures import pictures_router
|
||||
from api.swipes import swipes_router
|
||||
from api.users import users_router
|
||||
from db.internal import connect_db, disconnect_db
|
||||
from db.internal import connect_db, disconnect_db, initialize_db
|
||||
from settings import startup_settings
|
||||
from settings.settings import settings_down, settings_up
|
||||
from settings.startup_settings import setup_settings
|
||||
@@ -41,6 +41,7 @@ def create_app():
|
||||
|
||||
app.add_event_handler("startup", setup_settings)
|
||||
app.add_event_handler("startup", connect_db)
|
||||
app.add_event_handler("startup", initialize_db)
|
||||
app.add_event_handler("startup", settings_up)
|
||||
|
||||
app.include_router(general_router)
|
||||
|
||||
+87
-101
@@ -1,14 +1,13 @@
|
||||
import json
|
||||
|
||||
import psycopg2.extras
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
from api.models import Account
|
||||
|
||||
# account create and delete
|
||||
|
||||
def create_account(
|
||||
conn: connection,
|
||||
async def create_account(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
author: str,
|
||||
platform: str,
|
||||
@@ -16,65 +15,59 @@ def create_account(
|
||||
password: str,
|
||||
metadata: dict
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.accounts
|
||||
(groupname, author, platform, login,
|
||||
password, metadata, created_at)
|
||||
values (%s, %s, %s, %s, now())
|
||||
returning id
|
||||
""",
|
||||
(groupname, author, platform, login, password, json.dumps(metadata)),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
conn.commit()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0]
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
insert into picrinth.accounts
|
||||
(groupname, author, platform, login,
|
||||
password, metadata, created_at)
|
||||
values ($1, $2, $3, $4, $5, $6, now())
|
||||
returning id
|
||||
""",
|
||||
groupname, author, platform, login, password, json.dumps(metadata),
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["id"]
|
||||
|
||||
|
||||
def delete_account(
|
||||
conn: connection,
|
||||
async def delete_account(
|
||||
conn: Connection,
|
||||
account_id: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.accounts
|
||||
where account_id = %s
|
||||
""",
|
||||
(account_id),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.accounts
|
||||
where account_id = $1
|
||||
""",
|
||||
account_id,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# account checks
|
||||
|
||||
def check_account_existence(
|
||||
conn: connection,
|
||||
async def check_account_existence(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
platform: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.accounts
|
||||
where groupname = %s and platform = %s
|
||||
);
|
||||
""",
|
||||
(groupname, platform),
|
||||
)
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.accounts
|
||||
where groupname = $1 and platform = $2
|
||||
);
|
||||
""",
|
||||
groupname, platform,
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
|
||||
# account update
|
||||
|
||||
def update_account(
|
||||
conn: connection,
|
||||
async def update_account(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
author: str,
|
||||
platform: str,
|
||||
@@ -82,73 +75,66 @@ def update_account(
|
||||
password: str,
|
||||
metadata: dict
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.accounts
|
||||
SET author = %s,
|
||||
login = %s,
|
||||
password = %s,
|
||||
metadata = %s
|
||||
where groupname = %s and platform = %s
|
||||
""",
|
||||
(author, login, password, json.dumps(metadata), groupname, platform),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.accounts
|
||||
SET author = $1,
|
||||
login = $2,
|
||||
password = $3,
|
||||
metadata = $4
|
||||
where groupname = $5 and platform = $6
|
||||
""",
|
||||
author, login, password, json.dumps(metadata), groupname, platform,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
def update_account_metadata(
|
||||
conn: connection,
|
||||
async def update_account_metadata(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
platform: str,
|
||||
metadata: dict
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.accounts
|
||||
SET metadata = %s
|
||||
where groupname = %s and platform = %s
|
||||
""",
|
||||
(json.dumps(metadata), groupname, platform),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.accounts
|
||||
SET metadata = $1
|
||||
where groupname = $2 and platform = $3
|
||||
""",
|
||||
json.dumps(metadata), groupname, platform,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
# account receiving
|
||||
|
||||
def get_accounts_by_group(
|
||||
conn: connection,
|
||||
async def get_accounts_by_group(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
) -> list[Account]:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select *
|
||||
from picrinth.accounts
|
||||
where groupname = %s
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
return [Account().fill(account_data) for (account_data,) in cur.fetchall()]
|
||||
rows = await conn.fetch(
|
||||
"""
|
||||
select *
|
||||
from picrinth.accounts
|
||||
where groupname = $1
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
return [Account().fill(account_data) for account_data in rows]
|
||||
|
||||
|
||||
def get_accounts_by_group_platform(
|
||||
conn: connection,
|
||||
async def get_accounts_by_group_platform(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
platform: str
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select groupname, author,
|
||||
platform, login, password,
|
||||
metadata, created_at
|
||||
from picrinth.accounts
|
||||
where groupname = %s and platform = %s
|
||||
""",
|
||||
(groupname, platform),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select groupname, author,
|
||||
platform, login, password,
|
||||
metadata, created_at
|
||||
from picrinth.accounts
|
||||
where groupname = $1 and platform = $2
|
||||
""",
|
||||
groupname, platform,
|
||||
)
|
||||
|
||||
+51
-61
@@ -1,83 +1,73 @@
|
||||
import psycopg2.extras
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
# feed create and delete
|
||||
|
||||
def create_feed(
|
||||
conn: connection,
|
||||
async def create_feed(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
image_ids: list[int]
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.feeds
|
||||
(groupname, image_ids, created_at)
|
||||
values (%s, %s, now())
|
||||
returning id
|
||||
""",
|
||||
(groupname, image_ids),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
conn.commit()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0]
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
insert into picrinth.feeds
|
||||
(groupname, image_ids, created_at)
|
||||
values ($1, $2, now())
|
||||
returning id
|
||||
""",
|
||||
groupname, image_ids,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["id"]
|
||||
|
||||
|
||||
def delete_feed(
|
||||
conn: connection,
|
||||
async def delete_feed(
|
||||
conn: Connection,
|
||||
feed_id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.feeds
|
||||
where id = %s
|
||||
""",
|
||||
(feed_id,),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.feeds
|
||||
where id = $1
|
||||
""",
|
||||
feed_id,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# feed receiving
|
||||
|
||||
def get_feed(
|
||||
conn: connection,
|
||||
async def get_feed(
|
||||
conn: Connection,
|
||||
feed_id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select groupname
|
||||
from picrinth.feeds
|
||||
where id = %s
|
||||
""",
|
||||
(feed_id,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select groupname
|
||||
from picrinth.feeds
|
||||
where id = $1
|
||||
""",
|
||||
feed_id,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["groupname"] # type: ignore
|
||||
|
||||
|
||||
# additional
|
||||
|
||||
def get_groupname_by_feed_id(
|
||||
conn: connection,
|
||||
async def get_groupname_by_feed_id(
|
||||
conn: Connection,
|
||||
feed_id: int
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select groupname
|
||||
from picrinth.feeds
|
||||
where id = %s
|
||||
""",
|
||||
(feed_id,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select groupname
|
||||
from picrinth.feeds
|
||||
where id = $1
|
||||
""",
|
||||
feed_id,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["groupname"] # type: ignore
|
||||
|
||||
+193
-223
@@ -1,300 +1,270 @@
|
||||
import psycopg2.extras
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
# group create and delete
|
||||
|
||||
def create_group(
|
||||
conn: connection,
|
||||
async def create_group(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
invite_code: str,
|
||||
author: str,
|
||||
allow_skips: bool = True,
|
||||
feed_interval_minutes: int = 1440,
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.groups
|
||||
(groupname, invite_code, author, allow_skips,
|
||||
feed_interval_minutes, created_at)
|
||||
values (%s, %s, %s, %s, %s, now())
|
||||
""",
|
||||
(groupname, invite_code, author, allow_skips, feed_interval_minutes),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
insert into picrinth.groups
|
||||
(groupname, invite_code, author, allow_skips,
|
||||
feed_interval_minutes, created_at)
|
||||
values ($1, $2, $3, $4, $5, now())
|
||||
""",
|
||||
groupname, invite_code, author, allow_skips, feed_interval_minutes,
|
||||
)
|
||||
return result != "INSERT 0 0"
|
||||
|
||||
|
||||
def delete_group(
|
||||
conn: connection,
|
||||
async def delete_group(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.groups
|
||||
where groupname = %s
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.groups
|
||||
where groupname = $1
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# group checks
|
||||
|
||||
def check_group_existence(
|
||||
conn: connection,
|
||||
async def check_group_existence(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.groups
|
||||
where groupname = %s
|
||||
);
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.groups
|
||||
where groupname = $1
|
||||
);
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
|
||||
def check_invite_code(
|
||||
conn: connection,
|
||||
async def check_invite_code(
|
||||
conn: Connection,
|
||||
invite_code: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.groups
|
||||
where invite_code = %s
|
||||
);
|
||||
""",
|
||||
(invite_code,),
|
||||
)
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.groups
|
||||
where invite_code = $1
|
||||
);
|
||||
""",
|
||||
invite_code,
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
|
||||
def check_group_author(
|
||||
conn: connection,
|
||||
async def check_group_author(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
author: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.groups
|
||||
where groupname = %s and author = %s
|
||||
);
|
||||
""",
|
||||
(groupname, author),
|
||||
)
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.groups
|
||||
where groupname = $1 and author = $2
|
||||
);
|
||||
""",
|
||||
groupname, author,
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
|
||||
# group updates
|
||||
|
||||
def update_group_groupname(
|
||||
conn: connection,
|
||||
async def update_group_groupname(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
new_groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set groupname = %s
|
||||
where groupname = %s
|
||||
""",
|
||||
(new_groupname, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set groupname = $1
|
||||
where groupname = $2
|
||||
""",
|
||||
new_groupname, groupname,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
def update_group_author(
|
||||
conn: connection,
|
||||
async def update_group_author(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
author: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set author = %s
|
||||
where groupname = %s
|
||||
""",
|
||||
(author, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set author = $1
|
||||
where groupname = $2
|
||||
""",
|
||||
author, groupname,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
def update_group_invite_code(
|
||||
conn: connection,
|
||||
async def update_group_invite_code(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
invite_code: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set invite_code = %s
|
||||
where groupname = %s
|
||||
""",
|
||||
(invite_code, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set invite_code = $1
|
||||
where groupname = $2
|
||||
""",
|
||||
invite_code, groupname,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
def update_group_allow_skips(
|
||||
conn: connection,
|
||||
async def update_group_allow_skips(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
allow_skips: bool
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set allow_skips = %s
|
||||
where groupname = %s
|
||||
""",
|
||||
(allow_skips, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set allow_skips = $1
|
||||
where groupname = $2
|
||||
""",
|
||||
allow_skips, groupname,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
def update_group_feed_interval(
|
||||
conn: connection,
|
||||
async def update_group_feed_interval(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
feed_interval: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set feed_interval_minutes = %s
|
||||
where groupname = %s
|
||||
""",
|
||||
(feed_interval, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set feed_interval_minutes = $1
|
||||
where groupname = $2
|
||||
""",
|
||||
feed_interval, groupname,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
def update_group_last_feed(
|
||||
conn: connection,
|
||||
async def update_group_last_feed(
|
||||
conn: Connection,
|
||||
groupname: str,
|
||||
last_feed_id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set last_feed_id = %s
|
||||
where groupname = %s
|
||||
""",
|
||||
(last_feed_id, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.groups
|
||||
set last_feed_id = $1
|
||||
where groupname = $2
|
||||
""",
|
||||
last_feed_id, groupname,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
# group receiving
|
||||
|
||||
def get_group(
|
||||
conn: connection,
|
||||
async def get_group(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select groupname, author,
|
||||
invite_code, allow_skips,
|
||||
feed_interval_minutes,
|
||||
last_feed_id, created_at
|
||||
from picrinth.groups
|
||||
where groupname = %s
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select groupname, author,
|
||||
invite_code, allow_skips,
|
||||
feed_interval_minutes,
|
||||
last_feed_id, created_at
|
||||
from picrinth.groups
|
||||
where groupname = $1
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
|
||||
|
||||
def get_group_by_invite_code(
|
||||
conn: connection,
|
||||
async def get_group_by_invite_code(
|
||||
conn: Connection,
|
||||
invite_code: str
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select groupname, author,
|
||||
invite_code, allow_skips,
|
||||
feed_interval_minutes,
|
||||
last_feed_id, created_at
|
||||
from picrinth.groups
|
||||
where invite_code = %s
|
||||
""",
|
||||
(invite_code,),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select groupname, author,
|
||||
invite_code, allow_skips,
|
||||
feed_interval_minutes,
|
||||
last_feed_id, created_at
|
||||
from picrinth.groups
|
||||
where invite_code = $1
|
||||
""",
|
||||
invite_code,
|
||||
)
|
||||
|
||||
|
||||
def get_groupname_by_invite_code(
|
||||
conn: connection,
|
||||
async def get_groupname_by_invite_code(
|
||||
conn: Connection,
|
||||
invite_code: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select groupname
|
||||
from picrinth.groups
|
||||
where invite_code = %s
|
||||
""",
|
||||
(invite_code,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0] # type: ignore
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select groupname
|
||||
from picrinth.groups
|
||||
where invite_code = $1
|
||||
""",
|
||||
invite_code,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["groupname"] # type: ignore
|
||||
|
||||
|
||||
def get_group_invite_code(
|
||||
conn: connection,
|
||||
async def get_group_invite_code(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select invite_code
|
||||
from picrinth.groups
|
||||
where groupname = %s
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0] # type: ignore
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select invite_code
|
||||
from picrinth.groups
|
||||
where groupname = $1
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["invite_code"] # type: ignore
|
||||
|
||||
def get_group_last_feed_id(
|
||||
conn: connection,
|
||||
async def get_group_last_feed_id(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select last_feed_id
|
||||
from picrinth.groups
|
||||
where groupname = %s
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0] # type: ignore
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select last_feed_id
|
||||
from picrinth.groups
|
||||
where groupname = $1
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["last_feed_id"] # type: ignore
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import asyncpg
|
||||
|
||||
|
||||
async def is_db_initialized(conn: asyncpg.Connection) -> bool:
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from information_schema.schemata
|
||||
where schema_name = 'picrinth'
|
||||
);
|
||||
""",
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
|
||||
async def initialize_db(conn: asyncpg.Connection) -> None:
|
||||
await conn.execute(
|
||||
"""
|
||||
create schema picrinth;
|
||||
|
||||
create table picrinth.users (
|
||||
id serial not null,
|
||||
username text not null,
|
||||
"password" text not null,
|
||||
"role" text not null default 'user',
|
||||
"disabled" bool not null default false,
|
||||
last_seen_at timestamp with time zone null,
|
||||
created_at timestamp with time zone default now(),
|
||||
constraint username_unique unique (username)
|
||||
);
|
||||
|
||||
create table picrinth.groups (
|
||||
id serial not null,
|
||||
groupname text not null,
|
||||
invite_code text not null,
|
||||
author text null,
|
||||
allow_skips bool not null default true,
|
||||
feed_interval_minutes integer null default 1440,
|
||||
last_feed_id int null,
|
||||
created_at timestamp with time zone default now(),
|
||||
constraint groupname_unique unique (groupname),
|
||||
constraint invite_code_unique unique (invite_code)
|
||||
);
|
||||
|
||||
create table picrinth.memberships (
|
||||
username text,
|
||||
groupname text,
|
||||
joined_at timestamp with time zone null,
|
||||
primary key (username, groupname),
|
||||
foreign key (username) references picrinth.users (username) on delete cascade on update cascade,
|
||||
foreign key (groupname) references picrinth.groups (groupname) on delete cascade on update cascade
|
||||
);
|
||||
|
||||
create table picrinth.pictures (
|
||||
id serial not null,
|
||||
source text not null,
|
||||
external_id text not null,
|
||||
"url" text not null,
|
||||
metadata jsonb null,
|
||||
created_at timestamp with time zone default now(),
|
||||
constraint pictures_pkey primary key (id),
|
||||
constraint url_unique unique (url)
|
||||
);
|
||||
|
||||
create table picrinth.feeds (
|
||||
id serial not null,
|
||||
groupname text not null,
|
||||
image_ids integer[] not null,
|
||||
created_at timestamp with time zone default now(),
|
||||
constraint feeds_pkey primary key (id),
|
||||
foreign key (groupname) references picrinth.groups (groupname) on delete cascade on update cascade,
|
||||
constraint unique_feed_per_timestamp_per_group unique (groupname, created_at)
|
||||
);
|
||||
|
||||
create table picrinth.swipes (
|
||||
id serial not null,
|
||||
username text not null,
|
||||
feed_id integer not null,
|
||||
picture_id integer not null,
|
||||
"value" smallint not null,
|
||||
created_at timestamp with time zone default now(),
|
||||
primary key (id),
|
||||
foreign key (username) references picrinth.users (username) on delete cascade on update cascade,
|
||||
foreign key (feed_id) references picrinth.feeds (id) on delete cascade on update cascade,
|
||||
foreign key (picture_id) references picrinth.pictures (id) on delete cascade on update cascade,
|
||||
constraint swipes_unique unique (username, feed_id, picture_id)
|
||||
);
|
||||
|
||||
create table picrinth.accounts (
|
||||
groupname text not null,
|
||||
author text null,
|
||||
platform text not null,
|
||||
"login" text not null,
|
||||
"password" text not null,
|
||||
metadata jsonb null,
|
||||
created_at timestamp with time zone default now(),
|
||||
foreign key (groupname) references picrinth.groups (groupname) on delete cascade on update cascade,
|
||||
-- foreign key (author) references picrinth.groups (author) on delete cascade on update cascade,
|
||||
constraint unique_account_for_group_per_platform unique (groupname, platform)
|
||||
);
|
||||
""",
|
||||
)
|
||||
+32
-11
@@ -1,17 +1,18 @@
|
||||
import sys
|
||||
|
||||
import psycopg2
|
||||
import asyncpg
|
||||
from loguru import logger
|
||||
|
||||
import db.initialization
|
||||
from db.models import database
|
||||
from settings import startup_settings
|
||||
|
||||
|
||||
def connect_db():
|
||||
async def connect_db():
|
||||
logger.info("Initializing DB connection")
|
||||
try:
|
||||
database.conn = psycopg2.connect(
|
||||
dbname=startup_settings.db_name,
|
||||
database.pool = await asyncpg.create_pool(
|
||||
database=startup_settings.db_name,
|
||||
user=startup_settings.db_user,
|
||||
password=startup_settings.db_password,
|
||||
host=startup_settings.db_host,
|
||||
@@ -23,22 +24,42 @@ def connect_db():
|
||||
logger.success("Successfully initialized DB connection")
|
||||
|
||||
|
||||
def disconnect_db():
|
||||
async def disconnect_db():
|
||||
logger.info("Closing DB connection")
|
||||
if database.conn:
|
||||
if database.pool:
|
||||
try:
|
||||
database.conn.close()
|
||||
await database.pool.close()
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to disconnect from DB: {e}")
|
||||
return
|
||||
else:
|
||||
logger.error("Failed to disconnect from DB: no connection")
|
||||
logger.error("Failed to disconnect from DB: no connection pool")
|
||||
logger.success("Successfully closed DB connection")
|
||||
|
||||
|
||||
def get_db_connection():
|
||||
if database.conn is not None:
|
||||
yield database.conn
|
||||
async def initialize_db():
|
||||
if database.pool is None:
|
||||
logger.error("No connection pool")
|
||||
sys.exit(1)
|
||||
|
||||
async with database.pool.acquire() as conn:
|
||||
try:
|
||||
if await db.initialization.is_db_initialized(conn):
|
||||
logger.success("DB already initialized, skipping setup")
|
||||
return
|
||||
else:
|
||||
logger.info("Initializing DB schema and tables")
|
||||
await db.initialization.initialize_db(conn)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to initialize DB: {e}")
|
||||
sys.exit(1)
|
||||
logger.success("Successfully initialized DB schema and tables")
|
||||
|
||||
|
||||
async def get_db_connection():
|
||||
if database.pool is not None:
|
||||
async with database.pool.acquire() as connection:
|
||||
yield connection
|
||||
else:
|
||||
logger.error("No connection pool")
|
||||
sys.exit(1)
|
||||
|
||||
+55
-64
@@ -1,92 +1,83 @@
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
# membership create and delete
|
||||
|
||||
def create_membership(
|
||||
conn: connection,
|
||||
async def create_membership(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.memberships
|
||||
(username, groupname, joined_at)
|
||||
values (%s, %s, now())
|
||||
""",
|
||||
(username, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
insert into picrinth.memberships
|
||||
(username, groupname, joined_at)
|
||||
values ($1, $2, now())
|
||||
""",
|
||||
username, groupname,
|
||||
)
|
||||
return result != "INSERT 0 0"
|
||||
|
||||
|
||||
def delete_membership(
|
||||
conn: connection,
|
||||
async def delete_membership(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.memberships
|
||||
where username = %s and groupname = %s
|
||||
""",
|
||||
(username, groupname),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.memberships
|
||||
where username = $1 and groupname = $2
|
||||
""",
|
||||
username, groupname,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# membership checks
|
||||
|
||||
def check_membership_exists(
|
||||
conn: connection,
|
||||
async def check_membership_exists(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.memberships
|
||||
where username = %s and groupname = %s
|
||||
);
|
||||
""",
|
||||
(username, groupname),
|
||||
)
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.memberships
|
||||
where username = $1 and groupname = $2
|
||||
);
|
||||
""",
|
||||
username, groupname,
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
|
||||
# membership receiving
|
||||
|
||||
def get_memberships_by_username(
|
||||
conn: connection,
|
||||
async def get_memberships_by_username(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select *
|
||||
from picrinth.memberships
|
||||
where username = %s
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
return cur.fetchall()
|
||||
return await conn.fetch(
|
||||
"""
|
||||
select *
|
||||
from picrinth.memberships
|
||||
where username = $1
|
||||
""",
|
||||
username,
|
||||
)
|
||||
|
||||
|
||||
def get_memberships_by_groupname(
|
||||
conn: connection,
|
||||
async def get_memberships_by_groupname(
|
||||
conn: Connection,
|
||||
groupname: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select *
|
||||
from picrinth.memberships
|
||||
where groupname = %s
|
||||
""",
|
||||
(groupname,),
|
||||
)
|
||||
return cur.fetchall()
|
||||
return await conn.fetch(
|
||||
"""
|
||||
select *
|
||||
from picrinth.memberships
|
||||
where groupname = $1
|
||||
""",
|
||||
groupname,
|
||||
)
|
||||
|
||||
+4
-2
@@ -1,8 +1,10 @@
|
||||
from psycopg2._psycopg import connection
|
||||
import asyncpg
|
||||
|
||||
from asyncpg import Pool
|
||||
|
||||
|
||||
class DataBase:
|
||||
conn: connection | None = None
|
||||
pool: Pool | None = None
|
||||
|
||||
|
||||
database = DataBase()
|
||||
|
||||
+46
-55
@@ -1,78 +1,69 @@
|
||||
import json
|
||||
|
||||
import psycopg2.extras
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
# picture create and delete
|
||||
|
||||
def create_picture(
|
||||
conn: connection,
|
||||
async def create_picture(
|
||||
conn: Connection,
|
||||
source: str,
|
||||
external_id: str,
|
||||
url: str,
|
||||
metadata: dict
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.pictures
|
||||
(source, external_id, url, metadata, created_at)
|
||||
values (%s, %s, %s, %s, now())
|
||||
returning id
|
||||
""",
|
||||
(source, external_id, url, json.dumps(metadata)),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
conn.commit()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0]
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
insert into picrinth.pictures
|
||||
(source, external_id, url, metadata, created_at)
|
||||
values ($1, $2, $3, $4, now())
|
||||
returning id
|
||||
""",
|
||||
source, external_id, url, json.dumps(metadata),
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["id"]
|
||||
|
||||
|
||||
def delete_picture(
|
||||
conn: connection,
|
||||
async def delete_picture(
|
||||
conn: Connection,
|
||||
id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.pictures
|
||||
where id = %s
|
||||
""",
|
||||
(id,),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.pictures
|
||||
where id = $1
|
||||
""",
|
||||
id,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# picture receiving
|
||||
|
||||
def get_picture(
|
||||
conn: connection,
|
||||
async def get_picture(
|
||||
conn: Connection,
|
||||
id: int
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select id, source,
|
||||
external_id, url,
|
||||
metadata, created_at
|
||||
from picrinth.pictures
|
||||
where id = %s
|
||||
""",
|
||||
(id,),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select id, source,
|
||||
external_id, url,
|
||||
metadata, created_at
|
||||
from picrinth.pictures
|
||||
where id = $1
|
||||
""",
|
||||
id,
|
||||
)
|
||||
|
||||
|
||||
def get_all_pictures_ids(
|
||||
conn: connection,
|
||||
async def get_all_pictures_ids(
|
||||
conn: Connection,
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select id
|
||||
from picrinth.pictures
|
||||
""",
|
||||
)
|
||||
return [element for (element,) in cur.fetchall()]
|
||||
rows = await conn.fetch(
|
||||
"""
|
||||
select id
|
||||
from picrinth.pictures
|
||||
""",
|
||||
)
|
||||
return [element["id"] for element in rows]
|
||||
|
||||
+57
-69
@@ -1,100 +1,88 @@
|
||||
import psycopg2.extras
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
# swipe create and delete
|
||||
|
||||
def create_swipe(
|
||||
conn: connection,
|
||||
async def create_swipe(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
feed_id: int,
|
||||
picture_id: int,
|
||||
value: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.swipes
|
||||
(username, feed_id, picture_id, value, created_at)
|
||||
values (%s, %s, %s, %s, now())
|
||||
returning id
|
||||
""",
|
||||
(username, feed_id, picture_id, value),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
conn.commit()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0]
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
insert into picrinth.swipes
|
||||
(username, feed_id, picture_id, value, created_at)
|
||||
values ($1, $2, $3, $4, now())
|
||||
returning id
|
||||
""",
|
||||
username, feed_id, picture_id, value,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["id"]
|
||||
|
||||
|
||||
def delete_swipe(
|
||||
conn: connection,
|
||||
async def delete_swipe(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
feed_id: int,
|
||||
picture_id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.swipes
|
||||
where username = %s and picture_id = %s and feed_id = %s
|
||||
""",
|
||||
(username, picture_id, feed_id),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.swipes
|
||||
where username = $1 and picture_id = $2 and feed_id = $3
|
||||
""",
|
||||
username, picture_id, feed_id,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# swipe receiving
|
||||
|
||||
def get_swipe(
|
||||
conn: connection,
|
||||
async def get_swipe(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
feed_id: int,
|
||||
picture_id: int
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select username,
|
||||
feed_id, picture_id,
|
||||
value, created_at
|
||||
from picrinth.swipes
|
||||
where username = %s and feed_id = %s and picture_id = %s
|
||||
""",
|
||||
(username, feed_id, picture_id),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select username,
|
||||
feed_id, picture_id,
|
||||
value, created_at
|
||||
from picrinth.swipes
|
||||
where username = $1 and feed_id = $2 and picture_id = $3
|
||||
""",
|
||||
username, feed_id, picture_id,
|
||||
)
|
||||
|
||||
|
||||
def get_swipes_by_picture_id(
|
||||
conn: connection,
|
||||
async def get_swipes_by_picture_id(
|
||||
conn: Connection,
|
||||
feed_id: int,
|
||||
picture_id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select *
|
||||
from picrinth.swipes
|
||||
where feed_id = %s and picture_id = %s
|
||||
""",
|
||||
(feed_id, picture_id),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select *
|
||||
from picrinth.swipes
|
||||
where feed_id = $1 and picture_id = $2
|
||||
""",
|
||||
feed_id, picture_id,
|
||||
)
|
||||
|
||||
def get_swipes_by_user(
|
||||
conn: connection,
|
||||
async def get_swipes_by_user(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
feed_id: int
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select *
|
||||
from picrinth.swipes
|
||||
where username = %s and feed_id = %s
|
||||
""",
|
||||
(username, feed_id),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select *
|
||||
from picrinth.swipes
|
||||
where username = $1 and feed_id = $2
|
||||
""",
|
||||
username, feed_id,
|
||||
)
|
||||
|
||||
+129
-151
@@ -1,203 +1,181 @@
|
||||
import psycopg2.extras
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
# user create and delete
|
||||
|
||||
def create_user(
|
||||
conn: connection,
|
||||
async def create_user(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
password: str,
|
||||
role: str = "user"
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
insert into picrinth.users
|
||||
(username, password, role, disabled, created_at)
|
||||
values (%s, %s, %s, false, now())
|
||||
""",
|
||||
(username, password, role),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
insert into picrinth.users
|
||||
(username, password, role, disabled, created_at)
|
||||
values ($1, $2, $3, false, now())
|
||||
""",
|
||||
username, password, role,
|
||||
)
|
||||
return result != "INSERT 0 0"
|
||||
|
||||
|
||||
def delete_user(
|
||||
conn: connection,
|
||||
async def delete_user(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
delete from picrinth.users
|
||||
where username = %s
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
delete from picrinth.users
|
||||
where username = $1
|
||||
""",
|
||||
username,
|
||||
)
|
||||
return result != "DELETE 0"
|
||||
|
||||
|
||||
# user checks
|
||||
|
||||
def check_user_existence(
|
||||
conn: connection,
|
||||
async def check_user_existence(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.users
|
||||
where username = %s
|
||||
);
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
return cur.fetchone()[0] # type: ignore
|
||||
|
||||
def check_user_disabled(
|
||||
conn: connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select disabled
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
select exists(
|
||||
select 1
|
||||
from picrinth.users
|
||||
where username = %s;
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0] # type: ignore
|
||||
where username = $1
|
||||
);
|
||||
""",
|
||||
username,
|
||||
)
|
||||
return row["exists"] # type: ignore
|
||||
|
||||
async def check_user_disabled(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select disabled
|
||||
from picrinth.users
|
||||
where username = $1;
|
||||
""",
|
||||
username,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["disabled"] # type: ignore
|
||||
|
||||
|
||||
# user updates
|
||||
|
||||
def update_user_disabled(
|
||||
conn: connection,
|
||||
async def update_user_disabled(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
disabled: bool
|
||||
):
|
||||
# if disabled = True => user is disabled
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set disabled = %s
|
||||
where username = %s
|
||||
""",
|
||||
(disabled, username),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set disabled = $1
|
||||
where username = $2
|
||||
""",
|
||||
disabled, username,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
def update_user_role(
|
||||
conn: connection,
|
||||
async def update_user_role(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
role: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set role = %s
|
||||
where username = %s
|
||||
""",
|
||||
(role, username),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set role = $1
|
||||
where username = $2
|
||||
""",
|
||||
role, username,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
def update_user_username(
|
||||
conn: connection,
|
||||
async def update_user_username(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
newUsername: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set username = %s
|
||||
where username = %s;
|
||||
""",
|
||||
(newUsername, username),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set username = $1
|
||||
where username = $2;
|
||||
""",
|
||||
newUsername, username,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
def update_user_password(
|
||||
conn: connection,
|
||||
async def update_user_password(
|
||||
conn: Connection,
|
||||
username: str,
|
||||
password: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set password = %s
|
||||
where username = %s
|
||||
""",
|
||||
(password, username),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set password = $1
|
||||
where username = $2
|
||||
""",
|
||||
password, username,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
def update_user_last_seen(
|
||||
conn: connection,
|
||||
async def update_user_last_seen(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set last_seen_at = now()
|
||||
where username = %s
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
conn.commit()
|
||||
return cur.rowcount > 0
|
||||
result = await conn.execute(
|
||||
"""
|
||||
update picrinth.users
|
||||
set last_seen_at = now()
|
||||
where username = $1
|
||||
""",
|
||||
username,
|
||||
)
|
||||
return result != "UPDATE 0"
|
||||
|
||||
|
||||
# user receiving
|
||||
|
||||
def get_user(
|
||||
conn: connection,
|
||||
async def get_user(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select username, password, role,
|
||||
disabled, last_seen_at, created_at
|
||||
from picrinth.users
|
||||
where username = %s
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
return cur.fetchone()
|
||||
return await conn.fetchrow(
|
||||
"""
|
||||
select username, password, role,
|
||||
disabled, last_seen_at, created_at
|
||||
from picrinth.users
|
||||
where username = $1
|
||||
""",
|
||||
username,
|
||||
)
|
||||
|
||||
def get_user_password(
|
||||
conn: connection,
|
||||
async def get_user_password(
|
||||
conn: Connection,
|
||||
username: str
|
||||
):
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
select password
|
||||
from picrinth.users
|
||||
where username = %s
|
||||
""",
|
||||
(username,),
|
||||
)
|
||||
result = cur.fetchone()
|
||||
if result is None:
|
||||
return None
|
||||
return result[0] # type: ignore
|
||||
result = await conn.fetchrow(
|
||||
"""
|
||||
select password
|
||||
from picrinth.users
|
||||
where username = $1
|
||||
""",
|
||||
username,
|
||||
)
|
||||
if result is None:
|
||||
return None
|
||||
return result["password"] # type: ignore
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
import db.pictures as db
|
||||
from api.models import Account, Picture
|
||||
|
||||
|
||||
def gelbooru(conn: connection, account: Account):
|
||||
async def gelbooru(conn: Connection, account: Account):
|
||||
picture = Picture(external_id = "3", url = "", metadata = {})
|
||||
picture_id = db.create_picture(conn, "gelbooru", picture.external_id, picture.url, picture.metadata)
|
||||
picture_id = await db.create_picture(conn, "gelbooru", picture.external_id, picture.url, picture.metadata)
|
||||
return picture_id
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from psycopg2._psycopg import connection
|
||||
from asyncpg import Connection
|
||||
|
||||
import db.pictures as db
|
||||
from api.models import Account, Picture
|
||||
|
||||
|
||||
def pinterest(conn: connection, account: Account):
|
||||
async def pinterest(conn: Connection, account: Account):
|
||||
picture = Picture(external_id = "1", url = "", metadata = {})
|
||||
picture_id = db.create_picture(conn, "pinterest", picture.external_id, picture.url, picture.metadata)
|
||||
picture_id = await db.create_picture(conn, "pinterest", picture.external_id, picture.url, picture.metadata)
|
||||
return picture_id
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from asyncpg import Connection
|
||||
from fastapi import HTTPException, status
|
||||
from gppt import GetPixivToken
|
||||
from loguru import logger
|
||||
from pixivpy3 import AppPixivAPI
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.pictures as db
|
||||
from api.models import Account, Picture
|
||||
@@ -10,14 +10,14 @@ from db.accounts import update_account_metadata
|
||||
|
||||
# Wrapper functions
|
||||
|
||||
def pixiv(conn: connection, account: Account) -> list[int]:
|
||||
async def pixiv(conn: Connection, account: Account) -> list[int]:
|
||||
# Getting refresh token
|
||||
refresh_token = account.metadata.get('refresh_token', '')
|
||||
if not refresh_token:
|
||||
try:
|
||||
refresh_token = get_refresh_token(account.login, account.password)
|
||||
account.metadata['refresh_token'] = refresh_token
|
||||
update_account_metadata(conn, account.groupname, account.platform, account.metadata)
|
||||
await update_account_metadata(conn, account.groupname, account.platform, account.metadata)
|
||||
except Exception as e:
|
||||
# TODO: review ruff "do not use bare `except`"
|
||||
logger.debug(f"Pixiv refresh token missing and creation failed: {e}")
|
||||
@@ -50,18 +50,18 @@ def pixiv(conn: connection, account: Account) -> list[int]:
|
||||
# Saving recommendations as Pictures to DB
|
||||
pictures_ids = []
|
||||
for picture in pictures:
|
||||
pictures_ids.append(db.create_picture(conn, "pixiv", picture.external_id, picture.url, picture.metadata))
|
||||
pictures_ids.append(await db.create_picture(conn, "pixiv", picture.external_id, picture.url, picture.metadata))
|
||||
return pictures_ids
|
||||
|
||||
|
||||
def like_picture(conn: connection, account: Account, picture_id: int):
|
||||
async def like_picture(conn: Connection, account: Account, picture_id: int):
|
||||
# Getting refresh token
|
||||
refresh_token = account.metadata.get('refresh_token', '')
|
||||
if not refresh_token:
|
||||
try:
|
||||
refresh_token = get_refresh_token(account.login, account.password)
|
||||
account.metadata['refresh_token'] = refresh_token
|
||||
update_account_metadata(conn, account.groupname, account.platform, account.metadata)
|
||||
await update_account_metadata(conn, account.groupname, account.platform, account.metadata)
|
||||
except Exception as e:
|
||||
# TODO: review ruff "do not use bare `except`"
|
||||
logger.debug(f"Pixiv refresh token missing and creation failed: {e}")
|
||||
|
||||
+10
-10
@@ -1,5 +1,5 @@
|
||||
from asyncpg import Connection
|
||||
from loguru import logger
|
||||
from psycopg2._psycopg import connection
|
||||
|
||||
import db.pictures as db
|
||||
from api.models import Account, Picture
|
||||
@@ -9,8 +9,8 @@ from scraper.pixiv import pixiv
|
||||
from settings import startup_settings
|
||||
|
||||
|
||||
def generate_feed(
|
||||
conn: connection,
|
||||
async def generate_feed(
|
||||
conn: Connection,
|
||||
accounts: list[Account]
|
||||
) -> list:
|
||||
feed = []
|
||||
@@ -20,22 +20,22 @@ def generate_feed(
|
||||
|
||||
match account.platform:
|
||||
case "pinterest":
|
||||
temp_feed = pinterest(conn, account)
|
||||
temp_feed = await pinterest(conn, account)
|
||||
feed.append(temp_feed)
|
||||
|
||||
case "pixiv":
|
||||
temp_feed = pixiv(conn, account)
|
||||
temp_feed = await pixiv(conn, account)
|
||||
feed.append(temp_feed)
|
||||
|
||||
case "gelbooru":
|
||||
temp_feed = gelbooru(conn, account)
|
||||
temp_feed = await gelbooru(conn, account)
|
||||
feed.append(temp_feed)
|
||||
|
||||
case _:
|
||||
logger.warning(f"Platform for feed generation is not supported: {account.platform}")
|
||||
|
||||
# TODO: remove mock results
|
||||
feed = db.get_all_pictures_ids(conn)
|
||||
feed = await db.get_all_pictures_ids(conn)
|
||||
return feed
|
||||
|
||||
|
||||
@@ -43,11 +43,11 @@ def generate_feed(
|
||||
def process_swipe():
|
||||
return
|
||||
|
||||
def get_picture(
|
||||
conn: connection,
|
||||
async def get_picture(
|
||||
conn: Connection,
|
||||
picture_id: int
|
||||
) -> int:
|
||||
picture_data = db.get_picture(conn, picture_id)
|
||||
picture_data = await db.get_picture(conn, picture_id)
|
||||
if picture_id is None:
|
||||
return -1
|
||||
return Picture().fill(picture_data).id
|
||||
|
||||
@@ -41,7 +41,7 @@ def settings_up():
|
||||
with open(json_path + json_settings_name, "w") as f:
|
||||
json.dump(settings.model_dump_json(), f, ensure_ascii = False, indent=4)
|
||||
logger.info("Wrote settings to the JSON")
|
||||
logger.info("Successfully configured settings")
|
||||
logger.success("Successfully configured settings")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to configure settings during startup: {e}")
|
||||
raise e
|
||||
|
||||
Reference in New Issue
Block a user