+++ /dev/null
-package main
-
-import (
- "code.octet-stream.net/broadcaster/protocol"
- "crypto/sha256"
- "encoding/hex"
- "io"
- "log"
- "net/http"
- "os"
- "path/filepath"
-)
-
-type FilesMachine struct {
- specs []protocol.FileSpec
- cachePath string
- missing []string
-}
-
-func NewFilesMachine(cachePath string) FilesMachine {
- if err := os.MkdirAll(cachePath, 0750); err != nil {
- log.Fatal(err)
- }
- return FilesMachine{
- cachePath: cachePath,
- }
-}
-
-func (m *FilesMachine) UpdateSpecs(specs []protocol.FileSpec) {
- m.specs = specs
- m.RefreshMissing()
-}
-
-func (m *FilesMachine) RefreshMissing() {
- // Delete any files in the cache dir who are not in the spec
- entries, err := os.ReadDir(m.cachePath)
- if err != nil {
- log.Fatal(err)
- }
- okay := make([]string, 0)
- for _, file := range entries {
- hash := ""
- for _, spec := range m.specs {
- if file.Name() == spec.Name {
- hash = spec.Hash
- break
- }
- }
- // if we have an extraneous file, delete it
- if hash == "" {
- log.Println("Deleting extraneous cached audio file:", file.Name())
- os.Remove(filepath.Join(m.cachePath, file.Name()))
- continue
- }
- // if the hash isn't right, delete it
- f, err := os.Open(filepath.Join(m.cachePath, file.Name()))
- if err != nil {
- log.Fatal(err)
- }
- hasher := sha256.New()
- io.Copy(hasher, f)
- if hex.EncodeToString(hasher.Sum(nil)) != hash {
- log.Println("Deleting cached audio file with incorrect hash:", file.Name())
- os.Remove(filepath.Join(m.cachePath, file.Name()))
- } else {
- okay = append(okay, file.Name())
- }
- }
- m.missing = nil
- for _, spec := range m.specs {
- missing := true
- for _, file := range okay {
- if spec.Name == file {
- missing = false
- }
- }
- if missing {
- m.missing = append(m.missing, spec.Name)
- }
- }
- if len(m.missing) > 1 {
- log.Println(len(m.missing), "missing files")
- } else if len(m.missing) == 1 {
- log.Println("1 missing file")
- } else {
- log.Println("All files are in sync with server")
- }
- statusCollector.FilesInSync <- len(m.missing) == 0
-}
-
-func (m *FilesMachine) IsCacheComplete() bool {
- return len(m.missing) == 0
-}
-
-func (m *FilesMachine) NextFile() string {
- next, remainder := m.missing[0], m.missing[1:]
- m.missing = remainder
- return next
-}
-
-func (m *FilesMachine) DownloadSingle(filename string, downloadResult chan<- error) {
- log.Println("Downloading", filename)
- out, err := os.Create(filepath.Join(m.cachePath, filename))
- if err != nil {
- downloadResult <- err
- return
- }
- defer out.Close()
- resp, err := http.Get(config.ServerURL + "/audio-files/" + filename)
- if err != nil {
- downloadResult <- err
- return
- }
- defer resp.Body.Close()
- _, err = io.Copy(out, resp.Body)
- downloadResult <- err
-}