diff --git a/app/services/itop_service.py b/app/services/itop_service.py index 3c21c4d..f90fcdc 100644 --- a/app/services/itop_service.py +++ b/app/services/itop_service.py @@ -144,63 +144,63 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass): except Exception: pass - # ─── 1. Typologies: Environnements ─── + # ─── 1. Typologies: Environnements (batch) ─── + existing_envs = {r.name.lower() for r in db.execute(text("SELECT name FROM environments")).fetchall()} for item in client.get_all("Environnement", "name"): name = item.get("name", "") - if not name: + if not name or name.lower() in existing_envs: continue - existing = db.execute(text("SELECT id FROM environments WHERE LOWER(name)=LOWER(:n)"), {"n": name}).fetchone() - if not existing: - try: - db.execute(text("INSERT INTO environments (name, code) VALUES (:n, :c)"), - {"n": name, "c": name[:10].upper().replace(" ", "").replace("-", "")}) - db.commit() - stats["environments"] += 1 - except Exception: - db.rollback() + try: + db.execute(text("INSERT INTO environments (name, code) VALUES (:n, :c)"), + {"n": name, "c": name[:10].upper().replace(" ", "").replace("-", "")}) + existing_envs.add(name.lower()) + stats["environments"] += 1 + except Exception: + db.rollback() + db.commit() - # ─── 2. Typologies: Domaines applicatifs ─── + # ─── 2. Typologies: Domaines applicatifs (batch) ─── + existing_doms = {r.name.lower() for r in db.execute(text("SELECT name FROM domains")).fetchall()} for item in client.get_all("DomaineApplicatif", "name"): name = item.get("name", "") - if not name: + if not name or name.lower() in existing_doms: continue - existing = db.execute(text("SELECT id FROM domains WHERE LOWER(name)=LOWER(:n)"), {"n": name}).fetchone() - if not existing: - try: - db.execute(text("INSERT INTO domains (name, code) VALUES (:n, :c)"), - {"n": name, "c": name[:10].upper().replace(" ", "")}) - db.commit() - stats["domains"] += 1 - except Exception: - db.rollback() + try: + db.execute(text("INSERT INTO domains (name, code) VALUES (:n, :c)"), + {"n": name, "c": name[:10].upper().replace(" ", "")}) + existing_doms.add(name.lower()) + stats["domains"] += 1 + except Exception: + db.rollback() + db.commit() - # ─── 3. Typologies: Zones ─── + # ─── 3. Typologies: Zones (batch) ─── + existing_zones = {r.name.lower() for r in db.execute(text("SELECT name FROM zones")).fetchall()} for item in client.get_all("Zone", "name"): name = item.get("name", "") - if not name: + if not name or name.lower() in existing_zones: continue - existing = db.execute(text("SELECT id FROM zones WHERE LOWER(name)=LOWER(:n)"), {"n": name}).fetchone() - if not existing: - try: - db.execute(text("INSERT INTO zones (name, is_dmz) VALUES (:n, :d)"), - {"n": name, "d": "dmz" in name.lower()}) - db.commit() - stats["zones"] += 1 - except Exception: - db.rollback() + try: + db.execute(text("INSERT INTO zones (name, is_dmz) VALUES (:n, :d)"), + {"n": name, "d": "dmz" in name.lower()}) + existing_zones.add(name.lower()) + stats["zones"] += 1 + except Exception: + db.rollback() + db.commit() - # ─── 4. Typologies: DomainLdap → domain_ltd_list ─── + # ─── 4. Typologies: DomainLdap → domain_ltd_list (batch) ─── + existing_ltd = {r.name.lower() for r in db.execute(text("SELECT name FROM domain_ltd_list")).fetchall()} for item in client.get_all("DomainLdap", "name"): name = item.get("name", "") - if not name: + if not name or name.lower() in existing_ltd: continue - existing = db.execute(text("SELECT id FROM domain_ltd_list WHERE LOWER(name)=LOWER(:n)"), {"n": name}).fetchone() - if not existing: - try: - db.execute(text("INSERT INTO domain_ltd_list (name) VALUES (:n)"), {"n": name}) - db.commit() - except Exception: - db.rollback() + try: + db.execute(text("INSERT INTO domain_ltd_list (name) VALUES (:n)"), {"n": name}) + existing_ltd.add(name.lower()) + except Exception: + db.rollback() + db.commit() # ─── 5. Contacts + Teams (filtre périmètre IT uniquement) ─── persons = client.get_all("Person", "name,first_name,email,phone,org_name,function,status") @@ -233,6 +233,9 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass): seen_emails = set() stats["contacts_deactivated"] = 0 + contacts_by_email = {} + for r in db.execute(text("SELECT id, email FROM contacts")).fetchall(): + contacts_by_email[r.email.lower()] = r for p in persons: fullname = f"{p.get('first_name','')} {p.get('name','')}".strip() email = p.get("email", "") @@ -254,7 +257,7 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass): seen_itop_ids.add(int(itop_id)) seen_emails.add(email.lower()) - existing = db.execute(text("SELECT id FROM contacts WHERE LOWER(email)=LOWER(:e)"), {"e": email}).fetchone() + existing = contacts_by_email.get(email.lower()) if existing: db.execute(text("""UPDATE contacts SET name=:n, role=:r, itop_id=:iid, telephone=:tel, team=:t, function=:f, is_active=:a, updated_at=NOW() WHERE id=:id"""), @@ -292,6 +295,9 @@ def sync_from_itop(db, itop_url, itop_user, itop_pass): # Person name → email lookup person_email = {} + contacts_by_email = {} + for r in db.execute(text("SELECT id, email FROM contacts")).fetchall(): + contacts_by_email[r.email.lower()] = r for p in persons: fullname = f"{p.get('first_name','')} {p.get('name','')}".strip() person_email[fullname.lower()] = p.get("email", "") diff --git a/app/templates/macros.html b/app/templates/macros.html new file mode 100644 index 0000000..f730399 --- /dev/null +++ b/app/templates/macros.html @@ -0,0 +1,33 @@ +{% macro badge_etat(etat) -%} +{{ (etat or '-')[:6] }} +{%- endmacro %} + +{% macro badge_env(env) -%} +{{ (env or '-')[:6] }} +{%- endmacro %} + +{% macro badge_os(os) -%} +{{ (os or '-')[:6] }} +{%- endmacro %} + +{% macro badge_zone(zone) -%} +{{ zone or '-' }} +{%- endmacro %} + +{% macro badge_status(status) -%} +{{ status or '-' }} +{%- endmacro %} + +{% macro badge_source(source_type, campaign_id=None, campaign_label=None, run_id=None, run_label=None) -%} +{% if source_type == 'import' %}xlsx +{% elif source_type == 'standard' %}{{ campaign_label or 'Campagne' }} +{% elif source_type == 'quickwin' %}{{ run_label or 'QuickWin' }} +{% else %}{{ source_type or '?' }}{% endif %} +{%- endmacro %} + +{% macro filter_select(name, label, options, selected) -%} + +{%- endmacro %}