Skip to content

Commit

Permalink
Improved look and feel
Browse files Browse the repository at this point in the history
  • Loading branch information
JaiiR320 committed Feb 15, 2024
1 parent 5739395 commit fa2c38f
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 145 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
/bin

# Tailwind CLI
tailwind.exe
tailwind.exe

.env
29 changes: 28 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,29 @@
# SpotifAI


## Description

Website used to load in a user's liked library, then go through each song and use AI to tag the songs. There will be MANY tags, so a search bar is used to search keywords that equal or match the tag. Once a tags have been selected, you can export that to a playlist to Spotify.

## Key features

- AI tagging songs
- Filter library by tags
- Export to playlist

## Roadmap

- Add a user to the website
- Import a user's library and list
- read through user's library and create tags
- add filtering by fuzzy find
- export tagged songs to a playlist

## Future additions

- Remove or add tags to specific songs
- Create custom tags (playlists)
- Global database with all songs and all tags (might be extremely taxing think of paging to reduce object size)
- Search global database using same search system
- Intelligent addition of tags
- Improve tagging and tag names
- Standalone Spotify addon?
2 changes: 1 addition & 1 deletion bin/build-errors.log

Large diffs are not rendered by default.

46 changes: 26 additions & 20 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ func main() {
router.PUT("/tag", HandleAddTag)
router.DELETE("/tag/:name", HandleDeleteTag)

// initialize liked songs list
scripts.InitializeSongList("example.json")

log.Fatal(router.Start(":3000"))
}

Expand Down Expand Up @@ -96,11 +93,37 @@ func HandleSpotifyCallback(c echo.Context) error {
}

log.Println(model.CurrentUser.DisplayName, "logged in")
err = getLikedSongs()
if err != nil {
return err
}

model.Logged = true

return c.Redirect(http.StatusFound, "/")
}

func getLikedSongs() error {
log.Println("Getting liked songs")
client := req.C()
resp, err := client.R().
SetHeader("Authorization", "Bearer "+model.AccessToken.AccessToken).
SetSuccessResult(&model.LikedSongsResponse).
Get("https://api.spotify.com/v1/me/tracks")
if err != nil {
return err
}

if resp.GetStatusCode() != http.StatusOK {
return fmt.Errorf("no response from Spotify")
}

model.LikedSongs = model.LikedSongsResponse.Items
model.FilteredSongs = model.LikedSongsResponse.Items

return nil
}

func getToken(c echo.Context) error {
log.Println("Getting token")
idAndSecret := base64.StdEncoding.EncodeToString([]byte(model.Client_id + ":" + model.Client_secret))
Expand All @@ -113,7 +136,6 @@ func getToken(c echo.Context) error {
SetQueryParam("code", c.QueryParam("code")).
SetQueryParam("redirect_uri", "http://localhost:3000/callback").
SetSuccessResult(&model.AccessToken).
EnableDump().
Post("https://accounts.spotify.com/api/token")
if err != nil {
return err
Expand All @@ -132,7 +154,6 @@ func getUser() error {
resp, err := client.R().
SetHeader("Authorization", "Bearer "+model.AccessToken.AccessToken).
SetSuccessResult(&model.CurrentUser).
EnableDump().
Get("https://api.spotify.com/v1/me")
if err != nil {
return err
Expand All @@ -144,18 +165,3 @@ func getUser() error {

return nil
}

// req := scripts.Get("https://api.spotify.com/v1/me").
// WithHeader("Authorization", "Bearer "+model.AccessToken.AccessToken).
// WithObject(&model.CurrentUser)
// return req.Do()

// post := scripts.Post("https://accounts.spotify.com/api/token").
// WithHeader("Content-Type", "application/x-www-form-urlencoded").
// WithHeader("Authorization", "Basic "+idAndSecret).
// WithQuery("grant_type", "authorization_code").
// WithQuery("code", c.QueryParam("code")).
// WithQuery("redirect_uri", "http://localhost:3000/callback").
// WithObject(&model.AccessToken)

// return post.Do()
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imroc/req/v3 v3.42.3 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/klauspost/compress v1.17.6 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/imroc/req/v3 v3.42.3 h1:ryPG2AiwouutAopwPxKpWKyxgvO8fB3hts4JXlh3PaE=
github.com/imroc/req/v3 v3.42.3/go.mod h1:Axz9Y/a2b++w5/Jht3IhQsdBzrG1ftJd1OJhu21bB2Q=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
Expand Down
4 changes: 3 additions & 1 deletion model/functions.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package model

import "github.com/JaiiR320/SpotifAI/utils"
import (
"github.com/JaiiR320/SpotifAI/utils"
)

func AddTag(tag string) {
Tags = append(Tags, tag)
Expand Down
2 changes: 2 additions & 0 deletions model/globals.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ var Tags []string
var LikedSongs []Item
var FilteredSongs []Item

var LikedSongsResponse Playlist

// Access variables
var AccessToken TokenResponse
var CurrentUser User
Expand Down
11 changes: 9 additions & 2 deletions scripts/buildGPTRequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@ import (
"encoding/json"
"errors"
"net/http"
"os"

"github.com/JaiiR320/SpotifAI/model"
"github.com/imroc/req/v3"
"github.com/joho/godotenv"
)

var OpenAIKey = "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"

func GenerateTracks(tracks []model.Item, tags []string) (string, error) {
err := godotenv.Load(".env")
if err != nil {
return "", err
}

OpenAIKey := os.Getenv("OPENAI_KEY")

if len(tracks) == 0 || len(tags) == 0 {
return "", errors.New("no tracks or tags to filter")
}
Expand Down
29 changes: 3 additions & 26 deletions scripts/filterSongs.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ import (

func FilterSongs(songs []model.Item, tags []string) []model.Item {
if len(tags) == 0 {
log.Println("No tags to filter")
return model.LikedSongs
}
//GenerateTracks(model.LikedSongs, model.Tags)
log.Print("Filtering songs")
selectedItems := make([]model.Item, 0)
for i := 0; i < 15; i++ {
for i := 0; i < 20; i++ {
randomIndex := rand.Intn(len(model.LikedSongs))
selectedItems = append(selectedItems, model.LikedSongs[randomIndex])
}
//return GenerateTracks(model.LikedSongs, model.Tags)
return selectedItems
}

Expand All @@ -28,27 +29,3 @@ type Song struct {
type Songs struct {
Songs []Song `json:"songs"`
}

// Filter Songs
// str, err := GenerateTracks(model.LikedSongs, model.Tags)
// if err != nil {
// log.Panic(err)
// }

// var jsonSongs Songs
// err = json.Unmarshal([]byte(str), &jsonSongs)
// if err != nil {
// log.Panic(err)
// }

// var filteredSongs []model.Item

// for _, s := range jsonSongs.Songs {
// for _, song := range songs {
// if strings.Contains(song.Track.Name, s.Title) {
// filteredSongs = append(filteredSongs, song)
// }
// }
// }

// return filteredSongs
86 changes: 73 additions & 13 deletions static/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,10 @@ video {
height: 3rem;
}

.h-24 {
height: 6rem;
}

.h-6 {
height: 1.5rem;
}
Expand All @@ -585,6 +589,10 @@ video {
height: 100%;
}

.h-svh {
height: 100svh;
}

.w-1\/3 {
width: 33.333333%;
}
Expand All @@ -605,6 +613,22 @@ video {
width: auto;
}

.w-full {
width: 100%;
}

.w-4 {
width: 1rem;
}

.w-9 {
width: 2.25rem;
}

.flex-grow {
flex-grow: 1;
}

.scale-150 {
--tw-scale-x: 1.5;
--tw-scale-y: 1.5;
Expand All @@ -623,18 +647,26 @@ video {
align-items: center;
}

.justify-start {
justify-content: flex-start;
.justify-normal {
justify-content: normal;
}

.justify-center {
justify-content: center;
.justify-start {
justify-content: flex-start;
}

.justify-between {
justify-content: space-between;
}

.overflow-hidden {
overflow: hidden;
}

.overflow-y-auto {
overflow-y: auto;
}

.truncate {
overflow: hidden;
text-overflow: ellipsis;
Expand Down Expand Up @@ -695,24 +727,47 @@ video {
padding-right: 0.75rem;
}

.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}

.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}

.pl-4 {
padding-left: 1rem;
}

.pt-1 {
padding-top: 0.25rem;
}

.pr-4 {
padding-right: 1rem;
}

.pt-4 {
padding-top: 1rem;
}

.pt-3 {
padding-top: 0.75rem;
}

.pt-2 {
padding-top: 0.5rem;
}

.pt-2\.5 {
padding-top: 0.625rem;
}

.text-center {
text-align: center;
}

.text-right {
text-align: right;
}

.align-middle {
vertical-align: middle;
}
Expand Down Expand Up @@ -746,6 +801,11 @@ video {
line-height: 1.75rem;
}

.text-base {
font-size: 1rem;
line-height: 1.5rem;
}

.font-bold {
font-weight: 700;
}
Expand Down Expand Up @@ -774,10 +834,6 @@ video {
outline-offset: 2px;
}

.filter {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}

.transition-transform {
transition-property: transform;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
Expand All @@ -792,6 +848,10 @@ video {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

.fitView {
height: calc(100vh - 7.5rem);
}

.hover\:scale-110:hover {
--tw-scale-x: 1.1;
--tw-scale-y: 1.1;
Expand Down
Loading

0 comments on commit fa2c38f

Please sign in to comment.