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
|