handlers.documents module

summary:

מנתב קבצים שנשלחים לבוט לפי upload_mode: שחזור ZIP לריפו GitHub, ייבוא ZIP, וקבצי טקסט שנשמרים דרך שכבת הקבצים. כולל ולידציה והגנות מפני »פצצת ZIP«.

תיאור כללי

handlers.documents מרכז את הטיפול במסמכים וקבצים שנשלחים לבוט (Facade). הוא אחראי לנתב בין מסלולי GitHub, ZIP וקבצים טקסטואליים, ולשמור מדדים ואירועי Observability לאורך הזרימה.

נקודות הרחבה עיקריות

  • DocumentHandler.handle_document – נקודת הכניסה; בודקת upload_mode ומפנה למסלול המתאים.

  • DocumentHandler._handle_github_restore_zip_to_repo – שחזור ZIP לריפו קיים (Commit מרובה קבצים).

  • DocumentHandler._handle_github_create_repo_from_zip – יצירת ריפו חדש והעלאת תכולת ה‑ZIP.

  • DocumentHandler._handle_zip_import – יבוא ZIP פנימי (Backup) ושחזור קבצים לחשבון המשתמש.

  • DocumentHandler._handle_zip_create – צבירת קבצים ל‑bundle ZIP לשימוש חוזר.

  • DocumentHandler._handle_textual_file – זיהוי קידוד ושמירה של קבצים טקסטואליים/קוד, בלי שינוי בתוכן.

קישורים לטסטים רלוונטיים

  • tests/handlers/test_documents.py – כיסוי למסלולי upload_mode ולתוצאות צפויות.

API Reference

Handlers עבור מסמכים וקבצים הנשלחים לבוט.

handlers.documents.detect_zip_common_root(names)[מקור]

מזהה תיקיית שורש משותפת בארכיון, או None אם אין כזו.

תיקיית שורש קיימת רק אם כל הרשומות נמצאות תחתיה. אם יש ולו קובץ אחד בשורש הארכיון, אין שורש משותף — אחרת ZIP כמו README.md + src/main.py היה מזוהה בטעות עם שורש src, ו-src/main.py היה נחתך ל-main.py.

אזהרה

אל תחילו אותה על שחזור ZIP לריפו. ה-ZIP של גיבוי ריפו הוא ה-zipball של GitHub — שכל תוכנו תחת תיקייה אחת בשם owner-repo-sha — ואליו נוסף metadata.json בשורש. הקובץ הזה מפעיל כאן את הכלל שלמעלה, השורש אינו מזוהה, וכל הריפו נפרס רובד אחד עמוק מדי. ‏``_handle_github_restore_zip_to_repo`` מחזיק בכוונה חישוב משלו שסופר תיקיות בלבד. איחוד השניים כבר נעשה פעם אחת (PR #3205) והוא ששבר את השחזור.

Return type:

Optional[str]

פרמטרים:

names (Iterable[str])

handlers.documents.normalize_repo_folder(folder)[מקור]

מנרמל נתיב של תיקיית יעד בריפו ומחזיר אותו בלי לוכסנים בקצוות.

מחזיר מחרוזת ריקה עבור שורש הריפו. זורק ValueError אם הנתיב מנסה לצאת מהריפו (..), אם הוא נתיב מוחלט, או אם הוא מכיל תווים אסורים.

Return type:

str

פרמטרים:

folder (str)

handlers.documents.sanitize_zip_member_path(path)[מקור]

מנקה נתיב של קובץ מתוך ZIP ומחזיר אותו, או None אם יש לדלג עליו.

זו ההגנה מפני Zip-Slip: ארכיון יכול להכיל נתיב כמו ../../secrets, ובלעדיה הוא היה נכתב מחוץ לתיקיית היעד שהמשתמש בחר.

Return type:

Optional[str]

פרמטרים:

path (str)

class handlers.documents.DocumentHandler(notify_admins, get_reporter, log_user_activity, encodings_to_try, emit_event, errors_total)[מקור]

Bases: object

אחראי על טיפול בכל המסלולים של קבצים שמגיעים לבוט.

פרמטרים:
  • notify_admins (Callable[[ContextTypes.DEFAULT_TYPE, str], Awaitable[None]])

  • get_reporter (Callable[[], Optional[_ReporterProto]])

  • log_user_activity (Callable[[Update, ContextTypes.DEFAULT_TYPE], Awaitable[None]])

  • encodings_to_try (Sequence[str] | Callable[[], Sequence[str]])

  • emit_event (Callable[..., object] | None)

  • errors_total (Optional[_MetricProto])

__init__(notify_admins, get_reporter, log_user_activity, encodings_to_try, emit_event, errors_total)[מקור]
פרמטרים:
Return type:

None

async handle_document(update, context)[מקור]

נתיב ראשי לטיפול בקובץ שנשלח.

Return type:

None

פרמטרים:
  • update (telegram.Update)

  • context (telegram.ext.ContextTypes.DEFAULT_TYPE)