-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
145 lines (120 loc) · 3.77 KB
/
main.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"context"
"database/sql"
_ "embed"
"os"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
_ "github.com/mattn/go-sqlite3"
"github.com/zibbp/spotify-playlist-sync/config"
"github.com/zibbp/spotify-playlist-sync/convert"
"github.com/zibbp/spotify-playlist-sync/db"
"github.com/zibbp/spotify-playlist-sync/spotify"
"github.com/zibbp/spotify-playlist-sync/tidal"
"github.com/urfave/cli/v2"
)
//go:embed schema.sql
var ddl string
func initialize() (*config.Config, *config.JsonConfigService, *spotify.Service, *db.Queries) {
ctx := context.Background()
// initialize config
c, err := config.Init()
if err != nil {
log.Fatal().Err(err).Msg("Failed to load config")
}
// database
dbConn, err := sql.Open("sqlite3", "/data/tracks.db")
if err != nil {
log.Fatal().Err(err).Msg("Failed to open database")
}
// create tables
if _, err := dbConn.ExecContext(ctx, ddl); err != nil {
log.Fatal().Err(err).Msg("Failed to create tables")
}
queries := db.New(dbConn)
// load json config which has credentials
jsonConfig := config.NewJsonConfigService("/data/config.json")
err = jsonConfig.Init()
if err != nil {
log.Fatal().Err(err).Msg("Failed to load Spotify config")
}
// initialize the spotify connection
spotifyService, err := spotify.Initialize(c.SpotifyClientId, c.SpotifyClientSecret, c.SpotifyRedirectUri, jsonConfig)
if err != nil {
log.Fatal().Err(err).Msg("Failed to initialize Spotify service")
}
// authenticate with spotify
err = spotifyService.Authenticate()
if err != nil {
log.Fatal().Err(err).Msg("Failed to authenticate with Spotify")
}
return c, jsonConfig, spotifyService, queries
}
func main() {
var saveMissingTracks bool
var saveTidalPlaylist bool
var saveNavidromePlaylist bool
app := &cli.App{
Name: "spotify-playlist-sync",
Usage: "sync spotify playlists to other services",
Commands: []*cli.Command{
{
Name: "tidal",
Usage: "sync playlists to tidal",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "save-missing-tracks",
Usage: "Save missing tracks during the conversion",
Destination: &saveMissingTracks,
},
&cli.BoolFlag{
Name: "save-tidal-playlist",
Usage: "Save the tidal playlist",
Destination: &saveTidalPlaylist,
},
&cli.BoolFlag{
Name: "save-navidrome-playlist",
Usage: "Save a version of the tidal playlist for importing in Navidrome",
Destination: &saveNavidromePlaylist,
},
},
Action: func(cCtx *cli.Context) error {
c, jsonConfigService, spotifyService, queries := initialize()
tidalService, err := tidal.Initialize(c.TidalClientId, c.TidalClientSecret, jsonConfigService)
if err != nil {
log.Fatal().Err(err).Msg("Failed to initialize Tidal service")
}
// authenticate with Tidal
err = tidalService.DeviceAuthenticate()
if err != nil {
log.Fatal().Err(err).Msg("Failed to authenticate with Tidal")
}
// convert
convertService, err := convert.Initialize(spotifyService, tidalService, jsonConfigService, queries)
if err != nil {
log.Fatal().Err(err).Msg("Failed to initialize convert service")
}
err = convertService.SpotifyToTidal(saveMissingTracks, saveTidalPlaylist, saveMissingTracks)
if err != nil {
log.Fatal().Err(err).Msg("Failed to convert Spotify to Tidal")
}
return nil
},
},
},
}
debug := os.Getenv("DEBUG")
if debug == "true" {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
} else {
zerolog.SetGlobalLevel(zerolog.InfoLevel)
}
container := os.Getenv("CONTAINER")
if container != "true" {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
}
if err := app.Run(os.Args); err != nil {
log.Fatal().Err(err).Msg("Failed to run app")
}
}