{"id":13456391,"url":"https://github.com/ssddanbrown/rss","last_synced_at":"2025-04-04T20:14:53.001Z","repository":{"id":41477254,"uuid":"508483613","full_name":"ssddanbrown/rss","owner":"ssddanbrown","description":"PROJECT MIGRATED TO CODEBERG -- A simple twitter-feed-style RSS aggregator written in PHP, Laravel, Inertia.js, Tailwind and Vue.js","archived":false,"fork":false,"pushed_at":"2024-08-02T17:15:36.000Z","size":1930,"stargazers_count":550,"open_issues_count":0,"forks_count":21,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-28T19:12:46.299Z","etag":null,"topics":["inertiajs","laravel","php","rss","rss-aggregator"],"latest_commit_sha":null,"homepage":"https://codeberg.org/danb/rss","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ssddanbrown.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["ssddanbrown"],"ko_fi":"ssddanbrown"}},"created_at":"2022-06-28T23:26:22.000Z","updated_at":"2025-03-24T20:18:53.000Z","dependencies_parsed_at":"2023-09-29T00:43:46.591Z","dependency_job_id":"213c84a0-b361-4041-99b7-481fea9aeff7","html_url":"https://github.com/ssddanbrown/rss","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssddanbrown%2Frss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssddanbrown%2Frss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssddanbrown%2Frss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssddanbrown%2Frss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ssddanbrown","download_url":"https://codeload.github.com/ssddanbrown/rss/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242680,"owners_count":20907134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["inertiajs","laravel","php","rss","rss-aggregator"],"created_at":"2024-07-31T08:01:21.125Z","updated_at":"2025-04-04T20:14:52.974Z","avatar_url":"https://github.com/ssddanbrown.png","language":"PHP","funding_links":["https://github.com/sponsors/ssddanbrown","https://ko-fi.com/ssddanbrown"],"categories":["Apps","置顶","PHP"],"sub_categories":["RSS","9、效率工具集合"],"readme":"# RSS\n\nA simple, opinionated, RSS feed aggregator.\n\n[![PHPUnit](https://github.com/ssddanbrown/rss/actions/workflows/phpunit.yml/badge.svg?branch=main)](https://github.com/ssddanbrown/rss/actions/workflows/phpunit.yml)\n\n## Features\n\nThe following features are built into the application:\n\n- Supports RSS and ATOM formats.\n- Regular auto-fetching of RSS feeds.\n  - Every hour by default, configurable down to 5 mins. \n- Custom feed names and colors.\n- Feed-based tags for categorization.\n- Ability to hide feed posts by default.\n- 3 different post layout modes (card, list, compact).\n- Fetching of page open-graph images.\n- Feeds managed via a single plaintext file.\n- System-based dark/light theme.\n- Post title/description search.\n- Ready-to-use docker image.\n- Mobile screen compatible.\n- Built-in support to prune old post data.\n\n## Limitations\n\nThe below possibly expected features are missing from this application.\nThis is not a list of planned features. Please see the [Low Maintenance Project](#low-maintenance-project) section below for more info.\n\n- No import of full post/article content.\n- No feed management via the UI.\n- No user system or user management system.\n- No authentication or authorization built-in.\n- No customization, extension or plugin system.\n- No organisation upon simple feed-level tagging.\n- Error handling is limited and will likely not alert clearly upon issue.\n\nUpon the above, it's quite likely you'll come across issues. This project was created to meet a personal need while learning some new technologies. Much of the logic is custom written instead of using battle-tested libraries. \n\n## Screenshots\n\n\n\u003ctable\u003e\n\t\u003ctbody\u003e\n\t\t\u003ctr\u003e\n\t\t\t\u003ctd width=\"25%\"\u003e\n\t\t\t\tCard View\n\t\t\t\t\u003cimg src=\"https://github.com/ssddanbrown/rss/raw/main/.github/screenshots/card-view.png\"\u003e\n\t\t\t\u003c/td\u003e\n\t\t\t\u003ctd width=\"25%\"\u003e\n\t\t\t\tList View\n\t\t\t\t\u003cimg src=\"https://github.com/ssddanbrown/rss/raw/main/.github/screenshots/list-view.png\"\u003e\n\t\t\t\u003c/td\u003e\n\t\t\t\u003ctd width=\"25%\"\u003e\n\t\t\t\tCompact View\n\t\t\t\t\u003cimg src=\"https://github.com/ssddanbrown/rss/raw/main/.github/screenshots/compact-view.png\"\u003e\n\t\t\t\u003c/td\u003e\n\t\t\t\u003ctd width=\"25%\"\u003e\n\t\t\t\tDark Mode\n\t\t\t\t\u003cimg src=\"https://github.com/ssddanbrown/rss/raw/main/.github/screenshots/dark-mode.png\"\u003e\n\t\t\t\u003c/td\u003e\n\t\t\u003c/tr\u003e\n\t\u003c/tbody\u003e\n\u003c/table\u003e\n\n\n## Docker Usage\n\nA pre-built docker image is available to run the application. \nStorage data is confined to a single `/app/storage` directory for easy volume mounting.\nPort 80 is exposed by default for application access. This application does not support HTTPS, for that you should instead use a proxy layer such as nginx.\n\n#### Docker Run Command Example\n\nIn the below command, the application will be accessible at http://localhost:8080 on the host and the files would be stored in a `/home/barry/rss` directory. In this example, feeds would be configured in a `/home/barry/rss/feeds.txt` file.\n\n```shell\ndocker run -d \\\n    --restart unless-stopped \\\n    -p 8080:80 \\\n    -v /home/barry/rss:/app/storage \\\n    ghcr.io/ssddanbrown/rss:latest  \n```\n\n#### Docker Compose Example\n\nIn the below `docker-compose.yml` example, the application will be accessible at http://localhost:8080 on the host and the files would be stored in a `./rss-files` directory relative to the docker-compose.yml file. In this example, feeds would be configured in a `./rss-files/feeds.txt` file.\n\n```yml\n---\nversion: \"2\"\nservices:\n    rss:\n        image: ghcr.io/ssddanbrown/rss:latest\n        container_name: rss\n        environment:\n            - APP_NAME=RSS\n        volumes:\n            - ./rss-files:/app/storage\n        ports:\n            - \"8080:80\"\n        restart: unless-stopped\n```\n\n\n### Building the Docker Image\n\nIf you'd like to build the image from scratch, instead of using the pre-built image, you can do so like this:\n\n```shell\ndocker build -f docker/Dockerfile .\n```\n\n## Feed Configuration\n\nFeed configuration is handled by a plaintext file on the host system.\nBy default, using our docker image, this configuration would be located in a `feeds.txt` file within the path you mounted to `/app/storage`.\n\nThe format of this file can be seen below:\n\n```txt\nhttps://feed.url.com/feed.xml feed-name #tag-a #tag-b\nhttps://example.com/feed.xml Example #updates #news\n\n# Lines starting with a hash are considered comments.\n# Empty lines are fine and will be ignored.\n\n# Underscores in names will be converted to spaces.\nhttps://example.com/feed-b.xml News_Site #news\n\n# Feed color can be set using square brackets after the name.\n# The color must be a CSS-compatible color value.\nhttps://example.com/feed-c.xml Blue_News[#0078b9] #news #blue\n\n# Feeds starting with a '-' are flagged as hidden.\n# Posts for hidden feeds won't be shown on the homepage\n# but can be seen via any type of active filter.\n- https://example.com/feed-d.xml Cat_Facts #cats #facts\n```\n\n## App Configuration\n\nThe application allows some configuration through variables.\nThese can be set via the `.env` file or, when using docker, via environment variables.\n\n```shell\n# The name of the application.\n# Only really shown in the title/browser-tab.\nAPP_NAME=RSS\n\n# The path to the config file.\n# Defaults to `storage/feeds.txt` within the application folder.\nAPP_CONFIG_FILE=/app/storage/feeds.txt\n\n# Enable or disable the loading of post thumbnails.\n# Does not control them within the UI, but controls the fetching\n# when posts are fetched.\n# Defaults to true.\nAPP_LOAD_POST_THUMBNAILS=true\n\n# The number of minutes before a feed is considered outdated and\n# therefore should be updated upon request.\n# This effectively has a minimum of 5 minutes in the docker setup.\nAPP_FEED_UPDATE_FREQUENCY=60\n\n# The number of days to wait before a post should be pruned.\n# Uses the post published_at time to determine lifetime.\n# Setting this to false disables any auto-pruning.\n# If active, pruning will auto-run daily.\n# Defaults to false (No pruning) \nAPP_PRUNE_POSTS_AFTER_DAYS=30\n```\n\n## Usage Behind a Reverse Proxy\n\nWhen using behind a reverse proxy, ensure common forwarding headers are set so that the application can properly detect the right host and path to use.\nThe below shows a sub-path proxy config location block for nginx. Note the `X-Forwarded-Prefix` header to make the application aware of sub-path usage.\n\n```nginx\nlocation /rss/ {\n    proxy_pass http://container-ip:80/;\n    proxy_set_header Host              $host;\n    proxy_set_header X-Real-IP         $remote_addr;\n    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_set_header X-Forwarded-Host  $host;\n    proxy_set_header X-Forwarded-Port  $server_port;\n    proxy_set_header X-Forwarded-Prefix \"/rss/\";\n    proxy_redirect off;\n}\n```\n\n## Manual Install\n\nManually installing the application is not recommended unless you are performing development work on the project.\nInstead, use of the docker image is advised.\n\nThis project is based upon Laravel so the requirements and install process are much the same.\nYou will need git, PHP, composer and NodeJS installed. Installation would generally be as follows:\n\n```shell\n# Clone down and enter the project\ngit clone https://github.com/ssddanbrown/rss.git\ncd rss\n\n# Install PHP dependencies via composer\n# This will check you meet the minimum PHP version and extensions required.\ncomposer install\n\n# Create database file\ntouch storage/database/database.sqlite\n\n# Copy config, generate app key, migrate database \u0026 link storage\ncp .env.example .env\nphp artisan key:generate\nphp artisan migrate\nphp artisan storage:link\n\n# Install JS dependencies \u0026 build CSS/JS\nnpm install\nnpm run build\n```\n\nFor a production server you'd really want to have a webserver active to server the `public` directory and handle PHP.\nYou'd also need a process to run the laravel queue system in addition to a cron job to run the schedule.\n\nOn a development system, These can be done like so:\n\n```shell\n# Serve the app\nphp artisan serve\n\n# Watch the queue\nphp artisan queue:listen\n\n# Work the schedule\nphp artisan schedule:work\n```\n\n## Low Maintenance Project\n\nThis is a low maintenance project. The scope of features and support are purposefully kept narrow for my purposes to ensure longer term maintenance is viable. I'm not looking to grow this into a bigger project at all.\n\nIssues and PRs raised for bugs are perfectly fine assuming they don't significantly increase the scope of the project. Please don't open PRs for new features that expand the scope.\n\n## Development\n\nThis project uses [PHPUnit](https://phpunit.de/) for testing. Tests will use their own in-memory SQLite instance. Tests can be ran like so:\n\n```shell\n./vendor/bin/phpunit\n```\n\n[PHP CS Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) is used for formatting. This can be ran like so:\n\n```bash\n./vendor/bin/php-cs-fixer fix\n```\n\nA command is built-in to test RSS feeds where needed. This will just provide a boolean yes/no fetchable status result, but you can run it with debugging with breakpoints for further diagnosis:\n\n```bash\nphp artisan rss:test-feed https://danb.me/blog/index.xml\n```\n\n## Attribution\n\nThis is primarily built using the following great projects and technologies:\n\n- [Laravel](https://laravel.com/) - [MIT License](https://github.com/laravel/framework/blob/10.x/LICENSE.md)\n- [InertiaJS](https://inertiajs.com/) - [MIT License](https://github.com/inertiajs/inertia/blob/master/LICENSE)\n- [SQLite](https://www.sqlite.org/index.html) - [Public Domain](https://www.sqlite.org/copyright.html)\n- [TailwindCSS](https://tailwindcss.com/) - [MIT License](https://github.com/tailwindlabs/tailwindcss/blob/master/LICENSE)\n- [Vue.js](https://vuejs.org/) - [MIT License](https://github.com/vuejs/vue/blob/main/LICENSE)\n- [PHPUnit](https://phpunit.de/) - [BSD-3-Clause-Like](https://github.com/sebastianbergmann/phpunit/blob/main/LICENSE)\n- [Bootstrap Icons](https://icons.getbootstrap.com/) - [MIT License](https://github.com/twbs/icons/blob/main/LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssddanbrown%2Frss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fssddanbrown%2Frss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssddanbrown%2Frss/lists"}