💾 Archived View for republic.circumlunar.space › users › johngodlee › posts › 2018-04-07-pypodd-opml… captured on 2024-02-05 at 10:39:57. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-04)

-=-=-=-=-=-=-

Updating pypodd to run .opml files

DATE: 2018-04-07

AUTHOR: John L. Godlee

Pypodd

OPML (Outline Processor Markup Language) is a type of .xml which is often used to hold information for RSS feeds. Lots of podcast aggregators use the OPML format to allow exporting of your list of podcasts, including the one that I use on my phone, PocketCasts[1]. So I wanted to extend the functionality of my pypodd program so that it would be able to use an OPML list of subscriptions instead of the .csv that I put together in a quite ad hoc manner when I was writing the program.

1: https://play.pocketcasts.com

Here is a sample of what an OPML file looks like:

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<opml version="1.0">
  <head>
    <title>Pocket Casts Feeds</title>
  </head>
  <body>
    <outline text="feeds">
      <outline type="rss" text="Hospital Records Podcast" xmlUrl="http://podcast.hospitalrecords.com/HospitalRecordsPodcast.xml" />
      <outline type="rss" text="Slow Radio" xmlUrl="https://podcasts.files.bbci.co.uk/p05k5bq0.rss" />
      <outline type="rss" text="The Heart" xmlUrl="http://feeds.theheartradio.org/TheHeartRadio" />
      <outline type="rss" text="Gardeners' Question Time" xmlUrl="https://podcasts.files.bbci.co.uk/b006qp2f.rss" />
    </outline>
  </body>
</opml>

I found that actually, thanks to a package that has already been written called listparser[2], adding this feature was REALLY REALLY EASY!

2: https://pythonhosted.org/listparser/

I wrapped the existing .csv import method in an if else statement, saying that if the file extension was csv proceed with the .csv import method, but if the file extension was .xml, use the other import method. The code looks like this:

if subsLoc.endswith("csv"): 
  with open(subsLoc) as f:
    subs = csv.reader(f)
    subs = list(subs)
  # Split subs into URLs and titles
  urlList = [x[0] for x in subs]    
  subList = [x[1] for x in subs]
elif subsLoc.endswith("xml"):
  with open(subsLoc) as f:
    subs = listparser.parse(f)
  urlList = [x.url for x in subs.feeds]
  subList = [x.title for x in subs.feeds] 
else: 
  raw_input("Subscriptions list is not `.csv` or OPML `.xml`, exiting ...")
  sys.exit(0)

Also note the "quit" if the designated file doesn't include either of the two specified extensions. Maybe to be super bulletproof I should do a check to see if the .xml file includes <opml version="">, as I suppose there are lots of different .xml formats.