mirror of
https://github.com/gabehf/Koito.git
synced 2026-04-22 20:11:50 -07:00
feat: native import & export
This commit is contained in:
parent
1d02cede49
commit
7b0cff0a07
13 changed files with 645 additions and 2 deletions
172
internal/importer/koito.go
Normal file
172
internal/importer/koito.go
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
package importer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/gabehf/koito/internal/cfg"
|
||||
"github.com/gabehf/koito/internal/db"
|
||||
"github.com/gabehf/koito/internal/export"
|
||||
"github.com/gabehf/koito/internal/logger"
|
||||
"github.com/gabehf/koito/internal/models"
|
||||
"github.com/gabehf/koito/internal/utils"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
)
|
||||
|
||||
func ImportKoitoFile(ctx context.Context, store db.DB, filename string) error {
|
||||
l := logger.FromContext(ctx)
|
||||
l.Info().Msgf("Beginning Koito import on file: %s", filename)
|
||||
data := new(export.KoitoExport)
|
||||
f, err := os.Open(path.Join(cfg.ConfigDir(), "import", filename))
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: os.Open: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
err = json.NewDecoder(f).Decode(data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: Decode: %w", err)
|
||||
}
|
||||
|
||||
if data.Version != "1" {
|
||||
return fmt.Errorf("ImportKoitoFile: unupported version: %s", data.Version)
|
||||
}
|
||||
|
||||
l.Info().Msgf("Beginning data import for user: %s", data.User)
|
||||
|
||||
count := 0
|
||||
|
||||
for i := range data.Listens {
|
||||
// use this for save/get mbid for all artist/album/track
|
||||
mbid := uuid.Nil
|
||||
|
||||
artistIds := make([]int32, 0)
|
||||
for _, ia := range data.Listens[i].Artists {
|
||||
if ia.MBID != nil {
|
||||
mbid = *ia.MBID
|
||||
}
|
||||
artist, err := store.GetArtist(ctx, db.GetArtistOpts{
|
||||
MusicBrainzID: mbid,
|
||||
Name: getPrimaryAliasFromAliasSlice(ia.Aliases),
|
||||
})
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
var imgid = uuid.Nil
|
||||
// not a perfect way to check if the image url is an actual source vs manual upload but
|
||||
// im like 99% sure it will work perfectly
|
||||
if strings.HasPrefix(ia.ImageUrl, "http") {
|
||||
imgid = uuid.New()
|
||||
}
|
||||
// save artist
|
||||
artist, err := store.SaveArtist(ctx, db.SaveArtistOpts{
|
||||
Name: getPrimaryAliasFromAliasSlice(ia.Aliases),
|
||||
Image: imgid,
|
||||
ImageSrc: ia.ImageUrl,
|
||||
MusicBrainzID: mbid,
|
||||
Aliases: utils.FlattenAliases(ia.Aliases),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
}
|
||||
artistIds = append(artistIds, artist.ID)
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
} else {
|
||||
artistIds = append(artistIds, artist.ID)
|
||||
}
|
||||
}
|
||||
// call associate album
|
||||
albumId := int32(0)
|
||||
if data.Listens[i].Album.MBID != nil {
|
||||
mbid = *data.Listens[i].Album.MBID
|
||||
}
|
||||
album, err := store.GetAlbum(ctx, db.GetAlbumOpts{
|
||||
MusicBrainzID: mbid,
|
||||
Title: getPrimaryAliasFromAliasSlice(data.Listens[i].Album.Aliases),
|
||||
ArtistID: artistIds[0],
|
||||
})
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
var imgid = uuid.Nil
|
||||
// not a perfect way to check if the image url is an actual source vs manual upload but
|
||||
// im like 99% sure it will work perfectly
|
||||
if strings.HasPrefix(data.Listens[i].Album.ImageUrl, "http") {
|
||||
imgid = uuid.New()
|
||||
}
|
||||
// save album
|
||||
album, err = store.SaveAlbum(ctx, db.SaveAlbumOpts{
|
||||
Title: getPrimaryAliasFromAliasSlice(data.Listens[i].Album.Aliases),
|
||||
Image: imgid,
|
||||
ImageSrc: data.Listens[i].Album.ImageUrl,
|
||||
MusicBrainzID: mbid,
|
||||
Aliases: utils.FlattenAliases(data.Listens[i].Album.Aliases),
|
||||
ArtistIDs: artistIds,
|
||||
VariousArtists: data.Listens[i].Album.VariousArtists,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
}
|
||||
albumId = album.ID
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
} else {
|
||||
albumId = album.ID
|
||||
}
|
||||
|
||||
// call associate track
|
||||
if data.Listens[i].Track.MBID != nil {
|
||||
mbid = *data.Listens[i].Track.MBID
|
||||
}
|
||||
track, err := store.GetTrack(ctx, db.GetTrackOpts{
|
||||
MusicBrainzID: mbid,
|
||||
Title: getPrimaryAliasFromAliasSlice(data.Listens[i].Track.Aliases),
|
||||
ArtistIDs: artistIds,
|
||||
})
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
// save track
|
||||
track, err = store.SaveTrack(ctx, db.SaveTrackOpts{
|
||||
Title: getPrimaryAliasFromAliasSlice(data.Listens[i].Track.Aliases),
|
||||
RecordingMbzID: mbid,
|
||||
Duration: int32(data.Listens[i].Track.Duration),
|
||||
ArtistIDs: artistIds,
|
||||
AlbumID: albumId,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
}
|
||||
// save track aliases
|
||||
err = store.SaveTrackAliases(ctx, track.ID, utils.FlattenAliases(data.Listens[i].Track.Aliases), "Import")
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
}
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
}
|
||||
|
||||
// save listen
|
||||
err = store.SaveListen(ctx, db.SaveListenOpts{
|
||||
TrackID: track.ID,
|
||||
Time: data.Listens[i].ListenedAt,
|
||||
UserID: 1,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("ImportKoitoFile: %w", err)
|
||||
}
|
||||
|
||||
l.Info().Msgf("ImportKoitoFile: Imported listen for track %s", track.Title)
|
||||
count++
|
||||
}
|
||||
|
||||
return finishImport(ctx, filename, count)
|
||||
}
|
||||
func getPrimaryAliasFromAliasSlice(aliases []models.Alias) string {
|
||||
for _, a := range aliases {
|
||||
if a.Primary {
|
||||
return a.Alias
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue