https://github.com/awernick/plvc
Spotifty Playlist Version Control
https://github.com/awernick/plvc
git github python3 spotify
Last synced: 3 months ago
JSON representation
Spotifty Playlist Version Control
- Host: GitHub
- URL: https://github.com/awernick/plvc
- Owner: awernick
- Created: 2020-06-28T18:14:56.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2023-01-23T22:07:27.000Z (over 3 years ago)
- Last Synced: 2025-12-31T23:55:40.927Z (6 months ago)
- Topics: git, github, python3, spotify
- Language: Python
- Homepage:
- Size: 42 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 11
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# plvc - Spotify Playlist Version Control
I was tired of loosing / forgetting awesome songs due to Spotify's daily modification of their playlists, so I decided to create plvc.
Plvc was created with two goals in mind:
1. Tracking changes to your playlists:
- Adding / removing songs
- Spotify removing songs due to licensing issues
2. Tracking new / old playlists added to your personal library
## How Does It Work?
There are three components to plvc:
- Spotify API
- Git repos
- Github PR API
To keep things simple, I decided to use git's version control capabilities to keep track of changes to my Spotify playlists.
For each playlist in a Spotify account, plvc creates a `{playlist_uid}_{playlist_normalized_name}.txt` file with the following format:
```
{playlist_uid} - {playlist_name} by {playlist_owner}
{track_uid} - {track_name} by {track_artists}
{track_uid} - {track_name} by {track_artists}
{track_uid} - {track_name} by {track_artists}
...
```
In addition to creating playlist text files, plvc requires an additional git repository to store / track changes to the generated files. This repository will contain the history of track / playlist changes, making it easy to see how your music changed over time.
For example, let's assume we have these two repos:
```
plvc.git - repo containing the version control logic
history.git - repo containing playlist text files and history
```
When running plvc, the following steps will occur:
1. Pull the latest master from origin in our `history.git` repo
2. Create a temporary branch from master. Branch name will be the current timestamp e.g `Aug-28-2020-12-23-05`
3. Using the Spotify API, generate a playlist text file containing all the track metadata
4. Create a commit containing the newly generated playlist text files, and push to origin
5. Using the Github API, create a PR from our temporary branch to our base branch (`master`)
6. If no conflicts are found, automatically merge and close the PR.
7. Profit
## Usage
To use plvc, a few ENV variables are needed:
```
PLAYLIST_REPO_DIR - Absolute path to the repository containg the playlist text files (`history.git` in the example)
PLAYLIST_REPO_REMOTE_URL - Origin remote url for our playlist history repository
SPOTIFY_CLIENT_ID - Spotify client ID
SPOTIFY_CLIENT_SECRET - Spotify client secret
SPOTIFY_REDIRECT_URI - Spotify redirect URI
SPOTIFY_USERNAME - Spotify username
GITHUB_ACCESS_TOKEN - Github access token with repo permissions
GITHUB_PLAYLIST_REPO_ID - Repository name for the playlist history in Github
SENTRY_DSN - DSN to report to Sentry. Not needed, but I use it for my own personal reporting in my server
```
These variables can be stored in an `.env` file within the plvc directory, or loaded in your execution environment.
To start plvc:
```
# Skip if you don't need a virtualenv
pyhton3 -m venv venv
source venv/bin/activate
pip3 install -r plvc/requirements.txt
python3 plvc
```
## Troubleshooting
### 1. My plvc instance is stuck in `[Spotify] Authenticating via OAuth`
In order to view a user's public and private playlists, plvc needs to use Spotify's [Authorization Code Flow](https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow). This auth flow requires the account owner to accept a prompt giving plvc permission to access their personal information.
This auth flow should work fine if you are running plvc in an environment with a graphical user interface (e.g. your personal laptop, a server with a windowing system, etc...)
If you are running plvc on a server, you will need to obtain your Spotify access token and refresh token somehow and store it in a `token-info.json` at the root of your plvc directory.
To obtain a valid `token-info.json` file to be used server side, I recommend:
1. Running plvc in an environment that has a GUI and a browser
2. Copying the `token-info.json` generated by plvc to your server
3. Run plvc server-side and ensure that the auth process is working correctly
If you know of other ways of obtaining a valid Spotify access token and refresh token, then simply create a `token-info.json` file in the root of your plvc directory and plug in the values.
The `token-info.json` file should look like this:
```
{
"access_token": "YOURACCESSTOKEN",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "playlist-read-collaborative playlist-read-private user-library-read",
"expires_at": 1598642585,
"refresh_token": "YOURREFRESHTOKEN"
}
```
### 2. I can't pull / push from / to my playlist history repository
Since we are pushing / pulling from a remote origin, make sure that the user excuting plvc has read / write permissions to the playlist history repository.
### 3. Why are PRs not being created in my Github repository?
Make sure that the Github access token you are using with plvc has the following permissions:
## Additional Setup
In my personal setup, I'm running plvc as a systemd service with a 1 hour trigger.
Here are my config files:
**plvc.service:**
```
[Unit]
Description=plvc
Wants=plvc.timer
[Service]
Type=simple
WorkingDirectory=/path/to/plvc
ExecStart=/path/to/plvc/venv/bin/python .
[Install]
WantedBy=multi-user.target
```
**plvc.timer:**
```
[Unit]
Description=Run plvc every hour
Requires=plvc.service
[Timer]
Unit=plvc.service
OnUnitInactiveSec=60m
AccuracySec=1s
[Install]
WantedBy=timers.target
```
For error reporting, I use [Sentry](https://sentry.io/) to send email notifications whenever an exception is raised.