get_podcasts.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #!/usr/bin/env python3
  2. #############################
  3. ###### USER VARIABLES #######
  4. #############################
  5. # set download root dir
  6. download_root_dir = '/home/bryan/Downloads/Podcasts'
  7. # set handheld directory
  8. handheld_root_dir = '/run/media/bryan/D5E7-1B94/Podcasts'
  9. # feeds (python list)
  10. feedurls = ['http://linuxactionnews.com/rss', \
  11. 'http://wakingup.libsyn.com/rss', \
  12. 'http://feeds.soundcloud.com/users/soundcloud:users:146429914/sounds.rss', \
  13. 'http://billburr.libsyn.com/rss', \
  14. 'http://feeds.99percentinvisible.org/99percentinvisible', \
  15. 'http://rss.art19.com/tim-ferriss-show', \
  16. 'http://feed.thisamericanlife.org/talpodcast']
  17. # number of old episodes to keep
  18. old_episodes_keep = 3
  19. # include episode name in filename (1 = on, 0 = off)
  20. episode_name_in_filename = 0
  21. # enable debug output (1 = on, 0 = off)
  22. debug = 0
  23. #################################
  24. ###### END USER VARIABLES #######
  25. #################################
  26. import podcastparser
  27. import urllib.request
  28. import os
  29. import time
  30. import datetime
  31. import glob
  32. import shutil
  33. # spoof headers for certain rss feeds
  34. opener=urllib.request.build_opener()
  35. opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
  36. urllib.request.install_opener(opener)
  37. #################################
  38. ######### GET EPISODES ##########
  39. #################################
  40. # parse feeds
  41. for feed in feedurls:
  42. # parsed is a dict
  43. parsed = podcastparser.parse(feed, urllib.request.urlopen(feed), old_episodes_keep)
  44. # debug
  45. if debug == 1:
  46. import pprint
  47. pprint.pprint(parsed)
  48. # get podcast title
  49. podcast_title = parsed['title']
  50. print('Checking ' + podcast_title + ' for new episdoes...')
  51. # check if download dir exists and if not, make it
  52. podcast_download_dir = os.path.join(download_root_dir, podcast_title)
  53. if not os.path.exists(podcast_download_dir):
  54. os.mkdir(podcast_download_dir)
  55. # parse episodes
  56. for episode in parsed['episodes']:
  57. # format release time to date format
  58. release_time = int(episode['published'])
  59. episode_date = datetime.datetime.fromtimestamp(release_time)
  60. episode_date = episode_date.strftime("%y-%m-%d")
  61. # debug
  62. if debug == 1:
  63. print(release_time)
  64. print(episode_date)
  65. # create filename based on episode date and/or episode title
  66. if episode_name_in_filename == 0:
  67. episode_title = episode_date
  68. else:
  69. episode_title = episode_date + " " + episode['title']
  70. full_episode_path = os.path.splitext(os.path.join(podcast_download_dir, episode_title))[0]
  71. for enclosures in episode['enclosures']:
  72. # get download url
  73. url = enclosures['url']
  74. if debug == 1:
  75. print(url)
  76. if enclosures['mime_type'] == 'audio/mpeg':
  77. full_episode_path += '.mp3'
  78. # download file and save to episode title
  79. if not os.path.exists(full_episode_path):
  80. try:
  81. print('Downloading ' + episode['title'])
  82. urllib.request.urlretrieve(url, full_episode_path)
  83. except urllib.error.HTTPError as e:
  84. print('HTTPError' + ': Could not download ' + podcast_title + '\n' + 'Reason: ' + e.reason + '\n' + 'URL: ' + url)
  85. except urllib.error.URLError:
  86. print('URLError')
  87. except urllib.error.ContentTooShortError:
  88. print('Download failed, file corrupt!')
  89. # remove old episodes
  90. old_files = glob.glob(os.path.join(podcast_download_dir, '*'))
  91. old_files.sort()
  92. for file in old_files[:-old_episodes_keep]:
  93. os.unlink(file)
  94. #################################
  95. ######## MANAGE HANDHELD ########
  96. #################################
  97. if os.path.exists(handheld_root_dir):
  98. # define copy to handheld function
  99. def copy_files(src_file, dest_dir):
  100. if not os.path.isdir(dest_dir):
  101. os.makedir(dest_dir)
  102. filename = os.path.basename(src_file)
  103. dest_file = os.path.join(dest_dir, filename)
  104. if not os.path.exists(dest_file):
  105. print('Copying ' + src_file + ' to ' + dest_file)
  106. shutil.copyfile(src_file, dest_file)
  107. # copy to handheld
  108. podcast_dirs = glob.glob(os.path.join(download_root_dir, '*'))
  109. for podcast_dir in podcast_dirs:
  110. podcast_name = os.path.basename(podcast_dir)
  111. handheld_target_dir = os.path.join(handheld_root_dir, podcast_name)
  112. files_to_copy = glob.glob(os.path.join(podcast_dir, '*'))
  113. for file in files_to_copy:
  114. if debug == 1:
  115. print(file + ' ' + handheld_target_dir)
  116. copy_files(file, handheld_target_dir)
  117. # remove old files from handheld
  118. podcast_dirs = glob.glob(os.path.join(handheld_root_dir, '*'))
  119. for podcast_dir in podcast_dirs:
  120. old_files = glob.glob(os.path.join(podcast_dir, '*'))
  121. old_files.sort()
  122. for file in old_files[:-old_episodes_keep]:
  123. os.unlink(file)
  124. else:
  125. print('Handheld not detected, skipping...')