Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Download all items in a podcast.
#!/usr/bin/env python
from __future__ import print_function
import datetime
import feedparser
import time
import os
import sys
from six.moves import urllib
from contextlib import closing
# From
if sys.version_info < (3, 3):
def touch(fname, mode=0o666, dir_fd=None, **kwargs):
flags = os.O_CREAT | os.O_APPEND
times = kwargs['times'] if 'times' in kwargs else None
with os.fdopen(, flags, mode)) as f:
os.utime(fname, times)
def touch(fname, mode=0o666, dir_fd=None, **kwargs):
flags = os.O_CREAT | os.O_APPEND
with os.fdopen(, flags=flags, mode=mode, dir_fd=dir_fd)) as f:
os.utime(f.fileno() if os.utime in os.supports_fd else fname,
dir_fd=None if os.supports_fd else dir_fd, **kwargs)
# From
def downloadFile(url, file_name):
# Download the file from `url` and save it locally under `file_name`:
with closing(urllib.request.urlopen(url)) as response, open(file_name, 'wb') as out_file:
data = # a `bytes` object
def downloadAll(feedURL):
feed = feedparser.parse(feedURL)
print("Processing feed %s..." % feed['feed']['title'])
for post in reversed(feed.entries):
print("Processing item %s... " % post.title, end="")
if len(post.enclosures) != 1:
print("Post has %d enclosures, not 1. Skipping post."
% len(post.enclosures))
media = post.enclosures[0]
mediaURL = media.href
# cut the extension off the end to use in the filename
mediaExt = mediaURL[mediaURL.rfind('.')+1:]
quesPos = mediaExt.find('?')
if quesPos != -1:
mediaExt = mediaExt[:quesPos]
mediaSize = int(media.length) # media.length is of type str
filename = "%s.%s" % (post.title.replace('/', '_'), mediaExt)
stat = os.stat(filename) if os.path.isfile(filename) else None
if stat and stat.st_size > 0\
and (stat.st_size == mediaSize or mediaSize == 0):
print("File already downloaded. Skipping.")
if stat and stat.st_size != mediaSize:
print("Incorrect file found. Redownloading... ", end="")
print("Downloading... ", end="")
# Download the file...
downloadFile(mediaURL, filename)
# From
pubTimestamp = time.mktime(post.published_parsed)
# ... and set its created time to the publication time.
touch(filename, times=(stat.st_atime if stat else pubTimestamp,
_feedURLfilename = ".podcast_source"
if __name__ == "__main__":
import sys
# Remember the feed URL in a hidden file named _feedURLfilename
# Always use the command-line URL if given and remember it in that file.
if len(sys.argv) == 2:
feedURL = sys.argv[1]
with open(_feedURLfilename, 'w') as feedURLfile:
elif len(sys.argv) == 1 and os.path.isfile(_feedURLfilename):
with open(_feedURLfilename, 'r') as feedURLfile:
feedURL =
print("USAGE: %s feedURL" % sys.argv[0])

This comment has been minimized.

Copy link

joshdick commented Oct 13, 2017

Great tiny tool! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.