Exemplo n.º 1
0
 def versionUpdate(self):
     try:
         if sabnzbd.NEW_VERSION and self.version_notify:
             #logging.info("[osx] New Version : %s" % (sabnzbd.NEW_VERSION))
             new_release, new_rel_url = sabnzbd.NEW_VERSION.split(';')
             osx.sendGrowlMsg("SABnzbd","%s : %s" % (T('New release available'),new_release),osx.NOTIFICATION['other'])
             self.version_notify = 0
     except :
         logging.info("[osx] versionUpdate Exception %s" % (sys.exc_info()[0]))
Exemplo n.º 2
0
def parring(nzo, workdir):
    """ Perform par processing. Returns: (par_error, re_add)
    """
    filename = nzo.final_name
    osx.sendGrowlMsg(T('Post-processing'), nzo.final_name,
                     osx.NOTIFICATION['pp'])
    logging.info('Par2 check starting on %s', filename)

    ## Collect the par files
    if nzo.partable:
        par_table = nzo.partable.copy()
    else:
        par_table = {}
    repair_sets = par_table.keys()

    re_add = False
    par_error = False

    if repair_sets:

        for set_ in repair_sets:
            logging.info("Running repair on set %s", set_)
            parfile_nzf = par_table[set_]
            need_re_add, res = par2_repair(parfile_nzf, nzo, workdir, set_)
            if need_re_add:
                re_add = True
            else:
                par_error = par_error or not res

        if re_add:
            logging.info('Readded %s to queue', filename)
            nzo.priority = REPAIR_PRIORITY
            sabnzbd.nzbqueue.add_nzo(nzo)
            sabnzbd.downloader.Downloader.do.resume_from_postproc()

        logging.info('Par2 check finished on %s', filename)

    else:
        # See if alternative SFV check is possible
        sfv = None
        if cfg.sfv_check():
            for sfv in globber(workdir, '*.sfv'):
                par_error = par_error or not sfv_check(sfv)
            if par_error:
                nzo.set_unpack_info(
                    'Repair',
                    T('Some files failed to verify against "%s"') %
                    unicoder(os.path.basename(sfv)))

        if not sfv:
            logging.info("No par2 sets for %s", filename)
            nzo.set_unpack_info('Repair',
                                T('[%s] No par2 sets') % unicoder(filename))

    return par_error, re_add
Exemplo n.º 3
0
    def run(self):
        """ Process the queue (including waits and retries) """
        from sabnzbd.nzbqueue import NzbQueue
        def sleeper(delay):
            for n in range(delay):
                if not self.shutdown:
                    time.sleep(1.05)

        self.shutdown = False
        msgid = None
        while not self.shutdown:
            if not msgid:
                (msgid, nzo) = self.queue.get()
                if self.shutdown or not msgid:
                    break
            logging.debug("Popping msgid %s", msgid)

            filename, data, newzbin_cat, nzo_info = _grabnzb(msgid)
            if filename and data:
                filename = name_fixer(filename)

                pp = nzo.pp
                script = nzo.script
                cat = nzo.cat
                if cat == '*' or not cat:
                    cat = cat_convert(newzbin_cat)

                priority = nzo.priority
                nzbname = nzo.custom_name

                cat, pp, script, priority = cat_to_opts(cat, pp, script, priority)

                try:
                    sabnzbd.nzbqueue.insert_future_nzo(nzo, filename, msgid, data, pp=pp, script=script, cat=cat, priority=priority, nzbname=nzbname, nzo_info=nzo_info)
                except:
                    logging.error(Ta('Failed to update newzbin job %s'), msgid)
                    logging.info("Traceback: ", exc_info = True)

                    NzbQueue.do.remove(nzo.nzo_id, False)
                msgid = None
            else:
                if filename:
                    sleeper(int(filename))
                else:
                    # Fatal error, give up on this one
                    bad_fetch(nzo, msgid, msg=nzo_info, retry=True)
                    msgid = None

            osx.sendGrowlMsg(T('NZB added to queue'),filename,osx.NOTIFICATION['download'])

            # Keep some distance between the grabs
            sleeper(5)

        logging.debug('Stopping MSGIDGrabber')
Exemplo n.º 4
0
    def add(self, nzo, save=True, quiet=False):
        assert isinstance(nzo, NzbObject)
        if not nzo.nzo_id:
            nzo.nzo_id = sabnzbd.get_new_id('nzo', nzo.workpath, self.__nzo_table)

        # If no files are to be downloaded anymore, send to postproc
        if not nzo.files and not nzo.futuretype:
            sabnzbd.remove_data(nzo.nzo_id, nzo.workpath)
            sabnzbd.proxy_postproc(nzo)
            return

        # Reset try_lists
        nzo.reset_try_list()
        self.reset_try_list()

        if nzo.nzo_id:
            nzo.deleted = False
            priority = nzo.priority
            self.__nzo_table[nzo.nzo_id] = nzo
            if priority > HIGH_PRIORITY:
                #Top and repair priority items are added to the top of the queue
                self.__nzo_list.insert(0, nzo)
            elif priority == LOW_PRIORITY:
                self.__nzo_list.append(nzo)
            else:
                #for high priority we need to add the item at the bottom
                #of any other high priority items above the normal priority
                #for normal priority we need to add the item at the bottom
                #of the normal priority items above the low priority
                if self.__nzo_list:
                    pos = 0
                    added = False
                    for position in self.__nzo_list:
                        if position.priority < priority:
                            self.__nzo_list.insert(pos, nzo)
                            added = True
                            break
                        pos += 1
                    if not added:
                        #if there are no other items classed as a lower priority
                        #then it will be added to the bottom of the queue
                        self.__nzo_list.append(nzo)
                else:
                    #if the queue is empty then simple append the item to the bottom
                    self.__nzo_list.append(nzo)
            if save:
                self.save(nzo)

            if not (quiet or nzo.status in ('Fetching',)):
                osx.sendGrowlMsg(T('NZB added to queue'), nzo.filename, osx.NOTIFICATION['download'])

        if cfg.auto_sort():
            self.sort_by_avg_age()
Exemplo n.º 5
0
 def versionUpdate(self):
     try:
         if sabnzbd.NEW_VERSION and self.version_notify:
             #logging.info("[osx] New Version : %s" % (sabnzbd.NEW_VERSION))
             new_release, new_rel_url = sabnzbd.NEW_VERSION.split(';')
             osx.sendGrowlMsg(
                 "SABnzbd",
                 "%s : %s" % (T('New release available'), new_release),
                 osx.NOTIFICATION['other'])
             self.version_notify = 0
     except:
         logging.info("[osx] versionUpdate Exception %s" %
                      (sys.exc_info()[0]))
Exemplo n.º 6
0
 def pause(self, save=True):
     """ Pause the downloader, optionally saving admin
     """
     if not self.paused:
         self.paused = True
         logging.info("Pausing")
         osx.sendGrowlMsg("SABnzbd",T('Paused'),osx.NOTIFICATION['download'])
         if self.is_paused():
             BPSMeter.do.reset()
         if cfg.autodisconnect():
             self.disconnect()
         if save:
             sabnzbd.save_state()
Exemplo n.º 7
0
 def applicationShouldTerminate_(self, sender):
     logging.info('[osx] application terminating')
     self.setMenuTitle("\n\n%s\n"% (T('Stopping...')))
     self.status_item.setHighlightMode_(NO)
     sabnzbd.OSX_ICON = 0
     logging.info('[osx] application stopping daemon')
     sabnzbd.halt()
     cherrypy.engine.exit()
     sabnzbd.SABSTOP = True
     osx.sendGrowlMsg('SABnzbd',T('SABnzbd shutdown finished'),osx.NOTIFICATION['other'])
     logging.info('Leaving SABnzbd')
     sys.stderr.flush()
     sys.stdout.flush()
     return NSTerminateNow
Exemplo n.º 8
0
def parring(nzo, workdir):
    """ Perform par processing. Returns: (par_error, re_add)
    """
    filename = nzo.final_name
    osx.sendGrowlMsg(T('Post-processing'), nzo.final_name, osx.NOTIFICATION['pp'])
    logging.info('Par2 check starting on %s', filename)

    ## Collect the par files
    if nzo.partable:
        par_table = nzo.partable.copy()
    else:
        par_table = {}
    repair_sets = par_table.keys()

    re_add = False
    par_error = False

    if repair_sets:

        for set_ in repair_sets:
            logging.info("Running repair on set %s", set_)
            parfile_nzf = par_table[set_]
            need_re_add, res = par2_repair(parfile_nzf, nzo, workdir, set_)
            if need_re_add:
                re_add = True
            else:
                par_error = par_error or not res

        if re_add:
            logging.info('Readded %s to queue', filename)
            nzo.priority = REPAIR_PRIORITY
            sabnzbd.nzbqueue.add_nzo(nzo)
            sabnzbd.downloader.Downloader.do.resume_from_postproc()

        logging.info('Par2 check finished on %s', filename)

    else:
        # See if alternative SFV check is possible
        sfv = None
        if cfg.sfv_check():
            for sfv in globber(workdir, '*.sfv'):
                par_error = par_error or not sfv_check(sfv)
            if par_error:
                nzo.set_unpack_info('Repair', T('Some files failed to verify against "%s"') % unicoder(os.path.basename(sfv)))

        if not sfv:
            logging.info("No par2 sets for %s", filename)
            nzo.set_unpack_info('Repair', T('[%s] No par2 sets') % unicoder(filename))

    return par_error, re_add
Exemplo n.º 9
0
 def pause(self, save=True):
     """ Pause the downloader, optionally saving admin
     """
     if not self.paused:
         self.paused = True
         logging.info("Pausing")
         osx.sendGrowlMsg("SABnzbd", T('Paused'),
                          osx.NOTIFICATION['download'])
         if self.is_paused():
             BPSMeter.do.reset()
         if cfg.autodisconnect():
             self.disconnect()
         if save:
             sabnzbd.save_state()
Exemplo n.º 10
0
 def applicationShouldTerminate_(self, sender):
     logging.info('[osx] application terminating')
     self.setMenuTitle("\n\n%s\n" % (T('Stopping...')))
     self.status_item.setHighlightMode_(NO)
     sabnzbd.OSX_ICON = 0
     logging.info('[osx] application stopping daemon')
     sabnzbd.halt()
     cherrypy.engine.exit()
     sabnzbd.SABSTOP = True
     osx.sendGrowlMsg('SABnzbd', T('SABnzbd shutdown finished'),
                      osx.NOTIFICATION['other'])
     logging.info('Leaving SABnzbd')
     sys.stderr.flush()
     sys.stdout.flush()
     return NSTerminateNow
Exemplo n.º 11
0
def process_job(nzo):
    """ Process one job """
    assert isinstance(nzo, sabnzbd.nzbstuff.NzbObject)
    start = time.time()

    # keep track of whether we can continue
    all_ok = True
    # keep track of par problems
    par_error = False
    # keep track of any unpacking errors
    unpack_error = False
    nzb_list = []
    # These need to be initialised incase of a crash
    workdir_complete = ''
    postproc_time = 0
    script_log = ''
    script_line = ''
    crash_msg = ''

    ## Get the job flags
    nzo.save_attribs()
    flag_repair, flag_unpack, flag_delete = nzo.repair_opts
    # Normalize PP
    if flag_delete: flag_unpack = True
    if flag_unpack: flag_repair = True

    # Get the NZB name
    filename = nzo.final_name
    msgid = nzo.msgid

    if cfg.allow_streaming() and not (flag_repair or flag_unpack or flag_delete):
        # After streaming, force +D
        nzo.set_pp(3)
        nzo.status = 'Failed'
        nzo.save_attribs()
        all_ok = False

    try:

        # Get the folder containing the download result
        workdir = nzo.downpath
        tmp_workdir_complete = None

        # if no files are present (except __admin__), fail the job
        if len(globber(workdir)) < 2:
            emsg = T('Download failed - Out of your server\'s retention?')
            nzo.fail_msg = emsg
            nzo.status = 'Failed'
            # do not run unpacking or parity verification
            flag_repair = flag_unpack = False
            par_error = unpack_error = True
            all_ok = False

        script = nzo.script
        cat = nzo.cat

        logging.info('Starting PostProcessing on %s' + \
                     ' => Repair:%s, Unpack:%s, Delete:%s, Script:%s, Cat:%s',
                     filename, flag_repair, flag_unpack, flag_delete, script, cat)

        ## Par processing, if enabled
        if flag_repair:
            par_error, re_add = parring(nzo, workdir)
            if re_add:
                # Try to get more par files
                return False

        ## Check if user allows unsafe post-processing
        if flag_repair and cfg.safe_postproc():
            all_ok = all_ok and not par_error

        # Set complete dir to workdir in case we need to abort
        workdir_complete = workdir
        dirname = nzo.final_name

        if all_ok:
            one_folder = False
            ## Determine class directory
            if cfg.create_group_folders():
                complete_dir = addPrefixes(cfg.complete_dir.get_path(), nzo.dirprefix)
                complete_dir = create_dirs(complete_dir)
            else:
                catdir = config.get_categories(cat).dir()
                if catdir.endswith('*'):
                    catdir = catdir.strip('*')
                    one_folder = True
                complete_dir = real_path(cfg.complete_dir.get_path(), catdir)

            ## TV/Movie/Date Renaming code part 1 - detect and construct paths
            file_sorter = Sorter(cat)
            complete_dir = file_sorter.detect(dirname, complete_dir)
            if file_sorter.is_sortfile():
                one_folder = False

            if one_folder:
                workdir_complete = create_dirs(complete_dir)
            else:
                workdir_complete = get_unique_path(os.path.join(complete_dir, dirname), create_dir=True)
            if not workdir_complete or not os.path.exists(workdir_complete):
                crash_msg = T('Cannot create final folder %s') % unicoder(os.path.join(complete_dir, dirname))
                raise IOError

            if cfg.folder_rename() and not one_folder:
                tmp_workdir_complete = prefix(workdir_complete, '_UNPACK_')
                try:
                    renamer(workdir_complete, tmp_workdir_complete)
                except:
                    pass # On failure, just use the original name
            else:
                tmp_workdir_complete = workdir_complete

            newfiles = []
            ## Run Stage 2: Unpack
            if flag_unpack:
                if all_ok:
                    #set the current nzo status to "Extracting...". Used in History
                    nzo.status = 'Extracting'
                    logging.info("Running unpack_magic on %s", filename)
                    unpack_error, newfiles = unpack_magic(nzo, workdir, tmp_workdir_complete, flag_delete, one_folder, (), (), (), ())
                    logging.info("unpack_magic finished on %s", filename)
                else:
                    nzo.set_unpack_info('Unpack', T('No post-processing because of failed verification'))

            if cfg.safe_postproc():
                all_ok = all_ok and not unpack_error

            if all_ok:
                ## Move any (left-over) files to destination
                nzo.status = 'Moving'
                nzo.set_action_line(T('Moving'), '...')
                for root, dirs, files in os.walk(workdir):
                    if not root.endswith(JOB_ADMIN):
                        for file_ in files:
                            path = os.path.join(root, file_)
                            new_path = path.replace(workdir, tmp_workdir_complete)
                            new_path = get_unique_filename(new_path)
                            move_to_path(path, new_path, unique=False)

            ## Set permissions right
            if not sabnzbd.WIN32:
                perm_script(tmp_workdir_complete, cfg.umask())

            if all_ok:
                ## Remove files matching the cleanup list
                cleanup_list(tmp_workdir_complete, True)

                ## Check if this is an NZB-only download, if so redirect to queue
                ## except when PP was Download-only
                if flag_repair:
                    nzb_list = nzb_redirect(tmp_workdir_complete, nzo.final_name, nzo.pp, script, cat, priority=nzo.priority)
                else:
                    nzb_list = None
                if nzb_list:
                    nzo.set_unpack_info('Download', T('Sent %s to queue') % unicoder(nzb_list))
                    try:
                        remove_dir(tmp_workdir_complete)
                    except:
                        pass
                else:
                    cleanup_list(tmp_workdir_complete, False)

        script_output = ''
        script_ret = 0
        if not nzb_list:
            ## Give destination its final name
            if cfg.folder_rename() and tmp_workdir_complete and not one_folder:
                if not all_ok:
                    workdir_complete = tmp_workdir_complete.replace('_UNPACK_', '_FAILED_')
                    workdir_complete = get_unique_path(workdir_complete, n=0, create_dir=False)
                try:
                    collapse_folder(tmp_workdir_complete, workdir_complete)
                except:
                    logging.error(Ta('Error renaming "%s" to "%s"'), tmp_workdir_complete, workdir_complete)
                    logging.info("Traceback: ", exc_info = True)

            job_result = int(par_error) + int(unpack_error)*2

            if cfg.ignore_samples() > 0:
                remove_samples(workdir_complete)

            ## TV/Movie/Date Renaming code part 2 - rename and move files to parent folder
            if all_ok:
                if newfiles and file_sorter.is_sortfile():
                    file_sorter.rename(newfiles, workdir_complete)
                    workdir_complete = file_sorter.move(workdir_complete)

            ## Run the user script
            script_path = make_script_path(script)
            if all_ok and (not nzb_list) and script_path:
                #set the current nzo status to "Ext Script...". Used in History
                nzo.status = 'Running'
                nzo.set_action_line(T('Running script'), unicoder(script))
                nzo.set_unpack_info('Script', T('Running user script %s') % unicoder(script), unique=True)
                script_log, script_ret = external_processing(script_path, workdir_complete, nzo.filename,
                                                             msgid, dirname, cat, nzo.group, job_result)
                script_line = get_last_line(script_log)
                if script_log:
                    script_output = nzo.nzo_id
                if script_line:
                    nzo.set_unpack_info('Script', unicoder(script_line), unique=True)
                else:
                    nzo.set_unpack_info('Script', T('Ran %s') % unicoder(script), unique=True)
            else:
                script = ""
                script_line = ""
                script_ret = 0

        ## Email the results
        if (not nzb_list) and cfg.email_endjob():
            if (cfg.email_endjob() == 1) or (cfg.email_endjob() == 2 and (unpack_error or par_error)):
                emailer.endjob(dirname, msgid, cat, all_ok, workdir_complete, nzo.bytes_downloaded,
                               nzo.unpack_info, script, TRANS(script_log), script_ret)

        if script_output:
            # Can do this only now, otherwise it would show up in the email
            if script_ret:
                script_ret = 'Exit(%s) ' % script_ret
            else:
                script_ret = ''
            if script_line:
                nzo.set_unpack_info('Script',
                                    u'%s%s <a href="./scriptlog?name=%s">(%s)</a>' % (script_ret, unicoder(script_line), urllib.quote(script_output),
                                     T('More')), unique=True)
            else:
                nzo.set_unpack_info('Script',
                                    u'%s<a href="./scriptlog?name=%s">%s</a>' % (script_ret, urllib.quote(script_output),
                                    T('View script output')), unique=True)

        ## Cleanup again, including NZB files
        cleanup_list(workdir_complete, False)

        ## Remove newzbin bookmark, if any
        if msgid and all_ok:
            Bookmarks.do.del_bookmark(msgid)
        elif all_ok:
            sabnzbd.proxy_rm_bookmark(nzo.url)

        ## Show final status in history
        if all_ok:
            osx.sendGrowlMsg(T('Download Completed'), filename, osx.NOTIFICATION['complete'])
            nzo.status = 'Completed'
        else:
            osx.sendGrowlMsg(T('Download Failed'), filename, osx.NOTIFICATION['complete'])
            nzo.status = 'Failed'

    except:
        logging.error(Ta('Post Processing Failed for %s (%s)'), filename, crash_msg)
        if not crash_msg:
            logging.info("Traceback: ", exc_info = True)
            crash_msg = T('see logfile')
        nzo.fail_msg = T('PostProcessing was aborted (%s)') % unicoder(crash_msg)
        osx.sendGrowlMsg(T('Download Failed'), filename, osx.NOTIFICATION['complete'])
        nzo.status = 'Failed'
        par_error = True
        all_ok = False

    if all_ok:
        # If the folder only contains one file OR folder, have that as the path
        # Be aware that series/generic/date sorting may move a single file into a folder containing other files
        workdir_complete = one_file_or_folder(workdir_complete)
        workdir_complete = os.path.normpath(workdir_complete)

    # Log the overall time taken for postprocessing
    postproc_time = int(time.time() - start)

    # Create the history DB instance
    history_db = database.get_history_handle()
    # Add the nzo to the database. Only the path, script and time taken is passed
    # Other information is obtained from the nzo
    history_db.add_history_db(nzo, workdir_complete, nzo.downpath, postproc_time, script_log, script_line)
    # The connection is only used once, so close it here
    history_db.close()

    ## Clean up the NZO
    try:
        logging.info('Cleaning up %s (keep_basic=%s)', filename, str(not all_ok))
        sabnzbd.nzbqueue.NzbQueue.do.cleanup_nzo(nzo, keep_basic=not all_ok)
    except:
        logging.error(Ta('Cleanup of %s failed.'), nzo.final_name)
        logging.info("Traceback: ", exc_info = True)

    ## Remove download folder
    if all_ok:
        try:
            if os.path.exists(workdir):
                logging.debug('Removing workdir %s', workdir)
                remove_all(os.path.join(workdir, JOB_ADMIN))
                remove_dir(workdir)
        except:
            logging.error(Ta('Error removing workdir (%s)'), workdir)
            logging.info("Traceback: ", exc_info = True)

    return True
Exemplo n.º 12
0
def process_job(nzo):
    """ Process one job """
    assert isinstance(nzo, sabnzbd.nzbstuff.NzbObject)
    start = time.time()

    # keep track of whether we can continue
    all_ok = True
    # keep track of par problems
    par_error = False
    # keep track of any unpacking errors
    unpack_error = False
    nzb_list = []
    # These need to be initialised incase of a crash
    workdir_complete = ''
    postproc_time = 0
    script_log = ''
    script_line = ''
    crash_msg = ''

    ## Get the job flags
    nzo.save_attribs()
    flag_repair, flag_unpack, flag_delete = nzo.repair_opts
    # Normalize PP
    if flag_delete: flag_unpack = True
    if flag_unpack: flag_repair = True

    # Get the NZB name
    filename = nzo.final_name
    msgid = nzo.msgid

    if cfg.allow_streaming() and not (flag_repair or flag_unpack
                                      or flag_delete):
        # After streaming, force +D
        nzo.set_pp(3)
        nzo.status = 'Failed'
        nzo.save_attribs()
        all_ok = False

    try:

        # Get the folder containing the download result
        workdir = nzo.downpath
        tmp_workdir_complete = None

        # if no files are present (except __admin__), fail the job
        if len(globber(workdir)) < 2:
            emsg = T('Download failed - Out of your server\'s retention?')
            nzo.fail_msg = emsg
            nzo.status = 'Failed'
            # do not run unpacking or parity verification
            flag_repair = flag_unpack = False
            par_error = unpack_error = True
            all_ok = False

        script = nzo.script
        cat = nzo.cat

        logging.info('Starting PostProcessing on %s' + \
                     ' => Repair:%s, Unpack:%s, Delete:%s, Script:%s, Cat:%s',
                     filename, flag_repair, flag_unpack, flag_delete, script, cat)

        ## Par processing, if enabled
        if flag_repair:
            par_error, re_add = parring(nzo, workdir)
            if re_add:
                # Try to get more par files
                return False

        ## Check if user allows unsafe post-processing
        if flag_repair and cfg.safe_postproc():
            all_ok = all_ok and not par_error

        # Set complete dir to workdir in case we need to abort
        workdir_complete = workdir
        dirname = nzo.final_name

        if all_ok:
            one_folder = False
            ## Determine class directory
            if cfg.create_group_folders():
                complete_dir = addPrefixes(cfg.complete_dir.get_path(),
                                           nzo.dirprefix)
                complete_dir = create_dirs(complete_dir)
            else:
                catdir = config.get_categories(cat).dir()
                if catdir.endswith('*'):
                    catdir = catdir.strip('*')
                    one_folder = True
                complete_dir = real_path(cfg.complete_dir.get_path(), catdir)

            ## TV/Movie/Date Renaming code part 1 - detect and construct paths
            file_sorter = Sorter(cat)
            complete_dir = file_sorter.detect(dirname, complete_dir)
            if file_sorter.is_sortfile():
                one_folder = False

            if one_folder:
                workdir_complete = create_dirs(complete_dir)
            else:
                workdir_complete = get_unique_path(os.path.join(
                    complete_dir, dirname),
                                                   create_dir=True)
            if not workdir_complete or not os.path.exists(workdir_complete):
                crash_msg = T('Cannot create final folder %s') % unicoder(
                    os.path.join(complete_dir, dirname))
                raise IOError

            if cfg.folder_rename() and not one_folder:
                tmp_workdir_complete = prefix(workdir_complete, '_UNPACK_')
                try:
                    renamer(workdir_complete, tmp_workdir_complete)
                except:
                    pass  # On failure, just use the original name
            else:
                tmp_workdir_complete = workdir_complete

            newfiles = []
            ## Run Stage 2: Unpack
            if flag_unpack:
                if all_ok:
                    #set the current nzo status to "Extracting...". Used in History
                    nzo.status = 'Extracting'
                    logging.info("Running unpack_magic on %s", filename)
                    unpack_error, newfiles = unpack_magic(
                        nzo, workdir, tmp_workdir_complete, flag_delete,
                        one_folder, (), (), (), ())
                    logging.info("unpack_magic finished on %s", filename)
                else:
                    nzo.set_unpack_info(
                        'Unpack',
                        T('No post-processing because of failed verification'))

            if cfg.safe_postproc():
                all_ok = all_ok and not unpack_error

            if all_ok:
                ## Move any (left-over) files to destination
                nzo.status = 'Moving'
                nzo.set_action_line(T('Moving'), '...')
                for root, dirs, files in os.walk(workdir):
                    if not root.endswith(JOB_ADMIN):
                        for file_ in files:
                            path = os.path.join(root, file_)
                            new_path = path.replace(workdir,
                                                    tmp_workdir_complete)
                            new_path = get_unique_filename(new_path)
                            move_to_path(path, new_path, unique=False)

            ## Set permissions right
            if not sabnzbd.WIN32:
                perm_script(tmp_workdir_complete, cfg.umask())

            if all_ok:
                ## Remove files matching the cleanup list
                cleanup_list(tmp_workdir_complete, True)

                ## Check if this is an NZB-only download, if so redirect to queue
                ## except when PP was Download-only
                if flag_repair:
                    nzb_list = nzb_redirect(tmp_workdir_complete,
                                            nzo.final_name,
                                            nzo.pp,
                                            script,
                                            cat,
                                            priority=nzo.priority)
                else:
                    nzb_list = None
                if nzb_list:
                    nzo.set_unpack_info(
                        'Download',
                        T('Sent %s to queue') % unicoder(nzb_list))
                    try:
                        remove_dir(tmp_workdir_complete)
                    except:
                        pass
                else:
                    cleanup_list(tmp_workdir_complete, False)

        script_output = ''
        script_ret = 0
        if not nzb_list:
            ## Give destination its final name
            if cfg.folder_rename() and tmp_workdir_complete and not one_folder:
                if not all_ok:
                    workdir_complete = tmp_workdir_complete.replace(
                        '_UNPACK_', '_FAILED_')
                    workdir_complete = get_unique_path(workdir_complete,
                                                       n=0,
                                                       create_dir=False)
                try:
                    collapse_folder(tmp_workdir_complete, workdir_complete)
                except:
                    logging.error(Ta('Error renaming "%s" to "%s"'),
                                  tmp_workdir_complete, workdir_complete)
                    logging.info("Traceback: ", exc_info=True)

            job_result = int(par_error) + int(unpack_error) * 2

            if cfg.ignore_samples() > 0:
                remove_samples(workdir_complete)

            ## TV/Movie/Date Renaming code part 2 - rename and move files to parent folder
            if all_ok:
                if newfiles and file_sorter.is_sortfile():
                    file_sorter.rename(newfiles, workdir_complete)
                    workdir_complete = file_sorter.move(workdir_complete)

            ## Run the user script
            script_path = make_script_path(script)
            if all_ok and (not nzb_list) and script_path:
                #set the current nzo status to "Ext Script...". Used in History
                nzo.status = 'Running'
                nzo.set_action_line(T('Running script'), unicoder(script))
                nzo.set_unpack_info('Script',
                                    T('Running user script %s') %
                                    unicoder(script),
                                    unique=True)
                script_log, script_ret = external_processing(
                    script_path, workdir_complete, nzo.filename, msgid,
                    dirname, cat, nzo.group, job_result)
                script_line = get_last_line(script_log)
                if script_log:
                    script_output = nzo.nzo_id
                if script_line:
                    nzo.set_unpack_info('Script',
                                        unicoder(script_line),
                                        unique=True)
                else:
                    nzo.set_unpack_info('Script',
                                        T('Ran %s') % unicoder(script),
                                        unique=True)
            else:
                script = ""
                script_line = ""
                script_ret = 0

        ## Email the results
        if (not nzb_list) and cfg.email_endjob():
            if (cfg.email_endjob() == 1) or (cfg.email_endjob() == 2 and
                                             (unpack_error or par_error)):
                emailer.endjob(dirname, msgid, cat, all_ok, workdir_complete,
                               nzo.bytes_downloaded, nzo.unpack_info, script,
                               TRANS(script_log), script_ret)

        if script_output:
            # Can do this only now, otherwise it would show up in the email
            if script_ret:
                script_ret = 'Exit(%s) ' % script_ret
            else:
                script_ret = ''
            if script_line:
                nzo.set_unpack_info(
                    'Script',
                    u'%s%s <a href="./scriptlog?name=%s">(%s)</a>' %
                    (script_ret, unicoder(script_line),
                     urllib.quote(script_output), T('More')),
                    unique=True)
            else:
                nzo.set_unpack_info('Script',
                                    u'%s<a href="./scriptlog?name=%s">%s</a>' %
                                    (script_ret, urllib.quote(script_output),
                                     T('View script output')),
                                    unique=True)

        ## Cleanup again, including NZB files
        cleanup_list(workdir_complete, False)

        ## Remove newzbin bookmark, if any
        if msgid and all_ok:
            Bookmarks.do.del_bookmark(msgid)
        elif all_ok:
            sabnzbd.proxy_rm_bookmark(nzo.url)

        ## Show final status in history
        if all_ok:
            osx.sendGrowlMsg(T('Download Completed'), filename,
                             osx.NOTIFICATION['complete'])
            nzo.status = 'Completed'
        else:
            osx.sendGrowlMsg(T('Download Failed'), filename,
                             osx.NOTIFICATION['complete'])
            nzo.status = 'Failed'

    except:
        logging.error(Ta('Post Processing Failed for %s (%s)'), filename,
                      crash_msg)
        if not crash_msg:
            logging.info("Traceback: ", exc_info=True)
            crash_msg = T('see logfile')
        nzo.fail_msg = T('PostProcessing was aborted (%s)') % unicoder(
            crash_msg)
        osx.sendGrowlMsg(T('Download Failed'), filename,
                         osx.NOTIFICATION['complete'])
        nzo.status = 'Failed'
        par_error = True
        all_ok = False

    if all_ok:
        # If the folder only contains one file OR folder, have that as the path
        # Be aware that series/generic/date sorting may move a single file into a folder containing other files
        workdir_complete = one_file_or_folder(workdir_complete)
        workdir_complete = os.path.normpath(workdir_complete)

    # Log the overall time taken for postprocessing
    postproc_time = int(time.time() - start)

    # Create the history DB instance
    history_db = database.get_history_handle()
    # Add the nzo to the database. Only the path, script and time taken is passed
    # Other information is obtained from the nzo
    history_db.add_history_db(nzo, workdir_complete, nzo.downpath,
                              postproc_time, script_log, script_line)
    # The connection is only used once, so close it here
    history_db.close()

    ## Clean up the NZO
    try:
        logging.info('Cleaning up %s (keep_basic=%s)', filename,
                     str(not all_ok))
        sabnzbd.nzbqueue.NzbQueue.do.cleanup_nzo(nzo, keep_basic=not all_ok)
    except:
        logging.error(Ta('Cleanup of %s failed.'), nzo.final_name)
        logging.info("Traceback: ", exc_info=True)

    ## Remove download folder
    if all_ok:
        try:
            if os.path.exists(workdir):
                logging.debug('Removing workdir %s', workdir)
                remove_all(workdir, recursive=True)
        except:
            logging.error(Ta('Error removing workdir (%s)'), workdir)
            logging.info("Traceback: ", exc_info=True)

    return True
Exemplo n.º 13
0
 def stop(self):
     self.shutdown = True
     osx.sendGrowlMsg("SABnzbd",T('Shutting down'),osx.NOTIFICATION['startup'])
Exemplo n.º 14
0
 def stop(self):
     self.shutdown = True
     osx.sendGrowlMsg("SABnzbd", T('Shutting down'),
                      osx.NOTIFICATION['startup'])