mirror of
https://git.sr.ht/~phw/scotty
synced 2025-06-05 04:58:33 +02:00
Allow reading Spotify history directly from ZIP file
This commit is contained in:
parent
ef6780701a
commit
7fb77da135
3 changed files with 108 additions and 33 deletions
82
internal/backends/spotifyhistory/archive.go
Normal file
82
internal/backends/spotifyhistory/archive.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright © 2025 Philipp Wolfer <phw@uploadedlobster.com>
|
||||
|
||||
This file is part of Scotty.
|
||||
|
||||
Scotty is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
|
||||
Scotty is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
Scotty. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package spotifyhistory
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
|
||||
"go.uploadedlobster.com/scotty/internal/archive"
|
||||
)
|
||||
|
||||
var historyFileGlobs = []string{
|
||||
"Spotify Extended Streaming History/Streaming_History_Audio_*.json",
|
||||
"Streaming_History_Audio_*.json",
|
||||
}
|
||||
|
||||
// Access a Spotify history archive.
|
||||
// This can be either the ZIP file as provided by Spotify
|
||||
// or a directory where this was extracted to.
|
||||
type HistoryArchive struct {
|
||||
backend archive.Archive
|
||||
}
|
||||
|
||||
// Open a Spotify history archive from file path.
|
||||
func OpenHistoryArchive(path string) (*HistoryArchive, error) {
|
||||
backend, err := archive.OpenArchive(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &HistoryArchive{backend: backend}, nil
|
||||
}
|
||||
|
||||
func (h *HistoryArchive) GetHistoryFiles() ([]archive.FileInfo, error) {
|
||||
for _, glob := range historyFileGlobs {
|
||||
files, err := h.backend.Glob(glob)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(files) > 0 {
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
return files[i].Name < files[j].Name
|
||||
})
|
||||
return files, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Found no files, fail
|
||||
return nil, errors.New("found no history files in archive")
|
||||
}
|
||||
|
||||
func readHistoryFile(f archive.OpenableFile) (StreamingHistory, error) {
|
||||
file, err := f.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer file.Close()
|
||||
history := StreamingHistory{}
|
||||
err = history.Read(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue