#(c) 2004-2008 Thunderstone Media, LLC #Creative Commons Attribution-Noncommercial 3.0 United States License # #Python Developyment By: # #Ray Slakinski #August Trometer import iPXSettings from iPXTools import * from iPXDownloader import * from time import * from datetime import * class Feeds: def __init__(self): self.feedList = [] self.__getEnabledFeeds(iPXSettings.FeedListPrefs['iPodderXFeeds']) def retrFeeds(self): import re for feed in self.feedList: if feed.has_key('feedURL'): if len(feed['feedURL']) > 0: if not feed.has_key('feedID'): logIt('Feeds file could not provide feedID, generating new one') feed['feedID'] = genHash(feed['feedURL']) if iPXSettings.ranFromUI == False and checkForUI() == True: logIt('Shutting down script - UI has started...') break elif feed.has_key('feedURL'): if re.search('opml$', feed['feedURL'], re.IGNORECASE): opmlFeeds = getOpmlFeeds(feed['feedURL']) for entry in opmlFeeds: feed['feedURL'] = opmlFeeds[entry] feed['feedTitle'] = entry feedData = FeedData(feed, None, False) else: if feed.has_key('ttl') and feed.has_key('lastChecked'): currTime = mktime(gmtime()) lastChecked = mktime(strptime(feed['lastChecked'], '%a, %d %b %Y %H:%M:%S GMT')) if (lastChecked + (float(feed['ttl']) * 60)) - currTime <= 0: FeedData(feed) else: logIt('Skipping feed(%s) for TTL reasons.' % feed['feedURL']) logIt('TTL Value = %s' % str((lastChecked + (float(feed['ttl']) * 60)) - currTime) + ' seconds.') else: FeedData(feed) def retrFeed(self, feedID, retrType): import re for feed in self.feedList: if not feed.has_key('feedID'): logIt('Feeds file could not provide feedID, generating new one') feed['feedID'] = genHash(feed['feedURL']) if retrType > 0: if feed['feedID'] == feedID: if re.search('opml$', feed['feedURL'], re.IGNORECASE): opmlFeeds = getOpmlFeeds(feed['feedURL']) for entry in opmlFeeds: feed['feedURL'] = opmlFeeds[entry] feed['feedTitle'] = entry FeedData(feed, None, False) else: FeedData(feed, None, False) else: if feed['feedURL'] == feedID: if re.search('opml$', feed['feedURL'], re.IGNORECASE): opmlFeeds = getOpmlFeeds(feed['feedURL']) for entry in opmlFeeds: feed['feedURL'] = opmlFeeds[entry] feed['feedTitle'] = entry FeedData(feed, None, False) else: FeedData(feed, None, False) def retrEnclosure(self, feedID, entryGUID, encURL, hasFile=False): getEncURL = entryGUID + ';;' + encURL #logIt('FeedID: %s, getEncURL: %s' % (feedID, getEncURL)) for feed in self.feedList: if feed['feedID'] == feedID: FeedData(feed, getEncURL, False, hasFile) def getEnclosuresList(self): import os encList = [] for feed in self.feedList: if feed.has_key('feedID'): hashFile = iPXSettings.rssPath + 'feedData/' + feed['feedID'] + '.ipxd' if os.path.isfile(hashFile): try: EntriesData = readplist(hashFile) if EntriesData.has_key('entries'): for entry in EntriesData['entries']: if entry.has_key('read'): if entry['read'] == True: if entry.has_key('flagged'): if entry['flagged'] == False: if entry.has_key('enclosures'): for enc in entry['enclosures']: if enc.has_key('path'): if len(enc['path']) > 0: encList.append(enc) else: if entry.has_key('enclosures'): for enc in entry['enclosures']: if enc.has_key('path'): if len(enc['path']) > 0: encList.append(enc) else: if entry.has_key('enclosures'): for enc in entry['enclosures']: if enc.has_key('path'): if len(enc['path']) > 0: encList.append(enc) except Exception, msg: logIt('getEnclosuresList Faied: %s' % msg) return encList def createQMCacheBridge(self): import iPXQuotaManager, os for feed in self.feedList: if feed.has_key('feedID'): hashFile = iPXSettings.rssPath + 'feedData/' + feed['feedID'] + '.ipxd' if os.path.isfile(hashFile): try: EntriesData = readplist(hashFile) if Entries.has_key('entries'): for entry in EntriesData['entries']: if entry.has_key('enclosures'): for enc in entry['enclosures']: if enc.has_key('path'): encFile = os.path.join(iPXSettings.downloadDirectory + '/' + enc['path'] + '/' + enc['file']) if os.path.isfile(encFile): iPXQuotaManager.writeQuotaCache(feed['feedID'], entry['guid'], enc['path'] + '/' + enc['file'], enc['length']) except Exception, msg: logIt('getEnclosuresList Faied: %s' % msg) return #encList def __getEnabledFeeds(self, feedList): newFeedList = [] self.feedList = [] append = self.feedList.append for feed in feedList: if feed['enabled']: append(feed) class FeedData: def __init__(self, feed, getEncURL=None, useEtag=True, hasFile=False): import re self.feed = feed self.status = 0 self.explicit = False self.entries = {} self.parsedFeed = {} self.entriesData = [] printMSG(' ') try: if feed.has_key('customFeedTitle'): if len(feed['customFeedTitle']) > 0: printMSG('%s;;%s' % (HTML2Text(feed['customFeedTitle']), feed['feedID'])) else: printMSG('%s;;%s' % (HTML2Text(feed['feedTitle']), feed['feedID'])) else: printMSG('%s;;%s' % (HTML2Text(feed['feedTitle']), feed['feedID'])) except: printMSG('%s;;%s' % (HTML2Text(feed['feedURL']), feed['feedID'])) status = 0 if not getEncURL == None: if hasFile: self.__getEntryEnclosure(getEncURL, hasFile) else: self.__getEntryEnclosure(getEncURL) elif feed.has_key('etag') and iPXSettings.DEBUG == 0 and useEtag == True: status = self.__getFeed(feed['feedURL'], feed['etag'], feed['feedID']) elif feed.has_key('etag') and useEtag == False: status = self.__getFeed(feed['feedURL'], 'None', feed['feedID']) else: status = self.__getFeed(feed['feedURL'], 'None', feed['feedID']) if status >= 0: feed['error'] = False if status == 200 or status == 301 or status == 302: if self.parsedFeed.has_key('feed'): #Check feed level, which overrides entry level if self.parsedFeed.feed.has_key('itunes_explicit'): if re.search('yes', self.parsedFeed.feed.itunes_explicit, re.IGNORECASE): self.explicit = True elif self.parsedFeed.feed.has_key('media_adult'): if re.search('true', self.parsedFeed.feed.media_adult, re.IGNORECASE): self.explicit = True feed['explicit'] = self.explicit self.__getEntries() elif (status != 500) and (status != 304) and (status != 302) and (status != 301) and (status != 0): feed['error'] = True logIt('Feed recieved a status of %d, expected 200 or 304' % status) self.__saveFeedData(feed) def __getEntries(self): from sets import Set import sys, os, re newEntriesList = [] encList = [] tempList = [] hashFile = '' numDownloads = 0 numDFiles = 0 totalDSize = 0 maxDownloads = 10000000 totalDSize = 0 if self.feed.has_key('downloadBehavior'): if int(self.feed['downloadBehavior']) == 3: maxDownloads = 0 elif int(self.feed['downloadBehavior']) == 2: maxDownloads = 3 elif int(self.feed['downloadBehavior']) == 1: maxDownloads = 1 self.feed['downloadBehavior'] = 0 hashFile = iPXSettings.rssPath + 'feedData/' + self.feed['feedID'] + '.ipxd' if os.path.isfile(hashFile): try: EntriesData = readplist(hashFile) if EntriesData.has_key('entries'): entryOrig = EntriesData['entries'] else: logIt('Hash file seems to be currupt... resetting file') entryOrig = {} except: import plistlib logIt('Hash file seems to be currupt... resetting file') EntriesData = plistlib.Plist() entryOrig = {} else: if sys.platform == 'darwin': EntriesData = NSMutableDictionary.dictionary() else: import plistlib EntriesData = plistlib.Plist() entryOrig = {} append = newEntriesList.append for entry in entryOrig: if not entry.has_key('guid'): entry['guid'] = '' if not entry.has_key('read'): entry['read'] = True if not entry['guid'] in encList: if len(entry['guid']) > 1: encList.append(entry['guid']) append(entry) if self.parsedFeed.has_key('entries'): for entry in self.parsedFeed.entries: if entry.has_key('modified_parsed'): if not entry.modified_parsed == None: pubDate = entry.modified_parsed else: pubDate = gmtime() else: pubDate = gmtime() strCat = '' catList = [] if entry.has_key('categories'): for dict in entry.categories: append = catList.append for cat in dict: if not type(cat) is NoneType: if not cat == 'None': try: append(cat.encode('utf-8')) except: pass categories = Set(catList) for category in categories: if not re.search('http://', category, re.IGNORECASE) or re.search('https://', category, re.IGNORECASE): strCat = strCat + category + ', ' if len(strCat) > 0: if strCat[len(strCat)-2] == ',': strCat = strCat[:-2] strAuthor = '' if entry.has_key('author'): strAuthor = entry.author strLink = self.feed['feedURL'] if entry.has_key('link'): strLink = entry.link strCommentsLink = '' if entry.has_key('comments'): strCommentsLink = entry.comments strSourceLink = '' strSourceName = '' if entry.has_key('source'): if entry.source.has_key('url'): strSourceLink = entry.source.url if entry.source.has_key('value'): strSourceName = entry.source.value explicit = False #Check feed level, which overrides entry level if self.parsedFeed.feed.has_key('itunes_explicit'): if re.search('yes', self.parsedFeed.feed.itunes_explicit, re.IGNORECASE): explicit = True elif self.parsedFeed.feed.has_key('media_adult'): if re.search('true', self.parsedFeed.feed.media_adult, re.IGNORECASE): explicit = True #Check entry level if not set by feed level if explicit == False: if entry.has_key('itunes_explicit'): if re.search('yes', entry.itunes_explicit, re.IGNORECASE): explicit = True elif entry.has_key('media_adult'): if re.search('true', entry.media_adult, re.IGNORECASE): explicit = True uniDescription = unicode('No Entry Text Found In Feed', 'utf-8') if entry.has_key('content'): uniDescription = entry.content[0].value elif entry.has_key('summary_detail'): uniDescription = entry.summary_detail.value elif entry.has_key('description'): uniDescription = entry.description try: if len(uniDescription) == 0: uniDescription = unicode('No Entry Text Found In Feed', 'utf-8') except: uniDescription = unicode('No Entry Text Found In Feed', 'utf-8') uniDescription = uniDescription.strip() uniDescription = uniDescription.strip(chr(0)) uniDescription = uniDescription.replace('\x00', '') uniDescription = uniDescription.replace('\r', '') if type(uniDescription) == StringType: uniDescription = HTML2Text(uniDescription) uniSummary = unicode('', 'utf-8') if entry.has_key('summary_detail'): uniDescription = entry.summary_detail.value uniSummary = uniSummary.strip() uniSummary = uniSummary.strip(chr(0)) uniSummary = uniSummary.replace('\x00', '') uniSummary = uniSummary.replace('\r', '') if type(uniSummary) == StringType: uniSummary = HTML2Text(uniSummary) if entry.has_key('guid'): strGUID = entry.guid elif entry.has_key('title'): if len(entry.title) > 20: strGUID = genHash(entry.title) else: strGUID = genHash(uniDescription) else: strGUID = genHash(uniDescription) uniTitle = unicode('', 'utf-8') if entry.has_key('title'): uniTitle = HTML2Text(entry.title) try: uniTitle = tmpTitle.encode('utf-8') except Exception, msg: pass strLink = self.feed['feedURL'] if entry.has_key('link'): strLink = entry.link encArray = [] if entry.has_key('enclosures') or entry.has_key('links') or entry.has_key('apple-wallpapers_image'): if iPXSettings.showExplicit == True: if numDownloads < maxDownloads: encArray, numDownloaded, sizeDownloaded = self.__getEntryEnclosures(entry, True, self.feed['baseHost']) else: encArray, numDownloaded, sizeDownloaded = self.__getEntryEnclosures(entry, False) elif explicit == True: encArray, numDownloaded, sizeDownloaded = self.__getEntryEnclosures(entry, False) else: if numDownloads < maxDownloads: encArray, numDownloaded, sizeDownloaded = self.__getEntryEnclosures(entry, True, self.feed['baseHost']) else: encArray, numDownloaded, sizeDownloaded = self.__getEntryEnclosures(entry, False) if numDownloaded > 0: numDownloaded = 0 numDownloads = numDownloads + 1 numDFiles = numDFiles + numDownloads totalDSize = totalDSize + long(sizeDownloaded) if self.feed.has_key('textToAudio'): if not strGUID in encList: if self.feed['textToAudio']: tempEnc = self.downloadTextAsAudio(uniTitle, strftime('%A %B %d %Y', pubDate), uniDescription, strGUID) if not tempEnc == None: encArray.append(tempEnc) newEntry = {'description': uniDescription, 'summary': uniSummary, 'link': strLink, 'title': uniTitle, 'read': False, 'enclosures': encArray, 'pubDate': strftime('%a, %d %b %Y %H:%M:%S GMT', pubDate), #'datePublished' : strftime('%Y-%b-%dT%H:%M:%SZ', pubDate), 'category': strCat, 'commentsLink': strCommentsLink, 'feedTitle': HTML2Text(self.feed['feedTitle']), 'sourceTitle': strSourceName, 'sourceLink': HTML2Text(strSourceLink), 'explicit': explicit, 'author': strAuthor, 'guid': strGUID } tempList.append(newEntry['guid']) if strGUID in encList: for entry in newEntriesList: if entry.has_key('guid'): if entry['guid'] == newEntry['guid']: if entry.has_key('origDescription'): if not genHash(entry['origDescription']) == genHash(newEntry['description']): entry['bakDescription'] = entry['origDescription'] entry['origDescription'] = newEntry['description'] entry['description'] = textDiff(entry['origDescription'], newEntry['description']) entry['title'] = newEntry['title'] if genHash(HTML2Text(newEntry['description'])) != genHash(HTML2Text(entry['origDescription'])): entry['read'] = False if len(entry['enclosures']) < len(newEntry['enclosures']): entry['enclosures'] = newEntry['enclosures'] entry['read'] = False elif genHash(entry['description']) != genHash(newEntry['description']): entry['bakDescription'] = entry['description'] entry['origDescription'] = newEntry['description'] entry['description'] = textDiff(entry['description'], newEntry['description']) entry['title'] = newEntry['title'] if genHash(HTML2Text(newEntry['description'])) != genHash(HTML2Text(entry['origDescription'])): entry['read'] = False if len(entry['enclosures']) < len(newEntry['enclosures']): entry['enclosures'] = newEntry['enclosures'] entry['read'] = False elif genHash(entry['title']) != genHash(newEntry['title']): if len(newEntry['title']) > 0: entry['title'] = newEntry['title'] if len(entry['enclosures']) < len(newEntry['enclosures']): entry['enclosures'] = newEntry['enclosures'] entry['read'] = False elif len(entry['enclosures']) < len(newEntry['enclosures']): entry['enclosures'] = newEntry['enclosures'] entry['read'] = False else: encList.append(newEntry['guid']) newEntriesList.append(newEntry) if numDFiles > 0: self.__saveHashFile(EntriesData, newEntriesList, tempList, numDFiles, totalDSize, hashFile) numDFiles = 0 totalDSize = 0.0 self.__saveHashFile(EntriesData, newEntriesList, tempList, numDownloads, totalDSize, hashFile) def __saveHashFile(self, EntriesData, newEntriesList, tempList, numDownloads, totalDSize, hashFile, skipDelOld=False): import os logIt('Saving to hashFile: %s' % hashFile) dellist = [] if skipDelOld == False: #Lets delete old entries... for entry in newEntriesList: if not entry['guid'] in tempList: flagged = False if entry.has_key('flagged'): flagged = entry['flagged'] hasFile = False if entry.has_key('enclosures'): if len(entry['enclosures']) > 0: for enclosure in entry['enclosures']: path = enclosure['path'] fullPath = iPXSettings.downloadDirectory + '/' + path fileName = enclosure['file'] if os.path.isfile(fullPath + '/' + fileName): hasFile = True break if hasFile == False: if entry['read'] == True: if flagged == False: if len(entry['enclosures']) == 0: try: tmpEntryDate = strptime(entry['pubDate'], '%a, %d %b %Y %H:%M:%S %Z') entryDate = date(tmpEntryDate[0], tmpEntryDate[1], tmpEntryDate[2]) dateDelta = date.today() - entryDate strDateDelta = str(dateDelta).split() if len(strDateDelta) > 1: if iPXSettings.maxEntryAge > 0: if int(strDateDelta[0]) > iPXSettings.maxEntryAge: dellist.append(entry) except: pass if len(dellist) > 0: remove = newEntriesList.remove for entry in dellist: remove(entry) if EntriesData.has_key('statistics'): stats = EntriesData['statistics'] numDFiles = numDownloads if stats.has_key('numDFiles'): numDFiles = numDFiles + long(stats['numDFiles']) totalDSizeMB = float(totalDSize) / 1048576.0 if stats.has_key('totalDSize'): totalDSizeMB = float(totalDSizeMB) + float(stats['totalDSize']) strTotalDSizeMB = '%.2f' % totalDSizeMB firstCheck = strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()) if stats.has_key('firstCheck'): firstCheck = stats['firstCheck'] stats = {'firstCheck': firstCheck, 'lastCheck': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'numDFiles': str(numDFiles), 'totalDSize': strTotalDSizeMB} else: totalDSizeMB = float(totalDSize) / 1048576.0 strTotalDSizeMB = '%.2f' % totalDSizeMB numDFiles = numDownloads stats = {'firstCheck': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'lastCheck': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'numDFiles': str(numDFiles), 'totalDSize': strTotalDSizeMB} EntriesData['statistics'] = stats EntriesData['entries'] = newEntriesList writeplist(EntriesData, hashFile) def __getEntryEnclosure(self, getEncURL, hasFile=False): import sys, os, re logIt('getEncURL') origEntriesList = [] hashFile = '' totalDSize = 0 numDFiles = 1 hashFile = iPXSettings.rssPath + 'feedData/' + self.feed['feedID'] + '.ipxd' if iPXSettings.ranHistCheck == False: iPXSettings.histGUIDs = getHistory() iPXSettings.ranHistCheck = True if os.path.isfile(hashFile): try: EntriesData = readplist(hashFile) if EntriesData.has_key('entries'): entryOrig = EntriesData['entries'] else: logIt('Hash file seems to be currupt... resetting file') entryOrig = {} except: import plistlib logIt('Hash file seems to be currupt... resetting file') EntriesData = plistlib.Plist() entryOrig = {} else: if sys.platform == 'darwin': EntriesData = NSMutableDictionary.dictionary() else: import plistlib EntriesData = plistlib.Plist() entryOrig = {} append = origEntriesList.append for entry in entryOrig: append(entry) getEncURLSplit = getEncURL.split(';;') guid = getEncURLSplit[0] encURL = getEncURLSplit[1] for entry in origEntriesList: if entry['guid'] == guid: for enclosure in entry['enclosures']: if enclosure['enclosureURL'] == encURL: downloadError = False url = encURL.strip() length = '0' if enclosure.has_key('length'): if len(enclosure['length']) > 0: length = enclosure['length'] totalDSize = totalDSize + long(length) fileType = enclosure['type'] guid = enclosure['guid'] feedTitle = HTML2Text(self.feed['feedTitle']) feedTitle = feedTitle.replace('/', ' ') if iPXSettings.organizeDownloads == 1: customFolder = strftime('%m-%d-%Y',localtime()) else: customFolder = feedTitle if self.feed.has_key('customFolder'): if len(self.feed['customFolder']) > 0: customFolder = self.feed['customFolder'] customFolder = stringCleaning(customFolder) if hasFile: iPXID = '' importProg = '' fileType = '' customGenre = '' downloadStatus = enclosure['downloadStatus'] if self.feed.has_key('customGenre'): customGenre = self.feed['customGenre'] path = enclosure['path'] fullPath = iPXSettings.downloadDirectory + '/' + path fileName = enclosure['file'] if os.path.isfile(fullPath + '/' + fileName): fileType = detectFileType(fullPath + '/' + fileName) # Audio if re.search('audio', fileType, re.IGNORECASE): convertToAAC = False if self.feed.has_key('convertToAAC'): convertToAAC = self.feed['convertToAAC'] makeBookmarkable = False if self.feed.has_key('makeBookmarkable'): makeBookmarkable = self.feed['makeBookmarkable'] importProg = 'iTunes' iPXID, importProg = updatePlaylist(fullPath, fileName, customFolder, customGenre, convertToAAC, makeBookmarkable) # Image elif re.search('image', fileType, re.IGNORECASE): importProg = 'iPhoto' iPXID, importProg = updateiPhoto(fullPath, fileName, customFolder, 0) # Video Files elif re.search('video/quicktime', fileType, re.IGNORECASE): importProg = 'iTunes' iPXID, importProg = updatePlaylist(fullPath, fileName, customFolder, '', False, False) elif re.search('data', fileType, re.IGNORECASE): if (re.search('mp3$', fileName, re.IGNORECASE)): if (iPXSettings.moveAudio > 0): importProg = 'iTunes' iPXID, importProg = updatePlaylist(fullPath, fileName, customFolder, customGenre, convertToAAC, makeBookmarkable) elif (re.search('mov$', fileName, re.IGNORECASE)): if (iPXSettings.moveVideo > 0): importProg = 'iTunes' iPXID, importProg = updatePlaylist(fullPath, fileName, customFolder, customGenre, False, False) elif (re.search('aa$', fileName, re.IGNORECASE)): if (iPXSettings.moveVideo > 0): importProg = 'iTunes' iPXID, importProg = updatePlaylist(fullPath, fileName, customFolder, customGenre, False, False) else: fileNameSplit = url.split('/') fileName = fileNameSplit[len(fileNameSplit) - 1] fileName = latin1_to_ascii(fileName) fileName = stringCleaning(fileName) importProg = '' fileLocation = '' path = iPXSettings.downloadDirectory + '/' + customFolder path = latin1_to_ascii(path) downloadStatus = 0 fileName, iPXID, importProg, fileType, downloadStatus = self.iPXDownload(url, guid, path, fileName, length, fileType, True) if downloadStatus == 1: downloadError = False if not guid in iPXSettings.histGUIDs: saveHistory(guid) iPXSettings.histGUIDs.append(guid) else: downloadError = True totalDSize = long(length) tempEnc = {'enclosureURL': url, 'length': length, 'type': fileType, 'file': fileName, 'path': latin1_to_ascii(customFolder), 'guid': guid, 'import': importProg, 'iPXID': iPXID, 'textToAudio': False, 'downloadStatus': downloadStatus, 'downloadDate': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'downloadError': downloadError} enclosure.update(tempEnc) tempList = [] self.__saveHashFile(EntriesData, origEntriesList, tempList, numDFiles, totalDSize, hashFile, True) def __getEntryEnclosures(self, entry, doDownload, host=None): from sets import Set import re returnEncList = [] numDownloaded = 0 sizeDownloaded = 0 keywords = [] if self.feed.has_key('keywords'): keywords = self.feed['keywords'].split(',') if iPXSettings.ranHistCheck == False: iPXSettings.histGUIDs = getHistory() iPXSettings.ranHistCheck = True okDownload = True if entry.has_key('guid'): if not entry['guid'] == None: if entry['guid'] in iPXSettings.histGUIDs: okDownload = False elif not host == None: if host + entry['guid'] in iPXSettings.histGUIDs: okDownload = False else: okDownload = True else: okDownload = True else: okDownload = True strTitle = '' uniDescription = unicode('', 'utf-8') strCat = '' if (len(keywords) > 0) and (doDownload == True): if entry.has_key('title'): strTitle = HTML2Text(entry.title) if entry.has_key('summary_detail'): uniDescription = entry.summary_detail.value if len(uniDescription) == 0: uniDescription = unicode('No Entry Text Found In Feed', 'utf-8') if entry.has_key('content'): uniDescription = entry.content[0].value elif entry.has_key('content'): uniDescription = entry.content[0].value elif entry.has_key('description'): uniDescription = entry.description catList = [] if entry.has_key('categories'): for dict in entry.categories: for cat in dict: try: if not type(cat) is NoneType: if not cat == 'None': try: catList.append(cat.encode('utf-8')) except: pass except Exception, msg: logIt('Type error: %s' % msg) categories = Set(catList) for category in categories: if not re.search('http://', category, re.IGNORECASE) or re.search('https://', category, re.IGNORECASE): strCat = strCat + category + ', ' if len(strCat) > 0: if strCat[len(strCat)-2] == ',': strCat = strCat[:-2] if re.search('rss', self.parsedFeed.version, re.IGNORECASE): if entry.has_key('enclosures'): for enclosure in entry.enclosures: if enclosure.has_key('url'): if len(enclosure.url) > 0: url = enclosure.url url = url.strip() url = prepURL(url) fileNameSplit = url.split('/') fileName = fileNameSplit[len(fileNameSplit) - 1] fileName = latin1_to_ascii(fileName) fileType = 'Unknown' if enclosure.has_key('type'): fileType = enclosure.type length = '0' if enclosure.has_key('length'): if len(enclosure.length) > 0: length = enclosure.length try: temp = long(length) except: length = '0' if entry.has_key('guid'): guid = entry.guid else: guid = enclosure.url importProg = '' fileLocation = '' feedTitle = HTML2Text(self.feed['feedTitle']) feedTitle = feedTitle.replace('/', '-') if iPXSettings.organizeDownloads == 1: customFolder = strftime('%m-%d-%Y',localtime()) else: customFolder = feedTitle if self.feed.has_key('customFolder'): if len(self.feed['customFolder']) > 0: customFolder = self.feed['customFolder'] customFolder = stringCleaning(customFolder) path = iPXSettings.downloadDirectory + '/' + customFolder path = latin1_to_ascii(path) downloadStatus = 0 autoDownload = True if self.feed.has_key('autoDownload'): autoDownload = self.feed['autoDownload'] downloadError = False if autoDownload: encArray = [] if entry.has_key('enclosures') or entry.has_key('links'): didFind = True if len(keywords) > 0: for keyword in keywords: keywordSplit = keyword.split(' ') for word in keywordSplit: if len(word) > 1: if (re.search(word.strip(), url, re.IGNORECASE) or re.search(word.strip(), strTitle, re.IGNORECASE) or re.search(word.strip(), uniDescription, re.IGNORECASE)or re.search(word.strip(), strCat, re.IGNORECASE)): didFind = True else: didFind = False break if url in iPXSettings.histGUIDs: doDownload = False if didFind and okDownload and doDownload: fileName, fileLocation, importProg, fileType, downloadStatus = self.iPXDownload(url, guid, path, fileName, length, fileType, doDownload) if downloadStatus == 1: numDownloaded = numDownloaded + 1 sizeDownloaded = long(sizeDownloaded) + long(length) elif downloadStatus == 0: downloadError = True elif didFind and okDownload and not doDownload: fileName, fileLocation, importProg, fileType, downloadStatus = self.iPXDownload(url, guid, path, fileName, length, fileType, doDownload) tempEnc = {'enclosureURL': url, 'length': length, 'type': fileType, 'file': fileName, 'path': latin1_to_ascii(customFolder), 'guid': guid, 'import': importProg, 'iPXID': fileLocation, 'textToAudio': False, 'downloadError': downloadError, 'downloadDate': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'downloadStatus': downloadStatus} returnEncList.append(tempEnc) elif entry.has_key('apple-wallpapers_image'): if len(entry['apple-wallpapers_image']) > 0: url = entry['apple-wallpapers_image'] url = url.strip() url = prepURL(url) fileNameSplit = url.split('/') fileName = fileNameSplit[len(fileNameSplit) - 1] fileName = latin1_to_ascii(fileName) fileType = 'image' length = '0' if entry.has_key('guid'): guid = entry.guid else: guid = url importProg = '' fileLocation = '' feedTitle = HTML2Text(self.feed['feedTitle']) feedTitle = feedTitle.replace('/', '-') if iPXSettings.organizeDownloads == 1: customFolder = strftime('%m-%d-%Y',localtime()) else: customFolder = feedTitle if self.feed.has_key('customFolder'): if len(self.feed['customFolder']) > 0: customFolder = self.feed['customFolder'] customFolder = stringCleaning(customFolder) path = iPXSettings.downloadDirectory + '/' + customFolder path = latin1_to_ascii(path) downloadStatus = 0 autoDownload = True if self.feed.has_key('autoDownload'): autoDownload = self.feed['autoDownload'] downloadError = False if autoDownload: encArray = [] if entry.has_key('enclosures') or entry.has_key('links') or entry.has_key('apple-wallpapers_image'): didFind = True if len(keywords) > 0: for keyword in keywords: keywordSplit = keyword.split(' ') for word in keywordSplit: if len(word) > 1: if (re.search(word.strip(), url, re.IGNORECASE) or re.search(word.strip(), strTitle, re.IGNORECASE) or re.search(word.strip(), uniDescription, re.IGNORECASE)or re.search(word.strip(), strCat, re.IGNORECASE)): didFind = True else: didFind = False break if url in iPXSettings.histGUIDs: doDownload = False if didFind and okDownload and doDownload: fileName, fileLocation, importProg, fileType, downloadStatus = self.iPXDownload(url, guid, path, fileName, length, fileType, doDownload) if downloadStatus == 1: numDownloaded = numDownloaded + 1 sizeDownloaded = long(sizeDownloaded) + long(length) elif downloadStatus == 0: downloadError = True elif didFind and okDownload and not doDownload: fileName, fileLocation, importProg, fileType, downloadStatus = self.iPXDownload(url, guid, path, fileName, length, fileType, doDownload) tempEnc = {'enclosureURL': url, 'length': length, 'type': fileType, 'file': fileName, 'path': latin1_to_ascii(customFolder), 'guid': guid, 'import': importProg, 'iPXID': fileLocation, 'textToAudio': False, 'downloadError': downloadError, 'downloadDate': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'downloadStatus': downloadStatus} returnEncList.append(tempEnc) elif re.search('atom', self.parsedFeed.version, re.IGNORECASE): if entry.has_key('links'): for link in entry.links: if link.rel == 'enclosure': if link.has_key('href'): if len(link.href) > 0: url = link.href url = url.strip() url = prepURL(url) fileNameSplit = url.split('/') fileName = fileNameSplit[len(fileNameSplit) - 1] fileName = latin1_to_ascii(fileName) fileType = '' if link.has_key('type'): fileType = link.type length = '0' if link.has_key('length'): if len(link['length']) > 0: length = link['length'] if entry.has_key('guid'): guid = entry.guid else: guid = link.href importProg = '' fileLocation = '' downloadError = False feedTitle = HTML2Text(self.feed['feedTitle']) feedTitle = feedTitle.replace('/', '-') if iPXSettings.organizeDownloads == 1: customFolder = strftime('%m-%d-%Y',localtime()) else: customFolder = feedTitle if self.feed.has_key('customFolder'): if len(self.feed['customFolder']) > 0: customFolder = self.feed['customFolder'] customFolder = stringCleaning(customFolder) path = iPXSettings.downloadDirectory + '/' + customFolder path = latin1_to_ascii(path) if self.feed.has_key('autoDownload'): if self.feed['autoDownload'] == True: didFind = True if len(keywords) > 0: for keyword in keywords: keywordSplit = keyword.split(' ') for word in keywordSplit: if len(word) > 1: if (re.search(word, url, re.IGNORECASE) or re.search(word, strTitle, re.IGNORECASE) or re.search(word, uniDescription, re.IGNORECASE) or re.search(word, strCat, re.IGNORECASE)): didFind = True break else: didFind = False if url in iPXSettings.histGUIDs: doDownload = False if didFind and okDownload: fileName, fileLocation, importProg, fileType, downloadStatus = self.iPXDownload(url, guid, path, fileName,length, fileType, doDownload) if downloadStatus == 1: numDownloaded = numDownloaded + 1 sizeDownloaded = long(sizeDownloaded) + long(length) elif downloadStatus == 0: downloadError = True tempEnc = {'enclosureURL': url, 'length': length, 'type': fileType, 'file': fileName, 'path': latin1_to_ascii(customFolder), 'guid': guid, 'import': importProg, 'textToAudio': False, 'downloadError': downloadError, 'downloadDate': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'iPXID': fileLocation} returnEncList.append(tempEnc) return returnEncList, numDownloaded, sizeDownloaded def __saveFeedData(self, newFeed): import sys logIt('Saving feeds.plist') try: FeedListPrefs = readplist(iPXSettings.feedFile) feedDetails = FeedListPrefs['iPodderXFeeds'] for feed in feedDetails: if feed.has_key('feedURL'): if feed['feedURL'] == newFeed['feedURL']: feed.update(newFeed) FeedListPrefs['iPodderXFeeds'] = feedDetails #FeedListPrefs.write(iPXSettings.feedFile) writeplist(FeedListPrefs, iPXSettings.feedFile) except Exception, msg: logIt(msg) sys.exit(5) def __getFeed(self, url, etagInfo, feedID): import feedparser, urllib, urllib2, urlparse parsedFeed = {} etag = '' self.feed['lastChecked'] = strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()) self.feed['baseHost'] = 'http:/' for part in urlparse.urlparse(url): if not part == urlparse.urlparse(url)[0]: if len(part) > 0: if '/' in part: splitPart = part.split('/') for newPart in splitPart: if newPart == splitPart[len(splitPart)-1]: break if len(newPart) > 0: self.feed['baseHost'] = self.feed['baseHost'] + '/' + newPart else: self.feed['baseHost'] = self.feed['baseHost'] + '/' + part self.feed['baseHost'] = self.feed['baseHost'] + '/' logIt('etagInfo: %s' % etagInfo) userName = None if self.feed.has_key('username'): userName = self.feed['username'] password = '' if self.feed.has_key('password'): password = decrypt(self.feed['password']) if iPXSettings.useProxyServer and userName != None: status, url, x = getFileViaProxySSL(url, userName, password, True, False) status, feedData, r = getFileViaProxySSL(url, userName, password, False, False) if status == 200: parsedFeed = feedparser.parse(feedData) if parsedFeed.has_key('entries'): if len(parsedFeed.entries) > 0: self.parsedFeed = parsedFeed self.feed['etag'] = '' if parsedFeed.feed.has_key('ttl'): self.feed['ttl'] = parsedFeed.feed.ttl else: self.feed['ttl'] self.feed['feedTitle'] = HTML2Text(parsedFeed.feed.title) if self.feed.has_key('customFeedTitle'): if len(self.feed['customFeedTitle']) > 0: self.feed['feedTitle'] = self.feed['customFeedTitle'] self.feed['siteURL'] = parsedFeed.feed.link return 200 else: return 0 else: req = urllib2.Request(url) req.add_header('Accept-encoding', 'gzip') if not etagInfo == 'None': req.add_header('If-None-Match', etagInfo) if not userName == None: setOpener(url, userName, password) else: setOpener() try: h = urllib2.urlopen(req) except urllib2.HTTPError, e: logIt('Feed recieved a status of %s' % e.code) if e.code == 401: printMSG('AUTHENTICATION_FAILED;;%s' % feedID) if e.code == 407: printMSG('PROXY_AUTHENTICATION_FAILED') return -1 except Exception, msg: logIt('Feed failed to connect %s' % msg) return -1 try: etag = h.info()['etag'] except: etag = '' try: if h.info().has_key('Content-Encoding'): if h.info()['Content-Encoding'] == 'gzip': import gzip from StringIO import StringIO tempData = h.read() feedData = gzip.GzipFile(fileobj=StringIO(tempData)).read() else: try: feedData = h.read() except Exception, msg: logIt('FeedData ERRMSG: %s' % msg) feedData = '' if iPXSettings.SUPERDEBUG: print feedData parsedFeed = feedparser.parse(feedData) if parsedFeed.has_key('entries'): if len(parsedFeed.entries) > 0: self.parsedFeed = parsedFeed self.feed['etag'] = etag if parsedFeed.feed.has_key('ttl'): self.feed['ttl'] = parsedFeed.feed.ttl else: self.feed['ttl'] = 0 self.feed['feedTitle'] = HTML2Text(parsedFeed.feed.title) if self.feed.has_key('customFeedTitle'): if len(self.feed['customFeedTitle']) > 0: self.feed['feedTitle'] = self.feed['customFeedTitle'] self.feed['siteURL'] = parsedFeed.feed.link parsedFeed.status = 200 return int(parsedFeed.status) except: return -1 def iPXDownload(self, encURL, encGUID, downloadPath, fileName, size, fileType, doDownload): logIt('Downloading: %s' % encURL) status = 1 fileLocation = '' importProg = '' head = None userName = None password = '' if self.feed.has_key('username'): userName = self.feed['username'] if self.feed.has_key('password'): password = decrypt(self.feed['password']) #head = HTTPHead(encURL, userName, password) if head != None: if len(head.getName()) > 0: fileName = head.getName() if head.getType() != None: fileType = head.getType() if head.getLength() != None: size = long(head.getLength()) if iPXSettings.quotaEnabled > 0 and doDownload == True: import iPXQuotaManager if iPXSettings.ranQuotaTest == False: printMSG('Compiling SmartSpace Information...') iPXSettings.delList, iPXSettings.quotaSizeTaken = iPXQuotaManager.getAllowedDelList() iPXSettings.ranQuotaTest = True iPXQuotaManager.getToQuota(size) convertToAAC = False if self.feed.has_key('convertToAAC'): convertToAAC = self.feed['convertToAAC'] makeBookmarkable = False if self.feed.has_key('makeBookmarkable'): makeBookmarkable = self.feed['makeBookmarkable'] if doDownload: customGenre = '' if self.feed.has_key('customGenre'): customGenre = self.feed['customGenre'] if iPXSettings.organizeDownloads == 1: customFolder = strftime('%m-%d-%Y',localtime()) else: customFolder = self.feed['feedTitle'] if self.feed.has_key('customFolder'): if len(self.feed['customFolder']) > 0: customFolder = self.feed['customFolder'] customFolder = latin1_to_ascii(customFolder) fileName, fileLocation, importProg, fileType, status = downloadFile(encURL,fileType,downloadPath,fileName,customFolder,customGenre,convertToAAC,makeBookmarkable,userName,password) if not encGUID in iPXSettings.histGUIDs and status == 1: saveHistory(encGUID) if iPXSettings.anonFeedback and status == 1: doPing(encURL, self.feed['feedURL']) elif not encGUID in iPXSettings.histGUIDs: saveHistory(encGUID) return fileName, fileLocation, importProg, fileType, status def downloadTextAsAudio(self, strTitle, pubDate, text, strGUID): import sys, os customFolder = self.feed['feedTitle'] feedTitle = customFolder if len(strTitle) == 0: strTitle = customFolder + ': ' x = 0 textSplit = text.split(' ') for word in textSplit: tmpWord = word + ' ' strTitle = strTitle + tmpWord if x == 5: break else: x = x + 1 strTitle = strTitle.strip() text = 'From ' + feedTitle + ', posted on ' + pubDate + '. '+ text if self.feed.has_key('customFolder'): if len(self.feed['customFolder']) > 0: customFolder = self.feed['customFolder'] customFolder = stringCleaning(customFolder) if sys.platform == 'darwin': saveDir = iPXSettings.downloadDirectory + '/' + customFolder elif sys.platform == 'win32': saveDir = iPXSettings.downloadDirectory + '\\' + customFolder checkDir(saveDir) saveName = HTML2Text(strTitle) saveName = pubDate + ' - ' + saveName saveName = stringCleaning(saveName) if sys.platform == 'darwin': saveName = saveName + '.aiff' elif sys.platform == 'win32': saveName = saveName + '.wav' if text2Audio(text, saveDir, saveName) == True: length = 0 if os.path.isfile(saveDir + '/' + saveName): length = os.path.getsize(saveDir + '/' + saveName) if iPXSettings.quotaEnabled > 0: import iPXQuotaManager iPXQuotaManager.getToQuota(length) importProg = '' fileLocation = '' if (iPXSettings.moveAudio > 0): customGenre = 'iPodderX NewsCaster' if self.feed.has_key('customGenre'): customGenre = self.feed['customGenre'] convertToAAC = True if self.feed.has_key('convertToAAC'): convertToAAC = self.feed['convertToAAC'] makeBookmarkable = False if self.feed.has_key('makeBookmarkable'): makeBookmarkable = self.feed['makeBookmarkable'] fileLocation, importProg = updatePlaylist(saveDir, saveName, customFolder, customGenre, convertToAAC, makeBookmarkable) tempEnc = {'length': str(length), 'type': 'audio', 'file': saveName, 'path': saveDir, 'guid': strGUID, 'import': importProg, 'iPXID': fileLocation, 'textToAudio': True, 'downloadError': False, 'downloadDate': strftime('%a, %d %b %Y %H:%M:%S GMT',gmtime()), 'downloadStatus': '1'} return tempEnc else: return None