diff --git a/.gitignore b/.gitignore index c5da5fc..edbf6ae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,194 @@ config.ini +*.sqlite +# Created by https://www.toptal.com/developers/gitignore/api/venv,python +# Edit at https://www.toptal.com/developers/gitignore?templates=venv,python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +### venv ### +# Virtualenv +# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ +[Bb]in +[Ii]nclude +[Ll]ib +[Ll]ib64 +[Ll]ocal +[Ss]cripts +pyvenv.cfg +pip-selfcheck.json + +# End of https://www.toptal.com/developers/gitignore/api/venv,python + # ---> Python # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/api_calls.py b/api_calls.py new file mode 100644 index 0000000..a2c3f02 --- /dev/null +++ b/api_calls.py @@ -0,0 +1,34 @@ +import requests +import os + +def get_mb_id(artist_name): + mb_url = f'https://musicbrainz.org/ws/2/artist?query=artist:%22{artist_name}%22&fmt=json' + response = requests.get(mb_url) + if response.status_code == 200: + mb_data = response.json() + if mb_data['count'] > 0: + if mb_data['artists'][0]['score'] > 80: + return mb_data['artists'][0]['id'] + else: + print("No artist found of hight enough confidance.") + else: + print("No artist found.") + else: + print(f"Error: {response.status_code}") + +def get_image(mb_id, ftv_api_key, artist_path): + ftv_api_url = f'https://webservice.fanart.tv/v3/music/{mb_id}?api_key={ftv_api_key}' + response = requests.get(ftv_api_url) + ftv_data =response.json() + if not ('status' in ftv_data): + art_url = ftv_data['artistthumb'][0]['url'] + print(art_url) + response = requests.get(art_url) + if response.status_code == 200: + with open(os.path.join(artist_path, 'artist.jpg'), 'wb') as f: + f.write(response.content) + else: + print("Error downloading: ", response.status_code) + else: + error_msg = ftv_data['error message'] + print(f"Error: {error_msg}") \ No newline at end of file diff --git a/dir_activities.py b/dir_activities.py index 373dd0b..198eae5 100644 --- a/dir_activities.py +++ b/dir_activities.py @@ -1,8 +1,7 @@ import os def get_all(path): - all_dirs = [] - for root, dirs, files in os.walk(path): - all_dirs.extend(dir for dir in dirs if os.path.isdir(os.path.join(root, dir))) - all_dirs = all_dirs[1:] - return all_dirs \ No newline at end of file + return [name for name in os.listdir(path) if os.path.isdir(os.path.join(path, name))] + +def has_artist_art(path): + return os.path.exists(os.path.join(path, "artist.jpg")) \ No newline at end of file diff --git a/get_artist_art.py b/get_artist_art.py index 64cead3..912d30a 100755 --- a/get_artist_art.py +++ b/get_artist_art.py @@ -1,12 +1,31 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python3.12 import configparser -import dir_activities +import os +import dir_activities +import api_calls config = configparser.ConfigParser() config.read('config.ini') music_path = config['music']['dir'] +ftv_api_key = config['fanart_tv']['api_key'] +count = 1 dir_list = dir_activities.get_all(music_path) -print(dir_list) +dir_list.sort() +for artist in dir_list: + if (not(dir_activities.has_artist_art(artist))): + print(dir_activities.has_artist_art(artist)) + print(str(count) + ": " + artist) + try: + mb_id = api_calls.get_mb_id(artist) + # print("Getting ", artist_image) + artist_image = api_calls.get_image(mb_id, ftv_api_key, os.path.join(music_path, artist)) + + # api_requests.get_art(artist_image, artist, music_path) + except Exception as e: + print("Artist or art not found.") + print(e) + + count += 1