Browse Source

Merge branch 'master' of http://gitlab.jaquin.fr/clovis/bdlg2023-sms-back

tripeur 2 years ago
parent
commit
5703ceebbd
9 changed files with 101 additions and 22 deletions
  1. 3 0
      .env.example
  2. 4 1
      .gitignore
  3. 1 1
      app/api/endpoints/sms.py
  4. 3 0
      app/core/config.py
  5. 42 0
      app/create_sms_batch.py
  6. 3 7
      app/initial_data.py
  7. 13 2
      script/KdeConnect.py
  8. 6 3
      script/run.sh
  9. 26 8
      script/send_sms.py

+ 3 - 0
.env.example

@@ -17,5 +17,8 @@ TEST_DATABASE_PASSWORD=ywRCUjJijmQoBmWxIfLldOoITPzajPSNvTvHyugQoSqGwNcvQE
 TEST_DATABASE_PORT=37270
 TEST_DATABASE_DB=test_db
 
+
+BATCH_SMS_PHONE_NUMBER="01 10 10 10 10"
+
 FIRST_SUPERUSER_EMAIL=example@example.com
 FIRST_SUPERUSER_PASSWORD=OdLknKQJMUwuhpAVHvRC

+ 4 - 1
.gitignore

@@ -133,4 +133,7 @@ venv.bak/
 dmypy.json
 
 # Pyre type checker
-.pyre/
+.pyre/
+
+# script log
+log.txt

+ 1 - 1
app/api/endpoints/sms.py

@@ -92,7 +92,7 @@ async def list_sms_to_send(
     return results.scalars().all()
 
 
-@router.get("/sms/send-now/{sms_id}", response_model=SMSResponse)
+@router.post("/sms/send-now/{sms_id}", response_model=SMSResponse)
 async def send_sms_now(
     sms_id: UUID,
     current_user: User = Depends(deps.get_current_user),

+ 3 - 0
app/core/config.py

@@ -63,6 +63,9 @@ class Settings(BaseSettings):
     TEST_DATABASE_DB: str = "postgres"
     TEST_SQLALCHEMY_DATABASE_URI: str = ""
 
+    # SMS batch
+    BATCH_SMS_PHONE_NUMBER: str = ""
+
     # FIRST SUPERUSER
     FIRST_SUPERUSER_EMAIL: EmailStr
     FIRST_SUPERUSER_PASSWORD: str

+ 42 - 0
app/create_sms_batch.py

@@ -0,0 +1,42 @@
+"""
+
+"""
+
+from sqlalchemy import select
+from datetime import datetime, timedelta
+from app.core import config, security
+from app.core.session import session
+from app.models import User, Sms, Project
+
+TEST_SMS_PROJECT_NAME = "test_project pour sms"
+NUMBER_OF_SMS = 100
+
+
+def main() -> None:
+    print("Create SMS ")
+    with session() as db:
+        # Get or create the project hosting the sms
+        result = db.execute(select(Project).where(Project.name == TEST_SMS_PROJECT_NAME))
+        project = result.scalars().first()
+        if project is None:
+            project = Project(name=TEST_SMS_PROJECT_NAME, is_public=False)
+            db.add(project)
+            db.commit()
+            db.refresh(project)
+
+        now = datetime.now()
+
+        for t in range(NUMBER_OF_SMS):
+            sending_time = now + timedelta(minutes=t * 5)
+            sms = Sms(
+                project_id=project.id,
+                content=sending_time.strftime("%m/%d/%Y, %H:%M:%S"),
+                phone_number=config.settings.BATCH_SMS_PHONE_NUMBER,
+                sending_time=sending_time,
+            )
+            db.add(sms)
+        db.commit()
+
+
+if __name__ == "__main__":
+    main()

+ 3 - 7
app/initial_data.py

@@ -5,8 +5,6 @@ It is included in `init.sh` script.
 By defualt `main` create a superuser if not exists
 """
 
-import asyncio
-
 from sqlalchemy import select
 
 from app.core import config, security
@@ -14,12 +12,10 @@ from app.core.session import session
 from app.models import User
 
 
-async def main() -> None:
+def main() -> None:
     print("Start initial data")
     with session() as db:
-        result = db.execute(
-            select(User).where(User.email == config.settings.FIRST_SUPERUSER_EMAIL)
-        )
+        result = db.execute(select(User).where(User.email == config.settings.FIRST_SUPERUSER_EMAIL))
         user = result.scalars().first()
 
         if user is None:
@@ -39,4 +35,4 @@ async def main() -> None:
 
 
 if __name__ == "__main__":
-    asyncio.run(main())
+    main()

+ 13 - 2
script/KdeConnect.py

@@ -1,4 +1,5 @@
 import subprocess
+import logging
 import re
 
 from pydantic import BaseModel
@@ -64,9 +65,17 @@ class KDEConnect:
         command: list[str] = ["kdeconnect-cli"]
         command.extend(args)
         process: CompletedProcess = subprocess.run(command, capture_output=True)
+
+        subprocess_response = process.stdout.decode("utf-8")
+        logging.debug("Subprocess call : \n>> " + " ".join(command) + "\n" + subprocess_response)
         if process.stderr != b"":
-            print(f"[Err] {process.stderr.decode('utf-8')}")
-        return process.stdout.decode("utf-8")
+            error_msg: str = process.stderr.decode("utf-8")
+            if error_msg.endswith("devices found\n"):
+                logging.info(error_msg)
+            else:
+                raise KDEConnectError(error_msg)
+
+        return subprocess_response
 
     @staticmethod
     def get_device_list() -> list[KDEDevice]:
@@ -75,6 +84,8 @@ class KDEConnect:
         output: list[KDEDevice] = []
         device_entries: list[str] = KDEConnect.run_kde_command(["-l"]).strip().split("\n")
         for device_str in device_entries:
+            if device_str == "":
+                continue
             result = re.search("^- ([^:]+): ([a-z0-9_]{36})", device_str)
             reachable = "reachable" in device_str
             paired = "paired" in device_str

+ 6 - 3
script/run.sh

@@ -1,8 +1,11 @@
 #!/usr/bin/env bash
 
+cd /home/clovis/Documents/bdlg2023-sms-back
+
+source venv/bin/activate
+
 set -a
-source .env
+source script/.env
 set +a
 
-cd ..
-python3 send_sms.py
+python3 -m script.send_sms

+ 26 - 8
script/send_sms.py

@@ -1,6 +1,8 @@
 import os
+import logging
+import time
 import requests
-from KdeConnect import KDEConnect
+from .KdeConnect import KDEConnect
 
 from app.schemas.responses import AccessTokenResponse, SMSResponse
 
@@ -8,24 +10,27 @@ from app.schemas.responses import AccessTokenResponse, SMSResponse
 def send_sms_from_api(url: str, login: str, pwd: str, device_name: str):
     """Connect to sms-server API to retreieve sms to be send and send them using kdeconnect-cli"""
     # Log in to API get access token
-    response = requests.get(
+    response = requests.post(
         url + "/auth/access-token",
         data={"grant_type": "password", "username": login, "password": pwd},
     )
-    authentication: AccessTokenResponse = response.json()
+    authentication = AccessTokenResponse.parse_raw(response.content)
     headers = {"Authorization": "Bearer " + authentication.access_token}
 
     # List SMS to be send
     response = requests.get(url + "/sms/to-send", headers=headers)
-    sms_list: list[SMSResponse] = response.json()
-
+    sms_list: list[SMSResponse] = [SMSResponse.parse_obj(obj) for obj in response.json()]
+    logging.info(f"{len(sms_list):5} SMS a envoyer")
     # Init KDE Connect
     kde = KDEConnect(device_name=device_name)
 
     # send sms & update api
     for sms in sms_list:
-        kde.send_sms(sms.phone_number, sms.content)
-        requests.get(url + "/sms/sent-now/" + sms.id, headers=headers)
+        try:
+            kde.send_sms(sms.phone_number, sms.content)
+            requests.post(url + "/sms/send-now/" + sms.id, headers=headers)
+        except Exception as exc:
+            logging.warning(f"Echec lors de l'envoie du sms {sms.id}\n{str(exc)}")
 
 
 class InvalidEnvironnementVariable(Exception):
@@ -49,4 +54,17 @@ def main():
 
 
 if __name__ == "__main__":
-    main()
+    logging.basicConfig(
+        format="%(asctime)s %(levelname)s - %(message)s",
+        level=logging.DEBUG,
+        filemode="a",
+        filename="log.txt",
+    )
+    while True:
+        starting_time = time.time()
+        try:
+            main()
+        except Exception as e:
+            logging.exception("An error as occured : ")
+        elapsed_time = time.time() - starting_time
+        time.sleep(300 - elapsed_time)