diff --git a/app/db/sqlite/artists.py b/app/db/sqlite/artists.py index 5849706a..9ad8c5ca 100644 --- a/app/db/sqlite/artists.py +++ b/app/db/sqlite/artists.py @@ -10,7 +10,7 @@ from .utils import SQLiteManager class SQLiteArtistMethods: @staticmethod - def insert_one_artist(cur: Cursor, artisthash: str, colors: str | list[str]): + def insert_one_artist(cur: Cursor, artisthash: str, colors: list[str]): """ Inserts a single artist into the database. """ @@ -23,16 +23,23 @@ class SQLiteArtistMethods: cur.execute(sql, (artisthash, colors)) @staticmethod - def get_all_artists(): + def get_all_artists(cur_: Cursor = None): """ Get all artists from the database and return a generator of Artist objects """ sql = """SELECT * FROM artists""" - with SQLiteManager() as cur: - cur.execute(sql) + if not cur_: + with SQLiteManager() as cur: + cur.execute(sql) - for artist in cur.fetchall(): + for artist in cur.fetchall(): + yield artist + + cur.close() + + else: + cur_.execute(sql) + + for artist in cur_.fetchall(): yield artist - - cur.close() diff --git a/app/db/sqlite/utils.py b/app/db/sqlite/utils.py index 3b35e1a5..69b1d5c5 100644 --- a/app/db/sqlite/utils.py +++ b/app/db/sqlite/utils.py @@ -62,7 +62,12 @@ class SQLiteManager: for you. It also commits and closes the connection when you're done. """ - def __init__(self, conn: Optional[Connection] = None, userdata_db=False) -> None: + def __init__( + self, + conn: Optional[Connection] = None, + userdata_db=False, + test_db_path: str = None, + ) -> None: """ When a connection is passed in, don't close the connection, because it's a connection to the search database [in memory db]. @@ -70,6 +75,7 @@ class SQLiteManager: self.conn = conn self.CLOSE_CONN = True self.userdata_db = userdata_db + self.test_db_path = test_db_path if conn: self.conn = conn @@ -79,7 +85,10 @@ class SQLiteManager: if self.conn is not None: return self.conn.cursor() - db_path = Db.get_app_db_path() + if self.test_db_path: + db_path = self.test_db_path + else: + db_path = Db.get_app_db_path() if self.userdata_db: db_path = Db.get_userdata_db_path() diff --git a/app/lib/colorlib.py b/app/lib/colorlib.py index 20ad5580..dd0eca33 100644 --- a/app/lib/colorlib.py +++ b/app/lib/colorlib.py @@ -56,24 +56,25 @@ class ProcessAlbumColors: albums = [a for a in AlbumStore.albums if len(a.colors) == 0] with SQLiteManager() as cur: - for album in tqdm(albums, desc="Processing missing album colors"): - sql = "SELECT COUNT(1) FROM albums WHERE albumhash = ?" - cur.execute(sql, (album.albumhash,)) - count = cur.fetchone()[0] + try: + for album in tqdm(albums, desc="Processing missing album colors"): + sql = "SELECT COUNT(1) FROM albums WHERE albumhash = ?" + cur.execute(sql, (album.albumhash,)) + count = cur.fetchone()[0] - if count != 0: - continue + if count != 0: + continue - colors = process_color(album.albumhash) + colors = process_color(album.albumhash) - if colors is None: - continue + if colors is None: + continue - album.set_colors(colors) - color_str = json.dumps(colors) - db.insert_one_album(cur, album.albumhash, color_str) - - cur.close() + album.set_colors(colors) + color_str = json.dumps(colors) + db.insert_one_album(cur, album.albumhash, color_str) + finally: + cur.close() class ProcessArtistColors: @@ -85,21 +86,24 @@ class ProcessArtistColors: all_artists = [a for a in ArtistStore.artists if len(a.colors) == 0] with SQLiteManager() as cur: - for artist in tqdm(all_artists, desc="Processing missing artist colors"): - sql = "SELECT COUNT(1) FROM artists WHERE artisthash = ?" + try: + for artist in tqdm( + all_artists, desc="Processing missing artist colors" + ): + sql = "SELECT COUNT(1) FROM artists WHERE artisthash = ?" - cur.execute(sql, (artist.artisthash,)) - count = cur.fetchone()[0] + cur.execute(sql, (artist.artisthash,)) + count = cur.fetchone()[0] - if count != 0: - continue + if count != 0: + continue - colors = process_color(artist.artisthash, is_album=False) + colors = process_color(artist.artisthash, is_album=False) - if colors is None: - continue + if colors is None: + continue - artist.set_colors(colors) - adb.insert_one_artist(cur, artist.artisthash, colors) - - cur.close() + artist.set_colors(colors) + adb.insert_one_artist(cur, artist.artisthash, colors) + finally: + cur.close() diff --git a/app/store/artists.py b/app/store/artists.py index b6ad3dcf..e24bfccf 100644 --- a/app/store/artists.py +++ b/app/store/artists.py @@ -20,9 +20,9 @@ class ArtistStore: """ cls.artists = get_all_artists(TrackStore.tracks, AlbumStore.albums) - db_artists: list[tuple] = list(ardb.get_all_artists()) + # db_artists: list[tuple] = list(ardb.get_all_artists()) - for art in tqdm(db_artists, desc="Loading artists"): + for art in tqdm(ardb.get_all_artists(), desc="Loading artists"): cls.map_artist_color(art) @classmethod diff --git a/app/utils/bisection.py b/app/utils/bisection.py index fca59520..bc280065 100644 --- a/app/utils/bisection.py +++ b/app/utils/bisection.py @@ -6,7 +6,9 @@ class UseBisection: items. """ - def __init__(self, source: list, search_from: str, queries: list[str], limit=-1) -> None: + def __init__( + self, source: list, search_from: str, queries: list[str], limit=-1 + ) -> None: self.source_list = source self.queries_list = queries self.attr = search_from @@ -45,27 +47,3 @@ class UseBisection: break return results - - -def bisection_search_string(strings: list[str], target: str) -> str | None: - """ - Finds a string in a list of strings using bisection search. - """ - if not strings: - return None - - strings = sorted(strings) - - left = 0 - right = len(strings) - 1 - while left <= right: - middle = (left + right) // 2 - if strings[middle] == target: - return strings[middle] - - if strings[middle] < target: - left = middle + 1 - else: - right = middle - 1 - - return None diff --git a/app/utils/dates.py b/app/utils/dates.py index b86e2964..e8cf913e 100644 --- a/app/utils/dates.py +++ b/app/utils/dates.py @@ -1,3 +1,4 @@ +import pendulum from datetime import datetime _format = "%Y-%m-%d %H:%M:%S" @@ -21,44 +22,6 @@ def date_string_to_time_passed(prev_date: str) -> str: diff = now - then seconds = diff.seconds - print(seconds) - if seconds < 0: - return "from the future 🛸" - - if seconds < 15: - return "now" - - if seconds < 60: - return f"{int(seconds)} seconds ago" - - if seconds < 3600: - return f"{int(seconds // 60)} minutes ago" - - if seconds < 86400: - return f"{int(seconds // 3600)} hours ago" - - days = diff.days - - if days == 1: - return "yesterday" - - if days < 7: - return f"{days} days ago" - - if days < 14: - return "1 week ago" - - if days < 30: - return f"{int(days // 7)} weeks ago" - - if days < 60: - return "1 month ago" - - if days < 365: - return f"{int(days // 30)} months ago" - - if days < 730: - return "1 year ago" - - return f"{int(days // 365)} years ago" + now = pendulum.now() + return now.subtract(seconds=seconds).diff_for_humans() diff --git a/poetry.lock b/poetry.lock index ed58a4df..38b34a23 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "altgraph" version = "0.17.3" description = "Python graph (network) package" -category = "dev" optional = false python-versions = "*" files = [ @@ -16,7 +15,6 @@ files = [ name = "astroid" version = "2.15.1" description = "An abstract syntax tree for Python with inference support." -category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -36,7 +34,6 @@ wrapt = [ name = "attrs" version = "22.2.0" description = "Classes Without Boilerplate" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -55,7 +52,6 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy name = "black" version = "22.12.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -90,7 +86,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -102,7 +97,6 @@ files = [ name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -187,7 +181,6 @@ files = [ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -202,7 +195,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -214,7 +206,6 @@ files = [ name = "colorgram-py" version = "1.2.0" description = "A Python module for extracting colors from images. Get a palette of any picture!" -category = "main" optional = false python-versions = "*" files = [ @@ -229,7 +220,6 @@ pillow = ">=3.3.1" name = "dill" version = "0.3.6" description = "serialize all of python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -244,7 +234,6 @@ graph = ["objgraph (>=1.7.2)"] name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -259,7 +248,6 @@ test = ["pytest (>=6)"] name = "flask" version = "2.2.3" description = "A simple framework for building complex web applications." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -281,7 +269,6 @@ dotenv = ["python-dotenv"] name = "flask-cors" version = "3.0.10" description = "A Flask extension adding a decorator for CORS support" -category = "main" optional = false python-versions = "*" files = [ @@ -297,7 +284,6 @@ Six = "*" name = "gunicorn" version = "20.1.0" description = "WSGI HTTP Server for UNIX" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -318,7 +304,6 @@ tornado = ["tornado (>=0.2)"] name = "hypothesis" version = "6.70.0" description = "A library for property-based testing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -351,7 +336,6 @@ zoneinfo = ["backports.zoneinfo (>=0.2.1)", "tzdata (>=2022.7)"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -363,7 +347,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -375,7 +358,6 @@ files = [ name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -393,7 +375,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "itsdangerous" version = "2.1.2" description = "Safely pass data to untrusted environments and back." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -405,7 +386,6 @@ files = [ name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -423,7 +403,6 @@ i18n = ["Babel (>=2.7)"] name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -469,7 +448,6 @@ files = [ name = "macholib" version = "1.16.2" description = "Mach-O header analysis and editing" -category = "dev" optional = false python-versions = "*" files = [ @@ -484,7 +462,6 @@ altgraph = ">=0.17" name = "markupsafe" version = "2.1.2" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -544,7 +521,6 @@ files = [ name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -556,7 +532,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -568,7 +543,6 @@ files = [ name = "packaging" version = "23.0" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -580,7 +554,6 @@ files = [ name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -592,7 +565,6 @@ files = [ name = "pefile" version = "2023.2.7" description = "Python PE parsing module" -category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -600,11 +572,44 @@ files = [ {file = "pefile-2023.2.7.tar.gz", hash = "sha256:82e6114004b3d6911c77c3953e3838654b04511b8b66e8583db70c65998017dc"}, ] +[[package]] +name = "pendulum" +version = "2.1.2" +description = "Python datetimes made easy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, + {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, + {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, + {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, + {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, + {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, + {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, + {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, + {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, + {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, + {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, +] + +[package.dependencies] +python-dateutil = ">=2.6,<3.0" +pytzdata = ">=2020.1" + [[package]] name = "pillow" version = "9.4.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -695,7 +700,6 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "platformdirs" version = "3.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -711,7 +715,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest- name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -727,7 +730,6 @@ testing = ["pytest", "pytest-benchmark"] name = "psutil" version = "5.9.4" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -754,7 +756,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "pyinstaller" version = "5.9.0" description = "PyInstaller bundles a Python application and all its dependencies into a single package." -category = "dev" optional = false python-versions = "<3.12,>=3.7" files = [ @@ -788,7 +789,6 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] name = "pyinstaller-hooks-contrib" version = "2023.1" description = "Community maintained hooks for PyInstaller" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -800,7 +800,6 @@ files = [ name = "pylint" version = "2.17.1" description = "python code static checker" -category = "dev" optional = false python-versions = ">=3.7.2" files = [ @@ -829,7 +828,6 @@ testutils = ["gitpython (>3)"] name = "pytest" version = "7.2.2" description = "pytest: simple powerful testing with Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -849,11 +847,35 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytzdata" +version = "2020.1" +description = "The Olson timezone database for Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, + {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, +] + [[package]] name = "pywin32" version = "306" description = "Python for Window Extensions" -category = "main" optional = false python-versions = "*" files = [ @@ -877,7 +899,6 @@ files = [ name = "pywin32-ctypes" version = "0.2.0" description = "" -category = "dev" optional = false python-versions = "*" files = [ @@ -889,7 +910,6 @@ files = [ name = "pyxdg" version = "0.28" description = "PyXDG contains implementations of freedesktop.org standards in python." -category = "main" optional = false python-versions = "*" files = [ @@ -901,7 +921,6 @@ files = [ name = "rapidfuzz" version = "2.13.7" description = "rapid fuzzy string matching" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1003,7 +1022,6 @@ full = ["numpy"] name = "requests" version = "2.28.2" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7, <4" files = [ @@ -1025,7 +1043,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "setuptools" version = "67.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1042,7 +1059,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "show-in-file-manager" version = "1.1.4" description = "Open the system file manager and select files in it" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1059,7 +1075,6 @@ pyxdg = {version = ">=0.25", markers = "platform_system == \"Linux\""} name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1071,7 +1086,6 @@ files = [ name = "sortedcontainers" version = "2.4.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "dev" optional = false python-versions = "*" files = [ @@ -1083,7 +1097,6 @@ files = [ name = "tinytag" version = "1.8.1" description = "Read music meta data and length of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA and Wave files" -category = "main" optional = false python-versions = ">=2.7" files = [ @@ -1097,7 +1110,6 @@ tests = ["flake8", "pytest", "pytest-cov"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1109,7 +1121,6 @@ files = [ name = "tomlkit" version = "0.11.6" description = "Style preserving TOML library" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1121,7 +1132,6 @@ files = [ name = "tqdm" version = "4.65.0" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1142,7 +1152,6 @@ telegram = ["requests"] name = "typing-extensions" version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1154,7 +1163,6 @@ files = [ name = "unidecode" version = "1.3.6" description = "ASCII transliterations of Unicode text" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1166,7 +1174,6 @@ files = [ name = "urllib3" version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -1183,7 +1190,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "watchdog" version = "3.0.0" description = "Filesystem events monitoring" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1223,7 +1229,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "werkzeug" version = "2.2.3" description = "The comprehensive WSGI web application library." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1241,7 +1246,6 @@ watchdog = ["watchdog"] name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -1325,4 +1329,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.12" -content-hash = "cb65430f7a95cd82d5011f293ff3bba2fa972fe4f9973b2b1fffff2abb97bffd" +content-hash = "81941c92f1b4a468b554fc7eeae857897f352142cc3c03393349297ac11dcaae" diff --git a/pyproject.toml b/pyproject.toml index a4cd1073..cc62e987 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,7 @@ tinytag = "^1.8.1" Unidecode = "^1.3.6" psutil = "^5.9.4" show-in-file-manager = "^1.1.4" +pendulum = "^2.1.2" [tool.poetry.dev-dependencies] pylint = "^2.15.5" diff --git a/tests/sqlite/test_sqlite_actions.py b/tests/sqlite/test_sqlite_actions.py new file mode 100644 index 00000000..07a45275 --- /dev/null +++ b/tests/sqlite/test_sqlite_actions.py @@ -0,0 +1,59 @@ +import json +import sqlite3 +import os +from app.db.sqlite.artists import SQLiteArtistMethods +from app.db.sqlite.queries import CREATE_APPDB_TABLES + +from app.db.sqlite.utils import SQLiteManager + +db_path = "test.db" + + +def test_sqlite_manager(): + with SQLiteManager(test_db_path=db_path) as cur: + for query in CREATE_APPDB_TABLES.split(";"): + cur.execute(query) + + cur.execute( + "INSERT INTO tracks (album, albumartist, albumhash, artist, bitrate, copyright, date, disc, duration, filepath, folder, genre, last_mod, title, track, trackhash) VALUES ('Dummy Album', 'Dummy Album Artist', 'dummyalbumhash', 'Dummy Artist', 320, 'Dummy Copyright', 1630454400, 1, 180, '/path/to/dummy/file.mp3', '/path/to/dummy/folder', 'Dummy Genre', 1630454400.5, 'Dummy Title', 1, 'dummytrackhash');" + ) + + cur.execute("SELECT * FROM tracks") + result = cur.fetchone() + assert result[7] == 1630454400 + + # Test using a connection + with SQLiteManager(conn=sqlite3.connect(db_path)) as cur: + cur.execute("SELECT * FROM tracks") + result = cur.fetchone() + assert result[7] == 1630454400 + + +def test_insert_one_artist(): + color1 = "rgb(0, 0, 0)" + color2 = "rgb(255, 255, 255)" + + with SQLiteManager(test_db_path=db_path) as cur: + SQLiteArtistMethods.insert_one_artist(cur, "artisthash1", [color1, color2]) + cur.execute("SELECT * FROM artists WHERE artisthash=?", ("artisthash1",)) + + result = cur.fetchone() + assert result[1:] == ("artisthash1", json.dumps([color1, color2]), None) + + +def test_get_all_artists(): + with SQLiteManager(test_db_path=db_path) as cur: + artists = SQLiteArtistMethods.get_all_artists(cur) + + # assert that that the generator is not empty and that for each tuple has 4 elements + + try: + while True: + artist = next(artists) + assert len(artist) == 4 + except StopIteration: + pass + + +def test_remove_test_db(): + os.remove(db_path) diff --git a/tests/test_utils.py b/tests/test_utils.py index fd8da263..01c72d13 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -18,7 +18,7 @@ def test_extract_featured_artists_from_title(): ["Ed Sheeran", "Stormzy"], ["Lil Peep"], ["Juice Wrld", "Lil Peep"], - ["Juice Wrld/Lil Peep"], + ["Juice Wrld", "Lil Peep"], ["Burna Boy"], [], ]