sms.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. from typing import Annotated
  2. import datetime
  3. from uuid import UUID
  4. from fastapi import APIRouter, Depends, HTTPException, Query
  5. from sqlalchemy import delete, select
  6. from sqlalchemy.orm import Session
  7. from app.api import deps
  8. from app.api.utils import update_object_from_payload
  9. from app.models import (
  10. Project,
  11. Sms,
  12. User,
  13. )
  14. from app.schemas.requests import SmsCreateRequest, SmsUpdateRequest
  15. from app.schemas.responses import SMSResponse
  16. router = APIRouter()
  17. @router.get("/project/{project_id}/sms", response_model=list[SMSResponse])
  18. async def list_project_sms(
  19. project_id: UUID,
  20. current_user: User = Depends(deps.get_current_user),
  21. session: Session = Depends(deps.get_session),
  22. ):
  23. """List sms from project"""
  24. p = session.get(Project, project_id)
  25. if p is None:
  26. raise HTTPException(status_code=404, detail="Project not found")
  27. results = session.execute(select(Sms).where(Sms.project_id == project_id))
  28. return results.scalars().all()
  29. @router.post("/project/{project_id}/sms", response_model=SMSResponse)
  30. async def create_sms(
  31. project_id: UUID,
  32. new_sms: SmsCreateRequest,
  33. current_user: User = Depends(deps.get_current_user),
  34. session: Session = Depends(deps.get_session),
  35. ):
  36. """Create a new to the project"""
  37. p = session.get(Project, project_id)
  38. if p is None:
  39. raise HTTPException(status_code=404, detail="Project not found")
  40. sms = Sms(project_id=project_id, **new_sms.model_dump())
  41. session.add(sms)
  42. session.commit()
  43. return sms
  44. @router.post("/project/{project_id}/sms/{sms_id}", response_model=SMSResponse)
  45. async def update_sms(
  46. project_id: UUID,
  47. sms_id: UUID,
  48. new_sms: SmsUpdateRequest,
  49. current_user: User = Depends(deps.get_current_user),
  50. session: Session = Depends(deps.get_session),
  51. ):
  52. """Update an sms from the project"""
  53. sms = session.get(Sms, sms_id)
  54. if (sms is None) or (sms.project_id != str(project_id)):
  55. raise HTTPException(status_code=404, detail="Sms not found")
  56. update_object_from_payload(sms, new_sms.model_dump(exclude_unset=True))
  57. session.commit()
  58. session.refresh(sms)
  59. return sms
  60. @router.delete("/project/{project_id}/sms/{sms_id}")
  61. async def delete_sms(
  62. project_id: UUID,
  63. sms_id: UUID,
  64. current_user: User = Depends(deps.get_current_user),
  65. session: Session = Depends(deps.get_session),
  66. ):
  67. """Delete a sms from the project"""
  68. session.execute(delete(Sms).where((Sms.id == sms_id) & (Sms.project_id == str(project_id))))
  69. session.commit()
  70. @router.get("/sms/to-send", response_model=list[SMSResponse])
  71. async def list_sms_to_send(
  72. current_user: User = Depends(deps.get_current_user),
  73. session: Session = Depends(deps.get_session),
  74. max_delay: Annotated[
  75. int | None, Query(description="the maximum delay a sms should be send with")
  76. ] = 10,
  77. ):
  78. """List sms that should be send by now"""
  79. now = datetime.datetime.now()
  80. min_sending_time = now - datetime.timedelta(minutes=max_delay)
  81. results = session.execute(
  82. select(Sms).where(
  83. (Sms.sending_time > min_sending_time)
  84. & (Sms.sending_time < now)
  85. & (Sms.send_time == None) # noqa: E711
  86. )
  87. )
  88. return results.scalars().all()
  89. @router.post("/sms/send-now/{sms_id}", response_model=SMSResponse)
  90. async def send_sms_now(
  91. sms_id: UUID,
  92. current_user: User = Depends(deps.get_current_user),
  93. session: Session = Depends(deps.get_session),
  94. ):
  95. """Update the SMS to be sent now"""
  96. sms = session.get(Sms, sms_id)
  97. if sms is None:
  98. raise HTTPException(status_code=404, detail="SMS not found")
  99. elif sms.send_time is not None:
  100. raise HTTPException(status_code=400, detail="SMS has already been sent")
  101. else:
  102. sms.send_time = datetime.datetime.now()
  103. session.commit()
  104. return sms
  105. @router.get("/sms/not-send", response_model=list[SMSResponse])
  106. async def list_not_sent(
  107. current_user: User = Depends(deps.get_current_user),
  108. session: Session = Depends(deps.get_session),
  109. ):
  110. """List sms that are not sent"""
  111. results = session.execute(select(Sms).where((Sms.send_time == None))) # noqa: E711
  112. return results.scalars().all()
  113. @router.get("/sms/future", response_model=list[SMSResponse])
  114. async def list_future_sms(
  115. current_user: User = Depends(deps.get_current_user),
  116. session: Session = Depends(deps.get_session),
  117. ):
  118. """List sms that should be sent in the future"""
  119. results = session.execute(select(Sms).where(Sms.sending_time > datetime.datetime.now()))
  120. return results.scalars().all()