Skip to content

Commit c59ba32

Browse files
committed
yay
1 parent 4b167c8 commit c59ba32

File tree

10 files changed

+472
-1
lines changed

10 files changed

+472
-1
lines changed

README.md

Lines changed: 175 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,176 @@
11
# rsstools
2-
tools for managing rss feeds in python
2+
3+
A powerful Python tool for creating, editing, and managing RSS feeds with both programmatic and command-line interfaces.
4+
5+
## Features
6+
7+
- Create new RSS feeds with all required elements
8+
- Add, update, and remove items from feeds
9+
- Load and save RSS feeds to XML files
10+
- Validate feed structure and required elements
11+
- Command-line interface for easy management
12+
- Support for optional elements like author and publication date
13+
- JSON export capability for feed items
14+
15+
## Installation
16+
17+
### Dependencies
18+
19+
First, ensure you have Python 3.7 or higher installed. This package requires the following dependencies:
20+
21+
```
22+
click>=8.0.0
23+
```
24+
25+
### Installing via pip (recommended)
26+
27+
1. Run this command:
28+
```bash
29+
pip install rsstools
30+
```
31+
32+
### Installing via pyz
33+
34+
1. Download the latest pyz from the releases tab.
35+
2. Run:
36+
37+
```bash
38+
pip install rsstools.pyz
39+
```
40+
41+
### Installing from source
42+
43+
This package requires the following dependencies:
44+
```
45+
click>=8.0.0
46+
```
47+
48+
1. Clone the repository:
49+
```bash
50+
git clone https://github.com/sctech-tr/rsstools.git
51+
cd rsstools
52+
```
53+
54+
2. Install the package:
55+
```bash
56+
pip install .
57+
```
58+
59+
## Usage
60+
61+
### Command Line Interface
62+
63+
1. Create a new RSS feed:
64+
```bash
65+
rsstools create -t "My Blog" -l "https://myblog.com" -d "My personal blog" -o feed.xml
66+
```
67+
68+
2. Add an item to the feed:
69+
```bash
70+
rsstools add feed.xml \
71+
-t "First Post" \
72+
-l "https://myblog.com/first" \
73+
-d "My first post" \
74+
-a "John Doe" \
75+
-p "2024-10-18T12:00:00"
76+
```
77+
78+
3. List all items in a feed:
79+
```bash
80+
rsstools list feed.xml
81+
```
82+
83+
4. Export items to JSON:
84+
```bash
85+
rsstools list feed.xml -o items.json
86+
```
87+
88+
5. Update an item:
89+
```bash
90+
rsstools update feed.xml "https://myblog.com/first" -t "Updated Post Title"
91+
```
92+
93+
6. Remove an item:
94+
```bash
95+
rsstools remove feed.xml "https://myblog.com/first"
96+
```
97+
98+
### Python API
99+
100+
```python
101+
102+
from rsstools import RSSFeedCreator
103+
from datetime import datetime
104+
105+
# Create a new feed
106+
feed = RSSFeedCreator(
107+
title="My Blog",
108+
link="https://myblog.com",
109+
description="My personal blog about technology"
110+
)
111+
112+
# Add an item
113+
feed.add_item(
114+
title="First Post",
115+
link="https://myblog.com/first-post",
116+
description="This is my first blog post",
117+
author="John Doe",
118+
pub_date=datetime.now()
119+
)
120+
121+
# Save the feed
122+
feed.save("blog_feed.xml")
123+
124+
# Load an existing feed
125+
feed.load("blog_feed.xml")
126+
127+
# Update an item
128+
feed.update_item(
129+
guid="https://myblog.com/first-post",
130+
title="Updated First Post"
131+
)
132+
133+
# Remove an item
134+
feed.remove_item(guid="https://myblog.com/first-post")
135+
136+
# Get all items
137+
items = feed.get_items()
138+
```
139+
140+
## Contributing
141+
142+
1. Fork the repository
143+
2. Open a PR
144+
145+
## License
146+
147+
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
148+
149+
## Error Handling
150+
151+
The package uses custom exceptions (`RSSToolsError`) for error handling. Always wrap your code in try-except blocks when using the API:
152+
153+
```python
154+
from rsstools import RSSFeedCreator, RSSToolsError
155+
156+
try:
157+
feed = RSSFeedCreator("My Blog", "https://myblog.com", "My blog description")
158+
feed.save("feed.xml")
159+
except RSSToolsError as e:
160+
print(f"Error: {str(e)}")
161+
```
162+
163+
## Common Issues and Solutions
164+
165+
1. **Invalid Feed Structure**: Ensure your RSS feed follows the standard RSS 2.0 format.
166+
2. **File Permissions**: Make sure you have write permissions in the directory where you're saving the feed.
167+
3. **Date Format**: When using the CLI, provide dates in ISO format (YYYY-MM-DDTHH:MM:SS).
168+
169+
## Getting Help
170+
171+
Use the `--help` flag with any command to see available options:
172+
```bash
173+
rsstools --help
174+
rsstools create --help
175+
rsstools add --help
176+
```

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build-system]
2+
requires = ["setuptools", "wheel"]
3+
build-backend = "setuptools.build_meta

rsstools/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .feed_creator import RSSFeedCreator
2+
from .exceptions import RSSToolsError
3+
4+
__version__ = "0.1.0"
5+
__all__ = ["RSSFeedCreator", "RSSToolsError"]

rsstools/__main__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from rsstools.cli import main
2+
3+
if __name__ == '__main__':
4+
main()

rsstools/cli.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import click
2+
import json
3+
from datetime import datetime
4+
from .feed_creator import RSSFeedCreator
5+
from .exceptions import RSSToolsError
6+
7+
@click.group()
8+
def cli():
9+
"""RSS Feed Creator and Editor - Create and manage RSS feeds easily."""
10+
pass
11+
12+
@cli.command()
13+
@click.option('--title', '-t', required=True, help='Feed title')
14+
@click.option('--link', '-l', required=True, help='Feed link')
15+
@click.option('--description', '-d', required=True, help='Feed description')
16+
@click.option('--output', '-o', required=True, help='Output file path')
17+
def create(title, link, description, output):
18+
"""Create a new RSS feed."""
19+
try:
20+
feed = RSSFeedCreator(title, link, description)
21+
feed.save(output)
22+
click.echo(f"Successfully created RSS feed: {output}")
23+
except RSSToolsError as e:
24+
click.echo(f"Error: {str(e)}", err=True)
25+
26+
@cli.command()
27+
@click.argument('feed_file')
28+
@click.option('--title', '-t', required=True, help='Item title')
29+
@click.option('--link', '-l', required=True, help='Item link')
30+
@click.option('--description', '-d', required=True, help='Item description')
31+
@click.option('--author', '-a', help='Item author')
32+
@click.option('--pub-date', '-p', help='Publication date (ISO format)')
33+
def add(feed_file, title, link, description, author, pub_date):
34+
"""Add a new item to an RSS feed."""
35+
try:
36+
feed = RSSFeedCreator("", "", "")
37+
feed.load(feed_file)
38+
39+
pub_date_obj = None
40+
if pub_date:
41+
pub_date_obj = datetime.fromisoformat(pub_date)
42+
43+
feed.add_item(
44+
title=title,
45+
link=link,
46+
description=description,
47+
author=author,
48+
pub_date=pub_date_obj
49+
)
50+
51+
feed.save(feed_file)
52+
click.echo(f"Successfully added item to feed: {title}")
53+
except RSSToolsError as e:
54+
click.echo(f"Error: {str(e)}", err=True)
55+
56+
@cli.command()
57+
@click.argument('feed_file')
58+
@click.argument('guid')
59+
def remove(feed_file, guid):
60+
"""Remove an item from an RSS feed by its GUID."""
61+
try:
62+
feed = RSSFeedCreator("", "", "")
63+
feed.load(feed_file)
64+
65+
if feed.remove_item(guid):
66+
feed.save(feed_file)
67+
click.echo(f"Successfully removed item with GUID: {guid}")
68+
else:
69+
click.echo(f"Item with GUID {guid} not found")
70+
except RSSToolsError as e:
71+
click.echo(f"Error: {str(e)}", err=True)
72+
73+
@cli.command()
74+
@click.argument('feed_file')
75+
@click.argument('guid')
76+
@click.option('--title', '-t', help='New title')
77+
@click.option('--link', '-l', help='New link')
78+
@click.option('--description', '-d', help='New description')
79+
@click.option('--author', '-a', help='New author')
80+
def update(feed_file, guid, title, link, description, author):
81+
"""Update an item in the RSS feed."""
82+
try:
83+
feed = RSSFeedCreator("", "", "")
84+
feed.load(feed_file)
85+
86+
updates = {}
87+
if title:
88+
updates['title'] = title
89+
if link:
90+
updates['link'] = link
91+
if description:
92+
updates['description'] = description
93+
if author:
94+
updates['author'] = author
95+
96+
if feed.update_item(guid, **updates):
97+
feed.save(feed_file)
98+
click.echo(f"Successfully updated item with GUID: {guid}")
99+
else:
100+
click.echo(f"Item with GUID {guid} not found")
101+
except RSSToolsError as e:
102+
click.echo(f"Error: {str(e)}", err=True)
103+
104+
@cli.command()
105+
@click.argument('feed_file')
106+
@click.option('--output', '-o', help='Output JSON file (optional)')
107+
def list(feed_file, output):
108+
"""List all items in an RSS feed."""
109+
try:
110+
feed = RSSFeedCreator("", "", "")
111+
feed.load(feed_file)
112+
items = feed.get_items()
113+
114+
if output:
115+
with open(output, 'w') as f:
116+
json.dump(items, f, indent=2)
117+
click.echo(f"Items exported to: {output}")
118+
else:
119+
for item in items:
120+
click.echo("\n--- Item ---")
121+
for key, value in item.items():
122+
click.echo(f"{key}: {value}")
123+
except RSSToolsError as e:
124+
click.echo(f"Error: {str(e)}", err=True)
125+
126+
def main():
127+
cli()

rsstools/exceptions.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class RSSToolsError(Exception):
2+
"""Base exception for RSSTools."""
3+
pass

0 commit comments

Comments
 (0)