Rewrite aimport_json()
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"adownload",
|
||||||
"aimport",
|
"aimport",
|
||||||
"allauth",
|
"allauth",
|
||||||
"appendonly",
|
"appendonly",
|
||||||
|
@ -73,11 +73,12 @@ async def add_reward_campaign(reward_campaign: dict | None) -> None:
|
|||||||
logger.info("Added reward campaign %s", our_reward_campaign)
|
logger.info("Added reward campaign %s", our_reward_campaign)
|
||||||
|
|
||||||
|
|
||||||
async def add_drop_campaign(drop_campaign: dict | None) -> None:
|
async def add_drop_campaign(drop_campaign: dict | None, *, local: bool) -> None:
|
||||||
"""Add a drop campaign to the database.
|
"""Add a drop campaign to the database.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
drop_campaign (dict): The drop campaign to add.
|
drop_campaign (dict): The drop campaign to add.
|
||||||
|
local (bool): Only update status if we are scraping from the Twitch directly.
|
||||||
"""
|
"""
|
||||||
if not drop_campaign:
|
if not drop_campaign:
|
||||||
return
|
return
|
||||||
@ -101,7 +102,7 @@ async def add_drop_campaign(drop_campaign: dict | None) -> None:
|
|||||||
logger.info("Added game %s", game)
|
logger.info("Added game %s", game)
|
||||||
|
|
||||||
our_drop_campaign, created = await DropCampaign.objects.aupdate_or_create(twitch_id=drop_campaign["id"])
|
our_drop_campaign, created = await DropCampaign.objects.aupdate_or_create(twitch_id=drop_campaign["id"])
|
||||||
await our_drop_campaign.aimport_json(drop_campaign, game)
|
await our_drop_campaign.aimport_json(drop_campaign, game, scraping_local_files=local)
|
||||||
if created:
|
if created:
|
||||||
logger.info("Added drop campaign %s", our_drop_campaign.twitch_id)
|
logger.info("Added drop campaign %s", our_drop_campaign.twitch_id)
|
||||||
|
|
||||||
@ -129,14 +130,14 @@ async def add_time_based_drops(drop_campaign: dict, our_drop_campaign: DropCampa
|
|||||||
raise NotImplementedError(msg)
|
raise NotImplementedError(msg)
|
||||||
|
|
||||||
our_time_based_drop, created = await TimeBasedDrop.objects.aupdate_or_create(twitch_id=time_based_drop["id"])
|
our_time_based_drop, created = await TimeBasedDrop.objects.aupdate_or_create(twitch_id=time_based_drop["id"])
|
||||||
await our_time_based_drop.aimport_json(time_based_drop, our_drop_campaign)
|
await our_time_based_drop.aimport_json(data=time_based_drop, drop_campaign=our_drop_campaign)
|
||||||
|
|
||||||
if created:
|
if created:
|
||||||
logger.info("Added time-based drop %s", our_time_based_drop.twitch_id)
|
logger.info("Added time-based drop %s", our_time_based_drop.twitch_id)
|
||||||
|
|
||||||
if our_time_based_drop and time_based_drop.get("benefitEdges"):
|
if our_time_based_drop and time_based_drop.get("benefitEdges"):
|
||||||
for benefit_edge in time_based_drop["benefitEdges"]:
|
for benefit_edge in time_based_drop["benefitEdges"]:
|
||||||
benefit, created = await Benefit.objects.aupdate_or_create(twitch_id=benefit_edge["benefit"])
|
benefit, created = await Benefit.objects.aupdate_or_create(twitch_id=benefit_edge["benefit"]["id"])
|
||||||
await benefit.aimport_json(benefit_edge["benefit"], our_time_based_drop)
|
await benefit.aimport_json(benefit_edge["benefit"], our_time_based_drop)
|
||||||
if created:
|
if created:
|
||||||
logger.info("Added benefit %s", benefit.twitch_id)
|
logger.info("Added benefit %s", benefit.twitch_id)
|
||||||
@ -194,7 +195,7 @@ async def process_json_data(num: int, campaign: dict | None, *, local: bool) ->
|
|||||||
await add_reward_campaign(reward_campaign=reward_campaign)
|
await add_reward_campaign(reward_campaign=reward_campaign)
|
||||||
|
|
||||||
if campaign.get("data", {}).get("user", {}).get("dropCampaign"):
|
if campaign.get("data", {}).get("user", {}).get("dropCampaign"):
|
||||||
await add_drop_campaign(drop_campaign=campaign["data"]["user"]["dropCampaign"])
|
await add_drop_campaign(drop_campaign=campaign["data"]["user"]["dropCampaign"], local=local)
|
||||||
|
|
||||||
if campaign.get("data", {}).get("currentUser", {}).get("dropCampaigns"):
|
if campaign.get("data", {}).get("currentUser", {}).get("dropCampaigns"):
|
||||||
for drop_campaign in campaign["data"]["currentUser"]["dropCampaigns"]:
|
for drop_campaign in campaign["data"]["currentUser"]["dropCampaigns"]:
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
# Generated by Django 5.1 on 2024-09-01 22:36
|
# Generated by Django 5.1 on 2024-09-01 22:36
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
import django.contrib.auth.models
|
import django.contrib.auth.models
|
||||||
import django.contrib.auth.validators
|
import django.contrib.auth.validators
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import django.utils.timezone
|
import django.utils.timezone
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.db.migrations.operations.base import Operation
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
# Generated by Django 5.1 on 2024-09-02 23:28
|
# Generated by Django 5.1 on 2024-09-02 23:28
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
from django.db.migrations.operations.base import Operation
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
# Generated by Django 5.1 on 2024-09-07 19:19
|
# Generated by Django 5.1 on 2024-09-07 19:19
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
from django.db.migrations.operations.base import Operation
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
# Generated by Django 5.1 on 2024-09-09 02:34
|
# Generated by Django 5.1 on 2024-09-09 02:34
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from django.db.migrations.operations.base import Operation
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
# Generated by Django 5.1 on 2024-09-15 19:40
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies: list[tuple[str, str]] = [
|
||||||
|
("core", "0004_alter_dropcampaign_name_alter_game_box_art_url_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations: list[Operation] = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="benefit",
|
||||||
|
options={"ordering": ["-twitch_created_at"]},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="dropcampaign",
|
||||||
|
options={"ordering": ["ends_at"]},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="reward",
|
||||||
|
options={"ordering": ["-earnable_until"]},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="rewardcampaign",
|
||||||
|
options={"ordering": ["-starts_at"]},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="timebaseddrop",
|
||||||
|
options={"ordering": ["required_minutes_watched"]},
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,50 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2024-09-16 19:32
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import core.models
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies: list[tuple[str, str]] = [
|
||||||
|
("core", "0005_alter_benefit_options_alter_dropcampaign_options_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations: list[Operation] = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="benefit",
|
||||||
|
name="image",
|
||||||
|
field=models.ImageField(null=True, upload_to=core.models.get_benefit_image_path),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="dropcampaign",
|
||||||
|
name="image",
|
||||||
|
field=models.ImageField(null=True, upload_to=core.models.get_drop_campaign_image_path),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="game",
|
||||||
|
name="image",
|
||||||
|
field=models.ImageField(null=True, upload_to=core.models.get_game_image_path),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="reward",
|
||||||
|
name="banner_image",
|
||||||
|
field=models.ImageField(null=True, upload_to=core.models.get_reward_banner_image_path),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="reward",
|
||||||
|
name="thumbnail_image",
|
||||||
|
field=models.ImageField(null=True, upload_to=core.models.get_reward_thumbnail_image_path),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="rewardcampaign",
|
||||||
|
name="image",
|
||||||
|
field=models.ImageField(null=True, upload_to=core.models.get_reward_image_path),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 5.1.1 on 2024-09-21 00:08
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from django.db.migrations.operations.base import Operation
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies: list[tuple[str, str]] = [
|
||||||
|
("core", "0006_benefit_image_dropcampaign_image_game_image_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations: list[Operation] = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="game",
|
||||||
|
options={"ordering": ["name"]},
|
||||||
|
),
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="owner",
|
||||||
|
options={"ordering": ["name"]},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="game",
|
||||||
|
name="slug",
|
||||||
|
field=models.TextField(null=True, unique=True),
|
||||||
|
),
|
||||||
|
]
|
831
core/models.py
831
core/models.py
File diff suppressed because it is too large
Load Diff
@ -40,9 +40,15 @@ THOUSAND_SEPARATOR = " "
|
|||||||
ROOT_URLCONF = "core.urls"
|
ROOT_URLCONF = "core.urls"
|
||||||
STATIC_URL = "static/"
|
STATIC_URL = "static/"
|
||||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||||
|
|
||||||
STATICFILES_DIRS: list[Path] = [BASE_DIR / "static"]
|
STATICFILES_DIRS: list[Path] = [BASE_DIR / "static"]
|
||||||
STATIC_ROOT: Path = BASE_DIR / "staticfiles"
|
STATIC_ROOT: Path = BASE_DIR / "staticfiles"
|
||||||
STATIC_ROOT.mkdir(exist_ok=True)
|
STATIC_ROOT.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
MEDIA_URL = "/media/"
|
||||||
|
MEDIA_ROOT: Path = DATA_DIR / "media"
|
||||||
|
MEDIA_ROOT.mkdir(exist_ok=True)
|
||||||
|
|
||||||
AUTH_USER_MODEL = "core.User"
|
AUTH_USER_MODEL = "core.User"
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
INTERNAL_IPS: list[str] = ["127.0.0.1"]
|
INTERNAL_IPS: list[str] = ["127.0.0.1"]
|
||||||
@ -135,6 +141,9 @@ DATABASES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
STORAGES: dict[str, dict[str, str]] = {
|
STORAGES: dict[str, dict[str, str]] = {
|
||||||
|
"default": {
|
||||||
|
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||||
|
},
|
||||||
"staticfiles": {
|
"staticfiles": {
|
||||||
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
|
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-bs-theme="dark">
|
<html lang="en" data-bs-theme="dark">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
@ -13,10 +14,8 @@
|
|||||||
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
|
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
|
||||||
<link rel="stylesheet" href="{% static 'css/style.css' %}">
|
<link rel="stylesheet" href="{% static 'css/style.css' %}">
|
||||||
</head>
|
</head>
|
||||||
<body data-bs-spy="scroll"
|
|
||||||
data-bs-target=".toc"
|
<body data-bs-spy="scroll" data-bs-target=".toc" data-bs-offset="-200" tabindex="0">
|
||||||
data-bs-offset="-200"
|
|
||||||
tabindex="0">
|
|
||||||
{% include "partials/alerts.html" %}
|
{% include "partials/alerts.html" %}
|
||||||
<article class="container mt-5">
|
<article class="container mt-5">
|
||||||
{% include "partials/header.html" %}
|
{% include "partials/header.html" %}
|
||||||
@ -25,4 +24,5 @@
|
|||||||
</article>
|
</article>
|
||||||
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>{{ game.name }}</h2>
|
<h2>{{ game.name }}</h2>
|
||||||
<img src="{{ game.box_art_url }}" alt="{{ game.name }} box art" height="283" width="212">
|
<img src="{{ game.box_art_url }}" alt="{{ game.name }} box art" height="283" width="212">
|
||||||
|
|
||||||
<h3>Game Details</h3>
|
<h3>Game Details</h3>
|
||||||
<table class="table table-hover table-sm table-striped" cellspacing="0">
|
<table class="table table-hover table-sm table-striped" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
@ -23,18 +22,17 @@
|
|||||||
<td><a href="{{ game.box_art_url }}" target="_blank">{{ game.box_art_url }}</a></td>
|
<td><a href="{{ game.box_art_url }}" target="_blank">{{ game.box_art_url }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h3>Organization</h3>
|
<h3>Organization</h3>
|
||||||
<table class="table table-hover table-sm table-striped" cellspacing="0">
|
<table class="table table-hover table-sm table-striped" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
{% if game.org %}
|
{% if game.org %}
|
||||||
<td><a href="#">{{ game.org.name }} - <span class="text-muted">{{ game.org.pk }}</span></a></td>
|
<td><a href="#">{{ game.org.name }} -
|
||||||
|
<span class="text-muted">{{ game.org.pk }}</span></a></td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td>No organization associated with this game.</td>
|
<td>No organization associated with this game.</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h3>Drop Campaigns</h3>
|
<h3>Drop Campaigns</h3>
|
||||||
{% if game.drop_campaigns.all %}
|
{% if game.drop_campaigns.all %}
|
||||||
{% for drop_campaign in game.drop_campaigns.all %}
|
{% for drop_campaign in game.drop_campaigns.all %}
|
||||||
@ -48,18 +46,28 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><img src="{{ drop_campaign.image_url }}" alt="{{ drop_campaign.name }} image"></td>
|
<td><img src="{{ drop_campaign.image_url }}" alt="{{ drop_campaign.name }} image"></td>
|
||||||
<td>
|
<td>
|
||||||
<p><strong>Status:</strong> {{ drop_campaign.status }}</p>
|
<p><strong>Status:</strong>
|
||||||
<p><strong>Description:</strong> {{ drop_campaign.description }}</p>
|
{{ drop_campaign.status }}
|
||||||
<p><strong>Starts at:</strong> {{ drop_campaign.starts_at }}</p>
|
</p>
|
||||||
<p><strong>Ends at:</strong> {{ drop_campaign.ends_at }}</p>
|
<p><strong>Description:</strong>
|
||||||
<p><strong>More details:</strong> <a href="{{ drop_campaign.details_url }}"
|
{{ drop_campaign.description }}
|
||||||
target="_blank">{{ drop_campaign.details_url }}</a></p>
|
</p>
|
||||||
<p><strong>Account Link:</strong> <a href="{{ drop_campaign.account_link_url }}"
|
<p><strong>Starts at:</strong>
|
||||||
target="_blank">{{ drop_campaign.account_link_url }}</a></p>
|
{{ drop_campaign.starts_at }}
|
||||||
|
</p>
|
||||||
|
<p><strong>Ends at:</strong>
|
||||||
|
{{ drop_campaign.ends_at }}
|
||||||
|
</p>
|
||||||
|
<p><strong>More details:</strong>
|
||||||
|
<a href="{{ drop_campaign.details_url }}" target="_blank">{{ drop_campaign.details_url }}</a>
|
||||||
|
</p>
|
||||||
|
<p><strong>Account Link:</strong>
|
||||||
|
<a href="{{ drop_campaign.account_link_url }}"
|
||||||
|
target="_blank">{{ drop_campaign.account_link_url }}</a>
|
||||||
|
</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
{% if drop_campaign.drops.all %}
|
{% if drop_campaign.drops.all %}
|
||||||
<table class="table table-hover table-sm table-striped" cellspacing="0">
|
<table class="table table-hover table-sm table-striped" cellspacing="0">
|
||||||
<tr>
|
<tr>
|
||||||
@ -75,8 +83,7 @@
|
|||||||
<td>{{ item.name }}</td>
|
<td>{{ item.name }}</td>
|
||||||
<td>{{ item.required_minutes_watched }}</td>
|
<td>{{ item.required_minutes_watched }}</td>
|
||||||
{% for benefit in item.benefits.all %}
|
{% for benefit in item.benefits.all %}
|
||||||
<td><img src="{{ benefit.image_url }}" alt="{{ benefit.name }} reward image" height="50" width="50">
|
<td><img src="{{ benefit.image_url }}" alt="{{ benefit.name }} reward image" height="50" width="50"></td>
|
||||||
</td>
|
|
||||||
<td>{{ benefit.name }}</td>
|
<td>{{ benefit.name }}</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
@ -89,6 +96,5 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
<p>No drop campaigns associated with this game.</p>
|
<p>No drop campaigns associated with this game.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<div class="alert alert-dismissible {{ message.tags }} fade show"
|
<div class="alert alert-dismissible {{ message.tags }} fade show" role="alert">
|
||||||
role="alert">
|
<div>{{ message | safe }}</div>
|
||||||
<div>{{ message | safe }}</div>
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
<button type="button"
|
</div>
|
||||||
class="btn-close"
|
|
||||||
data-bs-dismiss="alert"
|
|
||||||
aria-label="Close"></button>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
<h2 class="card-title h2">Information</h2>
|
<h2 class="card-title h2">Information</h2>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<p>
|
<p>
|
||||||
This site allows users to subscribe to Twitch drops notifications. You can choose to be alerted when new drops are found on Twitch or when the drops become available for farming.
|
This site allows users to subscribe to Twitch drops notifications. You can choose to be alerted
|
||||||
|
when new drops are found on Twitch or when the drops become available for farming.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,48 +1,50 @@
|
|||||||
{% if webhooks %}
|
{% if webhooks %}
|
||||||
<div class="card mb-4 shadow-sm" id="info-box">
|
<div class="card mb-4 shadow-sm" id="info-box">
|
||||||
<div class="row g-0">
|
<div class="row g-0">
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="card-title h2">Site news</h2>
|
<h2 class="card-title h2">Site news</h2>
|
||||||
<div class="mt-auto">
|
<div class="mt-auto">
|
||||||
{% for webhook in webhooks %}
|
{% for webhook in webhooks %}
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<img src="{{ webhook.avatar }}?size=32"
|
<img src="{{ webhook.avatar }}?size=32" alt="{{ webhook.name }}" class="rounded-circle"
|
||||||
alt="{{ webhook.name }}"
|
height="32" width="32">
|
||||||
class="rounded-circle"
|
<a href="{{ webhook.url }}" target="_blank">{{ webhook.name }}</a>
|
||||||
height="32"
|
<div class="form-check form-switch">
|
||||||
width="32">
|
<input class="form-check-input" type="checkbox" id="new-drop-switch-daily">
|
||||||
<a href="{{ webhook.url }}" target="_blank">{{ webhook.name }}</a>
|
<label class="form-check-label" for="new-drop-switch-daily">Daily notification of newly
|
||||||
<div class="form-check form-switch">
|
added games to TTVdrops</label>
|
||||||
<input class="form-check-input" type="checkbox" id="new-drop-switch-daily">
|
</div>
|
||||||
<label class="form-check-label" for="new-drop-switch-daily">Daily notification of newly added games to TTVdrops</label>
|
<div class="form-check form-switch">
|
||||||
</div>
|
<input class="form-check-input" type="checkbox" id="new-drop-switch-weekly">
|
||||||
<div class="form-check form-switch">
|
<label class="form-check-label" for="new-drop-switch-weekly">
|
||||||
<input class="form-check-input" type="checkbox" id="new-drop-switch-weekly">
|
Weekly notification of newly added games to TTVdrops
|
||||||
<label class="form-check-label" for="new-drop-switch-weekly">
|
</label>
|
||||||
Weekly notification of newly added games to TTVdrops
|
</div>
|
||||||
</label>
|
<br>
|
||||||
</div>
|
<div class="form-check form-switch">
|
||||||
<br>
|
<input class="form-check-input" type="checkbox" id="new-org-switch-daily">
|
||||||
<div class="form-check form-switch">
|
<label class="form-check-label" for="new-org-switch-daily">
|
||||||
<input class="form-check-input" type="checkbox" id="new-org-switch-daily">
|
Daily notification of newly added <abbr
|
||||||
<label class="form-check-label" for="new-org-switch-daily">
|
title="Organizations are the companies that own the games.">organizations</abbr> to
|
||||||
Daily notification of newly added <abbr title="Organizations are the companies that own the games.">organizations</abbr> to TTVdrops
|
TTVdrops
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check form-switch">
|
<div class="form-check form-switch">
|
||||||
<input class="form-check-input" type="checkbox" id="new-org-switch-weekly">
|
<input class="form-check-input" type="checkbox" id="new-org-switch-weekly">
|
||||||
<label class="form-check-label" for="new-org-switch-weekly">
|
<label class="form-check-label" for="new-org-switch-weekly">
|
||||||
Weekly notification of newly added <abbr title="Organizations are the companies that own the games.">organizations</abbr> to TTVdrops
|
Weekly notification of newly added <abbr
|
||||||
</label>
|
title="Organizations are the companies that own the games.">organizations</abbr> to
|
||||||
</div>
|
TTVdrops
|
||||||
</div>
|
</label>
|
||||||
{% endfor %}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p class="text-muted">No webhooks added yet.</p>
|
<p class="text-muted">No webhooks added yet.</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -1,50 +1,42 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1 class="my-4">Add Discord Webhook</h1>
|
<h1 class="my-4">Add Discord Webhook</h1>
|
||||||
<div class="card card-body mb-3">
|
<div class="card card-body mb-3">
|
||||||
Webhooks will be saved in a cookie and will be sent to the server when you subscribe to a drop.
|
Webhooks will be saved in a cookie and will be sent to the server when you subscribe to a drop.
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<form method="post" class="needs-validation" novalidate>
|
|
||||||
{% csrf_token %}
|
|
||||||
{{ form.non_field_errors }}
|
|
||||||
<div class="mb-3">
|
|
||||||
{{ form.webhook_url.errors }}
|
|
||||||
<label for="{{ form.webhook_url.id_for_label }}" class="form-label">{{ form.webhook_url.label }}</label>
|
|
||||||
<input type="url"
|
|
||||||
name="webhook_url"
|
|
||||||
required=""
|
|
||||||
class="form-control"
|
|
||||||
aria-describedby="id_webhook_url_helptext"
|
|
||||||
id="id_webhook_url">
|
|
||||||
<div class="form-text text-muted">{{ form.webhook_url.help_text }}</div>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="btn btn-primary">Add Webhook</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<h2 class="mt-5">Webhooks</h2>
|
|
||||||
{% if webhooks %}
|
|
||||||
<div class="list-group">
|
|
||||||
{% for webhook in webhooks %}
|
|
||||||
<div class="list-group-item d-flex justify-content-between align-items-center">
|
|
||||||
<span>
|
|
||||||
{% if webhook.avatar %}
|
|
||||||
<img src="https://cdn.discordapp.com/avatars/{{ webhook.id }}/a_{{ webhook.avatar }}.png"
|
|
||||||
alt="Avatar of {{ webhook.name }}"
|
|
||||||
class="rounded-circle"
|
|
||||||
height="32"
|
|
||||||
width="32">
|
|
||||||
{% endif %}
|
|
||||||
<a href="https://discord.com/api/webhooks/{{ webhook.id }}/{{ webhook.token }}"
|
|
||||||
target="_blank"
|
|
||||||
class="text-decoration-none">{{ webhook.name }}</a>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="alert alert-info">No webhooks added</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<form method="post" class="needs-validation" novalidate>
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.non_field_errors }}
|
||||||
|
<div class="mb-3">
|
||||||
|
{{ form.webhook_url.errors }}
|
||||||
|
<label for="{{ form.webhook_url.id_for_label }}" class="form-label">{{ form.webhook_url.label }}</label>
|
||||||
|
<input type="url" name="webhook_url" required="" class="form-control"
|
||||||
|
aria-describedby="id_webhook_url_helptext" id="id_webhook_url">
|
||||||
|
<div class="form-text text-muted">{{ form.webhook_url.help_text }}</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Add Webhook</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<h2 class="mt-5">Webhooks</h2>
|
||||||
|
{% if webhooks %}
|
||||||
|
<div class="list-group">
|
||||||
|
{% for webhook in webhooks %}
|
||||||
|
<div class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
|
<span>
|
||||||
|
{% if webhook.avatar %}
|
||||||
|
<img src="https://cdn.discordapp.com/avatars/{{ webhook.id }}/a_{{ webhook.avatar }}.png"
|
||||||
|
alt="Avatar of {{ webhook.name }}" class="rounded-circle" height="32" width="32">
|
||||||
|
{% endif %}
|
||||||
|
<a href="https://discord.com/api/webhooks/{{ webhook.id }}/{{ webhook.token }}" target="_blank"
|
||||||
|
class="text-decoration-none">{{ webhook.name }}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info">No webhooks added</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
Reference in New Issue
Block a user