diff --git a/maloja/images.py b/maloja/images.py index 151c0cd..e576c84 100644 --- a/maloja/images.py +++ b/maloja/images.py @@ -16,12 +16,14 @@ from threading import Lock from concurrent.futures import ThreadPoolExecutor import re import datetime +import time import sqlalchemy as sql -MAX_RESOLVE_THREADS = 10 +MAX_RESOLVE_THREADS = 5 +MAX_SECONDS_TO_RESOLVE_REQUEST = 5 # remove old db file (columns missing) @@ -126,10 +128,19 @@ def remove_image_from_cache(track_id=None,artist_id=None,album_id=None): with engine.begin() as conn: op = DB[table].delete().where( DB[table].c.id==entity_id, + ).returning( + DB[table].c.id, + DB[table].c.localproxyurl ) - result = conn.execute(op) + result = conn.execute(op).all() + + for row in result: + targetpath = data_dir['cache']('images',row.localproxyurl.split('/')[-1]) + try: + os.remove(targetpath) + except: + pass - # TODO delete proxy def dl_image(url): try: @@ -254,23 +265,39 @@ def resolve_image(artist_id=None,track_id=None,album_id=None): # the actual http request for the full image def image_request(artist_id=None,track_id=None,album_id=None): - # check cache - result = get_image_from_cache(artist_id=artist_id,track_id=track_id,album_id=album_id) - if result is not None: - # we got an entry, even if it's that there is no image (value None) - if result['value'] is None: - # use placeholder - placeholder_url = "https://generative-placeholders.glitch.me/image?width=300&height=300&style=" - if artist_id: - result['value'] = placeholder_url + f"tiles&colors={artist_id % 100}" - if track_id: - result['value'] = placeholder_url + f"triangles&colors={track_id % 100}" - if album_id: - result['value'] = placeholder_url + f"joy-division&colors={album_id % 100}" - return result - else: - # no entry, which means we're still working on it - return {'type':'noimage','value':'wait'} + + # because we use lazyload, we can allow our http requests to take a little while at least + # not the full backend request, but a few seconds to give us time to fetch some images + # because 503 retry-after doesn't seem to be honored + attempt = 0 + while attempt < MAX_SECONDS_TO_RESOLVE_REQUEST: + attempt += 1 + # check cache + result = get_image_from_cache(artist_id=artist_id,track_id=track_id,album_id=album_id) + if result is not None: + # we got an entry, even if it's that there is no image (value None) + if result['value'] is None: + # use placeholder + if malojaconfig["FANCY_PLACEHOLDER_ART"]: + placeholder_url = "https://generative-placeholders.glitch.me/image?width=300&height=300&style=" + if artist_id: + result['value'] = placeholder_url + f"tiles&colors={artist_id % 100}" + if track_id: + result['value'] = placeholder_url + f"triangles&colors={track_id % 100}" + if album_id: + result['value'] = placeholder_url + f"joy-division&colors={album_id % 100}" + else: + if artist_id: + result['value'] = "/static/svg/placeholder_artist.svg" + if track_id: + result['value'] = "/static/svg/placeholder_track.svg" + if album_id: + result['value'] = "/static/svg/placeholder_album.svg" + return result + time.sleep(1) + + # no entry, which means we're still working on it + return {'type':'noimage','value':'wait'} diff --git a/maloja/pkg_global/conf.py b/maloja/pkg_global/conf.py index a9be47b..e6dac70 100644 --- a/maloja/pkg_global/conf.py +++ b/maloja/pkg_global/conf.py @@ -197,6 +197,7 @@ malojaconfig = Configuration( "display_art_icons":(tp.Boolean(), "Display Album/Artist Icons", True), "default_album_artist":(tp.String(), "Default Albumartist", "Various Artists"), "use_album_artwork_for_tracks":(tp.Boolean(), "Use Album Artwork for tracks", True), + "fancy_placeholder_art":(tp.Boolean(), "Use fancy placeholder artwork",True), "discourage_cpu_heavy_stats":(tp.Boolean(), "Discourage CPU-heavy stats", False, "Prevent visitors from mindlessly clicking on CPU-heavy options. Does not actually disable them for malicious actors!"), "use_local_images":(tp.Boolean(), "Use Local Images", True), #"local_image_rotate":(tp.Integer(), "Local Image Rotate", 3600), diff --git a/maloja/web/static/svg/LICENSE b/maloja/web/static/svg/LICENSE new file mode 100644 index 0000000..6be4c3e --- /dev/null +++ b/maloja/web/static/svg/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015-present Ionic (http://ionic.io/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/maloja/web/static/svg/placeholder_album.svg b/maloja/web/static/svg/placeholder_album.svg new file mode 100644 index 0000000..751e22a --- /dev/null +++ b/maloja/web/static/svg/placeholder_album.svg @@ -0,0 +1 @@ + diff --git a/maloja/web/static/svg/placeholder_artist.svg b/maloja/web/static/svg/placeholder_artist.svg new file mode 100644 index 0000000..f7e6b85 --- /dev/null +++ b/maloja/web/static/svg/placeholder_artist.svg @@ -0,0 +1 @@ + diff --git a/maloja/web/static/svg/placeholder_track.svg b/maloja/web/static/svg/placeholder_track.svg new file mode 100644 index 0000000..a6e6efb --- /dev/null +++ b/maloja/web/static/svg/placeholder_track.svg @@ -0,0 +1 @@ +