handleStartDownload starts a new download job.
(w http.ResponseWriter, r *http.Request)
| 105 | |
| 106 | // handleStartDownload starts a new download job. |
| 107 | func (s *Server) handleStartDownload(w http.ResponseWriter, r *http.Request) { |
| 108 | var req DownloadRequest |
| 109 | if err := json.NewDecoder(r.Body).Decode(&req); err != nil { |
| 110 | writeError(w, http.StatusBadRequest, "Invalid request body", err.Error()) |
| 111 | return |
| 112 | } |
| 113 | |
| 114 | // Validate |
| 115 | if req.Repo == "" { |
| 116 | writeError(w, http.StatusBadRequest, "Missing required field: repo", "") |
| 117 | return |
| 118 | } |
| 119 | |
| 120 | // Parse filters from repo:filter syntax |
| 121 | if strings.Contains(req.Repo, ":") && len(req.Filters) == 0 { |
| 122 | parts := strings.SplitN(req.Repo, ":", 2) |
| 123 | req.Repo = parts[0] |
| 124 | if parts[1] != "" { |
| 125 | for _, f := range strings.Split(parts[1], ",") { |
| 126 | f = strings.TrimSpace(f) |
| 127 | if f != "" { |
| 128 | req.Filters = append(req.Filters, f) |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | if !hfdownloader.IsValidModelName(req.Repo) { |
| 135 | writeError(w, http.StatusBadRequest, "Invalid repo format", "Expected owner/name") |
| 136 | return |
| 137 | } |
| 138 | |
| 139 | // If dry-run, return the plan |
| 140 | if req.DryRun { |
| 141 | s.handlePlanInternal(w, req) |
| 142 | return |
| 143 | } |
| 144 | |
| 145 | // Create and start the job (or return existing if duplicate) |
| 146 | job, wasExisting, err := s.jobs.CreateJob(req) |
| 147 | if err != nil { |
| 148 | writeError(w, http.StatusInternalServerError, "Failed to create job", err.Error()) |
| 149 | return |
| 150 | } |
| 151 | |
| 152 | // Return appropriate status |
| 153 | if wasExisting { |
| 154 | // Job already exists for this repo - return it with 200 |
| 155 | writeJSON(w, http.StatusOK, map[string]any{ |
| 156 | "job": job, |
| 157 | "message": "Download already in progress", |
| 158 | }) |
| 159 | } else { |
| 160 | // New job created |
| 161 | writeJSON(w, http.StatusAccepted, job) |
| 162 | } |
| 163 | } |
| 164 |