restructure static file directory

main
htylight 2023-09-10 20:21:19 +08:00
parent 9eed55164a
commit 6721ae550d
7 changed files with 105 additions and 49 deletions

View File

@ -192,3 +192,28 @@ async def delete_group_chat(group_chat_id: str, members: list[str]):
raise Exception
finally:
await session.close()
async def delete_group_chat_member(group_chat_id: str, member_id: str):
session = async_session()
try:
group_chat: GroupChat = (
await session.scalars(
select(GroupChat).where(GroupChat.id == group_chat_id)
)
).one()
group_chat.members.remove(member_id)
flag_modified(group_chat, "members")
contact: Contact = (
await session.scalars(select(Contact).where(Contact.user_id == member_id))
).one()
del contact.group_chats[group_chat_id]
flag_modified(contact, "group_chats")
session.add_all([group_chat, contact])
await session.commit()
except Exception:
raise Exception
finally:
session.close()

View File

@ -54,6 +54,7 @@ async def invite_members(member_invitation: GroupChatMembers):
@router.get("/member_name_avatar", response_model=MemberNameAvatarResponse)
async def get_member_name_avatar(group_chat_id: str, member_id: str, is_friend: bool):
res = await group_chat_crud.select_member_name_avatar(member_id, is_friend)
print(res)
data = {}
if is_friend:
if res.get(group_chat_id):
@ -66,7 +67,7 @@ async def get_member_name_avatar(group_chat_id: str, member_id: str, is_friend:
# make sure this user is still in this group chat
data["remark"] = res[2][group_chat_id]["myRemark"]
data["nickname"] = res[0]
data["avatar"] = res[1]
data["avatar"] = res[1] or ""
return {
"code": 10800,
@ -149,3 +150,13 @@ async def delete_group_chat(deletion: GroupChatMembers):
except Exception as e:
print(f"Delete Group Chat Fail With Error: {e}")
return {"code": 9999, "msg": "Server Error"}
@router.post("/quit", response_model=BaseResponseModel)
async def quit_group_chat(group_chat_id: str, member_id: str):
try:
await group_chat_crud.delete_group_chat_member(group_chat_id, member_id)
return {"code": 10800, "msg": "Quit Group Chat Successfully"}
except Exception as e:
print(f"Quit Group Chat Fail With Error: {e}")
return {"code": 9999, "msg": "Server Error"}

View File

@ -6,7 +6,7 @@ from ..utils import password
from ..utils.email_code import send_email, has_code, verify_code
from ..response_models.base import BaseResponseModel
router = APIRouter(prefix='/user_account', tags=['user_account'])
router = APIRouter(prefix="/user_account", tags=["user_account"])
class ChangedAccount(BaseModel):
@ -17,58 +17,71 @@ class ChangedAccount(BaseModel):
code: str | None = None
@router.post('/change/username', response_model=BaseResponseModel)
@router.post("/change/username", response_model=BaseResponseModel)
async def change_username(changed_account: ChangedAccount):
is_existed, user = await user_crud.select_account_by('username', changed_account.username)
is_existed, user = await user_crud.select_account_by(
"username", changed_account.username
)
if is_existed:
return {'code': 10401, 'msg': f'This Username ({changed_account.username}) Has Been Used'}
return {
"code": 10401,
"msg": f"This Username ({changed_account.username}) Has Been Used",
}
await user_crud.update_account('username', changed_account.id, changed_account.username)
await user_crud.update_account(
"username", changed_account.id, changed_account.username
)
return {'code': 10400, 'msg': 'Update Username Successfully'}
return {"code": 10400, "msg": "Update Username Successfully"}
@router.get('/get/email_code', response_model=BaseResponseModel)
@router.get("/get/email_code", response_model=BaseResponseModel)
async def get_change_email_code(email: str, background_tasks: BackgroundTasks):
is_existed, _ = await user_crud.select_account_by('email', email)
is_existed, _ = await user_crud.select_account_by("email", email)
if is_existed:
return {'code': 10401, 'msg': f'This Email ({email}) Has Been Used'}
return {"code": 10401, "msg": f"This Email ({email}) Has Been Used"}
if has_code(email):
return {'code': 10402, 'msg': f'Code of Email ({email}) Is Still Available'}
return {"code": 10402, "msg": f"Code of Email ({email}) Is Still Available"}
background_tasks.add_task(send_email, email)
return {'code': 10400, 'msg': 'Send Verification Code Successfully'}
return {"code": 10400, "msg": "Send Verification Code Successfully"}
@router.post('/change/email', response_model=BaseResponseModel)
@router.post("/change/email", response_model=BaseResponseModel)
async def change_email(changed_account: ChangedAccount):
is_correct = verify_code(changed_account.email, changed_account.code)
if not is_correct:
return {'code': 10403, 'msg': f'Email Code ({changed_account.code}) Is Not Correct'}
return {
"code": 10403,
"msg": f"Email Code ({changed_account.code}) Is Not Correct",
}
await user_crud.update_account('email', changed_account.id, changed_account.email)
await user_crud.update_account("email", changed_account.id, changed_account.email)
return {'code': 10400, 'msg': 'Update Email Successfully'}
return {"code": 10400, "msg": "Update Email Successfully"}
@router.get('/get/password_code', response_model=BaseResponseModel)
@router.get("/get/password_code", response_model=BaseResponseModel)
async def get_change_password_code(email: str, background_tasks: BackgroundTasks):
if has_code(email):
return {'code': 10402, 'msg': f'Code of Email ({email}) Is Still Available'}
return {"code": 10402, "msg": f"Code of Email ({email}) Is Still Available"}
background_tasks.add_task(send_email, email)
return {'code': 10400, 'msg': 'Send Verification Code Successfully'}
return {"code": 10400, "msg": "Send Verification Code Successfully"}
@router.post('/change/password', response_model=BaseResponseModel)
@router.post("/change/password", response_model=BaseResponseModel)
async def change_password(changed_account: ChangedAccount):
is_correct = verify_code(changed_account.email, changed_account.code)
if not is_correct:
return {'code': 10403, 'msg': f'Email Code ({changed_account.code}) Is Not Correct'}
return {
"code": 10403,
"msg": f"Email Code ({changed_account.code}) Is Not Correct",
}
hashed_password = password.get_hashed_password(changed_account.password)
await user_crud.update_account('password', changed_account.id, hashed_password)
await user_crud.update_account("password", changed_account.id, hashed_password)
return {'code': 10400, 'msg': 'Update Email Successfully'}
return {"code": 10400, "msg": "Update Email Successfully"}

View File

@ -48,13 +48,13 @@ async def get_profile(id: str):
@router.get("/avatar")
async def download_avatar(avatar_filename: str):
avatar_dir_path = static_file.create_dir("avatars")
return FileResponse(avatar_dir_path / avatar_filename)
user_avatar_dir_path = static_file.create_avatar_dir("user", "avatars")
return FileResponse(user_avatar_dir_path / avatar_filename)
@router.post("/change/avatar", response_model=UserAvatarResponse)
async def change_avatar(id: str, file: Uint8List):
avatar_dir_path = static_file.create_dir("avatars")
avatar_dir_path = static_file.create_avatar_dir("user", "avatars")
avatar_filename = static_file.create_avatar_filename()
async with await open_file(avatar_dir_path / avatar_filename, "wb") as f:

View File

@ -29,7 +29,7 @@ def send_email(to: str):
msg = EmailMessage()
connect_email_server()
msg["Subject"] = "Together app signup verification code"
msg["From"] = "TogetherApp <together_app@outlook.com>"
msg["From"] = f"TogetherApp <{username}>"
msg["To"] = f"<{to}>"
email_content = f"""\

View File

@ -35,11 +35,17 @@ alphabet = [
]
def create_dir(dir_name: str) -> Path:
avatar_dir_path = Path(os.getcwd()) / "static" / dir_name
if not avatar_dir_path.exists():
avatar_dir_path.mkdir()
return avatar_dir_path
def create_avatar_dir(type: Literal["user", "group_chat"], dir_name: str) -> Path:
if type == "user":
avatar_dir_path = Path(os.getcwd()) / "static" / dir_name / "user"
if not avatar_dir_path.exists():
avatar_dir_path.mkdir()
return avatar_dir_path
else:
avatar_dir_path = Path(os.getcwd()) / "static" / dir_name / "group_chat"
if not avatar_dir_path.exists():
avatar_dir_path.mkdir()
return avatar_dir_path
def create_avatar_filename() -> str:

View File

@ -6,10 +6,10 @@ from fastapi.security import OAuth2PasswordBearer
from jose import jwt, ExpiredSignatureError, JWTError
# openssl rand -hex 32
SECRET_KEY = '1c3c03b79d084f0c7b41ba11d1d9a4979f72d9fc6eaaaa0a855065e8a5be0468'
ALGORITHM = 'HS256'
SECRET_KEY = "1c3c03b79d084f0c7b41ba11d1d9a4979f72d9fc6eaaaa0a855065e8a5be0468"
ALGORITHM = "HS256"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl='token')
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
class SigninClaim(TypedDict):
@ -22,33 +22,34 @@ class SigninClaim(TypedDict):
def create_signin_token(id: str, device_id: str) -> str:
claim: SigninClaim = {
'sub': id,
'iss': 'together',
'iat': datetime.now().timestamp(),
'exp': (datetime.now() + timedelta(days=23)).timestamp(),
'device_id': device_id,
"sub": id,
"iss": "together",
"iat": datetime.now().timestamp(),
"exp": (datetime.now() + timedelta(days=23)).timestamp(),
"device_id": device_id,
}
return jwt.encode(claim, SECRET_KEY, algorithm=ALGORITHM)
def verify_signin_token(token) -> Tuple[str | None, str]:
def verify_signin_token(token: str) -> Tuple[str | None, str]:
try:
claim: SigninClaim = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
if claim['exp'] - datetime.now().timestamp() <= 10*24*60*60:
new_token = _prolong_token(token)
return new_token, claim['sub']
print(claim["sub"])
if claim["exp"] - datetime.now().timestamp() <= 10 * 24 * 60 * 60:
new_token = _prolong_token(claim)
return new_token, claim["sub"]
else:
return None, claim['sub']
return None, claim["sub"]
except ExpiredSignatureError:
print(f'{token} expire ========================')
print(f"{token} expire ========================")
raise ExpiredSignatureError
except JWTError:
print(f'This token {token} is not sign by me ==========================')
print(f"This token {token} is not sign by me ==========================")
raise JWTError
def _prolong_token(claim: SigninClaim) -> str:
claim['iat'] = datetime.now().timestamp()
claim['exp'] = (datetime.now() + timedelta(days=30)).timestamp()
claim["iat"] = datetime.now().timestamp()
claim["exp"] = (datetime.now() + timedelta(days=30)).timestamp()
token = jwt.encode(claim, SECRET_KEY, algorithm=ALGORITHM)
return token