📜 ⬆️ ⬇️

Python, podcasts and bikes.

In preparation, the PC for the role of the home server is constantly trying to give up all sorts of gui. Hands reached the podcasts. Hpodder did not cause delight, broke the tags in the files. That was written my bike in python.

It turned out two files.
Settings file.
# -*- coding: utf8 -*-
# .
[settings]
download_dir = /home/bobathecar/scriptForPodcast/episodes/
download_episodes = 1

[podcasts]
budam = budam.rpod.ru/rss.xml
= vasilysweekend.rpod.ru/rss.xml
Umputun = feeds.feedburner.com/Umputun
= it-thoughts.rpod.ru/rss.xml
iAnime = i-anime.rpod.ru/rss.xml
Radio-T = feeds.feedburner.com/Radio-t

The name will be written in the artist tag.
and the script itself

 #!/usr/bin/env python # -*- coding: utf8 -*- #      #     url from xml.dom import minidom from UserDict import UserDict import time, urllib, sys, os, re class Podcast(UserDict): '''Class to repr single podcast item''' extentionsDict = { "audio/mpeg": "mp3", "video/mp4": "mp4", "video/quicktime": "mov", "video/x-ms-wmv": "wmv" } def __init__(self): UserDict.__init__(self) self["linkToFile"] = "none" self["fileType"] = "audio/mpeg" def download(self, *args, **kwargs): ''' download podcast into file ''' # make sure we have what to download if self["linkToFile"] == "none": raise LinkNotFound # default directory set to current directory outputDir = os.path.abspath(os.path.curdir) if len(args) == 1: # Only file name fileName = os.path.splitext("%s" %args[0])[0] elif len(args) == 2: # file name and output dir outputDir = "%s" %args[0] fileName = os.path.splitext("%s" %args[1])[0] elif kwargs.has_key("file"): fileName = os.path.splitext(kwargs["file"])[0] if kwargs.has_key("dir"): outputDir = kwargs["dir"] outputDir = outputDir.rstrip(os.path.sep) # if output directory not exist # try to create output directory if os.path.exists(outputDir) == False: os.mkdir(outputDir) u = urllib.urlopen(self["linkToFile"]) #     strInfo = str(u.info()) try: #      self["fileType"] = re.findall(r"(?<=Content-Type: )\w+\/?\w*", strInfo)[0] except: pass #      self["path_to_file"] = os.path.join(outputDir, fileName + os.path.extsep + self.extentionsDict[self["fileType"]] ) #   Content-Length LentgthHeader = re.findall(r"(?<=Content-Length: )\d+", strInfo) if len(LentgthHeader) == 1: #       #    +-10%      NotDownloadedLength = float(LentgthHeader[0]) if os.path.exists(self["path_to_file"]) and \ NotDownloadedLength*0.9 < \ float(os.path.getsize(self["path_to_file"]))\ < NotDownloadedLength*1.1: print " %s  , " % self["path_to_file"].encode("utf8") u.close() return self["path_to_file"] try: f = open(self["path_to_file"], "wb") f.write(u.read()) except IOError: print "   " finally: f.close() u.close() def rewriteTags(self, **kwargs): #     #     # tag=value if self["path_to_file"] == "none": return False # default action if self["fileType"] == "audio/mpeg": #      mutagen from mutagen.easyid3 import EasyID3 from mutagen.mp3 import MP3 import mutagen.id3 try: tags = MP3(self["path_to_file"], ID3=EasyID3) try: tags.add_tags(ID3=EasyID3) except mutagen.id3.error: pass for tag, value in kwargs.iteritems(): tags[tag] = value print("%s = %s" %(tag, value)) tags.save() except IOError: print "   %s" % self["path_to_file"] return False class LinkNotFound(Exception): pass def _getFirstNodeOrNoneByName(obj, tag): els = obj.getElementsByTagName(tag) if len(els) > 0: return els[0].firstChild.data else: return "unknown" if __name__ == "__main__": from ConfigParser import SafeConfigParser #     config = SafeConfigParser() config.read("./gpds.conf") try: download_episodes = config.get("settings", "download_episodes") download_episodes = int(download_episodes) except: download_episodes = 1 try: download_dir = config.get("settings", "download_dir") except: download_dir = os.path.abspath(os.curdir) links = config.items("podcasts") timePattern = re.compile(r"\w{2,6}, \d\d \w{2,6} \d{2,4} \d\d:\d\d:\d\d") #      for (author, rssLink) in links: try: rss = urllib.urlopen(rssLink) rssXML = minidom.parseString(rss.read()) items = rssXML.getElementsByTagName("item") for lastXMLPodcast in items[:download_episodes]: p = Podcast() p["title"] = _getFirstNodeOrNoneByName(lastXMLPodcast, "title") p["author"] = author.decode("utf8") enclosure = lastXMLPodcast.getElementsByTagName("enclosure")[0] p["linkToFile"] = enclosure.getAttribute("url") pubDate = _getFirstNodeOrNoneByName(lastXMLPodcast, "pubDate") try: p["pubDate"] = time.strftime("%d-%m-%y", \ time.strptime(timePattern.findall(pubDate)[0], \ "%a, %d %b %Y %H:%M:%S")\ ) except: p["pubDate"] = "_downloaded_at_%s" % \ time.strftime("%d-%m-%y", time.gmtime()) print " %s - %s  %s" %(\ p["author"].encode("utf8"), \ p["title"].encode("utf8"), \ p["pubDate"].encode("utf8")\ ) p.download( os.path.join(download_dir, p["author"]),\ "%s_%s" %(p["title"], p["pubDate"])\ ) p.rewriteTags( \ artist=p["author"], \ title=p["title"], \ album=u"  %s" %p["author"], \ genre=u"Podcast" \ ) finally: rss.close() 
#!/usr/bin/env python # -*- coding: utf8 -*- # # url from xml.dom import minidom from UserDict import UserDict import time, urllib, sys, os, re class Podcast(UserDict): '''Class to repr single podcast item''' extentionsDict = { "audio/mpeg": "mp3", "video/mp4": "mp4", "video/quicktime": "mov", "video/x-ms-wmv": "wmv" } def __init__(self): UserDict.__init__(self) self["linkToFile"] = "none" self["fileType"] = "audio/mpeg" def download(self, *args, **kwargs): ''' download podcast into file ''' # make sure we have what to download if self["linkToFile"] == "none": raise LinkNotFound # default directory set to current directory outputDir = os.path.abspath(os.path.curdir) if len(args) == 1: # Only file name fileName = os.path.splitext("%s" %args[0])[0] elif len(args) == 2: # file name and output dir outputDir = "%s" %args[0] fileName = os.path.splitext("%s" %args[1])[0] elif kwargs.has_key("file"): fileName = os.path.splitext(kwargs["file"])[0] if kwargs.has_key("dir"): outputDir = kwargs["dir"] outputDir = outputDir.rstrip(os.path.sep) # if output directory not exist # try to create output directory if os.path.exists(outputDir) == False: os.mkdir(outputDir) u = urllib.urlopen(self["linkToFile"]) # strInfo = str(u.info()) try: # self["fileType"] = re.findall(r"(?<=Content-Type: )\w+\/?\w*", strInfo)[0] except: pass # self["path_to_file"] = os.path.join(outputDir, fileName + os.path.extsep + self.extentionsDict[self["fileType"]] ) # Content-Length LentgthHeader = re.findall(r"(?<=Content-Length: )\d+", strInfo) if len(LentgthHeader) == 1: # # +-10% NotDownloadedLength = float(LentgthHeader[0]) if os.path.exists(self["path_to_file"]) and \ NotDownloadedLength*0.9 < \ float(os.path.getsize(self["path_to_file"]))\ < NotDownloadedLength*1.1: print " %s , " % self["path_to_file"].encode("utf8") u.close() return self["path_to_file"] try: f = open(self["path_to_file"], "wb") f.write(u.read()) except IOError: print " " finally: f.close() u.close() def rewriteTags(self, **kwargs): # # # tag=value if self["path_to_file"] == "none": return False # default action if self["fileType"] == "audio/mpeg": # mutagen from mutagen.easyid3 import EasyID3 from mutagen.mp3 import MP3 import mutagen.id3 try: tags = MP3(self["path_to_file"], ID3=EasyID3) try: tags.add_tags(ID3=EasyID3) except mutagen.id3.error: pass for tag, value in kwargs.iteritems(): tags[tag] = value print("%s = %s" %(tag, value)) tags.save() except IOError: print " %s" % self["path_to_file"] return False class LinkNotFound(Exception): pass def _getFirstNodeOrNoneByName(obj, tag): els = obj.getElementsByTagName(tag) if len(els) > 0: return els[0].firstChild.data else: return "unknown" if __name__ == "__main__": from ConfigParser import SafeConfigParser # config = SafeConfigParser() config.read("./gpds.conf") try: download_episodes = config.get("settings", "download_episodes") download_episodes = int(download_episodes) except: download_episodes = 1 try: download_dir = config.get("settings", "download_dir") except: download_dir = os.path.abspath(os.curdir) links = config.items("podcasts") timePattern = re.compile(r"\w{2,6}, \d\d \w{2,6} \d{2,4} \d\d:\d\d:\d\d") # for (author, rssLink) in links: try: rss = urllib.urlopen(rssLink) rssXML = minidom.parseString(rss.read()) items = rssXML.getElementsByTagName("item") for lastXMLPodcast in items[:download_episodes]: p = Podcast() p["title"] = _getFirstNodeOrNoneByName(lastXMLPodcast, "title") p["author"] = author.decode("utf8") enclosure = lastXMLPodcast.getElementsByTagName("enclosure")[0] p["linkToFile"] = enclosure.getAttribute("url") pubDate = _getFirstNodeOrNoneByName(lastXMLPodcast, "pubDate") try: p["pubDate"] = time.strftime("%d-%m-%y", \ time.strptime(timePattern.findall(pubDate)[0], \ "%a, %d %b %Y %H:%M:%S")\ ) except: p["pubDate"] = "_downloaded_at_%s" % \ time.strftime("%d-%m-%y", time.gmtime()) print " %s - %s %s" %(\ p["author"].encode("utf8"), \ p["title"].encode("utf8"), \ p["pubDate"].encode("utf8")\ ) p.download( os.path.join(download_dir, p["author"]),\ "%s_%s" %(p["title"], p["pubDate"])\ ) p.rewriteTags( \ artist=p["author"], \ title=p["title"], \ album=u" %s" %p["author"], \ genre=u"Podcast" \ ) finally: rss.close()


As a result, my cycling shakes a specified number of recent episodes of podcasts. Renames files, and rewrites tags. Finally, my mp3 player will be cleaned up and podcasts will always be where I expect to be.

')

Source: https://habr.com/ru/post/51537/


All Articles