This commit is contained in:
julien 2025-06-20 15:41:41 +02:00
commit 2cdee0eed1
4 changed files with 92 additions and 65 deletions

View File

@ -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 {
@ -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"`
@ -525,16 +535,18 @@ 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) CreateTranscode(ctx context.Context, fileID string) (*StreamInfo, error) {
body := map[string]string{"id": fileID}
func (c *Client) GetTranscode(ctx context.Context, transcodeID string) (*StreamInfo, error) {
var raw struct {
Success bool `json:"success"`
Value struct {
@ -545,15 +557,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 +583,7 @@ func (c *Client) GetTranscode(ctx context.Context, transcodeID string) (*StreamI
}
return info, nil
}

View File

@ -95,56 +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
}
// 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

View File

@ -360,6 +360,14 @@ 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)
return
}
job := &download.DownloadJob{
ID: l.ID,
Link: l.DownloadURL,
@ -369,7 +377,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)

View File

@ -51,11 +51,14 @@
</div>
<div class="card">
<section class="section is-info">
<section class="section is-primary">
<h1 class="title">Section</h1>
<h2 class="subtitle">
A simple container to divide your page into <strong>sections</strong>, like
the one you're currently reading.
</h2>
<div class="column">
<div hx-get="/godownloader/settings" hx-trigger="load" hx-target="#download-list"> </div>
<div id="download-list">
<!-- Liste des chemins apparaîtra ici -->
</div>
</div>
</section>
</div>