mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-21 16:11:56 +00:00
Changes
This commit is contained in:
parent
6c52aa7d78
commit
89b20fbf6f
@ -21,6 +21,7 @@ This assumes you have goscrobble-api and goscrobble-web cloned in the same folde
|
|||||||
|
|
||||||
Access API @ http://127.0.0.1:42069/api/v1
|
Access API @ http://127.0.0.1:42069/api/v1
|
||||||
Access frontend @ http://127.0.0.1:3000
|
Access frontend @ http://127.0.0.1:3000
|
||||||
|
pgAdmin @ http://127.0.0.1:5050 (admin@admin.com / root)
|
||||||
|
|
||||||
## Prod deployment
|
## Prod deployment
|
||||||
cp .env.production .env # Fill in the blanks
|
cp .env.production .env # Fill in the blanks
|
||||||
|
@ -26,6 +26,8 @@ services:
|
|||||||
image: postgres:14.1
|
image: postgres:14.1
|
||||||
volumes:
|
volumes:
|
||||||
- database-data:/var/lib/postgresql/data/
|
- database-data:/var/lib/postgresql/data/
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_USER=goscrobble
|
- POSTGRES_USER=goscrobble
|
||||||
@ -37,6 +39,16 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:6379:6379"
|
- "127.0.0.1:6379:6379"
|
||||||
|
|
||||||
|
pgadmin:
|
||||||
|
container_name: pgadmin4_container
|
||||||
|
image: dpage/pgadmin4
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
PGADMIN_DEFAULT_EMAIL: admin@admin.com
|
||||||
|
PGADMIN_DEFAULT_PASSWORD: root
|
||||||
|
ports:
|
||||||
|
- "5050:80"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
database-data:
|
database-data:
|
||||||
data:
|
data:
|
95
docs/migrate.php
Normal file
95
docs/migrate.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Temp script to migrate old data from MySQL to PostgreSQL
|
||||||
|
|
||||||
|
// PLEASE RUN ALL MIGRATIONS ON POSTGRES BEFORE RUNNING THIS.
|
||||||
|
|
||||||
|
echo PHP_EOL . "Loading connections...";
|
||||||
|
|
||||||
|
global $mysqli;
|
||||||
|
$mysqli = new mysqli('172.27.138.37', 'goscrobble', 'X9u7jdfy', 'goscrobble');
|
||||||
|
if ($mysqli->connect_errno) {
|
||||||
|
die("Failed to connect to MySQL");
|
||||||
|
}
|
||||||
|
|
||||||
|
global $postgres;
|
||||||
|
$postgres = new PDO("pgsql:host=127.0.0.1;port=5432;dbname=goscrobble;user=goscrobble;password=supersecretdatabasepassword1");
|
||||||
|
|
||||||
|
function getArray($query): array
|
||||||
|
{
|
||||||
|
global $mysqli;
|
||||||
|
if (!$result = $mysqli->query($query)) {
|
||||||
|
die($mysqli->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo PHP_EOL . "Skipping schema_migrations (Already exists)";
|
||||||
|
|
||||||
|
echo PHP_EOL . "Migrating config";
|
||||||
|
// $config = getArray("SELECT * FROM config");
|
||||||
|
// $update = $postgres->prepare("UPDATE config SET value = ? WHERE key = ?");
|
||||||
|
// foreach ($config as $row) {
|
||||||
|
// $update->execute([
|
||||||
|
// $row['value'],
|
||||||
|
// $row['key'],
|
||||||
|
// ]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
echo PHP_EOL . "Migrating users";
|
||||||
|
$users = getArray("SELECT
|
||||||
|
BIN_TO_UUID(uuid, true) as uuid,
|
||||||
|
created_at,
|
||||||
|
inet_ntoa(conv(created_ip, 16, 10)) as created_ip,
|
||||||
|
modified_at,
|
||||||
|
inet_ntoa(modified_ip) as modified_ip,
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
email,
|
||||||
|
verified,
|
||||||
|
active,
|
||||||
|
admin,
|
||||||
|
`mod`,
|
||||||
|
token,
|
||||||
|
private,
|
||||||
|
timezone
|
||||||
|
FROM users;");
|
||||||
|
|
||||||
|
$update = $postgres->prepare("INSERT INTO users (uuid, created_at, created_ip, modified_at, modified_ip, username, password, email, verified, active, admin, mod, token, private, timezone) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
|
||||||
|
foreach ($users as $row) {
|
||||||
|
echo PHP_EOL . $row['username'];
|
||||||
|
$update->execute([
|
||||||
|
$row['uuid'],
|
||||||
|
$row['created_at'],
|
||||||
|
$row['created_ip'],
|
||||||
|
$row['modified_at'],
|
||||||
|
$row['modified_ip'],
|
||||||
|
$row['username'],
|
||||||
|
$row['password'],
|
||||||
|
$row['email'],
|
||||||
|
$row['verified'],
|
||||||
|
$row['active'],
|
||||||
|
$row['admin'],
|
||||||
|
$row['mod'],
|
||||||
|
$row['token'],
|
||||||
|
$row['private'],
|
||||||
|
$row['timezone'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo PHP_EOL . "Migrating albums";
|
||||||
|
// echo PHP_EOL . "Migrating artists";
|
||||||
|
// echo PHP_EOL . "Migrating tracks";
|
||||||
|
// echo PHP_EOL . "Migrating genres";
|
||||||
|
// echo PHP_EOL . "Migrating links";
|
||||||
|
// echo PHP_EOL . "Migrating oauth_tokens";
|
||||||
|
// echo PHP_EOL . "Migrating refresh_tokens";
|
||||||
|
// echo PHP_EOL . "Migrating resettoken";
|
||||||
|
// echo PHP_EOL . "Migrating album_artist";
|
||||||
|
// echo PHP_EOL . "Migrating track_album";
|
||||||
|
// echo PHP_EOL . "Migrating track_artist";
|
||||||
|
// echo PHP_EOL . "Migrating scrobbles";
|
@ -73,7 +73,7 @@ func insertAlbum(name string, mbid string, spotifyId string, artists []string, i
|
|||||||
func getAlbumByCol(col string, val string, tx *sql.Tx) Album {
|
func getAlbumByCol(col string, val string, tx *sql.Tx) Album {
|
||||||
var album Album
|
var album Album
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
"SELECT uuid, name, IFNULL(desc, ''), IFNULL(img,''), mbid, spotify_id FROM albums WHERE "+col+" = $1",
|
`SELECT uuid, name, COALESCE(desc, ''), COALESCE(img,''), mbid, spotify_id FROM albums WHERE "`+col+`" = $1`,
|
||||||
val).Scan(&album.UUID, &album.Name, &album.Desc, &album.Img, &album.MusicBrainzID, &album.SpotifyID)
|
val).Scan(&album.UUID, &album.Name, &album.Desc, &album.Img, &album.MusicBrainzID, &album.SpotifyID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -92,8 +92,8 @@ func insertNewAlbum(album *Album, name string, mbid string, spotifyId string, im
|
|||||||
album.SpotifyID = spotifyId
|
album.SpotifyID = spotifyId
|
||||||
album.Img = img
|
album.Img = img
|
||||||
|
|
||||||
_, err := tx.Exec("INSERT INTO albums (uuid, name, mbid, spotify_id, img) "+
|
_, err := tx.Exec(`INSERT INTO albums (uuid, name, mbid, spotify_id, img) `+
|
||||||
"VALUES ($1,$2,$3,$4,$5)", album.UUID, album.Name, album.MusicBrainzID, album.SpotifyID, album.Img)
|
`VALUES ($1,$2,$3,$4,$5)`, album.UUID, album.Name, album.MusicBrainzID, album.SpotifyID, album.Img)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -101,8 +101,8 @@ func insertNewAlbum(album *Album, name string, mbid string, spotifyId string, im
|
|||||||
func (album *Album) linkAlbumToArtists(artists []string, tx *sql.Tx) error {
|
func (album *Album) linkAlbumToArtists(artists []string, tx *sql.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
for _, artist := range artists {
|
for _, artist := range artists {
|
||||||
_, err = tx.Exec("INSERT INTO album_artist (album, artist) "+
|
_, err = tx.Exec(`INSERT INTO album_artist (album, artist) `+
|
||||||
"VALUES ($1,$2)", album.UUID, artist)
|
`VALUES ($1,$2)`, album.UUID, artist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -112,14 +112,14 @@ func (album *Album) linkAlbumToArtists(artists []string, tx *sql.Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (album *Album) updateAlbum(col string, val string, tx *sql.Tx) error {
|
func (album *Album) updateAlbum(col string, val string, tx *sql.Tx) error {
|
||||||
_, err := tx.Exec("UPDATE albums SET "+col+" = $1 WHERE uuid = $2", val, album.UUID)
|
_, err := tx.Exec(`UPDATE albums SET "`+col+`" = $1 WHERE uuid = $2`, val, album.UUID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAlbumByUUID(uuid string) (Album, error) {
|
func getAlbumByUUID(uuid string) (Album, error) {
|
||||||
var album Album
|
var album Album
|
||||||
err := db.QueryRow("SELECT uuid, name, IFNULL(desc,''), IFNULL(img,''), mbid, spotify_id FROM albums WHERE uuid = $1",
|
err := db.QueryRow(`SELECT uuid, name, COALESCE(desc,''), COALESCE(img,''), mbid, spotify_id FROM albums WHERE uuid = $1`,
|
||||||
uuid).Scan(&album.UUID, &album.Name, &album.Desc, &album.Img, &album.MusicBrainzID, &album.SpotifyID)
|
uuid).Scan(&album.UUID, &album.Name, &album.Desc, &album.Img, &album.MusicBrainzID, &album.SpotifyID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -83,7 +83,7 @@ func insertArtist(name string, mbid string, spotifyId string, img string, tx *sq
|
|||||||
func getArtistByCol(col string, val string, tx *sql.Tx) Artist {
|
func getArtistByCol(col string, val string, tx *sql.Tx) Artist {
|
||||||
var artist Artist
|
var artist Artist
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
"SELECT uuid, name, IFNULL(desc,''), IFNULL(img,''), mbid, spotify_id FROM artists WHERE "+col+" = $1",
|
`SELECT uuid, name, COALESCE(desc,''), COALESCE(img,''), mbid, spotify_id FROM artists WHERE "`+col+`" = $1`,
|
||||||
val).Scan(&artist.UUID, &artist.Name, &artist.Desc, &artist.Img, &artist.MusicBrainzID, &artist.SpotifyID)
|
val).Scan(&artist.UUID, &artist.Name, &artist.Desc, &artist.Img, &artist.MusicBrainzID, &artist.SpotifyID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -102,21 +102,21 @@ func insertNewArtist(artist *Artist, name string, mbid string, spotifyId string,
|
|||||||
artist.SpotifyID = spotifyId
|
artist.SpotifyID = spotifyId
|
||||||
artist.Img = img
|
artist.Img = img
|
||||||
|
|
||||||
_, err := tx.Exec("INSERT INTO artists (uuid, name, mbid, spotify_id, img) "+
|
_, err := tx.Exec(`INSERT INTO artists (uuid, name, mbid, spotify_id, img) `+
|
||||||
"VALUES ($1,$2,$3,$4,$5)", artist.UUID, artist.Name, artist.MusicBrainzID, artist.SpotifyID, artist.Img)
|
`VALUES ($1,$2,$3,$4,$5)`, artist.UUID, artist.Name, artist.MusicBrainzID, artist.SpotifyID, artist.Img)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (artist *Artist) updateArtist(col string, val string, tx *sql.Tx) error {
|
func (artist *Artist) updateArtist(col string, val string, tx *sql.Tx) error {
|
||||||
_, err := tx.Exec("UPDATE artists SET "+col+" = $1 WHERE uuid = $2", val, artist.UUID)
|
_, err := tx.Exec(`UPDATE artists SET "`+col+`" = $1 WHERE uuid = $2`, val, artist.UUID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArtistByUUID(uuid string) (Artist, error) {
|
func getArtistByUUID(uuid string) (Artist, error) {
|
||||||
var artist Artist
|
var artist Artist
|
||||||
err := db.QueryRow("SELECT uuid, name, IFNULL(desc, ''), IFNULL(img,''), mbid, spotify_id FROM artists WHERE uuid = $1",
|
err := db.QueryRow(`SELECT uuid, name, COALESCE(desc, ''), COALESCE(img,''), mbid, spotify_id FROM artists WHERE uuid = $1`,
|
||||||
uuid).Scan(&artist.UUID, &artist.Name, &artist.Desc, &artist.Img, &artist.MusicBrainzID, &artist.SpotifyID)
|
uuid).Scan(&artist.UUID, &artist.Name, &artist.Desc, &artist.Img, &artist.MusicBrainzID, &artist.SpotifyID)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -129,15 +129,16 @@ func getArtistByUUID(uuid string) (Artist, error) {
|
|||||||
func getTopArtists(userUuid string) (TopArtists, error) {
|
func getTopArtists(userUuid string) (TopArtists, error) {
|
||||||
var topArtist TopArtists
|
var topArtist TopArtists
|
||||||
|
|
||||||
rows, err := db.Query("SELECT artists.uuid, artists.name, IFNULL(artists.uuid,''), count(*) "+
|
log.Println(userUuid)
|
||||||
"FROM scrobbles "+
|
rows, err := db.Query(`SELECT artists.uuid, artists.name, COALESCE(artists.uuid,''), count(*) `+
|
||||||
"JOIN tracks ON tracks.uuid = scrobbles.track "+
|
`FROM scrobbles `+
|
||||||
"JOIN track_artist ON track_artist.track = tracks.uuid "+
|
`JOIN tracks ON tracks.uuid = scrobbles.track `+
|
||||||
"JOIN artists ON track_artist.artist = artists.uuid "+
|
`JOIN track_artist ON track_artist.track = tracks.uuid `+
|
||||||
"WHERE scrobbles.user = $1 "+
|
`JOIN artists ON track_artist.artist = artists.uuid `+
|
||||||
"GROUP BY artists.uuid "+
|
`WHERE scrobbles."user" = $1 `+
|
||||||
"ORDER BY count(*) DESC "+
|
`GROUP BY artists.uuid `+
|
||||||
"LIMIT 14;",
|
`ORDER BY count(*) DESC `+
|
||||||
|
`LIMIT 14;`,
|
||||||
userUuid)
|
userUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch top artist: %+v", err)
|
log.Printf("Failed to fetch top artist: %+v", err)
|
||||||
|
@ -20,7 +20,7 @@ func getAllConfigs() (Config, error) {
|
|||||||
config := Config{}
|
config := Config{}
|
||||||
configs := make(map[string]string)
|
configs := make(map[string]string)
|
||||||
|
|
||||||
rows, err := db.Query("SELECT key, value FROM config")
|
rows, err := db.Query(`SELECT key, value FROM config`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch config: %+v", err)
|
log.Printf("Failed to fetch config: %+v", err)
|
||||||
return config, errors.New("Failed to fetch configs")
|
return config, errors.New("Failed to fetch configs")
|
||||||
@ -53,7 +53,7 @@ func getAllConfigs() (Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateConfigValue(key string, value string) error {
|
func updateConfigValue(key string, value string) error {
|
||||||
_, err := db.Exec("UPDATE config SET value = $1 WHERE key = $2", value, key)
|
_, err := db.Exec(`UPDATE config SET value = $1 WHERE key = $2`, value, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to update config: %+v", err)
|
fmt.Printf("Failed to update config: %+v", err)
|
||||||
return errors.New("Failed to update config value.")
|
return errors.New("Failed to update config value.")
|
||||||
@ -65,8 +65,7 @@ func updateConfigValue(key string, value string) error {
|
|||||||
func getConfigValue(key string) (string, error) {
|
func getConfigValue(key string) (string, error) {
|
||||||
var value string
|
var value string
|
||||||
|
|
||||||
err := db.QueryRow("SELECT value FROM config "+
|
err := db.QueryRow(`SELECT value FROM config WHERE key = $1`,
|
||||||
"WHERE key = $1",
|
|
||||||
key).Scan(&value)
|
key).Scan(&value)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -13,7 +13,7 @@ type Genre struct {
|
|||||||
func getGenreByUUID(uuid string) Genre {
|
func getGenreByUUID(uuid string) Genre {
|
||||||
var genre Genre
|
var genre Genre
|
||||||
err := db.QueryRow(
|
err := db.QueryRow(
|
||||||
"SELECT uuid, name FROM artists WHERE uuid = $1",
|
`SELECT uuid, name FROM artists WHERE uuid = $1`,
|
||||||
uuid).Scan(&genre.UUID, &genre.Name)
|
uuid).Scan(&genre.UUID, &genre.Name)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -28,7 +28,7 @@ func getGenreByUUID(uuid string) Genre {
|
|||||||
func getGenreByName(name string) Genre {
|
func getGenreByName(name string) Genre {
|
||||||
var genre Genre
|
var genre Genre
|
||||||
err := db.QueryRow(
|
err := db.QueryRow(
|
||||||
"SELECT uuid, name FROM artists WHERE name = $1",
|
`SELECT uuid, name FROM artists WHERE name = $1`,
|
||||||
name).Scan(&genre.UUID, &genre.Name)
|
name).Scan(&genre.UUID, &genre.Name)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -41,7 +41,7 @@ func getGenreByName(name string) Genre {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (genre *Genre) updateGenreName(name string, value string) error {
|
func (genre *Genre) updateGenreName(name string, value string) error {
|
||||||
_, err := db.Exec("UPDATE genres SET name = $1 WHERE uuid = $2", name, genre.UUID)
|
_, err := db.Exec(`UPDATE genres SET name = $1 WHERE uuid = $2`, name, genre.UUID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
// updateSpotifyData - Pull data for all users
|
// updateSpotifyData - Pull data for all users
|
||||||
func updateSpotifyData() {
|
func updateSpotifyData() {
|
||||||
// Lets ignore if not configured
|
// Lets ignore if not configured
|
||||||
val, _ := getConfigValue("SPOTIFY_APP_SECRET")
|
val, _ := getConfigValue("SPOTIFY_API_SECRET")
|
||||||
if val == "" {
|
if val == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -35,12 +35,12 @@ func updateSpotifyData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getSpotifyAuthHandler() spotify.Authenticator {
|
func getSpotifyAuthHandler() spotify.Authenticator {
|
||||||
appId, _ := getConfigValue("SPOTIFY_APP_ID")
|
appId, _ := getConfigValue("SPOTIFY_API_ID")
|
||||||
appSecret, _ := getConfigValue("SPOTIFY_APP_SECRET")
|
appSecret, _ := getConfigValue("SPOTIFY_API_SECRET")
|
||||||
|
|
||||||
redirectUrl := os.Getenv("GOSCROBBLE_DOMAIN") + "/api/v1/link/spotify"
|
redirectUrl := os.Getenv("GOSCROBBLE_DOMAIN") + "/api/v1/link/spotify"
|
||||||
if redirectUrl == "http://localhost:3000/api/v1/link/spotify" {
|
if redirectUrl == "http://localhost:3000/api/v1/link/spotify" {
|
||||||
// Handle backend on a different port
|
// Handle backend on a different port if running in dev-env
|
||||||
redirectUrl = "http://localhost:42069/api/v1/link/spotify"
|
redirectUrl = "http://localhost:42069/api/v1/link/spotify"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ func ParseSpotifyInput(userUUID string, data spotify.RecentlyPlayedItem, client
|
|||||||
// updateImageDataFromSpotify update artist/album images from spotify ;D
|
// updateImageDataFromSpotify update artist/album images from spotify ;D
|
||||||
func (user *User) updateImageDataFromSpotify() error {
|
func (user *User) updateImageDataFromSpotify() error {
|
||||||
// Check that data is set before we attempt to pull
|
// Check that data is set before we attempt to pull
|
||||||
val, _ := getConfigValue("SPOTIFY_APP_SECRET")
|
val, _ := getConfigValue("SPOTIFY_API_SECRET")
|
||||||
if val == "" {
|
if val == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ func (user *User) updateImageDataFromSpotify() error {
|
|||||||
client := auth.NewClient(token)
|
client := auth.NewClient(token)
|
||||||
client.AutoRetry = true
|
client.AutoRetry = true
|
||||||
|
|
||||||
rows, err := db.Query("SELECT uuid, name FROM artists WHERE IFNULL(img,'') NOT IN ('pending', 'complete') LIMIT 100")
|
rows, err := db.Query(`SELECT uuid, name FROM artists WHERE COALESCE(img,'') NOT IN ('pending', 'complete') LIMIT 100`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch config: %+v", err)
|
log.Printf("Failed to fetch config: %+v", err)
|
||||||
return errors.New("Failed to fetch artists")
|
return errors.New("Failed to fetch artists")
|
||||||
@ -282,7 +282,7 @@ func (user *User) updateImageDataFromSpotify() error {
|
|||||||
}
|
}
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
|
|
||||||
rows, err = db.Query("SELECT uuid, name FROM albums WHERE IFNULL(img,'') NOT IN ('pending', 'complete') LIMIT 100")
|
rows, err = db.Query("SELECT uuid, name FROM albums WHERE COALESCE(img,'') NOT IN ('pending', 'complete') LIMIT 100")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch config: %+v", err)
|
log.Printf("Failed to fetch config: %+v", err)
|
||||||
return errors.New("Failed to fetch artists")
|
return errors.New("Failed to fetch artists")
|
||||||
|
@ -20,8 +20,8 @@ type OauthToken struct {
|
|||||||
func getOauthToken(userUuid string, service string) (OauthToken, error) {
|
func getOauthToken(userUuid string, service string) (OauthToken, error) {
|
||||||
var oauth OauthToken
|
var oauth OauthToken
|
||||||
|
|
||||||
err := db.QueryRow("SELECT user, service, access_token, refresh_token, expiry, username, last_synced, url FROM oauth_tokens "+
|
err := db.QueryRow(`SELECT "user", service, access_token, refresh_token, expiry, username, last_synced, url FROM oauth_tokens `+
|
||||||
"WHERE user = $1 AND service = $2",
|
`WHERE "user" = $1 AND service = $2`,
|
||||||
userUuid, service).Scan(&oauth.UserUUID, &oauth.Service, &oauth.AccessToken, &oauth.RefreshToken, &oauth.Expiry, &oauth.Username, &oauth.LastSynced, &oauth.URL)
|
userUuid, service).Scan(&oauth.UserUUID, &oauth.Service, &oauth.AccessToken, &oauth.RefreshToken, &oauth.Expiry, &oauth.Username, &oauth.LastSynced, &oauth.URL)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -32,14 +32,14 @@ func getOauthToken(userUuid string, service string) (OauthToken, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func insertOauthToken(userUuid string, service string, token string, refresh string, expiry time.Time, username string, lastSynced time.Time, url string) error {
|
func insertOauthToken(userUuid string, service string, token string, refresh string, expiry time.Time, username string, lastSynced time.Time, url string) error {
|
||||||
_, err := db.Exec("REPLACE INTO oauth_tokens (user, service, access_token, refresh_token, expiry, username, last_synced, url) "+
|
_, err := db.Exec(`REPLACE INTO oauth_tokens ("user", service, access_token, refresh_token, expiry, username, last_synced, url) `+
|
||||||
"VALUES ($1,$2,$3,$4,$5,$6,$7,$8)", userUuid, service, token, refresh, expiry, username, lastSynced, url)
|
`VALUES ($1,$2,$3,$4,$5,$6,$7,$8)`, userUuid, service, token, refresh, expiry, username, lastSynced, url)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeOauthToken(userUuid string, service string) error {
|
func removeOauthToken(userUuid string, service string) error {
|
||||||
_, err := db.Exec("DELETE FROM oauth_tokens WHERE user = $1 AND service = $2", userUuid, service)
|
_, err := db.Exec(`DELETE FROM oauth_tokens WHERE "user" = $1 AND service = $2`, userUuid, service)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,7 @@ func getScrobblesForUser(userUuid string, limit int, page int) (ScrobbleResponse
|
|||||||
var count int
|
var count int
|
||||||
|
|
||||||
// Yeah this isn't great. But for now.. it works! Cache later
|
// Yeah this isn't great. But for now.. it works! Cache later
|
||||||
total, err := getDbCount(
|
total, err := getDbCount(`SELECT COUNT(*) FROM scrobbles WHERE "user" = $1`, userUuid)
|
||||||
"SELECT COUNT(*) FROM scrobbles WHERE user = $1", userUuid)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch scrobble count: %+v", err)
|
log.Printf("Failed to fetch scrobble count: %+v", err)
|
||||||
@ -67,16 +66,16 @@ func getScrobblesForUser(userUuid string, limit int, page int) (ScrobbleResponse
|
|||||||
}
|
}
|
||||||
|
|
||||||
rows, err := db.Query(
|
rows, err := db.Query(
|
||||||
"SELECT scrobbles.uuid, scrobbles.created_at, artists.uuid, artists.name, albums.name, tracks.uuid, tracks.name, scrobbles.source FROM scrobbles "+
|
`SELECT scrobbles.uuid, scrobbles.created_at, artists.uuid, artists.name, albums.name, tracks.uuid, tracks.name, scrobbles.source FROM scrobbles `+
|
||||||
"JOIN tracks ON scrobbles.track = tracks.uuid "+
|
`JOIN tracks ON scrobbles.track = tracks.uuid `+
|
||||||
"JOIN track_artist ON track_artist.track = tracks.uuid "+
|
`JOIN track_artist ON track_artist.track = tracks.uuid `+
|
||||||
"JOIN track_album ON track_album.track = tracks.uuid "+
|
`JOIN track_album ON track_album.track = tracks.uuid `+
|
||||||
"JOIN artists ON track_artist.artist = artists.uuid "+
|
`JOIN artists ON track_artist.artist = artists.uuid `+
|
||||||
"JOIN albums ON track_album.album = albums.uuid "+
|
`JOIN albums ON track_album.album = albums.uuid `+
|
||||||
"JOIN users ON scrobbles.user = users.uuid "+
|
`JOIN users ON scrobbles.user = users.uuid `+
|
||||||
"WHERE user = $1 "+
|
`WHERE "user" = $1 `+
|
||||||
"GROUP BY scrobbles.uuid, albums.uuid "+
|
`GROUP BY scrobbles.uuid, albums.uuid `+
|
||||||
"ORDER BY scrobbles.created_at DESC LIMIT $2",
|
`ORDER BY scrobbles.created_at DESC LIMIT $2`,
|
||||||
userUuid, limit)
|
userUuid, limit)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -602,6 +602,8 @@ func getArtists(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println(uuid)
|
||||||
|
|
||||||
track, err := getTopArtists(uuid)
|
track, err := getTopArtists(uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
throwOkError(w, err.Error())
|
throwOkError(w, err.Error())
|
||||||
@ -702,7 +704,7 @@ func postSpotifyReponse(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// getSpotifyClientID - Returns public spotify APP ID
|
// getSpotifyClientID - Returns public spotify APP ID
|
||||||
func getSpotifyClientID(w http.ResponseWriter, r *http.Request, claims CustomClaims, v string) {
|
func getSpotifyClientID(w http.ResponseWriter, r *http.Request, claims CustomClaims, v string) {
|
||||||
key, err := getConfigValue("SPOTIFY_APP_ID")
|
key, err := getConfigValue("SPOTIFY_API_ID")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
throwOkError(w, "Failed to get Spotify ID")
|
throwOkError(w, "Failed to get Spotify ID")
|
||||||
return
|
return
|
||||||
|
@ -53,25 +53,25 @@ func getAllStats() (StatsRequest, error) {
|
|||||||
statsReq := StatsRequest{}
|
statsReq := StatsRequest{}
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
statsReq.Users, err = getDbCount("SELECT COUNT(*) FROM users WHERE active = true")
|
statsReq.Users, err = getDbCount(`SELECT COUNT(*) FROM users WHERE active = true`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch user count: %+v", err)
|
log.Printf("Failed to fetch user count: %+v", err)
|
||||||
return statsReq, errors.New("Failed to fetch stats")
|
return statsReq, errors.New("Failed to fetch stats")
|
||||||
}
|
}
|
||||||
|
|
||||||
statsReq.Scrobbles, err = getDbCount("SELECT COUNT(*) FROM scrobbles")
|
statsReq.Scrobbles, err = getDbCount(`SELECT COUNT(*) FROM scrobbles`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch scrobble count: %+v", err)
|
log.Printf("Failed to fetch scrobble count: %+v", err)
|
||||||
return statsReq, errors.New("Failed to fetch stats")
|
return statsReq, errors.New("Failed to fetch stats")
|
||||||
}
|
}
|
||||||
|
|
||||||
statsReq.Tracks, err = getDbCount("SELECT COUNT(*) FROM tracks")
|
statsReq.Tracks, err = getDbCount(`SELECT COUNT(*) FROM tracks`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch track count: %+v", err)
|
log.Printf("Failed to fetch track count: %+v", err)
|
||||||
return statsReq, errors.New("Failed to fetch stats")
|
return statsReq, errors.New("Failed to fetch stats")
|
||||||
}
|
}
|
||||||
|
|
||||||
statsReq.Artists, err = getDbCount("SELECT COUNT(*) FROM artists")
|
statsReq.Artists, err = getDbCount(`SELECT COUNT(*) FROM artists`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch artist count: %+v", err)
|
log.Printf("Failed to fetch artist count: %+v", err)
|
||||||
return statsReq, errors.New("Failed to fetch stats")
|
return statsReq, errors.New("Failed to fetch stats")
|
||||||
|
@ -29,7 +29,7 @@ func getUserUuidForToken(token string) (string, error) {
|
|||||||
var uuid string
|
var uuid string
|
||||||
cachedKey := getRedisVal("user_token:" + token)
|
cachedKey := getRedisVal("user_token:" + token)
|
||||||
if cachedKey == "" {
|
if cachedKey == "" {
|
||||||
err := db.QueryRow("SELECT uuid FROM users WHERE token = $1 AND active = true", token).Scan(&uuid)
|
err := db.QueryRow(`SELECT uuid FROM users WHERE token = $1 AND active = true`, token).Scan(&uuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.New("Invalid Token")
|
return "", errors.New("Invalid Token")
|
||||||
}
|
}
|
||||||
@ -50,14 +50,14 @@ func insertRefreshToken(userUuid string, token string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func deleteRefreshToken(token string) error {
|
func deleteRefreshToken(token string) error {
|
||||||
_, err := db.Exec("DELETE FROM refresh_tokens WHERE token = $1", token)
|
_, err := db.Exec(`DELETE FROM refresh_tokens WHERE token = $1`, token)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func isValidRefreshToken(refreshTokenStr string) (User, error) {
|
func isValidRefreshToken(refreshTokenStr string) (User, error) {
|
||||||
var refresh RefreshToken
|
var refresh RefreshToken
|
||||||
err := db.QueryRow("SELECT uuid, user, token, expiry FROM refresh_tokens WHERE token = $1",
|
err := db.QueryRow(`SELECT uuid, "user", token, expiry FROM refresh_tokens WHERE token = $1`,
|
||||||
refreshTokenStr).Scan(&refresh.UUID, &refresh.User, &refresh.Token, &refresh.Expiry)
|
refreshTokenStr).Scan(&refresh.UUID, &refresh.User, &refresh.Token, &refresh.Expiry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return User{}, errors.New("Invalid Refresh Token")
|
return User{}, errors.New("Invalid Refresh Token")
|
||||||
|
@ -98,7 +98,7 @@ func insertTrack(name string, legnth int, mbid string, spotifyId string, album s
|
|||||||
func getTrackByCol(col string, val string, tx *sql.Tx) Track {
|
func getTrackByCol(col string, val string, tx *sql.Tx) Track {
|
||||||
var track Track
|
var track Track
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
"SELECT uuid, name, IFNULL(desc,''), IFNULL(img,''), mbid FROM tracks WHERE "+col+" = $1 LIMIT 1",
|
`SELECT uuid, name, COALESCE(desc,''), COALESCE(img,''), mbid FROM tracks WHERE "`+col+`" = $1 LIMIT 1`,
|
||||||
val).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.MusicBrainzID)
|
val).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.MusicBrainzID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -114,11 +114,11 @@ func getTrackWithArtists(name string, artists []string, album string, tx *sql.Tx
|
|||||||
var track Track
|
var track Track
|
||||||
artistString := strings.Join(artists, "','")
|
artistString := strings.Join(artists, "','")
|
||||||
err := tx.QueryRow(
|
err := tx.QueryRow(
|
||||||
"SELECT uuid, name, IFNULL(desc,''), IFNULL(img,''), mbid FROM tracks "+
|
`SELECT uuid, name, COALESCE(desc,''), COALESCE(img,''), mbid FROM tracks `+
|
||||||
"LEFT JOIN track_artist ON tracks.uuid = track_artist.track "+
|
`LEFT JOIN track_artist ON tracks.uuid = track_artist.track `+
|
||||||
"LEFT JOIN track_album ON tracks.uuid = track_album.track "+
|
`LEFT JOIN track_album ON tracks.uuid = track_album.track `+
|
||||||
"WHERE name = $1 AND track_artist.artistIN ('"+artistString+"') "+
|
`WHERE name = $1 AND track_artist.artistIN ('`+artistString+`') `+
|
||||||
"AND track_album.album = $2 LIMIT 1",
|
`AND track_album.album = $2 LIMIT 1`,
|
||||||
name, album).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.MusicBrainzID)
|
name, album).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.MusicBrainzID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -137,8 +137,8 @@ func insertNewTrack(track *Track, name string, length int, mbid string, spotifyI
|
|||||||
track.MusicBrainzID = mbid
|
track.MusicBrainzID = mbid
|
||||||
track.SpotifyID = spotifyId
|
track.SpotifyID = spotifyId
|
||||||
|
|
||||||
_, err := tx.Exec("INSERT INTO tracks (uuid, name, length, mbid, spotify_id) "+
|
_, err := tx.Exec(`INSERT INTO tracks (uuid, name, length, mbid, spotify_id) `+
|
||||||
"VALUES ($1,$2,$3,$4,$5)", track.UUID, track.Name, track.Length, track.MusicBrainzID, track.SpotifyID)
|
`VALUES ($1,$2,$3,$4,$5)`, track.UUID, track.Name, track.Length, track.MusicBrainzID, track.SpotifyID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -158,8 +158,8 @@ func (track *Track) linkTrack(album string, artists []string, tx *sql.Tx) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (track *Track) linkTrackToAlbum(albumUuid string, tx *sql.Tx) error {
|
func (track *Track) linkTrackToAlbum(albumUuid string, tx *sql.Tx) error {
|
||||||
_, err := tx.Exec("INSERT INTO track_album (track, album) "+
|
_, err := tx.Exec(`INSERT INTO track_album (track, album) `+
|
||||||
"VALUES ($1, $2)", track.UUID, albumUuid)
|
`VALUES ($1, $2)`, track.UUID, albumUuid)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -167,8 +167,8 @@ func (track *Track) linkTrackToAlbum(albumUuid string, tx *sql.Tx) error {
|
|||||||
func (track *Track) linkTrackToArtists(artists []string, tx *sql.Tx) error {
|
func (track *Track) linkTrackToArtists(artists []string, tx *sql.Tx) error {
|
||||||
var err error
|
var err error
|
||||||
for _, artist := range artists {
|
for _, artist := range artists {
|
||||||
_, err = tx.Exec("INSERT INTO track_artist (track, artist) "+
|
_, err = tx.Exec(`INSERT INTO track_artist (track, artist) `+
|
||||||
"VALUES ($1,$2)", track.UUID, artist)
|
`VALUES ($1,$2)`, track.UUID, artist)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -178,18 +178,18 @@ func (track *Track) linkTrackToArtists(artists []string, tx *sql.Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (track *Track) updateTrack(col string, val string, tx *sql.Tx) error {
|
func (track *Track) updateTrack(col string, val string, tx *sql.Tx) error {
|
||||||
_, err := tx.Exec("UPDATE tracks SET "+col+" = $1 WHERE uuid = $2", val, track.UUID)
|
_, err := tx.Exec(`UPDATE tracks SET "`+col+`" = $1 WHERE uuid = $2`, val, track.UUID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTrackByUUID(uuid string) (Track, error) {
|
func getTrackByUUID(uuid string) (Track, error) {
|
||||||
var track Track
|
var track Track
|
||||||
err := db.QueryRow("SELECT tracks.uuid, tracks.name, IFNULL(albums.desc,''), IFNULL(albums.uuid,''), tracks.length, tracks.mbid, tracks.spotify_id "+
|
err := db.QueryRow(`SELECT tracks.uuid, tracks.name, COALESCE(albums.desc,''), COALESCE(albums.uuid,''), tracks.length, tracks.mbid, tracks.spotify_id `+
|
||||||
"FROM tracks "+
|
`FROM tracks `+
|
||||||
"LEFT JOIN track_album ON track_album.track = tracks.uuid "+
|
`LEFT JOIN track_album ON track_album.track = tracks.uuid `+
|
||||||
"LEFT JOIN albums ON track_album.album = albums.uuid "+
|
`LEFT JOIN albums ON track_album.album = albums.uuid `+
|
||||||
"WHERE tracks.uuid = $1",
|
`WHERE tracks.uuid = $1`,
|
||||||
uuid).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.Length, &track.MusicBrainzID, &track.SpotifyID)
|
uuid).Scan(&track.UUID, &track.Name, &track.Desc, &track.Img, &track.Length, &track.MusicBrainzID, &track.SpotifyID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -203,15 +203,15 @@ func getTrackByUUID(uuid string) (Track, error) {
|
|||||||
func getTopTracks(userUuid string) (TopTracks, error) {
|
func getTopTracks(userUuid string) (TopTracks, error) {
|
||||||
var topTracks TopTracks
|
var topTracks TopTracks
|
||||||
|
|
||||||
rows, err := db.Query("SELECT tracks.uuid, tracks.name, IFNULL(albums.uuid,''), count(*) "+
|
rows, err := db.Query(`SELECT tracks.uuid, tracks.name, COALESCE(albums.uuid,''), count(*) `+
|
||||||
"FROM scrobbles "+
|
`FROM scrobbles `+
|
||||||
"JOIN tracks ON tracks.uuid = scrobbles.track "+
|
`JOIN tracks ON tracks.uuid = scrobbles.track `+
|
||||||
"JOIN track_album ON track_album.track = tracks.uuid "+
|
`JOIN track_album ON track_album.track = tracks.uuid `+
|
||||||
"JOIN albums ON track_album.album = albums.uuid "+
|
`JOIN albums ON track_album.album = albums.uuid `+
|
||||||
"WHERE user = $1 "+
|
`WHERE "user" = $1 `+
|
||||||
"GROUP BY scrobbles.track "+
|
`GROUP BY scrobbles.track `+
|
||||||
"ORDER BY count(*) DESC "+
|
`ORDER BY count(*) DESC `+
|
||||||
"LIMIT 14",
|
`LIMIT 14`,
|
||||||
userUuid)
|
userUuid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch top tracks: %+v", err)
|
log.Printf("Failed to fetch top tracks: %+v", err)
|
||||||
@ -251,9 +251,9 @@ func (track *Track) loadExtraTrackInfo() error {
|
|||||||
func (track *Track) getArtistsForTrack() error {
|
func (track *Track) getArtistsForTrack() error {
|
||||||
artists := []Artist{}
|
artists := []Artist{}
|
||||||
|
|
||||||
rows, err := db.Query("SELECT track_artist.artist "+
|
rows, err := db.Query(`SELECT track_artist.artist `+
|
||||||
"FROM track_artist "+
|
`FROM track_artist `+
|
||||||
"WHERE track_artist.track = $1",
|
`WHERE track_artist.track = $1`,
|
||||||
track.UUID)
|
track.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch artists for track: %+v", err)
|
log.Printf("Failed to fetch artists for track: %+v", err)
|
||||||
@ -283,9 +283,9 @@ func (track *Track) getArtistsForTrack() error {
|
|||||||
func (track *Track) getAlbumsForTrack() error {
|
func (track *Track) getAlbumsForTrack() error {
|
||||||
albums := []Album{}
|
albums := []Album{}
|
||||||
|
|
||||||
rows, err := db.Query("SELECT track_album.album "+
|
rows, err := db.Query(`SELECT track_album.album `+
|
||||||
"FROM track_album "+
|
`FROM track_album `+
|
||||||
"WHERE track_album.track = $1",
|
`WHERE track_album.track = $1`,
|
||||||
track.UUID)
|
track.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch album for track: %+v", err)
|
log.Printf("Failed to fetch album for track: %+v", err)
|
||||||
@ -320,7 +320,7 @@ func getTopUsersForTrackUUID(trackUUID string, limit int, page int) (TopUserTrac
|
|||||||
// Yeah this isn't great. But for now.. it works! Cache later
|
// Yeah this isn't great. But for now.. it works! Cache later
|
||||||
// TODO: This is counting total scrobbles, not unique users
|
// TODO: This is counting total scrobbles, not unique users
|
||||||
total, err := getDbCount(
|
total, err := getDbCount(
|
||||||
"SELECT COUNT(*) FROM scrobbles WHERE track = $1 GROUP BY track, user", trackUUID)
|
`SELECT COUNT(*) FROM scrobbles WHERE track = $1 GROUP BY track, "user"`, trackUUID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch scrobble count: %+v", err)
|
log.Printf("Failed to fetch scrobble count: %+v", err)
|
||||||
@ -328,12 +328,12 @@ func getTopUsersForTrackUUID(trackUUID string, limit int, page int) (TopUserTrac
|
|||||||
}
|
}
|
||||||
|
|
||||||
rows, err := db.Query(
|
rows, err := db.Query(
|
||||||
"SELECT scrobbles.user, users.username, COUNT(*) "+
|
`SELECT scrobbles.user, users.username, COUNT(*) `+
|
||||||
"FROM scrobbles "+
|
`FROM scrobbles `+
|
||||||
"JOIN users ON scrobbles.user = users.uuid "+
|
`JOIN users ON scrobbles."user" = users.uuid `+
|
||||||
"WHERE track = $1 "+
|
`WHERE track = $1 `+
|
||||||
"GROUP BY scrobbles.user "+
|
`GROUP BY scrobbles."user" `+
|
||||||
"ORDER BY COUNT(*) DESC LIMIT $2",
|
`ORDER BY COUNT(*) DESC LIMIT $2`,
|
||||||
trackUUID, limit)
|
trackUUID, limit)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -99,7 +99,7 @@ func loginUser(logReq *RequestRequest, ip net.IP) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.Contains(logReq.Username, "@") {
|
if strings.Contains(logReq.Username, "@") {
|
||||||
err := db.QueryRow("SELECT uuid, username, email, password, admin, mod FROM users WHERE email = $1 AND active = true",
|
err := db.QueryRow(`SELECT uuid, username, email, password, admin, mod FROM users WHERE email = $1 AND active = true`,
|
||||||
logReq.Username).Scan(&user.UUID, &user.Username, &user.Email, &user.Password, &user.Admin, &user.Mod)
|
logReq.Username).Scan(&user.UUID, &user.Username, &user.Email, &user.Password, &user.Admin, &user.Mod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -107,7 +107,7 @@ func loginUser(logReq *RequestRequest, ip net.IP) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err := db.QueryRow("SELECT uuid, username, email, password, admin, mod FROM users WHERE username = $1 AND active = true",
|
err := db.QueryRow(`SELECT uuid, username, email, password, admin, mod FROM users WHERE username = $1 AND active = true`,
|
||||||
logReq.Username).Scan(&user.UUID, &user.Username, &user.Email, &user.Password, &user.Admin, &user.Mod)
|
logReq.Username).Scan(&user.UUID, &user.Username, &user.Email, &user.Password, &user.Admin, &user.Mod)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
return resp, errors.New("Invalid Username or Password")
|
return resp, errors.New("Invalid Username or Password")
|
||||||
@ -140,20 +140,20 @@ func insertUser(username string, email string, password []byte, ip net.IP) error
|
|||||||
|
|
||||||
log.Printf(ip.String())
|
log.Printf(ip.String())
|
||||||
|
|
||||||
_, err := db.Exec("INSERT INTO users (uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, token) "+
|
_, err := db.Exec(`INSERT INTO users (uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, token) `+
|
||||||
"VALUES ($1,NOW(),$2,NOW(),$3,$4,$5,$6,$7)", uuid, ip.String(), ip.String(), username, email, password, token)
|
`VALUES ($1,NOW(),$2,NOW(),$3,$4,$5,$6,$7)`, uuid, ip.String(), ip.String(), username, email, password, token)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) updateUser(field string, value string, ip net.IP) error {
|
func (user *User) updateUser(field string, value string, ip net.IP) error {
|
||||||
_, err := db.Exec("UPDATE users SET "+field+" = $1, modified_at = NOW(), modified_ip = $2 WHERE uuid = $3", value, ip, user.UUID)
|
_, err := db.Exec(`UPDATE users SET "`+field+`" = $1, modified_at = NOW(), modified_ip = $2 WHERE uuid = $3`, value, ip, user.UUID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) updateUserDirect(field string, value string) error {
|
func (user *User) updateUserDirect(field string, value string) error {
|
||||||
_, err := db.Exec("UPDATE users SET "+field+" = $1 WHERE uuid = $2", value, user.UUID)
|
_, err := db.Exec(`UPDATE users SET "`+field+`" = $1 WHERE uuid = $2`, value, user.UUID)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -176,7 +176,7 @@ func isValidPassword(password string, user User) bool {
|
|||||||
// userAlreadyExists - Returns bool indicating if a record exists for either username or email
|
// userAlreadyExists - Returns bool indicating if a record exists for either username or email
|
||||||
// Using two look ups to make use of DB indexes.
|
// Using two look ups to make use of DB indexes.
|
||||||
func userAlreadyExists(req *RequestRequest) bool {
|
func userAlreadyExists(req *RequestRequest) bool {
|
||||||
count, err := getDbCount("SELECT COUNT(*) FROM users WHERE username = $1", req.Username)
|
count, err := getDbCount(`SELECT COUNT(*) FROM users WHERE username = $1`, req.Username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error querying for duplicate users: %v", err)
|
fmt.Printf("Error querying for duplicate users: %v", err)
|
||||||
return true
|
return true
|
||||||
@ -188,7 +188,7 @@ func userAlreadyExists(req *RequestRequest) bool {
|
|||||||
|
|
||||||
if req.Email != "" {
|
if req.Email != "" {
|
||||||
// Only run email check if there's an email...
|
// Only run email check if there's an email...
|
||||||
count, err = getDbCount("SELECT COUNT(*) FROM users WHERE email = $1", req.Email)
|
count, err = getDbCount(`SELECT COUNT(*) FROM users WHERE email = $1`, req.Email)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -201,7 +201,7 @@ func userAlreadyExists(req *RequestRequest) bool {
|
|||||||
|
|
||||||
func getUserByUUID(uuid string) (User, error) {
|
func getUserByUUID(uuid string) (User, error) {
|
||||||
var user User
|
var user User
|
||||||
err := db.QueryRow("SELECT uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users WHERE uuid = $1 AND active = true",
|
err := db.QueryRow(`SELECT uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users WHERE uuid = $1 AND active = true`,
|
||||||
uuid).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
uuid).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -213,7 +213,7 @@ func getUserByUUID(uuid string) (User, error) {
|
|||||||
|
|
||||||
func getUserByUsername(username string) (User, error) {
|
func getUserByUsername(username string) (User, error) {
|
||||||
var user User
|
var user User
|
||||||
err := db.QueryRow("SELECT uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users WHERE username = $1 AND active = true",
|
err := db.QueryRow(`SELECT uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users WHERE username = $1 AND active = true`,
|
||||||
username).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
username).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -225,7 +225,7 @@ func getUserByUsername(username string) (User, error) {
|
|||||||
|
|
||||||
func getUserByEmail(email string) (User, error) {
|
func getUserByEmail(email string) (User, error) {
|
||||||
var user User
|
var user User
|
||||||
err := db.QueryRow("SELECT uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users WHERE email = $1 AND active = true",
|
err := db.QueryRow(`SELECT uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users WHERE email = $1 AND active = true`,
|
||||||
email).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
email).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -237,8 +237,8 @@ func getUserByEmail(email string) (User, error) {
|
|||||||
|
|
||||||
func getUserByResetToken(token string) (User, error) {
|
func getUserByResetToken(token string) (User, error) {
|
||||||
var user User
|
var user User
|
||||||
err := db.QueryRow("SELECT users.uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users "+
|
err := db.QueryRow(`SELECT users.uuid, created_at, created_ip, modified_at, modified_ip, username, email, password, verified, admin, mod, timezone, token FROM users `+
|
||||||
"JOIN resettoken ON resettoken.user = users.uuid WHERE resettoken.token = $1 AND active = true",
|
`JOIN resettoken ON resettoken.user = users.uuid WHERE resettoken.token = $1 AND active = true`,
|
||||||
token).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
token).Scan(&user.UUID, &user.CreatedAt, &user.CreatedIp, &user.ModifiedAt, &user.ModifiedIP, &user.Username, &user.Email, &user.Password, &user.Verified, &user.Admin, &user.Mod, &user.Timezone, &user.Token)
|
||||||
|
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
@ -269,26 +269,26 @@ func (user *User) sendResetEmail(ip net.IP) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) saveResetToken(token string, expiry time.Time) error {
|
func (user *User) saveResetToken(token string, expiry time.Time) error {
|
||||||
_, _ = db.Exec("DELETE FROM resettoken WHERE user = $1", user.UUID)
|
_, _ = db.Exec(`DELETE FROM resettoken WHERE "user" = $1`, user.UUID)
|
||||||
_, err := db.Exec("INSERT INTO resettoken (user, token, expiry) "+
|
_, err := db.Exec(`INSERT INTO resettoken ("user", token, expiry) `+
|
||||||
"VALUES ($1,$2,$3)", user.UUID, token, expiry)
|
`VALUES ($1,$2,$3)`, user.UUID, token, expiry)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearOldResetTokens() {
|
func clearOldResetTokens() {
|
||||||
_, _ = db.Exec("DELETE FROM resettoken WHERE expiry < NOW()")
|
_, _ = db.Exec(`DELETE FROM resettoken WHERE expiry < NOW()`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func clearResetToken(token string) error {
|
func clearResetToken(token string) error {
|
||||||
_, err := db.Exec("DELETE FROM resettoken WHERE token = $1", token)
|
_, err := db.Exec(`DELETE FROM resettoken WHERE token = $1`, token)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkResetToken - If a token exists check it
|
// checkResetToken - If a token exists check it
|
||||||
func checkResetToken(token string) (bool, error) {
|
func checkResetToken(token string) (bool, error) {
|
||||||
count, err := getDbCount("SELECT COUNT(*) FROM resettoken WHERE token = $1", token)
|
count, err := getDbCount(`SELECT COUNT(*) FROM resettoken WHERE token = $1`, token)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@ -303,7 +303,7 @@ func (user *User) updatePassword(newPassword string, ip net.IP) error {
|
|||||||
return errors.New("Bad password")
|
return errors.New("Bad password")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Exec("UPDATE users SET password = $1 WHERE uuid = $2", hash, user.UUID)
|
_, err = db.Exec(`UPDATE users SET password = $1 WHERE uuid = $2`, hash, user.UUID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("Failed to update password")
|
return errors.New("Failed to update password")
|
||||||
}
|
}
|
||||||
@ -321,8 +321,8 @@ func (user *User) getNavidromeTokens() (OauthToken, error) {
|
|||||||
|
|
||||||
func getAllSpotifyUsers() ([]User, error) {
|
func getAllSpotifyUsers() ([]User, error) {
|
||||||
users := make([]User, 0)
|
users := make([]User, 0)
|
||||||
rows, err := db.Query("SELECT users.uuid, created_at, created_ip, modified_at, modified_ip, users.username, email, password, verified, admin, mod, timezone FROM users " +
|
rows, err := db.Query(`SELECT users.uuid, created_at, created_ip, modified_at, modified_ip, users.username, email, password, verified, admin, mod, timezone FROM users ` +
|
||||||
"JOIN oauth_tokens ON oauth_tokens.user = users.uuid AND oauth_tokens.service = 'spotify' WHERE users.active = true")
|
`JOIN oauth_tokens ON oauth_tokens."user" = users.uuid AND oauth_tokens.service = 'spotify' WHERE users.active = true`)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch spotify users: %+v", err)
|
log.Printf("Failed to fetch spotify users: %+v", err)
|
||||||
@ -353,8 +353,8 @@ func getAllSpotifyUsers() ([]User, error) {
|
|||||||
|
|
||||||
func getAllNavidromeUsers() ([]User, error) {
|
func getAllNavidromeUsers() ([]User, error) {
|
||||||
users := make([]User, 0)
|
users := make([]User, 0)
|
||||||
rows, err := db.Query("SELECT users.uuid, created_at, created_ip, modified_at, modified_ip, users.username, email, password, verified, admin, mod, timezone FROM users " +
|
rows, err := db.Query(`SELECT users.uuid, created_at, created_ip, modified_at, modified_ip, users.username, email, password, verified, admin, mod, timezone FROM users ` +
|
||||||
"JOIN oauth_tokens ON oauth_tokens.user = users.uuid AND oauth_tokens.service = 'navidrome' WHERE users.active = true")
|
`JOIN oauth_tokens ON oauth_tokens."user" = users.uuid AND oauth_tokens.service = 'navidrome' WHERE users.active = true`)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to fetch navidrome users: %+v", err)
|
log.Printf("Failed to fetch navidrome users: %+v", err)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
|
|
||||||
ALTER TABLE tracks DROP COLUMN spotify_id;
|
ALTER TABLE tracks DROP COLUMN spotify_id;
|
||||||
ALTER TABLE users DROP COLUMN spotify_id;
|
|
||||||
ALTER TABLE albums DROP COLUMN spotify_id;
|
ALTER TABLE albums DROP COLUMN spotify_id;
|
||||||
ALTER TABLE artists DROP COLUMN spotify_id;
|
ALTER TABLE artists DROP COLUMN spotify_id;
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
|
|
||||||
ALTER TABLE users ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
|
||||||
ALTER TABLE albums ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
ALTER TABLE albums ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
||||||
ALTER TABLE artists ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
ALTER TABLE artists ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
||||||
ALTER TABLE tracks ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
ALTER TABLE tracks ADD COLUMN spotify_id VARCHAR(255) NOT NULL DEFAULT '';
|
||||||
|
|
||||||
CREATE INDEX usersSpotifyLookup ON users (spotify_id);
|
|
||||||
CREATE INDEX albumsSpotifyLookup ON albums (spotify_id);
|
CREATE INDEX albumsSpotifyLookup ON albums (spotify_id);
|
||||||
CREATE INDEX artistsSpotifyLookup ON artists (spotify_id);
|
CREATE INDEX artistsSpotifyLookup ON artists (spotify_id);
|
||||||
CREATE INDEX tracksSpotifyLookup ON tracks (spotify_id);
|
CREATE INDEX tracksSpotifyLookup ON tracks (spotify_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user