Skip to content

Tags: a-rich/DJ-Tools

Tags

v2.8.1

Toggle v2.8.1's commit message
chore: can't push 2.8.0 because that name is already in PyPI

v2.7.14

Toggle v2.7.14's commit message
Release: b8a7948

v2.7.13

Toggle v2.7.13's commit message
Release: 13abe47

v.2.7.12

Toggle v.2.7.12's commit message
Release: fbeb7bf

v.2.7.11

Toggle v.2.7.11's commit message
Release: ea2f932

v2.7.2

Toggle v2.7.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Releases/2.7.2 (#190)

docs: add developer docs, playlist_filters module
refactor: cleanup the exported members
refactor: show full BaseConfig if not on the CLI execution path
script: rename files
build: update to pyproject.toml

---------

Co-authored-by: github-actions <[email protected]>

v2.7.0

Toggle v2.7.0's commit message
Release 2.7.0: 09d1c61

v2.6.0

Toggle v2.6.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Releases/2.6.0 (#119)

feat(scripts): analyze Rekordbox My Tags by user (#102)

Why?
It's cool to see the distribution of tags by users of my Beatcloud.

What?
Group tracks in an XML by the part of the `Location` path that
corresponds with username, search the `Comments` field for the regex
matching `My Tags` data, counting the frequency of each tag, and then
plot histograms per user.

feat(scripts): move "My Tags" data around

Why?
Users would like the ability to do bulk edits to their "My Tags" data.

What?
An r/rekordbox user asked for a way to move "My Tag" data that encodes genre info into the `Genre` field.

I wanted to be able to sort my `Comments` field to sort by energy level, so I added the ability to move particular tags to the front of the `Comments` field.

feat(rekordbox): deprecate registered_users.yaml

Why?
Users shouldn't have to maintain a list of registered users. The whole
point of this file is to facilitate `Location` field manipulations as
part of `rewrite_xml` but, since the `Location` field has a hardcoded
substring of "DJ Music", we can infer all users' `USB_PATH`.

What?
Remove the usage of `registered_users.yaml`.

feat(sync): parameterize track title/artist order (#105)

Why?
Some users may already have a collection stored in the `ARTIST_FIRST`
format. These users should still be able to use the `--check-tracks` and
`--playlist-from-upload` features without having to rename all their
files.

What?
Adds the `sync` package configuration option, `ARTIST_FIRST`, which has
Spotify API calls return tracks as `artist - track` instead of
`track - artist`. Additionally, when using with
`CHECK_TRACKS_LOCAL_DIRS`, Beatcloud tracks will have their filenames
temporarily reversed to be the opposite of however they're stored as in
order to facilitate `ARTIST_FIRST` comparison.

feat(version): add single source package version

Why?
A `__version__` variable and `--version` option should be available.

What?
Add a `version.py` module containing a `__version__` variable which is:
  - used to setup the package
  - exported from the `__init__` module
  - printed with the `--version` option

refactor(configs): improve config print upon execution

Why?
Interpreting the config in the console is difficult.

What?
Override the `__repr__` method of `BaseConfig` to print only the
attributes of the sub-class. Format the representation with new lines
and indentations to improve readability.

feat(playlist_builder): Minimal Deep Tech logic (#107)

Why?
The genre "Minimal Deep Tech" straddles "House" and "Techno". Users
should be able to control which tracks appear in that genre playlist
depending on some conditions.

What?
A prefix genre tag of "Techno" followed by "Minimal Deep Tech" controls
which tracks belong in playlists called "Minimal Deep Tech" with a parent
playlist called "Techno".

feat(playlist_builder): automatic pure playlists

Why?
Users should not have to configure the playlist builder to apply "pure"
playlist logic.

What?
Automatically find playlists prefixed with "Pure " and feed those
suffixes into the TagParser.

feat(playlist_builder): print ASCII histograms of tag statistics (#109)

Why?
To quickly iterate on the proper Combiner playlist expressions, it would
be helpful if the CLI immediately output useful information to help
guide users in the right direction.

What?
Print simple ASCII tables for each TagParser implementation for each
playlist in the set of Combiner playlists generated in the run. Tables
show the frequency of each tag's apperance in each playlist. Tag
frequencies are scaled to a maximum value to constrain table heights.

TODO: Investigate vertical X-axis labels to constrain histogram width.
Investigate splitting histograms into chunks when there is a large
number of X-axis labels.

feat(collections): create collection abstractions

Why?
The `rekordbox` package offers many modules that are only useful to
Rekordbox users because they make assumptions about the structure of
collections, playlists, and tracks. Abstractions should be created for
these structures so that implementations can be made for different DJ
software platforms. This decouples the database (de)serialization logic
from the modules like the `PlaylistBuilder`.

What?
Rename the `rekordbox` package to `collection`. Create abstract classes
for Collection, Playlist, and Track. Implement these abstractions for the
Rekordbox use-case. Replace all Rekordbox-specific implementation
details in the `collection` package with the methods defined on the
abstractions. Add a configuration option for DJ software.

Renamed a bunch of the CLI args.

fix: More elegant music sync (#116)

Why?
The carriage return prints made by `awscli` which contain information
about the amount of data and number of files transferred was getting
lost due to the use of `readline()` which splits on "\n" characters.

What?
Read stdout one character at a time so the carriage return data can be
displayed.

Also remove the usage of `shell=True` from all `Popen` calls.

refactor: CLI sub-commands (#117)

Why?
The `--help` menu is verbose and hard to read.

What?
Break down all the CLI args into sub-commands based on the package they
pertain to.

refactor: Filter list args and parse JSON args

Why?
Previously, the `--spotify-playlist-subreddits` arg would accept YAML
strings and parse them into dictionaries. Formatting an arg as YAML is
annoying since whitespace matters. JSON is much easier to use.

Overriding list type args that have a default value was not possible
without editing the config that defines that default value.

What?
Revert `parse_yaml` back to `parse_json` for the
`--spotify-playlists-subreddits` argument.

Iterate parsed args and apply a `list(filter(None, ...` expression to
values that are an instance of `list`.

v2.5.0

Toggle v2.5.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Releases/2.4.1 (#101)

* [FIX] Delay playlist selector lookup creation (#86)

Why?
Combiner playlists that include playlist selectors previously did not include tracks that were added to those playlists in the same run.

What?
Delay the creation of the playlist selector tag -> track lookup until after any other TagParser implementations have been run.

In addition, this MR inserts all auto-playlists into a folder called AUTO_PLAYLISTS so as to make it simpler to bulk import these playlists.

* [FIX] Catch async.exceptions.TimeoutErrors (#89)

Why?
The underlying `aiohttp` calls for the `spotify.playlist_builder` module
occasionally timeout. These `TimeoutError` exceptions need to be caught
so that potentially successful Reddit submissions retrievals can occur.

What?
Wrap the `asyncpraw` method that returns an AsyncGenerator with another
generator which applies try / except logic that differentiates between
`StopAsyncIteration` exceptions and other exceptions.

* Optimize Pytest suite (#91)

Why?
Testing time should be minimized.

What?
Factor out `rekordbox.xml` loading into a session scoped fixture. Use
`tmpdir_factory` to create a temporary directory which may be session scoped;
use this temporary directory, in combination with the factored out
`rekordbox.xml` loading fixture, in the `test_xml` fixture. Mock `os.system`
calls in `test_upload_log` and `test_download_xml`. Minimize the amount of
content in `rekordbox.xml` so as to speed up reading and writing that file.

* [ENHANCEMENT] Replace os.path with pathlib.Path (#93)

Why?
When looking at code using os.path operations, developers have to
evaluate expressions the same way as the Python interpreter
(inside -> out). By comparison, pathlib.Path uses method chaining which
is much more intuitive. In addition, pathlib.Path accounts for the
eccentricities of Windows paths under the hood; this means all the
ridiculous `.replace(os.sep, "/")` calls can be removed.

What?
Replace all uses, where appropriate, of `os.path` with `pathlib.Path`.

* [ENHANCEMENT] Collapse djtools directory (#97)

Why?
test_data was in the src directory creating an unnecessary level
between the root and the library source.

What?
Move test_data to the project root, collapse src/djtools into
djtools.

* [ENHANCEMENT] Better logging for check-tracks (#98)

Why?
The `--check-tracks` feature logs too verbosely and also omits info that
would be nice to have such as the count of local files. There's also an
uncaught error when trying to zip emtpy lists of tracks.

What?
Simplify logging and include local file counts. Skip comparison loop if
there aren't any tracks.

* [ENHANCEMENT] Diataxis docs

Why?
There are no docs!

What?
Create docs. Use the Diataxis framework to organize the docs and use
`mkdocs` and `mkdocstring` to generate the docs. Host the docs on GitHub
Pages. Added a `.pylintrc` and linted the entire repo's `.py` files.

A few functions were renamed for clarity.
* `randomize_playlists` is not `shuffle_playlists`
* `set_tag` is now `set_track_number`
* `rekordbox_playlists` is now `build_playlists`
* `get_playlist_track_locations` is now `get_playlist_tracks`

The `Combiner` class was removed from `tag_parsers.py`, made to not inherit from `TagParser`, and moved into it's own module `playlist_combiner.py`.

v2.4.1-beta.2

Toggle v2.4.1-beta.2's commit message
hotfix