Tiny Tiny RSS#

Upgrade#

Updating to a major TT-RSS version requires a database migration. This happens for example when you upgrade from Debian 10 (TT-RSS 18) to Debian 11 (TT-RSS 21)

See also

  • Tiny Tiny RSS - ArchWiki 1

  1. make a backup of the database

  2. update TT-RSS

    sudo -u www-data -- /usr/bin/php /usr/share/tt-rss/www/update.php --update-schema=force-yes
    

Torification#

TT-RSS can download all feeds through TOR.

Some websites actively block TOR exit node addresses. In this case you will need to configure an RSS bridge/proxy which can be simply a script that downloads the RSS XML file through clearnet. This file must then be served on a system that is accessible to your TT-RSS instance.

See also

  • Tiny Tiny RSS over TOR 2

  1. install TOR and Privoxy

    apt-get install tor privoxy
    
  2. Check that TOR is running

    systemctl status tor@default.service
    
  3. configure Privoxy. Add this content to the configuration file

    /etc/privoxy/config#
    1forward-socks5t    /   127.0.0.1:9050   .
    2listen-address    127.0.0.1:8123
    3
    4# [ ... ]
    

    Note

    You can add more forwarding rules to ignore routing the traffic through TOR for specific domains. Have a look at the /etc/privoxy/config file provided by the package which is well documented.

  4. append the following at the end of TT-RSS's configuration file

    /etc/tt-rss/config.php#
    1    // [ ... ]
    2
    3    define('HTTP_PROXY', '127.0.0.1:8123');
    4    define('_HTTP_PROXY', '127.0.0.1:8123');
    5    define('_CURL_HTTP_PROXY', '127.0.0.1:8123');
    6    define('SELF_USER_AGENT', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0');
    

    These variables should cover recent TT-RSS versions.

  5. restart the services

    systemctl restart tt-rss privoxy ${webserver}
    

Feed proxy#

Sometimes TT-RSS is unable to fetch feeds. You can use this script to act as a bridge to download the XML files directly. You need a running webserver, in this example Apache HTTPD, and then point TT-RSS to the new RSS feed URLs.

  1. install the dependencies

    apt-get install python3-yaml
    
  2. install fpyutils. See reference

  3. create a new user

    useradd -m -s /bin/bash -U rss
    passwd rss
    usermod -aG jobs rss
    
  4. create the jobs directories. See reference

    mkdir -p /home/jobs/{scripts,services}/by-user/rss
    
  5. create the script

    /home/jobs/scripts/by-user/rss/feed_proxy.py#
     1#!/usr/bin/env python3
     2# -*- coding: utf-8 -*-
     3#
     4# feed_proxy.py
     5#
     6# Copyright (C) 2021-2022 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com)
     7#
     8# This program is free software: you can redistribute it and/or modify
     9# it under the terms of the GNU General Public License as published by
    10# the Free Software Foundation, either version 3 of the License, or
    11# (at your option) any later version.
    12#
    13# This program is distributed in the hope that it will be useful,
    14# but WITHOUT ANY WARRANTY; without even the implied warranty of
    15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16# GNU General Public License for more details.
    17#
    18# You should have received a copy of the GNU General Public License
    19# along with this program.  If not, see <https://www.gnu.org/licenses/>.
    20r"""Save RSS feeds."""
    21
    22import pathlib
    23import shlex
    24import sys
    25import time
    26
    27import requests
    28import yaml
    29
    30if __name__ == '__main__':
    31    configuration_file = shlex.quote(sys.argv[1])
    32    config = yaml.load(open(configuration_file, 'r'), Loader=yaml.SafeLoader)
    33
    34    for f in config['feeds']:
    35        for feed in f:
    36            try:
    37                if f[feed]['user_agent'] == str():
    38                    headers = dict()
    39                else:
    40                    headers = {'User-Agent': f[feed]['user_agent']}
    41                r = requests.get(f[feed]['url'], headers=headers, timeout=60)
    42                full_path_file = str(
    43                    pathlib.Path(config['files']['base_path'],
    44                                 f[feed]['relative_path']))
    45                # Write the new file as binary.
    46                with open(full_path_file, 'wb') as f:
    47                    f.write(r.content)
    48
    49            except requests.exceptions.RequestException as e:
    50                print(e)
    51
    52            time.sleep(config['network']['sleep_seconds_between_feeds'])
    
  6. create a configuration file

    /home/jobs/scripts/by-user/rss/feed_proxy.mypurpose.yaml#
     1#
     2# feed_proxy.mypurpose.yaml
     3#
     4# Copyright (C) 2021-2022 Franco Masotti (franco \D\o\T masotti {-A-T-} tutanota \D\o\T com)
     5#
     6# This program is free software: you can redistribute it and/or modify
     7# it under the terms of the GNU General Public License as published by
     8# the Free Software Foundation, either version 3 of the License, or
     9# (at your option) any later version.
    10#
    11# This program is distributed in the hope that it will be useful,
    12# but WITHOUT ANY WARRANTY; without even the implied warranty of
    13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14# GNU General Public License for more details.
    15#
    16# You should have received a copy of the GNU General Public License
    17# along with this program.  If not, see <https://www.gnu.org/licenses/>.
    18
    19feeds:
    20    - Feed one:
    21        url: 'https://some.domain/atom.xml'
    22        relative_path: 'some_domain.xml'
    23        # Leave empty for default.
    24        user_agent: ''
    25    - Feed two:
    26        url: 'https://another.domain/rss.xml'
    27        relative_path: 'another.xml'
    28        user_agent: ''
    29
    30files:
    31    base_path: '/var/www/feeds'
    32
    33network:
    34    sleep_seconds_between_feeds: 10
    

    Important

    files.base_path must point to a readable directory of the webserver, for example /var/www

  7. create the Systemd service unit file

    /home/jobs/services/by-user/rss/feed-proxy.mypurpose.service#
     1[Unit]
     2Description=Feed proxy mypurpose
     3Requires=network-online.target
     4After=network-online.target
     5
     6[Service]
     7Type=simple
     8ExecStart=/home/jobs/scripts/by-user/rss/feed_proxy.py /home/jobs/scripts/by-user/rss/feed_proxy.mypurpose.yaml
     9User=rss
    10Group=rss
    

    Note

    You can use torsocks to retrieve feeds via TOR.

  8. create the Systemd service timer unit file

    /home/jobs/services/by-user/rss/feed-proxy.mypurpose.timer#
    1[Unit]
    2Description=Once every 60 minutes feed proxy mypurpose
    3
    4[Timer]
    5OnCalendar=hourly
    6Persistent=true
    7
    8[Install]
    9WantedBy=timers.target
    
  9. add the rss user to the group of the user running the webserver, www-data

    usermod -aG www-data rss
    
  10. run the deploy script

Footnotes

1

https://wiki.archlinux.org/title/Tiny_Tiny_RSS#Pacman_hook GNU Free Documentation License 1.3 or later, Copyright (c) ArchWiki contributors

2

https://blog.franco.net.eu.org/notes/tt-rss-torification.html CC BY-SA 4.0, Copyright (c) 2021 Franco Masotti