They don't exist yet, but I was trying to decide in my head if there was a meaningful difference between emrging two songs, and a SongGroup, and I decided they are indeed different, but really only in a small way
177 lines
8.2 KiB
Markdown
177 lines
8.2 KiB
Markdown
# Zuletzt
|
|
**Zuletzt** gives you the statistics of your music listening habits.
|
|
|
|
Inspired by [Last.fm](https://last.fm),
|
|
[Maloja](https://github.com/krateng/maloja), and
|
|
[Lastfmstats.com](https://www.lastfmstats.com).
|
|
|
|
**Z**uletzt is written with [**Z**ig](https://github.com/ziglang/zig) and
|
|
[Jetzig](https://github.com/jetzig-framework/jetzig) as a means of learning the
|
|
language, reintroducing myself to programming, and combining the functionality
|
|
of the aforementioned inspirations.
|
|
|
|
Zuletzt means "last" in German.
|
|
|
|
Licensed under MIT.
|
|
|
|
## Usage
|
|
Zuletzt allows uploads of Scrobbles at the `/upload` page, where you
|
|
can import Scrobbles from a Spotify data export, Last.FM data export (a `.json`
|
|
file from lastfmstats.com), or by providing a Last.FM username and connecting
|
|
to Last.FM directly.
|
|
|
|
Zuletzt will not make any assumptions about the data, and only change metadata
|
|
when asked to by a rule. Two albums will be considered the same if:
|
|
- They share the same title (case/diacritic sensitive)
|
|
- The album artist(s) are the same
|
|
|
|
Zuletzt allows you to list multiple artists under an album using rules, but
|
|
does not try to automatically split artists along common delimiters. For
|
|
example, there's no way to know that "Mermaid Avenue" by "Billy Bragg, Wilco"
|
|
is performed by two artists, while "Ants From Up There" by "Black Country, New
|
|
Road" is performed by one artist. Thus, a rule needs to be made to tell Zuletzt
|
|
"Mermaid Avenue" is performed by "Billy Bragg" and "Wilco".
|
|
|
|
Two songs will only be considered the same if:
|
|
- They share the same title (case/diacritic sensitive)
|
|
- They appear on the same album
|
|
|
|
If two or more songs with the same spelling appear on an album, they are
|
|
necessarily grouped under the same name, as there is no way to differentiate
|
|
them (see "Once In Royal David's City" on Sufjan Stevens's "Songs For
|
|
Christmas", for example). Every artist that performs on those songs with
|
|
receive attribution for the combined song.
|
|
|
|
If two artists have the same name, they are necessarily listed as the same
|
|
artist, but can be separated with a rule, or after the fact, with a
|
|
disambiguation string.
|
|
|
|
## Quirks
|
|
Zuletzt does not assume any two songs are the same song unless they
|
|
share the exact same metadata. However, there are plenty of situations where a
|
|
song might appear on more than one album (consider a greatest hits album).
|
|
Thus, a song which was played on one album 30 times, and also played on a
|
|
different album 20 times, would not receive the credit of being played a total
|
|
of 50 times. To resolve this, Zuletzt lets the user specify that these two
|
|
songs are the same. This is, however, different from SongGroups. SongGroups,
|
|
while superficially providing very similar functionality, does not permanently
|
|
combine the statistics of the two songs, but will show their combined
|
|
statistics anyways. This is useful if, for example, one song is a remix of
|
|
another - they are, in reality, different songs, but there is a clear
|
|
connection between them, and it may be interesting to see what their combined
|
|
statistics are. The decision to merge songs or make a SongGroup, or neither, is
|
|
left to the user, but the general thought is:
|
|
- If they're the *exact* same song, merge them, and the data becomes more
|
|
accurate for that song
|
|
- If one is somehow remixed/covered/altered in some way, make a SongGroup, and
|
|
see the combined info *as if* you had merged them.
|
|
|
|
## To-Do List:
|
|
- [ ] Entity statistics
|
|
- [x] See all artists under "/artists"
|
|
- [ ] List all songs on artist page, with respective album
|
|
- [x] List all albums on artist page
|
|
- [x] Include number of plays for each
|
|
- [x] List albums features on
|
|
- [x] See all albums under "/albums"
|
|
- [x] See all songs from album
|
|
- [x] Include number of plays
|
|
- [x] Include name of artist(s)
|
|
- [ ] Include artists features on each song
|
|
- [x] See all songs under "/songs"
|
|
- [x] Include respective artist(s)
|
|
- [ ] Include respective album[^10]
|
|
- [x] Include number of plays
|
|
- [ ] Create disambiguation pages
|
|
- [ ] Artists
|
|
- [ ] Albums
|
|
- [ ] Songs
|
|
- [ ] Toggleable default sorting method
|
|
- [ ] Default to sorting by plays
|
|
- [ ] Filter by dates
|
|
- [ ] Highlight specific high-performing entities
|
|
- [ ] Lastfmstats.com statistics[^1]
|
|
- [ ] Collections
|
|
- [ ] Import from Discogs[^2]
|
|
- [ ] Import listening history
|
|
- [x] From Lastfmstats.com (.json file)[^3]
|
|
- [x] From Last.fm (authentication)
|
|
- [x] From Spotify (.json file)
|
|
- [ ] From other streaming services[^4]
|
|
- [ ] "Unofficial scrobbles"[^9]
|
|
- [ ] Import rules
|
|
- [ ] Simple find/replace
|
|
- [ ] User-defined regex
|
|
- [ ] Tags
|
|
- [ ] Genres
|
|
- [ ] Owned
|
|
- [ ] Holiday
|
|
- [ ] [MusicBrainz
|
|
integration](https://musicbrainz.org/doc/libmusicbrainz)[^11]
|
|
- [ ] Concerts
|
|
- [ ] Import from Setlist.fm[^5]
|
|
- [ ] Ratings
|
|
- [ ] RYM integration[^6]
|
|
- [ ] Rank songs
|
|
- [ ] Custom statistics[^7]
|
|
- [ ] "Playlists"[^8]
|
|
- [ ] First launch setup
|
|
|
|
[^1]: I do not intend to exactly replicate all the statistics Lastfmstats.com
|
|
provides, but I would at least like to give the user the option to see those
|
|
kinds of statistics, or generate them themselves (see 7).
|
|
|
|
[^2]: I do not intend to provide the level of granularity that Discogs
|
|
provides, but a simple toggle that means "I own some version of this release"
|
|
is all that is necessary.
|
|
|
|
[^3]: I have not investigated any other service for downloading your listening
|
|
history from Last.fm, but providing the listening history as a JSON rather than
|
|
a CSV is highly preferred. I may eventually provide my own way of downloading
|
|
Last.fm data as a JSON, but I would prefer to allow users to enter their
|
|
username, or authenticate, and avoid needing to upload a file altogether.
|
|
|
|
[^4]: I only intend to allow imports from Last.fm and Spotify at the moment
|
|
because those are the only data sources I currently rely on. To that extent, I
|
|
imagine I could import from other sources as well fairly easily, although I do
|
|
not know what their data dumps look like.
|
|
|
|
[^5]: I only intend to allow imports from Setlist.fm at the moment because that
|
|
is the only data source I currently rely on.
|
|
|
|
[^6]: RYM has the most data, and once it has an API, will be the only
|
|
user-driven review site that *has* an API. In this context, "integration"
|
|
simply means displaying the critic score and user score next to the album. You
|
|
will be able to write reviews and ranks songs/albums(/artists?), but not for
|
|
them to be published to RYM.
|
|
|
|
[^7]: I envision something akin to the Custom Reports from [Actual
|
|
Budget](https://github.com/actualbudget/actual) that will allow users to create
|
|
their own ways of rating/ranking songs/albums, and view their listening habits.
|
|
|
|
[^8]: Misleading title, but same functionality as "Lists" on AlbumOfTheYear,
|
|
although I would like to allow albums and songs to appear on the same list.
|
|
|
|
[^9]: This is a working title, but I have sources (iPods) that provide a play
|
|
count, but no play dates, so I can't list them among my usual Scrobbles.
|
|
However, I would still like to display that information along with everything
|
|
else, so I would like to provide a way of entering this data into a separate
|
|
category that can be toggled to display alongside "official" Scrobbles.
|
|
|
|
[^10]: Would probably select the album with the most scrobbles
|
|
|
|
[^11]: I probably don't understand it well enough, but it appears that I should
|
|
be able to do this using `@cImport` and/or `translate-c` on the original
|
|
MusicBrainz source, but it's not all clear to me on how that would work yet.
|
|
This is a necessary step for what I have planned however, so we'll see where it
|
|
goes. **Update 3/25/25:** A Zig implementation for what Zuletzt requires (and
|
|
*only* what Zuletzt requires) has been (mostly) written.
|
|
|
|
## Contributing
|
|
I am a math student who is interested in programming. I will
|
|
not be writing quality code. That said, Zuletzt is something that, at the
|
|
moment, I am very excited about making, and using to relearn some things about
|
|
programming. Unless contributions are given in the form of code review, or some
|
|
kind of constructive criticism, it's not likely that I accept pull requests.
|
|
The project is, however, licensed under the MIT License, so feel free to do
|
|
what you like with it in your own way.
|