ICS → מייבא Discourse דרך ה-REST API

הערות התנהגות מבדיקות של ics_to_discourse.py

הרצתי סדרת בדיקות על הסקריפט הזה (עם ובלי --time-only-dedupe) וחשבתי שיהיה שימושי לתעד את זרימת העדכון/אימוץ בפירוט.


1. כיצד נקבעת ייחודיות

  • מצב ברירת מחדל: אימוץ דורש התאמה מדויקת של התחלה + סיום + מיקום.
  • עם --time-only-dedupe: אימוץ דורש רק התחלה + סיום; המיקום נחשב כ"קרוב מספיק".

אם לא נמצא נושא קיים התואם לכללים אלה, נוצר נושא חדש.


2. תפקיד סמן ה-UID

  • כל נושא אירוע מקבל סמן HTML נסתר בפוסט הראשון:
  <!-- ICSUID:xxxxxxxxxxxxxxxx -->
  • בהרצות עוקבות, הסקריפט מחפש תחילה את הסמן הזה.
  • אם נמצא, הנושא נחשב כהתאמת UID ומעודכן ישירות, ללא קשר לכמה רועש או מיושן עשוי להיות טקסט ה-DESCRIPTION.
  • זה הופך את ה-UID למפתח הזהות האמיתי. שדות תיאור גלויים אינם משפיעים על ההתאמה.

3. זרימת עדכון עם התאמת UID

  1. הסקריפט מאחזר את הפוסט הראשון ומסיר את הסמן:
old_clean = strip_marker(old_raw)
fresh_clean = strip_marker(fresh_raw)
  1. אם old_clean == fresh_clean: אין עדכון (מונע תנודתיות).
  2. אם הם שונים: בודק אם השינוי הוא “משמעותי”:
meaningful = (
    _norm_time(old_attrs.get("start")) != _norm_time(new_attrs.get("start"))
    or _norm_time(old_attrs.get("end")) != _norm_time(new_attrs.get("end"))
    or _norm_loc(old_attrs.get("location")) != _norm_loc(new_attrs.get("location"))
)
  • אם meaningful = True → עדכון עם דחיפה (הנושא עולה ב’הכי חדש’).

  • אם meaningful = False → עדכון בשקט (bypass_bump=True → רק תיקון, ללא דחיפה).

    1. תגיות משולבות (מבטיח שתגיות סטטיות/ברירת מחדל קיימות, לעולם לא מסיר תגיות מנהל/ידניות).
    2. כותרת וקטגוריה לעולם אינם משתנים בעדכון.

  1. זרימת עדכון ללא התאמת UID
    1. הסקריפט מנסה אימוץ:
      • בונה שלשות מועמדות של התחלה/סיום/מיקום (או התחלה/סיום בלבד עם --time-only-dedupe).
      • מחפש ב-/search.json וב-/latest.json אירוע קיים עם תכונות תואמות.
      • אם נמצא → מאמץ את הנושא, מתקין מחדש את סמן ה-UID + תגיות (גוף נשאר ללא שינוי בשלב זה).
      • אם לא נמצא → יוצר נושא חדש לגמרי עם הסמן והתגיות.
    2. לאחר אימוץ או יצירה, כל סנכרונים עתידיים יפתרו ישירות לפי UID.

  1. השלכות מעשיות
    • שינויי זמן
    • ברירת מחדל: אימוץ נכשל (זמנים שונים) → נוצר נושא חדש.
    • עם --time-only-dedupe: אימוץ נכשל באותה צורה; נוצר נושא חדש.
    • שינויי מיקום
    • ברירת מחדל: אימוץ נכשל (מיקום שונה) → נוצר נושא חדש.
    • עם --time-only-dedupe: אימוץ מצליח (זמנים תואמים), אך הבדל במיקום מסומן כ"משמעותי" → עדכון עם דחיפה.
    • שינויי תיאור
    • אם טקסט ה-DESCRIPTION משתנה אך התחלה/סיום/מיקום לא:
    • הגוף מתעדכן בשקט (bypass_bump=True).
    • נוצר תיקון לנושא, אך ללא דחיפה ב’הכי חדש’.
    • אם DESCRIPTION ללא שינוי (או רק רעש כמו Last Updated: שמתנרמל), לא מתבצע כלל עדכון.
    • סמן UID
    • מבטיח התאמה אמינה בסנכרונים עתידיים.
    • פירושו ששדות DESCRIPTION רועשים אינם משפיעים על מציאת הנושא הנכון.

  1. מדוע ה-DESCRIPTION לפעמים “נשאר זהה”
    הסקריפט משווה את כל הגוף (ללא סמן ה-UID).
    אם רק שורה תנודתית כמו Last Updated: שונה, אך היא מתנרמלת (למשל, רווחים, סיומות שורה, יוניקוד), old_clean ו-fresh_clean נראים זהים → לא מתבצע עדכון.
    זה מכוון, כדי למנוע תנודתיות מרעש הזנה.

סיכום
• זמן מגדיר ייחודיות (תמיד יוצר נושא חדש כאשר זמנים משתנים).
• שינויי מיקום → דחיפה גלויה (כדי שמשתמשים ישימו לב לעדכוני מיקום).
• שינויי תיאור → עדכון שקט (תיקון אך ללא דחיפה).
• סמן UID = מפתח זהות אמין, מבטיח שהנושא הנכון תמיד יימצא, גם אם ה-DESCRIPTION מיושן או רועש.

זה מכה איזון טוב: שינויים חשובים מופיעים ב’הכי חדש’, תנודתיות לא חשובה נשארת בלתי נראית.