170 lines
5.2 KiB
Python
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.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()
|