Scotty
Scotty transfers your listens/scrobbles and favorite tracks between various music listen tracking and streaming services.
Note: This project is currently work in progress. While the basics are working there are many loose ends and there is no documentation except for this file yet. Use at your own risk.
Example use cases
- Submit listens from ListenBrainz to Maloja or Last.fm
- Transfer loved tracks from Funkwhale to ListenBrainz
- Submit listens stored in a Rockbox
.scrobbler.log
file to ListenBrainz, Last.fm or Maloja
- Submit listens from Spotify extended history files to ListenBrainz, Last.fm or Maloja
- Store your favorite tracks from Deezer as a JSPF playlist
- Backup your listening history from ListenBrainz or Last.fm
Installation
Scotty is a command line utility written in Go. Binary packages for various
operating systems are available on the release page.
You can also install Scotty from source with the following command:
go install go.uploadedlobster.com/scotty@latest
This requires go
to be installed on your system. You can get it from https://go.dev/dl/ .
Configuration
To use Scotty you need to configure at least two services (e.g. ListenBrainz, Last.fm, Funkwhale or Spotify).
By default Scotty stores the configuration in a platform dependent configuration directory (e.g. on Unix like system this is $HOME/.config/scotty/scotty.toml
), but you can also run it with a different configuration file using the --config
command line parameter.
New services can be configured interactively using the service add
, service edit
and service delete
commands. Run scotty service --help
for tails.
The configuration file in TOML format can also be edited manually. For a full example see config.example.toml.
Usage
Run scotty --help
for general command line help.
Tutorial
As a full example consider that you want to transfer your listen history and loved tracks from Deezer to ListenBrainz. You first need to configure these services. Let's start with adding ListenBrainz. Run scotty service add
. Scotty will allow you to interactively configure the service. First you need to select "listenbrainz" as the backend:
$ scotty service add
Use the arrow keys to navigate: ↓ ↑ → ←
? Backend:
deezer
dump
funkwhale
jspf
lastfm
▸ listenbrainz
maloja
scrobbler-log
spotify
subsonic
Next Scotty will ask how to name this service. You can accept the suggested name "listenbrainz". Naming services differently can be useful when you configure multiple services with the same backend (e.g. multiple separate accounts).
✔ listenbrainz
✔ Service name: listenbrainz█
Next you need to provide your ListenBrainz user name and user token:
✔ listenbrainz
✔ Service name: listenbrainz
✔ User name: outsidecontext
✔ Access token: *************************************
Saved service listenbrainz using backend listenbrainz
Hint: If you made a mistake and want to change a value, run scotty service edit
to change the configuration of existing services.
For Deezer we need access to the Deezer API. You need a Deezer account for which you have to register an application in the Deezer developer portal. Give this application any name (e.g. Scotty) and use http://127.0.0.1:2369/callback/deezer
as the "Redirect URL after authentication". After creating the application note the "Application ID" and "Secret Key".
Now you can add a new service by running scotty service add
again. Choose the "deezer" backend and set a name (let's use the default "deezer") as well as the Application ID and Secret Key you obtained before.
Before you can use Deezer you need to authorize Scotty to access your account. For this run scotty service auth --service deezer
. If your Application ID and Secret Key were correct your browser should open with Deezer's login and authorization page. Confirm the access. On success the browser will show "Token received, you can close this window now.". Close the browser window and return to your terminal.
Running scotty service list
should now show the two services "deezer" and "listenbrainz".
Now you can use these services to transfer data between them. To transfer the loved tracks from Deezer to ListenBrainz run:
scotty beam loves deezer listenbrainz
The output will look something like this:
Transferring loves from deezer to listenbrainz...
From timestamp: 1970-01-01 01:00:01 +0100 CET (1)
✓ exporting [=======================================================] done
✓ importing [=======================================================] done
Imported 4 of 4 loves into listenbrainz.
Latest timestamp: 2023-11-23 14:44:46 +0100 CET (1700747086)
Scotty will remember the latest timestamp for which it transferred data between the two services. The next time you run scotty beam loves deezer listenbrainz
it will only consider tracks loved after the previous import. If you for some reason want to override this and start importing at an earlier time again, you can specify an earlier start time with the --timestamp
parameter, which can be either a Unix timestamp (seconds since 1970-01-01 00:00:00) or a date time string like "2023-12-10 16:12:00".
For example to import listens starting at a specific timestamp use:
scotty beam listens deezer listenbrainz --timestamp "2023-12-06 14:26:24"
Supported backends
The following table lists the available backends and the currently supported features.
Backend |
Listens Export |
Listens Import |
Loves Export |
Loves Import |
deezer |
✓ |
⨯ |
✓ |
- |
funkwhale |
✓ |
⨯ |
✓ |
- |
jspf |
- |
✓ |
- |
✓ |
lastfm |
✓ |
✓ |
✓ |
✓ |
listenbrainz |
✓ |
✓ |
✓ |
✓ |
maloja |
✓ |
✓ |
⨯ |
⨯ |
scrobbler-log |
✓ |
✓ |
⨯ |
⨯ |
spotify |
✓ |
⨯ |
✓ |
- |
spotify-history |
✓ |
⨯ |
⨯ |
⨯ |
subsonic |
⨯ |
⨯ |
✓ |
- |
✓ implemented - not yet implemented ⨯ unavailable / not planned
See the comments in config.example.toml for a description of each backend's available configuration options.
Contribute
The source code for Scotty is available on SourceHut. To report issues or feature requests please create a ticket.
Patches can be submitted to the mailing list ~phw/musicbrainz@lists.sr.ht. You can clone the repository directly on SourceHut and submit your changes with the "Prepare patchset" button. Please see SourceHut's documentation for sending patches upstream for details.
You can help translate this project into your language with Weblate. Please request new languages on the mailing list ~phw/musicbrainz@lists.sr.ht. See internal/translations/README.md for details.
License
Scotty © 2023-2024 Philipp Wolfer phw@uploadedlobster.com
Scotty is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
Scotty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Scotty. If not, see https://www.gnu.org/licenses/.
See COPYING for details.
Some source files in Scotty are licensed under the MIT license. Please see the license notice in the headers of the individual files for more information.
All user interface strings and their translations are published under the conditions of CC0 1.0 Universal (CC0 1.0).