diff options
| -rw-r--r-- | .docker/app/startup.sh | 30 | ||||
| -rw-r--r-- | .docker/app/update.sh | 24 | ||||
| -rw-r--r-- | .docker/app/updater.sh | 24 | ||||
| -rw-r--r-- | .github/workflows/publish.yml | 26 | ||||
| -rw-r--r-- | README.md | 10 | ||||
| -rw-r--r-- | docker-compose.yml | 8 | ||||
| -rw-r--r-- | js/App.js | 59 | ||||
| -rw-r--r-- | js/CommonFilters.js | 2 | ||||
| -rwxr-xr-x | js/FeedTree.js | 11 | ||||
| -rwxr-xr-x | js/common.js | 4 | ||||
| -rw-r--r-- | locale/sq/LC_MESSAGES/messages.mo | bin | 53161 -> 53698 bytes | |||
| -rw-r--r-- | locale/sq/LC_MESSAGES/messages.po | 24 |
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: @@ -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: . @@ -411,40 +411,39 @@ const App = { }, // htmlspecialchars()-alike for headlines data-content attribute escapeHtml: function(p) { - if (typeof p == "string") { - const map = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''' - }; + if (typeof p !== 'string') + return p; - return p.replace(/[&<>"']/g, function(m) { return map[m]; }); - } else { + const map = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/', + }; + + 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 '&': return '&'; + case '<': return '<'; + case '>': return '>'; + case '"': return '"'; + case ''': case ''': return "'"; + case '/': case '/': 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(/"/g, "\""); - name = name.replace(/&/g, "&"); - name = name.replace(/—/g, "-"); - name = name.replace(/</g, "<"); - name = name.replace(/>/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 Binary files differindex f8f96b1f0..2ea5786b2 100644 --- a/locale/sq/LC_MESSAGES/messages.mo +++ b/locale/sq/LC_MESSAGES/messages.mo 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..." |