107 lines
2.7 KiB
Go
107 lines
2.7 KiB
Go
package jobs
|
|
|
|
import (
|
|
"encoding/json"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"ddc/internal/fetch"
|
|
"ddc/internal/files"
|
|
)
|
|
|
|
const (
|
|
phaseDownloading = "downloading"
|
|
phasePaused = "paused"
|
|
phaseFailed = "failed"
|
|
phaseDone = "done"
|
|
)
|
|
|
|
type jobRecord struct {
|
|
SourceURL string `json:"sourceUrl"`
|
|
DisplayURL string `json:"displayUrl"`
|
|
RequestedName string `json:"requestedName,omitempty"`
|
|
FileName string `json:"fileName"`
|
|
AutoExtract bool `json:"autoExtract"`
|
|
Destination string `json:"destination,omitempty"`
|
|
Subfolder string `json:"subfolder,omitempty"`
|
|
Phase string `json:"phase"`
|
|
Message string `json:"message,omitempty"`
|
|
Download *fetch.State `json:"download,omitempty"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
}
|
|
|
|
func (job *Job) record() jobRecord {
|
|
job.mutex.Lock()
|
|
defer job.mutex.Unlock()
|
|
record := jobRecord{
|
|
SourceURL: job.sourceURL,
|
|
DisplayURL: job.displayURL,
|
|
RequestedName: job.requestedName,
|
|
FileName: job.fileName,
|
|
AutoExtract: job.autoExtract,
|
|
Phase: phaseFor(job.status, job.downloaded),
|
|
Message: job.message,
|
|
Download: job.downloadState,
|
|
CreatedAt: job.createdAt,
|
|
}
|
|
if job.target != nil {
|
|
record.Destination = job.target.destination
|
|
record.Subfolder = job.target.subfolder
|
|
}
|
|
return record
|
|
}
|
|
|
|
func phaseFor(status Status, downloaded bool) string {
|
|
switch {
|
|
case downloaded:
|
|
return phaseDone
|
|
case status == StatusPaused:
|
|
return phasePaused
|
|
case status == StatusFailed:
|
|
return phaseFailed
|
|
default:
|
|
return phaseDownloading
|
|
}
|
|
}
|
|
|
|
func (job *Job) saveRecord() {
|
|
data, err := json.MarshalIndent(job.record(), "", " ")
|
|
if err != nil {
|
|
log.Printf("could not encode download %s: %v", job.id, err)
|
|
return
|
|
}
|
|
job.recordMutex.Lock()
|
|
defer job.recordMutex.Unlock()
|
|
if err := files.WriteAtomically(filepath.Join(job.directory, files.JobFileName), data); err != nil && !os.IsNotExist(err) {
|
|
log.Printf("could not save download %s: %v", job.id, err)
|
|
}
|
|
}
|
|
|
|
func readRecord(directory string) (jobRecord, bool) {
|
|
data, err := os.ReadFile(filepath.Join(directory, files.JobFileName))
|
|
if err != nil {
|
|
return jobRecord{}, false
|
|
}
|
|
var record jobRecord
|
|
if err := json.Unmarshal(data, &record); err != nil {
|
|
return jobRecord{}, false
|
|
}
|
|
return record, true
|
|
}
|
|
|
|
func (job *Job) applyRecord(record jobRecord) {
|
|
job.sourceURL = record.SourceURL
|
|
job.displayURL = record.DisplayURL
|
|
job.requestedName = record.RequestedName
|
|
job.fileName = record.FileName
|
|
job.autoExtract = record.AutoExtract
|
|
if !record.CreatedAt.IsZero() {
|
|
job.createdAt = record.CreatedAt
|
|
}
|
|
if record.Destination != "" {
|
|
job.target = &moveTarget{destination: record.Destination, subfolder: record.Subfolder}
|
|
}
|
|
}
|