Esempio n. 1
0
def listQueue(includeIds=True, convertToUnicode=True):
    """ Return a listing of the current queue. By default this function will convert all
    strings to unicode, as it's only used right now for the return of XMLRPC calls """
    members = []
    for nzb in Hellanzb.nzbQueue:
        if includeIds:
            name = archiveName(os.path.basename(nzb.nzbFileName))
            rarPassword = nzb.rarPassword

            if convertToUnicode:
                name = toUnicode(name)
                rarPassword = toUnicode(rarPassword)

            member = {
                'id': nzb.id,
                'nzbName': name,
                'is_par_recovery': nzb.isParRecovery
            }

            if rarPassword is not None:
                member['rarPassword'] = rarPassword
            if nzb.msgid is not None:
                member['msgid'] = nzb.msgid
            if not nzb.calculatingBytes:
                member['total_mb'] = nzb.totalBytes / 1024 / 1024
        else:
            member = os.path.basename(nzb.nzbFileName)
        members.append(member)
    return members
Esempio n. 2
0
def listQueue(includeIds=True, convertToUnicode=True):
    """ Return a listing of the current queue. By default this function will convert all
    strings to unicode, as it's only used right now for the return of XMLRPC calls """
    members = []
    for nzb in Hellanzb.nzbQueue:
        if includeIds:
            name = archiveName(os.path.basename(nzb.nzbFileName))
            rarPassword = nzb.rarPassword

            if convertToUnicode:
                name = toUnicode(name)
                rarPassword = toUnicode(rarPassword)

            member = {"id": nzb.id, "nzbName": name, "is_par_recovery": nzb.isParRecovery}

            if rarPassword is not None:
                member["rarPassword"] = rarPassword
            if nzb.msgid is not None:
                member["msgid"] = nzb.msgid
            if not nzb.calculatingBytes:
                member["total_mb"] = nzb.totalBytes / 1024 / 1024
        else:
            member = os.path.basename(nzb.nzbFileName)
        members.append(member)
    return members
Esempio n. 3
0
def findAndLoadPostponedDir(nzb):
    """ Move a postponed working directory for the specified nzb, if one is found, to the
    WORKING_DIR """
    def fixNZBFileName(nzb):
        if os.path.normpath(os.path.dirname(nzb.destDir)) == os.path.normpath(
                Hellanzb.POSTPONED_DIR):
            nzb.destDir = Hellanzb.WORKING_DIR

    nzbfilename = nzb.nzbFileName
    d = os.path.join(Hellanzb.POSTPONED_DIR, archiveName(nzbfilename))
    if os.path.isdir(d):
        try:
            os.rmdir(Hellanzb.WORKING_DIR)
        except OSError:
            files = os.listdir(Hellanzb.WORKING_DIR)[0]
            if len(files):
                name = files[0]
                ext = getFileExtension(name)
                if ext != None:
                    name = name.replace(ext, '')
                move(Hellanzb.WORKING_DIR,
                     os.path.join(Hellanzb.TEMP_DIR, name))

            else:
                debug('ERROR Stray WORKING_DIR!: ' +
                      str(os.listdir(Hellanzb.WORKING_DIR)))
                name = os.path.join(Hellanzb.TEMP_DIR, 'stray_WORKING_DIR')
                hellaRename(name)
                move(Hellanzb.WORKING_DIR, name)

        move(d, Hellanzb.WORKING_DIR)
        Hellanzb.queue.unpostpone(nzb)
        ensureSafePostponedLoad(nzb.nzbFileName)

        info('Loaded postponed directory: ' + archiveName(nzbfilename))

        fixNZBFileName(nzb)
        return True
    else:
        fixNZBFileName(nzb)
        return False
Esempio n. 4
0
def findAndLoadPostponedDir(nzb):
    """ Move a postponed working directory for the specified nzb, if one is found, to the
    WORKING_DIR """

    def fixNZBFileName(nzb):
        if os.path.normpath(os.path.dirname(nzb.destDir)) == os.path.normpath(Hellanzb.POSTPONED_DIR):
            nzb.destDir = Hellanzb.WORKING_DIR

    nzbfilename = nzb.nzbFileName
    d = os.path.join(Hellanzb.POSTPONED_DIR, archiveName(nzbfilename))
    if os.path.isdir(d):
        try:
            os.rmdir(Hellanzb.WORKING_DIR)
        except OSError:
            files = os.listdir(Hellanzb.WORKING_DIR)[0]
            if len(files):
                name = files[0]
                ext = getFileExtension(name)
                if ext != None:
                    name = name.replace(ext, "")
                move(Hellanzb.WORKING_DIR, os.path.join(Hellanzb.TEMP_DIR, name))

            else:
                debug("ERROR Stray WORKING_DIR!: " + str(os.listdir(Hellanzb.WORKING_DIR)))
                name = os.path.join(Hellanzb.TEMP_DIR, "stray_WORKING_DIR")
                hellaRename(name)
                move(Hellanzb.WORKING_DIR, name)

        move(d, Hellanzb.WORKING_DIR)
        Hellanzb.queue.unpostpone(nzb)
        ensureSafePostponedLoad(nzb.nzbFileName)

        info("Loaded postponed directory: " + archiveName(nzbfilename))

        fixNZBFileName(nzb)
        return True
    else:
        fixNZBFileName(nzb)
        return False
Esempio n. 5
0
 def unpostpone(self, nzb):
     """ Recall a postponed NZB """
     self.nzbFilesLock.acquire()
     arName = archiveName(nzb.nzbFileName)
     found = []
     for nzbFile in self.postponedNzbFiles:
         # FIXME:
         # Why is this not nzbFile.nzb == nzb?
         if nzbFile.nzb.archiveName == arName:
             found.append(nzbFile)
     for nzbFile in found:
         self.postponedNzbFiles.remove(nzbFile)
     self.nzbFilesLock.release()
Esempio n. 6
0
def resumePostProcessors():
    """ Pickup left off Post Processors that were cancelled via CTRL-C """
    # FIXME: with the new queue, could kill the processing dir sym links (for windows)
    from Hellanzb.NZBLeecher.NZBModel import NZB
    for archiveDirName in os.listdir(Hellanzb.PROCESSING_DIR):
        if archiveDirName[0] == '.':
            continue
        
        archive = NZB.fromStateXML('processing', archiveDirName)
        troll = PostProcessor.PostProcessor(archive)

        info('Resuming post processor: ' + archiveName(archiveDirName))
        troll.start()
Esempio n. 7
0
 def unpostpone(self, nzb):
     """ Recall a postponed NZB """
     self.nzbFilesLock.acquire()
     arName = archiveName(nzb.nzbFileName)
     found = []
     for nzbFile in self.postponedNzbFiles:
         # FIXME:
         # Why is this not nzbFile.nzb == nzb?
         if nzbFile.nzb.archiveName == arName:
             found.append(nzbFile)
     for nzbFile in found:
         self.postponedNzbFiles.remove(nzbFile)
     self.nzbFilesLock.release()
Esempio n. 8
0
    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
Esempio n. 9
0
    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
Esempio n. 10
0
    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
Esempio n. 11
0
    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