rss-generator/generator.py
2026-04-18 21:15:43 -04:00

170 lines
5.2 KiB
Python

import os
import sys
import subprocess
import platform
from uuid import uuid4
from datetime import datetime
from pathlib import Path
import xml.etree.ElementTree as ET
from config import TITLE, URL, DESCRIPTION, GENERATOR, LANGUAGE, XML_BASE_PATH, EXECUTE_FROM_RSS_GENERATOR_DIR
class RSSGenerator:
ATOM_NAMESPACE = "HTTP://WWW.W3.ORG/2005/ATOM"
def __init__(self):
self.now = datetime.now().strftime("%a, %d %b %Y %H:%M:%S %z")
self.output_path = f"../{XML_BASE_PATH}/index.xml" if XML_BASE_PATH else "../index.xml"
if not EXECUTE_FROM_RSS_GENERATOR_DIR:
self.output_path = self.output_path.replace('../', '')
self.post_title = None
self.post_link = None
self.post_desc = None
self.post_date = self.now
self.tree = None
self.root = None
self.channel = None
self.items = []
def main(self):
self.clear()
if os.path.exists(self.output_path):
print('RSS feed exists, parsing...')
self.tree = ET.parse(self.output_path)
self.parse_existing_feed()
self.action_screen()
else:
print('RSS feed does not exist, generating a new one...')
Path("/".join(self.output_path.split('/')[:-1])).mkdir(parents=True, exist_ok=True)
self.generate_new_feed()
self.request_new_post_details()
self.push_new_post()
self.tree = ET.ElementTree(self.root)
self.action_screen()
def action_screen(self):
result = input("\nWhat would you like to do? \n[1] Add a new entry [2] List all posts [3] Delete an entry\n[4] Edit an entry [5] Save [6] Quit Without Saving\nEnter number: ")
self.clear()
if int(result) == 1:
self.request_new_post_details()
self.push_new_post()
self.action_screen()
if int(result) == 2:
self.list_posts()
self.action_screen()
elif int(result) == 3:
self.delete_post()
self.action_screen()
elif int(result) == 4:
self.edit_post()
self.action_screen()
elif int(result) == 5:
self.tree.write(self.output_path, encoding='utf-8', xml_declaration=True)
sys.exit(0)
elif int(result) == 6:
sys.exit(0)
else:
print('Unknown Command!')
self.action_screen()
def parse_existing_feed(self):
self.root = self.tree.getroot()
self.channel = self.root.find('channel')
def generate_new_feed(self):
self.root = ET.Element("rss", {"version": "2.0", "xmlns:atom": self.ATOM_NAMESPACE})
self.channel = ET.SubElement(self.root, "channel")
title = ET.SubElement(self.channel, "title")
title.text = TITLE
link = ET.SubElement(self.channel, "{http://www.w3.org/2005/Atom}link")
link.set("rel", "self")
link.set("href", f"{URL}/{self.output_path}".replace('../', ''))
link.set("type", "application/atom+xml")
desc = ET.SubElement(self.channel, "description")
desc.text = DESCRIPTION
generator = ET.SubElement(self.channel, "generator")
generator.text = GENERATOR
lang = ET.SubElement(self.channel, "language")
lang.text = LANGUAGE
def request_new_post_details(self):
self.post_title = input("\nPost Title: ")
self.post_link = input("Post Link: ")
self.post_desc = input("Post Description: ")
def push_new_post(self):
item = ET.SubElement(self.channel, 'item')
title = ET.SubElement(item, 'title')
title.text = self.post_title
link = ET.SubElement(item, 'link')
link.text = self.post_link
description = ET.SubElement(item, 'description')
description.text = self.post_desc
guid = ET.SubElement(item, 'guid')
guid.text = str(uuid4())
pub_date = ET.SubElement(item, 'pubDate')
pub_date.text = self.now
def list_posts(self):
print("\nHere is a list of all your posts:")
for idx, item in enumerate(self.channel.findall('item')):
title = item.find('title').text
print(f"[{idx}] {title}")
def delete_post(self):
self.list_posts()
result = input("\nWhich post would you like to delete? Enter number: ")
for idx, item in enumerate(self.channel.findall('item')):
if idx == int(result):
self.channel.remove(item)
def edit_post(self):
self.list_posts()
result = input("\nWhich post would you like to edit? Enter number: ")
self.request_new_post_details()
for idx, item in enumerate(self.channel.findall('item')):
if idx == int(result):
item.find('title').text = self.post_title
item.find('description').text = self.post_desc
item.find('link').text = self.post_link
def clear(self):
system = platform.system().lower()
if system == 'windows':
subprocess.run('cls', shell=True)
else:
subprocess.run('clear', shell=True)
if __name__ == '__main__':
rss = RSSGenerator()
rss.main()