mirror of
https://github.com/idanoo/GoScrobble.git
synced 2024-11-22 08:25:14 +00:00
0.0.29
- Add image handler - Store images locally
This commit is contained in:
parent
489527c8f9
commit
8bc462878a
@ -21,3 +21,4 @@ MAIL_FROM_ADDRESS=
|
|||||||
MAIL_FROM_NAME=
|
MAIL_FROM_NAME=
|
||||||
|
|
||||||
GOSCROBBLE_DOMAIN=""
|
GOSCROBBLE_DOMAIN=""
|
||||||
|
STATIC_DIR="web"
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,6 +9,8 @@
|
|||||||
web/.env.production
|
web/.env.production
|
||||||
web/.env.development
|
web/.env.development
|
||||||
|
|
||||||
|
web/img/*
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
# Test binary, built with `go test -c`
|
||||||
*.test
|
*.test
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ stages:
|
|||||||
- bundle
|
- bundle
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
VERSION: 0.0.28
|
VERSION: 0.0.29
|
||||||
|
|
||||||
build-go:
|
build-go:
|
||||||
image: golang:1.16.2
|
image: golang:1.16.2
|
||||||
|
@ -51,6 +51,12 @@ func main() {
|
|||||||
goscrobble.RefereshExpiry = time.Duration(i) * time.Second
|
goscrobble.RefereshExpiry = time.Duration(i) * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goscrobble.StaticDirectory = "web"
|
||||||
|
staticDirectoryStr := os.Getenv("STATIC_DIR")
|
||||||
|
if staticDirectoryStr != "" {
|
||||||
|
goscrobble.StaticDirectory = staticDirectoryStr
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore reverse proxies
|
// Ignore reverse proxies
|
||||||
goscrobble.ReverseProxies = strings.Split(os.Getenv("REVERSE_PROXIES"), ",")
|
goscrobble.ReverseProxies = strings.Split(os.Getenv("REVERSE_PROXIES"), ",")
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# 0.0.29
|
||||||
|
- Add image handler
|
||||||
|
- Store images locally
|
||||||
|
|
||||||
# 0.0.28
|
# 0.0.28
|
||||||
- Fix mobile view on user pages
|
- Fix mobile view on user pages
|
||||||
- Fix favicon issue
|
- Fix favicon issue
|
||||||
|
@ -31,3 +31,4 @@ These are stored in `web/.env.production` and `web/.env.development`
|
|||||||
MAIL_FROM_NAME= // FROM name
|
MAIL_FROM_NAME= // FROM name
|
||||||
|
|
||||||
GOSCROBBLE_DOMAIN="" // Full domain for email links (https://goscrobble.com))
|
GOSCROBBLE_DOMAIN="" // Full domain for email links (https://goscrobble.com))
|
||||||
|
STATIC_DIR="web" // Location to store images (This will serve from web/static)
|
||||||
|
@ -129,7 +129,7 @@ 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 BIN_TO_UUID(`artists`.`uuid`, true), `artists`.`name`, IFNULL(`artists`.`img`,''), count(*) "+
|
rows, err := db.Query("SELECT BIN_TO_UUID(`artists`.`uuid`, true), `artists`.`name`, IFNULL(BIN_TO_UUID(`artists`.`uuid`, true),''), count(*) "+
|
||||||
"FROM `scrobbles` "+
|
"FROM `scrobbles` "+
|
||||||
"JOIN `tracks` ON `tracks`.`uuid` = `scrobbles`.`track` "+
|
"JOIN `tracks` ON `tracks`.`uuid` = `scrobbles`.`track` "+
|
||||||
"JOIN track_artist ON track_artist.track = tracks.uuid "+
|
"JOIN track_artist ON track_artist.track = tracks.uuid "+
|
||||||
|
46
internal/goscrobble/image.go
Normal file
46
internal/goscrobble/image.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package goscrobble
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func importImage(uuid string, url string) error {
|
||||||
|
// Create the file
|
||||||
|
path, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := os.Create(path + string(os.PathSeparator) + StaticDirectory + string(os.PathSeparator) + "img" + string(os.PathSeparator) + uuid + "_full.jpg")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer out.Close()
|
||||||
|
|
||||||
|
// Get the data
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
// Check server response
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return fmt.Errorf("Bad response status: %s", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writer the body to file
|
||||||
|
_, err = io.Copy(out, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resizeImage(uuid string) error {
|
||||||
|
return nil
|
||||||
|
}
|
@ -84,7 +84,6 @@ func (user *User) updateNavidromePlaydata(tx *sql.Tx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
response, err := getNavidromeNowPlaying(&tokens)
|
response, err := getNavidromeNowPlaying(&tokens)
|
||||||
fmt.Println(response)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New(fmt.Sprintf("Failed to fetch Navidrome Tokens %+v", err))
|
return errors.New(fmt.Sprintf("Failed to fetch Navidrome Tokens %+v", err))
|
||||||
}
|
}
|
||||||
|
@ -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 BIN_TO_UUID(`uuid`, true), `name` FROM `artists` WHERE IFNULL(`img`,'') = '' LIMIT 50")
|
rows, err := db.Query("SELECT BIN_TO_UUID(`uuid`, true), `name` FROM `artists` WHERE IFNULL(`img`,'') NOT IN ('pending', 'complete') LIMIT 50")
|
||||||
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")
|
||||||
@ -271,11 +271,18 @@ func (user *User) updateImageDataFromSpotify() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_ = artist.updateArtist("img", img, tx)
|
|
||||||
|
err = importImage(uuid, img)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Failed to import image: %+v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = artist.updateArtist("img", "pending", tx)
|
||||||
}
|
}
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
|
|
||||||
rows, err = db.Query("SELECT BIN_TO_UUID(`uuid`, true), `name` FROM `albums` WHERE IFNULL(`img`,'') = '' LIMIT 50")
|
rows, err = db.Query("SELECT BIN_TO_UUID(`uuid`, true), `name` FROM `albums` WHERE IFNULL(`img`,'') NOT IN ('pending', 'complete') LIMIT 50")
|
||||||
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")
|
||||||
@ -305,10 +312,12 @@ func (user *User) updateImageDataFromSpotify() error {
|
|||||||
tx, _ = db.Begin()
|
tx, _ = db.Begin()
|
||||||
for uuid, img := range toUpdate {
|
for uuid, img := range toUpdate {
|
||||||
album, err = getAlbumByUUID(uuid)
|
album, err = getAlbumByUUID(uuid)
|
||||||
|
err = importImage(uuid, img)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_ = album.updateAlbum("img", img, tx)
|
_ = album.updateAlbum("img", "pending", tx)
|
||||||
}
|
}
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
return nil
|
return nil
|
||||||
|
@ -22,6 +22,9 @@ type jsonResponse struct {
|
|||||||
// List of Reverse proxies
|
// List of Reverse proxies
|
||||||
var ReverseProxies []string
|
var ReverseProxies []string
|
||||||
|
|
||||||
|
// Static image directory
|
||||||
|
var StaticDirectory string
|
||||||
|
|
||||||
// RequestRequest - Incoming JSON!
|
// RequestRequest - Incoming JSON!
|
||||||
type RequestRequest struct {
|
type RequestRequest struct {
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
@ -88,6 +91,10 @@ func HandleRequests(port string) {
|
|||||||
// This just prevents it serving frontend stuff over /api
|
// This just prevents it serving frontend stuff over /api
|
||||||
r.PathPrefix("/api")
|
r.PathPrefix("/api")
|
||||||
|
|
||||||
|
// SERVE STATIC FILES - NO AUTH
|
||||||
|
spaStatic := spaStaticHandler{staticPath: StaticDirectory}
|
||||||
|
r.PathPrefix("/img").Handler(spaStatic)
|
||||||
|
|
||||||
// SERVE FRONTEND - NO AUTH
|
// SERVE FRONTEND - NO AUTH
|
||||||
spa := spaHandler{staticPath: "web/build", indexPath: "index.html"}
|
spa := spaHandler{staticPath: "web/build", indexPath: "index.html"}
|
||||||
r.PathPrefix("/").Handler(spa)
|
r.PathPrefix("/").Handler(spa)
|
||||||
@ -733,7 +740,7 @@ func getServerInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
info := ServerInfo{
|
info := ServerInfo{
|
||||||
Version: "0.0.28",
|
Version: "0.0.29",
|
||||||
RegistrationEnabled: cachedRegistrationEnabled,
|
RegistrationEnabled: cachedRegistrationEnabled,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,12 +6,43 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// spaStaticHandler - Handles static imges
|
||||||
|
type spaStaticHandler struct {
|
||||||
|
staticPath string
|
||||||
|
indexPath string
|
||||||
|
}
|
||||||
|
|
||||||
// spaHandler - Handles Single Page Applications (React)
|
// spaHandler - Handles Single Page Applications (React)
|
||||||
type spaHandler struct {
|
type spaHandler struct {
|
||||||
staticPath string
|
staticPath string
|
||||||
indexPath string
|
indexPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServerHTTP - Frontend React server
|
||||||
|
func (h spaStaticHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Get the absolute path to prevent directory traversal
|
||||||
|
path, err := filepath.Abs(r.URL.Path)
|
||||||
|
if err != nil {
|
||||||
|
http.ServeFile(w, r, filepath.Join(h.staticPath, "img/placeholder.jpg"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(h.staticPath, path)
|
||||||
|
|
||||||
|
_, err = os.Stat(path)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
// file does not exist, serve placeholder
|
||||||
|
http.ServeFile(w, r, filepath.Join(h.staticPath, "img/placeholder.jpg"))
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
http.ServeFile(w, r, filepath.Join(h.staticPath, "img/placeholder.jpg"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, use http.FileServer to serve the static images
|
||||||
|
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
// ServerHTTP - Frontend React server
|
// ServerHTTP - Frontend React server
|
||||||
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
// Get the absolute path to prevent directory traversal
|
// Get the absolute path to prevent directory traversal
|
||||||
|
@ -8,6 +8,9 @@ import (
|
|||||||
var endTicker chan bool
|
var endTicker chan bool
|
||||||
|
|
||||||
func StartBackgroundWorkers() {
|
func StartBackgroundWorkers() {
|
||||||
|
user, _ := getUserByUsername("idanoo")
|
||||||
|
go user.updateImageDataFromSpotify()
|
||||||
|
|
||||||
endTicker := make(chan bool)
|
endTicker := make(chan bool)
|
||||||
|
|
||||||
hourTicker := time.NewTicker(time.Duration(1) * time.Hour)
|
hourTicker := time.NewTicker(time.Duration(1) * time.Hour)
|
||||||
|
@ -166,7 +166,7 @@ func (track *Track) updateTrack(col string, val string, tx *sql.Tx) error {
|
|||||||
|
|
||||||
func getTrackByUUID(uuid string) (Track, error) {
|
func getTrackByUUID(uuid string) (Track, error) {
|
||||||
var track Track
|
var track Track
|
||||||
err := db.QueryRow("SELECT BIN_TO_UUID(`tracks`.`uuid`, true), `tracks`.`name`, IFNULL(`albums`.`desc`,''), IFNULL(`albums`.`img`,''), `tracks`.`length`, `tracks`.`mbid`, `tracks`.`spotify_id` "+
|
err := db.QueryRow("SELECT BIN_TO_UUID(`tracks`.`uuid`, true), `tracks`.`name`, IFNULL(`albums`.`desc`,''), IFNULL(BIN_TO_UUID(`albums`.`uuid`, true),''), `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 "+
|
||||||
@ -184,7 +184,7 @@ 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 BIN_TO_UUID(`tracks`.`uuid`, true), `tracks`.`name`, IFNULL(`albums`.`img`,''), count(*) "+
|
rows, err := db.Query("SELECT BIN_TO_UUID(`tracks`.`uuid`, true), `tracks`.`name`, IFNULL(BIN_TO_UUID(`albums`.`uuid`, true),''), 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 "+
|
||||||
|
@ -1 +1 @@
|
|||||||
REACT_APP_API_URL=http://127.0.0.1:42069/api/v1/
|
REACT_APP_API_URL=http://127.0.0.1:42069
|
||||||
|
BIN
web/img/placeholder.jpg
Normal file
BIN
web/img/placeholder.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
@ -49,7 +49,7 @@ function handleErrorResp(error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const PostLogin = (formValues) => {
|
export const PostLogin = (formValues) => {
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "login", formValues)
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/login", formValues)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.data.token) {
|
if (response.data.token) {
|
||||||
let expandedUser = jwt(response.data.token)
|
let expandedUser = jwt(response.data.token)
|
||||||
@ -82,7 +82,7 @@ export const PostLogin = (formValues) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PostRefreshToken = (refreshToken) => {
|
export const PostRefreshToken = (refreshToken) => {
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "refresh", {token: refreshToken})
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/refresh", {token: refreshToken})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.data.token) {
|
if (response.data.token) {
|
||||||
let expandedUser = jwt(response.data.token)
|
let expandedUser = jwt(response.data.token)
|
||||||
@ -115,7 +115,7 @@ export const PostRefreshToken = (refreshToken) => {
|
|||||||
|
|
||||||
|
|
||||||
export const PostRegister = (formValues) => {
|
export const PostRegister = (formValues) => {
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "register", formValues)
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/register", formValues)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.data.message) {
|
if (response.data.message) {
|
||||||
toast.success(response.data.message);
|
toast.success(response.data.message);
|
||||||
@ -133,7 +133,7 @@ export const PostRegister = (formValues) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PostResetPassword = (formValues) => {
|
export const PostResetPassword = (formValues) => {
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "resetpassword", formValues)
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/resetpassword", formValues)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.data.message) {
|
if (response.data.message) {
|
||||||
toast.success(response.data.message);
|
toast.success(response.data.message);
|
||||||
@ -151,7 +151,7 @@ export const PostResetPassword = (formValues) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const sendPasswordReset = (values) => {
|
export const sendPasswordReset = (values) => {
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "sendreset", values).then(
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/sendreset", values).then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -160,7 +160,7 @@ export const sendPasswordReset = (values) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getStats = () => {
|
export const getStats = () => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "stats").then(
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/stats").then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -169,7 +169,7 @@ export const getStats = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getRecentScrobbles = (id) => {
|
export const getRecentScrobbles = (id) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "user/" + id + "/scrobbles", { headers: getHeaders() })
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/user/" + id + "/scrobbles", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -178,7 +178,7 @@ export const getRecentScrobbles = (id) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getConfigs = () => {
|
export const getConfigs = () => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "config", { headers: getHeaders() })
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/config", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -193,7 +193,7 @@ export const postConfigs = (values, toggle) => {
|
|||||||
values.REGISTRATION_ENABLED = "0"
|
values.REGISTRATION_ENABLED = "0"
|
||||||
}
|
}
|
||||||
|
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "config", values, { headers: getHeaders() })
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/config", values, { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.data && data.data.message) {
|
if (data.data && data.data.message) {
|
||||||
toast.success(data.data.message);
|
toast.success(data.data.message);
|
||||||
@ -206,7 +206,7 @@ export const postConfigs = (values, toggle) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getProfile = (userName) => {
|
export const getProfile = (userName) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "profile/" + userName, { headers: getHeaders() })
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/profile/" + userName, { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -215,7 +215,7 @@ export const getProfile = (userName) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getUser = () => {
|
export const getUser = () => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "user", { headers: getHeaders() })
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/user", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -224,7 +224,7 @@ export const getUser = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const patchUser = (values) => {
|
export const patchUser = (values) => {
|
||||||
return axios.patch(process.env.REACT_APP_API_URL + "user", values, { headers: getHeaders() })
|
return axios.patch(process.env.REACT_APP_API_URL + "/api/v1/user", values, { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -233,7 +233,7 @@ export const patchUser = (values) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const validateResetPassword = (tokenStr) => {
|
export const validateResetPassword = (tokenStr) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "user/", { headers: getHeaders() })
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/user/", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -242,7 +242,7 @@ export const validateResetPassword = (tokenStr) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getSpotifyClientId = () => {
|
export const getSpotifyClientId = () => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "user/spotify", { headers: getHeaders() })
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/user/spotify", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data
|
return data.data
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -272,7 +272,7 @@ export const spotifyConnectionRequest = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const spotifyDisonnectionRequest = () => {
|
export const spotifyDisonnectionRequest = () => {
|
||||||
return axios.delete(process.env.REACT_APP_API_URL + "user/spotify", { headers: getHeaders() })
|
return axios.delete(process.env.REACT_APP_API_URL + "/api/v1/user/spotify", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
toast.success(data.data.message);
|
toast.success(data.data.message);
|
||||||
return true
|
return true
|
||||||
@ -282,7 +282,7 @@ export const spotifyDisonnectionRequest = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const navidromeConnectionRequest = (values) => {
|
export const navidromeConnectionRequest = (values) => {
|
||||||
return axios.post(process.env.REACT_APP_API_URL + "user/navidrome", values, { headers: getHeaders() })
|
return axios.post(process.env.REACT_APP_API_URL + "/api/v1/user/navidrome", values, { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
toast.success(data.data.message);
|
toast.success(data.data.message);
|
||||||
return true
|
return true
|
||||||
@ -292,7 +292,7 @@ export const navidromeConnectionRequest = (values) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const navidromeDisonnectionRequest = () => {
|
export const navidromeDisonnectionRequest = () => {
|
||||||
return axios.delete(process.env.REACT_APP_API_URL + "user/navidrome", { headers: getHeaders() })
|
return axios.delete(process.env.REACT_APP_API_URL + "/api/v1/user/navidrome", { headers: getHeaders() })
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
toast.success(data.data.message);
|
toast.success(data.data.message);
|
||||||
return true
|
return true
|
||||||
@ -303,7 +303,7 @@ export const navidromeDisonnectionRequest = () => {
|
|||||||
|
|
||||||
|
|
||||||
export const getServerInfo = () => {
|
export const getServerInfo = () => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "serverinfo")
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/serverinfo")
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
return data.data
|
return data.data
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -312,7 +312,7 @@ export const getServerInfo = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getArtist = (uuid) => {
|
export const getArtist = (uuid) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "artists/" + uuid).then(
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/artists/" + uuid).then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -321,7 +321,7 @@ export const getArtist = (uuid) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getAlbum = (uuid) => {
|
export const getAlbum = (uuid) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "albums/" + uuid).then(
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/albums/" + uuid).then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -330,7 +330,7 @@ export const getAlbum = (uuid) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getTrack = (uuid) => {
|
export const getTrack = (uuid) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "tracks/" + uuid).then(
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/tracks/" + uuid).then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -339,7 +339,7 @@ export const getTrack = (uuid) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getTopTracks = (uuid) => {
|
export const getTopTracks = (uuid) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "tracks/top/" + uuid).then(
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/tracks/top/" + uuid).then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
@ -348,7 +348,7 @@ export const getTopTracks = (uuid) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getTopArtists = (uuid) => {
|
export const getTopArtists = (uuid) => {
|
||||||
return axios.get(process.env.REACT_APP_API_URL + "artists/top/" + uuid).then(
|
return axios.get(process.env.REACT_APP_API_URL + "/api/v1/artists/top/" + uuid).then(
|
||||||
(data) => {
|
(data) => {
|
||||||
return data.data;
|
return data.data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
|
@ -21,7 +21,7 @@ const TopTable = (props) => {
|
|||||||
number="1"
|
number="1"
|
||||||
title={tracks[1].name}
|
title={tracks[1].name}
|
||||||
link={"/" + props.type + "/" + tracks[1].uuid}
|
link={"/" + props.type + "/" + tracks[1].uuid}
|
||||||
img={tracks[1].img}
|
uuid={tracks[1].img}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{ Object.keys(props.items).length > 5 &&
|
{ Object.keys(props.items).length > 5 &&
|
||||||
@ -31,28 +31,28 @@ const TopTable = (props) => {
|
|||||||
number="2"
|
number="2"
|
||||||
title={tracks[2].name}
|
title={tracks[2].name}
|
||||||
link={"/" + props.type + "/" + tracks[2].uuid}
|
link={"/" + props.type + "/" + tracks[2].uuid}
|
||||||
img={tracks[2].img}
|
uuid={tracks[2].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={150}
|
size={150}
|
||||||
number="3"
|
number="3"
|
||||||
title={tracks[3].name}
|
title={tracks[3].name}
|
||||||
link={"/" + props.type + "/" + tracks[3].uuid}
|
link={"/" + props.type + "/" + tracks[3].uuid}
|
||||||
img={tracks[3].img}
|
uuid={tracks[3].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={150}
|
size={150}
|
||||||
number="4"
|
number="4"
|
||||||
title={tracks[4].name}
|
title={tracks[4].name}
|
||||||
link={"/" + props.type + "/" + tracks[4].uuid}
|
link={"/" + props.type + "/" + tracks[4].uuid}
|
||||||
img={tracks[4].img}
|
uuid={tracks[4].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={150}
|
size={150}
|
||||||
number="5"
|
number="5"
|
||||||
title={tracks[5].name}
|
title={tracks[5].name}
|
||||||
link={"/" + props.type + "/" + tracks[5].uuid}
|
link={"/" + props.type + "/" + tracks[5].uuid}
|
||||||
img={tracks[5].img}
|
uuid={tracks[5].img}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -63,63 +63,63 @@ const TopTable = (props) => {
|
|||||||
number="6"
|
number="6"
|
||||||
title={tracks[6].name}
|
title={tracks[6].name}
|
||||||
link={"/" + props.type + "/" + tracks[6].uuid}
|
link={"/" + props.type + "/" + tracks[6].uuid}
|
||||||
img={tracks[6].img}
|
uuid={tracks[6].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="7"
|
number="7"
|
||||||
title={tracks[7].name}
|
title={tracks[7].name}
|
||||||
link={"/" + props.type + "/" + tracks[7].uuid}
|
link={"/" + props.type + "/" + tracks[7].uuid}
|
||||||
img={tracks[7].img}
|
uuid={tracks[7].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="8"
|
number="8"
|
||||||
title={tracks[8].name}
|
title={tracks[8].name}
|
||||||
link={"/" + props.type + "/" + tracks[8].uuid}
|
link={"/" + props.type + "/" + tracks[8].uuid}
|
||||||
img={tracks[8].img}
|
uuid={tracks[8].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="9"
|
number="9"
|
||||||
title={tracks[9].name}
|
title={tracks[9].name}
|
||||||
link={"/" + props.type + "/" + tracks[9].uuid}
|
link={"/" + props.type + "/" + tracks[9].uuid}
|
||||||
img={tracks[9].img}
|
uuid={tracks[9].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="10"
|
number="10"
|
||||||
title={tracks[10].name}
|
title={tracks[10].name}
|
||||||
link={"/" + props.type + "/" + tracks[10].uuid}
|
link={"/" + props.type + "/" + tracks[10].uuid}
|
||||||
img={tracks[10].img}
|
uuid={tracks[10].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="11"
|
number="11"
|
||||||
title={tracks[11].name}
|
title={tracks[11].name}
|
||||||
link={"/" + props.type + "/" + tracks[11].uuid}
|
link={"/" + props.type + "/" + tracks[11].uuid}
|
||||||
img={tracks[11].img}
|
uuid={tracks[11].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="12"
|
number="12"
|
||||||
title={tracks[12].name}
|
title={tracks[12].name}
|
||||||
link={"/" + props.type + "/" + tracks[12].uuid}
|
link={"/" + props.type + "/" + tracks[12].uuid}
|
||||||
img={tracks[12].img}
|
uuid={tracks[12].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="13"
|
number="13"
|
||||||
title={tracks[13].name}
|
title={tracks[13].name}
|
||||||
link={"/" + props.type + "/" + tracks[13].uuid}
|
link={"/" + props.type + "/" + tracks[13].uuid}
|
||||||
img={tracks[13].img}
|
uuid={tracks[13].img}
|
||||||
/>
|
/>
|
||||||
<TopTableBox
|
<TopTableBox
|
||||||
size={100}
|
size={100}
|
||||||
number="14"
|
number="14"
|
||||||
title={tracks[14].name}
|
title={tracks[14].name}
|
||||||
link={"/" + props.type + "/" + tracks[14].uuid}
|
link={"/" + props.type + "/" + tracks[14].uuid}
|
||||||
img={tracks[14].img}
|
uuid={tracks[14].img}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,12 @@ import { Link } from 'react-router-dom';
|
|||||||
import './TopTableBox.css'
|
import './TopTableBox.css'
|
||||||
|
|
||||||
const TopTableBox = (props) => {
|
const TopTableBox = (props) => {
|
||||||
let img = 'https://www.foot.com/wp-content/uploads/2017/06/placeholder-square-300x300.jpg';
|
|
||||||
if (props.img && props.img !== '') {
|
|
||||||
img = props.img
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link to={props.link} float="left" >
|
<Link to={props.link} float="left" >
|
||||||
<div
|
<div
|
||||||
className="topTableBox"
|
className="topTableBox"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `url(${img})`,
|
backgroundImage: `url(${process.env.REACT_APP_API_URL + "/img/" + props.uuid + "_full.jpg"})`,
|
||||||
backgroundSize: `cover`,
|
backgroundSize: `cover`,
|
||||||
backgroundPosition: `top center`,
|
backgroundPosition: `top center`,
|
||||||
width: `${props.size}px`,
|
width: `${props.size}px`,
|
||||||
|
Loading…
Reference in New Issue
Block a user