Merge pull request 'move changes into master' (#41) from staging into master
All checks were successful
Build and Push Docker Image / build (push) Successful in 11s

Reviewed-on: https://gitea.corbz.dev/corbz/PYRSS-Website/pulls/41
This commit is contained in:
Corban-Lee Jones 2024-08-14 19:32:18 +00:00
commit 4d9877963e
16 changed files with 207 additions and 89 deletions

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.1.12
current_version = 0.2.2
commit = True
tag = True

View File

@ -7,4 +7,3 @@ staticfiles/
.bump2version.cfg
.env
.git/
.gitignore

View File

@ -21,15 +21,21 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install bump2version
run: pip install bump2version
- name: Get current version from bump2version
id: version
run: echo "VERSION=$(bump2version --dry-run --list patch | grep current_version | sed -r s,"^.*=",,)" >> $GITHUB_ENV
- name: Set Docker tag based on branch
id: tag
run: |
# master branch uses specific version tagging, others use the branch name
if [[ "${{ gitea.ref_name }}" == "master" ]]; then
TAG="latest"
elif [[ "${{ gitea.ref_name }}" == "staging" ]]; then
TAG="staging"
elif [[ "${{ gitea.ref_name }}" == "dev" ]]; then
TAG="dev"
TAG="${{ env.VERSION }}"
else
TAG="${{ gitea.ref_name }}"
fi
echo "TAG=$TAG" >> $GITHUB_ENV
@ -42,5 +48,12 @@ jobs:
- name: Tag & Push Docker image
run: |
# Push the branch-specific or version-specific tag
docker tag pyrss-website:${{ env.TAG }} xordk/pyrss-website:${{ env.TAG }}
docker push xordk/pyrss-website:${{ env.TAG }}
# If on master, push an additional "latest" tag
if [[ "${{ gitea.ref_name }}" == "master" ]]; then
docker tag pyrss-website:${{ env.TAG }} xordk/pyrss-website:latest
docker push xordk/pyrss-website:latest
fi

33
CHANGELOG.md Normal file
View File

@ -0,0 +1,33 @@
**unreleased**
**v0.2.2**
- Enhancement: added open graph meta tags
- Fix: csrf trusted origins warning, from not including url protocol
- Fix/Enhancement: Replaced `<a href="#" onclick="doThing()">` buttons with `<button>`.
**v0.2.1**
- Enhancement: Added confirmation modal for closing a server
**v0.2.0**
- Enhancement: Improved warning when server doesn't include bot member
- Enhancement: Made it easier to update labels to the current server's details
- Enhancement: 'Go Back' button on the server page, takes the user to the 'select a server' page.
- Docs: Further documented `static/home/servers.js`
- Other: removed some unused/unreferenced code
**v0.1.14**
- Fix: layout issue for the 'select a server' page was off-centre
**v0.1.13**
- Docs: Start of changelog
- Fix: remove db flush from entrypoint file
**v0.1.0**
- Initial Release

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -46,7 +46,7 @@ async function initContentTable() {
data: "title",
className: "text-truncate",
render: function(data, type, row) {
return `<a href="${row.url}" class="text-decoration-none" target="_blank">${data}</a>`
return `<a href="${row.url}" class="btn btn-link text-decoration-none" target="_blank">${data}</a>`
}
},
{
@ -54,7 +54,7 @@ async function initContentTable() {
data: "subscription.name",
className: "text-nowrap",
render: function(data, type, row) {
return `<a href="#" onclick="goToSubscription(${row.subscription.id})" class="text-decoration-none">${data}</a>`
return `<button type="button" onclick="goToSubscription(${row.subscription.id})" class="btn btn-link text-decoration-none">${data}</button>`
}
},
{
@ -143,7 +143,7 @@ function resolveChannelNames(guildId) {
$("<a>").text(channel.text)
.attr("href", href)
.attr("target", "_blank")
.addClass("text-decoration-none text-nowrap")
.addClass("btn btn-link text-decoration-none text-nowrap")
);
}
});

View File

@ -40,7 +40,7 @@ async function initFiltersTable() {
title: "Name",
data: "name",
render: function(data, type, row) {
return `<a href="#" onclick="showEditFilterModal(${row.id})" class="text-decoration-none">${data}</a>`
return `<button type="button" onclick="showEditFilterModal(${row.id})" class="btn btn-link text-decoration-none">${data}</button>`
}
},
{

View File

@ -9,17 +9,11 @@ $(document).ready(async function() {
await loadServerOptions();
});
// $('#serverTabs [data-bs-toggle="tab"]').on("show.bs.tab", function(event) {
// const activeTab = $(event.target);
// $(".tab-pane-buttons .tab-pane-buttons-item").hide();
// $(`.tab-pane-buttons .tab-pane-buttons-item[data-tab="${activeTab.attr("id")}"]`).show();
// });
$(document).on("selectedServerChange", function() {
$("#subscriptionsTab").click();
});
function genHexString(len) {
function genHexString(len=6) {
let output = '';
for (let i = 0; i < len; ++i) {
output += (Math.floor(Math.random() * 16)).toString(16);

View File

@ -1,3 +1,6 @@
// #region Loaded Servers
var loadedServers = {};
// Returns the currently active server, or null if none are active.
@ -44,9 +47,21 @@ function removeFromLoadedServers(serverPrimaryKey) {
delete loadedServers[serverPrimaryKey];
removeServerTemplate(serverPrimaryKey);
$("#backToSelectServer").click();
}
// #endregion
// #region Server Back Btn
$("#backToSelectServer").on("click", function() {
$("#noSelectedServer").show();
$("#selectedServerContainer").hide();
}
});
// #endregion
// #region Server Modal
$("#serverOptionsRefreshBtn").on("click", async function() {
await loadServerOptions();
@ -94,6 +109,10 @@ async function loadServerOptions() {
}
// #endregion
// #region Server Sidebar
// Load any existing 'saved guilds' from the database
async function loadSavedGuilds() {
try {
@ -137,9 +156,17 @@ function removeServerTemplate(serverPrimaryKey) {
// Open 'Add Server' Form Modal
$("#newServerBtn").on("click", function() {
$("#serverFormModal").modal("show");
newServerModal();
});
function newServerModal() {
$("#serverFormModal").modal("show");
}
// #endregion
// #region New Server
// Submit 'Add Server' Form
$("#serverForm").on("submit", async function(event) {
event.preventDefault();
@ -182,6 +209,10 @@ async function registerNewServer(serverName, serverGuildId, serverIconHash, serv
return response.id;
}
// #endregion
// #region Select Server
function selectServer(primaryKey) {
var server = loadedServers[primaryKey];
@ -203,12 +234,34 @@ function selectServer(primaryKey) {
loadedServers[primaryKey].currentlyActive = true;
$("#noSelectedServer").hide();
$("#selectedServerContainer").show();
$("#selectedServerContainer").show().css("display", "flex");
$(document).trigger("selectedServerChange");
}
// #endregion
// #region Delete Server Btn
$("#deleteSelectedServerBtn").on("click", async function() {
const notes = [
"No Subscriptions, Filters or Tracked Content will be deleted.",
"No data will be deleted for other users.",
"The server will no longer appear on your sidebar.",
"You can re-add the server",
"All Subscriptions, Filters and Tracked Content will be available when/if you re-add the server."
];
const notesString = arrayToHtmlList(notes).prop("outerHTML");
await confirmDeleteModal(
"Close this server?",
`This is a safe, non-permanent action:<br><br>${notesString}`,
deleteSelectedServer,
null
);
});
async function deleteSelectedServer() {
var activeServer = getCurrentlyActiveServer();
if (!activeServer) {
@ -226,5 +279,38 @@ $("#deleteSelectedServerBtn").on("click", async function() {
alert(error)
alert(JSON.stringify(error, null, 4))
}
};
});
// #endregion
$(document).on("selectedServerChange", function() {
resolveServerStrings();
$("#serverJoinAlert").hide();
})
// #region Resolve Strings
function resolveServerStrings() {
const server = getCurrentlyActiveServer();
// Server names
$(".resolve-to-server-name").text(server.name);
// Server Guild Ids
$(".resolve-to-server-id").text(server.guild_id)
// Bot Invite links
$(".resolve-to-invite-link").attr("href", `https://discord.com/oauth2/authorize
?client_id=1129345991758336020
&permissions=2147534848
&scope=bot+applications.commands
&guild_id=${server.guild_id}
&disable_guild_select=true`);
}
$("#backToSelectServer").on("click", function() {
});
// #endregion

View File

@ -43,7 +43,7 @@ async function initSubscriptionTable() {
data: "name",
className: "text-truncate",
render: function(data, type, row) {
return `<a href="#" onclick="showEditSubModal(${row.id})" class="text-decoration-none">${data}</a>`;
return `<button type="button" onclick="showEditSubModal(${row.id})" class="btn btn-link text-decoration-none">${data}</button>`;
}
},
{
@ -51,7 +51,7 @@ async function initSubscriptionTable() {
data: "url",
className: "text-truncate",
render: function(data, type) {
return `<a href="${data}" class="text-decoration-none" target="_blank">${data}</a>`;
return `<a href="${data}" class="btn btn-link text-decoration-none" target="_blank">${data}</a>`;
}
},
{
@ -371,19 +371,14 @@ async function loadSubscriptions(guildId) {
// #region Server Change Event Handler
$(document).on("selectedServerChange", async function() {
let server = getCurrentlyActiveServer();
guildId = server.guild_id;
// Hide alerts
$("#serverJoinAlert").attr("style", "display: none !important");
$("#subEmbedColour .colour-reset").attr("data-defaultcolour", "#" + server.default_embed_colour);
updateBotInviteLink();
const activeServer = getCurrentlyActiveServer();
$("#subEmbedColour .colour-reset").attr("data-defaultcolour", "#" + activeServer.default_embed_colour);
await loadSubscriptions(activeServer.guild_id);
await loadChannelOptions(activeServer.guild_id);
await loadFilterOptions(activeServer.guild_id);
await loadSubscriptions(guildId);
await loadChannelOptions(guildId);
await loadFilterOptions(guildId);
await loadMutatorOptions();
})
@ -479,7 +474,7 @@ async function loadChannelOptions(guildId) {
// Also check that the user hasn't changed the currently active guild, otherwise
// the alert will show under the wrong server.
if (getCurrentlyActiveServer().guild_id === guildId)
showServerJoinAlert();
$("#serverJoinAlert").show();
const guildName = getServerFromSnowflake(guildId).name;
@ -587,29 +582,3 @@ async function loadFilterOptions(guildId) {
}
// #endregion
// #region Bot Not in Server Alert
function showServerJoinAlert() {
const guildId = getCurrentlyActiveServer().guild_id;
const inviteUrl = `https://discord.com/oauth2/authorize
?client_id=1129345991758336020
&permissions=2147534848&scope=bot+applications.commands
&guild_id=${guildId}
&disable_guild_select=true`
$("#serverJoinAlert a.alert-link").attr("href", inviteUrl);
$("#serverJoinAlert").show();
}
// #endregion
function updateBotInviteLink() {
const guildId = getCurrentlyActiveServer().guild_id;
const inviteUrl = `https://discord.com/oauth2/authorize
?client_id=1129345991758336020
&permissions=2147534848&scope=bot+applications.commands
&guild_id=${guildId}
&disable_guild_select=true`
$("#invitePyrssToServerBtn").attr("href", inviteUrl);
}

View File

@ -22,37 +22,52 @@
</ul>
</div>
<div class="flex-grow-1 container-fluid bg-body overflow-y-auto" style="min-width: 0;">
<div id="noSelectedServer">
select a server
<div id="noSelectedServer" class="h-100">
<div class="d-flex justify-content-center align-items-center flex-column h-100">
<img src="{% static '/images/pyrss_logo.webp' %}" alt="PYRSS Logo">
<h1 class="fw-bold mb-4">PYRSS</h1>
<div class="d-flex align-items-center flex-nowrap flex-column">
<p class="col-lg-8 text-center">Select or <a onclick="newServerModal();" class="text-link text-decoration-none" role="button">add a server</a> from the left hand menu to get started. For more help check the <a href="https://gitea.corbz.dev/corbz/PYRSS-Website/src/branch/master/README.md" class="text-decoration-none" target="_blank">README</a>.</p>
<div class="col-lg-8 text-center">
<h5>Resources</h5>
<div class="hstack gap-3 justify-content-center">
<a href="https://gitea.corbz.dev/corbz/PYRSS-Website" class="text-body text-decoration-none" target="_blank"><i class="bi bi-git fs-3"></i></a>
<a href="https://en.wikipedia.org/wiki/RSS" class="text-body text-decoration-none" target="_blank"><i class="bi bi-rss-fill fs-3"></i></a>
<a href="https://discord.com/developers/docs/intro" class="text-body text-decoration-none" target="_blank"><i class="bi bi-discord fs-3"></i></a>
<a href="https://gitea.corbz.dev/corbz/PYRSS-Website/src/branch/master/README.md" class="text-body text-decoration-none" target="_blank"><i class="bi bi-question-circle-fill fs-3"></i></a>
</div>
</div>
</div>
</div>
</div>
<div id="selectedServerContainer" class="row" style="display: none;">
<div class="col-12 bg-body-tertiary border-bottom">
<div class="px-3 py-4 d-flex justify-content-start align-items-center">
<img src="" alt="Selected Server Icon" class="rounded-3 selected-server-icon">
<img alt="Selected Server Icon" class="rounded-3 selected-server-icon">
<div class="ms-3" style="min-width: 0">
<h3 class="mb-0 selected-server-name text-truncate"></h3>
<h5 class="mb-0 selected-server-id text-truncate text-body-secondary"></h5>
<h3 class="mb-0 resolve-to-server-name text-truncate"></h3>
<h5 class="mb-0 resolve-to-server-id text-truncate text-body-secondary"></h5>
</div>
<div class="ms-auto">
<a href="" id="invitePyrssToServerBtn" class="btn btn-outline-info rounded-1" target="_blank" data-bs-toggle="tooltip" data-bs-title="Invite @PYRSS Bot">
<i class="bi bi-envelope"></i>
</a>
<button type="button" id="deleteSelectedServerBtn" class="btn btn-outline-danger rounded-1 ms-3">
<button type="button" id="deleteSelectedServerBtn" class="btn btn-outline-danger rounded-1 ms-3" data-bs-toggle="tooltip" data-bs-title="Close this server">
<i class="bi bi-x-lg"></i>
</button>
<button type="button" id="backToSelectServer" class="btn btn-outline-secondary rounded-1 ms-3" data-bs-toggle="tooltip" data-bs-title="Go back">
<i class="bi bi-box-arrow-right"></i>
</button>
</div>
</div>
</div>
<div class="col-12 m-0">
<div id="serverJoinAlert" class="alert alert-warning alert-dismissable fade show mt-4 mx-2 d-flex align-items-center" role="alert" style="display: none !important">
<i class="bi bi-warning"></i>
<span>
<div id="serverJoinAlert" class="col-12 m-0">
<div class="px-3 mt-4 mx-2 alert alert-warning fade show rounded-1 d-flex align-items-center">
<div class="me-4">
<strong>Warning:</strong>
The Bot isn't a member of this server, please <a href="" class="alert-link" target="_blank">invite the bot</a> to use it.
</span>
<button type="button" class="btn-close ms-auto" data-bs-dismiss="alert" aria-label="Close"></button>
The Bot isn't a member of
<span class="resolve-to-server-name"></span>,
features here will not function properly, please add the bot before proceeding.
</div>
<a class="ms-auto btn btn-warning rounded-1 text-nowrap resolve-to-invite-link">Add PYRSS</a>
</div>
</div>

View File

@ -17,9 +17,9 @@
<div class="offcanvas-body">
<ul class="navbar-nav justify-content-end flex-grow-1 pe-3 align-items-center">
<li class="nav-item">
<a href="#" id="themeToggle" class="me-3 text-body">
<button type="button" id="themeToggle" class="me-3 btn btn-link p-0 text-body">
<i class="bi bi-sun"></i>
</a>
</button>
</li>
{% if request.user.is_authenticated %}
<li class="nav-item">
@ -31,9 +31,9 @@
<ul class="dropdown-menu">
<li><h6 class="dropdown-header">@{{ request.user.username }}</h6></li>
<li>
<button type="button" class="dropdown-item" onclick="location.href = 'https://onesquareminesweeper.com/'">
<a href="https://gitea.corbz.dev/corbz/PYRSS-Website/src/branch/master/README.md" class="dropdown-item" target="_blank">
<i class="bi bi-question"></i><span class="ms-2">Help</span>
</button>
</a>
</li>
<li>
{% comment %}<!-- Logout only accepts POST requests -->{% endcomment %}

View File

@ -5,10 +5,21 @@
<head>
<meta charset="utf-8">
<meta name="author" content="Corban-Lee">
<meta name="description" content="Python RSS Discord Bot Dashboard">
<meta name="description" content="A feature-rich rss content aggregator for Discord">
<meta name="keywords" content="Discord, Python, RSS, Feed, News">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:title" content="PYRSS">
<meta property="og:description" content="A feature-rich rss content aggregator for Discord">
<meta property="og:image" content="{% static 'images/light-mode.png' %}">
<meta property="og:type" content="website">
<meta property="og:locale" content="en_GB" />
<meta name="twitter:title" content="PYRSS">
<meta name="twitter:description" content="A feature-rich rss content aggregator for Discord">
<meta name="twitter:image" content="https://alpha.corbz.dev/static/images/light-mode.png">
<meta name="twitter:card" content="summary_large_image">
<title>
PYRSS{% block title %}{% endblock %}
</title>

View File

@ -9,7 +9,7 @@ from django.utils import timezone
log = logging.getLogger(__name__)
VERSION = "0.1.12"
VERSION = "0.2.2"
# BASE_DIR is the root of the project, all paths should be constructed from it using pathlib
BASE_DIR = Path(__file__).parent.parent
@ -34,8 +34,8 @@ SECRET_KEY = env('SECRET_KEY', default="unsecure-default-secret-key")
DEBUG = env('DEBUG')
# Hosts and Origins that the server host must be within.
ALLOWED_HOSTS = ["localhost", "127.0.0.1", env("HOST", default="127.0.0.1")]
CSRF_TRUSTED_ORIGINS = ["http://localhost", "http://127.0.0.1", "https://" + env("HOST", default="127.0.0.1")]
ALLOWED_HOSTS = ["localhost", "127.0.0.1", "pyrss-website", env("HOST", default="127.0.0.1")]
CSRF_TRUSTED_ORIGINS = ["http://localhost", "http://127.0.0.1", "http://pyrss-website", "https://" + env("HOST", default="127.0.0.1")]
# Application definition

View File

@ -1,8 +1,6 @@
#!/bin/sh
python manage.py collectstatic
python manage.py flush --no-input
python manage.py migrate
exec "$@"