Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for scanning barcode in image. #5

Merged
merged 1 commit into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ __pycache__
build
coverage.xml
dist
venv
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
0.2.0 (TBD)
* `--track-choice` option to select a subset of tracks to scrobble.
* `scrobble cd` now accepts a path to an image with a barcode. Providing the barcode number itself as input
is still valid.
0.1.0 (2023-08-02):
* Initial release on GitHub and PyPI.
* `scrobble` is intended to be a general/omni-scrobbling tool that works with different tracklists.
Expand Down
84 changes: 53 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,37 +108,38 @@ scrobble cd --help
```sh
Usage: scrobble cd [OPTIONS] BARCODE [PLAYBACKEND]

╭─ Arguments ──────────────────────────────────────────────────────────────────────────╮
│ * barcode TEXT Barcode of the CD you want to scrobble. Double │
│ album releases are supported. │
│ [default: None] │
│ [required] │
│ playbackend [PLAYBACKEND] When did you finish listening? e.g., 'now' or │
│ '1 hour ago'. │
│ [default: now] │
╰──────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ────────────────────────────────────────────────────────────────────────────╮
│ --dryrun --no-dryrun --dryrun will print a list of tracks │
│ without scrobbling to Last.fm │
│ [default: no-dryrun] │
│ --verbose --no-verbose --verbose will print a bunch of stuff │
│ to your terminal. │
│ [default: no-verbose] │
│ --notify --no-notify --notify will send a push notification │
│ via Pushover with CD information. │
│ [default: no-notify] │
│ --release-choice --no-release-choice --release-choice will give you a list │
│ of options of more than one CD is │
│ matched. Otherwise, the app will go │
│ with the first match. │
│ [default: release-choice] │
│ --track-choice --no-track-choice --track-choice will give you a list of │
│ tracks in the release to choose to │
│ scrobble instead of scrobbling the │
│ entire release. │
│ [default: no-track-choice] │
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────╯
╭─ Arguments ───────────────────────────────────────────────────────────────────────────╮
│ * barcode TEXT Barcode (as a number) of the CD you want to │
│ scrobble, or a path to an image of a barcode. │
│ Double album releases are supported. │
│ [default: None] │
│ [required] │
│ playback_end [PLAYBACK_END] When did you finish listening? e.g., 'now' or │
│ '1 hour ago'. │
│ [default: now] │
╰───────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ─────────────────────────────────────────────────────────────────────────────╮
│ --dryrun --no-dryrun --dryrun will print a list of tracks │
│ without scrobbling to Last.fm │
│ [default: no-dryrun] │
│ --verbose --no-verbose --verbose will print a bunch of stuff to │
│ your terminal. │
│ [default: no-verbose] │
│ --notify --no-notify --notify will send a push notification │
│ via Pushover with CD information. │
│ [default: no-notify] │
│ --release-choice --no-release-choice --release-choice will give you a list of │
│ options of more than one CD is matched. │
│ Otherwise, the app will go with the │
│ first match. │
│ [default: release-choice] │
│ --track-choice --no-track-choice --track-choice will give you a list of │
│ tracks in the release to choose to │
│ scrobble instead of scrobbling the │
│ entire release. │
│ [default: no-track-choice] │
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────────────────────────────╯
```

## Examples
Expand All @@ -162,6 +163,27 @@ $ scrobble cd --dryrun --verbose 031452916021
🎵 11 Rammstein
⚠️ Dry run - no tracks were scrobbled.

# provide a path to a an image with a barcode instead of the barcode value itself
scrobble cd --dryrun --verbose --no-release-choice 'tests/resources/CD1-600.jpeg'

💿 MF DOOM - MM..FOOD (2017)
🎵 1 Beef Rapp
🎵 2 Hoe Cakes
🎵 3 Potholderz
🎵 4 One Beer
🎵 5 Deep Fried Frenz
🎵 6 Poo‐Putt Platter
🎵 7 Fillet‐O‐Rapper
🎵 8 Gumbo
🎵 9 Fig Leaf Bi‐Carbonate
🎵 10 Kon Karne
🎵 11 Guinesses
🎵 12 Kon Queso
🎵 13 Rapp Snitch Knishes
🎵 14 Vomitspit
🎵 15 Kookies
🎵 1 MM..FOOD Drive Tour
⚠️ Dry run - no tracks were scrobbled.

# scrobble Nymphetamine by Cradle of Filth which you finished
# listening to two hours ago
Expand Down
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,23 @@ classifiers = [
"Topic :: Utilities",
"Programming Language :: Python :: 3",
]

dependencies = [
"musicbrainzngs",
"parsedatetime",
"pylast",
"python-dateutil",
"pylast",
"rich",
"typer[all]",
"opencv-python"
]

[project.optional-dependencies]

test = [
"scrobble",
"pytest",
"pytest-cov"
"pytest-cov",
]

[project.urls]
Expand Down
17 changes: 15 additions & 2 deletions src/scrobble/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from typing import Optional

import os
import typer
from pathlib import Path
from typing_extensions import Annotated

from scrobble.lastfm import get_lastfm_client
Expand Down Expand Up @@ -33,7 +35,7 @@ def discogs():
@APP.command()
def cd(
barcode: Annotated[str, typer.Argument(
help='Barcode of the CD you want to scrobble. Double album releases are supported.'
help='Barcode (as a number) of the CD you want to scrobble, or a path to an image of a barcode. Double album releases are supported.'
)],
playback_end: Annotated[Optional[str], typer.Argument(
help="When did you finish listening? e.g., 'now' or '1 hour ago'."
Expand All @@ -60,7 +62,18 @@ def cd(

init_musicbrainz(USERAGENT)

scrobble_cd: CD = CD.find_cd(barcode, release_choice)
try:
resolved_barcode = int(barcode)
except ValueError:
if os.path.exists(Path(barcode).resolve()):
from scrobble.barcode_scanner import read_barcode
resolved_barcode = read_barcode(barcode)
if not resolved_barcode:
raise RuntimeError(f'The image you provided at path {barcode} did not contain a readable barcode.')
else:
raise ValueError(f"The barcode you entered: {barcode} is not not a number or a valid path to a barcode image.")

scrobble_cd: CD = CD.find_cd(resolved_barcode, release_choice)

if track_choice:
tracks_to_scrobble = choose_tracks(scrobble_cd.tracks)
Expand Down
7 changes: 7 additions & 0 deletions src/scrobble/barcode_scanner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from cv2 import barcode, imread
from typing import Optional


def read_barcode(imgpath: str) -> Optional[str]:
bd = barcode.BarcodeDetector()
return bd.detectAndDecode(imread(imgpath))[0]
Binary file added tests/resources/CD1-600.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions tests/test_barcode_scanner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from scrobble.barcode_scanner import read_barcode

def test_read_barcode():
test_image_path = 'tests/resources/CD1-600.jpeg'
assert read_barcode(test_image_path) == '826257008428'