summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.docker/app/startup.sh30
-rw-r--r--.docker/app/update.sh24
-rw-r--r--.docker/app/updater.sh24
-rw-r--r--.github/workflows/publish.yml26
-rw-r--r--README.md10
-rw-r--r--docker-compose.yml8
-rw-r--r--js/App.js59
-rw-r--r--js/CommonFilters.js2
-rwxr-xr-xjs/FeedTree.js11
-rwxr-xr-xjs/common.js4
-rw-r--r--locale/sq/LC_MESSAGES/messages.mobin53161 -> 53698 bytes
-rw-r--r--locale/sq/LC_MESSAGES/messages.po24
12 files changed, 151 insertions, 71 deletions
diff --git a/.docker/app/startup.sh b/.docker/app/startup.sh
index 64111dd19..535d9f4ab 100644
--- a/.docker/app/startup.sh
+++ b/.docker/app/startup.sh
@@ -13,6 +13,30 @@ done
unset HTTP_PORT
unset HTTP_HOST
+# allow setting environment variables with docker secrets
+# the format is <variable-name>__FILE
+SUFFIX="__FILE"
+
+# loop through all environment variables
+for VAR in $(printenv | awk -F= '{print $1}'); do
+ if [[ $VAR == *"$SUFFIX" ]]; then
+ ENV_FILE_NAME="$(printenv "${VAR}")"
+ ENV_VAR="${VAR%$SUFFIX}"
+
+ if printenv "$ENV_VAR" &>/dev/null; then
+ echo "warning: Both $ENV_VAR and $VAR are set. $VAR will override $ENV_VAR."
+ fi
+
+ if [[ -r "$ENV_FILE_NAME" ]]; then
+ VALUE="$(cat "$ENV_FILE_NAME")"
+ export "$ENV_VAR"="$VALUE"
+ echo "$ENV_VAR environment variable was set by secret file $ENV_FILE_NAME"
+ else
+ echo "warning: Secret file $ENV_FILE_NAME for $VAR is not readable or does not exist."
+ fi
+ fi
+done
+
if ! id app >/dev/null 2>&1; then
addgroup -g $OWNER_GID app
adduser -D -h $APP_INSTALL_BASE_DIR -G app -u $OWNER_UID app
@@ -96,6 +120,12 @@ if [ -z "$TTRSS_NO_STARTUP_PLUGIN_UPDATES" ]; then
https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-*.git)
NEW_ORIGIN_URL="https://github.com/tt-rss/tt-rss-plugin-${ORIGIN_URL#'https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-'}"
;;
+ https://dev.tt-rss.org/tt-rss/ttrss-*.git)
+ NEW_ORIGIN_URL="https://github.com/tt-rss/tt-rss-plugin-${ORIGIN_URL#'https://dev.tt-rss.org/tt-rss/ttrss-'}"
+ ;;
+ https://dev.tt-rss.org/tt-rss/plugins/ttrss-*.git)
+ NEW_ORIGIN_URL="https://github.com/tt-rss/tt-rss-plugin-${ORIGIN_URL#'https://dev.tt-rss.org/tt-rss/plugins/ttrss-'}"
+ ;;
*)
NEW_ORIGIN_URL=""
;;
diff --git a/.docker/app/update.sh b/.docker/app/update.sh
index e383091d1..4c89a7efc 100644
--- a/.docker/app/update.sh
+++ b/.docker/app/update.sh
@@ -8,6 +8,30 @@
unset HTTP_PORT
unset HTTP_HOST
+# allow setting environment variables with docker secrets
+# the format is <variable-name>__FILE
+SUFFIX="__FILE"
+
+# loop through all environment variables
+for VAR in $(printenv | awk -F= '{print $1}'); do
+ if [[ $VAR == *"$SUFFIX" ]]; then
+ ENV_FILE_NAME="$(printenv "${VAR}")"
+ ENV_VAR="${VAR%$SUFFIX}"
+
+ if printenv "$ENV_VAR" &>/dev/null; then
+ echo "warning: Both $ENV_VAR and $VAR are set. $VAR will override $ENV_VAR."
+ fi
+
+ if [[ -r "$ENV_FILE_NAME" ]]; then
+ VALUE="$(cat "$ENV_FILE_NAME")"
+ export "$ENV_VAR"="$VALUE"
+ echo "$ENV_VAR environment variable was set by secret file $ENV_FILE_NAME"
+ else
+ echo "warning: Secret file $ENV_FILE_NAME for $VAR is not readable or does not exist."
+ fi
+ fi
+done
+
if ! id app >/dev/null 2>&1; then
addgroup -g $OWNER_GID app
adduser -D -h $APP_INSTALL_BASE_DIR -G app -u $OWNER_UID app
diff --git a/.docker/app/updater.sh b/.docker/app/updater.sh
index c34cf5225..c38ddd20d 100644
--- a/.docker/app/updater.sh
+++ b/.docker/app/updater.sh
@@ -10,6 +10,30 @@ unset HTTP_HOST
unset ADMIN_USER_PASS
unset AUTO_CREATE_USER_PASS
+# allow setting environment variables with docker secrets
+# the format is <variable-name>__FILE
+SUFFIX="__FILE"
+
+# loop through all environment variables
+for VAR in $(printenv | awk -F= '{print $1}'); do
+ if [[ $VAR == *"$SUFFIX" ]]; then
+ ENV_FILE_NAME="$(printenv "${VAR}")"
+ ENV_VAR="${VAR%$SUFFIX}"
+
+ if printenv "$ENV_VAR" &>/dev/null; then
+ echo "warning: Both $ENV_VAR and $VAR are set. $VAR will override $ENV_VAR."
+ fi
+
+ if [[ -r "$ENV_FILE_NAME" ]]; then
+ VALUE="$(cat "$ENV_FILE_NAME")"
+ export "$ENV_VAR"="$VALUE"
+ echo "$ENV_VAR environment variable was set by secret file $ENV_FILE_NAME"
+ else
+ echo "warning: Secret file $ENV_FILE_NAME for $VAR is not readable or does not exist."
+ fi
+ fi
+done
+
# wait for the app container to delete .app_is_ready and perform rsync, etc.
sleep 30
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 744bb1488..1ef46b631 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -27,20 +27,25 @@ jobs:
test-php:
uses: ./.github/workflows/php-code-quality.yml
- publish-dockerhub:
- name: Publish ${{ matrix.image.name }} to Docker Hub
+ publish:
+ name: Publish Docker image ${{ matrix.image.name }}
needs:
- test-php
runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
strategy:
matrix:
image:
- name: app
dockerfile: ./.docker/app/Dockerfile
- repository: supahgreg/tt-rss
+ repository_dockerhub: supahgreg/tt-rss
+ repository_ghcr: ghcr.io/tt-rss/tt-rss
- name: web-nginx
dockerfile: ./.docker/web-nginx/Dockerfile
- repository: supahgreg/tt-rss-web-nginx
+ repository_dockerhub: supahgreg/tt-rss-web-nginx
+ repository_ghcr: ghcr.io/tt-rss/tt-rss-web-nginx
steps:
- name: Check out code
@@ -52,6 +57,13 @@ jobs:
- name: Get commit short SHA
run: echo "COMMIT_SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+ - name: Log in to GitHub Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
@@ -62,7 +74,9 @@ jobs:
id: meta
uses: docker/metadata-action@v5
with:
- images: ${{ matrix.image.repository }}
+ images: |
+ ${{ matrix.image.repository_dockerhub }}
+ ${{ matrix.image.repository_ghcr }}
tags: |
# update 'latest'
type=raw,value=latest
@@ -75,7 +89,7 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- - name: Build and push to Docker Hub
+ - name: Build and push to image registries
id: push
uses: docker/build-push-action@v6
with:
diff --git a/README.md b/README.md
index 7319a4125..78ccedec2 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ Please refer to [the wiki](https://github.com/tt-rss/tt-rss/wiki).
* The original tt-rss project, hosted at https://tt-rss.org/ and its various subdomains, [will be gone after 2025-11-01](https://community.tt-rss.org/t/the-end-of-tt-rss-org/7164).
* Massive thanks to fox for creating tt-rss, and maintaining it (and absolutely everything else that went along with it) for so many years.
* This project (https://github.com/tt-rss/tt-rss) is a fork of tt-rss as of 2025-10-03, created by one of its long-time contributors (`wn_`/`wn_name` on `tt-rss.org`, `supahgreg` on `github.com`).
- * The goal is to continue tt-rss development, with an initial focus on replacing `tt-rss.org` references and integrations + getting things working.
+ * The goal is to continue tt-rss development, with an initial focus on getting things working as expected without `tt-rss.org`.
* Developer note: Due to use of `invalid@email.com` on `supahgreg`'s pre-2025-10-03 commits (which were done on `tt-rss.org`) GitHub incorrectly shows `ivanivanov884`
(the GitHub user associated with that e-mail address) as the author instead of `wn_`/`supahgreg`. Apologies for any confusion. `¯\_(ツ)_/¯`
* Plugins that were under https://gitlab.tt-rss.org/tt-rss/plugins have been mirrored to `https://github.com/tt-rss/tt-rss-plugin-*`.
@@ -20,9 +20,11 @@ Please refer to [the wiki](https://github.com/tt-rss/tt-rss/wiki).
* Documentation from https://tt-rss.org has been recreated in https://github.com/tt-rss/tt-rss/wiki .
* The repository that held the content for https://tt-rss.org was mirrored to https://github.com/tt-rss/tt-rss-web-static .
Some content tweaks were made after mirroring (prior to the wiki being set up), and the repository is now archived.
-* Docker images (for `linux/amd64` and `linux/arm64`) are being built and published to Docker Hub [via GitHub Actions](https://github.com/tt-rss/tt-rss/actions/workflows/publish.yml).
- * See https://hub.docker.com/r/supahgreg/tt-rss/ and https://hub.docker.com/r/supahgreg/tt-rss-web-nginx/ , and
- [the installation guide](https://github.com/tt-rss/tt-rss/wiki/Installation-Guide) for how they can be used.
+* Docker images (for `linux/amd64` and `linux/arm64`) are being built and published ([via GitHub Actions](https://github.com/tt-rss/tt-rss/actions/workflows/publish.yml)) to:
+ * Docker Hub (as [supahgreg/tt-rss](https://hub.docker.com/r/supahgreg/tt-rss/) and [supahgreg/tt-rss-web-nginx](https://hub.docker.com/r/supahgreg/tt-rss-web-nginx/)).
+ * GitHub Container Registry (as [ghcr.io/tt-rss/tt-rss](https://github.com/orgs/tt-rss/packages/container/package/tt-rss)
+ and [ghcr.io/tt-rss/tt-rss-web-nginx](https://github.com/orgs/tt-rss/packages/container/package/tt-rss-web-nginx)).
+ * See [the installation guide](https://github.com/tt-rss/tt-rss/wiki/Installation-Guide) for how the images can be used.
## Development and contributing
diff --git a/docker-compose.yml b/docker-compose.yml
index ea11ca1bb..6ec016113 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -4,8 +4,6 @@
# please don't use this in production: it has no database persistence and maps to tt-rss source directly.
#
-version: '3'
-
services:
db:
image: postgres:15-alpine
@@ -18,7 +16,7 @@ services:
- POSTGRES_DB=${TTRSS_DB_NAME}
app:
- image: cthulhoo/ttrss-fpm-pgsql-static:latest
+ image: ghcr.io/tt-rss/tt-rss:latest
environment:
SKIP_RSYNC_ON_STARTUP: true
build:
@@ -33,7 +31,7 @@ services:
- db
updater:
- image: cthulhoo/ttrss-fpm-pgsql-static:latest
+ image: ghcr.io/tt-rss/tt-rss:latest
build:
dockerfile: .docker/app/Dockerfile
context: .
@@ -47,7 +45,7 @@ services:
command: /opt/tt-rss/updater.sh
web-nginx:
- image: cthulhoo/ttrss-web-nginx:latest
+ image: ghcr.io/tt-rss/tt-rss-web-nginx:latest
build:
dockerfile: .docker/web-nginx/Dockerfile
context: .
diff --git a/js/App.js b/js/App.js
index 370391f86..33bd81d9a 100644
--- a/js/App.js
+++ b/js/App.js
@@ -411,40 +411,39 @@ const App = {
},
// htmlspecialchars()-alike for headlines data-content attribute
escapeHtml: function(p) {
- if (typeof p == "string") {
- const map = {
- '&': '&amp;',
- '<': '&lt;',
- '>': '&gt;',
- '"': '&quot;',
- "'": '&#039;'
- };
+ if (typeof p !== 'string')
+ return p;
- return p.replace(/[&<>"']/g, function(m) { return map[m]; });
- } else {
+ const map = {
+ '&': '&amp;',
+ '<': '&lt;',
+ '>': '&gt;',
+ '"': '&quot;',
+ "'": '&#x27;',
+ '/': '&#x2F;',
+ };
+
+ return p.replace(/[&<>"'\/]/g, m => map[m]);
+ },
+ unescapeHtml: function(p) {
+ if (typeof p !== 'string' || p.indexOf('&') === -1)
return p;
- }
+
+ return p.replace(/&(?:amp|lt|gt|quot|#x27|#x2F|#039|#47);/g, function(entity) {
+ switch (entity) {
+ case '&amp;': return '&';
+ case '&lt;': return '<';
+ case '&gt;': return '>';
+ case '&quot;': return '"';
+ case '&#x27;': case '&#039;': return "'";
+ case '&#x2F;': case '&#47;': return '/';
+ default: return entity;
+ }
+ });
},
- // http://stackoverflow.com/questions/6251937/how-to-get-selecteduser-highlighted-text-in-contenteditable-element-and-replac
getSelectedText: function() {
- let text = "";
-
- if (typeof window.getSelection != "undefined") {
- const sel = window.getSelection();
- if (sel.rangeCount) {
- const container = document.createElement("div");
- for (let i = 0, len = sel.rangeCount; i < len; ++i) {
- container.appendChild(sel.getRangeAt(i).cloneContents());
- }
- text = container.innerHTML;
- }
- } else if (typeof document.selection != "undefined") {
- if (document.selection.type == "Text") {
- text = document.selection.createRange().textText;
- }
- }
-
- return text.stripTags();
+ const sel = window.getSelection();
+ return sel ? sel.toString().trim() : "";
},
displayIfChecked: function(checkbox, elemId) {
if (checkbox.checked) {
diff --git a/js/CommonFilters.js b/js/CommonFilters.js
index f6cc5a4e7..6d40373d6 100644
--- a/js/CommonFilters.js
+++ b/js/CommonFilters.js
@@ -527,6 +527,8 @@ const Filters = {
`);
if (!App.isPrefs()) {
+ // TODO: This section isn't working as expected (under Firefox 143, at least).
+ // `selectedText` is always empty at this point (tested by selecting some article text).
const selectedText = App.getSelectedText();
if (selectedText != "") {
diff --git a/js/FeedTree.js b/js/FeedTree.js
index 67d2a8035..683205579 100755
--- a/js/FeedTree.js
+++ b/js/FeedTree.js
@@ -237,16 +237,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/array", "dojo/co
return rc;
},
getLabel: function(item) {
- let name = String(item.name);
-
- /* Horrible */
- name = name.replace(/&quot;/g, "\"");
- name = name.replace(/&amp;/g, "&");
- name = name.replace(/&mdash;/g, "-");
- name = name.replace(/&lt;/g, "<");
- name = name.replace(/&gt;/g, ">");
-
- return name;
+ return App.unescapeHtml(item.name);
},
expandParentNodes: function(feed, is_cat, list) {
try {
diff --git a/js/common.js b/js/common.js
index 9635ab492..99cf52fa1 100755
--- a/js/common.js
+++ b/js/common.js
@@ -167,10 +167,6 @@ Array.prototype.uniq = function() {
return this.filter((v, i, a) => a.indexOf(v) === i);
};
-String.prototype.stripTags = function() {
- return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?(\/)?>|<\/\w+>/gi, '');
-}
-
/* exported xhr */
const xhr = {
_ts: 0,
diff --git a/locale/sq/LC_MESSAGES/messages.mo b/locale/sq/LC_MESSAGES/messages.mo
index f8f96b1f0..2ea5786b2 100644
--- a/locale/sq/LC_MESSAGES/messages.mo
+++ b/locale/sq/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/locale/sq/LC_MESSAGES/messages.po b/locale/sq/LC_MESSAGES/messages.po
index 0f21c0791..95237233a 100644
--- a/locale/sq/LC_MESSAGES/messages.po
+++ b/locale/sq/LC_MESSAGES/messages.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-05-04 13:44+0300\n"
-"PO-Revision-Date: 2025-05-06 17:02+0000\n"
+"PO-Revision-Date: 2025-10-10 18:07+0000\n"
"Last-Translator: Besnik Bleta <besnik@programeshqip.org>\n"
"Language-Team: Albanian <https://hosted.weblate.org/projects/tt-rss/webui/sq/"
">\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 5.12-dev\n"
+"X-Generator: Weblate 5.14-dev\n"
#: backend.php:61
msgid "Use default"
@@ -137,7 +137,7 @@ msgstr "Shfaqi artikujt"
#: index.php:181
msgid "Adaptive"
-msgstr ""
+msgstr "Që përshtatet"
#: index.php:182
msgid "All Articles"
@@ -376,7 +376,7 @@ msgstr "Po kryhen përditësime për versionin %d"
#: classes/Handler_Public.php:700 classes/Handler_Public.php:727
#: js/PrefHelpers.js:418 js/PrefHelpers.js:764
msgid "Update"
-msgstr ""
+msgstr "Përditësoje"
#: classes/Handler_Public.php:720
#, php-format
@@ -718,7 +718,7 @@ msgstr "Krejt artikujt"
#: classes/RPC.php:549
msgid "Fresh"
-msgstr ""
+msgstr "Nga e Para"
#: classes/RPC.php:552 classes/Feeds.php:1179
msgid "Recently read"
@@ -879,7 +879,7 @@ msgstr "Të përgjithshme"
#: classes/Pref_Feeds.php:646 js/PrefFeedTree.js:447 js/CommonDialogs.js:61
#: js/CommonDialogs.js:551
msgid "Place in category:"
-msgstr ""
+msgstr "Vendosi në kategori:"
#: classes/Pref_Feeds.php:653 js/Feeds.js:650 js/CommonDialogs.js:567
msgid "Language:"
@@ -1364,7 +1364,7 @@ msgstr "Pamje mozaik"
#: classes/Pref_Prefs.php:128
msgid "On wider screens, if always expanded"
-msgstr ""
+msgstr "Në ekrane më të mëdhenj, në qoftë përherë i zgjeruar"
#: classes/Pref_Prefs.php:129
msgid "Required score"
@@ -1617,7 +1617,7 @@ msgstr "Mesazh provë nga tt-rss"
#: classes/Pref_System.php:35
msgid "Task name"
-msgstr ""
+msgstr "Emër pune"
#: classes/Pref_System.php:36
msgid "Last executed"
@@ -1625,7 +1625,7 @@ msgstr "Ekzekutuar së fundi më"
#: classes/Pref_System.php:37
msgid "Duration (seconds)"
-msgstr ""
+msgstr "Kohëzgjatje (sekonda)"
#: classes/Pref_System.php:38
msgid "Return code"
@@ -1698,7 +1698,7 @@ msgstr "Dërgo email provë"
#: classes/Pref_System.php:240
msgid "Scheduled tasks"
-msgstr ""
+msgstr "Punë të vëna në plan"
#: classes/Pref_System.php:251
msgid "PHP Information"
@@ -2198,7 +2198,7 @@ msgstr ""
#: js/PrefFilterTree.js:66
msgid "Inverse"
-msgstr ""
+msgstr "Së prapthi"
#: js/PrefFilterTree.js:136 js/PrefFilterTree.js:165 js/PrefFilterTree.js:198
msgid "No filters selected."
@@ -2740,7 +2740,7 @@ msgstr "Tashmë e instaluar"
#: js/PrefHelpers.js:587
#, java-printf-format, javascript-format
msgid "Updated: %s"
-msgstr ""
+msgstr "U përditësua më: %s"
#: js/PrefHelpers.js:604
msgid "Looking for plugins..."