Skip to content

benrbray/borscht-hs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

borscht-hs

Borscht is in development! Many of the features below have been implemented in some form, but have not yet been glued together into a cohesive experience. Borscht is my way of practicing Haskell, so it's a Frankenstein's monster of different packages and coding styles.

borscht is a command line tool for organizing your personal music library.

  • Search for missing music metadata from the Discogs and MusicBrainz databases.
  • (in progress) Write custom Datalog inference rules to automatically tag and re-tag your music, and create playlists from saved Datalog queries.

borscht takes inspiration from beets, with a few key differences:

  • borscht works natively with both MusicBrainz and Discogs, whereas the Discogs plugin for beets is has been somewhat neglected
  • beets assumes your music is organized into albums, while borscht is happy to work with individual songs
  • borscht has a powerful tagging system based on datalog
  • borscht helps you assign an acceptable set of metadata to digital music files, but is not too concerned with preserving the correspondence between your digial and physical libraries
  • borscht is optimized for my personal use case, and doesn't have all the same bells and whistles as beets

About

I created borscht not only to create a music database that suits my use case, but also to practice writing non-trivial applications with Haskell. Before this project, my experience was mostly small single-file experiments compiled directly with ghc. Since the goal of this project was to learn as much as possible about "getting stuff done" in Haskell, the code is a bit of a mishmash of different styles, abstractions, and language extensions. During this project, I gained experience with the following topics:

  • I learned how to use cabal to manage project dependencies
  • I use req to make HTTP requests, including API authentication
  • I use aeson to parse JSON responses from the Discogs and MusicBrainz APIs
  • (in progress) I use persistent to manage a sqlite database for music libraries created with borscht
  • I use mtl to manage a monad transformer stack
  • I wrote a monadic parser combinator for Datalog inference rules R(X,Y) :- P(X,Z), P(Z,Y).
  • (in progress) I implemented semi-naive evaluation with stratified negation for Datalog, which powers the music tagging system.
  • I wrote a foreign function interface wrapper for the Kakasi C library, which transliterates Japanese kanji to romaji.
  • I merged a pull request into the Byline package adding support for vivid ANSI terminal colors, and a second one to repair an unlawful semigroup instance.

Here's a list of some tangential topics that I read about while working on borscht. These are all really interesting to me and I hope to work with them directly on future projects.

  • I learned about stm concurrency in Haskell by reading Peyton-Jones 2007, "Beautiful Concurrency", and inspecting the source code for the rate-limit package, which borscht uses to respect the rate limit intervals for API requests to the Discogs and MusicBrainz databases
  • While reading about Datalog, I learned about the datafun, flix projects, which extend Datalog with cool features like incrementalization, function abstraction, and lattices. I hope to add some of these features to my own datalog implementation! There's also the incremental differential-dataflow project.

FAQ

Why the name? Borscht is a type of soup made from beets!

What music do you listen to? Check out Tinariwen, Dakh Daughters, and Shaolin Afronauts.

Development

Dependency: text-icu

sudo apt install libicu-dev

Dependency: taglib

Borscht uses htaglib, which requires that we install TagLib separately. There's not much documentation, but the following worked for me on Ubuntu 20.04.

sudo apt install libtagc0-dev

Dependency: kakasi

The ICU library cannot transliterate Japanese kanji characters. Instead, Borscht relies on kakasi, which is not commonly avilable in package managers. First, download the kakasi source, then

$ ./config
$ make
$ make install

After installing, the necessary header and static library files should be found in /usr/local. For a local install, use ./config --prefix=$(pwd)/build before running make.

./usr/local/include/libkakasi.h
./usr/local/lib/libkakasi.a

Cabal statically links the kakasi library from these locations.

About

A music database curator written in Haskell.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published