From 0207057e7e56485cb8ebd969f754f259720d21ce Mon Sep 17 00:00:00 2001 From: ComradeCrow Date: Tue, 12 Mar 2024 16:00:32 -0700 Subject: minor update update gitignore, change filename, and impliment click --- .gitignore | 6 +- PodWeb.py | 184 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ podweb.py | 102 ---------------------------------- 3 files changed, 189 insertions(+), 103 deletions(-) create mode 100755 PodWeb.py delete mode 100755 podweb.py diff --git a/.gitignore b/.gitignore index b92086e..864c291 100644 --- a/.gitignore +++ b/.gitignore @@ -128,6 +128,9 @@ venv.bak/ # Rope project settings .ropeproject +# Visual Studio project settings +.vscode + # mkdocs documentation /site @@ -153,4 +156,5 @@ cython_debug/ #.idea/ debug_* -*.opml \ No newline at end of file +*.opml +*.xml \ No newline at end of file diff --git a/PodWeb.py b/PodWeb.py new file mode 100755 index 0000000..a48bcf5 --- /dev/null +++ b/PodWeb.py @@ -0,0 +1,184 @@ +#!/usr/bin/env python3 +import os +import click +import yaml +import xml.etree.ElementTree as xmlet + +import podcastparser +import urllib +import urllib.request +import pprint + +global options +options = {"DEBUG": False, + "serverlist": os.path.normpath(os.path.join(os.path.expanduser("~/.config/podweb"), "serverlist")), + "podcastpath": ""} + +class PodWeb(): + + def __init__(self, + debug : bool = False, + config : None | str = None, + server_list : None | str = None, + download_location : None | str = None) -> None: + self.options = options + self.options.update({"DEBUG": debug}) + self.servers = [] + self.DEFAULT_SERVERLIST_HEADING = '''## You can add podcast xml feeds here. +## You can also optionally add categories, website url, image urls, and names for the podcasts. +## The order of category, name, and url does not matter. +## Here are some example entries: +## - category: example category +## name: example podcast 1 +## url: https://example.com/feed.xml +## img: https://example.com/image.jpg +## site: https://example.com +## - name: example podcast 2 +## url: example.com/feed2.xml +''' + + if self.options["DEBUG"]: + self.config_path = os.path.abspath(os.path.curdir) + self.config_filepath = "debug_config.yaml" + self.options["serverlist"] = os.path.join(self.config_path, "debug_serverlist") + else: + self.config_path = os.path.normpath(os.path.expanduser("~/.config/podweb")) + self.config_filepath = os.path.join(self.config_path, "config.yaml") + if config: + self.config_filepath = os.path.normpath(os.path.expanduser(config)) + if server_list: + self.options["serverlist"] = os.path.normpath(os.path.expanduser(server_list)) + if download_location: + self.options["podcastpath"] = os.path.normpath(os.path.expanduser(download_location)) + self._load_config() + self._load_serverlist() + + def _load_config(self) -> None: + + if not os.path.exists(self.config_path): os.makedirs(self.config_path) + + if not os.path.isfile(self.config_filepath): + with open(self.config_filepath, "w+") as f: + yaml.dump(self.options, f) + + else: + with open(self.config_filepath, "r+") as f: + self.options.update(yaml.full_load(f)) + + def _update_config(self, changed_option : dict) -> None: + '''Makes a change to the config file''' + with open(self.options["serverlist"], "w+") as f: + config_options = yaml.full_load(f) + config_options.update(changed_option) + f.write(config_options) + + def _load_serverlist(self) -> list: + '''Loads the contents of the serverlist''' + self._create_serverlist() + with open(self.options["serverlist"], "r+") as f: + content = yaml.full_load(f) + if content: + self.servers = content + + def _create_serverlist(self) -> None: + '''Checks if the serverlist does not exist and creates it if not''' + if not os.path.isfile(self.options["serverlist"]): + with open(self.options["serverlist"], "w+") as f: + f.write(self.DEFAULT_SERVERLIST_HEADING) + + def _update_serverlist(self) -> None: + '''This is destructive and overwrites the current serverlist with the stored serverlist''' + with open(self.options["serverlist"], "w+") as f: + f.write(self.DEFAULT_SERVERLIST_HEADING) + if len(self.servers): + with open(self.options["serverlist"], "a") as f: + yaml.dump(self.servers, f) + + def add_podcast(self, feedurl : str, name = None, category = None, site = None, img = None) -> None: + feedparse = urllib.parse.urlparse(feedurl) + for i in self.servers: + iparse = urllib.parse.urlparse(i["url"]) + if iparse.hostname == feedparse.hostname and iparse.path == feedparse.path: + return None + new_feed = {"url": feedurl} + if not name or not img or not site: + parsed = podcastparser.parse(feedurl, urllib.request.urlopen(feedurl)) + if not name: name = parsed.get("title") + if not img: img = parsed.get("cover_url") + if not site: site = parsed.get("link") + if name: new_feed.update({"name": name}) + if site: new_feed.update({"site": site}) + if img: new_feed.update({"img": img}) + if category: new_feed.update({"category": category}) + self.servers.append(new_feed) + self._update_serverlist() + + def import_opml(self, opml_path : str) -> None: + body = xmlet.parse(source=opml_path).getroot().find("body") + for child in body: + i = child.attrib + if i["type"] == "rss": + self.add_podcast(feedurl = i["xmlUrl"], + name = i.get("text"), + site = i.get("htmlUrl"), + img = i.get("imageUrl")) + + def _parse_rss(self, url : str) -> dict: + parsed = podcastparser.parse(url, urllib.request.urlopen(url)) + return parsed + + def _parse_local_rss(self, file : str) -> dict: + with open(file, "rb") as f: + parsed = podcastparser.parse(file, f) + return parsed + +@click.group() +@click.pass_context +@click.option('-d', '--debug', is_flag=True) +@click.option('--config', default=None) +@click.option('--server-list', default=None) +@click.option('--download-location', default=None) +def cli(ctx, + debug : bool, + config : None | str, + server_list : None | str, + download_location : None | str): + """a simple podfetcher for the CLI.""" + ctx.obj = PodWeb(debug = debug, + config = config, + server_list = server_list, + download_location = download_location) + ctx.show_default = True + +@cli.command() +@click.argument("setting", + type=click.Choice(['configlocation', 'serverlistlocation', 'downloadlocation', 'servers'], + case_sensitive=False)) +@click.pass_obj +def get_setting(obj, setting): + if setting == "configlocation": + click.echo(obj.config_filepath) + if setting == 'serverlistlocation': + click.echo(obj.options["serverlist"]) + if setting == "downloadlocation": + click.echo(obj.options["podcastpath"]) + if setting == "servers": + for i in obj.servers: + name = "" + if i.get("name"): name = F"{i["name"]} - " + click.echo(F"{name}{i["url"]}") + +@cli.command() +@click.argument("url") +@click.pass_obj +def parse(obj, url): + click.echo(pprint.pformat(obj._parse_rss(url))) + +@cli.command() +@click.argument("filepath", type=click.Path(exists=True)) +@click.pass_obj +def parse_file(obj, filepath): + click.echo(pprint.pformat(obj._parse_local_rss(filepath))) + +if __name__ == "__main__": + cli() \ No newline at end of file diff --git a/podweb.py b/podweb.py deleted file mode 100755 index 4ac83ea..0000000 --- a/podweb.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python3 -import os -import copy -import click -import yaml -import xml - -import podcastparser -import urllib - -global options -options = {"DEBUG": False, "serverlist": os.path.normpath(os.path.join(os.path.expanduser("~/.config/podweb"), "serverlist")), "podcastpath": ""} - -class PodWeb(): - - def __init__(self, DEBUG : bool = False) -> None: - self.options = options - self.options.update({"DEBUG": DEBUG}) - self.servers = [] - self.DEFAULT_SERVERLIST_HEADING = '''## You can add podcast xml feeds here. -## You can also optionally add categories and names for the podcasts. -## The order of category, name, and url does not matter. -## Here are some example entries: -## - category: example category -## name: example podcast 1 -## url: https://example.com/feed.xml -## - name: example podcast 2 -## url: example.com/feed2.xml -''' - - if self.options["DEBUG"]: - self.config_path = "." - self.config_filepath = "debug_config.yaml" - self.options["serverlist"] = "debug_serverlist" - else: - self.config_path = os.path.normpath(os.path.expanduser("~/.config/podweb")) - self.config_filepath = os.path.join(self.config_path, "config.yaml") - - self._load_config() - self._load_serverlist() - - def _load_config(self) -> None: - - if not os.path.exists(self.config_path): os.makedirs(self.config_path) - - if not os.path.isfile(self.config_filepath): - with open(self.config_filepath, "w+") as f: - yaml.dump(self.options, f) - - else: - with open(self.config_filepath, "r+") as f: - self.options.update(yaml.full_load(f)) - - def _update_config(self, changed_option : dict) -> None: - '''Makes a change to the config file''' - with open(self.options["serverlist"], "w+") as f: - config_options = yaml.full_load(f) - config_options.update(changed_option) - f.write(config_options) - - def _load_serverlist(self) -> list: - '''Loads the contents of the serverlist''' - self._create_serverlist() - with open(self.options["serverlist"], "r+") as f: - content = yaml.full_load(f) - if content: - self.servers = content - - def _create_serverlist(self) -> None: - '''Checks if the serverlist does not exist and creates it if not''' - if not os.path.isfile(self.options["serverlist"]): - with open(self.options["serverlist"], "w+") as f: - f.write(self.DEFAULT_SERVERLIST_HEADING) - - def _update_serverlist(self) -> None: - '''This is destructive and overwrites the current serverlist with the stored serverlist''' - with open(self.options["serverlist"], "w+") as f: - f.write(self.DEFAULT_SERVERLIST_HEADING) - if len(self.servers): - with open(self.options["serverlist"], "a") as f: - yaml.dump(self.servers, f) - - def add_podcast(self, feedurl : str, name = None, category = None) -> None: - for i in self.servers: - iparse = urllib.parse.urlparse(i["url"]) - feedparse = urllib.parse.urlparse(feedurl) - if iparse.hostname == feedparse.hostname and iparse.path == feedparse.path: - return None - parsed = podcastparser.parse(feedurl, urllib.request.urlopen(feedurl)) - if name: - new_feed = {"url": feedurl, "name": name} - else: - new_feed = {"url": feedurl, "name": parsed["title"]} - if category: new_feed.update({"category": category}) - self.servers.append(new_feed) - self._update_serverlist() - - def import_opml(self, opml_path : str): - pass - - -testweb = PodWeb(DEBUG = True) \ No newline at end of file -- cgit 1.4.1-2-gfad0