From 6d5f014134d7d70db9c00efc0922e04fd3c912d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Hells=C3=A9n?= Date: Mon, 1 Sep 2025 21:50:38 +0200 Subject: [PATCH] Make Owner optional; use dateparser to parse dates; use json-repair to read JSON --- powerboi.ps1 | 83 +++-- pyproject.toml | 2 + templates/twitch/campaign_detail.html | 11 +- templates/twitch/campaign_list.html | 12 +- templates/twitch/dashboard.html | 4 +- twitch/admin.py | 8 +- twitch/management/commands/import_drops.py | 311 ++++++---------- ...ons_alter_dropcampaign_options_and_more.py | 272 ++++++++++++++ .../0007_remove_game_unique_game_slug.py | 17 + twitch/models.py | 349 +++++++++++++----- twitch/views.py | 109 +++--- uv.lock | 121 ++++-- 12 files changed, 852 insertions(+), 447 deletions(-) create mode 100644 twitch/migrations/0006_alter_dropbenefit_options_alter_dropcampaign_options_and_more.py create mode 100644 twitch/migrations/0007_remove_game_unique_game_slug.py diff --git a/powerboi.ps1 b/powerboi.ps1 index c444d18..7e6f9e1 100644 --- a/powerboi.ps1 +++ b/powerboi.ps1 @@ -1,6 +1,6 @@ -$src = "D:\broken" +$src = "C:\Responses\processed" $dest = "C:\Responses" -$deg = 16000 +$deg = 16000 # What to do when a destination file with the same name exists and contents are identical. # Options: 'skip' - do not move the source (leave it where it is) @@ -10,48 +10,49 @@ $SameFileAction = 'skip' New-Item -ItemType Directory -Path $dest -Force | Out-Null Get-ChildItem -Path $src -Filter *.json -Recurse -File | - ForEach-Object -Parallel { - $dest = $using:dest - # copy the using-scoped setting into a local variable for safe use inside the scriptblock - $sameAction = $using:SameFileAction - $name = $_.Name - $target = Join-Path $dest $name +ForEach-Object -Parallel { + $dest = $using:dest + # copy the using-scoped setting into a local variable for safe use inside the scriptblock + $sameAction = $using:SameFileAction + $name = $_.Name + $target = Join-Path $dest $name - if (Test-Path -LiteralPath $target) { - # Try comparing contents by hash. If identical, either skip or overwrite based on $using:SameFileAction. - try { - $srcHash = Get-FileHash -Algorithm SHA256 -Path $_.FullName - $dstHash = Get-FileHash -Algorithm SHA256 -Path $target - if ($srcHash.Hash -eq $dstHash.Hash) { - switch ($sameAction.ToLower()) { - 'skip' { - Write-Verbose "Skipping move for identical file: $name" - return - } - 'overwrite' { - Move-Item -LiteralPath $_.FullName -Destination $target -Force - return - } - default { - Write-Verbose "Unknown SameFileAction '$sameAction', skipping $name" - return - } + if (Test-Path -LiteralPath $target) { + # Try comparing contents by hash. If identical, either skip or overwrite based on $using:SameFileAction. + try { + $srcHash = Get-FileHash -Algorithm SHA256 -Path $_.FullName + $dstHash = Get-FileHash -Algorithm SHA256 -Path $target + if ($srcHash.Hash -eq $dstHash.Hash) { + switch ($sameAction.ToLower()) { + 'skip' { + Write-Verbose "Skipping move for identical file: $name" + return + } + 'overwrite' { + Move-Item -LiteralPath $_.FullName -Destination $target -Force + return + } + default { + Write-Verbose "Unknown SameFileAction '$sameAction', skipping $name" + return } } - } catch { - # If hashing failed for any reason, fall back to the existing collision-avoidance behavior. - Write-Verbose "Hash comparison failed for $($name): $($_)" - } - - # If we reach here, target exists and contents differ: find a non-colliding name (foo (1).json, etc.) - $i = 1 - while (Test-Path -LiteralPath $target) { - $base = [IO.Path]::GetFileNameWithoutExtension($name) - $ext = [IO.Path]::GetExtension($name) - $target = Join-Path $dest ("{0} ({1}){2}" -f $base,$i,$ext) - $i++ } } + catch { + # If hashing failed for any reason, fall back to the existing collision-avoidance behavior. + Write-Verbose "Hash comparison failed for $($name): $($_)" + } - Move-Item -LiteralPath $_.FullName -Destination $target -Force - } -ThrottleLimit $deg \ No newline at end of file + # If we reach here, target exists and contents differ: find a non-colliding name (foo (1).json, etc.) + $i = 1 + while (Test-Path -LiteralPath $target) { + $base = [IO.Path]::GetFileNameWithoutExtension($name) + $ext = [IO.Path]::GetExtension($name) + $target = Join-Path $dest ("{0} ({1}){2}" -f $base, $i, $ext) + $i++ + } + } + + Move-Item -LiteralPath $_.FullName -Destination $target -Force +} -ThrottleLimit $deg \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 3fd3c18..008a2e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,12 +5,14 @@ description = "Get notified when a new drop is available on Twitch." readme = "README.md" requires-python = ">=3.13" dependencies = [ + "dateparser>=1.2.2", "django-browser-reload>=1.18.0", "django-debug-toolbar>=5.2.0", "django-stubs[compatible-mypy]>=5.2.2", "django-watchfiles>=1.1.0", "django>=5.2.4", "djlint>=1.36.4", + "json-repair>=0.50.0", "orjson>=3.11.1", "platformdirs>=4.3.8", "python-dotenv>=1.1.1", diff --git a/templates/twitch/campaign_detail.html b/templates/twitch/campaign_detail.html index aa79fde..001a20a 100644 --- a/templates/twitch/campaign_detail.html +++ b/templates/twitch/campaign_detail.html @@ -7,10 +7,13 @@

{{ campaign.game.display_name }} - {{ campaign.clean_name }}

-

- {# TODO: Link to organization #} - {{ campaign.owner.name }} -

+ {% if campaign.owner %} +

+ {{ campaign.owner.name }} +

+ {% else %} +

Organization Unknown

+ {% endif %} {% if campaign.image_url %}
+ {% comment %} Find this header section in your template {% endcomment %}

{{ game_group.grouper.display_name|default:game_group.grouper.name|default:game_group.grouper.slug|default:game_group.grouper.id }}

-

- {{ game_group.list.0.owner.name }} -

+ {% comment %} MODIFICATION: Check if the owner exists before creating the link {% endcomment %} + {% if game_group.grouper.owner %} +

+ {{ game_group.grouper.owner.name }} +

+ {% endif %}
diff --git a/templates/twitch/dashboard.html b/templates/twitch/dashboard.html index 13beab9..5433624 100644 --- a/templates/twitch/dashboard.html +++ b/templates/twitch/dashboard.html @@ -69,7 +69,7 @@ Hover over the end time to see the exact date and time. Started {{ campaign.start_at|timesince }} ago