def xmlrpc_process(self, archiveDir, rarPassword=None): """ Post process the specified directory. The -p option is preferable -- it will do this for you, or use the current process if this XML-RPC call fails """ # FIXME: merge this with Daemon.postProcess if not os.path.isdir(archiveDir): raise Fault( 9001, 'Unable to process, not a directory: ' + toUnicode(archiveDir)) if not os.access(archiveDir, os.R_OK) or not os.access( archiveDir, os.W_OK): raise Fault(9001, 'Unable to process, no read/write access to directory: ' + \ toUnicode(archiveDir)) dirName = os.path.dirname(archiveDir.rstrip(os.sep)) # We are the queue daemon -- Symlink to the archiveDir. If we are ctrl-ced, we'll # pick up the post processing afterward restart if os.path.normpath(dirName) != os.path.normpath( Hellanzb.PROCESSING_DIR): destDir = dupeName( os.path.join(Hellanzb.PROCESSING_DIR, os.path.basename(archiveDir.rstrip(os.sep)))) # UNIX: symlink, windows =[ os.symlink(archiveDir, destDir) archiveDir = destDir archive = Archive(archiveDir, rarPassword=rarPassword) troll = PostProcessor(archive) troll.start() return self.xmlrpc_status()
def fromStateXML(type, target): """ Factory method, returns a new NZB object for the specified target, and recovers the NZB state from the RecoveredState object if the target exists there for the specified type (such as 'processing', 'downloading') """ if type == 'processing': recoveredDict = Hellanzb.recoveredState.getRecoveredDict( type, target) archiveDir = os.path.join(Hellanzb.PROCESSING_DIR, target) if recoveredDict and recoveredDict.get('nzbFileName') is not None: target = recoveredDict.get('nzbFileName') else: # If this is a processing recovery request, and we didn't recover any # state information, we'll consider this a basic Archive object (it has no # accompanying .NZB file to keep track of) return Archive.fromStateXML(archiveDir, recoveredDict) else: recoveredDict = Hellanzb.recoveredState.getRecoveredDict( type, archiveName(target)) # Pass the id in with the constructor (instead of setting it after the fact) -- # otherwise the constructor would unnecessarily incremenet the IDPool nzbId = None if recoveredDict: nzbId = recoveredDict['id'] nzb = NZB(target, nzbId) if type == 'processing': nzb.archiveDir = archiveDir if recoveredDict: for key, value in recoveredDict.iteritems(): if key == 'id' or key == 'order': continue if key == 'neededBlocks': value = int(value) if key == 'totalBytes': nzb.calculatingBytes = False value = int(value) if key == 'downloadTime': value = float(value) if key == 'parType': value = getParEnum(value) setattr(nzb, key, value) return nzb
def fromStateXML(type, target): """ Factory method, returns a new NZB object for the specified target, and recovers the NZB state from the RecoveredState object if the target exists there for the specified type (such as 'processing', 'downloading') """ if type == 'processing': recoveredDict = Hellanzb.recoveredState.getRecoveredDict(type, target) archiveDir = os.path.join(Hellanzb.PROCESSING_DIR, target) if recoveredDict and recoveredDict.get('nzbFileName') is not None: target = recoveredDict.get('nzbFileName') else: # If this is a processing recovery request, and we didn't recover any # state information, we'll consider this a basic Archive object (it has no # accompanying .NZB file to keep track of) return Archive.fromStateXML(archiveDir, recoveredDict) else: recoveredDict = Hellanzb.recoveredState.getRecoveredDict(type, archiveName(target)) # Pass the id in with the constructor (instead of setting it after the fact) -- # otherwise the constructor would unnecessarily incremenet the IDPool nzbId = None if recoveredDict: nzbId = recoveredDict['id'] nzb = NZB(target, nzbId) if type == 'processing': nzb.archiveDir = archiveDir if recoveredDict: for key, value in recoveredDict.iteritems(): if key == 'id' or key == 'order': continue if key == 'neededBlocks': value = int(value) if key == 'totalBytes': nzb.calculatingBytes = False value = int(value) if key == 'downloadTime': value = float(value) if key == 'parType': value = getParEnum(value) setattr(nzb, key, value) return nzb
def getStateAttribs(self): """ Return attributes to be written out to the """ attribs = Archive.getStateAttribs(self) # NZBs in isParRecovery mode need the par recovery state written if self.isParRecovery: attribs['isParRecovery'] = 'True' for attrib in ('neededBlocks', 'parPrefix'): val = getattr(self, attrib) if isinstance(val, int): val = str(val) attribs[attrib] = toUnicode(val) attribs['parType'] = getParName(self.parType) if self.downloadTime: attribs['downloadTime'] = str(self.downloadTime) if not self.calculatingBytes and self.totalBytes > 0: attribs['totalBytes'] = str(self.totalBytes) if self.category: attribs['category'] = self.category return attribs
def getStateAttribs(self): """ Return attributes to be written out to the """ attribs = Archive.getStateAttribs(self) # NZBs in isParRecovery mode need the par recovery state written if self.isParRecovery: attribs["isParRecovery"] = "True" for attrib in ("neededBlocks", "parPrefix"): val = getattr(self, attrib) if isinstance(val, int): val = str(val) attribs[attrib] = toUnicode(val) attribs["parType"] = getParName(self.parType) if self.downloadTime: attribs["downloadTime"] = str(self.downloadTime) if not self.calculatingBytes and self.totalBytes > 0: attribs["totalBytes"] = str(self.totalBytes) if self.category: attribs["category"] = self.category return attribs
def __init__(self, nzbFileName, id=None, rarPassword=None, archiveDir=None, category=''): Archive.__init__(self, archiveDir, id, None, rarPassword) ## NZB file general information self.nzbFileName = nzbFileName self.archiveName = archiveName(self.nzbFileName) # pretty name self.msgid = None filename = os.path.basename(nzbFileName) self.msgid = getMsgId(filename) if self.msgid: self.msgid = int(self.msgid) self.nzbFiles = [] self.skippedParFiles = [] self.category = category ## Where the nzb files will be downloaded self.destDir = Hellanzb.WORKING_DIR ## A cancelled NZB is marked for death. ArticleDecoder will dispose of any ## recently downloaded data that might have been downloading during the time the ## cancel call was made (after the fact cleanup) self.canceled = False self.canceledLock = Lock() ## Acquired during assembly of an NZBFile self.assembleLock = Lock() ## Total bytes this NZB represents self.totalBytes = 0 ## Whether the total byte count of this NZB is still being calculated self.calculatingBytes = True ## How many bytes were skipped for downloading self.totalSkippedBytes = 0 ## How many bytes have been downloaded for this NZB self.totalReadBytes = 0 ## How many bytes of encoded article data is currently cached to memory self.cachedArticleDataBytes = 0 ## Time this NZB began downloading self.downloadStartTime = None ## Amount of time taken to download the NZB self.downloadTime = 0 ## Amount of time taken to download AND decode the NZB self.downloadAndDecodeTime = 0 ## Whether or not we should redownload NZBFile and NZBSegment files on disk that ## are 0 bytes in size self.overwriteZeroByteFiles = True # All segment0001s are downloaded first. Every time we successfully decode a # segment0001, we add to this number self.firstSegmentsDownloaded = 0 ## Whether or not this NZB is downloading in par recovery mode self.isParRecovery = False ## Whether or not this is an NZB that contains all par files self.allParsMode = False ## Skipped par file's subjects are kept here, in a list, during post ## processing. This list is arranged by the file's size self.skippedParSubjects = None ## The number of par blocks (or par files for par1 mode), queued to download ## recovery blocks, the par version, and the par prefix for the current par ## recovery download self.neededBlocks = 0 self.queuedBlocks = 0 self.parType = None self.parPrefix = None
def __init__(self, nzbFileName, id = None, rarPassword = None, archiveDir = None, category = ''): Archive.__init__(self, archiveDir, id, None, rarPassword) ## NZB file general information self.nzbFileName = nzbFileName self.archiveName = archiveName(self.nzbFileName) # pretty name self.msgid = None filename = os.path.basename(nzbFileName) self.msgid = getMsgId(filename) if self.msgid: self.msgid = int(self.msgid) self.nzbFiles = [] self.skippedParFiles = [] self.category = category ## Where the nzb files will be downloaded self.destDir = Hellanzb.WORKING_DIR ## A cancelled NZB is marked for death. ArticleDecoder will dispose of any ## recently downloaded data that might have been downloading during the time the ## cancel call was made (after the fact cleanup) self.canceled = False self.canceledLock = Lock() ## Acquired during assembly of an NZBFile self.assembleLock = Lock() ## Total bytes this NZB represents self.totalBytes = 0 ## Whether the total byte count of this NZB is still being calculated self.calculatingBytes = True ## How many bytes were skipped for downloading self.totalSkippedBytes = 0 ## How many bytes have been downloaded for this NZB self.totalReadBytes = 0 ## How many bytes of encoded article data is currently cached to memory self.cachedArticleDataBytes = 0 ## Time this NZB began downloading self.downloadStartTime = None ## Amount of time taken to download the NZB self.downloadTime = 0 ## Amount of time taken to download AND decode the NZB self.downloadAndDecodeTime = 0 ## Whether or not we should redownload NZBFile and NZBSegment files on disk that ## are 0 bytes in size self.overwriteZeroByteFiles = True # All segment0001s are downloaded first. Every time we successfully decode a # segment0001, we add to this number self.firstSegmentsDownloaded = 0 ## Whether or not this NZB is downloading in par recovery mode self.isParRecovery = False ## Whether or not this is an NZB that contains all par files self.allParsMode = False ## Skipped par file's subjects are kept here, in a list, during post ## processing. This list is arranged by the file's size self.skippedParSubjects = None ## The number of par blocks (or par files for par1 mode), queued to download ## recovery blocks, the par version, and the par prefix for the current par ## recovery download self.neededBlocks = 0 self.queuedBlocks = 0 self.parType = None self.parPrefix = None