common library
Shared functionality & definitions for use across different parts of kans.
Background Overview
How Kans Works
Kans is supposed to be a general purpose music downloader. Eventually the aim is to make it a fully functional music manager as well. It is based on spotify-downloader (python 3) an application I worked on earlier. The overall process flow is the same as before:
- Get Song details from your music source (Spotify, YouTube, etc) →
- Find the closest match from a downloadable source (YouTube, SoundCloud, etc) →
- Download the song from the source at highest quality available →
- Change the file format and container if required (e.g. from MP3 to OGG) →
- Add metadata to the file (ID3 tags, album art, etc)
Design Rationale
Easy Extensibility of Sources
Since the aim is to have general extensibility i.e. the ability to simply add new sources to search for music as well as to download it, things like song results, download sources, song sources have to be standardized for easy interchange of song source and download source.
This is why components (Song Results, Search Sources, Download Sources, Downloader(s)) are standardized as interfaces. This means that contributors can implement their own sources/downloader(s) without having to dig too deep into the codebase.
Enums / Uniquely identifying Sources
Each Source also has to be uniquely identifiable, one way to do this would be to use Strings
but that seems to be a far too messy solution that depends on perfectly accurate typing on the
part of the coder. That would also be a pain to refactor/change later on. So, we use
Enums instead. This has the additional benefit of being far more performant as all enums
are
compile time constants.
Nesting & Data Structure
A lot of this library is just about standardizing data exchange. One way to do this would be to
have a Song
class that contains song details, linked to an Album
class for album details,
and an Artist
class for artist details. However, this would lead to a lot of nesting and
changes to the either the Album
or Artist
class would potentially require lots of
refactoring.
To avoid this, all data is keep under a single Result
(ResultInterface
) class.
Still, keeping track of disparate details like a tracks title, duration, tack number, etc. and
internally organizing them mentally is not easy. To this end, we nest the data via naming
convention. All fields start with either "track", "album", or "artist" to allow easier mental
categorization of the data.
Naming Conventions
- All fields/methods start with either "track", "album", or "artist".
Classes
- DetailsInterface
- Basic interface for music results from any source.