Made the feed config page less shit
This commit is contained in:
parent
35ede5aa33
commit
59d9062ded
1 changed files with 346 additions and 311 deletions
|
|
@ -103,7 +103,7 @@
|
|||
{% elif delivery_mode == "screenshot" %}
|
||||
<li>Screenshot layout: {{ screenshot_layout }}.</li>
|
||||
{% endif %}
|
||||
<li>Webhook text is truncated to {{ webhook_text_length_limit }} characters.</li>
|
||||
<li>Webhook text</li> is truncated to {{ webhook_text_length_limit }} characters.</li>
|
||||
<li>
|
||||
Filters:
|
||||
{% if has_blacklist_filters and has_whitelist_filters %}
|
||||
|
|
@ -161,331 +161,366 @@
|
|||
<button class="btn btn-danger btn-sm" name="feed_url" value="{{ feed.url }}">Pause</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
{% if delivery_mode == "embed" %}
|
||||
<form action="/use_text" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Send text message instead of embed</button>
|
||||
</form>
|
||||
{% elif delivery_mode == "screenshot" %}
|
||||
<form action="/use_text" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Send text message instead of screenshot</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="/use_embed" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Send embed instead of text message</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
|
||||
<h3 class="h6 text-uppercase text-muted mb-0">Screenshot Delivery</h3>
|
||||
<span class="badge {{ 'bg-info' if delivery_mode == 'screenshot' else 'bg-secondary' }}">
|
||||
{% if delivery_mode == "screenshot" %}
|
||||
Active:
|
||||
{% if screenshot_layout == "mobile" %}
|
||||
Mobile
|
||||
<div class="row row-cols-1 row-cols-lg-2 g-3 mt-2">
|
||||
<div class="col">
|
||||
<div class="card border border-secondary shadow-sm h-100 rounded-0">
|
||||
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
|
||||
Delivery Settings
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<section class="mb-3">
|
||||
<h4 class="h6 text-muted mb-2">Delivery Mode</h4>
|
||||
<p class="text-muted small mb-2">
|
||||
Choose between:<br>
|
||||
Embed: a Discord embed with title, description, and images.<br>
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
Screenshot: full-page screenshot of the entry link.<br>
|
||||
{% endif %}
|
||||
Text: plain message.
|
||||
</p>
|
||||
<div class="d-flex" role="group" aria-label="Delivery mode">
|
||||
{% if delivery_mode != "embed" %}
|
||||
<form action="/use_embed" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
style="border-top-right-radius: 0; border-bottom-right-radius: 0;"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Embed</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<span class="btn btn-primary btn-sm disabled"
|
||||
style="border-top-right-radius: 0; border-bottom-right-radius: 0;">Embed</span>
|
||||
{% endif %}
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
{% if delivery_mode != "screenshot" %}
|
||||
<form action="/use_screenshot" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm rounded-0"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Screenshot</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<span class="btn btn-primary btn-sm disabled rounded-0">Screenshot</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if delivery_mode != "text" %}
|
||||
<form action="/use_text" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
style="border-top-left-radius: 0; border-bottom-left-radius: 0;"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Text</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<span class="btn btn-primary btn-sm disabled"
|
||||
style="border-top-left-radius: 0; border-bottom-left-radius: 0;">Text</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% if delivery_mode == "screenshot" and not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
<hr class="border-secondary" />
|
||||
<section class="mb-3">
|
||||
<h4 class="h6 text-muted mb-2">Screenshot Layout</h4>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
{% if screenshot_layout == "mobile" %}
|
||||
<span class="btn btn-primary btn-sm disabled">Mobile</span>
|
||||
<form action="/use_screenshot_desktop" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Desktop</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="/use_screenshot_mobile" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Mobile</button>
|
||||
</form>
|
||||
<span class="btn btn-primary btn-sm disabled">Desktop</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="mt-2 small text-muted">
|
||||
Requires Chromium for Playwright. Run
|
||||
<code class="text-light">uv run playwright install chromium</code> once.
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
<hr class="border-secondary" />
|
||||
<section class="mb-3">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
|
||||
<h4 class="h6 text-muted mb-0">Image Delivery</h4>
|
||||
<span class="badge {{ 'bg-info' if media_gallery_image_limit < max_media_gallery_items else 'bg-secondary' }}">
|
||||
{% if media_gallery_image_limit == 0 %}
|
||||
No images
|
||||
{% elif media_gallery_image_limit == 1 %}
|
||||
First image only
|
||||
{% else %}
|
||||
Up to {{ media_gallery_image_limit }} images
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<p id="imageDeliveryHelp" class="text-muted small mb-2">
|
||||
How many images to include per entry. Only applies to embed mode.
|
||||
</p>
|
||||
<form action="/set_feed_media_gallery_image_limit"
|
||||
method="post"
|
||||
class="mb-0">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<label class="form-label small text-muted mb-2" for="image_limit">
|
||||
Images per entry:
|
||||
<output name="image_limit_value" for="image_limit">{{ media_gallery_image_limit }}</output>
|
||||
</label>
|
||||
<div class="d-flex flex-wrap align-items-center gap-3">
|
||||
<div class="flex-grow-1 image-limit-control">
|
||||
<input id="image_limit"
|
||||
class="form-range"
|
||||
type="range"
|
||||
name="image_limit"
|
||||
min="0"
|
||||
max="{{ max_media_gallery_items }}"
|
||||
step="1"
|
||||
value="{{ media_gallery_image_limit }}"
|
||||
aria-describedby="imageDeliveryHelp"
|
||||
oninput="this.form.elements.image_limit_value.value = this.value" />
|
||||
<div class="d-flex justify-content-between text-muted small">
|
||||
<span>0</span>
|
||||
</span> <span>{{ max_media_gallery_items }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">Save image limit</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
{% endif %}
|
||||
<hr class="border-secondary" />
|
||||
<section>
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
|
||||
<h4 class="h6 text-muted mb-0">Text Delivery</h4>
|
||||
<span class="badge {{ 'bg-info' if webhook_text_length_limit < max_webhook_text_length_limit else 'bg-secondary' }}">
|
||||
Max {{ webhook_text_length_limit }} characters
|
||||
</span>
|
||||
</div>
|
||||
<p id="textDeliveryHelp" class="text-muted small mb-2">
|
||||
Limit message length. Text mode allows values up to 4000 characters. Embeds are capped at 2000 characters.
|
||||
</p>
|
||||
<form action="/set_feed_webhook_text_length_limit"
|
||||
method="post"
|
||||
class="mb-0">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<div class="d-flex flex-wrap align-items-end gap-3">
|
||||
<div>
|
||||
<label class="form-label small text-muted mb-2" for="text_length_limit">Max characters</label>
|
||||
<input id="text_length_limit"
|
||||
class="form-control form-control-sm bg-dark border-dark text-light"
|
||||
type="number"
|
||||
name="text_length_limit"
|
||||
min="1"
|
||||
max="{{ max_webhook_text_length_limit }}"
|
||||
step="1"
|
||||
value="{{ webhook_text_length_limit }}"
|
||||
aria-describedby="textDeliveryHelp"
|
||||
required />
|
||||
</div>
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">Save text limit</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card border border-secondary shadow-sm h-100 rounded-0">
|
||||
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
|
||||
Feed Configuration
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<section class="mb-3">
|
||||
<h4 class="h6 text-muted mb-2">Feed URL</h4>
|
||||
<form action="/change_feed_url" method="post" class="mb-0">
|
||||
<input type="hidden" name="old_feed_url" value="{{ feed.url }}" />
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="url"
|
||||
class="form-control feed-page__wrap"
|
||||
name="new_feed_url"
|
||||
value="{{ feed.url }}"
|
||||
required />
|
||||
<button class="btn btn-warning" type="submit">Update URL</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<hr class="border-secondary" />
|
||||
<section class="mb-3">
|
||||
<h4 class="h6 text-muted mb-2">Webhook</h4>
|
||||
{% if current_webhook_name %}
|
||||
<p class="text-muted small mb-2">
|
||||
Current webhook:
|
||||
<strong>{{ current_webhook_name }}</strong>
|
||||
</p>
|
||||
{% elif current_webhook_url %}
|
||||
<p class="text-warning small mb-2">This feed references a missing webhook. Choose a webhook below to reattach it.</p>
|
||||
{% else %}
|
||||
Desktop
|
||||
<p class="text-warning small mb-2">No webhook is attached to this feed yet.</p>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
Inactive
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if webhooks %}
|
||||
<form action="/attach_feed_webhook"
|
||||
method="post"
|
||||
class="d-flex flex-wrap align-items-center gap-2 mb-2">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<input type="hidden"
|
||||
name="redirect_to"
|
||||
value="/feed?feed_url={{ feed.url|encode_url }}" />
|
||||
<select name="webhook_dropdown"
|
||||
class="form-select form-select-sm bg-dark border-dark text-muted"
|
||||
required>
|
||||
<option value=""
|
||||
disabled
|
||||
{% if not current_webhook_name %}selected{% endif %}>
|
||||
Select webhook...
|
||||
</option>
|
||||
{% for hook in webhooks %}
|
||||
<option value="{{ hook.name }}"
|
||||
{% if hook.name == current_webhook_name %}selected{% endif %}>
|
||||
{{ hook.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">Save webhook</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="text-muted small mb-2">Add a webhook first to attach this feed.</p>
|
||||
{% endif %}
|
||||
<div class="d-flex flex-wrap align-items-center gap-2">
|
||||
<span class="badge {{ 'bg-success' if save_sent_webhooks else 'bg-secondary' }}">
|
||||
Sent webhook tracking:
|
||||
{{ 'Enabled' if save_sent_webhooks else 'Disabled' }}
|
||||
</span>
|
||||
<form action="/set_feed_save_sent_webhooks" method="post" class="d-inline">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<input type="hidden"
|
||||
name="enabled"
|
||||
value="{{ 'false' if save_sent_webhooks else 'true' }}" />
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">
|
||||
{{ 'Disable saved webhook updates' if save_sent_webhooks else 'Enable saved webhook updates' }}
|
||||
</button>
|
||||
</form>
|
||||
<a class="btn btn-outline-info btn-sm"
|
||||
href="/sent_webhooks?feed_url={{ feed.url|encode_url }}">View sent webhooks</a>
|
||||
</div>
|
||||
</section>
|
||||
<hr class="border-secondary" />
|
||||
<section>
|
||||
<h4 class="h6 text-muted mb-2">Update Interval</h4>
|
||||
<div class="d-flex flex-wrap align-items-center gap-2 mb-2">
|
||||
<span class="badge {% if feed_interval %} bg-info {% else %} bg-secondary {% endif %}">
|
||||
{% if feed_interval %}
|
||||
Custom
|
||||
{% else %}
|
||||
Using global default
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-muted small mb-2">
|
||||
Current:
|
||||
<strong>
|
||||
{% if feed_interval %}
|
||||
{{ feed_interval }}
|
||||
{% if feed_interval >= 60 %}({{ (feed_interval / 60) | round(1) }} hours){% endif %}
|
||||
{% else %}
|
||||
{{ global_interval }}
|
||||
{% if global_interval >= 60 %}({{ (global_interval / 60) | round(1) }} hours){% endif %}
|
||||
{% endif %}
|
||||
minutes
|
||||
</strong>
|
||||
</p>
|
||||
<div class="d-flex flex-wrap align-items-center gap-2">
|
||||
<form action="/set_update_interval"
|
||||
method="post"
|
||||
class="d-inline-flex gap-2 align-items-center">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<input type="number"
|
||||
class="form-control form-control-sm interval-input"
|
||||
style="width: 100px"
|
||||
name="interval_minutes"
|
||||
placeholder="Minutes"
|
||||
min="1"
|
||||
value="{{ feed_interval if feed_interval else global_interval }}"
|
||||
required />
|
||||
<button class="btn btn-primary btn-sm" type="submit">Set Interval</button>
|
||||
</form>
|
||||
{% if feed_interval %}
|
||||
<form action="/reset_update_interval" method="post" class="d-inline">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<button class="btn btn-secondary btn-sm" type="submit">Reset to Global Default</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted mb-3">
|
||||
Screenshot delivery sends a full-page screenshot of the entry link instead of the normal
|
||||
embed or text message.
|
||||
</p>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
{% if delivery_mode != "screenshot" %}
|
||||
<form action="/use_screenshot" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Use screenshot delivery</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="/use_embed" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Disable screenshot delivery</button>
|
||||
</form>
|
||||
{% if screenshot_layout == "mobile" %}
|
||||
<form action="/use_screenshot_desktop" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-light btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Use desktop screenshot layout</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<form action="/use_screenshot_mobile" method="post" class="d-inline">
|
||||
<button class="btn btn-outline-secondary btn-sm"
|
||||
name="feed_url"
|
||||
value="{{ feed.url }}">Use mobile screenshot layout</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="mt-2 screenshot-requirement">
|
||||
Screenshot mode requires Chromium to be installed for Playwright. Run
|
||||
<code>uv run playwright install chromium</code> once on this machine.
|
||||
</div>
|
||||
</section>
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
|
||||
<h3 class="h6 text-uppercase text-muted mb-0">Image Delivery</h3>
|
||||
<span class="badge {{ 'bg-info' if media_gallery_image_limit < max_media_gallery_items else 'bg-secondary' }}">
|
||||
{% if media_gallery_image_limit == 0 %}
|
||||
No images
|
||||
{% elif media_gallery_image_limit == 1 %}
|
||||
First image only
|
||||
{% else %}
|
||||
Up to {{ media_gallery_image_limit }} images
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<p id="imageDeliveryHelp" class="text-muted mb-3">
|
||||
Choose 0 to send no entry images, 1 for the first image only,
|
||||
or up to {{ max_media_gallery_items }} for a Discord media gallery.
|
||||
This only affects embed delivery.
|
||||
</p>
|
||||
<form action="/set_feed_media_gallery_image_limit"
|
||||
method="post"
|
||||
class="mb-0">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<label class="form-label small text-muted mb-2" for="image_limit">
|
||||
Images per entry:
|
||||
<output name="image_limit_value" for="image_limit">{{ media_gallery_image_limit }}</output>
|
||||
</label>
|
||||
<div class="d-flex flex-wrap align-items-center gap-3">
|
||||
<div class="flex-grow-1 image-limit-control">
|
||||
<input id="image_limit"
|
||||
class="form-range"
|
||||
type="range"
|
||||
name="image_limit"
|
||||
min="0"
|
||||
max="{{ max_media_gallery_items }}"
|
||||
step="1"
|
||||
value="{{ media_gallery_image_limit }}"
|
||||
aria-describedby="imageDeliveryHelp"
|
||||
oninput="this.form.elements.image_limit_value.value = this.value" />
|
||||
<div class="d-flex justify-content-between text-muted small">
|
||||
<span>0</span>
|
||||
<span>{{ max_media_gallery_items }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row row-cols-1 row-cols-lg-2 g-3 mt-2">
|
||||
<div class="col">
|
||||
<div class="card border border-secondary shadow-sm h-100 rounded-0">
|
||||
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
|
||||
Customization
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm btn-outline-light"
|
||||
href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
|
||||
<a class="btn btn-sm btn-outline-light"
|
||||
href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<a class="btn {{ 'btn-primary' if delivery_mode == 'text' else 'btn-outline-light' }}"
|
||||
href="/custom?feed_url={{ feed.url|encode_url }}">
|
||||
Customize message
|
||||
</a>
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
<a class="btn {{ 'btn-primary' if delivery_mode == 'embed' else 'btn-outline-light' }}"
|
||||
href="/embed?feed_url={{ feed.url|encode_url }}">
|
||||
Customize embed
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">Save image limit</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
{% endif %}
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
|
||||
<h3 class="h6 text-uppercase text-muted mb-0">Text Delivery</h3>
|
||||
<span class="badge {{ 'bg-info' if webhook_text_length_limit < max_webhook_text_length_limit else 'bg-secondary' }}">
|
||||
Max {{ webhook_text_length_limit }} characters
|
||||
</span>
|
||||
</div>
|
||||
<p id="textDeliveryHelp" class="text-muted mb-3">
|
||||
Limit message length. Text mode allows values up to 4000 characters. Embeds are capped at 2000 characters.
|
||||
</p>
|
||||
<form action="/set_feed_webhook_text_length_limit"
|
||||
method="post"
|
||||
class="mb-0">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<div class="d-flex flex-wrap align-items-end gap-3">
|
||||
<div>
|
||||
<label class="form-label small text-muted mb-2" for="text_length_limit">Max characters</label>
|
||||
<input id="text_length_limit"
|
||||
class="form-control form-control-sm bg-dark border-dark text-light"
|
||||
type="number"
|
||||
name="text_length_limit"
|
||||
min="1"
|
||||
max="{{ max_webhook_text_length_limit }}"
|
||||
step="1"
|
||||
value="{{ webhook_text_length_limit }}"
|
||||
aria-describedby="textDeliveryHelp"
|
||||
required />
|
||||
</div>
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">Save text limit</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<h3 class="h6 text-uppercase text-muted mb-3">Customization</h3>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm btn-outline-light"
|
||||
href="/whitelist?feed_url={{ feed.url|encode_url }}">Whitelist</a>
|
||||
<a class="btn btn-sm btn-outline-light"
|
||||
href="/blacklist?feed_url={{ feed.url|encode_url }}">Blacklist</a>
|
||||
<a class="btn btn-sm btn-outline-light"
|
||||
href="/custom?feed_url={{ feed.url|encode_url }}">
|
||||
Customize message
|
||||
{% if delivery_mode == "text" %}(Currently active){% endif %}
|
||||
</a>
|
||||
{% if not "youtube.com/feeds/videos.xml" in feed.url %}
|
||||
<a class="btn btn-sm btn-outline-light"
|
||||
href="/embed?feed_url={{ feed.url|encode_url }}">
|
||||
Customize embed
|
||||
{% if delivery_mode == "embed" %}(Currently active){% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if is_steam_feed %}
|
||||
<div class="form-text mt-2">Steam feeds can enable thumbnails in embed settings.</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<h3 class="h6 text-uppercase text-muted mb-3">Feed URL</h3>
|
||||
<form action="/change_feed_url" method="post" class="mb-0">
|
||||
<input type="hidden" name="old_feed_url" value="{{ feed.url }}" />
|
||||
<div class="input-group input-group-sm feed-page__content">
|
||||
<input type="url"
|
||||
class="form-control feed-page__wrap"
|
||||
name="new_feed_url"
|
||||
value="{{ feed.url }}"
|
||||
required />
|
||||
<button class="btn btn-warning" type="submit">Update URL</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<h3 class="h6 text-uppercase text-muted mb-3">Webhook</h3>
|
||||
{% if current_webhook_name %}
|
||||
<p class="text-muted mb-3">
|
||||
Current webhook:
|
||||
<strong>{{ current_webhook_name }}</strong>
|
||||
</p>
|
||||
{% elif current_webhook_url %}
|
||||
<p class="text-warning mb-3">This feed references a missing webhook. Choose a webhook below to reattach it.</p>
|
||||
{% else %}
|
||||
<p class="text-warning mb-3">No webhook is attached to this feed yet.</p>
|
||||
{% endif %}
|
||||
{% if webhooks %}
|
||||
<form action="/attach_feed_webhook"
|
||||
method="post"
|
||||
class="d-flex flex-wrap align-items-center gap-2 mb-0">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<input type="hidden"
|
||||
name="redirect_to"
|
||||
value="/feed?feed_url={{ feed.url|encode_url }}" />
|
||||
<select name="webhook_dropdown"
|
||||
class="form-select form-select-sm bg-dark border-dark text-muted"
|
||||
required>
|
||||
<option value=""
|
||||
disabled
|
||||
{% if not current_webhook_name %}selected{% endif %}>
|
||||
Select webhook...
|
||||
</option>
|
||||
{% for hook in webhooks %}
|
||||
<option value="{{ hook.name }}"
|
||||
{% if hook.name == current_webhook_name %}selected{% endif %}>
|
||||
{{ hook.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">Save webhook</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<p class="text-muted mb-0">Add a webhook first to attach this feed.</p>
|
||||
{% endif %}
|
||||
<div class="mt-3 d-flex flex-wrap align-items-center gap-2">
|
||||
<span class="badge {{ 'bg-success' if save_sent_webhooks else 'bg-secondary' }}">
|
||||
Sent webhook tracking:
|
||||
{{ 'Enabled' if save_sent_webhooks else 'Disabled' }}
|
||||
</span>
|
||||
<form action="/set_feed_save_sent_webhooks" method="post" class="d-inline">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<input type="hidden"
|
||||
name="enabled"
|
||||
value="{{ 'false' if save_sent_webhooks else 'true' }}" />
|
||||
<button class="btn btn-outline-light btn-sm" type="submit">
|
||||
{{ 'Disable saved webhook updates' if save_sent_webhooks else 'Enable saved webhook updates' }}
|
||||
</button>
|
||||
</form>
|
||||
<a class="btn btn-outline-info btn-sm"
|
||||
href="/sent_webhooks?feed_url={{ feed.url|encode_url }}">View sent webhooks</a>
|
||||
</div>
|
||||
</section>
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<h3 class="h6 text-uppercase text-muted mb-3">Feed Information</h3>
|
||||
<div class="row g-2 text-muted small">
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Added: {{ feed.added | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Last Updated: {{ feed.last_updated | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Last Retrieved: {{ feed.last_retrieved | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Next Update: {{ feed.update_after | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">
|
||||
Updates:
|
||||
<span class="badge {{ 'bg-success' if feed.updates_enabled else 'bg-danger' }}">
|
||||
{{ 'Enabled' if feed.updates_enabled else 'Disabled' }}
|
||||
</span>
|
||||
{% if is_steam_feed %}
|
||||
<div class="form-text small mt-2">Steam feeds can enable thumbnails in embed settings.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="mt-4 pt-3 border-top border-secondary-subtle">
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
|
||||
<h3 class="h6 text-uppercase text-muted mb-0">Update Interval</h3>
|
||||
<span class="badge {% if feed_interval %} bg-info {% else %} bg-secondary {% endif %}">
|
||||
{% if feed_interval %}
|
||||
Custom
|
||||
{% else %}
|
||||
Using global default
|
||||
{% endif %}
|
||||
</span>
|
||||
<div class="col">
|
||||
<div class="card border border-secondary shadow-sm h-100 rounded-0">
|
||||
<div class="card-header bg-transparent border-secondary text-muted text-uppercase small fw-semibold">
|
||||
Feed Information
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-2 text-muted small">
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Added: {{ feed.added | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Last Updated: {{ feed.last_updated | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Last Retrieved: {{ feed.last_retrieved | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">Next Update: {{ feed.update_after | relative_time }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-6">
|
||||
<div class="p-2">
|
||||
Updates:
|
||||
<span class="badge {{ 'bg-success' if feed.updates_enabled else 'bg-danger' }}">
|
||||
{{ 'Enabled' if feed.updates_enabled else 'Disabled' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-muted mb-3">
|
||||
Current:
|
||||
<strong>
|
||||
{% if feed_interval %}
|
||||
{{ feed_interval }}
|
||||
{% if feed_interval >= 60 %}({{ (feed_interval / 60) | round(1) }} hours){% endif %}
|
||||
{% else %}
|
||||
{{ global_interval }}
|
||||
{% if global_interval >= 60 %}({{ (global_interval / 60) | round(1) }} hours){% endif %}
|
||||
{% endif %}
|
||||
minutes
|
||||
</strong>
|
||||
</p>
|
||||
<div class="d-flex flex-wrap align-items-center gap-2">
|
||||
<form action="/set_update_interval"
|
||||
method="post"
|
||||
class="d-inline-flex gap-2 align-items-center">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<input type="number"
|
||||
class="form-control form-control-sm interval-input"
|
||||
style="width: 100px"
|
||||
name="interval_minutes"
|
||||
placeholder="Minutes"
|
||||
min="1"
|
||||
value="{{ feed_interval if feed_interval else global_interval }}"
|
||||
required />
|
||||
<button class="btn btn-primary btn-sm" type="submit">Set Interval</button>
|
||||
</form>
|
||||
{% if feed_interval %}
|
||||
<form action="/reset_update_interval" method="post" class="d-inline">
|
||||
<input type="hidden" name="feed_url" value="{{ feed.url }}" />
|
||||
<button class="btn btn-secondary btn-sm" type="submit">Reset to Global Default</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue