Merge branch 'main' of https://lab.canguidev.fr/cangui/shelfy
This commit is contained in:
commit
2cdee0eed1
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
Loading…
Reference in New Issue
Block a user