spotifytobandcamp/server.go

274 lines
7.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"log"
"time"
"errors"
"strings"
"strconv"
"net/http"
"encoding/json"
"github.com/gofiber/fiber/v2"
"github.com/undertideco/bandcamp"
"github.com/gofiber/template/html"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/fiber/v2/middleware/session"
)
var MyClient = &http.Client{}
var Session = session.New()
var Queue = make(map[string]*RespBandcamp)
func checkToken(sess *session.Session) {
expire := sess.Get("expire")
if expire != nil {
if time.Now().Unix() > sess.Get("creation").(int64) + expire.(int64) {
sess.Destroy()
}
}
}
/*
check artist and album
items[x].track.album.name et items[x].track.album.artists[0].name
*/
func searchAlbumBandcamp(album string, artist string) (bool, string) {
bandcampClient := bandcamp.NewClient()
results, err := bandcampClient.Search(album)
if err != nil {
log.Println(err)
return false, ""
}
findAlbum := strings.ToLower(results[0].Title)
findArtist := strings.ToLower(results[0].Artist)
album = strings.ToLower(album)
artist = strings.ToLower(artist)
if (strings.Contains(findAlbum, album) || strings.Contains(album, findAlbum)) && strings.Compare(findArtist, artist) == 0 {
return true, results[0].URL
} else {
return false, ""
}
}
func searchArtistBandcamp(artist string) (bool, string) {
bandcampClient := bandcamp.NewClient()
results, err := bandcampClient.Search(artist)
if err != nil {
log.Println(err)
return false, ""
}
findArtist := strings.ToLower(results[0].Artist)
artist = strings.ToLower(artist)
if strings.Compare(findArtist, artist) == 0 {
return true, strings.Split(results[0].URL, "/album/")[0]
} else {
return false, ""
}
}
func testSpotifyPlaylist(token, tokentype, id string) error {
req, e := http.NewRequest("GET",
"https://api.spotify.com/v1/playlists/"+id+"/tracks", nil)
if e != nil {
return e
}
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", tokentype + " " + token)
res, err := MyClient.Do(req)
if err != nil {
return err
}
switch res.StatusCode {
case 400: return errors.New("La requete sest mal exécutée.")
case 401: return errors.New("La Playlist semble être privée.")
case 403: return errors.New("Accès refusé (token peut-être périmé).")
case 404: return errors.New("Playlist inexistante.")
}
return nil
}
func getAllTracksPlaylist(token, tokentype, id string, offset int) SpotifyPlaylist {
ret := SpotifyPlaylist{}
req, _ := http.NewRequest("GET",
"https://api.spotify.com/v1/playlists/"+id+"/tracks?offset="+strconv.FormatInt(int64(offset), 10),
nil)
req.Header.Add("Accept", "application/json")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", tokentype + " " + token)
res, _ := MyClient.Do(req)
playlist := &SpotifyPlaylist{}
defer res.Body.Close()
err := json.NewDecoder(res.Body).Decode(&playlist)
if err != nil {
log.Print(err.Error())
return ret
}
ret = *playlist
if ret.Total > offset {
r := getAllTracksPlaylist(token, tokentype, id, offset + 100)
ret.Items = append(ret.Items, r.Items...)
}
return ret
}
/*
id de la playlist
*/
func getListPlaylist(id, token, tokentype string) {
playlist := getAllTracksPlaylist(token, tokentype, id, 0)
var find bool
var tmp, artist, album, urlSpotify string
var MyResp = &RespBandcamp{}
MyResp.Todo = len(playlist.Items)
MyResp.Done = 0
Queue[token] = MyResp
for i := 0; i < len(playlist.Items); i++ {
album = playlist.Items[i].Track.Album.Name
artist = playlist.Items[i].Track.Album.Artists[0].Name
urlSpotify = playlist.Items[i].Track.Album.ExternalUrls.Spotify
if (MyResp.ContainsAlbum(album, artist)) {
MyResp.Todo--
continue
}
find, tmp = searchAlbumBandcamp(album, artist)
if find {
MyResp.AddAlbum(newUrlBandcamp(artist, album, urlSpotify, tmp))
} else {
find, tmp = searchArtistBandcamp(artist)
if find {
MyResp.AddArtist(newUrlBandcamp(artist, album, urlSpotify, tmp))
} else {
MyResp.AddNotfound(newUrlWoBandcamp(artist, album, urlSpotify))
}
}
MyResp.Done++
if i % 10 == 0 {
time.Sleep(5 * time.Second)
}
}
fmt.Printf("\nFinish\n")
}
func formHandler (c *fiber.Ctx) error {
sess, _ := Session.Get(c)
checkToken(sess)
if sess.Get("token") == nil {
panic("Vous nêtes pas connecté à Spotify.")
}
token := sess.Get("token").(string)
tokentype := sess.Get("tokentype").(string)
id := c.FormValue("id")
e := testSpotifyPlaylist(token, tokentype, id)
if e != nil {
panic(e.Error())
}
Queue[token] = nil
c.Set("Location", "/feudecamp")
go getListPlaylist(id, token, tokentype)
return c.SendStatus(303)
}
func getNew(c *fiber.Ctx) error {
sess, _ := Session.Get(c)
c.JSON(Queue[sess.Get("token").(string)])
return c.SendStatus(201)
}
func mytoken(c *fiber.Ctx) error {
tmp := newTokenUser()
err := c.BodyParser(&tmp)
if err != nil {
log.Panic(err.Error())
} else {
sess, err := Session.Get(c)
if err != nil {
log.Panic(err.Error())
}
expire, _ := strconv.Atoi(tmp.ExpiresIn)
sess.Set("token", tmp.Token)
sess.Set("expire", int64(expire))
sess.Set("tokentype", tmp.TokenType)
sess.Set("creation", time.Now().Unix())
err = sess.Save()
if err != nil {
log.Panic(err.Error())
}
}
return c.SendStatus(201)
}
func spotifyCallback(c *fiber.Ctx) error {
if c.Query("error") != "" {
return c.Render("index", fiber.Map{"error": "Erreur lors de la connexion.",})
} else {
return c.Render("spotify-token", fiber.Map{})
}
}
func index(c *fiber.Ctx) error {
sess, _ := Session.Get(c)
checkToken(sess)
return c.Render("index", fiber.Map{"connected": sess.Get("token") != nil,
"url": SpotifyURL})
}
func fdc(c *fiber.Ctx) error {
sess, _ := Session.Get(c)
if sess.Get("token") == nil {
panic("Vous nêtes pas connecté.")
} else if _, err := Queue[sess.Get("token").(string)]; !err {
panic("Vous navez pas lancé de playlist.")
}
return c.Render("feudecamp", fiber.Map{})
}
func main() {
//app := fiber.New(fiber.Config(Views: html, ViewsLayout: "layouts/main"))
app := fiber.New(fiber.Config{Views: html.New("./views", ".html"),})
app.Use(recover.New())
app.Static("/", "./static")
app.Get("/", index)
app.Post("/", mytoken)
app.Get("/feudecamp", fdc)
app.Post("/feudecamp", getNew)
app.Post("/back", formHandler)
app.Get("/callback", spotifyCallback)
log.Fatal(app.Listen(":8080"))
}