# **📺 MyYouTube — מפת הפרויקט**

מסמך זה מתאר את מבנה הפרויקט, תפקיד כל קובץ, וסדר הטעינה.

**לכל שינוי או שדרוג עתידי — מצא כאן את הקבצים הרלוונטיים.**

## **📦 קימפול ל-EXE**

הפרויקט מתקמפל לקובץ הרצה יחיד (MyYouTube.exe) בעזרת **PyInstaller**.

### **קבצים הקשורים לקימפול**

| **קובץ** | **תפקיד** |

| build\_exe.bat | סקריפט הקימפול — מריץ PyInstaller, מעביר את ה-EXE לתיקייה הראשית, ומנקה שאריות |

| server.py | מכיל לוגיקת getattr(sys, 'frozen', False) לזיהוי הרצה כ-EXE |

| py/config.py | מגדיר את BASE\_DIR לפי מצב הרצה (EXE / סקריפט) |

| icon.ico | אייקון ה-EXE (נדרש בתיקייה הראשית לפני הקימפול) |

### **פקודת הקימפול**

python \-m PyInstaller \--onefile \--noconsole \--name="MyYouTube" \--icon="icon.ico" \--add-data "py;py" server.py

⚠️ **חשוב:** הדגל \--add-data "py;py" נדרש כדי שתיקיית py/ תיכלל בתוך ה-EXE.

### **תלויות נדרשות לקימפול**

* Python מותקן ובנתיב ה-PATH  
* pip install pyinstaller

### **קבצים נדרשים ליד ה-EXE לאחר הקימפול**

* yt-dlp.exe — כלי שליפת הנתונים וההורדות מ-YouTube.  
* ffmpeg.exe — כלי למיזוג וידאו ואודיו (חובה להורדת סרטונים באיכות גבוהה).  
* index.html, styles.css, js/ — ממשק המשתמש.  
* icon.ico — אייקון (אופציונלי לאחר הקימפול).  
* myyoutube.log — קובץ לוג (נוצר אוטומטית בהפעלה הראשונה).

### **קובץ לוג (myyoutube.log)**

היות והתוכנה מקומפלת ללא חלון קונסול (--noconsole), כל הלוגים נכתבים לקובץ myyoutube.log ליד ה-EXE. הקובץ **מתאפס בכל הפעלה** — תוכן ההפעלה הקודמת נמחק. לשינוי התנהגות זו — ראה py/config.py שורת פתיחת הלוג (open(LOG\_FILE, 'w', ...)), החלף 'w' ב-'a' לצבירה.

### **תהליך הקימפול (build\_exe.bat)**

1. מריץ PyInstaller עם \--add-data "py;py" ומייצר dist\\MyYouTube.exe  
2. מעביר את ה-EXE לתיקייה הראשית  
3. מוחק את תיקיות build/, dist/ ואת MyYouTube.spec

## **🗂️ מבנה קבצים**

project/  
├── server.py           ← נקודת כניסה — הפעלת שרת, watchdog, פתיחת דפדפן  
├── index.html          ← מבנה HTML, סדר טעינת JS, כל ה-Views, מודאל הורדות  
├── styles.css          ← עיצוב כהה (CSS Variables \+ Tailwind)  
├── py/                 ← מודולי Python פנימיים  
│   ├── \_\_init\_\_.py  
│   ├── config.py       ← קבועים גלובליים, BASE\_DIR, הגדרת לוג, heartbeat state  
│   ├── ytdlp.py        ← כל הלוגיקה של yt-dlp (שליפה, תמונות, גרסה, עדכון)  
│   ├── handlers.py     ← MyHandler \+ כל ה-API routes  
│   └── downloader.py   ← מנהל משימות, תור הורדות, Innertube API לפלייליסטים  
└── js/  
    ├── config.js       ← קבועים גלובליים, Toast, ENDPOINTS, init  
    ├── store.js        ← שכבת נתונים (localStorage)  
    ├── youtube.js      ← IFrame API, מודאל צפייה, ניווט  
    ├── favorites.js    ← מועדפים ב-localStorage  
    ├── downloader.js   ← מנגנון הורדות צד לקוח (Polling, תור, עדכון UI חי, קישורים מותאמים)  
    ├── episodes.js     ← Virtual Scroll, כרטיסי סרטון, חיפוש, מיון  
    ├── updates.js      ← בדיקת עדכונים, feed, badge  
    └── library.js      ← ספרייה, קטגוריות, גרירה, ייצוא

## **📦 תפקיד כל קובץ מפתח**

### **Python (שרת)**

| **קובץ** | **תפקיד** |

| server.py | entry point — הפעלת השרת (ThreadingHTTPServer), פתיחת דפדפן, סגירה אוטומטית |

| py/config.py | קבועים, ניתוב BASE\_DIR, הגדרת לוגים והסטטוס של ה-heartbeat |

| py/ytdlp.py | שליפת ערוץ חדש (RSS/JSON), הורדת תמונות פרופיל, בדיקת גרסה ועדכון אוטומטי ל-yt-dlp |

| py/handlers.py | ניתוב בקשות HTTP. מקשר בין ה-JavaScript לפעולות בפייתון |

| py/downloader.py | מנהל **תור ההורדות (Queue)** ברקע. כולל חילוץ פלייליסטים פנימי (Innertube API), מזהה חסימות נטפרי, וקורא מהירויות ושלבים בזמן אמת. |

### **JavaScript (צד לקוח)**

| **קובץ** | **תפקיד** |

| js/config.js | קבועים גלובליים, ניתוב ENDPOINTS, הפעלת Heartbeat כדי למנוע כיבוי |

| js/store.js | קריאה וכתיבה ל-localStorage |

| js/youtube.js | ניהול נגן היוטיוב במודאל צף \+ התקדמות אוטומטית (Autoplay) |

| js/favorites.js | מועדפים (הוספה, הסרה, סינון לפי קטגוריות) |

| js/downloader.js | אחראי על מודאל ההורדות: Polling מהשרת כל שנייה, הצגת מהירויות, זיהוי לינקים אוטומטי (list=), ועיצוב דינמי. |

| js/episodes.js | Virtual Scroll, טעינת סרטונים חכמה, כרטיסי וידאו (כולל פס הורדה), ומנוע החיפוש |

| js/updates.js | בדיקת עדכונים שקטה ברקע כל 15 דק', תצוגת פעמון והודעות קופצות |

| js/library.js | תצוגת הדף הראשי, קטגוריות, מנגנון גרירה (Sortable) וייבוא/ייצוא |

## **🌐 API Endpoints (py/handlers.py)**

| **Method** | **Endpoint** | **תפקיד** |

| POST | /api/youtube/fetch-all | שליפת ערוץ YT (מידע \+ סרטונים) |

| GET | /api/data | טעינת נתונים מהשרת |

| POST | /api/data | שמירת נתונים לשרת |

| POST | /api/download/start | הכנסת סרטון/פלייליסט לתור ההורדות |

| GET | /api/download/status | קבלת סטטוס רציף (אחוזים, מהירות, שלב, חסימות, ושם מחולץ) |

| POST | /api/download/cancel | ביטול משימת הורדה / מחיקה מהתור |

| POST | /api/download/clear | ניקוי משימה שהסתיימה/נכשלה מהזיכרון |

| GET/POST | /api/ytdlp/\* | בדיקה, עדכון, וסטטוס של קובץ ה-yt-dlp |

| POST | /api/heartbeat | פעימת חיים — מונע סגירת השרת בזמן שהדפדפן פתוח |

| POST | /api/shutdown | סגירת השרת (מופעל אוטומטית בסגירת חלון) |

## **🔧 מפת שדרוגים — לפי נושא**

### **⬇️ ניהול הורדות (Downloader)**

* **קובץ שרת (py/downloader.py):**  
  * מנהל **תור (Queue)** להורדות באמצעות פועל (Worker) יחיד ברקע.  
  * **מנוע Innertube API לחילוץ פלייליסטים:** עוקף את חסימות נטפרי (418) ע"י שליחת בקשת JSON ישירה לגוגל, ומפצל כל פלייליסט למשימות הורדה בודדות בתור (הסרטונים נשמרים בתוך תת-תיקייה ממוספרת).  
  * **טריק חתימות "Android":** שימוש בלקוח android,web שעוקף את מנגנון האבטחה/חתימות של יוטיוב ללא צורך בעוגיות.  
  * קריאת מהירות ההורדה ושלב ההורדה (וידאו, שמע, או מיזוג).  
* **קובץ לקוח (js/downloader.js):**  
  * מבצע Polling כל שנייה להתעדכנות מול השרת.  
  * מזהה באופן אוטומטי מתי משתמש מזין פלייליסט (לפי list= ב-URL).  
  * עדכון UI דינמי: מחליף את הכותרת "סרטון מצורף ידנית" לשם האמיתי של הסרטון בזמן אמת, ומציג טקסט ייעודי לסרטונים שחולצו.  
* **מודאל מנהל ההורדות (index.html):**  
  * שורת חיפוש להוספת קישורים ידניים ללא כפתורי סימון מיותרים.  
  * מציג אחוזים, מהירות, ועיצוב נקי שלא "מתכווץ" (באמצעות flex-shrink-0).

### **🎨 עיצוב, מראה ותצוגה (UI/UX)**

| **מה לשנות** | **קובץ** |

| צבעים, גופנים, CSS Variables | styles.css → :root {} |

| מבנה HTML (views, כפתורים, מנהל הורדות) | index.html |

| כרטיסי סרטון (thumbnail, כפתורי הורדה) | js/episodes.js → createVideoCard() |

| חלון ההורדות הפעילות (עיצוב הכרטיסיות) | js/downloader.js → renderDownloadsManager() |

### **📡 YouTube / נתונים / שרת**

| **מה לשנות** | **קובץ** |

| שליפת נתונים מ-YouTube | py/ytdlp.py → fetch\_channel\_with\_ytdlp() |

| מודאל צפייה \+ Autoplay | js/youtube.js → openYTModal(), \_triggerAutoplayNext() |

| עקיפת שגיאות SSL (נטפרי) לשליפה | py/ytdlp.py → cmd \= \["--no-check-certificate"\] |

| עקיפת שגיאות SSL (נטפרי) להורדות | py/downloader.py → cmd \= \["--no-check-certificate"\] |

## **📝 הערות חשובות לדיבוג ותחזוקה**

* **ארכיטקטורת חילוץ פלייליסטים תחת נטפרי:** בניסיון לגלוש לעמוד HTML של פלייליסט, נטפרי חוסמים ב-100% מהמקרים (Error 418). הפתרון שיושם נמצא ב-py/downloader.py (בפונקציה \_fetch\_playlist\_videos): פייתון שולח בקשת POST ישירה וסמויה ל-youtubei/v1/browse (ממשק ה-Innertube הפנימי). זה לא נחסם ע"י נטפרי. הרשימה המוחזרת מפורקת לסרטונים בודדים שמוזנים אחד-אחד אל התור.  
* **עקיפת שגיאות חתימה (Signature Solving Failed):** הורדות פועלות ללא העברת עוגיות (cookies), אך עם זיוף של התחברות דרך מכשיר אנדרואיד (--extractor-args "youtube:player\_client=android,web"). זה מונע מיוטיוב להציג ל-yt-dlp חידות JS מורכבות.  
* **מנגנון תור (Queue):** ההורדות מנוהלות בתור (FIFO). משימה אחת רצה בפועל, בעוד השאר ממתינות על סטטוס queued (כחול).  
* **תלות FFMPEG:** חובה להניח את הקובץ ffmpeg.exe ליד ה-EXE. בלעדיו, שלב המיזוג (Merge) בהורדות ייכשל או שהסרטונים ירדו ללא קול.  
* **כותרות חכמות להורדה ידנית:** כאשר מכניסים קישור יחידני, המערכת קוראת לו בהתחלה "סרטון מצורף ידנית". השרת סורק את פלט הטרמינל כדי לאתר את השורה \[download\] Destination: ..., גוזר ממנה את שם הערוץ והכותרת ומשדר אותם מיד חזרה לדפדפן שמעדכן את העיצוב ללא ריענון.  
* **שגיאת "שם קובץ ארוך מדי":** בקשת הורדה מדפדפן חייבת לעבור decodeURIComponent() בצד הלקוח (או שרת) כדי שווינדוס לא יקבל נתיבי תיקייה מלאים ב-%D7%A9 שיגרמו לקריסת ההורדה עקב חריגה מאורך מותר.