Skip to content

Commit

Permalink
Testing
Browse files Browse the repository at this point in the history
  • Loading branch information
infojunkie committed Oct 29, 2023
1 parent 7a97e11 commit 2ee1969
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 20 deletions.
72 changes: 72 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Run this job on pushes to `main`, and for pull requests. If you don't specify
# `branches: [main], then this actions runs _twice_ on pull requests, which is
# annoying.

on:
push:
branches: [main]
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

# If you wanted to use multiple Python versions, you'd have specify a matrix in the job and
# reference the matrixe python version here.
- uses: actions/setup-python@v2
with:
python-version: 3.9

# Cache the installation of Poetry itself, e.g. the next step. This prevents the workflow
# from installing Poetry every time, which can be slow. Note the use of the Poetry version
# number in the cache key, and the "-0" suffix: this allows you to invalidate the cache
# manually if/when you want to upgrade Poetry, or if something goes wrong. This could be
# mildly cleaner by using an environment variable, but I don't really care.
- name: cache poetry install
uses: actions/cache@v2
with:
path: ~/.local
key: poetry-1.5.1-0

# Install Poetry. You could do this manually, or there are several actions that do this.
# `snok/install-poetry` seems to be minimal yet complete, and really just calls out to
# Poetry's default install script, which feels correct. I pin the Poetry version here
# because Poetry does occasionally change APIs between versions and I don't want my
# actions to break if it does.
#
# The key configuration value here is `virtualenvs-in-project: true`: this creates the
# venv as a `.venv` in your testing directory, which allows the next step to easily
# cache it.
- uses: snok/install-poetry@v1
with:
version: 1.5.1
virtualenvs-create: true
virtualenvs-in-project: true

# Cache your dependencies (i.e. all the stuff in your `pyproject.toml`). Note the cache
# key: if you're using multiple Python versions, or multiple OSes, you'd need to include
# them in the cache key. I'm not, so it can be simple and just depend on the poetry.lock.
- name: cache deps
id: cache-deps
uses: actions/cache@v2
with:
path: .venv
key: pydeps-${{ hashFiles('**/poetry.lock') }}

# Install dependencies. `--no-root` means "install all dependencies but not the project
# itself", which is what you want to avoid caching _your_ code. The `if` statement
# ensures this only runs on a cache miss.
- run: poetry install --no-interaction --no-root
if: steps.cache-deps.outputs.cache-hit != 'true'

# Now install _your_ project. This isn't necessary for many types of projects -- particularly
# things like Django apps don't need this. But it's a good idea since it fully-exercises the
# pyproject.toml and makes that if you add things like console-scripts at some point that
# they'll be installed and working.
- run: poetry install --no-interaction

# And finally run tests. I'm using pytest and all my pytest config is in my `pyproject.toml`
# so this line is super-simple. But it could be as complex as you need.
- run: poetry run pytest
128 changes: 120 additions & 8 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "discogs-tag"
version = "0.1.4"
version = "0.1.5"
description = "A rudimentary audio tagger based on Discogs metadata."
authors = ["infojunkie <[email protected]>"]
readme = "README.md"
Expand All @@ -12,9 +12,16 @@ fire = "^0.5.0"
mutagen = "^1.46.0"
importlib-metadata = "^6.8.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.0.0"
pytest-mock = "*"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
discogs-tag = "discogs_tag.cli:cli"

[tool.pytest.ini_options]
pythonpath = "src"
30 changes: 19 additions & 11 deletions src/discogs_tag/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,7 @@ def tag(release, dir = './', dry = False):
raise Exception(f'Expecting {len(tracks)} files but found {len(files)}. Aborting.')
for n, track in enumerate(tracks):
audio = mutagen.File(files[n], easy=True)
audio['title'] = track['title']
if 'artists' in track:
audio['artist'] = ', '.join([artist_name(artist) for artist in track['artists']])
positions = track['position'].split('-')
audio['tracknumber'] = positions[-1]
if (len(positions) > 1):
audio['discnumber'] = positions[0]
composers = ', '.join([artist_name(composer) for composer in filter(lambda a: a['role'].casefold() == 'Written-By'.casefold(), track['extraartists'])]) if 'extraartists' in track else None
if (composers):
audio['composer'] = composers
apply_metadata(track, audio)
if (dry):
pprint(audio)
else:
Expand All @@ -41,8 +32,25 @@ def tag(release, dir = './', dry = False):
if (not dry):
print(f'Processed {len(files)} audio files.')

def apply_metadata(track, audio):
audio['title'] = track['title']
if 'artists' in track:
audio['artist'] = ', '.join([artist_name(artist) for artist in track['artists']])
positions = track['position'].split('-')
audio['tracknumber'] = positions[-1]
if (len(positions) > 1):
audio['discnumber'] = positions[0]
composers = ', '.join([artist_name(composer) for composer in filter(lambda a: a['role'].casefold() == 'Written-By'.casefold(), track['extraartists'])]) if 'extraartists' in track else None
if (composers):
audio['composer'] = composers

def artist_name(artist):
return artist['anv'] or artist['name']
if 'anv' in artist:
return artist['anv']
elif 'name' in artist:
return artist['name']
else:
return None

def cli():
fire.Fire(tag)
25 changes: 25 additions & 0 deletions tests/test_discogs_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from discogs_tag.cli import apply_metadata

def test_apply_metadata():
audio = {}
apply_metadata({
'title': 'Title',
'artists': [{
'anv': 'Artist 1'
}, {
'name': 'Artist 2'
}],
'position': '1-02',
'extraartists': [{
'role': 'Guitar',
'name': 'Guitarist'
}, {
'role': 'Written-By',
'name': 'Composer'
}]
}, audio)
assert audio['title'] == 'Title'
assert audio['artist'] == 'Artist 1, Artist 2'
assert audio['discnumber'] == '1'
assert audio['tracknumber'] == '02'
assert audio['composer'] == 'Composer'

0 comments on commit 2ee1969

Please sign in to comment.