Skip to content

Latest commit

 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

spotify-tools

Two CLI tools built on the same Spotify auth/client foundation:

  1. albumize — takes a CSV of artist,album rows and builds a Spotify playlist containing every track it can find from those albums, reporting anything it couldn't match confidently.
  2. cover — given an existing playlist, samples its most frequent artists (+ their genres), builds a prompt from them, and generates + uploads an AI cover image for the playlist.

Built with Deno — no node_modules, no build step.

Setup

  1. Install Deno if you haven't: brew install deno
  2. In your Spotify Developer Dashboard app, add this redirect URI: http://127.0.0.1:8080/callback
  3. Copy .env.example to .env and fill in your SPOTIFY_CLIENT_ID (found on your app's dashboard page) and, if you'll use cover, your OPENAI_API_KEY. No Spotify client secret is needed — auth uses PKCE.
cp .env.example .env
# edit .env with your client ID (and OpenAI key, if using `cover`)

Usage

albumize

deno task albumize path/to/albums.csv --name "My Playlist" --dry-run
  • --name (required): name of the playlist to create.
  • --public true|false (default false): whether the playlist is public.
  • --dry-run: match and print the report only, skip creating/populating a playlist. Use this first to sanity-check matches before spending API calls creating a real playlist.

CSV input needs artist,album columns (header row required).

After matching, the tool prints a report:

  • Matched — albums found with high confidence, included automatically.
  • Ambiguous — best guess included, but flagged for a manual spot-check.
  • Not found — nothing confident enough; add these to the playlist by hand.

cover

deno task cover <playlist-id-or-url> --dry-run

Accepts a bare playlist ID, a spotify:playlist:... URI, or an open.spotify.com/playlist/... URL.

  • --sample-size (default 12): how many of the playlist's most-frequent artists to sample (used to derive genres — see below).
  • --prompt "<extra text>": appended to the end of the generated prompt, e.g. to steer toward a specific visual style (--prompt "in the style of a layered paper collage"). Skips the interactive style menu described below.
  • --no-style: skip the interactive style menu without providing --prompt — goes straight to the plain genre-only prompt. Useful for scripting, since the menu otherwise blocks waiting on stdin.
  • --no-upload: generate and save the image locally but don't attempt to set it as the playlist's cover. Since setting a cover requires owning the playlist (or being a collaborator), this is also how you can generate art for a public playlist you don't own — reading a public playlist's tracks needs no special permission, only the upload step does.
  • --dry-run: sample artists, fetch genres, and print the constructed prompt — skips the OpenAI call and the cover upload. Free to run repeatedly; only the real run costs an OpenAI image generation.

The prompt is built from genre only, not artist names — a real, recognizable musician in the prompt can trip OpenAI's output moderation for depicting a real person's likeness, even with no request for a portrait. Sampled artists still drive which genres get used and show up in the CLI output, just not in the text sent to the image model.

If neither --prompt nor --no-style is given, the tool prompts interactively with a numbered list of visual styles (collage, film photography, geometric abstraction, risograph print, etc.) — pick one to steer the image, or press Enter for a plain genre-only prompt. This exists because a fixed "abstract, atmospheric" prompt alone tends to converge on similar-looking imagery across different playlists.

Prints the sampled artists, their genres, and the exact prompt sent to the image model. On a real run, the generated image is saved locally to cover-art/<playlist-id>-<timestamp>.jpg (each run gets its own file, so repeat runs don't overwrite earlier ones) in addition to being uploaded as the playlist's cover.

This command requests an additional scope (ugc-image-upload) beyond what albumize needs — if you've already authorized albumize on this machine, the first cover run will open your browser once more to pick up the new scope; after that it's cached like normal.

Sample output:

Sample cover art 1 Sample cover art 4

Sample cover art 3 Sample cover art 2

Auth

The first run of either command opens your browser for one-time Spotify authorization. Tokens are cached at ~/.config/spotify-playlist-tools/token.json and silently refreshed on later runs.

About

Spotify CLI tools for creating playlists from CSV, playlist art creation, and more.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages