U-pod/pod.go

123 lines
2.7 KiB
Go

package main
import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/dhowden/tag"
"github.com/google/uuid"
)
type Episode struct {
Title string
File string
Cover string
PubDate string
Artist string
Size int64
}
var (
lastMod time.Time
rssLock sync.Mutex
)
func generateUUIDFromString(input string) uuid.UUID {
namespace := uuid.NameSpaceDNS // Namespace fisso per consistenza
return uuid.NewSHA1(namespace, []byte(input))
}
func generateRSS() error {
rssLock.Lock()
defer rssLock.Unlock()
episodes, err := scanEpisodes()
if err != nil {
return err
}
rss := fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
xmlns:podcast="https://podcastindex.org/namespace/1.0"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<description>%s</description>
<title>%s</title>
<link>%s</link>`, podTitle, podTitle, baseURL)
for _, ep := range episodes {
rss += fmt.Sprintf(`
<item>
<title>%s</title>
<enclosure url="%s/audio/%s" type="audio/mpeg" length="%d"/>
<pubDate>%s</pubDate>
`, ep.Title, baseURL, filepath.Base(ep.File), ep.Size, ep.PubDate)
if ep.Cover != "" {
rss += fmt.Sprintf(`
<itunes:image href="%s/covers/%s"/>`, baseURL, ep.Cover)
}
if ep.Artist != "" {
rss += fmt.Sprintf(`
<itunes:author>%s</itunes:author>`, ep.Artist)
}
rss += fmt.Sprintf(`<link>%s/audio/%s</link>`, baseURL, filepath.Base(ep.File))
rss += fmt.Sprintf(`<guid isPermaLink="false">%s</guid>`, generateUUIDFromString(ep.Title).String())
rss += fmt.Sprintf(`<description>%s</description>`, ep.Title)
rss += "\n </item>"
}
rss += "\n</channel>\n</rss>"
return os.WriteFile("feed.xml", []byte(rss), 0644)
}
func scanEpisodes() ([]Episode, error) {
var episodes []Episode
err := filepath.Walk(audioDir, func(path string, info os.FileInfo, err error) error {
if err != nil || info.IsDir() || !strings.HasSuffix(strings.ToLower(path), ".mp3") {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
meta, err := tag.ReadFrom(file)
if err != nil {
log.Printf("File %s senza metadati ID3: %v", path, err)
return nil
}
// relPath, _ := filepath.Rel(".", path)
baseName := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
// coverPath := filepath.Join(coversDir, baseName+".jpg")
ep := Episode{
Title: meta.Title(),
Artist: meta.Artist(),
File: baseName + ".mp3",
Cover: baseName + ".jpg",
PubDate: info.ModTime().Format(time.RFC1123),
Size: info.Size(),
}
episodes = append(episodes, ep)
return nil
})
return episodes, err
}