feat: add download tracking endpoints (sections 4.1, 4.2, 4.3, 4.4)
This commit is contained in:
@@ -607,3 +607,155 @@ func (db *DB) GetArtistIDByAlbum(ctx context.Context, albumID uuid.UUID) (*uuid.
|
||||
}
|
||||
return &artistID, nil
|
||||
}
|
||||
|
||||
type DownloadQueueRow struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
ArtistID *uuid.UUID `json:"artist_id"`
|
||||
AlbumID *uuid.UUID `json:"album_id"`
|
||||
DownloadID *string `json:"download_id"`
|
||||
Title string `json:"title"`
|
||||
Size int64 `json:"size"`
|
||||
SizeLeft int64 `json:"size_left"`
|
||||
Status string `json:"status"`
|
||||
Progress float32 `json:"progress"`
|
||||
ErrorMessage *string `json:"error_message"`
|
||||
Protocol string `json:"protocol"`
|
||||
Indexer *string `json:"indexer"`
|
||||
DownloadClient *string `json:"download_client"`
|
||||
TorrentHash *string `json:"torrent_hash"`
|
||||
OutputPath *string `json:"output_path"`
|
||||
AddedAt time.Time `json:"added_at"`
|
||||
CompletedAt *time.Time `json:"completed_at"`
|
||||
}
|
||||
|
||||
func (db *DB) AddToDownloadQueue(ctx context.Context, title string, size int64, torrentHash, indexer *string, albumID, artistID *uuid.UUID) (uuid.UUID, error) {
|
||||
var id uuid.UUID
|
||||
err := db.pool.QueryRow(ctx, `
|
||||
INSERT INTO download_queue (title, size, torrent_hash, indexer, album_id, artist_id, status)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, 'queued')
|
||||
RETURNING id
|
||||
`, title, size, torrentHash, indexer, albumID, artistID).Scan(&id)
|
||||
return id, err
|
||||
}
|
||||
|
||||
func (db *DB) GetDownloadQueueItem(ctx context.Context, id uuid.UUID) (*DownloadQueueRow, error) {
|
||||
var row DownloadQueueRow
|
||||
err := db.pool.QueryRow(ctx, `
|
||||
SELECT id, artist_id, album_id, download_id, title, size, size_left, status, progress,
|
||||
error_message, protocol, indexer, download_client, torrent_hash, output_path, added_at, completed_at
|
||||
FROM download_queue WHERE id = $1
|
||||
`, id).Scan(&row.ID, &row.ArtistID, &row.AlbumID, &row.DownloadID, &row.Title, &row.Size,
|
||||
&row.SizeLeft, &row.Status, &row.Progress, &row.ErrorMessage, &row.Protocol, &row.Indexer,
|
||||
&row.DownloadClient, &row.TorrentHash, &row.OutputPath, &row.AddedAt, &row.CompletedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
func (db *DB) ListDownloadQueue(ctx context.Context, status *string) ([]DownloadQueueRow, error) {
|
||||
var rows []DownloadQueueRow
|
||||
var query string
|
||||
var args []any
|
||||
|
||||
if status != nil {
|
||||
query = `
|
||||
SELECT id, artist_id, album_id, download_id, title, size, size_left, status, progress,
|
||||
error_message, protocol, indexer, download_client, torrent_hash, output_path, added_at, completed_at
|
||||
FROM download_queue WHERE status = $1 ORDER BY added_at DESC
|
||||
`
|
||||
args = []any{*status}
|
||||
} else {
|
||||
query = `
|
||||
SELECT id, artist_id, album_id, download_id, title, size, size_left, status, progress,
|
||||
error_message, protocol, indexer, download_client, torrent_hash, output_path, added_at, completed_at
|
||||
FROM download_queue ORDER BY added_at DESC
|
||||
`
|
||||
}
|
||||
|
||||
dbRows, err := db.pool.Query(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer dbRows.Close()
|
||||
|
||||
for dbRows.Next() {
|
||||
var row DownloadQueueRow
|
||||
err := dbRows.Scan(&row.ID, &row.ArtistID, &row.AlbumID, &row.DownloadID, &row.Title, &row.Size,
|
||||
&row.SizeLeft, &row.Status, &row.Progress, &row.ErrorMessage, &row.Protocol, &row.Indexer,
|
||||
&row.DownloadClient, &row.TorrentHash, &row.OutputPath, &row.AddedAt, &row.CompletedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, row)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func (db *DB) UpdateDownloadQueueStatus(ctx context.Context, id uuid.UUID, status string, errorMessage *string) error {
|
||||
if status == "completed" {
|
||||
_, err := db.pool.Exec(ctx, `
|
||||
UPDATE download_queue SET status = $1, completed_at = NOW() WHERE id = $2
|
||||
`, status, id)
|
||||
return err
|
||||
}
|
||||
if errorMessage != nil {
|
||||
_, err := db.pool.Exec(ctx, `
|
||||
UPDATE download_queue SET status = $1, error_message = $2 WHERE id = $3
|
||||
`, status, *errorMessage, id)
|
||||
return err
|
||||
}
|
||||
_, err := db.pool.Exec(ctx, `
|
||||
UPDATE download_queue SET status = $1 WHERE id = $2
|
||||
`, status, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) UpdateDownloadQueueProgress(ctx context.Context, id uuid.UUID, progress float32, sizeLeft int64, status string) error {
|
||||
_, err := db.pool.Exec(ctx, `
|
||||
UPDATE download_queue SET progress = $1, size_left = $2, status = $3 WHERE id = $4
|
||||
`, progress, sizeLeft, status, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) DeleteDownloadQueueItem(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := db.pool.Exec(ctx, `DELETE FROM download_queue WHERE id = $1`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (db *DB) GetDownloadQueueByTorrentHash(ctx context.Context, hash string) (*DownloadQueueRow, error) {
|
||||
var row DownloadQueueRow
|
||||
err := db.pool.QueryRow(ctx, `
|
||||
SELECT id, artist_id, album_id, download_id, title, size, size_left, status, progress,
|
||||
error_message, protocol, indexer, download_client, torrent_hash, output_path, added_at, completed_at
|
||||
FROM download_queue WHERE torrent_hash = $1
|
||||
`, hash).Scan(&row.ID, &row.ArtistID, &row.AlbumID, &row.DownloadID, &row.Title, &row.Size,
|
||||
&row.SizeLeft, &row.Status, &row.Progress, &row.ErrorMessage, &row.Protocol, &row.Indexer,
|
||||
&row.DownloadClient, &row.TorrentHash, &row.OutputPath, &row.AddedAt, &row.CompletedAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
type DownloadQueueStats struct {
|
||||
Total int64 `json:"total"`
|
||||
Downloading int64 `json:"downloading"`
|
||||
Queued int64 `json:"queued"`
|
||||
Completed int64 `json:"completed"`
|
||||
Failed int64 `json:"failed"`
|
||||
}
|
||||
|
||||
func (db *DB) GetDownloadQueueStats(ctx context.Context) (*DownloadQueueStats, error) {
|
||||
var stats DownloadQueueStats
|
||||
err := db.pool.QueryRow(ctx, `
|
||||
SELECT
|
||||
COUNT(*) as total,
|
||||
COUNT(*) FILTER (WHERE status = 'downloading') as downloading,
|
||||
COUNT(*) FILTER (WHERE status = 'queued') as queued,
|
||||
COUNT(*) FILTER (WHERE status = 'completed') as completed,
|
||||
COUNT(*) FILTER (WHERE status = 'failed') as failed
|
||||
FROM download_queue
|
||||
`).Scan(&stats.Total, &stats.Downloading, &stats.Queued, &stats.Completed, &stats.Failed)
|
||||
return &stats, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user