Skip to content

spotify playlist created #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed

Conversation

yashchau1303
Copy link

A python script to automate the creation of Spotify playlist and adding songs from Postgres database

Copy link
Member

@parth-paradkar parth-paradkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great initial PR, we can work more on top of this. Some suggestions:

  1. I think you should rename the directory to spotify_playlist
  2. We do not use the input function, since this code will run on the server. A playlist has already been created. You can add environment variables for Spotify playlist id, username, etc. Add them in the .env file and change the .env.template accordingly.
  3. You need to update the same playlist instead of creating a new one.
    Thanks!

Comment on lines 11 to 14
songs = []
q = session.query(Song).limit(50).all()
for i in q:
songs.append(i.name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be replaced by a list comprehension to make it cleaner.

q = session.query(Song).limit(50).all()
return [song.name for song in q]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, this function should be renamed to get_song_names



scope="playlist-modify-public"
username="Put your userid"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be loaded from an environment variable

Comment on lines 13 to 15
playlist_name = input("Enter a playlist name: ")
playlist_description = input("Enter a playlist description: ")
spotifyObject.user_playlist_create(user=username,name=playlist_name,public=True,description=playlist_description)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably won't need this code once the playlist has been created. Instead, we should get the playlist from user playlists using its id, which can be loaded from the environment variables.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your code seems to assume that we create a new playlist every time. However, we need to update a single playlist with the latest songs.

Comment on lines 20 to 23
for i in songs:
result = spotifyObject.search(q=i)
if(len(result['tracks']['items'])!=0):
list_of_songs.append(result['tracks']['items'][0]['uri'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can also be replaced by a list comprehension. Not so urgent though.


engine = create_engine('Database URL')
engine.dialect.description_encoding = None
session = Session(bind=engine)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are using a context manager that gets called to create sessions and commit the changes
You don't need to import sqlalchemy here since we have already written a context manager that handles this. Please have a look at c3po/db/metadata.py where it has been used.

@parth-paradkar
Copy link
Member

parth-paradkar commented Dec 16, 2020

@yashchau1303 please have a look at this where I have used the provider_id to get the Spotify ID. Instead of using the Songs table, we can use the posts table.

@pep8speaks
Copy link

pep8speaks commented Dec 18, 2020

Hello @yashchau1303! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

Line 7:1: E302 expected 2 blank lines, found 1
Line 10:14: E231 missing whitespace after ','
Line 10:43: E231 missing whitespace after ','
Line 10:74: E225 missing whitespace around operator
Line 10:80: E501 line too long (100 > 79 characters)
Line 11:26: E225 missing whitespace around operator
Line 18:21: W292 no newline at end of file

Line 7:6: E225 missing whitespace around operator
Line 8:9: E225 missing whitespace around operator
Line 9:33: E231 missing whitespace after ','
Line 12:2: E114 indentation is not a multiple of four (comment)
Line 12:2: E116 unexpected indentation (comment)
Line 19:57: E231 missing whitespace after ','
Line 19:81: E231 missing whitespace after ','
Line 19:103: W292 no newline at end of file

Line 4:1: E302 expected 2 blank lines, found 1

Comment last updated at 2020-12-18 13:27:12 UTC

Copy link
Member

@parth-paradkar parth-paradkar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make the requested changes

import os
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is not required here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which import??

Comment on lines 23 to 26




Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the whitespace

Comment on lines 7 to 10
engine = create_engine('postgresql+psycopg2://yash:root@localhost:5432/yash_test')
engine.dialect.description_encoding = None
session = Session(bind=engine)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not need this code. We are using context managers. If you need to use a session use with session_scope() as session: to create a new block. Import that from c3po.db.base. Refer to c3po/db/metadata.py for examples.

permalink_url = Column(String)
# permalink_url = Column(String)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't see how this is relevant to this PR. Can you please elaborate?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was getting an error as this column was not used further

playlist_id = os.getenv("SPOTIFY_PLAYLIST_ID")

# add songs to playlist
spotifyObject.user_playlist_add_tracks(user=username,playlist_id=playlist_id,tracks=list_of_songs)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't want to add all the songs that were fetched from the DB to be added again. For example, if we already have 50 songs in the playlist, this code will probably add 50 more on the second run, taking the number of songs to 100 with duplicates. Possible ways you can solve this:

  1. Remove all the songs in the playlist and the newly fetched songs.
  2. Write logic to cross-check between the list fetched from DB and the list of songs that already exist in the playlist and replace the ones that are not there in the list fetched from DB with the new ones.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also keep in mind that you are using spotipy v2.13.0 that is installed as a dependency of metadata-extractor. Ensure that you are using the methods given in that version and not the latest version.

# get first 50 songs from the db
def get_song_names():
songs = []
for u , l in session.query(UserPosts,Link).filter(UserPosts.link_id==Link.id).all():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a heavy query that will consume a lot of time. It is basically fetching all the posts and links from the table, the count of which is huge. We do not want to run such a heavy DB query. Please make use of limit and offset and modify your code logic accordingly.

session = Session(bind=engine)

# get first 50 songs from the db
def get_song_names():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the name to get_song_url

Comment on lines +14 to +15
else:
continue
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is code is redundant

songs = []
for u,l in session.query(UserPosts,Link).filter(UserPosts.link_id==Link.id).limit(50).all():
if len(songs)<=50:
if get_spotify_id(l.url) is not None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be changed to simply if get_spotify_id(l.url):

def get_song_url():
with session_scope() as session:
songs = []
for u,l in session.query(UserPosts,Link).filter(UserPosts.link_id==Link.id).limit(50).all():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are not using the u variable anywhere. It would be better if you queried the Songs table (which has entries that definitely have corresponding Spotify IDs). Do a join with the Links table and then get the URLs from there. This would ensure you get 50 songs in a single go.

@mukul-mehta mukul-mehta removed their request for review January 6, 2021 21:07
@parth-paradkar
Copy link
Member

Closing due to inactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants