{"id":29382018,"url":"https://github.com/ugns/rss2socials","last_synced_at":"2026-02-23T23:22:52.407Z","repository":{"id":301477128,"uuid":"1008723670","full_name":"ugns/rss2socials","owner":"ugns","description":"Modular Python CLI tool to automatically post new entries from an RSS or Atom feed to one or more social media platforms. Easily extensible, robust, and safe for automation and CI/CD workflows.","archived":false,"fork":false,"pushed_at":"2025-07-08T21:21:53.000Z","size":46,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-08T22:26:42.049Z","etag":null,"topics":["atom-feed","bluesky","generative-ai","python3","rss-parser","social-media"],"latest_commit_sha":null,"homepage":"","language":"Python","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/ugns.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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,"zenodo":null}},"created_at":"2025-06-26T02:10:02.000Z","updated_at":"2025-07-08T21:21:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"2b4b3ba4-f3ff-4bb5-ae9d-2ba706a8dff0","html_url":"https://github.com/ugns/rss2socials","commit_stats":null,"previous_names":["ugns/rss2socials"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/ugns/rss2socials","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ugns%2Frss2socials","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ugns%2Frss2socials/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ugns%2Frss2socials/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ugns%2Frss2socials/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ugns","download_url":"https://codeload.github.com/ugns/rss2socials/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ugns%2Frss2socials/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264526961,"owners_count":23623194,"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":["atom-feed","bluesky","generative-ai","python3","rss-parser","social-media"],"created_at":"2025-07-10T04:01:04.847Z","updated_at":"2026-02-23T23:22:47.387Z","avatar_url":"https://github.com/ugns.png","language":"Python","readme":"# rss2socials\n\n[![PyPI version](https://img.shields.io/pypi/v/rss2socials.svg)](https://pypi.org/project/rss2socials/)\n[![Python versions](https://img.shields.io/pypi/pyversions/rss2socials.svg)](https://pypi.org/project/rss2socials/)\n[![Build Status](https://github.com/ugns/rss2socials/actions/workflows/ci.yml/badge.svg)](https://github.com/ugns/rss2socials/actions/workflows/ci.yml)\n[![Coverage Status](https://img.shields.io/codecov/c/github/ugns/rss2socials)](https://codecov.io/gh/ugns/rss2socials)\n[![License: MIT](https://img.shields.io/github/license/ugns/rss2socials)](https://github.com/ugns/rss2socials/blob/main/LICENSE)\n[![Downloads](https://img.shields.io/pypi/dm/rss2socials.svg)](https://pypistats.org/packages/rss2socials)\n\n**rss2socials** is a modular Python CLI tool that automatically posts new entries from an RSS or Atom feed to one or more social media platforms. It is designed to be easily extensible, robust, and safe for automation and CI/CD workflows.\n\n## Features\n\n- **Dynamic connector system:** Add new social media platforms by simply dropping a connector module in `src/rss2socials/connector/`.\n- **Automatic deduplication:** Tracks posted links to avoid reposting.\n- **OpenAI-powered summaries:** Generates concise, platform-appropriate summaries for each post.\n- **Flexible CLI:** Configure via command-line arguments or environment variables.\n- **Comprehensive logging:** Supports configurable log levels for debugging and automation.\n- **Tested and maintainable:** 100% test coverage for core modules, with robust error handling.\n\n## Installation\n\n### From PyPI\n\n```sh\npip install rss2socials\n```\n\n### From Source (Recommended for Development)\n\nClone the repository and install all dependencies (main + dev) using pip-tools and a pinned requirements file for reproducibility:\n\n```sh\ngit clone https://github.com/ugns/rss2socials.git\ncd rss2socials\npip install pip-tools\npip-compile --extra dev --strip-extras --output-file=requirements.txt pyproject.toml\npip install -r requirements.txt\n```\n\n- This will install the package in editable mode along with all development tools (pytest, flake8, etc.).\n- You can also use `make dev` to automate these steps.\n\n## Requirements\n\n- **Python 3.9 or newer is required.**\n\n## Usage\n\n### Using the CLI Entrypoint\n\nAfter installation, you can use the CLI entrypoint (if installed from PyPI or with pip):\n\n```sh\nrss2socials --feed-url https://example.com/feed.xml --platform bluesky\n```\n\nOr, if you prefer to use the Python module directly:\n\n```sh\npython -m rss2socials --feed-url https://example.com/feed.xml --platform bluesky\n```\n\nBoth commands are equivalent and will invoke the CLI interface.\n\n### As a Library\n\nYou can also use `rss2socials` as a Python library in your own scripts:\n\n```python\nfrom rss2socials.cli import main\n\n# Call main() with sys.argv-style arguments\nmain([\n    \"--feed-url\", \"https://example.com/feed.xml\",\n    \"--platform\", \"bluesky\"\n])\n```\n\n### CLI Options\n- `--feed-url` (or `FEED_URL` env): RSS/Atom feed URL (required)\n- `--platform`: One or more platforms to post to (default: bluesky; auto-discovers available platforms)\n- `--seen-file`: File to track posted links (default: `seen_rss_posts.txt`)\n- `--post-age-limit-days`: Only post entries newer than this many days (default: 7)\n- `--log-level`: Logging level (default: INFO)\n\n## Dynamic Connector System\n\nTo add support for a new social media platform:\n1. Create a new Python file in `src/rss2socials/connector/` (e.g., `myplatform.py`).\n2. Implement a `post(summary, link, fetch_page_metadata)` function and set a `PLATFORM` string (e.g., `PLATFORM = \"myplatform\"`).\n3. Optionally, set `MAX_GRAPHEMES` for platform-specific length limits.\n\nThe CLI will automatically discover and make your platform available as a `--platform` option. No changes to the core code are required.\n\n**Example connector skeleton:**\n```python\nPLATFORM = \"myplatform\"\nMAX_GRAPHEMES = 300\n\ndef post(summary, link, fetch_page_metadata):\n    # Implement posting logic here\n    return True  # Return True if successful\n```\n\n## Environment Variables\n- `OPENAI_API_KEY`: Required for summary generation\n- `FEED_URL`, `SEEN_FILE`, `POST_AGE_LIMIT_DAYS`, `LOG_LEVEL`, `PLATFORM`: Optional, override CLI args\n- **Connector-specific variables:**\n  - For Bluesky:\n    - `BLUESKY_HANDLE`: Your Bluesky username (required)\n    - `BLUESKY_APP_PASSWORD`: Your Bluesky app password (required)\n  - Other connectors may require their own environment variables; see the connector's documentation or source code for details.\n\n## Development \u0026 Testing\n\n- Install all dependencies: `make dev`\n- Run tests: `make test` (uses tox for all supported Python versions)\n- Lint: `make lint`\n- Coverage: `make coverage`\n- Add new connectors in `src/rss2socials/connector/`\n- Regenerate constraints after dependency changes: `make freeze`\n\n## License\nMIT\n\n## Contributing\nContributions are welcome! Please use [Conventional Commits](https://www.conventionalcommits.org/) and ensure all tests pass before submitting a PR.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fugns%2Frss2socials","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fugns%2Frss2socials","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fugns%2Frss2socials/lists"}