1 Commits

Author SHA1 Message Date
Laurent Chedanne b5c84635cf Code changes for sql-to-api branch 2026-05-29 10:40:34 +02:00
8 changed files with 40 additions and 262 deletions
+1 -2
View File
@@ -1,4 +1,3 @@
env/*
config.json
config.json.*
csv/*
config.json.orig
+2 -9
View File
@@ -20,8 +20,7 @@ import csv
import calendar
from datetime import date, datetime, timezone
import pytz
from urllib.parse import unquote
import re
class EventRow():
@@ -171,7 +170,7 @@ def get_all_events(config, calendars_find):
elif field == "LOCATION":
event_row.set_location(event_field[1])
elif field == "DESCRIPTION":
event_row.set_description(clean_description(event_field[1]))
event_row.set_description(event_field[1])
event_rows.append(event_row)
sorted_rows = sorted(event_rows, key=lambda l: datetime.strptime(str(l.start_date)+'T'+str(l.start_time), "%Y-%m-%dT%H:%M:%S"))
@@ -180,12 +179,6 @@ def get_all_events(config, calendars_find):
return calendars_to_write
def clean_description(value):
if value.startswith("text/html,"):
value = value[len("text/html,"):]
value = unquote(value)
value = re.sub(r'<[^>]+>', '', value)
return value.strip().strip('"')
def write_csv(filename, rows):
"""Write CSV file"""
+37 -10
View File
@@ -139,10 +139,13 @@ def get_client_uuid_by_name(client_name, user_id):
query = ("select uuid from oc_timemanager_client where name=\""+client_name+"\" AND user_id=\""+user_id+"\"")
cursor.execute(query)
client_uuid = cursor.fetchone()[0]
row = cursor.fetchone()
save_db()
return client_uuid.decode('utf-8')
if not row:
return None
return row[0].decode('utf-8')
def get_project_uuid_by_name(project_name, client_uuid, user_id):
@@ -264,7 +267,6 @@ def create_project(name, client_uuid):
#print(json.dumps(response.json(), indent=1))
else:
print("Erreur de création project")
print(response)
print(response.reason)
def create_client(name):
@@ -312,15 +314,28 @@ def create_client(name):
}
response = requests.post(url, data=json.dumps(req_data), headers=headers)
# Vérification de la réponse
if response.status_code == 200:
pass
#print("Client créé avec succès.")
#print(json.dumps(response.json(), indent=1))
try:
resp = response.json()
# Tenter d'extraire l'UUID renvoyé par l'API (structure attendue)
client_uuid = None
if isinstance(resp, dict):
client_created = resp.get('data', {}).get('clients', {}).get('created', [])
if client_created and isinstance(client_created, list):
client_uuid = client_created[0].get('uuid')
if client_uuid:
return client_uuid
# si pas d'uuid dans la réponse, retourner None (le caller gérera)
return None
except Exception:
return None
else:
print("Erreur de création client")
print(response.reason)
return None
def insert_task_time(name, project_name, client_name, task_uuid, user_id, dstart, hstart, dend, hend):
@@ -423,11 +438,23 @@ for user_info in config['calendars']:
continue
# Description => Client
client_uuid = None
if not client_exist_by_name(client_name, user_id):
print("Création du client {}".format(client_name))
create_client(client_name)
client_uuid = get_client_uuid_by_name(client_name, user_id)
created_uuid = create_client(client_name)
if created_uuid:
client_uuid = created_uuid
else:
# tentative de récupération depuis la base au cas où l'API a créé l'entrée
client_uuid = get_client_uuid_by_name(client_name, user_id)
if not client_uuid:
print("Erreur: impossible d'obtenir l'UUID du client '{}' après création, saut.".format(client_name))
continue
else:
client_uuid = get_client_uuid_by_name(client_name, user_id)
if not client_uuid:
print("Erreur: le client '{}' existe mais son UUID est introuvable, saut.".format(client_name))
continue
# Categories => Project
if not project_exist_by_name(project_name, client_uuid, user_id):
-2
View File
@@ -23,8 +23,6 @@ Chaque entrée doit contenir au minimum :
- `user_name` : login Nextcloud utilisé pour authentifier les requêtes,
- `api_password` : mot de passe ou mot de passe d'application Nextcloud.
> Il est important de générer la clé API en s'étant connecté avec l'identifiant et non l'email car le script user_name utilise le champ "user_name" pour faire des vérifications en bases de données avant d'ajouter des données.
Colonnes CSV utilisées
----------------------
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
source env/bin/activate
python3 remove-users-data-timemanager.py $1
-116
View File
@@ -1,116 +0,0 @@
import csv
import requests
import json
import uuid
import re
import base64
import sys
import mysql.connector
from unidecode import unidecode
##########################################
# Config
##########################################
# Récupération de la config
with open('config.json', 'r') as f:
config = json.load(f)
mydb = mysql.connector.connect(
host=config['db_host'],
user=config['db_user'],
password=config['db_password'],
database=config['db_database']
)
cursor = mydb.cursor(buffered=True)
# Argument --yes pour auto-valider toutes les suppressions
valid_args = {'-y', '--yes'}
extra_args = [arg for arg in sys.argv[1:] if arg not in valid_args]
if extra_args:
print(f"Erreur : argument(s) non reconnu(s) : {' '.join(extra_args)}")
print(f"Usage : python {sys.argv[0]} [--yes | -y]")
sys.exit(1)
auto_confirm = bool(set(sys.argv[1:]) & valid_args)
##########################################
# Fonctions
##########################################
def check_users_exist(user_id):
"""Vérifie si l'utilisateur existe dans oc_users."""
cursor.execute("SELECT uid FROM oc_users WHERE uid = %s", (user_id,))
return cursor.fetchone() is not None
def remove_row_on_table_for_user(user_id, table):
"""Supprime toutes les entrées d'une table pour un utilisateur donné."""
query = f"DELETE FROM `{table}` WHERE user_id = %s"
cursor.execute(query, (user_id,))
affected = cursor.rowcount
mydb.commit()
print(f" [{table}] {affected} ligne(s) supprimée(s)")
##########################################
# Main
##########################################
tables = [
"oc_timemanager_client",
"oc_timemanager_commit",
"oc_timemanager_project",
"oc_timemanager_task",
"oc_timemanager_time"
]
# Listing de tous les utilisateurs configurés avant toute action
print("==========================================")
print("Utilisateurs configurés dans config.json :")
print("==========================================")
valid_users = []
for user_info in config['calendars']:
user_id = user_info.get('user_name', '')
if not user_id:
print(f" ⚠ [{user_id or '???'}] — infos de connexion incomplètes, ignoré")
continue
exists = check_users_exist(user_id)
status = "✔ existe en BDD" if exists else "✘ introuvable en BDD"
print(f"{user_id}{status}")
if exists:
valid_users.append(user_info)
print()
if not valid_users:
print("Aucun utilisateur valide à traiter. Fin du script.")
cursor.close()
mydb.close()
sys.exit(0)
if auto_confirm:
print("Mode auto-confirmation activé (--yes) : toutes les suppressions seront effectuées sans demande.\n")
# Traitement par utilisateur
for user_info in valid_users:
user_id = user_info['user_name']
print("==========================================")
print(f"User : {user_id}")
print("==========================================")
if auto_confirm:
confirmed = True
else:
reponse = input(f"\nSupprimer toutes les données TimeManager de '{user_id}' ? [o/N] : ").strip().lower()
confirmed = reponse in ('o', 'oui', 'y', 'yes')
if confirmed:
print("Suppression en cours...")
for table in tables:
remove_row_on_table_for_user(user_id, table)
print(f"✔ Données de '{user_id}' supprimées.\n")
else:
print(f"✘ Suppression annulée pour '{user_id}'.\n")
cursor.close()
mydb.close()
print("Terminé.")
-116
View File
@@ -1,116 +0,0 @@
import csv
import requests
import json
import uuid
import re
import base64
import sys
import mysql.connector
from unidecode import unidecode
##########################################
# Config
##########################################
# Récupération de la config
with open('config.json', 'r') as f:
config = json.load(f)
mydb = mysql.connector.connect(
host=config['db_host'],
user=config['db_user'],
password=config['db_password'],
database=config['db_database']
)
cursor = mydb.cursor(buffered=True)
# Argument --yes pour auto-valider toutes les suppressions
valid_args = {'-y', '--yes'}
extra_args = [arg for arg in sys.argv[1:] if arg not in valid_args]
if extra_args:
print(f"Erreur : argument(s) non reconnu(s) : {' '.join(extra_args)}")
print(f"Usage : python {sys.argv[0]} [--yes | -y]")
sys.exit(1)
auto_confirm = bool(set(sys.argv[1:]) & valid_args)
##########################################
# Fonctions
##########################################
def check_users_exist(user_id):
"""Vérifie si l'utilisateur existe dans oc_users."""
cursor.execute("SELECT uid FROM oc_users WHERE uid = %s", (user_id,))
return cursor.fetchone() is not None
def remove_row_on_table_for_user(user_id, table):
"""Supprime toutes les entrées d'une table pour un utilisateur donné."""
query = f"DELETE FROM `{table}` WHERE user_id = %s"
cursor.execute(query, (user_id,))
affected = cursor.rowcount
mydb.commit()
print(f" [{table}] {affected} ligne(s) supprimée(s)")
##########################################
# Main
##########################################
tables = [
"oc_timemanager_client",
"oc_timemanager_commit",
"oc_timemanager_project",
"oc_timemanager_task",
"oc_timemanager_time"
]
# Listing de tous les utilisateurs configurés avant toute action
print("==========================================")
print("Utilisateurs configurés dans config.json :")
print("==========================================")
valid_users = []
for user_info in config['calendars']:
user_id = user_info.get('user_name', '')
if not user_id:
print(f" ⚠ [{user_id or '???'}] — infos de connexion incomplètes, ignoré")
continue
exists = check_users_exist(user_id)
status = "✔ existe en BDD" if exists else "✘ introuvable en BDD"
print(f"{user_id}{status}")
if exists:
valid_users.append(user_info)
print()
if not valid_users:
print("Aucun utilisateur valide à traiter. Fin du script.")
cursor.close()
mydb.close()
sys.exit(0)
if auto_confirm:
print("Mode auto-confirmation activé (--yes) : toutes les suppressions seront effectuées sans demande.\n")
# Traitement par utilisateur
for user_info in valid_users:
user_id = user_info['user_name']
print("==========================================")
print(f"User : {user_id}")
print("==========================================")
if auto_confirm:
confirmed = True
else:
reponse = input(f"\nSupprimer toutes les données TimeManager de '{user_id}' ? [o/N] : ").strip().lower()
confirmed = reponse in ('o', 'oui', 'y', 'yes')
if confirmed:
print("Suppression en cours...")
for table in tables:
remove_row_on_table_for_user(user_id, table)
print(f"✔ Données de '{user_id}' supprimées.\n")
else:
print(f"✘ Suppression annulée pour '{user_id}'.\n")
cursor.close()
mydb.close()
print("Terminé.")
-3
View File
@@ -1,3 +0,0 @@
#!/bin/bash
ssh execcsv@crl-01.ovea.com