commit 3cdd1b85dbe0a790d7b661ea2383cff0cba60ddd Author: supahgreg Date: Wed Oct 15 20:28:24 2025 +0000 Initial commit diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2766316 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,24 @@ +version: 2 + +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + commit-message: + prefix: 'GitHub Actions:' + groups: + github-actions: + patterns: + - '*' + + - package-ecosystem: bundler + directory: / + schedule: + interval: weekly + commit-message: + prefix: 'Bundler:' + groups: + bundler: + patterns: + - '*' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..a9d24af --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,34 @@ +name: Lint + +on: + pull_request: + branches: [main] + push: + branches: [main] + # Allow manual triggering + workflow_dispatch: + # Allow other workflows (e.g. Pages) to invoke this one. + workflow_call: + +permissions: + contents: read + statuses: write + +jobs: + super-linter: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Run Super-Linter + uses: super-linter/super-linter/slim@v7 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DEFAULT_BRANCH: main + # Validate all files on push/workflow_dispatch, only changed files on PRs + VALIDATE_ALL_CODEBASE: ${{ github.event_name != 'pull_request' }} + VALIDATE_MARKDOWN: true + VALIDATE_YAML: true diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 0000000..c4c5fe1 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,52 @@ +name: Build and deploy Pages + +on: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + lint: + uses: ./.github/workflows/lint.yml + permissions: + contents: read + statuses: write + + build-and-deploy: + runs-on: ubuntu-latest + needs: lint + permissions: + contents: read + pages: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true + + - name: Build Jekyll site + run: bundle exec jekyll build --destination ./_site + + - name: Configure GitHub Pages + uses: actions/configure-pages@v5 + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./_site + + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..326898d --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Jekyll generated site +_site/ +.jekyll-cache/ +.jekyll-metadata + +# Ruby / Bundler +.bundle/ +vendor/bundle/ +*.gem +Gemfile.lock + +# Node +node_modules/ +package-lock.json + +# Environment and secrets +.env +.env.local + +# OS files +.DS_Store +Thumbs.db + +# Editor / IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Logs +*.log diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..eb39e53 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..627d3f6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,33 @@ +# Contributing to tt-rss Documentation + +Thank you for your interest in contributing to the Tiny Tiny RSS documentation! + +## How to Contribute + +* Contributions (documentation corrections/improvements, reporting issues, etc.) are welcome. +* Development and issue tracking for tt-rss primarily happens at [https://github.com/tt-rss/tt-rss](https://github.com/tt-rss/tt-rss). + +## Documentation License + +By contributing to this repository, you agree that your contributions will be licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0)](LICENSE). + +This means: +- Your contributions can be freely shared and adapted by others +- Proper attribution will be given +- Derivative works must be shared under the same license + +## Guidelines + +When contributing documentation: + +1. **Be clear and concise** - Write for users of all skill levels +2. **Test your examples** - Ensure code snippets and commands work as described +3. **Cite sources** - If including third-party content, state its source and license in your pull request +4. **Stay current** - tt-rss follows a continuous development model on the `main` branch, so the documentation needs to be kept current +5. **Check formatting** - Use proper Markdown formatting and verify links work + +## Questions? + +If you're unsure about including third-party content or have questions about licensing, please ask in your pull request or open a discussion. + +Thank you for helping improve tt-rss documentation! diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..8d8ca3d --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins +gem "jekyll-remote-theme" +gem "webrick", "~> 1.7" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9ab2817 --- /dev/null +++ b/LICENSE @@ -0,0 +1,48 @@ +Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) + +Copyright (c) 2025 tt-rss (https://github.com/tt-rss) + +This documentation and site content is licensed under the Creative Commons +Attribution-ShareAlike 4.0 International License. + +To view a copy of this license, visit: +https://creativecommons.org/licenses/by-sa/4.0/ + +or send a letter to: +Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + +--- + +You are free to: + + Share — copy and redistribute the material in any medium or format + Adapt — remix, transform, and build upon the material for any purpose, + even commercially. + +Under the following terms: + + Attribution — You must give appropriate credit, provide a link to the + license, and indicate if changes were made. You may do so + in any reasonable manner, but not in any way that suggests + the licensor endorses you or your use. + + ShareAlike — If you remix, transform, or build upon the material, you + must distribute your contributions under the same license + as the original. + + No additional restrictions — You may not apply legal terms or technological + measures that legally restrict others from doing + anything the license permits. + +--- + +NOTICE: + +This license applies to the documentation content in this repository. +The Tiny Tiny RSS software itself is licensed under the GNU General Public +License v3.0 (GPLv3). See https://github.com/tt-rss/tt-rss for software licensing. + +Any code snippets, configuration examples, or other software-related content +derived from the tt-rss repository retain their original GPLv3 license. + +Third-party content (if any) retains its original license and attribution. diff --git a/README.md b/README.md new file mode 100644 index 0000000..82cefb3 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# Tiny Tiny RSS Documentation Site + +This repository contains the source for the https://tt-rss.github.io. + +## License + +### Documentation Content + +The documentation and site content in this repository is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0)](LICENSE). + +**You are free to:** +- Share and redistribute the documentation +- Adapt and build upon the documentation + +**Under these terms:** +- **Attribution** — Give appropriate credit and link to the license +- **ShareAlike** — Distribute adaptations under the same CC BY-SA 4.0 license + +### Tiny Tiny RSS + +The tt-rss software itself is licensed under the [GNU General Public License v3.0 (GPLv3)](https://github.com/tt-rss/tt-rss/blob/master/COPYING). + +Any code snippets or configuration examples derived from tt-rss retain their original GPLv3 license. + +## Contributing + +Contributions to improve the documentation are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. + +By contributing, you agree that your contributions will be licensed under CC BY-SA 4.0. + +## Building Locally + +This is a Jekyll-based GitHub Pages site. To build locally: + +```bash +# Install dependencies +bundle install + +# Run local server +bundle exec jekyll serve + +# View at http://localhost:4000 +``` + +## Structure + +``` +tt-rss.github.io/ +├── _config.yml # Jekyll configuration +├── index.md # Homepage +├── docs/ # Documentation pages +├── images/ # Screenshots and images +├── LICENSE # CC BY-SA 4.0 license +├── CONTRIBUTING.md # Contribution guidelines +└── README.md # This file +``` + +## Use Links + +- **Documentation Repository:** [https://github.com/tt-rss/tt-rss.github.io](https://github.com/tt-rss/tt-rss.github.io) +- **Documentation Site:** [https://tt-rss.github.io](https://tt-rss.github.io) +- **Main Repository:** [https://github.com/tt-rss/tt-rss](https://github.com/tt-rss/tt-rss) +- **Discussions:** [https://github.com/tt-rss/tt-rss/discussions](https://github.com/tt-rss/tt-rss/discussions) +- **Issues:** [https://github.com/tt-rss/tt-rss/issues](https://github.com/tt-rss/tt-rss/issues) + diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..f22cedf --- /dev/null +++ b/_config.yml @@ -0,0 +1,50 @@ +title: Tiny Tiny RSS Documentation +description: Documentation for tt-rss, a free and open source web-based news feed reader +remote_theme: just-the-docs/just-the-docs +baseurl: "" +url: "https://tt-rss.github.io" + +# Just the Docs theme settings +color_scheme: light +search_enabled: true +search: + heading_level: 2 + previews: 3 + preview_words_before: 5 + preview_words_after: 10 + +# Heading anchor links +heading_anchors: true + +# Footer content +footer_content: 'Documentation licensed under CC BY-SA 4.0. tt-rss software licensed under GPLv3.' + +# Back to top link +back_to_top: true +back_to_top_text: "Back to top" + +# External links in header +aux_links: + "tt-rss on GitHub": + - "https://github.com/tt-rss/tt-rss" + "Discussions": + - "https://github.com/tt-rss/tt-rss/discussions" + "Report Issue": + - "https://github.com/tt-rss/tt-rss/issues" + +# Markdown settings +markdown: kramdown +kramdown: + syntax_highlighter_opts: + block: + line_numbers: false + +# Exclude from processing +exclude: + - README.md + - CONTRIBUTING.md + - LICENSE + - Gemfile + - Gemfile.lock + - node_modules + - vendor diff --git a/docs/API-Reference.md b/docs/API-Reference.md new file mode 100644 index 0000000..3b57ff6 --- /dev/null +++ b/docs/API-Reference.md @@ -0,0 +1,466 @@ +--- +layout: default +title: API Reference +nav_order: 3 +--- + +# API Reference +{: .no_toc } + +## Table of contents +{: .no_toc .text-delta } + +1. TOC +{:toc} + +--- + +API is pluggable, plugins can use host add\_api\_method() to add +custom API calls (see classes/pluginhost.php for-details). + +API is stateful. You need to login and maintain a session ID to perform further operations. Session ID should be specified using JSON parameter **sid**. I.e. + +```bash +curl -d '{"sid":"your-session-id","op":"getVersion"}' http://example.com/tt-rss/api/ +``` + +All API calls output JSON-encoded data. API can be enabled or disabled +per-user in the preferences. Client parameters should be passed encoded +using JSON in HTTP POST data (supported since-version:1.5.3). Older +versions allowed passing parameters using HTTP GET and POST, but this is +no longer supported. + +### Numeric values + +Numbers can also be passed (and are sometimes-returned) as quoted string literals, i.e. ``"0"``. + +Some tt-rss versions have issues recognizing ``0`` as a valid number +(unimplemented strict type checking causes ``0`` to be equivalent to-``false`` +in ``getHeadlines``, etc) so it might be a good idea to pass numerics as quoted +strings for better backwards compatibility. + +### Boolean values + +For boolean parameters the expected syntax is: + +- empty string, numeric zero, unquoted ``false`` literal (?), string literal ``"f"`` or ``"false"``: FALSE +- anything else: TRUE + +## Testing API calls (using-curl) + +```bash +curl -d '{"op":"login","user":"you","password":"xxx"}' http://example.com/tt-rss/api/ +``` + +```bash +curl -d '{"sid":"...","op":"getHeadlines","feed_id":"0","is_cat":"1"}' http://example.com/tt-rss/api/ +``` + +Most of the calls (except login, logout,-isLoggedIn) require valid login session +or will return this error object: {"error":"NOT_LOGGED_IN"} + +## Output format + +All API methods return JSON data like this: + +```json +{"seq":0,"status":0,"content":{"version":"1.4.3.1"}} +``` + +- seq (integer) is the sequence number supplied by client (``"seq":131``) +- status (integer) indicates whether request has been completed + successfully, can be either 0 (API\_STATUS\_OK) or 1 + (API\_STATUS\_ERR) +- content is the actual reply content, as documented below in method + descriptions. + +##### 1.4.3 and below (obsolete) + +Methods return the “content” object below, sequence numbers and statuses +are not supported. + +Methods +------- + +### getApiLevel (since version:1.5.8, api level-1) + +Return an abstracted integer API version level, increased with each API +functionality change. This is the proper way to detect host API +functionality, instead of using getVersion. + +```json +{"level":1} +``` + +Whether tt-rss returns error for this method (e.g. version:1.5.7-and +below) client should assume API level 0. + +### getVersion + +Returns tt-rss version. As of, version:1.5.8 it is not recommended to +use this to detect API functionality, please use getApiLevel instead. + +```json +{"version":"1.4.0"} +``` + +### login + +Parameters: + +- ``user`` (string) +- ``password`` (string) + +Returns client session ID. + +```json +{"session_id":"xxx"} +``` + +It can also return several error objects: + +- If API is disabled for this user: + error: "API_DISABLED" +- If specified username and password are incorrect: + error: "LOGIN_ERROR" + +In case it isn’t immediately obvious, you have to login and get a +session ID even if you are using single user mode. You can omit user and +password parameters. + +- On version:1.6.0 and above login also returns current API level as an + api\_level integer, you can use that instead of calling `getApiLevel` after login. +- Since API 17, also returns configuration object (see `getConfig`-below). + +### logout + +Closes your login session. Returns either status-message {"status":"OK"} or an error (e.g.-{"error":"NOT_LOGGED_IN"}) + +### isLoggedIn + +Returns a status message with boolean value showing whether your client (e.g. +specific session ID) is currently logged in. + +```json +{"status":false} +``` + +### getUnread + +Returns an integer value of currently unread articles. + +```json +{"unread":"992"} +``` + +### getCounters + +Returns JSON-encoded counter information. Requires version:1.5.0. + +* ``output_mode`` (string, default:-flc) - what kind of information to return (f - feeds, l - labels, c - categories, t --tags) + +### getFeeds + +Returns JSON-encoded list of feeds. The list includes category id, +title, feed url, etc. + +Parameters: + +- ``cat_id`` (integer) - return feeds under category cat\_id +- ``unread_only`` (bool) - only return feeds which have unread articles +- ``limit`` (integer) - limit amount of feeds returned to this value +- ``offset`` (integer) - skip this amount of feeds first +- ``include_nested`` (bool) - include child categories (as Feed-objects + ``with is_cat set)`` **requires version:1.6.0** + +Pagination: + +Limit and offset are useful if you need feedlist pagination. If you use +them, you shouldn’t filter by unread, handle filtering in your app +instead. + +Special category IDs are as follows: + +* 0 Uncategorized +* -1 Special (e.g. Starred, Published, Archived,-etc.) +* -2 Labels + +Added in version:1.5.0: + +- -3 All feeds, excluding virtual feeds (e.g. Labels and-such) +- -4 All feeds, including virtual feeds + +Known bug: Prior to version:1.5.0 passing null or 0 cat\_id to this +method returns full list of feeds instead of Uncategorized feeds only. + +### getCategories + +Returns JSON-encoded list of categories with unread counts. + +- ``unread_only`` (bool) - only return categories which have unread + articles +- ``enable_nested`` (bool) - switch to nested mode, only returns topmost + categories **requires version:1.6.0** +- ``include_empty`` (bool) - include empty categories **requires + version:1.7.6** + +Nested mode in this case means that a flat list of **only** topmost +categories is returned and unread counters include counters for child +categories. + +This should be used as a starting point, to display a root list of all +(for backwards-compatibility) or topmost categories, use getFeeds to +traverse deeper. + +### getHeadlines + +Returns JSON-encoded list of headlines. + +Parameters: + +- ``feed_id`` (integer|string) - only output articles for this feed (supports string values to retrieve tag virtual feeds since API level 18, otherwise-integer) +- ``limit`` (integer) - limits the amount of returned articles (see-below) +- ``skip`` (integer) - skip this amount of feeds first +- ``filter`` (string) - currently unused (?) +- ``is_cat`` (bool) - requested feed\_id is a category +- ``show_excerpt`` (bool) - include article excerpt in the output +- ``show_content`` (bool) - include full article text in the output +- ``view_mode`` (string = all\_articles, unread, adaptive,-marked, + updated) +- ``include_attachments`` (bool) - include article attachments (e.g. + enclosures) **requires version:1.5.3** +- ``since_id`` (integer) - only return articles with id greater than + ``since_id`` **requires version:1.5.6** +- ``include_nested`` (boolean) - include articles from child categories + **requires version:1.6.0** +- ``order_by`` (string) - override default sort order **requires + version:1.7.6** +- ``sanitize`` (bool) - sanitize content or not **requires version:1.8** + (default:-true) +- ``force_update`` (bool) - try to update feed before showing headlines + **requires version:1.14 (api-9)** (default:-false) +- ``has_sandbox`` (bool) - indicate support for sandboxing of iframe + elements **** (default:-false) +- ``include_header`` (bool) - adds status information when returning + headlines, instead of array(articles) return value changes to + array(header,-array(articles)) (api-12) + +Limit: + +Before **API level 6** maximum amount of returned headlines is capped at +60, API 6 and above sets it to 200. + +This parameters might change in the future (supported since **API-level +2**): + +- ``search`` (string) - search query (e.g. a list of-keywords) +- ``search_mode`` (string) - all\_feeds, this\_feed (default), this\_cat + (category containing requested-feed) +- ``match_on`` (string) - ignored + +Special feed IDs are as follows: + +- -1 starred +- -2 published +- -3 fresh +- -4 all articles +- 0 - archived +- IDs \< -10 labels + +Sort order values: + +- ``date_reverse`` - oldest first +- ``feed_dates`` - newest first, goes by feed date +- ``(nothing)`` - default + +### updateArticle + +Update information on specified articles. + +Parameters: + +- ``article_ids`` (comma-separated list of-integers) - article IDs to + operate on +- ``mode`` (integer) - type of operation to perform (0 - set to false, 1-- + set to true, 2 - toggle) +- ``field`` (integer) - field to operate on (0 - starred, 1 - published, 2 - unread, 3 - article note **since api level-1**) +- ``data`` (string) - optional data parameter when setting note field + (since **api level-1**) + +E.g. to set unread status of articles X and Y to false use the +following: + +?article\_ids=X,Y&mode=0&field=2 + +Since version:1.5.0 returns a status message: + +```json +{"status":"OK","updated":1} +``` + +“Updated” is number of articles updated by the query. + +### getArticle + +Requests JSON-encoded article object with specific ID. + +- ``article_id`` (integer) - article ID to return **as of 15.10.2010 + git** or version:1.5.0 supports comma-separated list of IDs + +Since version:1.4.3 also returns article attachments. + +### getConfig + +Returns tt-rss configuration parameters: + +```json +{"icons_dir":"icons","icons_url":"icons","daemon_is_running":true,"num_feeds":71} +``` + +- ``icons_dir`` - path to icons on the server filesystem +- ``icons_url`` - path to icons when requesting them over http +- ``daemon_is_running`` - whether update daemon is running +- ``num_feeds`` - amount of subscribed feeds (this can be used to-refresh + feedlist when this amount changes) +- ``custom_sort_types`` - map of plugin-provided article sort types (API-17+) + +### updateFeed + +Tries to update specified feed. This operation is not performed in the +background, so it might take considerable time and, potentially, be +aborted by the HTTP server. + +- ``feed_id`` (integer) - ID of feed to update + +Returns status-message if the operation has been completed. + +```json +{"status":"OK"} +``` + +### getPref + +Returns preference value of specified key. + +- ``pref_name`` (string) - preference key to return value of + +```json +{"value":true} +``` + +### catchupFeed + +Required version: version:1.4.3 + +Tries to catchup (e.g. mark as-read) specified feed. + +Parameters: + +- ``feed_id`` (integer) - ID of feed to update +- ``is_cat`` (boolean) - true if the specified feed\_id is a category +- ``mode`` (string) - optional: one of `all`, `1day`, `1week`, `2week`. defaults to `all`. **since api level 15**. + +Returns status-message if the operation has been completed. + +```json +{"status":"OK"} +``` + +### getCounters + +Required version: version:1.5.0 + +Returns a list of unread article counts for specified feed groups. + +Parameters: + +- ``output_mode`` (string) - Feed groups to return counters for + +Output mode is a character string, comprising several letters (defaults +to “flc”): + +- f - actual feeds +- l - labels +- c - categories +- t - tags + +Several global counters are returned as well, those can’t be disabled +with output\_mode. + +### getLabels (since API level-1) + +Returns list of configured labels, as an array of label objects: + +```json +{"id":2,"caption":"Debian","fg_color":"#e14a00","bg_color":"#ffffff","checked":false}, +``` + +Before version:1.7.5 + +Returned id is an internal database id of the label, you can convert it +to the valid feed id like this: + +feed\_id = \-11 - label\_id + +After: + +No conversion is necessary. + +Parameters: + +* ``article_id`` (int) - set “checked” to true if specified article id has returned label. + +### setArticleLabel (since API level-1) + +Assigns article\_ids to specified label. + +Parameters: + +* ``article_ids`` - comma-separated list of article ids +* ``label_id`` (int) - label id, as returned in getLabels +* ``assign`` (boolean) - assign or remove label + +Note: Up until version:1.15 setArticleLabel() clears the label cache for +the specified articles. Make sure to regenerate it (e.g. by calling-API +method getLabels() for the respecting articles) when you’re using +methods which don’t do that by themselves (e.g.-getHeadlines()) +otherwise getHeadlines() will not return labels for modified articles. + +### shareToPublished (since API level 4 --version:1.6.0) + +Creates an article with specified data in the Published feed. + +Parameters: + +* ``title`` - Article title (string) +* ``url`` - Article URL (string) +* ``content`` - Article content (string) +* ``sanitize`` (bool) - allows inserting HTML if disabled **requires API level 20** (default:-true) + +### subscribeToFeed (API level 5 --version:1.7.6) + +Subscribes to specified feed, returns a status code. See +subscribe\_to\_feed() in functions.php for details. + +Parameters: + +* ``feed_url`` - Feed URL (string) +* ``category_id`` - Category id to place feed into (defaults to 0,-Uncategorized) (int) +* ``login``, ``password`` - Self explanatory (string) + +### unsubscribeFeed (API level 5 --version:1.7.6) + +Unsubscribes specified feed. + +Parameters: + +* ``feed_id`` - Feed id to unsubscribe from + +### getFeedTree (API level 5 --version:1.7.6) + +* ``include_empty`` (bool) - include empty categories + +Returns full tree of categories and feeds. + +Note: counters for most feeds are not returned with this call for +performance reasons. diff --git a/docs/Android-Client.md b/docs/Android-Client.md new file mode 100644 index 0000000..7b2631d --- /dev/null +++ b/docs/Android-Client.md @@ -0,0 +1,62 @@ +--- +layout: default +title: Android Client +nav_order: 40 +--- + +## **IMPORTANT** + +* The original tt-rss-android 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). +* There are currently no plans to continue maintaining the app. +* The app's source code may be found at https://github.com/tt-rss/tt-rss-android . +* **APK downloads from https://gitlab.tt-rss.org/tt-rss/tt-rss-android/-/releases are no longer working. This is likely permanent.** +* This page's content should only be treated as a historical reference. +* Refer to https://github.com/tt-rss/tt-rss/discussions/29 for more information. + +## Screenshots + +[](images/tt-rss-android/Screenshot_20250509_135136.webp) + +[](images/tt-rss-android/Screenshot_20250509_135154.webp) + +[](images/tt-rss-android/Screenshot_20250509_135217.webp) + +[](images/tt-rss-android/Screenshot_20250509_135426.webp) + +[](images/tt-rss-android/Screenshot_20250509_135438.webp) + +## Download + +Releases are built automatically for every commit pushed to master branch and [published on Gitlab](https://gitlab.tt-rss.org/tt-rss/tt-rss-android/-/releases). + +> [!WARNING] +> This is the only official and supported way to get the APK. If you see the app on any marketplace or anywhere else, it had been uploaded there without my knowledge or consent. + +Release APKs are signed. You can verify the signature using [apksigner](https://developer.android.com/tools/apksigner): + +```sh +$ apksigner verify --print-certs org.fox.ttrss-signed.apk +Signer #1 certificate DN: CN=Andrew Dolgov, OU=N/A, O=tt-rss.org, L=Saint-Petersburg, ST=N/A, C=RU +Signer #1 certificate SHA-256 digest: c74664ba0fd8f8c97e2a548926609df1369236dd9d9d14c0e5c20b8c2b08cf06 +Signer #1 certificate SHA-1 digest: ac97a3ced638cd750272dab50c08ca979910dc74 +Signer #1 certificate MD5 digest: e4f38ce99c44714e3c21821a1c13717f +``` + +Signature digests must match above values. + +## FAQ + +### How do I automatically update the APK? + +There's no built-in auto updater, I suggest using [Obtainium](https://obtainium.imranr.dev/) instead. + +When adding new application in Obtainium, paste [app project page](https://gitlab.tt-rss.org/tt-rss/tt-rss-android) in first field, and select "Gitlab" in the "Override source" dropdown below. + +### I want to help test the app! Are there development builds available? + +Sometimes. Releases are not created for signed non-master branch builds, you can get the APKs from build pipeline artifacts [here](https://gitlab.tt-rss.org/tt-rss/tt-rss-android/-/jobs) - look for `build-signed-branch-apk`. Non-master builds install as a separate application with a gray icon. + +### Why are you not on Google Play? + +As a small time FOSS developer, dealing with Google and their marketplace is a tremendous pain in the ass. diff --git a/docs/Archived-Feed.md b/docs/Archived-Feed.md new file mode 100644 index 0000000..86319d4 --- /dev/null +++ b/docs/Archived-Feed.md @@ -0,0 +1,12 @@ +--- +layout: default +title: Archived Feed +nav_order: 41 +--- + +Archived is the place for articles for which originating feed no longer exists. +It's either Starred articles from unsubscribed feeds or [externally shared data](Share-Anything). + +> [!NOTE] +> Articles in Archived feed are not expired automatically, you can delete them manually +> using `Select...` → `Delete permanently` in the main toolbar. diff --git a/docs/Content-Filters.md b/docs/Content-Filters.md new file mode 100644 index 0000000..6ad1408 --- /dev/null +++ b/docs/Content-Filters.md @@ -0,0 +1,74 @@ +--- +layout: default +title: Content Filters +nav_order: 20 +--- + +Filters are a very powerful and flexible tool which may significantly ease the +task of extracting useful information from the sea of data that is RSS feeds. +Filters are applied to articles based on [regular +expression](http://en.wikipedia.org/wiki/Regular_expression) matches against +specified fields. After the match had been found, configured actions are taken. +Matching is case-insensitive, +[PCRE](http://php.net/manual/en/reference.pcre.pattern.syntax.php) pattern +syntax is used. + +> [!NOTE] +> Filter test dialog may not give entirely accurate results, especially for +> complex filters. It is suggested to test filters using ``Feed debugger`` (hotkey `f-D`) if you +> feel that some filter is somehow misfiring on a specific feed. + +### Load order + +Filters are loaded in user-specified order and applied sequentially. It is +possible to reorder filters using drag and drop. If no manual sorting is +specified, filters are sorted alphabetically according to user configured +caption. If no caption is specified for any filter, loading order is not +guaranteed. + +### Filter objects + +Each filter object may contain an arbitrary amount of regular expression rules +and actions. Each expression may have inverse flag set, which inverts matching +result. On top of that, filter may also have an inverse flag, which inverts the +final matching. + +- Filter object may be configured to successfully match when either one or +all rules match. +- Regular expressions may be matched against several article fields, such +as, title, content, author, etc. +- Do not include delimiters (e.g.-/) when writing regular +expressions. + +### Matching articles and applying actions + +Filter matching is performed during feed processing. + +> [!NOTE] +> Some actions may be applied only when the article is initially imported from the +> feed. Other actions may be applied every time article is seen in the originating +> feed. It is suggested to only rely on filters applying to articles imported +> after the filter had been created - they will not retroactively apply to your +> article database. + +Several actions are available: + +> [!WARNING] +> Filters may not apply actions conditionally based on previous filters. All actions for an article are applied together, once. + +1. ``Delete article`` - do not import article from the feed, does not +actually delete anything from the database +2. ``Mark as read`` - imports article automatically marked as read +3. ``Set starred`` - sets article starred automatically on import +4. ``Assign tags`` - assigns a comma-separated list of custom tags on import +5. ``Publish article`` - sets article published automatically on import +6.-``Modify score`` ([Scoring](Scoring.md)) - modifies article overall score based on +the parameter, a signed integer number. Final article score is calculated after all filters had been applied and is a sum of all matched scoring actions. +7. ``Assign label`` - assigns specified label to the article on import +8. ``Stop / Do nothing`` - stops further filter processing for this article, no following filters will be checked nor rules applied. +9. ``Invoke plugin`` - runs a plugin action when filter is matched +10. ``Ignore tags`` - a comma-separated list of tags which will be skipped on article import + +After all matching filters had been computed for the article, it is either +imported with modifications as specified by the rules, or dropped if `Delete +article` action has been found. diff --git a/docs/Email-Digests.md b/docs/Email-Digests.md new file mode 100644 index 0000000..e224d8d --- /dev/null +++ b/docs/Email-Digests.md @@ -0,0 +1,18 @@ +--- +layout: default +title: Email Digests +nav_order: 42 +--- + +Users may opt into receiving daily (sent once every 24-hours) digests of unread headlines via email. + +Digests are sent out by the update daemon or if running update.php —feeds +manually. At most 15 messages are sent in one batch. + +> [!NOTE] +> [PHPMailer plugin](https://github.com/tt-rss/tt-rss-plugin-mailer-smtp) is required to send mail under Docker. + + +* Digests may be customized by editing ``templates/digest_template*.txt``. +* You can preview your digest contents in preferences. + diff --git a/docs/Encryption.md b/docs/Encryption.md new file mode 100644 index 0000000..74e1172 --- /dev/null +++ b/docs/Encryption.md @@ -0,0 +1,18 @@ +--- +layout: default +title: Encryption +nav_order: 43 +--- + +Transparent at rest encryption is optionally supported for sensitive data stored in the database, currently limited to stored session data and passwords for feeds with authentication enabled. + +To enable, [global configuration](Global-Config) option `TTRSS_ENCRYPTION_KEY` should be set to a 32-byte hex string of random bytes, which may be generated using CLI like this: + +```sh +php ./update.php --gen-encryption-key +``` + +If enabled, existing plaintext login sessions are automatically encrypted when used, plaintext feed passwords are encrypted on feed update. + +> [!WARNING] +> Automatic encryption of plaintext data is a one-way process. If you decide to disable `TTRSS_ENCRYPTION_KEY` afterwards, all encrypted sessions would become invalid and you will get logged out. Feed passwords would become unreadable until you either enable encryption back using same key or edit feeds manually. diff --git a/docs/FAQ.md b/docs/FAQ.md new file mode 100644 index 0000000..a7f6c6b --- /dev/null +++ b/docs/FAQ.md @@ -0,0 +1,136 @@ +--- +layout: default +title: FAQ +nav_order: 30 +--- + +> [!NOTE] +> [Docker-related stuff is on a separate page](Installation-Guide#faq) + +### I want to check how tt-rss renders my feed / the feed I'm trying to use is parsed incorrectly + +tt-rss expects valid XML feed data which is parsed using libxml. Any XML parse errors, should you feel that libxml is misbehaving (which is-unlikely), should be reported to libxml developers. We don't add hacks for invalid XML on tt-rss side. + +Plugins may affect parsing, consider disabling any plugins before investigating XML-related issues. + +### I managed to lock myself out of tt-rss + +This assumes you can't simply reset your password via email (login form - forgot my-password). + +If you have OTP (2FA) enabled and know your password but can't provide an OTP token, you can disable OTP via SQL: + +``` +UPDATE ttrss_users SET otp_enabled = false WHERE login = 'you' +``` + +If you don't remember your password run the following query: + +``` +UPDATE ttrss_users + SET pwd_hash = 'SHA1:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8', salt = '', otp_enabled = false + WHERE login = 'you' +``` + +This sets your password back to default (``password``) and disables OTP. + +### I have HTTP authentication enabled and get “Your access level is insufficient to run this script” error on login + +The problem is that if you have `auth_remote` enabled in [PLUGINS](Global-Config) tt-rss tries to automatically log you in as the user specified by the server using HTTP authentication, which may not have administrative privileges. + +The easiest way is simply updating database using CLI (`php ./update.php---update-schema`). Docker setup does this on startup. + +Alternatively, you can either temporarily disable `auth_remote` (replace it with-`auth_internal`), temporarily disable HTTP authentication, or give yourself administrative permissions using SQL: + +```sql + update ttrss_users set access_level = 10 where login = 'you'; +``` + +### UI is missing CSS or is otherwise visibly broken + +- Try opening tt-rss using safe mode, clean browser profile, or an incognito + window (a different browser would also-work) +- Unless you're using SSL, try a different network connection in case your ISP is MITMing you +- Some values of ``Content-Security-Policy`` header may break tt-rss, if you + have this header set in your httpd config, try disabling it temporarily +- Check for any files in ``(tt-rss)/themes`` not known to Git (especially + ``default.php`` or ``default.css`` - formerly default CSS themes for tt-rss, + now removed), try temporarily removing all third party themes from + ``themes.local`` + +### Third party theme or plugin broke after update making the UI unusable + +Log in to tt-rss in safe mode (use an incognito window if you can't get to login-page). + +### I want to limit height of images to something more manageable + +For combined mode: + +``` +body.ttrss_main .cdm .content img, body.ttrss_main .cdm .content video { + max-height : 90vh; + height : auto; +} + +``` + +`90vh` means "90% of viewport height". This works on Chromium and derivatives, you can use `90%` for Firefox. + +### Feeds stop updating for users who rarely login + +This is controlled by a global configuration setting. You can override (or-disable) it through environment or `config.php` by setting `TTRSS_DAEMON_UPDATE_LOGIN_LIMIT` to `0`. + +Note that this also effectively disables purging of articles stored for inactive users. + +### I have questions about article purging / I don't think purging works. + +Purging is performed on successful feed update, no updates = no purging. + +Starred articles are never purged, unread articles are purged if relevant preference is enabled. + +Purging is done based on import timestamp, internal to tt-rss. It may be different from article date specified by the feed (i.e. article says it was published on 1970/01/01 but it was imported-today). You can see import timestamp if you hover over date in tt-rss web UI. + +Import date is bumped every time article is encountered in the feed, otherwise it will get purged and reimported again on every feed refresh, creating duplicates. + +When in doubt, use Feed debugger (`f D` on a-feed) to see additional purging-related information: + +``` +[11:08:10/6783] purging feed... +[11:08:10/6783] purge_feed: interval 60 days for feed XXX, owner: X, purge unread: 1 +[11:08:10/6783] purge_feed: deleted 1 articles. +[11:08:10/6783] update done. +``` + +Related question: + +### I archive or delete articles manually and I get duplicates. Why? + +Because the articles are still in the feed XML and get pulled in (again) on next feed update. + +See-also: [Archived Feed](Archived-Feed.md) + +### I have used update daemon before, but switched away from it. However, the UI keeps nagging me about the daemon not running or not updating feeds or whatever. + +Find and delete daemon lock file in LOCK_DIRECTORY. Usually, it’s lock/update_daemon.lock. You can also remove update_daemon.stamp. + +### I need an URL I can call to subscribe to feed to integrate with some third party browser extension/application. + +``` +https://example.com/tt-rss/public.php?op=bookmarklets--subscribe&feed_url=%s +``` + +If feed URL is empty (or not-given) tt-rss will display feed subscription dialog. + +### I need to get the number of unread articles for specific user + +There's a simple unauthenticated endpoint to do just that: + +``` +$ curl -s "https://example.com/tt-rss/public.php?op=getUnread&login=you&fresh=1" ; echo +8;1 +$ curl -s "https://example.com/tt-rss/public.php?op=getUnread&login=you" ; echo +8 +``` + +In single user mode, use “admin” for login. + +If optional parameter `&fresh=1` is passed via query string, return value includes fresh article count as a `;`-separated string. diff --git a/docs/Feed-Handler-Plugins.md b/docs/Feed-Handler-Plugins.md new file mode 100644 index 0000000..acb7ac2 --- /dev/null +++ b/docs/Feed-Handler-Plugins.md @@ -0,0 +1,33 @@ +--- +layout: default +title: Feed Handler Plugins +nav_order: 44 +--- + +> [!WARNING] +> Unless you have a strong need for these plugins, using them is not recommended. If +> you do use them, at least don't enable them for all feeds. + +Some plugins utilize global per-feed content hooks which either modify fetched +feed XML data (i.e. fixing broken-XML) or even generate it entirely, for tt-rss +to process, for websites that don't actually provide RSS feeds. + +While having this ability available for plugins is valuable there are several +downsides: + +1. This entirely bypasses rate-limiting and article duplicate checking done + during normal feed update process. A badly written plugin using + HOOK_FETCH_FEED may cause your tt-rss feed to keep updating + feeds indefinitely, processing all articles every time, causing unnecessary + CPU load on your server. + +2. If you have full text content plugins enabled, this may cause excessive load + on origin server, because your tt-rss instance is going to scrape site + content for every provided article on every feed update. + +This may result in your tt-rss instance being banned by origin servers for +causing excessive load and/or your VDS being suspended for suspected bad +behavior. + +Additionally, tt-rss being blacklisted by feed publishers may negatively affect +other users. diff --git a/docs/Generated-Feeds.md b/docs/Generated-Feeds.md new file mode 100644 index 0000000..2155ef1 --- /dev/null +++ b/docs/Generated-Feeds.md @@ -0,0 +1,86 @@ +--- +layout: default +title: Generated Feeds +nav_order: 45 +--- + +You can generate a feed (in Atom or JSON-format) for almost anything displayed +in headlines buffer (e.g. actual feeds, Labels, Categories,-etc.) by clicking +this icon: + +![](../images/gen_feed_icon.png) + +> [!WARNING] +> Subscribing to your own feed of search results is going to produce +> duplicate articles on each and every feed update. + +## Data protection + +Feed URLs are protected using random unique keys which are specific to each +generated feed. Key can be regenerated at any time, invalidating previous URL. + +![](../images/gen_feed_dialog.png) + +You can clear all generated feeds in Preferences (`Feeds` → `Published-& +shared articles`). + +## Anatomy of a generated feed URL + +``` +http://example.com/tt-rss/public.php?op=rss&id=61&is_cat=1&view-mode=adaptive&key=... +``` + +- ``id`` (integer) - requested feed ID +- ``is_cat`` (boolean) - whether the feed is a category +- ``view-mode`` (string) - see below +- ``key`` (string) - automatically generated access key, specific to feed id + +### Optional parameters: + +- ``login``, ``pass`` - see above +- ``format`` - since version:1.6.0 specifies output format, possible values: ``atom``, ``json`` +- ``limit`` - amount of articles to output, default: 30 +- ``offset`` - start output while skipping this amount of articles, default: 0 +- ``order`` - override default headlines order +- ``ts`` - output articles newer than timestamp in [strtotime](http://www.php.net/manual/en/function.strtotime.php) + accepted format (since-version:1.12) i.e. stuff like ts=1%20month%20ago + +### Special feed IDs: + +- ``-1`` - Starred articles +- ``-2`` - Published articles +- ``-3`` - Fresh articles +- ``-4`` - All articles +- ``0`` - Archived articles + +Feed ID values less than `-10` are considered Labels. + +### Special category IDs (is\_cat=1): + +- ``0`` - Uncategorized +- ``-1`` - Special category (includes Starred, Published,-etc.) +- ``-2`` - Labels category (includes your-labels) + +### View mode values: + +Note: It’s probably not a very good idea to use Adaptive view mode for +generated feeds. + +- adaptive - shows unread articles only when they are + unread articles, shows everything otherwise +- marked (this means-starred), has\_note, + published, unread, + unread\_first - should be self explanatory + +Actual output may differ between modes for several special feeds for +usability reasons, e.g. recently read feed ignores unread +specifier because unread articles are never part of the feed). + +### Order values: + +- ``default`` - depends on the feed: either import batch date or (for published and starred-feeds) ``last_published`` and ``last_marked`` +- ``title`` - sort by title +- ``date_reverse`` - reverse sort by batch date +- ``feed_dates`` - sort by feed-provided article dates + +See-also: [Publish Articles](Publish-Articles.md) diff --git a/docs/Global-Config.md b/docs/Global-Config.md new file mode 100644 index 0000000..12c6674 --- /dev/null +++ b/docs/Global-Config.md @@ -0,0 +1,81 @@ +--- +layout: default +title: Global Configuration +nav_order: 21 +--- + +All settings (see `_DEFAULTS[]` for default-values) are listed here: + +- https://github.com/tt-rss/tt-rss/blob/main/classes/Config.php (source code, including default-values) + +It is preferred to adjust tt-rss global configuration through the environment (e.g. using your Docker `.env`-file): + +```ini +# Copy this file to .env before building the container. +# Put any local modifications here. + +TTRSS_SESSION_COOKIE_LIFETIME=2592000 +``` + +Alternatively, you can **create** `config.php` in tt-rss root directory (copied from-`config.php-dist`), using the following syntax: + +```js +putenv('TTRSS_DB_HOST=myserver'); +putenv('TTRSS_SESSION_COOKIE_LIFETIME='.(86400*30)); +``` + +- Note lack of quotes around values. +- Options should be always prefixed by `TTRSS_`. +- Don't modify `classes/config.php`. +- You don't need to put everything to `config.php`, only the options which you've changed from the defaults. + +Legacy plugin-required constants also go to `config.php`, using `define()`: + +```js +define('LEGACY_CONSTANT',-'value'); +``` + +To set computed values via `putenv()` you have to get them evaluated by PHP, this would work: + +```js +putenv('TTRSS_SESSION_COOKIE_LIFETIME='.(86400*30)); +``` + +However, these won't give you expected results: + +```js +putenv("TTRSS_SESSION_COOKIE_LIFETIME='2592000'"); +// => 0, because quoted '2592000' is an invalid number + +putenv('TTRSS_SESSION_COOKIE_LIFETIME=86400*30'); +// => 86400, right side expression is not evaluated, +// instead you're casting string literal "86400*30" to an integer +``` + +> [!NOTE] +> All values should be precalculated when setting via `.env` because they are not evaluated by PHP and used as-is. + +## Minimal config.php for a non-Docker setup + +Should have at least these options defined: + +```php + [!WARNING] +> Podman is not Docker. Please don't report issues related to running tt-rss when using Podman or Podman Compose. + +This setup uses PostgreSQL and runs tt-rss using several containers as outlined below. +Consider using an external [Patroni cluster](https://patroni.readthedocs.io/en/latest/) instead of a single `db` container in "production" deployments. + +## TL;DR + +Place both `.env` and `docker-compose.yml` together in a directory, edit `.env` as you see fit, run `docker compose up -d`. + +### .env + +```ini +# Put any local modifications here. + +# Run FPM under this UID/GID. +# OWNER_UID=1000 +# OWNER_GID=1000 + +# FPM settings. +#PHP_WORKER_MAX_CHILDREN=5 +#PHP_WORKER_MEMORY_LIMIT=256M + +# ADMIN_USER_* settings are applied on every startup. + +# Set admin user password to this value. If not set, random password +# will be generated on startup, look for it in the 'app' container logs. +#ADMIN_USER_PASS= + +# Sets admin user access level to this value. Valid values: +# -2 - forbidden to login +# -1 - readonly +# 0 - default user +# 10 - admin +#ADMIN_USER_ACCESS_LEVEL= + +# Auto create another user (in addition to built-in-admin) unless it already exists. +#AUTO_CREATE_USER= +#AUTO_CREATE_USER_PASS= +#AUTO_CREATE_USER_ACCESS_LEVEL=0 + +# Default database credentials. +TTRSS_DB_USER=postgres +TTRSS_DB_NAME=postgres +TTRSS_DB_PASS=password + +# You can customize other config.php defines by setting overrides here. +# See tt-rss/.docker/app/Dockerfile for a complete list. + +# You probably shouldn't disable auth_internal unless you know what you're doing. +# TTRSS_PLUGINS=auth_internal,auth_remote +# TTRSS_SINGLE_USER_MODE=true +# TTRSS_SESSION_COOKIE_LIFETIME=2592000 +# TTRSS_FORCE_ARTICLE_PURGE=30 +# ... + +# Bind exposed port to 127.0.0.1 to run behind reverse proxy on the same host. +# If you plan to expose the container, remove "127.0.0.1:". +HTTP_PORT=127.0.0.1:8280 +#HTTP_PORT=8280 +``` + +### docker-compose.yml + +>[!WARNING] +> See [this FAQ entry](#i-got-the-updated-compose-file-above-and-now-my-database-keeps-restarting) +> if you're upgrading between PostgreSQL major versions (e.g. 15 to-17). + +> [!WARNING] +> Regarding PostgreSQL 18: +> * The `backups` container image currently includes `postgresql17-client`, meaning it won't be able to back up your DB if you use PostgreSQL 18. + Consider using an alternative backup solution if you're using PostgreSQL 18. +> * The PostgreSQL 18 Docker image changed the volume from `/var/lib/postgresql/data` to `/var/lib/postgresql`. +> The example below includes a commented-out volume mapping that demonstrates this. +> * See https://hub.docker.com/_/postgres and https://github.com/docker-library/postgres/pull/1259 for more info. + +```yaml +services: + db: + image: postgres:17-alpine + restart: unless-stopped + env_file: + - .env + environment: + - POSTGRES_USER=${TTRSS_DB_USER} + - POSTGRES_PASSWORD=${TTRSS_DB_PASS} + - POSTGRES_DB=${TTRSS_DB_NAME} + volumes: + - db:/var/lib/postgresql/data + # or, if 18+ + # - db:/var/lib/postgresql + + app: + image: supahgreg/tt-rss:latest + # or + # image: ghcr.io/tt-rss/tt-rss:latest + restart: unless-stopped + env_file: + - .env + volumes: + - app:/var/www/html + - ./config.d:/opt/tt-rss/config.d:ro + depends_on: + - db + +# optional, makes weekly backups of your install +# backups: +# image: supahgreg/tt-rss:latest +# # or +# # image: ghcr.io/tt-rss/tt-rss:latest +# restart: unless-stopped +# env_file: +# - .env +# volumes: +# - backups:/backups +# - app:/var/www/html +# depends_on: +# - db +# command: /opt/tt-rss/dcron.sh -f + + updater: + image: supahgreg/tt-rss:latest + # or + # image: ghcr.io/tt-rss/tt-rss:latest + restart: unless-stopped + env_file: + - .env + volumes: + - app:/var/www/html + - ./config.d:/opt/tt-rss/config.d:ro + depends_on: + - app + command: /opt/tt-rss/updater.sh + + web-nginx: + image: supahgreg/tt-rss-web-nginx:latest + # or + # image: ghcr.io/tt-rss/tt-rss-web-nginx:latest + restart: unless-stopped + env_file: + - .env + ports: + - ${HTTP_PORT}:80 + volumes: + - app:/var/www/html:ro + depends_on: + - app + +volumes: + db: + app: + backups: +``` + +## FAQ + +### Your Docker images won't run on X! + +If you're using an OS or architecture that isn't currently supported you'll likely need to +build your own Docker images by using an override and running `docker compose build`. + +```yaml +# docker-compose.override.yml +services: + app: + image: supahgreg/tt-rss:latest + # or + # image: ghcr.io/tt-rss/tt-rss:latest + build: + dockerfile: .docker/app/Dockerfile + context: https://github.com/tt-rss/tt-rss.git + args: + BUILDKIT_CONTEXT_KEEP_GIT_DIR: 1 + + web-nginx: + image: supahgreg/tt-rss-web-nginx:latest + # or + # image: ghcr.io/tt-rss/tt-rss-web-nginx:latest + build: + dockerfile: .docker/web-nginx/Dockerfile + context: https://github.com/tt-rss/tt-rss.git +``` + +`BUILDKIT_CONTEXT_KEEP_GIT_DIR` build argument is needed to display tt-rss version info properly. +If that doesn't work for you (no-BuildKit?) you'll have to resort to terrible hacks. + +> [!WARNING] +> Self-built images are not necessarily supported (i.e. best effort and/or community-support). + +### I got the updated Docker Compose file above and now my database keeps restarting + +We'll use the following error message as an example of what you might see in the logs: + +`Error message: The data directory was initialized by PostgreSQL version 12, which is not compatible with this version 15.4.` + +Official PostgreSQL containers have no support for migrating data between major versions. +Using the aforementioned example, you could do one of the following: + +1. Replace `postgres:15-alpine` with `postgres:12-alpine` in `docker-compose.yml` (or use `docker-compose.override.yml`, see-below) and keep using PG 12 +2. Use [this DB container](https://github.com/pgautoupgrade/docker-pgautoupgrade) which would automatically upgrade the database +3. Migrate the data manually using `pg_dump` and `pg_restore` (somewhat complicated if you haven't done it-before) + +### I'm using docker-compose.override.yml and now I'm getting schema update (and-other) strange issues + +Alternatively, you've changed something related to `/var/www/html/tt-rss` in `docker-compose.yml`. + +Your Docker setup is messed up for some reason, so tt-rss can't update itself to the persistent storage location on startup (this is just an example of one issue, there could be many-others). + +Consider undoing any recent changes, looking up error messages, etc. + +### How do I make it run without /tt-rss/ in the URL, i.e. at website root? + +Set the following variables in `.env`: + +```ini +APP_WEB_ROOT=/var/www/html/tt-rss +APP_BASE= +``` + +Don't forget to remove `/tt-rss/` from `TTRSS_SELF_URL_PATH`. + +### How do I apply configuration options? + +There are two sets of options you can change through the environment - options specific to tt-rss (those are prefixed with-`TTRSS_`) and options affecting container behavior. + +#### Options specific to tt-rss + +For example, to set tt-rss global option `SELF_URL_PATH`, add the following to `.env`: + +```ini +TTRSS_SELF_URL_PATH=http://example.com/tt-rss +``` + +Don't use quotes around values. Note the prefix (`TTRSS_`) before the value. + +Look [here](https://github.com/tt-rss/tt-rss/wiki/Global-Config) for more information. + +#### Container options + +Some options, but not all, are mentioned in `.env-dist`. You can see all available options in the [Dockerfile](https://github.com/tt-rss/tt-rss/blob/main/.docker/app/Dockerfile). + +### How do I customize the YML without committing my changes to git? + +You can use [docker-compose.override.yml](https://docs.docker.com/compose/extends/). For example, customize `db` to use a different `postgres` image: + +```yml +# docker-compose.override.yml +services: + db: + image: postgres:17-alpine +``` + +### I'm trying to run CLI tt-rss scripts inside the container and they complain about root + +In your Docker Compose directory, run something like one of the examples below. +Check https://github.com/tt-rss/tt-rss/blob/main/.docker/app/Dockerfile for the latest image's PHP version. + +```sh +docker compose exec --user app app php84 /var/www/html/tt-rss/update.php --help + +# ^ ^ +# | | +# | +- service (container) name +# +----- run as user +``` + +or + +```sh +docker compose exec app sudo -Eu app php84 /var/www/html/tt-rss/update.php --help +``` + +or + +```sh +docker exec -it sudo -Eu app php84 /var/www/html/tt-rss/update.php --help +``` + +Note: `sudo -E` is needed to keep environment variables. + +### How do I add plugins and themes? + +> [!NOTE] +> First party plugins can be added using plugin installer in `Preferences` → `Plugins`. + +By default, tt-rss code is stored on a persistent Docker volume (`app`). You can find +its location like this: + +```sh +docker volume inspect ttrss-docker_app | grep Mountpoint +``` + +Alternatively, you can mount any host directory as ``/var/www/html`` by updating ``docker-compose.yml``, i.e.: + +```yml +volumes: + - app:/var/www/html +``` + +Replace with: + +```yml +volumes: + - /opt/tt-rss:/var/www/html +``` + +Copy and/or git clone any third party plugins into ``plugins.local`` as usual. + +### I'm running into 502 errors and/or other connectivity issues + +First, check that all containers are running: + +``` +$ docker compose ps + Name Command State Ports +------------------------------------------------------------------------------------------------------------ +ttrss-docker-demo_app_1_f49351cb24ed /bin/sh -c /startup.sh Up 9000/tcp +ttrss-docker-demo_backups_1_8d2aa404e31a /dcron.sh -f Up 9000/tcp +ttrss-docker-demo_db_1_fc1a842fe245 docker-entrypoint.sh postgres Up 5432/tcp +ttrss-docker-demo_updater_1_b7fcc8f20419 /updater.sh Up 9000/tcp +ttrss-docker-demo_web-nginx_1_fcef07eb5c55 /docker-entrypoint.sh ngin ... Up 127.0.0.1:8280->80/tcp +``` + +Then, ensure that frontend (`web-nginx` or-`web`) container is up and can contact FPM (`app`) container: + +``` +$ docker compose exec web-nginx ping app +PING app (172.18.0.3): 56 data bytes +64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.144 ms +64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.128 ms +64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.206 ms +^C +--- app ping statistics --- +3 packets transmitted, 3 packets received, 0% packet loss +round-trip min/avg/max = 0.128/0.159/0.206 ms +``` + +Containers communicate via DNS names assigned by Docker based on service names defined in `docker-compose.yml`. This means that services (specifically,-`app`) and Docker DNS service should be functional. + +Similar issues may be also caused by Docker `iptables` functionality either being disabled or conflicting with `nftables`. + +### I want to rename `app` (FPM) container + +You can but you'll need to pass `APP_UPSTREAM` environment variable to the `web-nginx` container with its new name. + +### How do I put this container behind a reverse proxy? + +- Don't forget to pass `X-Forwarded-Proto` to the container if you're using HTTPS, otherwise tt-rss would generate plain HTTP URLs. +- Upstream address and port are set using `HTTP_PORT` in `.env`: + +```ini +HTTP_PORT=127.0.0.1:8280 +``` + +#### nginx example + +```nginx +location /tt-rss/ { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://127.0.0.1:8280/tt-rss/; + break; +} +``` + +If you run into problems with global PHP-to-FPM handler taking priority over proxied location, define the tt-rss location like this so it takes higher priority: + +```nginx +location ^~ /tt-rss/ { + .... +} +``` + +If you want to pass an entire nginx virtual host to tt-rss: + +```nginx +server { + server_name rss.example.com; + + ... + + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://127.0.0.1:8280/; + break; + } +} +``` + +Note that `proxy_pass` in this example points to container website root. + +#### Apache example + +``` + + + ProxyPreserveHost On + ProxyPass http://localhost:8280/tt-rss + ProxyPassReverse http://localhost:8280/tt-rss + RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME} + + +``` + +### I have internal web services tt-rss is complaining about (URL is invalid, loopback address, disallowed-ports) + +Put your local services on the same Docker network with tt-rss, then access them by service (=-host) names, i.e. `http://rss-bridge/`. + +```yml +services: + rss-bridge: +.... +networks: + default: + external: + name: ttrss-docker_default +``` + +If your service uses a non-standard (i.e. not 80 or-443) port, make an internal reverse proxy sidecar container for it. + +### Backup and restore + +If you have `backups` container enabled, stock configuration makes automatic backups (database, local plugins,-etc.) once a week to a separate storage volume. + +Note that this container is included as a safety net for people who wouldn't bother with backups otherwise. +If you value your data, you should invest your time into setting up something like [WAL-G](https://github.com/wal-g/wal-g) instead. + +#### Manually taking a backup + +To run [`.docker/app/backup.sh`](https://github.com/tt-rss/tt-rss/blob/main/.docker/app/backup.sh) (the backup script that executes-weekly): + +`docker compose exec backups /etc/periodic/weekly/backup` + +Alternatively, if you want to initiate backups from the host (or if you're using PostgreSQL 18+, currently incompatible with the `backup`-container) you can do something like this: + +```sh +source .env +docker compose exec \ + -e PGPASSWORD="$TTRSS_DB_PASS" \ + db \ + /bin/bash \ + -c "export PGPASSWORD=$TTRSS_DB_PASS \ + && pg_dump -U $TTRSS_DB_USER $TTRSS_DB_NAME" \ + | gzip -9 > backup.sql.gz +``` + +#### Restoring backups + +The process to restore the database from a `backups` container backup might look like this: + +1. Enter `backups` container shell: `docker compose exec backups /bin/sh` +2. Inside the container, locate and choose the backup file: `ls -t /backups/*.sql.gz` +3. Clear database (**THIS WOULD DELETE EVERYTHING IN THE-DB**): `psql -h db -U $TTRSS_DB_USER $TTRSS_DB_NAME -e -c "drop schema public cascade; create schema public"` +3. Restore the backup: `zcat /backups/ttrss-backup-yyyymmdd.sql.gz | psql -h db -U $TTRSS_DB_USER $TTRSS_DB_NAME` + +### How do I use custom certificates? + +You need to mount custom certificates into the *app* and *updater* containers like this: + +```yml +volumes: + .... + ./ca1.crt:/usr/local/share/ca-certificates/ca1.crt:ro + ./ca2.crt:/usr/local/share/ca-certificates/ca2.crt:ro + .... +``` + +Don't forget to restart the containers. + +### How do I run these images on Kubernetes? + +You'll need to set several mandatory environment values to the container running the `web-nginx` image: + +1. `APP_UPSTREAM` should point to the fully-qualified DNS service name provided by the app (FPM) container/pod +2. `RESOLVER` should be set to `kube-dns.kube-system.svc.cluster.local` + +### Where's the Helm chart? + +You'll have to make your own. + +### I'm using Podman, and... + +We neither test against nor support Podman. diff --git a/docs/Making-Plugins.md b/docs/Making-Plugins.md new file mode 100644 index 0000000..2080839 --- /dev/null +++ b/docs/Making-Plugins.md @@ -0,0 +1,39 @@ +--- +layout: default +title: Making Plugins +nav_order: 11 +--- + +Plugins may render new preference panes or embed themselves into several +existing one, store data using simple key -\> value data or directly in +the database, modify how articles are rendered, alter feed data, and +much more. + +You can use sample plugins bundled with tt-rss and [other +plugins](Plugins) as a starting point. Ask on the forums if you need help +with anything specific. + +Some useful information may be found here: + +- https://github.com/tt-rss/tt-rss/blob/main/classes/PluginHost.php +- https://github.com/tt-rss/tt-rss/blob/main/classes/Plugin.php + +Frontend (JS) uses different hooks, which are defined in [PluginHost.js](https://github.com/tt-rss/tt-rss/blob/main/js/PluginHost.js) + +## Localization support + +See ``time_to_read`` plugin for a complete example [here](https://github.com/tt-rss/tt-rss-plugin-time-to-read) + +### Implementation + +- Plugin translations are placed in a separate Gettext domain (name equals lowercase plugin-class). +- Translation (.po) file in ``(plugin-dir)/locale/(LANG)/LC_MESSAGES/`` name should correspond to Gettext domain name. + +### Using gettext + +- On the PHP side, either use helper methods defined in ``classes/plugin.php`` + (base class for all-plugins) or call ``_dgettext`` group of functions + directly. +- On the Javascript side, all translations are merged so you can use the usual + ``__()`` shortcut function. + diff --git a/docs/Plugins.md b/docs/Plugins.md new file mode 100644 index 0000000..dcc287c --- /dev/null +++ b/docs/Plugins.md @@ -0,0 +1,124 @@ +--- +layout: default +title: Plugins +nav_order: 10 +--- + +Tiny Tiny RSS supports many kinds of plugins: social plugins which share +articles to various sites, article filter plugins which mangle feed-provided +data on import (for example, inlining images or extracting full article-text +using Readability), hotkey plugins which alter the way keyboard shortcuts work, +etc. + +There are two kinds of plugins: user and system. User plugins are enabled in +`Preferences` → `Plugins`. System plugins require adding them to a [global +configuration](Global-Config) directive PLUGINS which is a +comma-separated list of enabled system plugins, i.e. + +```js +putenv('TTRSS_PLUGINS=auth_internal,-other_plugin'); +``` + +System plugins are always enabled for all users. If multiple search plugins are loaded, only the first one is used + +If you are interested in making plugins, see [Making-Plugins](Making-Plugins), +https://github.com/topics/tt-rss-plugin , https://github.com/topics/ttrss-plugins , etc. + +### Installing plugins + +> [!NOTE] +> First party plugins can be added via built-in plugin installer in `Preferences` → `Plugins`. + +Copy plugin folder to ```tt-rss/plugins.local``` then activate it in the settings panel. +Plugin folder name should correspond to plugin class name defined in ``(plugin)/init.php``, +i.e. ``Af_ExamplePlugin`` should be copied to ``plugins.local/af_exampleplugin``. + +## First party plugins (maintained on this site but not bundled with-tt-rss) + +https://github.com/orgs/tt-rss/repositories?q=tt-rss-plugin+sort%3Aname-asc + +## Third party plugins + +> [!WARNING] +> We’re not responsible for third party plugins. Use at your own risk. + +> [!NOTE] +> Third party plugins may be unmaintained and incompatible with newer tt-rss +> code (especially those from the old-forums). Please report plugin-related +> problems to their developers. + +### Sharing plugins + +#### A Tiny Tiny RSS plugin to post to a Wallabag v2 instance + +https://github.com/joshp23/ttrss-to-wallabag-v2 + +#### A plugin for Tiny Tiny RSS, to shorten urls via Yourls + +https://github.com/joshp23/tt-rss-yourls + +#### Adds support for sharing links with Shaarli to tt-rss + +https://github.com/joshp23/tt-rss-shaarli + +#### Convert DOI and other links to Sci-Hub links in TT-Rss + +https://github.com/joshp23/ttrss-to-Sci-Hub + +### Feed data manipulation plugins + +#### Enable embedded videos in feeds - videoframes + +https://github.com/tribut/ttrss-videoframes + +#### Configurable plugin to replace article stub with content from the linked URL's page + +https://github.com/feediron/ttrss_plugin-feediron + +#### A simple plugin to assist in the display of images from NASA's Astronomy Picture of the Day feed in TT-RSS + +https://github.com/joshp23/TTRSS-APOD-Fix + +### Webcomics plugins + +#### Comic plugin GU Comics, Married to the sea & Toothpaste for dinner + +https://github.com/tribut/ttrss-comics + +#### Lint/tidy plugin to repair invalid feeds + +https://github.com/Churten/tt-rss-ff-xmllint + +#### Embed content from Tapastic rss streams + +https://github.com/ldidry/af_tapastic.git + +### API plugins + +#### FreshRSS / Google Reader API Support + +Use any RSS app or client that supports FreshRSS or the Google Reader API. + +https://github.com/eric-pierce/freshapi + +#### Fever API emulator + +Simulates the Fever API for reading RSS Feeds with your Fever clients. + +https://github.com/DigitalDJ/tinytinyrss-fever-plugin + +### Other plugins + +#### Generate QR codes from article links, with xhr support and no disk cache + +https://github.com/GregThib/ttrss-qrcodegen + +#### Send XMPP notifications via Prosody mod_post_msg + +https://github.com/joshp23/ttrss-notify-xmpp-prosody + +#### Plugins for alternative navigation and night mode + +Set of plugins to (1) use cursor keys for a tree-style article navigation; (2) change to a minimal set of hotkeys; (3) toggle night mode for custom themes; (4) change the sort order of unread articles to Oldest first. + +https://github.com/ltGuillaume/FeedMei/tree/master/plugins.local/ diff --git a/docs/Publish-Articles.md b/docs/Publish-Articles.md new file mode 100644 index 0000000..4e8b2fe --- /dev/null +++ b/docs/Publish-Articles.md @@ -0,0 +1,21 @@ +--- +layout: default +title: Publish Articles +nav_order: 46 +--- + +You can publish selected articles to a special RSS feed, accessible to anyone +who knows the special randomly-generated URL. This works independently of +[Generated-Feeds](Generated-Feeds.md) which allows you to share entire feeds, +categories, etc. + +You can mark articles as published by clicking [standard feed +icon](http://feedicons.com/) near headline title: + +![](../images/publish_articles.png) + +Resulting URL is displayed in Preferences (`Feeds` → `Published & shared-articles`). + + +> [!NOTE] +> You can also publish articles automatically using filters (`Action` → `Publish-article`). diff --git a/docs/SSL-Certificate-Authentication.md b/docs/SSL-Certificate-Authentication.md new file mode 100644 index 0000000..37d8538 --- /dev/null +++ b/docs/SSL-Certificate-Authentication.md @@ -0,0 +1,96 @@ +--- +layout: default +title: SSL Certificate Authentication +nav_order: 52 +--- + +> [!WARNING] +> This guide is considered legacy and is no longer supported as it is not compatible with the +> [stock Docker Compose](Installation-Guide) setup. Please don't report any issues when +> trying to DIY this. + +This article details the steps to enable user authentication with TT-RSS using a client certificate. + +## Prerequisites + +You **must** have a working TT-RSS installation with SSL. This guide is not intended to walk you through installing TT-RSS, nor is it intended to help you enable HTTPS on your web server. + +If you have no idea how certificates work (i.e. the terms x509 and PKI make no sense to-you), stop now. + +This guide includes steps for Nginx. Of course other web servers (e.g.-Apache) support client certificates so you're welcome to use them if you prefer, the steps just aren't included here (but might be added at some-point). + +This guide was written with Debian 9 in mind, other distros will vary. + +## Getting Started + +Client certificates are typically created/issued by a private Certificate Authority (i.e. **you** as the administrator would create the certificates for your-users). You create a root certificate authority and install the **public** certificate for it on your web server. You then create certificates for each client, signed by the root certificate authority's private key. Each client is issued their certificate and private key (often as a single file with a `.p12`-extension). + +Note: + +1. These certificates are distinct from the ones used for encrypted/HTTPS connections on your server. Those are usually issued by public Certificate Authorities (e.g. Let's-Encrypt). +2. Do **not** do the certificate creation on your public, Internet-facing web server. This should be done on a computer that's offline and the certificate authority's private key should be kept in a safe place. + +## Server Setup + +Install your certificate authority public certificate on the server. The location doesn't really matter but this is how Debian does it: + +```sh +sudo cp ttrss-ca.crt /usr/local/share/ca-certificates/ +sudo chown root:root /usr/local/share/ca-certificates/ttrss-ca.crt +sudo chmod 644 /usr/local/share/ca-certificates/ttrss-ca.crt +``` + +(In Debian run the command `sudo update-ca-certificates` to rebuild the list of certificate-authorities.) + +Edit your Nginx conf file for your TT-RSS installation to add the certificate and have Nginx validate clients with it. + +Note: + +1. The file path and extension to the certificate are different than above because Debian builds a consolidated list of certificate authorities provided by the vendor, user, etc.; this is why we ran the update-ca-certificates command above and your distro may vary its approach so be aware of that. +2. We use `ssl_verify_client on;` which prevents access to the site unless a valid certificate is provided. If you want **both** password and certificate authentication, use `ssl_verify_client optional;` instead. +3. In the php location we do not use `$ssl_client_v_start` and `$ssl_client_v_end` Nginx variables by default. These variables were added in Nginx version 1.11.7 and Debian 9 does not ship that version. It's included as a comment for future support. + +```nginx +server { + + ssl_client_certificate /etc/ssl/certs/ttrss-ca.pem + ssl_verify_client on; + # ssl_verify_client optional; + + location ~ [^/]\.php(/|$) { + + fastcgi_param SSL_CLIENT_M_SERIAL $ssl_client_serial; + fastcgi_param SSL_CLIENT_S_DN $ssl_client_s_dn; + # fastcgi_param SSL_CLIENT_V_START $ssl_client_v_start; + # fastcgi_param SSL_CLIENT_V_END $ssl_client_v_end; + fastcgi_param SSL_CLIENT_V_START 0; + fastcgi_param SSL_CLIENT_V_END 0; + + } + +} +``` + +Now restart Nginx: + +```sh +sudo systemctl restart nginx +``` + +Update the TT-RSS config file to add `auth_remote` to the `PLUGINS` constant (near the end of the-file): + +```php +define('PLUGINS', 'auth_internal, auth_remote,-note'); +``` + +You might be tempted to remove `auth_internal` but we still need it so don't. + +Next, make sure your client certificate (the `.p12`-file) is installed on your computer. Different operating systems and browsers do this differently, so you're pretty much on your own there, but if you double-click the .p12 file from the desktop the operating system should offer to install it for you. Vendor-provided browsers (e.g. IE/Edge, Safari,-etc.) will typically use certificates provided by the operating system. Third-party installed browsers (e.g.-Firefox) often need to have the .p12 file added to them independent of the operating system. + +After successfully installing the client certificate, open a new browser window/tab and visit your TT-RSS install. You should immediately be asked to confirm or select the client certificate you want to use. Select the appropriate one. You may have to login with your username/password; this is expected. + +Go to Preferences and scroll to the bottom. Under *Login with an SSL certificate* the *Register* button should now be available. Click it, then *Save configuration*. + +At this point you should be able to test if this all works. Logout of your TT-RSS session, clear your browser cache and cookies, then open a new window/tab and visit your TT-RSS install. You may be asked to verify the client certificate (some browsers ask every session and others remember your-choice). Once you select the certificate it should just log you without using the username/password form. + +Finally, if you're never going to use password authentication you could remove `auth_internal` plugin in `config.php`, just remember to add it back if you remove certificate support in the future otherwise you'll get the login form but will never be able to login. You'll also need to enable it if you have to change client certificates as there will be no other way of logging in. diff --git a/docs/Scoring.md b/docs/Scoring.md new file mode 100644 index 0000000..1167107 --- /dev/null +++ b/docs/Scoring.md @@ -0,0 +1,32 @@ +--- +layout: default +title: Scoring +nav_order: 47 +--- + +Scoring is supported in a way similar to some newsreaders. Score is calculated +on article import using special filters with a "Modify score" action. + +Resulting score is a sum of all score modifiers from all matching filters. For +example, if the article matches two filters A (score-+100) and B (score--50), +the resulting score will be 50. + +Article score affects the position of the article in the headline buffer (which +is sorted by score) and alters the way article is displayed: + +| Score | Display / Action | +|-------|------------------| +| `<-500` | Score indicator points down, article is automatically marked as read +| `<-100` | Score indicator points down +| `<0` | Score indicator points down, 1.5.0: article is excluded from Fresh feed and (as of 1.5.10 also excluded from email-digest) | +| `0` | Display normally | +| `>0` | Score indicator points up | +| `>500` | Score indicator points up | +| `>1000` | Same as above, article is also marked as starred | + +### Adjusting manually + +Calculated score for an individual article may be adjusted by clicking on score +indicator in the headlines list: + +![](../images/score_indicator2.png) diff --git a/docs/Search-Syntax.md b/docs/Search-Syntax.md new file mode 100644 index 0000000..52a876f --- /dev/null +++ b/docs/Search-Syntax.md @@ -0,0 +1,25 @@ +--- +layout: default +title: Search Syntax +nav_order: 48 +--- + +> [!NOTE] +> This only applies to built-in search, other search plugins like may override this syntax. + +Search query consists of several keywords. Keyword starting with "-" is considered a negative match. Several special keywords are available: + +* ``@{date}`` - match by date. For example, @yesterday or @2011-11-03. Please note that due to incomplete implementation, special date keywords like yesterday might not match all articles if user timezone is different from tt-rss internal timezone (UTC). +* ``pub:{true,false}`` - match only published or unpublished articles +* ``star:{true, false}`` - same, starred articles +* ``unread:{true, false}`` - self explanatory (requires trunk as of-05.03.2015) +* ``note:{true, false, sometext}`` - same, for articles having an attached note or matching the specified text +* ``label:Somelabel`` - articles that belong to a specified label +* ``tag:mytag`` - articles which have specified tag +* ``title:``, ``author:`` - self explanatory + +When searching by keyword with spaces, use quotes like this: `"title:string with spaces"` or `tag:"multiple words"` + +If no special keywords are specified, search is done using PostgreSQL [Full Text Search](https://www.postgresql.org/docs/current/textsearch-intro.html) engine. + +Pointless as it may be, you can combine negative prefix with the special keywords: -star:true would essentially mean star:false. diff --git a/docs/Securing-Cache-Directories.md b/docs/Securing-Cache-Directories.md new file mode 100644 index 0000000..0d773f8 --- /dev/null +++ b/docs/Securing-Cache-Directories.md @@ -0,0 +1,43 @@ +--- +layout: default +title: Securing Cache Directories +nav_order: 49 +--- + +> [!NOTE] +> Official container images restrict `/cache` access by default. This page applies only to +> legacy host installations. + +While nothing critical is stored in cache directories by tt-rss nor do files +have easily guessable names, you may consider forbidding external access over +HTTP to these directories anyway. This is not required, however. + +You may also consider restricting access to config.php, just in case. + +## Using nginx + +```nginx +location /tt-rss/cache { + deny all; +} + +location = /tt-rss/config.php { + deny all; +} +``` + +Note: official docker setup has this out of the box. + +## Using apache (2.4-syntax) + +```apache + + Require all denied + + + + + Require all denied + + +``` diff --git a/docs/Share-Anything.md b/docs/Share-Anything.md new file mode 100644 index 0000000..e85e2c2 --- /dev/null +++ b/docs/Share-Anything.md @@ -0,0 +1,18 @@ +--- +layout: default +title: Share Anything +nav_order: 50 +--- + +You can share arbitrary webpages to appear as articles in your ``Published`` +feed. Combined with Readability this makes tt-rss function like a read-it-later +kind of website. + +Sharing is available via bookmarklet in Preferences: (`Feeds`-→ +`Bookmarklets`) (if you have ``bookmarklets`` plugin-enabled) or through Android +application. + +![](../images/share_anything.png) + +Since they have no actual originating feed, shared articles are placed into +[Archived articles](Archived-Feed) feed and then set published. diff --git a/docs/Sorting.md b/docs/Sorting.md new file mode 100644 index 0000000..2129420 --- /dev/null +++ b/docs/Sorting.md @@ -0,0 +1,57 @@ +--- +layout: default +title: Sorting +nav_order: 51 +--- + +Tiny Tiny RSS provides four options for how articles appear within a +selected feed: `Default`, `Newest`, `Oldest`, `Title`. + +> [!NOTE] +> Special feeds (e.g. *Starred-articles*) have unique sorting when *Default* is selected, otherwise they behave as described below. + +- *Descending score* means **higher numbers** are shown before lower numbers. +- *Descending date/time* means **more recent** is shown before less recent. +- *Ascending date/time* means **less recent** is shown before more recent. + +### Default + +This is the default (surprise!) and is recommended. + +1. Descending [score](Scoring). +2. Descending date/time the article was added into the Tiny Tiny RSS database. +3. Descending date/time the feed's site states the article was published or changed. + +### Newest + +1. Descending date/time the feed's site states the article was published or changed. + +### Oldest + +1. Ascending date/time the feed's site states the article was published or changed. + +### Title + +1. Alphabetically by the title of the article. +2. Ascending date/time the article was added into the Tiny Tiny RSS database +3. Ascending date/time the feed's site states the article was published or changed. + +## Special Feeds + +When *Default* is selected these special feeds behave as described below. + +### Starred articles + +1. Descending date/time when the article was starred. +2. Descending date/time the article was added into the Tiny Tiny RSS database. +3. Descending date/time the feed's site states the article was published or changed. + +### Published articles + +1. Descending date/time when the article was published. +2. Descending date/time the article was added into the Tiny Tiny RSS database. +3. Descending date/time the feed's site states the article was published or changed. + +### Recently read + +1. Descending date/time when the article was marked as read in Tiny Tiny RSS. diff --git a/docs/Themes.md b/docs/Themes.md new file mode 100644 index 0000000..a8f90f6 --- /dev/null +++ b/docs/Themes.md @@ -0,0 +1,46 @@ +--- +layout: default +title: Themes +nav_order: 12 +--- + +Install by copying theme CSS (and any other content, if-needed) into ``themes.local`` directory under tt-rss root, then you'll be able to activate it in preferences. + +**Please note that we’re not responsible for third party themes. Use at your own risk.** + +### FeedMei Theme + Plugins for Tiny Tiny RSS + + + + +A clean and minimal theme for Tiny Tiny RSS, loosely inspired by Feedly. Built by making the minimal amount of changes to the default theme. This repo also includes a set of plugins. + +**Codeberg** https://codeberg.org/ltguillaume/feedmei + +### Clean GReader Theme + + + +A theme built from scratch, independent of default css. Inspired by the +Google Reader it has a white/greyish look. + +**Github** https://github.com/naeramarth7/clean-greader + +### Feedly Theme + + + +A theme built from scratch, independent of default css. Emulates the greyish look of Feedly. + +**Github** https://github.com/levito/tt-rss-feedly-theme + +### Reeder Theme + + + +Theme emulates the paper/brownish look of the Reeder App from IOS. + +**Github** + +* tt-rss \>1.11 https://github.com/tschinz/tt-rss\_reeder\_theme +* tt-rss \<1.11 (old-version) https://github.com/tschinz/tt-rss\_reeder\_theme/tree/legacy diff --git a/images/gen_feed_dialog.png b/images/gen_feed_dialog.png new file mode 100644 index 0000000..127693a Binary files /dev/null and b/images/gen_feed_dialog.png differ diff --git a/images/gen_feed_icon.png b/images/gen_feed_icon.png new file mode 100644 index 0000000..7fc0a41 Binary files /dev/null and b/images/gen_feed_icon.png differ diff --git a/images/publish_articles.png b/images/publish_articles.png new file mode 100644 index 0000000..645b784 Binary files /dev/null and b/images/publish_articles.png differ diff --git a/images/score_indicator2.png b/images/score_indicator2.png new file mode 100644 index 0000000..4b21dd1 Binary files /dev/null and b/images/score_indicator2.png differ diff --git a/images/share_anything.png b/images/share_anything.png new file mode 100644 index 0000000..b4ea919 Binary files /dev/null and b/images/share_anything.png differ diff --git a/images/tt-rss-android/Screenshot_20250509_135136.webp b/images/tt-rss-android/Screenshot_20250509_135136.webp new file mode 100644 index 0000000..5fcfaf2 Binary files /dev/null and b/images/tt-rss-android/Screenshot_20250509_135136.webp differ diff --git a/images/tt-rss-android/Screenshot_20250509_135154.webp b/images/tt-rss-android/Screenshot_20250509_135154.webp new file mode 100644 index 0000000..91fc385 Binary files /dev/null and b/images/tt-rss-android/Screenshot_20250509_135154.webp differ diff --git a/images/tt-rss-android/Screenshot_20250509_135217.webp b/images/tt-rss-android/Screenshot_20250509_135217.webp new file mode 100644 index 0000000..1d833a7 Binary files /dev/null and b/images/tt-rss-android/Screenshot_20250509_135217.webp differ diff --git a/images/tt-rss-android/Screenshot_20250509_135426.webp b/images/tt-rss-android/Screenshot_20250509_135426.webp new file mode 100644 index 0000000..76414fa Binary files /dev/null and b/images/tt-rss-android/Screenshot_20250509_135426.webp differ diff --git a/images/tt-rss-android/Screenshot_20250509_135438.webp b/images/tt-rss-android/Screenshot_20250509_135438.webp new file mode 100644 index 0000000..ffae586 Binary files /dev/null and b/images/tt-rss-android/Screenshot_20250509_135438.webp differ diff --git a/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.21.21.webp b/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.21.21.webp new file mode 100644 index 0000000..f62b4dc Binary files /dev/null and b/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.21.21.webp differ diff --git a/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.19.webp b/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.19.webp new file mode 100644 index 0000000..9ecdd5b Binary files /dev/null and b/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.19.webp differ diff --git a/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.50.webp b/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.50.webp new file mode 100644 index 0000000..edd76ca Binary files /dev/null and b/images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.50.webp differ diff --git a/index.md b/index.md new file mode 100644 index 0000000..70eff46 --- /dev/null +++ b/index.md @@ -0,0 +1,79 @@ +--- +layout: default +title: Home +nav_order: 1 +description: "Tiny Tiny RSS (tt-rss) is a free, flexible, open-source, web-based news feed (RSS/Atom/other) reader and aggregator." +permalink: / +--- + +# Tiny Tiny RSS + +Tiny Tiny RSS (tt-rss) is a free, flexible, open-source, web-based news feed (RSS/Atom/other) reader and aggregator. + +## Screenshots + +[](images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.19.webp) +[](images/tt-rss/25.05/Screenshot_2025-05-10_at_09.21.21.webp) +[](images/tt-rss/25.05/Screenshot_2025-05-10_at_09.22.50.webp) + +## Features + +- Free software, licensed under [GNU GPLv3](http://www.gnu.org/copyleft/gpl.html) +- Self-hosted: control your own data and protect your privacy instead of relying on third party services +- Supports: + - organizing feeds by folders (and subfolders) + - [feed aggregation / syndication](docs/Generated-Feeds.md) + - keyboard shortcuts + - OPML import/export + - multiple ways to share stuff: export RSS feeds, plugins for various social sites, sharing by URL, etc. + - [sharing arbitrary content through tt-rss](docs/Share-Anything.md) + - [Plugins](docs/Plugins.md) and [themes](docs/Themes.md) + - embedding full article content via readability and site-specific plugins + - deduplication, including [perceptual hashing](https://github.com/tt-rss/tt-rss-plugin-perceptual-image-hash) for images + - podcasts + - [flexible article filtering](docs/Content-Filters.md) + - [JSON API](docs/API-Reference.md) + - and much more… +- [Android Client](docs/Android-Client.md) + +## Installation + +You will need the following: +* A modern web browser. This generally means a recent version of Chrome/Chromium or Firefox. +* A system running Docker. + +See the [Installation Guide](docs/Installation-Guide.md) for detailed instructions. + +> [!WARNING] +> If you choose to run tt-rss without using Docker support might be limited. + +> [!NOTE] +> Tiny Tiny RSS uses a continuous development model based on the `main` branch, which is considered stable. +> It's strongly recommended that you remain current-- meaning using either the most recent Docker image(s) or commit on `main`. + +## Get in touch + +* Go to [https://github.com/tt-rss/tt-rss/discussions](https://github.com/tt-rss/tt-rss/discussions) if you have questions or want to discuss something. +* Go to [https://github.com/tt-rss/tt-rss/issues](https://github.com/tt-rss/tt-rss/issues) if you want to report an issue, request an enhancement/feature, etc. + +## Documentation + +Browse the documentation: + +- [Installation Guide](docs/Installation-Guide.md) +- [API Reference](docs/API-Reference.md) +- [Plugins](docs/Plugins.md) and [Making Plugins](docs/Making-Plugins.md) +- [Themes](docs/Themes.md) +- [Content Filters](docs/Content-Filters.md) +- [FAQ](docs/FAQ.md) +- [Global Configuration](docs/Global-Config.md) + +## Development and Contributing + +* Contributions (documentation improvements, translations, reporting issues, etc.) are welcome. +* Development and issue tracking primarily happens in [https://github.com/tt-rss/tt-rss](https://github.com/tt-rss/tt-rss). +* Help translate tt-rss into your own language using [Weblate](https://hosted.weblate.org/engage/tt-rss/). + +--- + +This documentation is licensed under [CC BY-SA 4.0](LICENSE). The tt-rss software is licensed under [GNU GPLv3](https://www.gnu.org/copyleft/gpl.html).