From d576467db825648e24ee71ebd680c08bb23b424a Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Mon, 23 Mar 2026 16:17:15 -0400 Subject: [PATCH] [black] Reformat to use 88 line lengths --- pyproject.toml | 2 +- tests/foods_tests/test_recipe_scraper.py | 24 ++--- tests/foods_tests/test_usda.py | 4 +- tests/podcasts_tests/test_scrapers.py | 4 +- tests/scrobbles_tests/conftest.py | 8 +- tests/scrobbles_tests/test_utils.py | 4 +- tests/scrobbles_tests/test_views.py | 16 +--- tests/test_context_processors.py | 20 ++--- tests/videos_tests/test_api.py | 12 +-- vrobbler/apps/beers/models.py | 8 +- vrobbler/apps/beers/untappd.py | 8 +- vrobbler/apps/boardgames/bgg.py | 4 +- vrobbler/apps/boardgames/models.py | 41 +++------ vrobbler/apps/boardgames/sources/lichess.py | 12 +-- vrobbler/apps/boardgames/views.py | 8 +- vrobbler/apps/books/amazon.py | 28 ++---- vrobbler/apps/books/koreader.py | 26 ++---- vrobbler/apps/books/locg.py | 17 +--- .../commands/cleanup_book_scrobble_times.py | 4 +- .../commands/migrate_koreader_data_to_json.py | 11 +-- vrobbler/apps/books/models.py | 45 +++------- vrobbler/apps/books/openlibrary.py | 8 +- vrobbler/apps/books/sources/comicvine.py | 16 +--- vrobbler/apps/books/sources/google.py | 18 ++-- vrobbler/apps/books/sources/semantic.py | 12 +-- vrobbler/apps/books/tests/conftest.py | 4 +- vrobbler/apps/books/tests/test_koreader.py | 8 +- vrobbler/apps/bricksets/models.py | 4 +- .../commands/copy_chartrecord_data.py | 6 +- vrobbler/apps/foods/allrecipe.py | 8 +- vrobbler/apps/foods/models.py | 36 ++------ vrobbler/apps/foods/sources/rscraper.py | 8 +- vrobbler/apps/foods/sources/usda.py | 54 +++--------- vrobbler/apps/lifeevents/models.py | 10 +-- vrobbler/apps/lifeevents/urls.py | 4 +- vrobbler/apps/locations/models.py | 12 +-- vrobbler/apps/locations/tests/test_models.py | 20 ++--- vrobbler/apps/music/models.py | 88 ++++++------------- vrobbler/apps/music/musicbrainz.py | 34 +++---- vrobbler/apps/music/theaudiodb.py | 20 +++-- vrobbler/apps/music/utils.py | 8 +- vrobbler/apps/people/urls.py | 4 +- vrobbler/apps/podcasts/models.py | 8 +- .../apps/podcasts/sources/podcastindex.py | 4 +- vrobbler/apps/podcasts/utils.py | 15 +--- vrobbler/apps/profiles/constants.py | 4 +- vrobbler/apps/profiles/urls.py | 4 +- vrobbler/apps/profiles/utils.py | 12 +-- vrobbler/apps/puzzles/models.py | 8 +- vrobbler/apps/puzzles/sources/ipdb.py | 25 ++---- vrobbler/apps/scrobbles/admin.py | 5 +- vrobbler/apps/scrobbles/api/serializers.py | 4 +- vrobbler/apps/scrobbles/export.py | 4 +- vrobbler/apps/scrobbles/forms.py | 12 +-- vrobbler/apps/scrobbles/importers/imap.py | 8 +- vrobbler/apps/scrobbles/importers/lastfm.py | 14 ++- vrobbler/apps/scrobbles/importers/webdav.py | 4 +- .../commands/delete_zombie_scrobbles.py | 4 +- .../commands/migrate_scrobble_log_to_json.py | 4 +- vrobbler/apps/scrobbles/notifications.py | 10 +-- vrobbler/apps/scrobbles/utils.py | 30 ++----- vrobbler/apps/sports/models.py | 16 ++-- vrobbler/apps/sports/thesportsdb.py | 4 +- vrobbler/apps/tasks/utils.py | 12 +-- vrobbler/apps/tasks/webhooks.py | 20 ++--- vrobbler/apps/trails/models.py | 6 +- vrobbler/apps/videogames/howlongtobeat.py | 4 +- vrobbler/apps/videogames/igdb.py | 10 +-- vrobbler/apps/videogames/models.py | 12 +-- vrobbler/apps/videogames/retroarch.py | 8 +- vrobbler/apps/videogames/scrapers.py | 4 +- vrobbler/apps/videogames/utils.py | 8 +- vrobbler/apps/videos/api/serializers.py | 4 +- .../videos/management/commands/find_video.py | 14 ++- .../apps/videos/sources/skatevideosite.py | 4 +- vrobbler/apps/videos/sources/tmdb.py | 4 +- vrobbler/apps/videos/sources/youtube.py | 8 +- vrobbler/apps/videos/utils.py | 4 +- vrobbler/apps/videos/views.py | 13 +-- vrobbler/apps/webpages/models.py | 14 ++- vrobbler/apps/webpages/views.py | 20 +---- vrobbler/health_check.py | 4 +- vrobbler/settings.py | 36 ++------ 83 files changed, 310 insertions(+), 786 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 93545d1..6f1395c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ testpaths = ["tests"] DJANGO_SETTINGS_MODULE='vrobbler.settings-testing' [tool.black] -line-length = 79 +line-length = 88 target-version = ["py39", "py310"] include = ".py$" exclude = "migrations" diff --git a/tests/foods_tests/test_recipe_scraper.py b/tests/foods_tests/test_recipe_scraper.py index 0a70f16..e39701c 100644 --- a/tests/foods_tests/test_recipe_scraper.py +++ b/tests/foods_tests/test_recipe_scraper.py @@ -93,41 +93,29 @@ class TestRecipeScraperService: assert result is True def test_scrape_returns_title(self, scraper): - result = scraper.scrape( - RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe" - ) + result = scraper.scrape(RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe") assert result["title"] == "Test Recipe" def test_scrape_returns_ingredients(self, scraper): - result = scraper.scrape( - RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe" - ) + result = scraper.scrape(RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe") assert len(result["ingredients"]) == 3 assert "1 cup flour" in result["ingredients"] def test_scrape_returns_instructions(self, scraper): - result = scraper.scrape( - RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe" - ) + result = scraper.scrape(RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe") assert len(result["instructions"]) > 0 assert "Mix ingredients together" in result["instructions"] def test_scrape_returns_yields(self, scraper): - result = scraper.scrape( - RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe" - ) + result = scraper.scrape(RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe") assert result["yields"] == "4 servings" def test_scrape_returns_total_time(self, scraper): - result = scraper.scrape( - RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe" - ) + result = scraper.scrape(RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe") assert result["total_time"] == 30 def test_scrape_returns_url(self, scraper): - result = scraper.scrape( - RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe" - ) + result = scraper.scrape(RECIPE_HTML_WITH_SCHEMA, "https://example.com/recipe") assert result["url"] == "https://example.com/recipe" def test_scrape_raises_on_invalid_html(self, scraper): diff --git a/tests/foods_tests/test_usda.py b/tests/foods_tests/test_usda.py index bb22e41..1e11efc 100644 --- a/tests/foods_tests/test_usda.py +++ b/tests/foods_tests/test_usda.py @@ -9,9 +9,7 @@ from foods.sources.usda import ( class TestUSDAFoodAPI: @pytest.fixture def usda_api(self): - with patch( - "vrobbler.apps.foods.sources.usda.settings" - ) as mock_settings: + with patch("vrobbler.apps.foods.sources.usda.settings") as mock_settings: mock_settings.USDA_API_KEY = "test_api_key" return USDAFoodAPI(api_key="test_api_key") diff --git a/tests/podcasts_tests/test_scrapers.py b/tests/podcasts_tests/test_scrapers.py index 52eb155..8266030 100644 --- a/tests/podcasts_tests/test_scrapers.py +++ b/tests/podcasts_tests/test_scrapers.py @@ -1,9 +1,7 @@ import pytest from vrobbler.apps.podcasts.scrapers import scrape_data_from_google_podcasts -expected_desc_snippet = ( - "NPR's Up First is the news you need to start your day. " -) +expected_desc_snippet = "NPR's Up First is the news you need to start your day. " expected_img_url = "https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcR1F0CfR24RR6sme531yIkCrnK4zzmo97jeualO5drVPKG6oCk" expected_google_url = "https://podcasts.google.com/feed/aHR0cHM6Ly9mZWVkcy5ucHIub3JnLzUxMDMxOC9wb2RjYXN0LnhtbA" diff --git a/tests/scrobbles_tests/conftest.py b/tests/scrobbles_tests/conftest.py index 93d2d97..580ff15 100644 --- a/tests/scrobbles_tests/conftest.py +++ b/tests/scrobbles_tests/conftest.py @@ -68,9 +68,7 @@ class MopidyRequest: "artist": kwargs.get("artist", self.artist), "album": kwargs.get("album", self.album), "track_number": int(kwargs.get("track_number", self.track_number)), - "run_time_ticks": int( - kwargs.get("run_time_ticks", self.run_time_ticks) - ), + "run_time_ticks": int(kwargs.get("run_time_ticks", self.run_time_ticks)), "run_time": int(kwargs.get("run_time", self.run_time)), "playback_time_ticks": int( kwargs.get("playback_time_ticks", self.playback_time_ticks) @@ -113,9 +111,7 @@ def mopidy_track(): @pytest.fixture def mopidy_track_diff_album_request_data(**kwargs): mb_album_id = "0c56c457-afe1-4679-baab-759ba8dd2a58" - return MopidyRequest( - album="Gold", musicbrainz_album_id=mb_album_id - ).request_json + return MopidyRequest(album="Gold", musicbrainz_album_id=mb_album_id).request_json @pytest.fixture diff --git a/tests/scrobbles_tests/test_utils.py b/tests/scrobbles_tests/test_utils.py index 57444cd..e1d1b07 100644 --- a/tests/scrobbles_tests/test_utils.py +++ b/tests/scrobbles_tests/test_utils.py @@ -6,7 +6,5 @@ from vrobbler.apps.scrobbles.utils import timestamp_user_tz_to_utc def test_timestamp_user_tz_to_utc(): - timestamp = timestamp_user_tz_to_utc( - 1685561082, pytz.timezone("US/Eastern") - ) + timestamp = timestamp_user_tz_to_utc(1685561082, pytz.timezone("US/Eastern")) assert timestamp == datetime(2023, 5, 31, 23, 24, 42, tzinfo=pytz.utc) diff --git a/tests/scrobbles_tests/test_views.py b/tests/scrobbles_tests/test_views.py index 6d7b9ee..efba927 100644 --- a/tests/scrobbles_tests/test_views.py +++ b/tests/scrobbles_tests/test_views.py @@ -498,9 +498,7 @@ def test_scrobble_detail_view_with_notes_as_flat_list(client): user = get_user_model().objects.create_user( username="testuser", email="test@example.com", password="testpass" ) - task = Task.objects.create( - title="Test Task", description="Test description" - ) + task = Task.objects.create(title="Test Task", description="Test description") scrobble = Scrobble.objects.create( task=task, media_type="Task", @@ -522,9 +520,7 @@ def test_scrobble_detail_view_with_notes_as_dict_timestamps(client): user = get_user_model().objects.create_user( username="testuser", email="test@example.com", password="testpass" ) - task = Task.objects.create( - title="Test Task", description="Test description" - ) + task = Task.objects.create(title="Test Task", description="Test description") scrobble = Scrobble.objects.create( task=task, media_type="Task", @@ -552,9 +548,7 @@ def test_scrobble_detail_view_with_notes_and_labels(client): user = get_user_model().objects.create_user( username="testuser", email="test@example.com", password="testpass" ) - task = Task.objects.create( - title="Test Task", description="Test description" - ) + task = Task.objects.create(title="Test Task", description="Test description") scrobble = Scrobble.objects.create( task=task, media_type="Task", @@ -580,9 +574,7 @@ def test_scrobble_detail_view_post_updates_log(client): user = get_user_model().objects.create_user( username="testuser", email="test@example.com", password="testpass" ) - task = Task.objects.create( - title="Test Task", description="Test description" - ) + task = Task.objects.create(title="Test Task", description="Test description") scrobble = Scrobble.objects.create( task=task, media_type="Task", diff --git a/tests/test_context_processors.py b/tests/test_context_processors.py index f81f739..a0961f8 100644 --- a/tests/test_context_processors.py +++ b/tests/test_context_processors.py @@ -14,9 +14,7 @@ def mock_request(): class TestVersionInfo: def test_returns_version_and_commit(self, mock_request): with ( - patch( - "vrobbler.context_processors.get_version" - ) as mock_get_version, + patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, @@ -32,9 +30,7 @@ class TestVersionInfo: def test_uses_env_commit_if_set(self, mock_request): with ( patch.dict(os.environ, {"VROBBLER_COMMIT": "env_commit_hash"}), - patch( - "vrobbler.context_processors.get_version" - ) as mock_get_version, + patch("vrobbler.context_processors.get_version") as mock_get_version, ): mock_get_version.return_value = "1.0.0" @@ -44,9 +40,7 @@ class TestVersionInfo: def test_returns_unknown_when_version_fails(self, mock_request): with ( - patch( - "vrobbler.context_processors.get_version" - ) as mock_get_version, + patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, @@ -62,9 +56,7 @@ class TestVersionInfo: import subprocess with ( - patch( - "vrobbler.context_processors.get_version" - ) as mock_get_version, + patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, @@ -80,9 +72,7 @@ class TestVersionInfo: import subprocess with ( - patch( - "vrobbler.context_processors.get_version" - ) as mock_get_version, + patch("vrobbler.context_processors.get_version") as mock_get_version, patch( "vrobbler.context_processors.subprocess.check_output" ) as mock_check_output, diff --git a/tests/videos_tests/test_api.py b/tests/videos_tests/test_api.py index 895dbdb..6499bb6 100644 --- a/tests/videos_tests/test_api.py +++ b/tests/videos_tests/test_api.py @@ -48,12 +48,8 @@ class TestVideoAPI: assert response.status_code == 200 assert response.data["title"] == "Test Video" - def test_filter_videos_by_channel( - self, client, auth_headers, channel, video - ): - response = client.get( - f"/api/v1/videos/?channel={channel.id}", **auth_headers - ) + def test_filter_videos_by_channel(self, client, auth_headers, channel, video): + response = client.get(f"/api/v1/videos/?channel={channel.id}", **auth_headers) assert response.status_code == 200 assert len(response.data["results"]) == 1 assert response.data["results"][0]["channel"] == channel.id @@ -68,9 +64,7 @@ class TestChannelAPI: assert response.data["results"][0]["name"] == "Test Channel" def test_get_channel(self, client, auth_headers, channel): - response = client.get( - f"/api/v1/channels/{channel.id}/", **auth_headers - ) + response = client.get(f"/api/v1/channels/{channel.id}/", **auth_headers) assert response.status_code == 200 assert response.data["name"] == "Test Channel" diff --git a/vrobbler/apps/beers/models.py b/vrobbler/apps/beers/models.py index ac9a3d3..8e24994 100644 --- a/vrobbler/apps/beers/models.py +++ b/vrobbler/apps/beers/models.py @@ -67,9 +67,7 @@ class Beer(ScrobblableMixin): ) untappd_id = models.CharField(max_length=255, **BNULL) untappd_rating = models.FloatField(**BNULL) - producer = models.ForeignKey( - BeerProducer, on_delete=models.DO_NOTHING, **BNULL - ) + producer = models.ForeignKey(BeerProducer, on_delete=models.DO_NOTHING, **BNULL) def get_absolute_url(self) -> str: return reverse("beers:beer_detail", kwargs={"slug": self.uuid}) @@ -130,9 +128,7 @@ class Beer(ScrobblableMixin): ) style_ids.append(style_inst.id) - producer, _created = BeerProducer.objects.get_or_create( - **producer_dict - ) + producer, _created = BeerProducer.objects.get_or_create(**producer_dict) beer_dict["producer_id"] = producer.id beer = Beer.objects.create(**beer_dict) for style_id in style_ids: diff --git a/vrobbler/apps/beers/untappd.py b/vrobbler/apps/beers/untappd.py index 639fb62..ff77e19 100644 --- a/vrobbler/apps/beers/untappd.py +++ b/vrobbler/apps/beers/untappd.py @@ -85,9 +85,7 @@ def get_ibu_from_soup(soup) -> Optional[int]: def get_rating_from_soup(soup) -> str: rating = "" try: - rating = float( - soup.find(class_="num").get_text().strip("(").strip(")") - ) + rating = float(soup.find(class_="num").get_text().strip("(").strip(")")) except AttributeError: rating = None except ValueError: @@ -124,9 +122,7 @@ def get_beer_from_untappd_id(untappd_id: str) -> dict: beer_dict = {"untappd_id": untappd_id} if response.status_code != 200: - logger.warn( - "Bad response from untappd.com", extra={"response": response} - ) + logger.warn("Bad response from untappd.com", extra={"response": response}) return beer_dict soup = BeautifulSoup(response.text, "html.parser") diff --git a/vrobbler/apps/boardgames/bgg.py b/vrobbler/apps/boardgames/bgg.py index bb1c07e..94802fc 100644 --- a/vrobbler/apps/boardgames/bgg.py +++ b/vrobbler/apps/boardgames/bgg.py @@ -14,9 +14,7 @@ if TYPE_CHECKING: logger = logging.getLogger(__name__) -SEARCH_ID_URL = ( - "https://boardgamegeek.com/xmlapi/search?search={query}&exact=1" -) +SEARCH_ID_URL = "https://boardgamegeek.com/xmlapi/search?search={query}&exact=1" GAME_ID_URL = "https://boardgamegeek.com/xmlapi/boardgame/{id}" BGG_ACCESS_TOKEN = getattr(settings, "BGG_ACCESS_TOKEN", "") BASE_HEADERS = { diff --git a/vrobbler/apps/boardgames/models.py b/vrobbler/apps/boardgames/models.py index 17cdcb4..851e822 100644 --- a/vrobbler/apps/boardgames/models.py +++ b/vrobbler/apps/boardgames/models.py @@ -99,10 +99,7 @@ class BoardGameLogData(BaseLogData, LongPlayLogData): def player_log(self) -> str: if self.players: return ", ".join( - [ - BoardGameScoreLogData(**player).__str__() - for player in self.players - ] + [BoardGameScoreLogData(**player).__str__() for player in self.players] ) return "" @@ -134,9 +131,7 @@ class BoardGamePublisher(TimeStampedModel): return self.name def get_absolute_url(self): - return reverse( - "boardgames:publisher_detail", kwargs={"slug": self.uuid} - ) + return reverse("boardgames:publisher_detail", kwargs={"slug": self.uuid}) class BoardGameDesigner(TimeStampedModel): @@ -149,9 +144,7 @@ class BoardGameDesigner(TimeStampedModel): return str(self.name) def get_absolute_url(self): - return reverse( - "boardgames:designer_detail", kwargs={"slug": self.uuid} - ) + return reverse("boardgames:designer_detail", kwargs={"slug": self.uuid}) class BoardGameLocation(TimeStampedModel): @@ -159,23 +152,17 @@ class BoardGameLocation(TimeStampedModel): uuid = models.UUIDField(default=uuid4, editable=False, **BNULL) bgstats_id = models.UUIDField(**BNULL) description = models.TextField(**BNULL) - geo_location = models.ForeignKey( - GeoLocation, **BNULL, on_delete=models.DO_NOTHING - ) + geo_location = models.ForeignKey(GeoLocation, **BNULL, on_delete=models.DO_NOTHING) def __str__(self) -> str: return str(self.name) def get_absolute_url(self): - return reverse( - "boardgames:location_detail", kwargs={"slug": self.uuid} - ) + return reverse("boardgames:location_detail", kwargs={"slug": self.uuid}) class BoardGame(ScrobblableMixin): - COMPLETION_PERCENT = getattr( - settings, "BOARD_GAME_COMPLETION_PERCENT", 100 - ) + COMPLETION_PERCENT = getattr(settings, "BOARD_GAME_COMPLETION_PERCENT", 100) FIELDS_FROM_BGGEEK = [ "igdb_id", @@ -250,9 +237,7 @@ class BoardGame(ScrobblableMixin): return self.title def get_absolute_url(self): - return reverse( - "boardgames:boardgame_detail", kwargs={"slug": self.uuid} - ) + return reverse("boardgames:boardgame_detail", kwargs={"slug": self.uuid}) @property def logdata_cls(self): @@ -316,9 +301,7 @@ class BoardGame(ScrobblableMixin): self.cover.save(fname, ContentFile(r.content), save=True) @classmethod - def find_or_create( - cls, lookup_id: str, data: dict[str, Any] = {} - ) -> "BoardGame": + def find_or_create(cls, lookup_id: str, data: dict[str, Any] = {}) -> "BoardGame": """Given a Lookup ID (either BGG or BGA ID), return a board game object""" game = cls.objects.filter(bggeek_id=lookup_id).first() if not game: @@ -354,9 +337,7 @@ class BoardGame(ScrobblableMixin): game.uses_teams = data.get("useTeams", False) game.bgstats_id = data.get("uuid", None) if publisher: - publisher, _ = BoardGamePublisher.objects.get_or_create( - name=publisher - ) + publisher, _ = BoardGamePublisher.objects.get_or_create(name=publisher) game.publisher = publisher game.save() @@ -369,9 +350,7 @@ class BoardGame(ScrobblableMixin): if publishers: for name in publishers: - publisher, _ = BoardGamePublisher.objects.get_or_create( - name=name - ) + publisher, _ = BoardGamePublisher.objects.get_or_create(name=name) game.publishers.add(publisher) return game diff --git a/vrobbler/apps/boardgames/sources/lichess.py b/vrobbler/apps/boardgames/sources/lichess.py index 63aca95..e3bbfd6 100644 --- a/vrobbler/apps/boardgames/sources/lichess.py +++ b/vrobbler/apps/boardgames/sources/lichess.py @@ -11,9 +11,7 @@ User = get_user_model() def import_chess_games_for_user_id(user_id: int, commit: bool = False) -> dict: user = User.objects.get(id=user_id) - client = berserk.Client( - session=berserk.TokenSession(settings.LICHESS_API_KEY) - ) + client = berserk.Client(session=berserk.TokenSession(settings.LICHESS_API_KEY)) games = client.games.export_by_player(user.profile.lichess_username) for game_dict in games: chess, created = BoardGame.objects.get_or_create(title="Chess") @@ -62,9 +60,7 @@ def import_chess_games_for_user_id(user_id: int, commit: bool = False) -> dict: white_player.get("aiLevel", "") ) else: - other_player["name_str"] = white_player.get("user", {}).get( - "name", "" - ) + other_player["name_str"] = white_player.get("user", {}).get("name", "") other_player["lichess_username"] = other_player["name_str"] other_player["color"] = "white" @@ -82,9 +78,7 @@ def import_chess_games_for_user_id(user_id: int, commit: bool = False) -> dict: black_player.get("aiLevel", "") ) else: - other_player["name_str"] = black_player.get("user", {}).get( - "name", "" - ) + other_player["name_str"] = black_player.get("user", {}).get("name", "") other_player["lichess_username"] = other_player["name_str"] other_player["color"] = "black" if winner == "white": diff --git a/vrobbler/apps/boardgames/views.py b/vrobbler/apps/boardgames/views.py index a1b5076..987680f 100644 --- a/vrobbler/apps/boardgames/views.py +++ b/vrobbler/apps/boardgames/views.py @@ -37,9 +37,7 @@ class BoardGameListView(ScrobbleableListView): for designer in scrobble.board_game.designers.all(): designers_this_week[designer.id] = { "designer": designer, - "count": designers_this_week.get(designer.id, {}).get( - "count", 0 - ) + "count": designers_this_week.get(designer.id, {}).get("count", 0) + 1, } @@ -48,9 +46,7 @@ class BoardGameListView(ScrobbleableListView): for designer in scrobble.board_game.designers.all(): designers_this_month[designer.id] = { "designer": designer, - "count": designers_this_month.get(designer.id, {}).get( - "count", 0 - ) + "count": designers_this_month.get(designer.id, {}).get("count", 0) + 1, } diff --git a/vrobbler/apps/books/amazon.py b/vrobbler/apps/books/amazon.py index 5373c09..1888734 100644 --- a/vrobbler/apps/books/amazon.py +++ b/vrobbler/apps/books/amazon.py @@ -6,9 +6,7 @@ import logging logger = logging.getLogger(__name__) -USER_AGENT = ( - "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0" -) +USER_AGENT = "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0" AMAZON_SEARCH_URL = "https://www.amazon.com/s?k={amazon_id}" @@ -95,32 +93,20 @@ def get_amazon_product_dict(amazon_id: str) -> dict: soup = BeautifulSoup(response.text, "html.parser") try: - data_dict["title"] = soup.findAll("span", class_="celwidget")[ - 1 - ].text.strip() - data_dict["cover_url"] = soup.find("img", class_="frontImage").get( - "src" - ) - data_dict["summary"] = soup.findAll( - "div", class_="a-expander-content" - )[1].text + data_dict["title"] = soup.findAll("span", class_="celwidget")[1].text.strip() + data_dict["cover_url"] = soup.find("img", class_="frontImage").get("src") + data_dict["summary"] = soup.findAll("div", class_="a-expander-content")[1].text meta = soup.findAll("div", class_="rpi-attribute-value") data_dict["isbn"] = meta[AmazonAttribute.ISBN_10.value].text.strip() pages = meta[AmazonAttribute.PAGES.value].text if "pages" in pages: data_dict["pages"] = ( - meta[AmazonAttribute.PAGES.value] - .text.split("pages")[0] - .strip() + meta[AmazonAttribute.PAGES.value].text.split("pages")[0].strip() ) except IndexError as e: - logger.error( - f"Amazon lookup is failing for this product {amazon_id}: {e}" - ) + logger.error(f"Amazon lookup is failing for this product {amazon_id}: {e}") except AttributeError as e: - logger.error( - f"Amazon lookup is failing for this product {amazon_id}: {e}" - ) + logger.error(f"Amazon lookup is failing for this product {amazon_id}: {e}") return data_dict diff --git a/vrobbler/apps/books/koreader.py b/vrobbler/apps/books/koreader.py index e24c0a7..a9d0fad 100644 --- a/vrobbler/apps/books/koreader.py +++ b/vrobbler/apps/books/koreader.py @@ -146,9 +146,7 @@ def build_book_map(rows) -> dict: ) continue book = Book.objects.filter( - koreader_data_by_hash__icontains=book_row[ - KoReaderBookColumn.MD5.value - ] + koreader_data_by_hash__icontains=book_row[KoReaderBookColumn.MD5.value] ).first() if not book: @@ -202,15 +200,11 @@ def build_page_data(page_rows: list, book_map: dict, user_tz=None) -> dict: "end_ts": start_ts + duration, } if book_ids_not_found: - logger.info( - f"Found pages for books not in file: {set(book_ids_not_found)}" - ) + logger.info(f"Found pages for books not in file: {set(book_ids_not_found)}") return book_map -def build_scrobbles_from_book_map( - book_map: dict, user: "User" -) -> list["Scrobble"]: +def build_scrobbles_from_book_map(book_map: dict, user: "User") -> list["Scrobble"]: Scrobble = apps.get_model("scrobbles", "Scrobble") scrobbles_to_create = [] @@ -240,9 +234,9 @@ def build_scrobbles_from_book_map( seconds_from_last_page = 0 if prev_page_stats: - seconds_from_last_page = stats.get( - "end_ts" - ) - prev_page_stats.get("start_ts") + seconds_from_last_page = stats.get("end_ts") - prev_page_stats.get( + "start_ts" + ) playback_position_seconds = playback_position_seconds + stats.get( "duration" @@ -251,9 +245,7 @@ def build_scrobbles_from_book_map( end_of_reading = pages_processed == total_pages_read big_jump_to_this_page = (cur_page_number - last_page_number) > 10 is_session_gap = seconds_from_last_page > SESSION_GAP_SECONDS - if ( - is_session_gap and not big_jump_to_this_page - ) or end_of_reading: + if (is_session_gap and not big_jump_to_this_page) or end_of_reading: should_create_scrobble = True if should_create_scrobble: @@ -381,9 +373,7 @@ def process_koreader_sqlite_file(file_path, user_id) -> list: return new_scrobbles book_map = build_page_data( - cur.execute( - "SELECT * from page_stat_data ORDER BY id_book, start_time" - ), + cur.execute("SELECT * from page_stat_data ORDER BY id_book, start_time"), book_map, tz, ) diff --git a/vrobbler/apps/books/locg.py b/vrobbler/apps/books/locg.py index e7116c4..6510d01 100644 --- a/vrobbler/apps/books/locg.py +++ b/vrobbler/apps/books/locg.py @@ -13,9 +13,7 @@ HEADERS = { } LOCG_WRTIER_URL = "" LOCG_WRITER_DETAIL_URL = "https://leagueofcomicgeeks.com/people/{slug}" -LOCG_SEARCH_URL = ( - "https://leagueofcomicgeeks.com/search/ajax_issues?query={query}" -) +LOCG_SEARCH_URL = "https://leagueofcomicgeeks.com/search/ajax_issues?query={query}" LOCG_DETAIL_URL = "https://leagueofcomicgeeks.com/comic/{locg_slug}" @@ -72,26 +70,19 @@ def lookup_comic_by_locg_slug(slug: str) -> dict: attrs = soup.findAll("div", class_="details-addtl-block") try: data_dict["pages"] = ( - attrs[1] - .find("div", class_="value") - .text.split("pages")[0] - .strip() + attrs[1].find("div", class_="value").text.split("pages")[0].strip() ) except IndexError: logger.warn(f"No ISBN field") try: - data_dict["isbn"] = ( - attrs[3].find("div", class_="value").text.strip() - ) + data_dict["isbn"] = attrs[3].find("div", class_="value").text.strip() except IndexError: logger.warn(f"No ISBN field") writer_slug = None try: writer_slug = ( - soup.findAll("div", class_="name")[5] - .a.get("href") - .split("people/")[1] + soup.findAll("div", class_="name")[5].a.get("href").split("people/")[1] ) except IndexError: logger.warn(f"No wrtier found") diff --git a/vrobbler/apps/books/management/commands/cleanup_book_scrobble_times.py b/vrobbler/apps/books/management/commands/cleanup_book_scrobble_times.py index 5151f78..6dc7f0a 100644 --- a/vrobbler/apps/books/management/commands/cleanup_book_scrobble_times.py +++ b/vrobbler/apps/books/management/commands/cleanup_book_scrobble_times.py @@ -37,7 +37,5 @@ class Command(BaseCommand): def handle(self, *args, **options): scrobbles_to_create = [] - for scrobble in Scrobble.objects.filter( - media_type="Book", source="KOReader" - ): + for scrobble in Scrobble.objects.filter(media_type="Book", source="KOReader"): update_scrobble_from_page_data(scrobble) diff --git a/vrobbler/apps/books/management/commands/migrate_koreader_data_to_json.py b/vrobbler/apps/books/management/commands/migrate_koreader_data_to_json.py index 4f0c826..996eabb 100644 --- a/vrobbler/apps/books/management/commands/migrate_koreader_data_to_json.py +++ b/vrobbler/apps/books/management/commands/migrate_koreader_data_to_json.py @@ -52,8 +52,7 @@ class Command(BaseCommand): seconds_from_last_page = 0 if prev_page: seconds_from_last_page = ( - page.end_time.timestamp() - - prev_page.start_time.timestamp() + page.end_time.timestamp() - prev_page.start_time.timestamp() ) playback_position_seconds = ( playback_position_seconds + page.duration_seconds @@ -62,9 +61,7 @@ class Command(BaseCommand): end_of_reading = pages_processed == total_pages big_jump_to_this_page = False if prev_page: - big_jump_to_this_page = ( - page.number - prev_page.number - ) > 10 + big_jump_to_this_page = (page.number - prev_page.number) > 10 if ( seconds_from_last_page > SESSION_GAP_SECONDS and not big_jump_to_this_page @@ -113,9 +110,7 @@ class Command(BaseCommand): user_id=user.id, ).first() if scrobble: - logger.info( - f"Found existing scrobble {scrobble}, updating" - ) + logger.info(f"Found existing scrobble {scrobble}, updating") scrobble.book_page_data = scrobble_page_data scrobble.playback_position_seconds = ( scrobble.calc_reading_duration() diff --git a/vrobbler/apps/books/models.py b/vrobbler/apps/books/models.py index 08f5905..6aef53e 100644 --- a/vrobbler/apps/books/models.py +++ b/vrobbler/apps/books/models.py @@ -133,9 +133,7 @@ class Author(TimeStampedModel): class Book(LongPlayScrobblableMixin): COMPLETION_PERCENT = getattr(settings, "BOOK_COMPLETION_PERCENT", 95) - AVG_PAGE_READING_SECONDS = getattr( - settings, "AVERAGE_PAGE_READING_SECONDS", 60 - ) + AVG_PAGE_READING_SECONDS = getattr(settings, "AVERAGE_PAGE_READING_SECONDS", 60) title = models.CharField(max_length=255) original_title = models.CharField(max_length=255, **BNULL) @@ -260,9 +258,7 @@ class Book(LongPlayScrobblableMixin): # TODO use either a Google Books id identifier or author name like for tracks book, created = cls.objects.get_or_create(original_title=title) if not created: - logger.info( - "Found exact match for book by title", extra={"title": title} - ) + logger.info("Found exact match for book by title", extra={"title": title}) if not enrich: logger.info( @@ -296,9 +292,7 @@ class Book(LongPlayScrobblableMixin): if authors: for author_str in authors: if author_str: - author, a_created = Author.objects.get_or_create( - name=author_str - ) + author, a_created = Author.objects.get_or_create(name=author_str) author_list.append(author) if a_created: # TODO enrich author @@ -332,13 +326,9 @@ class Book(LongPlayScrobblableMixin): if not data: logger.warn(f"Checking openlibrary for {self.title}") if self.openlibrary_id and force_update: - data = lookup_book_from_openlibrary( - str(self.openlibrary_id) - ) + data = lookup_book_from_openlibrary(str(self.openlibrary_id)) else: - data = lookup_book_from_openlibrary( - str(self.title), author_name - ) + data = lookup_book_from_openlibrary(str(self.title), author_name) if not data: if self.locg_slug: @@ -385,10 +375,7 @@ class Book(LongPlayScrobblableMixin): if "pages" in data.keys() and data.get("pages") == None: data.pop("pages") - if ( - not isinstance(data.get("pages"), int) - and "pages" in data.keys() - ): + if not isinstance(data.get("pages"), int) and "pages" in data.keys(): logger.info( f"Pages for {self} from OL expected to be int, but got {data.get('pages')}" ) @@ -420,9 +407,7 @@ class Book(LongPlayScrobblableMixin): self.save() def fix_authors_metadata(self, openlibrary_author_id): - author = Author.objects.filter( - openlibrary_id=openlibrary_author_id - ).first() + author = Author.objects.filter(openlibrary_id=openlibrary_author_id).first() if not author: data = lookup_author_from_openlibrary(openlibrary_author_id) author_image_url = data.pop("author_headshot_url", None) @@ -433,9 +418,7 @@ class Book(LongPlayScrobblableMixin): r = requests.get(author_image_url) if r.status_code == 200: fname = f"{author.name}_{author.uuid}.jpg" - author.headshot.save( - fname, ContentFile(r.content), save=True - ) + author.headshot.save(fname, ContentFile(r.content), save=True) self.authors.add(author) def get_author_from_locg(self, locg_slug): @@ -451,9 +434,7 @@ class Book(LongPlayScrobblableMixin): author.headshot.save(fname, ContentFile(r.content), save=True) self.authors.add(author) - def page_data_for_user( - self, user_id: int, convert_timestamps: bool = True - ) -> dict: + def page_data_for_user(self, user_id: int, convert_timestamps: bool = True) -> dict: scrobbles = self.scrobble_set.filter(user=user_id) pages = {} @@ -461,9 +442,7 @@ class Book(LongPlayScrobblableMixin): if scrobble.logdata.page_data: for page, data in scrobble.logdata.page_data.items(): if convert_timestamps: - data["start_ts"] = datetime.fromtimestamp( - data["start_ts"] - ) + data["start_ts"] = datetime.fromtimestamp(data["start_ts"]) data["end_ts"] = datetime.fromtimestamp(data["end_ts"]) pages[page] = data sorted_pages = OrderedDict( @@ -502,9 +481,7 @@ class Paper(LongPlayScrobblableMixin): """Keeps track of Academic Papers""" COMPLETION_PERCENT = getattr(settings, "PAPER_COMPLETION_PERCENT", 60) - AVG_PAGE_READING_SECONDS = getattr( - settings, "AVERAGE_PAGE_READING_SECONDS", 60 - ) + AVG_PAGE_READING_SECONDS = getattr(settings, "AVERAGE_PAGE_READING_SECONDS", 60) title = models.CharField(max_length=255) semantic_title = models.CharField(max_length=255, **BNULL) diff --git a/vrobbler/apps/books/openlibrary.py b/vrobbler/apps/books/openlibrary.py index f213859..42ae640 100644 --- a/vrobbler/apps/books/openlibrary.py +++ b/vrobbler/apps/books/openlibrary.py @@ -10,7 +10,9 @@ from thefuzz import fuzz logger = logging.getLogger(__name__) ISBN_URL = "https://openlibrary.org/isbn/{isbn}.json" -SEARCH_URL = "https://openlibrary.org/search.json?q={query}&sort=editions&mode=everything" +SEARCH_URL = ( + "https://openlibrary.org/search.json?q={query}&sort=editions&mode=everything" +) AUTHOR_SEARCH_URL = "https://openlibrary.org/search/authors.json?q={query}" COVER_URL = "https://covers.openlibrary.org/b/olid/{id}-L.jpg" AUTHOR_URL = "https://openlibrary.org/authors/{id}.json" @@ -80,9 +82,7 @@ def lookup_author_from_openlibrary(olid: str) -> dict: } -def lookup_book_from_openlibrary( - title: str, author: Optional[str] = None -) -> dict: +def lookup_book_from_openlibrary(title: str, author: Optional[str] = None) -> dict: title_quoted = urllib.parse.quote(title) author_quoted = "" if author: diff --git a/vrobbler/apps/books/sources/comicvine.py b/vrobbler/apps/books/sources/comicvine.py index 601392f..cd81391 100644 --- a/vrobbler/apps/books/sources/comicvine.py +++ b/vrobbler/apps/books/sources/comicvine.py @@ -160,9 +160,7 @@ class ComicVineClient(object): # or not the request cache is to be used, store the procedure in a # local function to avoid repetition. def __httpget(): - response = requests.get( - self.API_URL, headers=self.HEADERS, params=params - ) + response = requests.get(self.API_URL, headers=self.HEADERS, params=params) if not response.ok: self._handle_http_error(response) @@ -214,19 +212,13 @@ def lookup_comic_from_comicvine(title: str) -> dict: api_key = getattr(settings, "COMICVINE_API_KEY", "") if not api_key: - logger.warning( - "No ComicVine API key configured, not looking anything up" - ) + logger.warning("No ComicVine API key configured, not looking anything up") return {} - client = ComicVineClient( - api_key=getattr(settings, "COMICVINE_API_KEY", None) - ) + client = ComicVineClient(api_key=getattr(settings, "COMICVINE_API_KEY", None)) raw_results = client.search(title).get("results") - results = [ - r for r in raw_results if r.get("resource_type") == resource_type - ] + results = [r for r in raw_results if r.get("resource_type") == resource_type] if not results: logger.warning("No comic found on ComicVine") return {} diff --git a/vrobbler/apps/books/sources/google.py b/vrobbler/apps/books/sources/google.py index e880912..5b11538 100644 --- a/vrobbler/apps/books/sources/google.py +++ b/vrobbler/apps/books/sources/google.py @@ -6,9 +6,7 @@ import requests from django.conf import settings API_KEY = settings.GOOGLE_API_KEY -GOOGLE_BOOKS_URL = ( - 'https://www.googleapis.com/books/v1/volumes?q="{title}"&key={key}' -) +GOOGLE_BOOKS_URL = 'https://www.googleapis.com/books/v1/volumes?q="{title}"&key={key}' logger = logging.getLogger(__name__) @@ -21,14 +19,10 @@ def lookup_book_from_google(title: str) -> dict: response = requests.get(url, headers=headers) if response.status_code != 200: - logger.warning( - "Bad response from Google", extra={"response": response} - ) + logger.warning("Bad response from Google", extra={"response": response}) return book_dict - google_result = ( - json.loads(response.content).get("items", [{}])[0].get("volumeInfo") - ) + google_result = json.loads(response.content).get("items", [{}])[0].get("volumeInfo") if not google_result: return {} @@ -69,8 +63,8 @@ def lookup_book_from_google(title: str) -> dict: book_dict["base_run_time_seconds"] = 3600 if book_dict.get("pages"): - book_dict["base_run_time_seconds"] = book_dict.get( - "pages", 10 - ) * getattr(settings, "AVERAGE_PAGE_READING_SECONDS", 60) + book_dict["base_run_time_seconds"] = book_dict.get("pages", 10) * getattr( + settings, "AVERAGE_PAGE_READING_SECONDS", 60 + ) return book_dict diff --git a/vrobbler/apps/books/sources/semantic.py b/vrobbler/apps/books/sources/semantic.py index a67ebe2..bfd63e4 100644 --- a/vrobbler/apps/books/sources/semantic.py +++ b/vrobbler/apps/books/sources/semantic.py @@ -18,9 +18,7 @@ def get_api_result(url): response = requests.get(url, headers=headers) if response.status_code != 200: - logger.warning( - "Bad response from Semantic", extra={"response": response} - ) + logger.warning("Bad response from Semantic", extra={"response": response}) return None return response @@ -64,12 +62,10 @@ def lookup_paper_from_semantic(title: str) -> dict: paper_dict["tldr"] = result.get("bib", {}).get("abstract") paper_dict["journal"] = result.get("journal", {}).get("name") paper_dict["journal_volume"] = result.get("journal", {}).get("volume") - paper_dict["openaccess_pdf_url"] = result.get("openAccessPdf", {}).get( - "url" + paper_dict["openaccess_pdf_url"] = result.get("openAccessPdf", {}).get("url") + paper_dict["base_run_time_seconds"] = paper_dict.get("pages", 10) * getattr( + settings, "AVERAGE_PAGE_READING_SECONDS", 60 ) - paper_dict["base_run_time_seconds"] = paper_dict.get( - "pages", 10 - ) * getattr(settings, "AVERAGE_PAGE_READING_SECONDS", 60) paper_dict["author_dicts"] = result.get("authors") paper_dict["genres"] = result.get("fieldsOfStudy") diff --git a/vrobbler/apps/books/tests/conftest.py b/vrobbler/apps/books/tests/conftest.py index fb87337..ca5a683 100644 --- a/vrobbler/apps/books/tests/conftest.py +++ b/vrobbler/apps/books/tests/conftest.py @@ -99,7 +99,9 @@ class KoReaderBookRows: ] ) if end_session: - start_time += 3600 # one second over an hour, marking a new reading session + start_time += ( + 3600 # one second over an hour, marking a new reading session + ) end_session = False else: start_time += AVERAGE_PAGE_READING_SECONDS diff --git a/vrobbler/apps/books/tests/test_koreader.py b/vrobbler/apps/books/tests/test_koreader.py index 76988ba..b45baa8 100644 --- a/vrobbler/apps/books/tests/test_koreader.py +++ b/vrobbler/apps/books/tests/test_koreader.py @@ -32,17 +32,13 @@ def test_load_page_data_to_map(get_mock, koreader_rows, valid_response): ) assert ( len(book_map[1]["pages"]) - == koreader_rows.BOOK_ROWS[0][ - KoReaderBookColumn.TOTAL_READ_PAGES.value - ] + == koreader_rows.BOOK_ROWS[0][KoReaderBookColumn.TOTAL_READ_PAGES.value] ) @pytest.mark.django_db @mock.patch("requests.get") -def test_build_scrobbles_from_pages( - get_mock, koreader_rows, demo_user, valid_response -): +def test_build_scrobbles_from_pages(get_mock, koreader_rows, demo_user, valid_response): get_mock.return_value = valid_response book_map = build_book_map(koreader_rows.BOOK_ROWS) book_map = build_page_data(koreader_rows.PAGE_STATS_ROWS, book_map) diff --git a/vrobbler/apps/bricksets/models.py b/vrobbler/apps/bricksets/models.py index 1728f10..3c37fe8 100644 --- a/vrobbler/apps/bricksets/models.py +++ b/vrobbler/apps/bricksets/models.py @@ -26,9 +26,7 @@ class BrickSet(LongPlayScrobblableMixin): number = models.CharField(max_length=10, **BNULL) release_year = models.IntegerField(**BNULL) piece_count = models.IntegerField(**BNULL) - brickset_rating = models.DecimalField( - max_digits=3, decimal_places=1, **BNULL - ) + brickset_rating = models.DecimalField(max_digits=3, decimal_places=1, **BNULL) lego_item_number = models.CharField(max_length=10, **BNULL) box_image = models.ImageField(upload_to="brickset/boxes/", **BNULL) box_image_small = ImageSpecField( diff --git a/vrobbler/apps/charts/management/commands/copy_chartrecord_data.py b/vrobbler/apps/charts/management/commands/copy_chartrecord_data.py index a8aff61..0374d1d 100644 --- a/vrobbler/apps/charts/management/commands/copy_chartrecord_data.py +++ b/vrobbler/apps/charts/management/commands/copy_chartrecord_data.py @@ -7,14 +7,16 @@ class Command(BaseCommand): def handle(self, *args, **options): with connection.cursor() as cursor: - cursor.execute(""" + cursor.execute( + """ INSERT OR IGNORE INTO charts_chartrecord (created, modified, user_id, rank, count, year, month, week, day, video_id, series_id, artist_id, track_id, period_start, period_end) SELECT created, modified, user_id, rank, count, year, month, week, day, video_id, series_id, artist_id, track_id, period_start, period_end FROM scrobbles_chartrecord - """) + """ + ) self.stdout.write( self.style.SUCCESS("Copied ChartRecord data to charts app") ) diff --git a/vrobbler/apps/foods/allrecipe.py b/vrobbler/apps/foods/allrecipe.py index b812b41..f4f74ba 100644 --- a/vrobbler/apps/foods/allrecipe.py +++ b/vrobbler/apps/foods/allrecipe.py @@ -87,9 +87,7 @@ def get_ibu_from_soup(soup) -> Optional[int]: def get_rating_from_soup(soup) -> str: rating = "" try: - rating = float( - soup.find(class_="num").get_text().strip("(").strip(")") - ) + rating = float(soup.find(class_="num").get_text().strip("(").strip(")")) except AttributeError: rating = None except ValueError: @@ -127,9 +125,7 @@ def get_food_from_allrecipe_id(allrecipe_id: str) -> dict: food_dict = {"allrecipe_id": allrecipe_id} if response.status_code != 200: - logger.warn( - "Bad response from allrecipe", extra={"response": response} - ) + logger.warn("Bad response from allrecipe", extra={"response": response}) return food_dict import pdb diff --git a/vrobbler/apps/foods/models.py b/vrobbler/apps/foods/models.py index 8bb0b50..2371252 100644 --- a/vrobbler/apps/foods/models.py +++ b/vrobbler/apps/foods/models.py @@ -63,17 +63,13 @@ class Food(ScrobblableMixin): cook_time_minutes = models.IntegerField(**BNULL) total_time_minutes = models.IntegerField(**BNULL) servings = models.IntegerField(**BNULL) - yield_text = models.CharField( - max_length=255, **BNULL - ) # e.g., "8 calzones" + yield_text = models.CharField(max_length=255, **BNULL) # e.g., "8 calzones" # Nutrition (per serving) calories = models.IntegerField(**BNULL) protein = models.DecimalField(max_digits=10, decimal_places=2, **BNULL) fat = models.DecimalField(max_digits=10, decimal_places=2, **BNULL) - carbohydrates = models.DecimalField( - max_digits=10, decimal_places=2, **BNULL - ) + carbohydrates = models.DecimalField(max_digits=10, decimal_places=2, **BNULL) fiber = models.DecimalField(max_digits=10, decimal_places=2, **BNULL) sugar = models.DecimalField(max_digits=10, decimal_places=2, **BNULL) sodium = models.DecimalField(max_digits=10, decimal_places=2, **BNULL) @@ -93,9 +89,7 @@ class Food(ScrobblableMixin): ) allrecipe_id = models.CharField(max_length=255, **BNULL) allrecipe_rating = models.FloatField(**BNULL) - category = models.ForeignKey( - FoodCategory, on_delete=models.DO_NOTHING, **BNULL - ) + category = models.ForeignKey(FoodCategory, on_delete=models.DO_NOTHING, **BNULL) class Meta: indexes = [ @@ -136,9 +130,7 @@ class Food(ScrobblableMixin): return FoodLogData @classmethod - def find_or_create_from_recipe( - cls, url: str, category=None - ) -> Tuple["Food", bool]: + def find_or_create_from_recipe(cls, url: str, category=None) -> Tuple["Food", bool]: """ Scrape a recipe URL and create/update Food instance. Uses django-taggit for tags and existing FoodCategory for category. @@ -164,16 +156,12 @@ class Food(ScrobblableMixin): nutrition = recipe_data.get("nutrition") if not nutrition: calculator = NutritionCalculator() - servings = ( - scraper.parse_servings(recipe_data.get("yields", "1")) or 1 - ) + servings = scraper.parse_servings(recipe_data.get("yields", "1")) or 1 nutrition = calculator.calculate_nutrition( recipe_data.get("ingredients", []), servings ) else: - servings = ( - scraper.parse_servings(recipe_data.get("yields", "1")) or 1 - ) + servings = scraper.parse_servings(recipe_data.get("yields", "1")) or 1 # Get or create category (if not provided) if not category and recipe_data.get("category"): @@ -198,9 +186,7 @@ class Food(ScrobblableMixin): calories=int(nutrition.get("calories", 0)) if nutrition else None, protein=nutrition.get("protein") if nutrition else None, fat=nutrition.get("fat") if nutrition else None, - carbohydrates=( - nutrition.get("carbohydrates") if nutrition else None - ), + carbohydrates=(nutrition.get("carbohydrates") if nutrition else None), fiber=nutrition.get("fiber") if nutrition else None, category=category, ) @@ -246,9 +232,7 @@ class Food(ScrobblableMixin): calories=int(nutrition.get("calories", 0)) if nutrition else None, protein=nutrition.get("protein") if nutrition else None, fat=nutrition.get("fat") if nutrition else None, - carbohydrates=( - nutrition.get("carbohydrates") if nutrition else None - ), + carbohydrates=(nutrition.get("carbohydrates") if nutrition else None), fiber=nutrition.get("fiber") if nutrition else None, category=category, ) @@ -263,9 +247,7 @@ class Food(ScrobblableMixin): try: ingredients = json.loads(self.ingredients) calculator = NutritionCalculator() - nutrition = calculator.calculate_nutrition( - ingredients, self.servings or 1 - ) + nutrition = calculator.calculate_nutrition(ingredients, self.servings or 1) self.calories = int(nutrition.get("calories", 0)) self.protein = nutrition.get("protein") diff --git a/vrobbler/apps/foods/sources/rscraper.py b/vrobbler/apps/foods/sources/rscraper.py index 317f8aa..de3f804 100644 --- a/vrobbler/apps/foods/sources/rscraper.py +++ b/vrobbler/apps/foods/sources/rscraper.py @@ -87,9 +87,7 @@ class RecipeScraperService: response = requests.get( url, timeout=10, - headers={ - "User-Agent": "Mozilla/5.0 (compatible; Vrobbler/0.3)" - }, + headers={"User-Agent": "Mozilla/5.0 (compatible; Vrobbler/0.3)"}, ) if response.status_code != 200: logger.debug("Recipe website returned non 200 response") @@ -181,9 +179,7 @@ class RecipeScraperService: keywords = recipe_data.get("keywords") if keywords: if isinstance(keywords, str): - tags.update( - [k.strip() for k in keywords.split(",") if k.strip()] - ) + tags.update([k.strip() for k in keywords.split(",") if k.strip()]) elif isinstance(keywords, list): tags.update([k.strip() for k in keywords if k.strip()]) diff --git a/vrobbler/apps/foods/sources/usda.py b/vrobbler/apps/foods/sources/usda.py index 4d1d5c5..5ab446d 100644 --- a/vrobbler/apps/foods/sources/usda.py +++ b/vrobbler/apps/foods/sources/usda.py @@ -110,22 +110,14 @@ class USDAFoodAPI: if "nutrientNumber" in nutrient: nutrient_id = str(nutrient.get("nutrientNumber", "")) value = nutrient.get("value") - elif "nutrient" in nutrient and isinstance( - nutrient["nutrient"], dict - ): - nutrient_id = str( - nutrient.get("nutrient", {}).get("id", "") - ) + elif "nutrient" in nutrient and isinstance(nutrient["nutrient"], dict): + nutrient_id = str(nutrient.get("nutrient", {}).get("id", "")) value = nutrient.get("value") elif "number" in nutrient: nutrient_id = str(nutrient.get("number", "")) value = nutrient.get("value") - if ( - nutrient_id - and nutrient_id in nutrient_map - and value is not None - ): + if nutrient_id and nutrient_id in nutrient_map and value is not None: key = nutrient_map[nutrient_id] try: nutrients[key] = float(value) @@ -404,11 +396,7 @@ class NutritionCalculator: # Strategy 1: Direct search ingredient_name, # Strategy 2: Singular form (remove trailing 's') - ( - ingredient_name.rstrip("s") - if ingredient_name.endswith("s") - else None - ), + (ingredient_name.rstrip("s") if ingredient_name.endswith("s") else None), # Strategy 3: Remove common suffixes re.sub( r"\s+(fresh|dried|ground|chopped|sliced)$", @@ -417,11 +405,7 @@ class NutritionCalculator: flags=re.IGNORECASE, ), # Strategy 4: Just the last word (sometimes works for simple ingredients) - ( - ingredient_name.split()[-1] - if len(ingredient_name.split()) > 1 - else None - ), + (ingredient_name.split()[-1] if len(ingredient_name.split()) > 1 else None), ] for query in strategies: @@ -431,9 +415,7 @@ class NutritionCalculator: try: results = self.usda.search_foods(query, page_size=5) if results: - logger.debug( - f"Found {query}: {results[0].get('description')}" - ) + logger.debug(f"Found {query}: {results[0].get('description')}") return results[0] except Exception as e: logger.warning(f"USDA search failed for '{query}': {e}") @@ -471,9 +453,7 @@ class NutritionCalculator: } # Get base weight in grams - base_grams = volume_to_grams.get( - unit, 100 - ) # Default to 100g if unknown + base_grams = volume_to_grams.get(unit, 100) # Default to 100g if unknown # Adjust for ingredient type (very simplified) if any( @@ -481,22 +461,16 @@ class NutritionCalculator: for word in ["flour", "sugar", "rice", "grain"] ): base_grams = volume_to_grams.get(unit, 125) # Dry ingredients - elif any( - word in ingredient_name.lower() - for word in ["oil", "butter", "fat"] - ): + elif any(word in ingredient_name.lower() for word in ["oil", "butter", "fat"]): base_grams = volume_to_grams.get(unit, 220) # Dense liquids elif any( - word in ingredient_name.lower() - for word in ["milk", "water", "broth"] + word in ingredient_name.lower() for word in ["milk", "water", "broth"] ): base_grams = volume_to_grams.get(unit, 240) # Liquids return quantity * base_grams - def calculate_nutrition( - self, ingredients: List[str], servings: int = 1 - ) -> Dict: + def calculate_nutrition(self, ingredients: List[str], servings: int = 1) -> Dict: """ Calculate total nutrition for a recipe from ingredient list. Returns nutrition per serving. @@ -543,12 +517,8 @@ class NutritionCalculator: # USDA data is typically per 100g, so scale accordingly multiplier = grams / 100 - totals["calories"] += ( - nutrients.get("calories", 0) * multiplier - ) - totals["protein"] += ( - nutrients.get("protein", 0) * multiplier - ) + totals["calories"] += nutrients.get("calories", 0) * multiplier + totals["protein"] += nutrients.get("protein", 0) * multiplier totals["fat"] += nutrients.get("fat", 0) * multiplier totals["carbohydrates"] += ( nutrients.get("carbohydrates", 0) * multiplier diff --git a/vrobbler/apps/lifeevents/models.py b/vrobbler/apps/lifeevents/models.py index f1b7863..b960a5e 100644 --- a/vrobbler/apps/lifeevents/models.py +++ b/vrobbler/apps/lifeevents/models.py @@ -20,9 +20,7 @@ class LifeEvent(ScrobblableMixin): return self.title def get_absolute_url(self): - return reverse( - "life-events:life-event_detail", kwargs={"slug": self.uuid} - ) + return reverse("life-events:life-event_detail", kwargs={"slug": self.uuid}) @property def logdata_cls(self): @@ -38,6 +36,6 @@ class LifeEvent(ScrobblableMixin): def scrobbles(self, user_id): Scrobble = apps.get_model("scrobbles", "Scrobble") - return Scrobble.objects.filter( - user_id=user_id, life_event=self - ).order_by("-timestamp") + return Scrobble.objects.filter(user_id=user_id, life_event=self).order_by( + "-timestamp" + ) diff --git a/vrobbler/apps/lifeevents/urls.py b/vrobbler/apps/lifeevents/urls.py index c803fba..8adf737 100644 --- a/vrobbler/apps/lifeevents/urls.py +++ b/vrobbler/apps/lifeevents/urls.py @@ -5,9 +5,7 @@ app_name = "lifeevents" urlpatterns = [ - path( - "lifeevents/", views.LifeEventListView.as_view(), name="lifeevent_list" - ), + path("lifeevents/", views.LifeEventListView.as_view(), name="lifeevent_list"), path( "lifeevent//", views.LifeEventDetailView.as_view(), diff --git a/vrobbler/apps/locations/models.py b/vrobbler/apps/locations/models.py index 59906f6..0af7dfa 100644 --- a/vrobbler/apps/locations/models.py +++ b/vrobbler/apps/locations/models.py @@ -42,9 +42,7 @@ class GeoLocation(ScrobblableMixin): return f"{self.lat} x {self.lon}" def get_absolute_url(self): - return reverse( - "locations:geolocation_detail", kwargs={"slug": self.uuid} - ) + return reverse("locations:geolocation_detail", kwargs={"slug": self.uuid}) @property def logdata_cls(self): @@ -101,9 +99,7 @@ class GeoLocation(ScrobblableMixin): @property def strings(self) -> ScrobblableConstants: - return ScrobblableConstants( - verb="Going", tags="world_map", priority="low" - ) + return ScrobblableConstants(verb="Going", tags="world_map", priority="low") def loc_diff(self, old_lat_lon: tuple) -> tuple: return ( @@ -114,9 +110,7 @@ class GeoLocation(ScrobblableMixin): def has_moved(self, previous_location: "GeoLocation") -> bool: has_moved = False - loc_diff = self.loc_diff( - (previous_location.lat, previous_location.lon) - ) + loc_diff = self.loc_diff((previous_location.lat, previous_location.lon)) if loc_diff[0] > GEOLOC_PROXIMITY or loc_diff[1] > GEOLOC_PROXIMITY: has_moved = True logger.debug( diff --git a/vrobbler/apps/locations/tests/test_models.py b/vrobbler/apps/locations/tests/test_models.py index 044e3fb..f53f108 100644 --- a/vrobbler/apps/locations/tests/test_models.py +++ b/vrobbler/apps/locations/tests/test_models.py @@ -13,9 +13,7 @@ def test_find_or_create(caplog): @pytest.mark.django_db def test_find_or_create_truncation(): - loc = GeoLocation.find_or_create( - {"lat": 44.2345, "lon": -68.2345, "alt": 60.356} - ) + loc = GeoLocation.find_or_create({"lat": 44.2345, "lon": -68.2345, "alt": 60.356}) assert loc.lat == 44.234 assert loc.lon == -68.234 assert loc.altitude == 60 @@ -25,9 +23,7 @@ def test_find_or_create_truncation(): def test_find_or_create_finds_existing(): extant = GeoLocation.objects.create(lat=44.234, lon=-68.234, altitude=50) - loc = GeoLocation.find_or_create( - {"lat": 44.2345, "lon": -68.2345, "alt": 60.356} - ) + loc = GeoLocation.find_or_create({"lat": 44.2345, "lon": -68.2345, "alt": 60.356}) assert loc.id == extant.id @@ -35,9 +31,7 @@ def test_find_or_create_finds_existing(): def test_find_or_create_creates_new(): extant = GeoLocation.objects.create(lat=44.234, lon=-69.234, altitude=60) - loc = GeoLocation.find_or_create( - {"lat": 44.2345, "lon": -68.2345, "alt": 60.356} - ) + loc = GeoLocation.find_or_create({"lat": 44.2345, "lon": -68.2345, "alt": 60.356}) assert not loc.id == extant.id @@ -47,9 +41,7 @@ def test_found_in_proximity_location(): lon = -69.234 loc = GeoLocation.objects.create(lat=lat, lon=lon, altitude=60) - close = GeoLocation.objects.create( - lat=lat + 0.0001, lon=lon - 0.0001, altitude=60 - ) + close = GeoLocation.objects.create(lat=lat + 0.0001, lon=lon - 0.0001, altitude=60) assert close not in loc.in_proximity(named=True) assert close in loc.in_proximity() @@ -60,9 +52,7 @@ def test_not_found_in_proximity_location(): lon = -69.234 loc = GeoLocation.objects.create(lat=lat, lon=lon, altitude=60) - far = GeoLocation.objects.create( - lat=lat + 0.0002, lon=lon - 0.0001, altitude=60 - ) + far = GeoLocation.objects.create(lat=lat + 0.0002, lon=lon - 0.0001, altitude=60) assert far not in loc.in_proximity() diff --git a/vrobbler/apps/music/models.py b/vrobbler/apps/music/models.py index cf7e723..c1b7a0f 100644 --- a/vrobbler/apps/music/models.py +++ b/vrobbler/apps/music/models.py @@ -109,9 +109,9 @@ class Artist(TimeStampedModel): def scrobbles(self): from scrobbles.models import Scrobble - return Scrobble.objects.filter( - track__in=self.track_set.all() - ).order_by("-timestamp") + return Scrobble.objects.filter(track__in=self.track_set.all()).order_by( + "-timestamp" + ) @property def tracks(self): @@ -130,9 +130,7 @@ class Artist(TimeStampedModel): if not self.allmusic_id or force: slug = get_allmusic_slug(self.name) if not slug: - logger.info( - "No allmusic link found", extra={"track_id": self.id} - ) + logger.info("No allmusic link found", extra={"track_id": self.id}) return self.allmusic_id = slug self.save(update_fields=["allmusic_id"]) @@ -141,9 +139,7 @@ class Artist(TimeStampedModel): if not self.bandcamp_id or force: slug = get_bandcamp_slug(self.name) if not slug: - logger.info( - "No bandcamp link found", extra={"track_id": self.id} - ) + logger.info("No bandcamp link found", extra={"track_id": self.id}) return self.bandcamp_id = slug self.save(update_fields=["bandcamp_id"]) @@ -193,13 +189,9 @@ class Artist(TimeStampedModel): Thus, when we find or create an artist, we should always provide an optional album name or track name, but probably not both.""" if album_name: - logger.info( - f"Looking for artist with name {name} and album {album_name}" - ) + logger.info(f"Looking for artist with name {name} and album {album_name}") if track_name: - logger.info( - f"Looking for artist with name {name} and track {track_name}" - ) + logger.info(f"Looking for artist with name {name} and track {track_name}") keys = {} name = clean_artist_name(name) @@ -310,9 +302,9 @@ class Album(TimeStampedModel): def scrobbles(self): from scrobbles.models import Scrobble - return Scrobble.objects.filter( - track__in=self.track_set.all() - ).order_by("-timestamp") + return Scrobble.objects.filter(track__in=self.track_set.all()).order_by( + "-timestamp" + ) @property def primary_image_url(self) -> str: @@ -349,9 +341,7 @@ class Album(TimeStampedModel): if self.album_artist and (not self.allmusic_id or force): slug = get_allmusic_slug(self.album_artist.name, self.name) if not slug: - logger.info( - f"No allmsuic link for {self} by {self.album_artist}" - ) + logger.info(f"No allmsuic link for {self} by {self.album_artist}") return self.allmusic_id = slug self.save(update_fields=["allmusic_id"]) @@ -380,9 +370,7 @@ class Album(TimeStampedModel): try: Album.objects.filter(pk=self.pk).update(**album_data) except: - logger.info( - f"Could not save info for album {self} with data {album_data}" - ) + logger.info(f"Could not save info for album {self} with data {album_data}") def scrape_bandcamp(self, force=False) -> None: if not self.bandcamp_id or force: @@ -404,13 +392,13 @@ class Album(TimeStampedModel): self.musicbrainz_id, includes=["artists", "release-groups"] ) if not self.musicbrainz_releasegroup_id: - self.musicbrainz_releasegroup_id = mb_data["release"][ - "release-group" - ]["id"] + self.musicbrainz_releasegroup_id = mb_data["release"]["release-group"][ + "id" + ] if not self.musicbrainz_albumartist_id: - self.musicbrainz_albumartist_id = mb_data["release"][ - "artist-credit" - ][0]["artist"]["id"] + self.musicbrainz_albumartist_id = mb_data["release"]["artist-credit"][ + 0 + ]["artist"]["id"] if not self.year: try: self.year = mb_data["release"]["date"][0:4] @@ -435,10 +423,7 @@ class Album(TimeStampedModel): if not new_artist: for t in self.track_set.all(): self.artists.add(t.artist) - if ( - not self.cover_image - or self.cover_image == "default-image-replace-me" - ): + if not self.cover_image or self.cover_image == "default-image-replace-me": self.fetch_artwork() self.fix_album_artist() self.scrape_theaudiodb() @@ -448,20 +433,15 @@ class Album(TimeStampedModel): if not self.cover_image and not force: if self.musicbrainz_id: try: - img_data = musicbrainzngs.get_image_front( - self.musicbrainz_id - ) + img_data = musicbrainzngs.get_image_front(self.musicbrainz_id) name = f"{self.name}_{self.uuid}.jpg" self.cover_image = ContentFile(img_data, name=name) logger.info(f"Setting image to {name}") except musicbrainzngs.ResponseError: - logger.warning( - f"No cover art found for {self.name} by release" - ) + logger.warning(f"No cover art found for {self.name} by release") if ( - not self.cover_image - or self.cover_image == "default-image-replace-me" + not self.cover_image or self.cover_image == "default-image-replace-me" ) and self.musicbrainz_releasegroup_id: try: img_data = musicbrainzngs.get_release_group_image_front( @@ -522,9 +502,7 @@ class Album(TimeStampedModel): @classmethod def find_or_create(cls, name: str, artist_name: str) -> "Album": - logger.info( - f"Looking for album with name {name} and artist_name {artist_name}" - ) + logger.info(f"Looking for album with name {name} and artist_name {artist_name}") artist = Artist.find_or_create(artist_name, album_name=name) album_dict = get_album_metadata_with_artist(name, artist.name) @@ -572,9 +550,7 @@ class Album(TimeStampedModel): if found_name and name != found_name: alt_name = name - album = Album.objects.filter( - musicbrainz_id=album_dict.get("mbid") - ).first() + album = Album.objects.filter(musicbrainz_id=album_dict.get("mbid")).first() if not album: year = None @@ -583,9 +559,7 @@ class Album(TimeStampedModel): album = Album.objects.create( name=found_name, musicbrainz_id=album_dict.get("mbid"), - musicbrainz_releasegroup_id=album_dict.get( - "release_group_mbid" - ), + musicbrainz_releasegroup_id=album_dict.get("release_group_mbid"), year=year, album_artist=artist, alt_names=alt_name, @@ -666,9 +640,7 @@ class Track(ScrobblableMixin): album = None if album_name: logger.info("Looking up album for: {album_name}") - album = Album.find_or_create( - name=album_name, artist_name=artist_name - ) + album = Album.find_or_create(name=album_name, artist_name=artist_name) artist = album.album_artist else: artist = Artist.find_or_create(artist_name, track_name=title) @@ -709,15 +681,11 @@ class Track(ScrobblableMixin): }, ) try: - mbid, length = get_recording_mbid_exact( - title, artist_name, album_name - ) + mbid, length = get_recording_mbid_exact(title, artist_name, album_name) except Exception: print("No musicbrainz result found, cannot enrich") return track - track.base_run_time_seconds = run_time_seconds or int( - length / 1000 - ) + track.base_run_time_seconds = run_time_seconds or int(length / 1000) track.musicbrainz_id = mbid if commit: track.save() diff --git a/vrobbler/apps/music/musicbrainz.py b/vrobbler/apps/music/musicbrainz.py index e963f28..1f8f869 100644 --- a/vrobbler/apps/music/musicbrainz.py +++ b/vrobbler/apps/music/musicbrainz.py @@ -29,9 +29,7 @@ def lookup_album_from_mb(musicbrainz_id: str) -> dict: "album": { "name": release_data.get("title"), "musicbrainz_id": musicbrainz_id, - "musicbrainz_releasegroup_id": release_data.get( - "release-group" - ).get("id"), + "musicbrainz_releasegroup_id": release_data.get("release-group").get("id"), "musicbrainz_albumaritist_id": primary_artist.get("id"), "year": release_data.get("year")[0:4], }, @@ -56,13 +54,11 @@ def lookup_album_dict_from_mb(release_name: str, artist_name: str) -> dict: top_result = {} try: - top_result = musicbrainzngs.search_releases( - release_name, artist=artist_name - )["release-list"][0] + top_result = musicbrainzngs.search_releases(release_name, artist=artist_name)[ + "release-list" + ][0] except IndexError: - logger.info( - f"No release found on MB for {artist_name} and {release_name}" - ) + logger.info(f"No release found on MB for {artist_name} and {release_name}") score = int(top_result.get("ext:score", 0)) if score < 85: @@ -86,9 +82,7 @@ def lookup_album_dict_from_mb(release_name: str, artist_name: str) -> dict: def lookup_artist_from_mb(artist_name: str) -> dict: try: - top_result = musicbrainzngs.search_artists(artist=artist_name)[ - "artist-list" - ][0] + top_result = musicbrainzngs.search_artists(artist=artist_name)["artist-list"][0] except IndexError: return {} score = int(top_result.get("ext:score")) @@ -204,9 +198,7 @@ def get_recording_mbid_exact( for track in tracks: if track["recording"]["title"].lower() == track_title.lower(): - return track["recording"]["id"], int( - track["recording"]["length"] - ) + return track["recording"]["id"], int(track["recording"]["length"]) raise Exception("No recording found") except musicbrainzngs.WebServiceError as e: @@ -224,9 +216,7 @@ def get_artist_metadata_extended(artist_name, strict=True): """ try: # Step 1: Search for artist - search_results = musicbrainzngs.search_artists( - artist=artist_name, limit=5 - ) + search_results = musicbrainzngs.search_artists(artist=artist_name, limit=5) for artist in search_results.get("artist-list", []): if not strict or artist["name"].lower() == artist_name.lower(): mbid = artist["id"] @@ -354,9 +344,7 @@ def get_album_metadata_with_artist(album_name, artist_name, strict=True): primary_artist = release["artist-credit"][0]["artist"] all_artists = [ - ac["artist"]["name"] - for ac in release["artist-credit"] - if "artist" in ac + ac["artist"]["name"] for ac in release["artist-credit"] if "artist" in ac ] artist_metadata = get_artist_metadata_brief(primary_artist["id"]) @@ -446,9 +434,7 @@ def get_track_metadata_with_artist(track_title, artist_name, strict=True): for release in recording["release-list"]: release_date = parse_date(release.get("date")) if release_date: - valid_candidates.append( - (recording["id"], release, release_date) - ) + valid_candidates.append((recording["id"], release, release_date)) if not valid_candidates: return None diff --git a/vrobbler/apps/music/theaudiodb.py b/vrobbler/apps/music/theaudiodb.py index 77e0b34..223c22d 100644 --- a/vrobbler/apps/music/theaudiodb.py +++ b/vrobbler/apps/music/theaudiodb.py @@ -6,9 +6,15 @@ import requests from django.conf import settings THEAUDIODB_API_KEY = getattr(settings, "THEAUDIODB_API_KEY") -ARTIST_SEARCH_URL = f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/search.php?s=" -ARTIST_FETCH_URL = f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/artist.php?i=" -ALBUM_SEARCH_URL = f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/searchalbum.php?s=" +ARTIST_SEARCH_URL = ( + f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/search.php?s=" +) +ARTIST_FETCH_URL = ( + f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/artist.php?i=" +) +ALBUM_SEARCH_URL = ( + f"https://www.theaudiodb.com/api/v1/json/{THEAUDIODB_API_KEY}/searchalbum.php?s=" +) logger = logging.getLogger(__name__) @@ -94,14 +100,10 @@ def lookup_album_from_tadb(name: str, artist: str) -> dict: album_info["rateyourmusic_id"] = album.get("strRateYourMusicID") if album.get("intYearReleased"): - album_info["theaudiodb_year_released"] = float( - album.get("intYearReleased") - ) + album_info["theaudiodb_year_released"] = float(album.get("intYearReleased")) if album.get("intScore"): album_info["theaudiodb_score"] = float(album.get("intScore")) if album.get("intScoreVotes"): - album_info["theaudiodb_score_votes"] = int( - album.get("intScoreVotes") - ) + album_info["theaudiodb_score_votes"] = int(album.get("intScoreVotes")) return album_info diff --git a/vrobbler/apps/music/utils.py b/vrobbler/apps/music/utils.py index 7ea8e30..34f7a8c 100644 --- a/vrobbler/apps/music/utils.py +++ b/vrobbler/apps/music/utils.py @@ -88,9 +88,7 @@ def condense_albums(commit: bool = False): track.albums.add(dup_track.album) # Find out if this track appears more than once - duplicates = Track.objects.filter( - title=track.title, artist=track.artist - ) + duplicates = Track.objects.filter(title=track.title, artist=track.artist) if duplicates.count() > 1: logger.info(f"Track appears more than once, condensing: {track}") @@ -98,9 +96,7 @@ def condense_albums(commit: bool = False): # Find all scrobbles duplicate_ids = duplicates.values_list("id", flat=True) scrobbles = Scrobble.objects.filter(track_id__in=duplicate_ids) - logger.info( - f"Found {scrobbles.count()} scrobbles to merge onto {track}" - ) + logger.info(f"Found {scrobbles.count()} scrobbles to merge onto {track}") if commit: scrobbles.update(track=track) track.albums.add(*list(set(albums_to_add))) diff --git a/vrobbler/apps/people/urls.py b/vrobbler/apps/people/urls.py index 76e4612..88be3d2 100644 --- a/vrobbler/apps/people/urls.py +++ b/vrobbler/apps/people/urls.py @@ -5,9 +5,7 @@ app_name = "people" urlpatterns = [ - path( - "people/", views.PersonCreateUpdateView.as_view(), name="person_form" - ), + path("people/", views.PersonCreateUpdateView.as_view(), name="person_form"), path( "people//edit/", views.PersonUpdateView.as_view(), diff --git a/vrobbler/apps/podcasts/models.py b/vrobbler/apps/podcasts/models.py index 2035b0f..27b58cf 100644 --- a/vrobbler/apps/podcasts/models.py +++ b/vrobbler/apps/podcasts/models.py @@ -39,9 +39,7 @@ class Producer(TimeStampedModel): class Podcast(TimeStampedModel): name = models.CharField(max_length=255) uuid = models.UUIDField(default=uuid4, editable=False, **BNULL) - producer = models.ForeignKey( - Producer, on_delete=models.DO_NOTHING, **BNULL - ) + producer = models.ForeignKey(Producer, on_delete=models.DO_NOTHING, **BNULL) podcastindex_id = models.CharField(max_length=100, **BNULL) owner = models.CharField(max_length=150, *BNULL) description = models.TextField(**BNULL) @@ -123,9 +121,7 @@ class PodcastEpisode(ScrobblableMixin): mopidy_uri = models.CharField(max_length=255, **BNULL) def get_absolute_url(self): - return reverse( - "podcasts:podcast_detail", kwargs={"slug": self.podcast.uuid} - ) + return reverse("podcasts:podcast_detail", kwargs={"slug": self.podcast.uuid}) def __str__(self): return f"{self.title}" diff --git a/vrobbler/apps/podcasts/sources/podcastindex.py b/vrobbler/apps/podcasts/sources/podcastindex.py index 88f3563..34e7583 100644 --- a/vrobbler/apps/podcasts/sources/podcastindex.py +++ b/vrobbler/apps/podcasts/sources/podcastindex.py @@ -14,9 +14,7 @@ PODCASTINDEX_API_SECRET = getattr(settings, "PODCASTINDEX_API_SECRET") def get_auth_headers(): now = int(time.time()) hash_data = hashlib.sha1( - (PODCASTINDEX_API_KEY + PODCASTINDEX_API_SECRET + str(now)).encode( - "utf-8" - ) + (PODCASTINDEX_API_KEY + PODCASTINDEX_API_SECRET + str(now)).encode("utf-8") ).hexdigest() return { diff --git a/vrobbler/apps/podcasts/utils.py b/vrobbler/apps/podcasts/utils.py index 95cf3cb..32b6adf 100644 --- a/vrobbler/apps/podcasts/utils.py +++ b/vrobbler/apps/podcasts/utils.py @@ -53,9 +53,7 @@ def fetch_metadata_from_rss(uri: str) -> dict[str, Any]: if isinstance(feed.feed.itunes_owner, dict) else feed.feed.itunes_owner ) - podcast_other = feed.feed.get("managingeditor") or feed.feed.get( - "copyright" - ) + podcast_other = feed.feed.get("managingeditor") or feed.feed.get("copyright") except AttributeError: podcast_owner = None podcast_other = None @@ -64,9 +62,7 @@ def fetch_metadata_from_rss(uri: str) -> dict[str, Any]: "podcast_name": getattr(feed.feed, "title", ""), # "podcast_description": getattr(feed.feed, "description", ""), # "podcast_link": getattr(feed.feed, "link", ""), - "podcast_producer": podcast_publisher - or podcast_owner - or podcast_other, + "podcast_producer": podcast_publisher or podcast_owner or podcast_other, } for entry in feed.entries: @@ -116,8 +112,7 @@ def parse_mopidy_uri(uri: str) -> dict[str, Any]: # Beacuse we have epsiode numbers on podcast_data["pub_date"] = parse( episode_str[ - episode_num_pad : len(PODCAST_DATE_FORMAT) - + episode_num_pad + episode_num_pad : len(PODCAST_DATE_FORMAT) + episode_num_pad ] ) except ParserError: @@ -129,9 +124,7 @@ def parse_mopidy_uri(uri: str) -> dict[str, Any]: if podcast_data["episode_num"]: gap_to_strip += episode_num_pad - podcast_data["title"] = ( - episode_str[gap_to_strip:].replace("-", " ").strip() - ) + podcast_data["title"] = episode_str[gap_to_strip:].replace("-", " ").strip() return podcast_data diff --git a/vrobbler/apps/profiles/constants.py b/vrobbler/apps/profiles/constants.py index c43de3e..7dfcc23 100644 --- a/vrobbler/apps/profiles/constants.py +++ b/vrobbler/apps/profiles/constants.py @@ -3,9 +3,7 @@ from datetime import datetime import pytz ALL_TIMEZONE_CHOICES = tuple(zip(pytz.all_timezones, pytz.all_timezones)) -COMMON_TIMEZONE_CHOICES = tuple( - zip(pytz.common_timezones, pytz.common_timezones) -) +COMMON_TIMEZONE_CHOICES = tuple(zip(pytz.common_timezones, pytz.common_timezones)) PRETTY_TIMEZONE_CHOICES = [] for tz in pytz.common_timezones: diff --git a/vrobbler/apps/profiles/urls.py b/vrobbler/apps/profiles/urls.py index 490f5b4..ffa333a 100644 --- a/vrobbler/apps/profiles/urls.py +++ b/vrobbler/apps/profiles/urls.py @@ -5,7 +5,5 @@ app_name = "profiles" urlpatterns = [ - path( - "settings/", views.ProfileFormView.as_view(), name="profile_settings" - ), + path("settings/", views.ProfileFormView.as_view(), name="profile_settings"), ] diff --git a/vrobbler/apps/profiles/utils.py b/vrobbler/apps/profiles/utils.py index afe8256..ff160d1 100644 --- a/vrobbler/apps/profiles/utils.py +++ b/vrobbler/apps/profiles/utils.py @@ -82,15 +82,9 @@ def fix_profile_historic_timezones(profile): profile.timezone_change_log = "" profile.timezone_change_log += f"{europe_tz} - {pendulum.parse(europe)}\n" - profile.timezone_change_log += ( - f"{home_tz} - {pendulum.parse(europe_end)}\n" - ) - profile.timezone_change_log += ( - f"{washington_tz} - {pendulum.parse(washington)}\n" - ) - profile.timezone_change_log += ( - f"{home_tz} - {pendulum.parse(washington_end)}\n" - ) + profile.timezone_change_log += f"{home_tz} - {pendulum.parse(europe_end)}\n" + profile.timezone_change_log += f"{washington_tz} - {pendulum.parse(washington)}\n" + profile.timezone_change_log += f"{home_tz} - {pendulum.parse(washington_end)}\n" profile.timezone_change_log += f"{camp_tz} - {pendulum.parse(camp)}\n" profile.timezone_change_log += f"{home_tz} - {pendulum.parse(camp_end)}\n" profile.timezone_change_log += f"{summer_tz} - {pendulum.parse(summer)}\n" diff --git a/vrobbler/apps/puzzles/models.py b/vrobbler/apps/puzzles/models.py index 1036bc9..ab7715e 100644 --- a/vrobbler/apps/puzzles/models.py +++ b/vrobbler/apps/puzzles/models.py @@ -110,9 +110,7 @@ class Puzzle(ScrobblableMixin): ( manufacturer, _created, - ) = PuzzleManufacturer.objects.get_or_create( - name=manufacturer_name - ) + ) = PuzzleManufacturer.objects.get_or_create(name=manufacturer_name) puzzle_dict["manufacturer_id"] = manufacturer.id genres = puzzle_dict.pop("genres", None) @@ -126,9 +124,7 @@ class Puzzle(ScrobblableMixin): r = requests.get(cover_url) if r.status_code == 200: fname = f"{puzzle.title}_{puzzle.uuid}.jpg" - puzzle.ipdb_image.save( - fname, ContentFile(r.content), save=True - ) + puzzle.ipdb_image.save(fname, ContentFile(r.content), save=True) return puzzle diff --git a/vrobbler/apps/puzzles/sources/ipdb.py b/vrobbler/apps/puzzles/sources/ipdb.py index bd8ec7f..ee07f91 100644 --- a/vrobbler/apps/puzzles/sources/ipdb.py +++ b/vrobbler/apps/puzzles/sources/ipdb.py @@ -30,9 +30,7 @@ def get_title_from_soup(soup) -> str: def get_manufacturer_from_soup(soup) -> str: manufacturer = "" try: - manufacturer = ( - soup.find(class_="infobox").div.contents[0].split("|")[0].strip() - ) + manufacturer = soup.find(class_="infobox").div.contents[0].split("|")[0].strip() except AttributeError: pass except ValueError: @@ -46,10 +44,7 @@ def get_pieces_count_from_soup(soup) -> int: pieces = 0 try: pieces = int( - soup.find(class_="infobox") - .div.contents[0] - .split("|")[1] - .split(" ")[1] + soup.find(class_="infobox").div.contents[0].split("|")[1].split(" ")[1] ) except AttributeError: pass @@ -63,9 +58,7 @@ def get_pieces_count_from_soup(soup) -> int: def get_publish_year_from_soup(soup) -> int: year = 1900 try: - year = int( - soup.find(class_="infobox").div.contents[0].split("|")[2].strip() - ) + year = int(soup.find(class_="infobox").div.contents[0].split("|")[2].strip()) except AttributeError: pass except ValueError: @@ -152,9 +145,7 @@ def get_barcode_from_soup(soup) -> str: def get_image_url_from_soup(soup) -> str: url = "" try: - url = ( - soup.find(class_="image-container").contents[0].contents[0]["src"] - ) + url = soup.find(class_="image-container").contents[0].contents[0]["src"] except AttributeError: pass except ValueError: @@ -210,9 +201,7 @@ def get_dimensions_from_soup(soup) -> str: def get_rating_from_soup(soup) -> str: rating = "" try: - rating = float( - soup.find(class_="num").get_text().strip("(").strip(")") - ) + rating = float(soup.find(class_="num").get_text().strip("(").strip(")")) except AttributeError: rating = None except ValueError: @@ -227,9 +216,7 @@ def get_puzzle_from_ipdb_id(ipdb_id: str) -> dict: puzzle_dict = {"ipdb_id": ipdb_id} if response.status_code != 200: - logger.warn( - "Bad response from untappd.com", extra={"response": response} - ) + logger.warn("Bad response from untappd.com", extra={"response": response}) return puzzle_dict soup = BeautifulSoup(response.text, "html.parser") diff --git a/vrobbler/apps/scrobbles/admin.py b/vrobbler/apps/scrobbles/admin.py index 8991ce8..8b8f5b6 100644 --- a/vrobbler/apps/scrobbles/admin.py +++ b/vrobbler/apps/scrobbles/admin.py @@ -70,7 +70,10 @@ class KoReaderImportAdmin(ImportBaseAdmin): @admin.register(RetroarchImport) class RetroarchImportAdmin(ImportBaseAdmin): ... -class RetroarchImportAdmin(ImportBaseAdmin): ... + + +class RetroarchImportAdmin(ImportBaseAdmin): + ... @admin.register(Genre) diff --git a/vrobbler/apps/scrobbles/api/serializers.py b/vrobbler/apps/scrobbles/api/serializers.py index 8a1d4b3..109bd89 100644 --- a/vrobbler/apps/scrobbles/api/serializers.py +++ b/vrobbler/apps/scrobbles/api/serializers.py @@ -63,9 +63,7 @@ class KoReaderImportSerializer(serializers.HyperlinkedModelSerializer): fields = "__all__" -class AudioScrobblerTSVImportSerializer( - serializers.HyperlinkedModelSerializer -): +class AudioScrobblerTSVImportSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = AudioScrobblerTSVImport fields = "__all__" diff --git a/vrobbler/apps/scrobbles/export.py b/vrobbler/apps/scrobbles/export.py index c5fb81c..7ca6568 100644 --- a/vrobbler/apps/scrobbles/export.py +++ b/vrobbler/apps/scrobbles/export.py @@ -13,9 +13,7 @@ def export_scrobbles(start_date=None, end_date=None, format="AS"): if start_date: end_query = Q(timestamp__lte=end_date) - scrobble_qs = Scrobble.objects.filter( - start_query, end_query, track__isnull=False - ) + scrobble_qs = Scrobble.objects.filter(start_query, end_query, track__isnull=False) headers = [] extension = "tsv" delimiter = "\t" diff --git a/vrobbler/apps/scrobbles/forms.py b/vrobbler/apps/scrobbles/forms.py index af4a1a7..6ea5e01 100644 --- a/vrobbler/apps/scrobbles/forms.py +++ b/vrobbler/apps/scrobbles/forms.py @@ -56,9 +56,7 @@ def django_form_field_from_type(field_type, required=True): if type(None) in args: required = False non_none_type = [arg for arg in args if arg is not type(None)][0] - return django_form_field_from_type( - non_none_type, required=required - ) + return django_form_field_from_type(non_none_type, required=required) # Determine actual type base_type = origin if origin else field_type @@ -84,9 +82,7 @@ def form_from_dataclass(dataclass): continue required = f.default is None and f.default_factory is None - form_fields[f.name] = django_form_field_from_type( - f.type, required=required - ) + form_fields[f.name] = django_form_field_from_type(f.type, required=required) if f.name in dataclass._excluded_fields: form_fields[f.name].disabled = True @@ -101,9 +97,7 @@ def form_from_dataclass(dataclass): def clean_notes(self): notes_str = self.cleaned_data.get("notes", "") - return [ - line.strip() for line in notes_str.splitlines() if line.strip() - ] + return [line.strip() for line in notes_str.splitlines() if line.strip()] form_cls.clean_notes = clean_notes return form_cls diff --git a/vrobbler/apps/scrobbles/importers/imap.py b/vrobbler/apps/scrobbles/importers/imap.py index 59a8e49..54f7a45 100644 --- a/vrobbler/apps/scrobbles/importers/imap.py +++ b/vrobbler/apps/scrobbles/importers/imap.py @@ -43,9 +43,7 @@ def import_scrobbles_from_imap() -> list[Scrobble]: try: message = email.message_from_bytes(msg_data[0][1]) - logger.info( - "Processing email message", extra={"email_msg": message} - ) + logger.info("Processing email message", extra={"email_msg": message}) except IndexError: logger.info("No email message data found") return @@ -75,9 +73,7 @@ def import_scrobbles_from_imap() -> list[Scrobble]: if filename.lower().endswith(".bgsplay"): # TODO Pull this out into a parse_pgsplay function try: - parsed_json = json.loads( - file_data.decode("utf-8") - ) + parsed_json = json.loads(file_data.decode("utf-8")) except Exception as e: logger.error( "Failed to parse JSON file", diff --git a/vrobbler/apps/scrobbles/importers/lastfm.py b/vrobbler/apps/scrobbles/importers/lastfm.py index c5100d2..8b2210e 100644 --- a/vrobbler/apps/scrobbles/importers/lastfm.py +++ b/vrobbler/apps/scrobbles/importers/lastfm.py @@ -54,9 +54,7 @@ class LastFM: lfm_scrobble.get("timestamp") ) timestamp = lfm_scrobble.get("timestamp") - stop_timestamp = timestamp + timedelta( - seconds=track.run_time_seconds - ) + stop_timestamp = timestamp + timedelta(seconds=track.run_time_seconds) new_scrobble = Scrobble( user=self.vrobbler_user, timestamp=timestamp, @@ -149,13 +147,11 @@ class LastFM: # TODO figure out if this will actually work # timestamp = datetime.fromtimestamp(int(scrobble.timestamp), UTC) - timestamp = datetime.utcfromtimestamp( - int(scrobble.timestamp) - ).replace(tzinfo=pytz.utc) - - logger.info( - f"Scrobble appended to list for bulk create", extra=log_dict + timestamp = datetime.utcfromtimestamp(int(scrobble.timestamp)).replace( + tzinfo=pytz.utc ) + + logger.info(f"Scrobble appended to list for bulk create", extra=log_dict) scrobbles.append( { "artist": artist, diff --git a/vrobbler/apps/scrobbles/importers/webdav.py b/vrobbler/apps/scrobbles/importers/webdav.py index 7153d09..4ac3843 100644 --- a/vrobbler/apps/scrobbles/importers/webdav.py +++ b/vrobbler/apps/scrobbles/importers/webdav.py @@ -20,9 +20,7 @@ def import_from_webdav_for_all_users(restart=False): webdav_pass__isnull=False, webdav_auto_import=True, ).values_list("user_id", flat=True) - logger.info( - f"Start import of {webdav_enabled_user_ids.count()} webdav accounts" - ) + logger.info(f"Start import of {webdav_enabled_user_ids.count()} webdav accounts") koreader_import_count = 0 diff --git a/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py b/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py index 55ad915..b37d0b8 100644 --- a/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py +++ b/vrobbler/apps/scrobbles/management/commands/delete_zombie_scrobbles.py @@ -24,6 +24,4 @@ class Command(BaseCommand): print(f"Deleted {scrobbles_found} zombie scrobbles") return - print( - f"Found {scrobbles_found} zombie scrobbles, use --delete to remove them" - ) + print(f"Found {scrobbles_found} zombie scrobbles, use --delete to remove them") diff --git a/vrobbler/apps/scrobbles/management/commands/migrate_scrobble_log_to_json.py b/vrobbler/apps/scrobbles/management/commands/migrate_scrobble_log_to_json.py index c3e05fd..ecd913d 100644 --- a/vrobbler/apps/scrobbles/management/commands/migrate_scrobble_log_to_json.py +++ b/vrobbler/apps/scrobbles/management/commands/migrate_scrobble_log_to_json.py @@ -41,8 +41,6 @@ class Command(BaseCommand): if not dry_run: scrobble.save(update_fields=["scrobble_log"]) else: - print( - f"Scrobble {scrobble} scrobble_log updated to {old_data}" - ) + print(f"Scrobble {scrobble} scrobble_log updated to {old_data}") print(f"Migrated scrobble logs for {updated_scrobble_count} scrobbles") diff --git a/vrobbler/apps/scrobbles/notifications.py b/vrobbler/apps/scrobbles/notifications.py index 47610a8..ef0f4bc 100644 --- a/vrobbler/apps/scrobbles/notifications.py +++ b/vrobbler/apps/scrobbles/notifications.py @@ -42,9 +42,7 @@ class ScrobbleNtfyNotification(ScrobbleNotification): def __init__(self, scrobble, **kwargs): super().__init__(scrobble) self.ntfy_str: str = f"{self.scrobble.media_obj}" - self.click_url = self.url_tmpl.format( - path=self.media_obj.get_absolute_url() - ) + self.click_url = self.url_tmpl.format(path=self.media_obj.get_absolute_url()) self.title = self.media_obj.strings.verb self.actions = "" if kwargs.get("end", False): @@ -89,11 +87,7 @@ class MoodNtfyNotification(BasicNtfyNotification): self.title = "Mood Check-in!" def send(self): - if ( - self.profile - and self.profile.ntfy_enabled - and self.profile.ntfy_url - ): + if self.profile and self.profile.ntfy_enabled and self.profile.ntfy_url: requests.post( self.profile.ntfy_url, data=self.ntfy_str.encode(encoding="utf-8"), diff --git a/vrobbler/apps/scrobbles/utils.py b/vrobbler/apps/scrobbles/utils.py index b2bcbed..c3857eb 100644 --- a/vrobbler/apps/scrobbles/utils.py +++ b/vrobbler/apps/scrobbles/utils.py @@ -37,9 +37,7 @@ User = get_user_model() def timestamp_user_tz_to_utc(timestamp: int, user_tz: ZoneInfo) -> datetime: - return user_tz.localize(datetime.utcfromtimestamp(timestamp)).astimezone( - pytz.utc - ) + return user_tz.localize(datetime.utcfromtimestamp(timestamp)).astimezone(pytz.utc) def convert_to_seconds(run_time: str) -> int: @@ -150,9 +148,7 @@ def import_lastfm_for_all_users(restart=False): ) continue - lfm_client = LastFM( - user=get_user_model().objects.filter(id=user_id).first() - ) + lfm_client = LastFM(user=get_user_model().objects.filter(id=user_id).first()) has_scrobbles = lfm_client.get_last_scrobbles( time_from=last_processed, check=True @@ -237,9 +233,7 @@ def import_from_webdav_for_all_users(restart=False): webdav_pass__isnull=False, webdav_auto_import=True, ).values_list("user_id", flat=True) - logger.info( - f"start import of {webdav_enabled_user_ids.count()} webdav accounts" - ) + logger.info(f"start import of {webdav_enabled_user_ids.count()} webdav accounts") koreader_import_count = 0 @@ -348,11 +342,7 @@ def send_mood_checkin_reminders() -> int: def extract_domain(url): parsed_url = urlparse(url) - domain = ( - parsed_url.netloc.split(".")[-2] - + "." - + parsed_url.netloc.split(".")[-1] - ) + domain = parsed_url.netloc.split(".")[-2] + "." + parsed_url.netloc.split(".")[-1] return domain @@ -367,20 +357,14 @@ def fix_playback_position_seconds( ) continue - if ( - scrobble.media_type == "Track" - and scrobble.media_obj.run_time_seconds - ): + if scrobble.media_type == "Track" and scrobble.media_obj.run_time_seconds: too_long = ( - scrobble.playback_position_seconds - > scrobble.media_obj.run_time_seconds + scrobble.playback_position_seconds > scrobble.media_obj.run_time_seconds ) zero = scrobble.playback_position_seconds == 0 null = not scrobble.playback_position_seconds if too_long or zero or null: - scrobble.playback_position_seconds = ( - scrobble.media_obj.run_time_seconds - ) + scrobble.playback_position_seconds = scrobble.media_obj.run_time_seconds updated_scrobbles.append(scrobble) if commit: scrobble.save(update_fields=["playback_position_seconds"]) diff --git a/vrobbler/apps/sports/models.py b/vrobbler/apps/sports/models.py index f2ab401..46879ef 100644 --- a/vrobbler/apps/sports/models.py +++ b/vrobbler/apps/sports/models.py @@ -43,9 +43,7 @@ class Sport(TheSportsDbMixin): @property def default_event_run_time(self): - default_run_time = getattr( - settings, "DEFAULT_EVENT_RUNTIME_SECONDS", 14400 - ) + default_run_time = getattr(settings, "DEFAULT_EVENT_RUNTIME_SECONDS", 14400) if self.default_event_run_time_seconds: default_run_time = self.default_event_run_time_seconds return default_run_time @@ -124,7 +122,9 @@ class SportEvent(ScrobblableMixin): ) def __str__(self): - return f"{self.start.date()} - {self.round} - {self.home_team} v {self.away_team}" + return ( + f"{self.start.date()} - {self.round} - {self.home_team} v {self.away_team}" + ) def get_absolute_url(self): return reverse("sports:event_detail", kwargs={"slug": self.uuid}) @@ -206,14 +206,10 @@ class SportEvent(ScrobblableMixin): round.save(update_fields=["name"]) players_list = get_players_from_event(event_name) - player_one = Player.objects.filter( - name__icontains=players_list[0] - ).first() + player_one = Player.objects.filter(name__icontains=players_list[0]).first() if not player_one: player_one = Player.objects.create(name=players_list[0]) - player_two = Player.objects.filter( - name__icontains=players_list[1] - ).first() + player_two = Player.objects.filter(name__icontains=players_list[1]).first() if not player_two: player_two = Player.objects.create(name=players_list[1]) diff --git a/vrobbler/apps/sports/thesportsdb.py b/vrobbler/apps/sports/thesportsdb.py index 1d0ce99..2b894d0 100644 --- a/vrobbler/apps/sports/thesportsdb.py +++ b/vrobbler/apps/sports/thesportsdb.py @@ -21,9 +21,7 @@ def lookup_event_from_thesportsdb(event_id: str) -> dict: if not event or type(event) != dict: return {} - sport, _created = Sport.objects.get_or_create( - thesportsdb_id=event.get("strSport") - ) + sport, _created = Sport.objects.get_or_create(thesportsdb_id=event.get("strSport")) try: start = parse(event.get("strTimestamp")) diff --git a/vrobbler/apps/tasks/utils.py b/vrobbler/apps/tasks/utils.py index 078690d..a5d9221 100644 --- a/vrobbler/apps/tasks/utils.py +++ b/vrobbler/apps/tasks/utils.py @@ -29,9 +29,7 @@ def get_title_from_labels( def convert_old_orgmode_log_to_new(commit=False): - scrobbles = Scrobble.objects.filter( - source="Org-mode", log__has_key="drawers" - ) + scrobbles = Scrobble.objects.filter(source="Org-mode", log__has_key="drawers") for scrobble in scrobbles: scrobble.log["title"] = scrobble.log.pop("description") scrobble.log["description"] = scrobble.log.pop("details") @@ -49,9 +47,7 @@ def convert_old_orgmode_log_to_new(commit=False): def convert_old_todoist_log_to_new(commit=False): - scrobbles = Scrobble.objects.filter( - source="Todoist", log__has_key="todoist_type" - ) + scrobbles = Scrobble.objects.filter(source="Todoist", log__has_key="todoist_type") for scrobble in scrobbles: scrobble.log["title"] = scrobble.log.pop("description") scrobble.log["description"] = scrobble.log.pop("details") @@ -94,9 +90,7 @@ def convert_notes_to_dict(commit=False): def convert_old_boardgame_log_to_new(commit=False): - scrobbles = Scrobble.objects.filter( - board_game__isnull=False, log__has_key="notes" - ) + scrobbles = Scrobble.objects.filter(board_game__isnull=False, log__has_key="notes") for scrobble in scrobbles: if isinstance(scrobble.log.get("notes"), str): scrobble.log["notes"] = [scrobble.log.pop("notes")] diff --git a/vrobbler/apps/tasks/webhooks.py b/vrobbler/apps/tasks/webhooks.py index 5ae512a..21b8fab 100644 --- a/vrobbler/apps/tasks/webhooks.py +++ b/vrobbler/apps/tasks/webhooks.py @@ -34,20 +34,14 @@ def todoist_webhook(request): is_note_type = todoist_tyllll = "note" new_labels = event_data.get("labels", []) old_labels = ( - post_data.get("event_data_extra", {}) - .get("old_item", {}) - .get("labels", []) + post_data.get("event_data_extra", {}).get("old_item", {}).get("labels", []) ) # TODO Don't hard code status strings in here is_updated = todoist_event in ["updated"] is_added = todoist_event in ["added"] - task_started = ( - "inprogress" in new_labels and "inprogress" not in old_labels - ) - task_stopped = ( - "inprogress" not in new_labels and "inprogress" in old_labels - ) + task_started = "inprogress" in new_labels and "inprogress" not in old_labels + task_stopped = "inprogress" not in new_labels and "inprogress" in old_labels if is_item_type and is_updated and (task_started or task_stopped): todoist_task = { @@ -71,9 +65,7 @@ def todoist_webhook(request): "updated_at": task_data.get("updated_at"), "details": task_data.get("description"), "notes": event_data.get("content"), - "is_deleted": ( - True if event_data.get("is_deleted") == "true" else False - ), + "is_deleted": (True if event_data.get("is_deleted") == "true" else False), } if (is_added and not todoist_note) or (is_updated and not todoist_task): @@ -104,9 +96,7 @@ def todoist_webhook(request): ) if todoist_note: - scrobble = todoist_scrobble_update_task( - todoist_note, user_profile.user_id - ) + scrobble = todoist_scrobble_update_task(todoist_note, user_profile.user_id) if not scrobble: logger.info( diff --git a/vrobbler/apps/trails/models.py b/vrobbler/apps/trails/models.py index b771b1a..8c99db0 100644 --- a/vrobbler/apps/trails/models.py +++ b/vrobbler/apps/trails/models.py @@ -72,6 +72,6 @@ class Trail(ScrobblableMixin): def scrobbles(self, user_id): Scrobble = apps.get_model("scrobbles", "Scrobble") - return Scrobble.objects.filter( - user_id=user_id, life_event=self - ).order_by("-timestamp") + return Scrobble.objects.filter(user_id=user_id, life_event=self).order_by( + "-timestamp" + ) diff --git a/vrobbler/apps/videogames/howlongtobeat.py b/vrobbler/apps/videogames/howlongtobeat.py index 8beb7ea..863cf44 100644 --- a/vrobbler/apps/videogames/howlongtobeat.py +++ b/vrobbler/apps/videogames/howlongtobeat.py @@ -37,9 +37,7 @@ def lookup_game_from_hltb(name_or_id: str) -> Optional[dict]: found_games = [] for g in results: found_games.append(f"{g.game_name} ({g.game_id})") - logger.info( - f"Found more than one match {found_games}, taking {hltb_game}" - ) + logger.info(f"Found more than one match {found_games}, taking {hltb_game}") game_dict = { "title": hltb_game.game_name, diff --git a/vrobbler/apps/videogames/igdb.py b/vrobbler/apps/videogames/igdb.py index a8571c7..0ae46cc 100644 --- a/vrobbler/apps/videogames/igdb.py +++ b/vrobbler/apps/videogames/igdb.py @@ -29,9 +29,7 @@ User = get_user_model() def get_igdb_token() -> str: - token_url = REFRESH_TOKEN_URL.format( - id=IGDB_CLIENT_ID, secret=IGDB_CLIENT_SECRET - ) + token_url = REFRESH_TOKEN_URL.format(id=IGDB_CLIENT_ID, secret=IGDB_CLIENT_SECRET) response = requests.post(token_url) results = json.loads(response.content) return results.get("access_token") @@ -100,9 +98,9 @@ def lookup_game_from_igdb(name_or_igdb_id: str) -> Dict: alt_name = game.get("alternative_names")[0].get("name") screenshot_url = None if "screenshots" in game.keys(): - screenshot_url = "https:" + game.get("screenshots")[0].get( - "url" - ).replace("t_thumb", "t_screenshot_big_2x") + screenshot_url = "https:" + game.get("screenshots")[0].get("url").replace( + "t_thumb", "t_screenshot_big_2x" + ) cover_url = None if "cover" in game.keys(): cover_url = "https:" + game.get("cover").get("url").replace( diff --git a/vrobbler/apps/videogames/models.py b/vrobbler/apps/videogames/models.py index 9cda534..df65e6d 100644 --- a/vrobbler/apps/videogames/models.py +++ b/vrobbler/apps/videogames/models.py @@ -58,9 +58,7 @@ class VideoGamePlatform(TimeStampedModel): return self.name def get_absolute_url(self): - return reverse( - "videogames:platform_detail", kwargs={"slug": self.uuid} - ) + return reverse("videogames:platform_detail", kwargs={"slug": self.uuid}) class VideoGameCollection(TimeStampedModel): @@ -85,9 +83,7 @@ class VideoGameCollection(TimeStampedModel): return self.name def get_absolute_url(self): - return reverse( - "videogames:collection_detail", kwargs={"slug": self.uuid} - ) + return reverse("videogames:collection_detail", kwargs={"slug": self.uuid}) class VideoGame(LongPlayScrobblableMixin): @@ -188,9 +184,7 @@ class VideoGame(LongPlayScrobblableMixin): return url def get_absolute_url(self): - return reverse( - "videogames:videogame_detail", kwargs={"slug": self.uuid} - ) + return reverse("videogames:videogame_detail", kwargs={"slug": self.uuid}) def hltb_link(self): return f"https://howlongtobeat.com/game/{self.hltb_id}" diff --git a/vrobbler/apps/videogames/retroarch.py b/vrobbler/apps/videogames/retroarch.py index b1b90f1..a8c5aa4 100644 --- a/vrobbler/apps/videogames/retroarch.py +++ b/vrobbler/apps/videogames/retroarch.py @@ -98,9 +98,7 @@ def import_retroarch_lrtl_files(playlog_path: str, user_id: int) -> List[dict]: logger.warning(f"User ID {user_id} is not valid, cannot scrobble") raise UserNotFound - game_logs = load_game_data( - playlog_path, pytz.timezone(user.profile.timezone) - ) + game_logs = load_game_data(playlog_path, pytz.timezone(user.profile.timezone)) found_game = None new_scrobbles = [] @@ -130,9 +128,7 @@ def import_retroarch_lrtl_files(playlog_path: str, user_id: int) -> List[dict]: # Found a game, check if scrobble exists end_datetime = game_data.get("last_played") - found_scrobble = found_game.scrobble_set.filter( - stop_timestamp=end_datetime - ) + found_scrobble = found_game.scrobble_set.filter(stop_timestamp=end_datetime) if found_scrobble: logger.info(f"Skipping scrobble for game {found_game.id}") continue diff --git a/vrobbler/apps/videogames/scrapers.py b/vrobbler/apps/videogames/scrapers.py index 57bb01f..6c6720b 100644 --- a/vrobbler/apps/videogames/scrapers.py +++ b/vrobbler/apps/videogames/scrapers.py @@ -8,7 +8,9 @@ from vrobbler.apps.videogames.exceptions import GameNotFound logger = logging.getLogger(__name__) -MAME_LOOKUP_URL = "http://adb.arcadeitalia.net/dettaglio_mame.php?game_name={query}&search_id=2" +MAME_LOOKUP_URL = ( + "http://adb.arcadeitalia.net/dettaglio_mame.php?game_name={query}&search_id=2" +) def _strip_and_clean(text): diff --git a/vrobbler/apps/videogames/utils.py b/vrobbler/apps/videogames/utils.py index b1c87e3..8b4e82d 100644 --- a/vrobbler/apps/videogames/utils.py +++ b/vrobbler/apps/videogames/utils.py @@ -32,9 +32,7 @@ def get_or_create_videogame( platforms = game_dict.get("platforms", []) if platforms: for platform in game_dict.get("platforms", []): - p, _created = VideoGamePlatform.objects.get_or_create( - name=platform - ) + p, _created = VideoGamePlatform.objects.get_or_create(name=platform) platform_ids.append(p.id) game_dict.pop("platforms") @@ -98,9 +96,7 @@ def get_or_create_videogame( return game -def load_game_data_from_igdb( - game_id: int, igdb_id: str = "" -) -> Optional[VideoGame]: +def load_game_data_from_igdb(game_id: int, igdb_id: str = "") -> Optional[VideoGame]: """Look up game, if it doesn't exist, lookup data from igdb""" game = VideoGame.objects.filter(id=game_id).first() if not game: diff --git a/vrobbler/apps/videos/api/serializers.py b/vrobbler/apps/videos/api/serializers.py index b9b2aad..fca01ca 100644 --- a/vrobbler/apps/videos/api/serializers.py +++ b/vrobbler/apps/videos/api/serializers.py @@ -15,9 +15,7 @@ class SeriesSerializer(serializers.HyperlinkedModelSerializer): class VideoSerializer(serializers.HyperlinkedModelSerializer): - channel = serializers.PrimaryKeyRelatedField( - queryset=Channel.objects.all() - ) + channel = serializers.PrimaryKeyRelatedField(queryset=Channel.objects.all()) tv_series = serializers.PrimaryKeyRelatedField( queryset=Series.objects.all(), required=False, allow_null=True ) diff --git a/vrobbler/apps/videos/management/commands/find_video.py b/vrobbler/apps/videos/management/commands/find_video.py index daedb5b..e53337f 100644 --- a/vrobbler/apps/videos/management/commands/find_video.py +++ b/vrobbler/apps/videos/management/commands/find_video.py @@ -8,22 +8,18 @@ class Command(BaseCommand): help = "Find or create a Video by ID and output it as JSON" def add_arguments(self, parser): - parser.add_argument( - "video_id", type=str, help="The video ID to find or create" - ) + parser.add_argument("video_id", type=str, help="The video ID to find or create") def handle(self, *args, **options): - instance = Video.find_or_create( - options.get("video_id", ""), overwrite=True - ) + instance = Video.find_or_create(options.get("video_id", ""), overwrite=True) data = json.loads(serializers.serialize("json", [instance]))[0] # --- Enrich with series model --- if instance.tv_series_id: series_instance = instance.tv_series - series_json = json.loads( - serializers.serialize("json", [series_instance]) - )[0] + series_json = json.loads(serializers.serialize("json", [series_instance]))[ + 0 + ] data["series"] = series_json # new nested field if instance.channel_id: diff --git a/vrobbler/apps/videos/sources/skatevideosite.py b/vrobbler/apps/videos/sources/skatevideosite.py index 90a5d5b..ef08bef 100644 --- a/vrobbler/apps/videos/sources/skatevideosite.py +++ b/vrobbler/apps/videos/sources/skatevideosite.py @@ -7,9 +7,7 @@ import logging logger = logging.getLogger(__name__) -USER_AGENT = ( - "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0" -) +USER_AGENT = "Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0" SKATEVIDEOSITE_URL = "https://www.skatevideosite.com" SKATEVIDEOSITE_SEARCH_URL = SKATEVIDEOSITE_URL + "/search/?q={title}" diff --git a/vrobbler/apps/videos/sources/tmdb.py b/vrobbler/apps/videos/sources/tmdb.py index e08f9aa..5b0f6c2 100644 --- a/vrobbler/apps/videos/sources/tmdb.py +++ b/vrobbler/apps/videos/sources/tmdb.py @@ -18,9 +18,7 @@ TMDB_IMAGE_URL = "https://image.tmdb.org/t/p/original" logger = logging.getLogger(__name__) -def lookup_video_from_tmdb( - name_or_id: str, kind: str = "movie" -) -> VideoMetadata: +def lookup_video_from_tmdb(name_or_id: str, kind: str = "movie") -> VideoMetadata: from videos.models import Series imdb_id = name_or_id diff --git a/vrobbler/apps/videos/sources/youtube.py b/vrobbler/apps/videos/sources/youtube.py index 01f723d..fddc992 100644 --- a/vrobbler/apps/videos/sources/youtube.py +++ b/vrobbler/apps/videos/sources/youtube.py @@ -26,14 +26,10 @@ def lookup_video_from_youtube(youtube_id: str) -> VideoMetadata: response = requests.get(url, headers=headers) if response.status_code != 200: - logger.warning( - "Bad response from Google", extra={"response": response} - ) + logger.warning("Bad response from Google", extra={"response": response}) return video_metadata - yt_metadata = ( - json.loads(response.content).get("items", [None])[0].get("snippet") - ) + yt_metadata = json.loads(response.content).get("items", [None])[0].get("snippet") duration_iso8601 = ( json.loads(response.content) .get("items", [None])[0] diff --git a/vrobbler/apps/videos/utils.py b/vrobbler/apps/videos/utils.py index 94c3bc0..f4779c4 100644 --- a/vrobbler/apps/videos/utils.py +++ b/vrobbler/apps/videos/utils.py @@ -19,9 +19,7 @@ def clean_up_videos(): try: video.save(update_fields=["imdb_id"]) except IntegrityError: - new_video = Video.objects.filter( - imdb_id="tt" + video.imdb_id - ).first() + new_video = Video.objects.filter(imdb_id="tt" + video.imdb_id).first() video.scrobble_set.all().update(video=new_video) video.delete() diff --git a/vrobbler/apps/videos/views.py b/vrobbler/apps/videos/views.py index dc86c20..ab419d8 100644 --- a/vrobbler/apps/videos/views.py +++ b/vrobbler/apps/videos/views.py @@ -32,9 +32,7 @@ class SeriesDetailView(LoginRequiredMixin, ChartContextMixin, generic.DetailView context_data = super().get_context_data(**kwargs) context_data["scrobbles"] = self.object.scrobbles_for_user(user_id) - next_episode_id = ( - self.object.last_scrobbled_episode(user_id).next_imdb_id or "" - ) + next_episode_id = self.object.last_scrobbled_episode(user_id).next_imdb_id or "" if self.object.is_episode_playing(user_id): next_episode_id = "" if next_episode_id: @@ -96,10 +94,7 @@ class VideoListView(ScrobbleableListView): if channel: channels_this_week[channel.id] = { "channel": channel, - "count": channels_this_week.get(channel.id, {}).get( - "count", 0 - ) - + 1, + "count": channels_this_week.get(channel.id, {}).get("count", 0) + 1, } channels_this_month = {} @@ -108,9 +103,7 @@ class VideoListView(ScrobbleableListView): if channel: channels_this_month[channel.id] = { "channel": channel, - "count": channels_this_month.get(channel.id, {}).get( - "count", 0 - ) + "count": channels_this_month.get(channel.id, {}).get("count", 0) + 1, } diff --git a/vrobbler/apps/webpages/models.py b/vrobbler/apps/webpages/models.py index b2cbcef..89b37e5 100644 --- a/vrobbler/apps/webpages/models.py +++ b/vrobbler/apps/webpages/models.py @@ -39,9 +39,9 @@ class Domain(TimeStampedModel): def scrobbles_for_user(self, user_id): from scrobbles.models import Scrobble - return Scrobble.objects.filter( - web_page__domain=self, user_id=user_id - ).order_by("-timestamp") + return Scrobble.objects.filter(web_page__domain=self, user_id=user_id).order_by( + "-timestamp" + ) class WebPage(ScrobblableMixin): @@ -136,9 +136,7 @@ class WebPage(ScrobblableMixin): def scrobbles(self, user): Scrobble = apps.get_model("scrobbles", "Scrobble") - return Scrobble.objects.filter(user=user, web_page=self).order_by( - "-timestamp" - ) + return Scrobble.objects.filter(user=user, web_page=self).order_by("-timestamp") def clean_title(self, title: str, save=True): if len(title.split("|")) > 1: @@ -213,9 +211,7 @@ class WebPage(ScrobblableMixin): return if response.status_code == 200: - logger.info( - "Website already exists in archive", extra={"url": self.url} - ) + logger.info("Website already exists in archive", extra={"url": self.url}) else: raise Exception( f"Failed to push URL to archivebox (Response {response.status_code})" diff --git a/vrobbler/apps/webpages/views.py b/vrobbler/apps/webpages/views.py index f0577b2..9f6c5a2 100644 --- a/vrobbler/apps/webpages/views.py +++ b/vrobbler/apps/webpages/views.py @@ -40,10 +40,7 @@ class WebPageListView(ScrobbleableListView): if domain: domains_this_week[domain.id] = { "domain": domain, - "count": domains_this_week.get(domain.id, {}).get( - "count", 0 - ) - + 1, + "count": domains_this_week.get(domain.id, {}).get("count", 0) + 1, } domains_this_month = {} @@ -52,10 +49,7 @@ class WebPageListView(ScrobbleableListView): if domain: domains_this_month[domain.id] = { "domain": domain, - "count": domains_this_month.get(domain.id, {}).get( - "count", 0 - ) - + 1, + "count": domains_this_month.get(domain.id, {}).get("count", 0) + 1, } context_data["domains_this_week"] = sorted( @@ -82,9 +76,7 @@ class WebPageDetailView(ScrobbleableDetailView): return context -class WebPageReadView( - LoginRequiredMixin, generic.edit.FormView, generic.DetailView -): +class WebPageReadView(LoginRequiredMixin, generic.edit.FormView, generic.DetailView): model = WebPage slug_field = "uuid" template_name = "webpages/webpage_read.html" @@ -95,11 +87,7 @@ class WebPageReadView( webpage = WebPage.objects.get(uuid=kwargs.get("slug")) latest_scrobble = webpage.scrobbles(user).last() if latest_scrobble.played_to_completion: - redirect( - reverse( - "webpages:webpage_detail", kwargs={"slug": webpage.uuid} - ) - ) + redirect(reverse("webpages:webpage_detail", kwargs={"slug": webpage.uuid})) return super().get(*args, **kwargs) def form_valid(self, *args): diff --git a/vrobbler/health_check.py b/vrobbler/health_check.py index d4e9154..c7504b6 100644 --- a/vrobbler/health_check.py +++ b/vrobbler/health_check.py @@ -19,9 +19,7 @@ class HealthCheckMiddleware: is_db_connected = False else: is_db_connected = True - logger.info( - "[health-check]", extra={"is_db_connected": is_db_connected} - ) + logger.info("[health-check]", extra={"is_db_connected": is_db_connected}) if is_db_connected: return HttpResponse("ok") return self.get_response(request) diff --git a/vrobbler/settings.py b/vrobbler/settings.py index 491145a..c951f01 100644 --- a/vrobbler/settings.py +++ b/vrobbler/settings.py @@ -37,9 +37,7 @@ TESTING = len(sys.argv) > 1 and sys.argv[1] == "test" TAGGIT_CASE_INSENSITIVE = True -KEEP_DETAILED_SCROBBLE_LOGS = os.getenv( - "VROBBLER_KEEP_DETAILED_SCROBBLE_LOGS", False -) +KEEP_DETAILED_SCROBBLE_LOGS = os.getenv("VROBBLER_KEEP_DETAILED_SCROBBLE_LOGS", False) # Key must be 16, 24 or 32 bytes long and will be converted to a byte stream ENCRYPTED_FIELD_KEY = os.getenv( @@ -54,9 +52,7 @@ DELETE_STALE_SCROBBLES = ( ) # Used to dump data coming from srobbling sources, helpful for building new inputs -DUMP_REQUEST_DATA = ( - os.getenv("VROBBLER_DUMP_REQUEST_DATA", "false").lower() in TRUTHY -) +DUMP_REQUEST_DATA = os.getenv("VROBBLER_DUMP_REQUEST_DATA", "false").lower() in TRUTHY USDA_API_KEY = os.getenv("VROBBLER_USDA_API_KEY") THESPORTSDB_API_KEY = os.getenv("VROBBLER_THESPORTSDB_API_KEY", "2") @@ -72,9 +68,7 @@ COMICVINE_API_KEY = os.getenv("VROBBLER_COMICVINE_API_KEY") BGG_ACCESS_TOKEN = os.getenv("VROBBLER_BGG_ACCESS_TOKEN", "") GEOLOC_ACCURACY = os.getenv("VROBBLER_GEOLOC_ACCURACY", 3) GEOLOC_PROXIMITY = os.getenv("VROBBLER_GEOLOC_PROXIMITY", "0.0001") -POINTS_FOR_MOVEMENT_HISTORY = os.getenv( - "VROBBLER_POINTS_FOR_MOVEMENT_HISTORY", 3 -) +POINTS_FOR_MOVEMENT_HISTORY = os.getenv("VROBBLER_POINTS_FOR_MOVEMENT_HISTORY", 3) TODOIST_CLIENT_ID = os.getenv("VROBBLER_TODOIST_CLIENT_ID", "") TODOIST_CLIENT_SECRET = os.getenv("VROBBLER_TODOIST_CLIENT_SECRET", "") @@ -97,9 +91,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" TIME_ZONE = os.getenv("VROBBLER_TIME_ZONE", "America/New_York") ALLOWED_HOSTS = ["*"] -CSRF_TRUSTED_ORIGINS = [ - os.getenv("VROBBLER_TRUSTED_ORIGINS", "http://localhost:8000") -] +CSRF_TRUSTED_ORIGINS = [os.getenv("VROBBLER_TRUSTED_ORIGINS", "http://localhost:8000")] X_FRAME_OPTIONS = "SAMEORIGIN" REDIS_URL = os.getenv("VROBBLER_REDIS_URL", None) @@ -108,9 +100,7 @@ if REDIS_URL: else: print("Eagerly running all tasks") -CELERY_TASK_ALWAYS_EAGER = ( - os.getenv("VROBBLER_SKIP_CELERY", "false").lower() in TRUTHY -) +CELERY_TASK_ALWAYS_EAGER = os.getenv("VROBBLER_SKIP_CELERY", "false").lower() in TRUTHY CELERY_BROKER_URL = REDIS_URL if REDIS_URL else "memory://localhost/" CELERY_RESULT_BACKEND = "django-db" CELERY_TIMEZONE = os.getenv("VROBBLER_TIME_ZONE", "America/New_York") @@ -231,9 +221,7 @@ DATABASES = { } if TESTING: - DATABASES = { - "default": dj_database_url.config(default="sqlite:///testdb.sqlite3") - } + DATABASES = {"default": dj_database_url.config(default="sqlite:///testdb.sqlite3")} db_str = "" if "sqlite" in DATABASES["default"]["ENGINE"]: @@ -269,9 +257,7 @@ REST_FRAMEWORK = { "rest_framework.authentication.SessionAuthentication", ], "DEFAULT_CONTENT_NEGOTIATION_CLASS": "vrobbler.negotiation.IgnoreClientContentNegotiation", - "DEFAULT_FILTER_BACKENDS": [ - "django_filters.rest_framework.DjangoFilterBackend" - ], + "DEFAULT_FILTER_BACKENDS": ["django_filters.rest_framework.DjangoFilterBackend"], "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination", "PAGE_SIZE": 200, } @@ -331,9 +317,7 @@ else: STATIC_ROOT = os.getenv( "VROBBLER_STATIC_ROOT", os.path.join(PROJECT_ROOT, "static") ) - MEDIA_ROOT = os.getenv( - "VROBBLER_MEDIA_ROOT", os.path.join(PROJECT_ROOT, "media") - ) + MEDIA_ROOT = os.getenv("VROBBLER_MEDIA_ROOT", os.path.join(PROJECT_ROOT, "media")) STATIC_URL = os.getenv("VROBBLER_STATIC_URL", "/static/") MEDIA_URL = os.getenv("VROBBLER_MEDIA_URL", "/media/") @@ -417,9 +401,7 @@ LOGGING = { }, } -LOG_TO_CONSOLE = ( - os.getenv("VROBBLER_LOG_TO_CONSOLE", "false").lower() in TRUTHY -) +LOG_TO_CONSOLE = os.getenv("VROBBLER_LOG_TO_CONSOLE", "false").lower() in TRUTHY if LOG_TO_CONSOLE: LOGGING["loggers"]["django"]["handlers"] = ["console"] LOGGING["loggers"]["vrobbler"]["handlers"] = ["console"]