-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed_service.go
106 lines (88 loc) · 2.49 KB
/
feed_service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package main
import (
"crypto/sha256"
"fmt"
"log"
"mime"
"os"
"path"
)
type storage interface {
Add(PodcastItem) error
Remove(string) (PodcastItem, error)
UpdateDescription(string, Description) (PodcastItem, error)
Items() ([]PodcastItem, error)
}
// FeedService is a service that manages podcast items.
type FeedService struct {
q *DownloadJobQueue
st storage
storagePath string
}
// NewFeedService creates a new FeedService instance.
func NewFeedService(
st storage,
storagePath string,
q *DownloadJobQueue,
downloader fileDownloader,
converter mediaTranscoder,
) *FeedService {
return &FeedService{
st: st,
storagePath: storagePath,
q: q,
}
}
// AddItem adds a new podcast item to the feed.
func (s *FeedService) AddItem(item PodcastItem, audioURL string) error {
filePath := path.Join(s.storagePath, fmt.Sprintf("%x", sha256.Sum256([]byte(audioURL))))
if exts, err := mime.ExtensionsByType(item.MIMEType); err != nil {
log.Printf("failed to get file extensions list for %s: %s", item.MIMEType, err)
} else if len(exts) == 0 {
log.Printf("no file extension registered for %s", item.MIMEType)
} else {
if exts[0] == ".f4a" {
exts[0] = ".m4a"
}
log.Printf("using %s as file extension for %s", exts[0], item.MIMEType)
filePath += exts[0]
}
item.FileName, item.Status = path.Base(filePath), ItemAdded
if err := s.st.Add(item); err != nil {
return fmt.Errorf("failed to add item to the feed: %w", err)
}
if err := s.q.Add(NewDownloadJob(item.ID(), audioURL, filePath)); err != nil {
return fmt.Errorf("failed to add download job for %s: %w", audioURL, err)
}
return nil
}
// UpdateItem updates an existing podcast item.
func (s *FeedService) UpdateItem(itemID string, desc Description) error {
log.Printf("updating %s", itemID)
_, err := s.st.UpdateDescription(itemID, desc)
if err != nil {
return err
}
return nil
}
// RemoveItem removes an existing podcast item.
func (s *FeedService) RemoveItem(itemID string) error {
log.Printf("removing %s", itemID)
item, err := s.st.Remove(itemID)
if err != nil {
return err
}
filePath := path.Join(s.storagePath, item.FileName)
if err := os.Remove(filePath); err != nil {
return fmt.Errorf("failed to delete %s: %w", filePath, err)
}
return nil
}
// Items returns a list of podcast items.
func (s *FeedService) Items() ([]PodcastItem, error) {
items, err := s.st.Items()
if err != nil {
return nil, fmt.Errorf("failed to fetch podcast items: %w", err)
}
return items, nil
}