From 7f4b9e4c65d3c22d6465d61651efc8201a944fb5 Mon Sep 17 00:00:00 2001 From: Jan Andrle Date: Mon, 20 Jul 2026 10:38:56 +0200 Subject: [PATCH] :tada: --- .gitea/workflows/update_feed.yml | 42 +++++++++++++++++ README.md | 57 ++++++++++++++++++++++- main.py | 79 ++++++++++++++++++++++++++++++++ requirements.txt | 2 + 4 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 .gitea/workflows/update_feed.yml create mode 100644 main.py create mode 100644 requirements.txt diff --git a/.gitea/workflows/update_feed.yml b/.gitea/workflows/update_feed.yml new file mode 100644 index 0000000..8d03428 --- /dev/null +++ b/.gitea/workflows/update_feed.yml @@ -0,0 +1,42 @@ +name: Update RSS Feed + +on: + schedule: + - cron: '0 6 * * *' # every day at 6:00 GMT (7CET/8CEST) + workflow_dispatch: + +jobs: + update-feed: + runs-on: ubuntu-latest + permissions: + contents: write + env: + RUNNER_TOOL_CACHE: ${{ github.workspace }}/_work/_tool + AGENT_TOOLSDIRECTORY: ${{ github.workspace }}/_work/_tool + + steps: + - name: Checkout repository + uses: https://gitea.com/actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Set up Python + uses: https://gitea.com/actions/setup-python@7f4fc3e22c37d6ff65e88745f38bd3157c663f7c # v4.9.1 + with: + python-version: '3.9.11' + + - name: Install dependencies + run: | + pip install -r requirements.txt + + - name: Run Scrape Obec Žižkovo Pole + env: + FB_PAGE: "obec.zizkovopole" + run: | + python main.py "$FB_PAGE" --pages 2 --output "$FB_PAGE.xml" + + - name: Commit and Push changes + run: | + git config --global user.name 'gitea-actions[bot]' + git config --global user.email 'gitea-actions[bot]@users.noreply.gitea.com' + git add *.xml + git commit -m "Update RSS feed(s)" || exit 0 + git push diff --git a/README.md b/README.md index f7be80b..2328215 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,56 @@ -# fb-rss-bridge +# Facebook to RSS Scraper -https://github.com/ManthsCode/fb-rss-bridge \ No newline at end of file +This tool scrapes public posts from a Facebook page and converts them into an RSS feed (.xml). It can be run locally or automated using GitHub Actions. + +## Prerequisites + +- Python 3.9+ +- pip (Python package installer) + +## Local Installation & Usage + +1. **Clone the repository:** + ```bash + git clone + cd fb-rss-bridge + ``` + +2. **Install dependencies:** + It is recommended to use a virtual environment. + ```bash + python3 -m venv .venv + source .venv/bin/activate + pip install -r requirements.txt + ``` + +3. **Run the scraper:** + ```bash + python3 main.py + ``` + + Replace `` with the Facebook page ID or username. + + **Options:** + - `--output`: Specify output file name (default: `feed.xml`) + - `--pages`: Number of pages to scrape (default: 1) + + **Example:** + ```bash + python3 main.py GitHub --pages 2 --output github_feed.xml + ``` + +## GitHub/Gitea Actions Automated Feed (Free Cloud Solution) + +This repository is configured to run automatically on GitHub's free tier for public repositories. + +1. **How it works:** + - The `.gitea/workflows/update_feed.yml` file defines a "cron job" that runs every 6 hours. + - It spins up a temporary server (runner), installs Python, runs the script, and saves the `feed.xml` back to your code. + - This entire process is free for public repositories on GitHub. + +2. **Configuration:** + The workflow is scheduled to run every 6 hours. You can customize the target Facebook page in `.gitea/workflows/update_feed.yml`: + ```yaml + env: + FB_PAGE: "GitHub" # Change this to the desired page ID/username + ``` diff --git a/main.py b/main.py new file mode 100644 index 0000000..a036c8a --- /dev/null +++ b/main.py @@ -0,0 +1,79 @@ +import argparse +import logging +from facebook_scraper import get_posts +from rfeed import Item, Feed, Guid +import datetime +import os + +# Configure logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') + +def scrape_facebook_page(page_name, pages_count=1): + """ + Scrapes the posts from a Facebook page. + """ + logging.info(f"Starting scrape for page: {page_name}") + posts_data = [] + try: + # get_posts returns a generator + for post in get_posts(page_name, pages=pages_count): + posts_data.append(post) + except Exception as e: + logging.error(f"Error scraping page {page_name}: {e}") + + logging.info(f"Retrieved {len(posts_data)} posts.") + return posts_data + +def generate_rss(posts, page_name, output_file="feed.xml"): + """ + Generates an RSS feed from the scraped posts. + """ + items = [] + for post in posts: + # Extract relevant data + post_id = post.get('post_id') + text = post.get('text') or "No text content" + post_url = post.get('post_url') + time = post.get('time') + image = post.get('image') + + # Create RSS item + item = Item( + title=text[:60] + "..." if len(text) > 60 else text, + link=post_url, + description=f"{text}

" + (f"" if image else ""), + author=page_name, + guid=Guid(post_id), + pubDate=time + ) + items.append(item) + + feed = Feed( + title=f"{page_name} Facebook Feed", + link=f"https://www.facebook.com/{page_name}", + description=f"RSS feed for {page_name} Facebook page", + language="en-US", + lastBuildDate=datetime.datetime.now(), + items=items + ) + + with open(output_file, "w", encoding='utf-8') as f: + f.write(feed.rss()) + logging.info(f"RSS feed written to {output_file}") + +def main(): + parser = argparse.ArgumentParser(description="Facebook to RSS Scraper") + parser.add_argument("page_name", help="Name or ID of the Facebook page") + parser.add_argument("--output", default="feed.xml", help="Output RSS file name") + parser.add_argument("--pages", type=int, default=1, help="Number of pages to scrape") + + args = parser.parse_args() + + posts = scrape_facebook_page(args.page_name, args.pages) + if posts: + generate_rss(posts, args.page_name, args.output) + else: + logging.warning("No posts found or scraping failed.") + +if __name__ == "__main__": + main() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c1a3fda --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +facebook-scraper +rfeed