From 0f300c3e72791d09a3a7eb0a982e65645ad7d125 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 18:05:13 +0200 Subject: [PATCH 01/11] up --- internal/route/main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/route/main.go b/internal/route/main.go index 1bef013..80e7b56 100644 --- a/internal/route/main.go +++ b/internal/route/main.go @@ -110,6 +110,8 @@ r.PathPrefix("/webdav/").Handler(http.HandlerFunc(func(w http.ResponseWriter, re http.Error(w, "Unauthorized", http.StatusUnauthorized) return } + log.Printf("✅ email saisie: %s", email) + log.Printf("✅ passw saisie: %s", password) var user models.User result := bd.Where("email = ?", email).First(&user) From 90810eefd4243300252eb985d417af60368c2001 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 18:20:31 +0200 Subject: [PATCH 02/11] up --- internal/route/main.go | 87 ++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/internal/route/main.go b/internal/route/main.go index 80e7b56..f0340df 100644 --- a/internal/route/main.go +++ b/internal/route/main.go @@ -95,58 +95,55 @@ func RoutesPublic(r *mux.Router, bd *gorm.DB) { http.Error(w, "Erreur lors de la génération de la playlist", http.StatusInternalServerError) } }) -r.PathPrefix("/webdav/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - authHeader := req.Header.Get("Authorization") - if authHeader == "" { - w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } + r.PathPrefix("/webdav/").Handler(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + authHeader := req.Header.Get("Authorization") + if authHeader == "" { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } - // Authentification HTTP Basic en base de données - email, password, ok := req.BasicAuth() - if !ok { - w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } - log.Printf("✅ email saisie: %s", email) - log.Printf("✅ passw saisie: %s", password) + // Authentification HTTP Basic en base de données + email, password, ok := req.BasicAuth() + if !ok { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + log.Printf("✅ email saisi: %s", email) + log.Printf("✅ password saisi: %s", password) - var user models.User - result := bd.Where("email = ?", email).First(&user) - if result.Error != nil { - w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } + var user models.User + result := bd.Where("email = ?", email).First(&user) + if result.Error != nil { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } - err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) - if err != nil { - w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) - http.Error(w, "Unauthorized", http.StatusUnauthorized) - return - } + err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)) + if err != nil { + w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } - // Lecture seule - if req.Method != "GET" && req.Method != "HEAD" && req.Method != "OPTIONS" && req.Method != "PROPFIND" { - http.Error(w, "Read-Only", http.StatusForbidden) - return - } + // ✅ Ici on autorise TOUTES les méthodes WebDAV (lecture/écriture/suppression) + log.Printf("✅ WebDAV FULL ACCESS for user: %s", email) - log.Printf("✅ WebDAV access for user: %s", email) + // Headers WebDAV que certains clients attendent + w.Header().Set("DAV", "1,2") + w.Header().Set("MS-Author-Via", "DAV") - w.Header().Set("DAV", "1,2") - w.Header().Set("MS-Author-Via", "DAV") + // Handler WebDAV complet + webdavHandler := &webdav.Handler{ + Prefix: "/webdav/", + FileSystem: webdav.Dir("/app/upload"), + LockSystem: webdav.NewMemLS(), + } - webdavHandler := &webdav.Handler{ - Prefix: "/webdav/", - FileSystem: webdav.Dir("/app/upload"), - LockSystem: webdav.NewMemLS(), - } - - webdavHandler.ServeHTTP(w, req) -})) + webdavHandler.ServeHTTP(w, req) + })) // WebDAV sécurisé // username := "tonuser" // ton login From 12d7a04ba181d17a149c76fb60257523a9d29845 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 19:12:22 +0200 Subject: [PATCH 03/11] up --- templates/settings.pages.tmpl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/templates/settings.pages.tmpl b/templates/settings.pages.tmpl index 14f93e3..c60f246 100644 --- a/templates/settings.pages.tmpl +++ b/templates/settings.pages.tmpl @@ -51,11 +51,14 @@
-
+

Section

-

- A simple container to divide your page into sections, like - the one you're currently reading. -

+
+
+
+ +
+ +
\ No newline at end of file From 6907794858d580f5c601b9a080e702e2e22b5168 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 19:40:08 +0200 Subject: [PATCH 04/11] add stream url --- renders/renders.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/renders/renders.go b/renders/renders.go index 9a0ca1a..07528e9 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -309,6 +309,12 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { // Enregistre chaque lien comme un job "en attente" for _, l := range links { + streamInfo, err := client.GetTranscode(ctx, l.ID) + if err != nil { + log.Println("Erreur GetTranscode:", err) + return + } + job := &download.DownloadJob{ ID: l.ID, Link: l.DownloadURL, @@ -318,7 +324,7 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { Size: l.Size, Host: l.Host, Progress: 0, // obligatoire si valeur attendue - StreamURL: "", // vide par défaut + StreamURL: streamInfo.StreamURL, // vide par défaut } if err := download.RegisterJobWithDB(job, db); err != nil { log.Printf("[ERROR] Job non enregistré : %v\n", err) From 196c29cd70d22fd4a1b25b27dc43f05f40ab0ea7 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 19:46:37 +0200 Subject: [PATCH 05/11] up debid link --- internal/debridlink/client.go | 21 +++++++++++++++------ renders/renders.go | 6 +++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/internal/debridlink/client.go b/internal/debridlink/client.go index dd58e37..cba3660 100644 --- a/internal/debridlink/client.go +++ b/internal/debridlink/client.go @@ -534,7 +534,13 @@ func (c *Client) CreateTranscode(ctx context.Context, fileID, preset string) (st return resp.TranscodeID, nil } -func (c *Client) GetTranscode(ctx context.Context, transcodeID string) (*StreamInfo, error) { +func (c *Client) GetTranscode(ctx context.Context, fileID string) (*StreamInfo, error) { + body := struct { + ID string `json:"id"` + }{ + ID: fileID, + } + var raw struct { Success bool `json:"success"` Value struct { @@ -545,15 +551,16 @@ func (c *Client) GetTranscode(ctx context.Context, transcodeID string) (*StreamI MimeType string `json:"mimetype"` Domain string `json:"domain"` File struct { - ID string `json:"id"` - Name string `json:"name"` - Size int64 `json:"size"` + ID string `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + Source string `json:"source"` } `json:"file"` } `json:"value"` } - path := fmt.Sprintf("stream/transcode/%s", transcodeID) - if err := c.doJSON(ctx, "GET", path, nil, nil, &raw); err != nil { + path := "stream/transcode/add" + if err := c.doJSON(ctx, "POST", path, nil, body, &raw); err != nil { return nil, err } @@ -570,3 +577,5 @@ func (c *Client) GetTranscode(ctx context.Context, transcodeID string) (*StreamI } return info, nil } + + diff --git a/renders/renders.go b/renders/renders.go index 07528e9..536d3c1 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -311,9 +311,9 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { for _, l := range links { streamInfo, err := client.GetTranscode(ctx, l.ID) if err != nil { - log.Println("Erreur GetTranscode:", err) - return - } + log.Println("Erreur GetTranscode:", err) + return + } job := &download.DownloadJob{ ID: l.ID, From 954b9c9037c5c1229358e4d502c9fca62c4ecde6 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 19:54:17 +0200 Subject: [PATCH 06/11] up --- internal/debridlink/client.go | 93 +++++++++++++++++------------------ renders/renders.go | 2 +- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/internal/debridlink/client.go b/internal/debridlink/client.go index cba3660..0908e2e 100644 --- a/internal/debridlink/client.go +++ b/internal/debridlink/client.go @@ -525,57 +525,56 @@ func (c *Client) ListFiles(ctx context.Context, parentID string) ([]File, error) } // =========================== Stream =========================== -func (c *Client) CreateTranscode(ctx context.Context, fileID, preset string) (string, error) { - var resp struct{ TranscodeID string `json:"transcodeId"` } - body := map[string]string{"fileId": fileID, "preset": preset} - if err := c.doJSON(ctx, "POST", "stream/transcode", nil, body, &resp); err != nil { - return "", err - } - return resp.TranscodeID, nil -} +// func (c *Client) CreateTranscode(ctx context.Context, fileID, preset string) (string, error) { +// var resp struct{ TranscodeID string `json:"transcodeId"` } +// body := map[string]string{"fileId": fileID} +// if err := c.doJSON(ctx, "POST", "stream/transcode", nil, body, &resp); err != nil { +// return "", err +// } +// return resp.TranscodeID, nil +// } -func (c *Client) GetTranscode(ctx context.Context, fileID string) (*StreamInfo, error) { - body := struct { - ID string `json:"id"` - }{ - ID: fileID, - } +func (c *Client) CreateTranscode(ctx context.Context, fileID string) (*StreamInfo, error) { + requestBody := map[string]string{ + "id": fileID, + } - var raw struct { - Success bool `json:"success"` - Value struct { - ID string `json:"id"` - StreamURL string `json:"streamUrl"` - DownloadURL string `json:"downloadUrl"` - Type string `json:"type"` - MimeType string `json:"mimetype"` - Domain string `json:"domain"` - File struct { - ID string `json:"id"` - Name string `json:"name"` - Size int64 `json:"size"` - Source string `json:"source"` - } `json:"file"` - } `json:"value"` - } + var raw struct { + Success bool `json:"success"` + Value struct { + ID string `json:"id"` + StreamURL string `json:"streamUrl"` + DownloadURL string `json:"downloadUrl"` + Type string `json:"type"` + MimeType string `json:"mimetype"` + Domain string `json:"domain"` + File struct { + ID string `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + Source string `json:"source"` + } `json:"file"` + } `json:"value"` + } - path := "stream/transcode/add" - if err := c.doJSON(ctx, "POST", path, nil, body, &raw); err != nil { - return nil, err - } + path := "stream/transcode/add" + if err := c.doJSON(ctx, "POST", path, nil, requestBody, &raw); err != nil { + return nil, err + } - info := &StreamInfo{ - ID: raw.Value.ID, - StreamURL: raw.Value.StreamURL, - DownloadURL: raw.Value.DownloadURL, - Type: raw.Value.Type, - MimeType: raw.Value.MimeType, - Domain: raw.Value.Domain, - FileID: raw.Value.File.ID, - FileName: raw.Value.File.Name, - FileSize: raw.Value.File.Size, - } - return info, nil + info := &StreamInfo{ + ID: raw.Value.ID, + StreamURL: raw.Value.StreamURL, + DownloadURL: raw.Value.DownloadURL, + Type: raw.Value.Type, + MimeType: raw.Value.MimeType, + Domain: raw.Value.Domain, + FileID: raw.Value.File.ID, + FileName: raw.Value.File.Name, + FileSize: raw.Value.File.Size, + } + return info, nil } + diff --git a/renders/renders.go b/renders/renders.go index 536d3c1..59ab3b0 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -309,7 +309,7 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { // Enregistre chaque lien comme un job "en attente" for _, l := range links { - streamInfo, err := client.GetTranscode(ctx, l.ID) + streamInfo, err := client.CreateTranscode(ctx,l.ID) if err != nil { log.Println("Erreur GetTranscode:", err) return From f530d9da51d08d165870a869f69ccc0952d3f6e5 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 19:57:40 +0200 Subject: [PATCH 07/11] up debug --- renders/renders.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/renders/renders.go b/renders/renders.go index 59ab3b0..8fa2184 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -309,6 +309,8 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { // Enregistre chaque lien comme un job "en attente" for _, l := range links { + log.Printf("[l'id] : %v\n", l.ID) + streamInfo, err := client.CreateTranscode(ctx,l.ID) if err != nil { log.Println("Erreur GetTranscode:", err) From f123e928c2bccf7d72708ac891566661afc558cd Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 20:15:23 +0200 Subject: [PATCH 08/11] up --- internal/debridlink/client.go | 71 +++++++++++++++++------------------ 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/internal/debridlink/client.go b/internal/debridlink/client.go index 0908e2e..23c811e 100644 --- a/internal/debridlink/client.go +++ b/internal/debridlink/client.go @@ -535,46 +535,45 @@ func (c *Client) ListFiles(ctx context.Context, parentID string) ([]File, error) // } func (c *Client) CreateTranscode(ctx context.Context, fileID string) (*StreamInfo, error) { - requestBody := map[string]string{ - "id": fileID, - } + body := map[string]string{"id": fileID} - var raw struct { - Success bool `json:"success"` - Value struct { - ID string `json:"id"` - StreamURL string `json:"streamUrl"` - DownloadURL string `json:"downloadUrl"` - Type string `json:"type"` - MimeType string `json:"mimetype"` - Domain string `json:"domain"` - File struct { - ID string `json:"id"` - Name string `json:"name"` - Size int64 `json:"size"` - Source string `json:"source"` - } `json:"file"` - } `json:"value"` - } + var raw struct { + Success bool `json:"success"` + Value struct { + ID string `json:"id"` + StreamURL string `json:"streamUrl"` + DownloadURL string `json:"downloadUrl"` + Type string `json:"type"` + MimeType string `json:"mimetype"` + Domain string `json:"domain"` + File struct { + ID string `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + Source string `json:"source"` + } `json:"file"` + } `json:"value"` + } - path := "stream/transcode/add" - if err := c.doJSON(ctx, "POST", path, nil, requestBody, &raw); err != nil { - return nil, err - } + path := "stream/transcode/add" + if err := c.doJSON(ctx, "POST", path, nil, body, &raw); err != nil { + return nil, err + } - info := &StreamInfo{ - ID: raw.Value.ID, - StreamURL: raw.Value.StreamURL, - DownloadURL: raw.Value.DownloadURL, - Type: raw.Value.Type, - MimeType: raw.Value.MimeType, - Domain: raw.Value.Domain, - FileID: raw.Value.File.ID, - FileName: raw.Value.File.Name, - FileSize: raw.Value.File.Size, - } - return info, nil + info := &StreamInfo{ + ID: raw.Value.ID, + StreamURL: raw.Value.StreamURL, + DownloadURL: raw.Value.DownloadURL, + Type: raw.Value.Type, + MimeType: raw.Value.MimeType, + Domain: raw.Value.Domain, + FileID: raw.Value.File.ID, + FileName: raw.Value.File.Name, + FileSize: raw.Value.File.Size, + } + return info, nil } + From 5cf0344b234f26bbc65e95429c860da12a135daa Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 20:19:13 +0200 Subject: [PATCH 09/11] up --- internal/debridlink/client.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/internal/debridlink/client.go b/internal/debridlink/client.go index 23c811e..c9e0961 100644 --- a/internal/debridlink/client.go +++ b/internal/debridlink/client.go @@ -319,6 +319,11 @@ func (c *Client) doJSON(ctx context.Context, method, path string, params url.Val return err } reqBody = bytes.NewReader(b) + + // 👇 DEBUG : afficher le body + log.Printf("➡️ [API %s] URL: %s\nBody: %s\n", method, urlStr, string(b)) + } else { + log.Printf("➡️ [API %s] URL: %s (empty body)", method, urlStr) } req, err := http.NewRequestWithContext(ctx, method, urlStr, reqBody) @@ -326,7 +331,11 @@ func (c *Client) doJSON(ctx context.Context, method, path string, params url.Val return err } - req.Header.Set("Authorization", "Bearer "+c.account.AccessToken) + // 👇 DEBUG : afficher le header Authorization + authHeader := "Bearer " + c.account.AccessToken + log.Printf("➡️ Authorization Header: %s\n", authHeader) + + req.Header.Set("Authorization", authHeader) req.Header.Set("Content-Type", "application/json") resp, err := c.http.Do(req) @@ -346,6 +355,7 @@ func (c *Client) doJSON(ctx context.Context, method, path string, params url.Val return nil } + // =========================== RSS =========================== type RSSFeed struct { ID string `json:"id" gorm:"column:id;primaryKey"` From 6aaa2f6e427e49792b18743509b8d2288a08bd88 Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 21:12:05 +0200 Subject: [PATCH 10/11] up --- renders/renders.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/renders/renders.go b/renders/renders.go index 8fa2184..84048cf 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -311,11 +311,11 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { for _, l := range links { log.Printf("[l'id] : %v\n", l.ID) - streamInfo, err := client.CreateTranscode(ctx,l.ID) - if err != nil { - log.Println("Erreur GetTranscode:", err) - return - } + // streamInfo, err := client.CreateTranscode(ctx,l.ID) + // if err != nil { + // log.Println("Erreur GetTranscode:", err) + // return + // } job := &download.DownloadJob{ ID: l.ID, @@ -326,7 +326,7 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { Size: l.Size, Host: l.Host, Progress: 0, // obligatoire si valeur attendue - StreamURL: streamInfo.StreamURL, // vide par défaut + StreamURL: "", // vide par défaut } if err := download.RegisterJobWithDB(job, db); err != nil { log.Printf("[ERROR] Job non enregistré : %v\n", err) From 9cfa861bb9aadcf3f7bf231e96b091df0e767adc Mon Sep 17 00:00:00 2001 From: cangui Date: Thu, 19 Jun 2025 21:21:17 +0200 Subject: [PATCH 11/11] up --- internal/debridlink/client.go | 2 +- renders/renders.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/debridlink/client.go b/internal/debridlink/client.go index c9e0961..c400c3e 100644 --- a/internal/debridlink/client.go +++ b/internal/debridlink/client.go @@ -157,7 +157,7 @@ func (c *Client) RequestDeviceCodeWithCredentials(ctx context.Context, username, form.Set("grant_type", "password") // possible variation form.Set("username", username) form.Set("password", password) - form.Set("scope", "get.post.downloader get.post.seedbox get.account") + form.Set("scope", "get.post.downloader get.post.seedbox get.account get.post.stream") req, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://debrid-link.com/api/oauth/device/code", strings.NewReader(form.Encode())) if err != nil { diff --git a/renders/renders.go b/renders/renders.go index 84048cf..f06aa16 100644 --- a/renders/renders.go +++ b/renders/renders.go @@ -311,11 +311,11 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { for _, l := range links { log.Printf("[l'id] : %v\n", l.ID) - // streamInfo, err := client.CreateTranscode(ctx,l.ID) - // if err != nil { - // log.Println("Erreur GetTranscode:", err) - // return - // } + streamInfo, err := client.CreateTranscode(ctx,l.ID) + if err != nil { + log.Println("Erreur GetTranscode:", err) + return + } job := &download.DownloadJob{ ID: l.ID, @@ -326,7 +326,7 @@ func HandleAddJob(db *gorm.DB) http.HandlerFunc { Size: l.Size, Host: l.Host, Progress: 0, // obligatoire si valeur attendue - StreamURL: "", // vide par défaut + StreamURL: streamInfo.StreamURL, // vide par défaut } if err := download.RegisterJobWithDB(job, db); err != nil { log.Printf("[ERROR] Job non enregistré : %v\n", err)