{"id":28646739,"url":"https://github.com/harisekhon/spotify-tools","last_synced_at":"2025-07-21T18:36:53.732Z","repository":{"id":6150874,"uuid":"7380122","full_name":"HariSekhon/Spotify-tools","owner":"HariSekhon","description":"Spotify Tools - Playlists Backups, Spotify CLI, URI translator, duplication detection / removal, API search queries, API automation etc.","archived":false,"fork":false,"pushed_at":"2025-03-14T19:44:30.000Z","size":725,"stargazers_count":76,"open_issues_count":0,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-13T02:06:48.346Z","etag":null,"topics":["bash","cli","golang","hacktoberfest","perl","spotify","spotify-api","spotify-cmd","spotify-metadata-api","spotify-uri","spotify-web-api","tool","tools"],"latest_commit_sha":null,"homepage":"https://www.linkedin.com/in/HariSekhon","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HariSekhon.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2012-12-30T20:35:53.000Z","updated_at":"2025-05-23T06:20:21.000Z","dependencies_parsed_at":"2022-08-06T19:15:18.354Z","dependency_job_id":"97269069-a82d-4d94-8963-755f40067aba","html_url":"https://github.com/HariSekhon/Spotify-tools","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/HariSekhon/Spotify-tools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HariSekhon%2FSpotify-tools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HariSekhon%2FSpotify-tools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HariSekhon%2FSpotify-tools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HariSekhon%2FSpotify-tools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HariSekhon","download_url":"https://codeload.github.com/HariSekhon/Spotify-tools/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HariSekhon%2FSpotify-tools/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266353142,"owners_count":23915900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-21T11:47:31.412Z","response_time":64,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","golang","hacktoberfest","perl","spotify","spotify-api","spotify-cmd","spotify-metadata-api","spotify-uri","spotify-web-api","tool","tools"],"created_at":"2025-06-13T02:06:47.429Z","updated_at":"2025-07-21T18:36:53.711Z","avatar_url":"https://github.com/HariSekhon.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spotify Tools\n\n[![Spotify Profile](https://img.shields.io/badge/Spotify%20Profile-HariSekhon-brightgreen?logo=spotify\u0026style=social)](https://open.spotify.com/user/harisekhon)\n[![GitHub stars](https://img.shields.io/github/stars/harisekhon/spotify-tools?logo=github)](https://github.com/HariSekhon/Spotify-tools/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/harisekhon/spotify-tools?logo=github)](https://github.com/HariSekhon/Spotify-tools/network)\n[![LineCount](https://sloc.xyz/github/HariSekhon/Spotify-tools/?badge-bg-color=2081C2)](https://github.com/boyter/scc/)\n[![Cocomo](https://sloc.xyz/github/HariSekhon/Spotify-tools/?badge-bg-color=2081C2\u0026category=cocomo)](https://github.com/boyter/scc/)\n[![My LinkedIn](https://img.shields.io/badge/LinkedIn%20Profile-HariSekhon-blue?logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIGZpbGw9IiNmZmZmZmYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+TGlua2VkSW48L3RpdGxlPjxwYXRoIGQ9Ik0yMC40NDcgMjAuNDUyaC0zLjU1NHYtNS41NjljMC0xLjMyOC0uMDI3LTMuMDM3LTEuODUyLTMuMDM3LTEuODUzIDAtMi4xMzYgMS40NDUtMi4xMzYgMi45Mzl2NS42NjdIOS4zNTFWOWgzLjQxNHYxLjU2MWguMDQ2Yy40NzctLjkgMS42MzctMS44NSAzLjM3LTEuODUgMy42MDEgMCA0LjI2NyAyLjM3IDQuMjY3IDUuNDU1djYuMjg2ek01LjMzNyA3LjQzM2MtMS4xNDQgMC0yLjA2My0uOTI2LTIuMDYzLTIuMDY1IDAtMS4xMzguOTItMi4wNjMgMi4wNjMtMi4wNjMgMS4xNCAwIDIuMDY0LjkyNSAyLjA2NCAyLjA2MyAwIDEuMTM5LS45MjUgMi4wNjUtMi4wNjQgMi4wNjV6bTEuNzgyIDEzLjAxOUgzLjU1NVY5aDMuNTY0djExLjQ1MnpNMjIuMjI1IDBIMS43NzFDLjc5MiAwIDAgLjc3NCAwIDEuNzI5djIwLjU0MkMwIDIzLjIyNy43OTIgMjQgMS43NzEgMjRoMjAuNDUxQzIzLjIgMjQgMjQgMjMuMjI3IDI0IDIyLjI3MVYxLjcyOUMyNCAuNzc0IDIzLjIgMCAyMi4yMjIgMGguMDAzeiIvPjwvc3ZnPgo=)](https://www.linkedin.com/in/HariSekhon/)\n[![GitHub Last Commit](https://img.shields.io/github/last-commit/HariSekhon/Spotify-Tools?logo=github)](https://github.com/HariSekhon/Spotify-tools/commits/master)\n\n[![Codacy](https://app.codacy.com/project/badge/Grade/afe697b0ce3f4df79f16b4b3d2ded54b)](https://www.codacy.com/gh/HariSekhon/Spotify-tools/dashboard)\n[![CodeFactor](https://www.codefactor.io/repository/github/harisekhon/spotify-tools/badge)](https://www.codefactor.io/repository/github/harisekhon/spotify-tools)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=HariSekhon_Spotify-tools\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=HariSekhon_Spotify-tools)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=HariSekhon_Spotify-tools\u0026metric=sqale_rating)](https://sonarcloud.io/dashboard?id=HariSekhon_Spotify-tools)\n[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=HariSekhon_Spotify-tools\u0026metric=reliability_rating)](https://sonarcloud.io/dashboard?id=HariSekhon_Spotify-tools)\n[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=HariSekhon_Spotify-tools\u0026metric=security_rating)](https://sonarcloud.io/dashboard?id=HariSekhon_Spotify-tools)\n[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=HariSekhon_Spotify-tools\u0026metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=HariSekhon_Spotify-tools)\n[![Linux](https://img.shields.io/badge/OS-Linux-blue?logo=linux)](https://github.com/HariSekhon/Spotify-tools#spotify-tools)\n[![Mac](https://img.shields.io/badge/OS-Mac-blue?logo=apple)](https://github.com/HariSekhon/Spotify-tools#spotify-tools)\n\n\u003c!--\n[![DockerHub](https://img.shields.io/badge/docker-available-blue?logo=docker\u0026logoColor=white)](https://hub.docker.com/r/harisekhon/nagios-plugins/)\n[![](https://images.microbadger.com/badges/image/harisekhon/spotify-tools.svg)](http://microbadger.com/#/images/harisekhon/spotify-tools)\n--\u003e\n\n[![CI Builds Overview](https://img.shields.io/badge/CI%20Builds-Overview%20Page-blue?logo=circleci)](https://harisekhon.github.io/CI-CD/)\n[![Jenkins](https://img.shields.io/badge/Jenkins-ready-blue?logo=jenkins\u0026logoColor=white)](https://github.com/HariSekhon/Spotify-tools/blob/master/Jenkinsfile)\n[![Concourse](https://img.shields.io/badge/Concourse-ready-blue?logo=concourse)](https://github.com/HariSekhon/Spotify-tools/blob/master/cicd/.concourse.yml)\n[![GoCD](https://img.shields.io/badge/GoCD-ready-blue?logo=go)](https://github.com/HariSekhon/Spotify-tools/blob/master/cicd/.gocd.yml)\n[![TeamCity](https://img.shields.io/badge/TeamCity-ready-blue?logo=teamcity)](https://github.com/HariSekhon/TeamCity-CI)\n\n[![CircleCI](https://circleci.com/gh/HariSekhon/Spotify-tools.svg?style=svg)](https://circleci.com/gh/HariSekhon/Spotify-tools)\n[![BuildKite](https://img.shields.io/buildkite/cb0dcf2e1eed7a2c3d6035b8c5ca1bf4a741c1153b89688fcf/master?label=BuildKite\u0026logo=buildkite)](https://buildkite.com/hari-sekhon/Spotify-tools)\n[![AppVeyor](https://img.shields.io/appveyor/build/harisekhon/Spotify-tools/master?logo=appveyor\u0026label=AppVeyor)](https://ci.appveyor.com/project/HariSekhon/Spotify-tools/branch/master)\n[![Drone](https://img.shields.io/drone/build/HariSekhon/Spotify-tools/master?logo=drone\u0026label=Drone)](https://cloud.drone.io/HariSekhon/Spotify-tools)\n[![Codefresh](https://g.codefresh.io/api/badges/pipeline/harisekhon/GitHub%2FSpotify-tools?branch=master\u0026key=eyJhbGciOiJIUzI1NiJ9.NWU1MmM5OGNiM2FiOWUzM2Y3ZDZmYjM3.O69674cW7vYom3v5JOGKXDbYgCVIJU9EWhXUMHl3zwA\u0026type=cf-1)](https://g.codefresh.io/pipelines/edit/new/builds?id=5ec401171350573576125f8d\u0026pipeline=Spotify-tools\u0026projects=GitHub\u0026projectId=5e52ca8ea284e00f882ea992\u0026rightbar=steps\u0026advanced=0\u0026context=github\u0026filter=page:1;pageSize:10;timeFrameStart:week)\n[![Cirrus CI](https://img.shields.io/cirrus/github/HariSekhon/Spotify-tools/master?logo=Cirrus%20CI\u0026label=Cirrus%20CI)](https://cirrus-ci.com/github/HariSekhon/Spotify-tools)\n[![Semaphore](https://harisekhon.semaphoreci.com/badges/Spotify-tools.svg)](https://harisekhon.semaphoreci.com/projects/Spotify-tools)\n[![Buddy](https://img.shields.io/badge/Buddy-ready-1A86FD?logo=buddy)](https://github.com/HariSekhon/Spotify-tools/blob/master/buddy.yml)\n[![Shippable](https://img.shields.io/badge/Shippable-legacy-lightgrey?logo=jfrog\u0026label=Shippable)](https://github.com/HariSekhon/Spotify-tools/blob/master/shippable.yml)\n[![Travis CI](https://img.shields.io/badge/TravisCI-ready-blue?logo=travis\u0026label=Travis%20CI)](https://github.com/HariSekhon/Spotify-tools/blob/master/.travis.yml)\n\n[![Azure DevOps](https://dev.azure.com/harisekhon/GitHub/_apis/build/status/HariSekhon.spotify-tools?branchName=master)](https://dev.azure.com/harisekhon/GitHub/_build/latest?definitionId=3\u0026branchName=master)\n[![GitLab Pipeline](https://img.shields.io/badge/GitLab%20CI-legacy-lightgrey?logo=gitlab)](https://gitlab.com/HariSekhon/spotify-tools/pipelines)\n[![BitBucket Pipeline](https://img.shields.io/badge/Bitbucket%20CI-legacy-lightgrey?logo=bitbucket)](https://bitbucket.org/harisekhon/spotify-tools/addon/pipelines/home#!/)\n[![AWS CodeBuild](https://img.shields.io/badge/AWS%20CodeBuild-ready-blue?logo=amazon%20aws)](https://github.com/HariSekhon/Spotify-tools/blob/master/cicd/buildspec.yml)\n[![GCP Cloud Build](https://img.shields.io/badge/GCP%20Cloud%20Build-ready-blue?logo=google%20cloud\u0026logoColor=white)](https://github.com/HariSekhon/Spotify-tools/blob/master/cicd/cloudbuild.yaml)\n\n[![Repo on GitHub](https://img.shields.io/badge/repo-GitHub-2088FF?logo=github)](https://github.com/HariSekhon/Spotify-tools)\n[![Repo on GitLab](https://img.shields.io/badge/repo-GitLab-FCA121?logo=gitlab)](https://gitlab.com/HariSekhon/Spotify-tools)\n[![Repo on Azure DevOps](https://img.shields.io/badge/repo-Azure%20DevOps-0078D7?logo=azure%20devops)](https://dev.azure.com/harisekhon/GitHub/_git/Spotify-tools)\n[![Repo on BitBucket](https://img.shields.io/badge/repo-BitBucket-0052CC?logo=bitbucket)](https://bitbucket.org/HariSekhon/Spotify-tools)\n\n[![ShellCheck](https://github.com/HariSekhon/Spotify-tools/actions/workflows/shellcheck.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/shellcheck.yaml)\n[![JSON](https://github.com/HariSekhon/Spotify-tools/actions/workflows/json.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/json.yaml)\n[![YAML](https://github.com/HariSekhon/Spotify-tools/actions/workflows/yaml.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/yaml.yaml)\n[![XML](https://github.com/HariSekhon/Spotify-tools/actions/workflows/xml.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/xml.yaml)\n[![Markdown](https://github.com/HariSekhon/Spotify-tools/actions/workflows/markdown.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/markdown.yaml)\n[![Validation](https://github.com/HariSekhon/Spotify-tools/actions/workflows/validate.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/validate.yaml)\n[![Kics](https://github.com/HariSekhon/Spotify-tools/actions/workflows/kics.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/kics.yaml)\n[![Grype](https://github.com/HariSekhon/Spotify-tools/actions/workflows/grype.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/grype.yaml)\n[![Semgrep](https://github.com/HariSekhon/Spotify-tools/actions/workflows/semgrep.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/semgrep.yaml)\n[![Semgrep Cloud](https://github.com/HariSekhon/Spotify-tools/actions/workflows/semgrep-cloud.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/semgrep-cloud.yaml)\n[![Trivy](https://github.com/HariSekhon/Spotify-tools/actions/workflows/trivy.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/trivy.yaml)\n\n[![GitHub Actions Ubuntu](https://github.com/HariSekhon/Spotify-tools/workflows/GitHub%20Actions%20Ubuntu/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22GitHub+Actions+Ubuntu%22)\n[![Mac](https://github.com/HariSekhon/Spotify-tools/actions/workflows/mac.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/mac.yaml)\n[![Mac 11](https://github.com/HariSekhon/Spotify-tools/actions/workflows/mac_11.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/mac_11.yaml)\n[![Mac 12](https://github.com/HariSekhon/Spotify-tools/actions/workflows/mac_12.yaml/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions/workflows/mac_12.yaml)\n[![Ubuntu](https://github.com/HariSekhon/Spotify-tools/workflows/Ubuntu/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Ubuntu%22)\n[![Ubuntu 20.04](https://github.com/HariSekhon/Spotify-tools/workflows/Ubuntu%2020.04/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Ubuntu+20.04%22)\n[![Ubuntu 22.04](https://github.com/HariSekhon/Spotify-tools/workflows/Ubuntu%2022.04/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Ubuntu+22.04%22)\n[![Debian](https://github.com/HariSekhon/Spotify-tools/workflows/Debian/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Debian%22)\n[![Debian 10](https://github.com/HariSekhon/Spotify-tools/workflows/Debian%2010/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Debian+10%22)\n[![Debian 11](https://github.com/HariSekhon/Spotify-tools/workflows/Debian%2011/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Debian+11%22)\n[![Debian 12](https://github.com/HariSekhon/Spotify-tools/workflows/Debian%2012/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Debian+12%22)\n[![Fedora](https://github.com/HariSekhon/Spotify-tools/workflows/Fedora/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Fedora%22)\n[![Alpine](https://github.com/HariSekhon/Spotify-tools/workflows/Alpine/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Alpine%22)\n[![Alpine 3](https://github.com/HariSekhon/Spotify-tools/workflows/Alpine%203/badge.svg)](https://github.com/HariSekhon/Spotify-tools/actions?query=workflow%3A%22Alpine+3%22)\n\n[git.io/spotify](https://git.io/spotify)\n\nSpotify tools to make it easy to:\n\n- query and control Spotify\n- backup all your Spotify playlists\n- keep human-readable `Artist - Track` playlists (could migrate to another music system)\n\nMy epic [Spotify Playlists](https://github.com/HariSekhon/Spotify-Playlists) collection (recently open sourced) uses this heavily.\n\nHari Sekhon\n\nCloud \u0026 Big Data Architect, United Kingdom\n\n[![My LinkedIn](https://img.shields.io/badge/LinkedIn%20Profile-HariSekhon-blue?logo=data:image/svg%2bxml;base64,PHN2ZyByb2xlPSJpbWciIGZpbGw9IiNmZmZmZmYiIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+TGlua2VkSW48L3RpdGxlPjxwYXRoIGQ9Ik0yMC40NDcgMjAuNDUyaC0zLjU1NHYtNS41NjljMC0xLjMyOC0uMDI3LTMuMDM3LTEuODUyLTMuMDM3LTEuODUzIDAtMi4xMzYgMS40NDUtMi4xMzYgMi45Mzl2NS42NjdIOS4zNTFWOWgzLjQxNHYxLjU2MWguMDQ2Yy40NzctLjkgMS42MzctMS44NSAzLjM3LTEuODUgMy42MDEgMCA0LjI2NyAyLjM3IDQuMjY3IDUuNDU1djYuMjg2ek01LjMzNyA3LjQzM2MtMS4xNDQgMC0yLjA2My0uOTI2LTIuMDYzLTIuMDY1IDAtMS4xMzguOTItMi4wNjMgMi4wNjMtMi4wNjMgMS4xNCAwIDIuMDY0LjkyNSAyLjA2NCAyLjA2MyAwIDEuMTM5LS45MjUgMi4wNjUtMi4wNjQgMi4wNjV6bTEuNzgyIDEzLjAxOUgzLjU1NVY5aDMuNTY0djExLjQ1MnpNMjIuMjI1IDBIMS43NzFDLjc5MiAwIDAgLjc3NCAwIDEuNzI5djIwLjU0MkMwIDIzLjIyNy43OTIgMjQgMS43NzEgMjRoMjAuNDUxQzIzLjIgMjQgMjQgMjMuMjI3IDI0IDIyLjI3MVYxLjcyOUMyNCAuNzc0IDIzLjIgMCAyMi4yMjIgMGguMDAzeiIvPjwvc3ZnPgo=)](https://www.linkedin.com/in/HariSekhon/)\n[![Spotify Profile](https://img.shields.io/badge/Spotify%20Profile-HariSekhon-brightgreen?logo=spotify\u0026style=social)](https://open.spotify.com/user/harisekhon)\n\u003cbr\u003e*(you're welcome to connect with me on LinkedIn)*\n\n## Inventory\n\n- bash-tools/spotify/spotify_*.sh` - [Spotify](https://www.spotify.com/) API scripts\n  - list all public playlists for any given user, even followed playlists\n  - list all private playlists for the currently authorized user\n  - backup all playlists or a selection of playlists by partial name or ID\n  - download playlist contents as Spotify URIs / `Artists - Track` / CSV format\n  - convert Spotify track URIs to human readable `Artist - Track` / CSV format\n  - iterate any command against all playlists - command can be templated with `{playlist}` name or `{playlist_id}` which will be auto-populated on each iteration\n  - convert a playlist name to an ID, or an ID to a playlist name\n  - search for tracks / artists / albums and output in either human readable form or as Spotify URIs for fast loading into the Spotify app or automated chaining with other adjacent tools\n  - list liked / top tracks / artists in either human readable form or as Spotify URIs\n  - generate a Spotify API token (used by all other bash scripts)\n  - query any Spotify API endpoint with authentication (used by all other bash scripts)\n- `spotify-cmd.pl` - Spotify desktop app control from the command line on Mac via AppleScript calls. Useful for automation that Mac HotKeys don't help with such as auto-nexting tracks every N seconds if you want to skip through sampling a playlist\n\n## Quick Start\n\nIf you want to recover an entire deleted playlist, you can do that quickly in the Spotify web interface -\u003e Account -\u003e [Recover Playlists](https://www.spotify.com/uk/account/recover-playlists/) page.\n\nFor deleted songs in the desktop app, you can immediately press Control + Shift + Z on Windows or Control + Z on Mac to undo it.\n\nThis repo is for everything else - Backups, Conversions from HTTP URIs to readable `Artist - Track` format, tracking individual songs removed from playlists over time (if Spotify loses the rights to them they silently disappear and you won't notice if not Git revision controlling them like my repo [Spotify Playlists](https://github.com/harisekhon/spotify-playists) etc.\n\n### Ready to run Docker image\n\nThese programs and their pre-compiled dependencies can be found ready to run on [DockerHub](https://hub.docker.com/r/harisekhon/spotify-tools/).\n\nList all programs:\n\n```shell\ndocker run harisekhon/spotify-tools\n```\n\nRun any given program:\n\n```shell\ndocker run harisekhon/spotify-tools \u003cprogram\u003e \u003cargs\u003e\n```\n\n### Automated Build from source\n\n```shell\ngit clone https://github.com/HariSekhon/Spotify-tools\ncd spotify-tools\nmake\n```\n\nThis builds all dependencies after which the programs can be run.\n\nAlternatively see the [Manual Setup](https://github.com/HariSekhon/Spotify-tools#manual-setup) section instead.\n\n## Examples\n\n### Backup Spotify Playlists\n\nDownloads the list of public playlists to `playlists.txt` (names) and `spotify/playlists.txt` (IDs + names in TSV format)\n\nFor each playlist, downloads the list of playlist tracks to a file of the same name in both human and Spotify usable formats\n\nAs it progresses, it outputs the playlist name followed by the progress of the URI download then the human readable download\n\n`playlists/` files contain the human readable `Artist - Track` format\n\n`playlists/spotify/` files contain the Spotify URI format (for restores or copying to new playlists)\n\n```shell\n$ ./bash-tools/spotify/spotify_backup.sh\n================================================================================\n                         Running Spotify Playlists Backup\n================================================================================\n\n2020-07-05 01:23:41  Dumping list of Spotify playlists to spotify/playlists.txt\n\n2020-07-05 01:23:43  Stripping spotify playlist IDs from spotify/playlists.txt =\u003e playlists.txt\n\n2020-07-05 01:23:44  Backing up Spotify playlists to /Users/hari/github/spotify-tools/playlists\n\nMy Shazam Tracks =\u003e URIs OK =\u003e Tracks OK\nUpbeat \u0026 Sexual Pop =\u003e URIs OK =\u003e Tracks OK\nBest R\u0026B =\u003e URIs OK =\u003e Tracks OK\nBest Pop =\u003e URIs OK =\u003e Tracks OK\nBest Rock =\u003e URIs OK =\u003e Tracks OK\nBest Motown / Funk / Boogie / Groove / Soul =\u003e URIs OK =\u003e Tracks OK\nChill =\u003e URIs OK =\u003e Tracks OK\n2019 06-07 Venice \u0026 Budapest =\u003e URIs OK =\u003e Tracks OK\n2019 05 - Winchester =\u003e URIs OK =\u003e Tracks OK\n2019 04 April - Bath =\u003e URIs OK =\u003e Tracks OK\n2019 01 Jan - South Woodford =\u003e URIs OK =\u003e Tracks OK\n2018 10 Oct - Dec =\u003e URIs OK =\u003e Tracks OK\n2018 09 Sept - Dec =\u003e URIs OK =\u003e Tracks OK\n2018 09 Sept =\u003e URIs OK =\u003e Tracks OK\n2018 08 - Aug - Vienna =\u003e URIs OK =\u003e Tracks OK\n2018 Gemma =\u003e URIs OK =\u003e Tracks OK\n2018 03 March - July Mix =\u003e URIs OK =\u003e Tracks OK\n2018 03 Driving Rock =\u003e URIs OK =\u003e Tracks OK\n2018 02 Feb Mix - London =\u003e URIs OK =\u003e Tracks OK\n2018 Jan - London - A New Beginning =\u003e URIs OK =\u003e Tracks OK\n2017 12 December Mix - Back in London Baby =\u003e URIs OK =\u003e Tracks OK\n2017 11 November Mix - Copenhagen =\u003e URIs OK =\u003e Tracks OK\n2017 10 October Mix - Copenhagen =\u003e URIs OK =\u003e Tracks OK\n2017 09 September Mix - Copenhagen =\u003e URIs OK =\u003e Tracks OK\n2017 08 August Mix - London \u0026 Copenhagen =\u003e URIs OK =\u003e Tracks OK\n2017 07 July Mix - Johannesburg =\u003e URIs OK =\u003e Tracks OK\n2017 06 June Mix - Johannesburg =\u003e URIs OK =\u003e Tracks OK\n...\n2020-07-05 01:41:42  Spotify playlists backup finished in 1078 seconds\n```\n\n### Convert Spotify URIs to Human readable Artist - Track\n\nYou can copy and paste the tracks from the Spotify desktop app or web player directly into text files, which puts them in Spotify URI format such as:\n\n```none\nhttp://open.spotify.com/track/61oGXsKgJOI0e3uS2wg1BV\nhttp://open.spotify.com/track/1j6API7GnhE8MRRedK4bda\nhttp://open.spotify.com/track/0RxFoUhB3mAI3qpgLSf7eM\n```\n\nor\n\n```none\nspotify:track:61oGXsKgJOI0e3uS2wg1BV\nspotify:track:1j6API7GnhE8MRRedK4bda\nspotify:track:0RxFoUhB3mAI3qpgLSf7eM\n```\n\nThen convert this to readable `Artist - Track` form for saving independently of Spotify but running `spotify_uri_to_name.sh` against the file:\n\n```shell\n$ ./bash-tools/spotify/spotify_uri_to_name.sh Pendulum.txt\nPendulum - Watercolour\nPendulum - Witchcraft\nPendulum - The Island - Pt. I\n...\n```\n\nYou can also pipe one or more Spotify URIs through standard input in either format that Spotify uses:\n\n```shell\n$ echo http://open.spotify.com/track/5TOYgNohZAFEPOtnchPhZS | ./bash-tools/spotify/spotify_uri_to_name.sh\nFoo Fighters - Arlandria\n\necho spotify:track:5TOYgNohZAFEPOtnchPhZS | ./bash-tools/spotify/spotify_uri_to_name.sh\nFoo Fighters - Arlandria\n```\n\n### Set all the tracks from your favourite playlist to \"Liked\"\n\nGive the playlist file full of Spotify URIs (dumped by the spotify_backup*.sh scripts above), you can mark all the songs from your favourite playlists as `Liked Songs` which then appear in your `Liked Songs` playlist too:\n\n```shell\nspotify_set_tracks_uri_to_liked.sh playlists/spotify/My_Favourite_Playlist\n```\n\nIf you've been using Spotify a long time, you'll remember that marked songs used to be called `Starred`, but were replaced by `Liked Songs`. Unfortunately Spotify made `Starred` a regular playlist and didn't carry them over, but you can easily mark all previously `Starred` songs as the newer `Liked Songs`:\n\n```shell\nspotify_set_tracks_uri_to_liked.sh playlists/spotify/Starred\n```\n\n### Spotify Cmd --help\n\n```shell\n$ ./spotify-cmd.pl --help\n\nCommand line interface to Spotify on Mac that leverages AppleScript\n\nUseful for automation that Mac HotKeys don't help with, such as auto skipping\nto next track every N secs to sample a playlist while working\n\nusage: spotify-cmd.pl \u003ccommand\u003e\n\ncommands:\n\nplay            Play\npause / stop    Pause\nplaypause       Toggle Play/Pause\nprevious        Previous Track and print previous track information\nnext [secs]     Next Track and print next track information.\n                Specifying optional secs will skip to next track\n                every [secs] seconds. Handy for skipping through a playlist\n                every 60 secs automatically and grabbing the good songs. Prints\n                track information every time it skips to the next track\n\nstatus          Show current track details\n\nvol up          Turn volume up\nvol down        Turn volume down\nvol \u003c1-100\u003e     Set volume to number \u003c1-100\u003e\n\nexit / quit     Exit Spotify\n\n-q  --quiet      Quiet mode. Do not print track information or volume after\n                 completing action\n-t  --timeout    Timeout in secs (default: 10)\n-v  --verbose    Verbose mode (-v, -vv, -vvv ...)\n-h  --help       Print description and usage options\n-V  --version    Print version and exit\n```\n\n### Manual Setup\n\nEnter the directory and run git submodule init and git submodule update to fetch my library repo:\n\n```shell\ngit clone https://github.com/HariSekhon/Spotify-tools\ncd spotify-tools\ngit submodule init\ngit submodule update\n```\n\nThen you will also need to fetch the following CPAN modules listed in `setup/cpan-requirements.txt` and `lib/setup/cpan-requirements.txt`:\n\nRunning the cpan command followed by the list of modules (as root) will fetch them for you, or you can use this script:\n\n```shell\nbash-tools/perl/perl_cpanm_install.sh setup/cpan-requirements.txt lib/setup/cpan-requirements.txt\n```\n\n### Contributions\n\nPatches, improvements and even general feedback are welcome in the form of GitHub pull requests and issue tickets.\n\n### Updating\n\nRun:\n\n```shell\nmake update\n```\n\nThis will git pull and then git submodule update which is necessary to pick up corresponding library updates.\nndencies.\n\nIf you update often and want to just quickly git pull + submodule update but skip rebuilding all those dependencies each\ntime then run `make update-no-recompile` (will miss new library dependencies - do full `make update` if you encounter\nissues).\n\n[git.io/spotify](https://git.io/spotify)\n\n## More Core Repos\n\n\u003c!-- OTHER_REPOS_START --\u003e\n\n### Knowledge\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Knowledge-Base\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Knowledge-Base)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Diagrams-as-Code\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Diagrams-as-Code)\n\n\u003c!--\n\nNot support on GitHub Markdown:\n\n\u003ciframe src=\"https://raw.githubusercontent.com/HariSekhon/HariSekhon/main/knowledge.md\" width=\"100%\" height=\"500px\"\u003e\u003c/iframe\u003e\n\nDoes nothing:\n\n\u003cembed src=\"https://raw.githubusercontent.com/HariSekhon/HariSekhon/main/knowledge.md\" width=\"100%\" height=\"500px\" /\u003e\n\n--\u003e\n\n### DevOps Code\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=DevOps-Bash-tools\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/DevOps-Bash-tools)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=DevOps-Python-tools\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/DevOps-Python-tools)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=DevOps-Perl-tools\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/DevOps-Perl-tools)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=DevOps-Golang-tools\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/DevOps-Golang-tools)\n\n\u003c!--\n[![Gist Card](https://github-readme-stats.vercel.app/api/gist?id=f8f551332440f1ca8897ff010e363e03)](https://gist.github.com/HariSekhon/f8f551332440f1ca8897ff010e363e03)\n--\u003e\n\n### Containerization\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Kubernetes-configs\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Kubernetes-configs)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Dockerfiles\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Dockerfiles)\n\n### CI/CD\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=GitHub-Actions\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/GitHub-Actions)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Jenkins\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Jenkins)\n\n### DBA - SQL\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=SQL-scripts\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/SQL-scripts)\n\n### DevOps Reloaded\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Nagios-Plugins\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Nagios-Plugins)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=HAProxy-configs\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/HAProxy-configs)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Terraform\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Terraform)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Packer-templates\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Packer-templates)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Nagios-Plugin-Kafka\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Nagios-Plugin-Kafka)\n\n### Templates\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Templates\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Templates)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Template-repo\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Template-repo)\n\n### Misc\n\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Spotify-tools\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Spotify-tools)\n[![Readme Card](https://github-readme-stats.vercel.app/api/pin/?username=HariSekhon\u0026repo=Spotify-playlists\u0026theme=ambient_gradient\u0026description_lines_count=3)](https://github.com/HariSekhon/Spotify-playlists)\n\nThe rest of my original source repos are\n[here](https://github.com/HariSekhon?tab=repositories\u0026q=\u0026type=source\u0026language=\u0026sort=stargazers).\n\nPre-built Docker images are available on my [DockerHub](https://hub.docker.com/u/harisekhon/).\n\n\u003c!-- 1x1 pixel counter to record hits --\u003e\n![](https://hit.yhype.me/github/profile?user_id=2211051)\n\n\u003c!-- OTHER_REPOS_END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharisekhon%2Fspotify-tools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharisekhon%2Fspotify-tools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharisekhon%2Fspotify-tools/lists"}