예제 #1
0
파일: generic.py 프로젝트: Goeny/SickRage
    def update_show_indexer_metadata(self, show_obj):
        if self.show_metadata and show_obj and self._has_show_metadata(show_obj):
            logger.log(
                u"Metadata provider " + self.name + " updating show indexer info metadata file for " + show_obj.name,
                logger.DEBUG,
            )

            nfo_file_path = self.get_show_file_path(show_obj)
            try:
                with ek.ek(open, nfo_file_path, "r") as xmlFileObj:
                    showXML = etree.ElementTree(file=xmlFileObj)

                indexerid = showXML.find("id")

                root = showXML.getroot()

                if indexerid:
                    indexerid.text = show_obj.indexerid
                else:
                    etree.SubElement(root, "id").text = str(show_obj.indexerid)

                # Make it purdy
                helpers.indentXML(root)

                showXML.write(nfo_file_path)
                helpers.chmodAsParent(nfo_file_path)

                return True
            except IOError, e:
                logger.log(
                    u"Unable to write file to " + nfo_file_path + " - are you sure the folder is writable? " + ex(e),
                    logger.ERROR,
                )
예제 #2
0
    def _write_image(self, image_data, image_path):
        """
        Saves the data in image_data to the location image_path. Returns True/False
        to represent success or failure.
        
        image_data: binary image data to write to file
        image_path: file location to save the image to
        """
        
        # don't bother overwriting it
        if ek.ek(os.path.isfile, image_path):
            logger.log(u"Image already exists, not downloading", logger.DEBUG)
            return False
        
        if not image_data:
            logger.log(u"Unable to retrieve image, skipping", logger.WARNING)
            return False

        image_dir = ek.ek(os.path.dirname, image_path)
        
        try:
            if not ek.ek(os.path.isdir, image_dir):
                logger.log("Metadata dir didn't exist, creating it at "+image_dir, logger.DEBUG)
                ek.ek(os.makedirs, image_dir)
                helpers.chmodAsParent(image_dir)

            outFile = ek.ek(open, image_path, 'wb')
            outFile.write(image_data)
            outFile.close()
            helpers.chmodAsParent(image_path)
        except IOError, e:
            logger.log(u"Unable to write image to "+image_path+" - are you sure the show folder is writable? "+ex(e), logger.ERROR)
            return False
예제 #3
0
    def addDefaultShow(indexer, indexer_id, name, status):
        """
        Adds a new show with the default settings
        """
        if not Show.find(sickbeard.showList, int(indexer_id)):
            logger.log(u"Adding show " + str(indexer_id))
            root_dirs = sickbeard.ROOT_DIRS.split('|')

            try:
                location = root_dirs[int(root_dirs[0]) + 1]
            except Exception:
                location = None

            if location:
                showPath = ek(os.path.join, location, sanitize_filename(name))
                dir_exists = helpers.makeDir(showPath)

                if not dir_exists:
                    logger.log(u"Unable to create the folder %s , can't add the show" % showPath, logger.WARNING)
                    return
                else:
                    helpers.chmodAsParent(showPath)

                sickbeard.showQueueScheduler.action.addShow(int(indexer), int(indexer_id), showPath,
                                                            default_status=status,
                                                            quality=int(sickbeard.QUALITY_DEFAULT),
                                                            flatten_folders=int(sickbeard.FLATTEN_FOLDERS_DEFAULT),
                                                            paused=sickbeard.TRAKT_START_PAUSED,
                                                            default_status_after=status)
            else:
                logger.log(u"There was an error creating the show, no root directory setting found", logger.WARNING)
                return
예제 #4
0
파일: generic.py 프로젝트: feld/SickRage
    def update_show_indexer_metadata(self, show_obj):
        if self.show_metadata and show_obj and self._has_show_metadata(show_obj):
            logger.log(
                u"Metadata provider " + self.name + " updating show indexer info metadata file for " + show_obj.name,
                logger.DEBUG)

            nfo_file_path = self.get_show_file_path(show_obj)
            assert isinstance(nfo_file_path, unicode)

            try:
                with io.open(nfo_file_path, 'rb') as xmlFileObj:
                    showXML = etree.ElementTree(file=xmlFileObj)

                indexerid = showXML.find('id')

                root = showXML.getroot()
                if indexerid is not None:
                    indexerid.text = str(show_obj.indexerid)
                else:
                    etree.SubElement(root, "id").text = str(show_obj.indexerid)

                # Make it purdy
                helpers.indentXML(root)

                showXML.write(nfo_file_path, encoding='UTF-8')
                helpers.chmodAsParent(nfo_file_path)

                return True
            except IOError, e:
                logger.log(
                    u"Unable to write file to " + nfo_file_path + " - are you sure the folder is writable? " + ex(e),
                    logger.ERROR)
예제 #5
0
파일: generic.py 프로젝트: achlee/SickRage
    def downloadResult(self, result):
        """
        Save the result to disk.
        """

        logger.log(u"Downloading a result from " + self.name + " at " + result.url)

        data = self.getURL(result.url)

        if data is None:
            return False

        # use the appropriate watch folder
        if self.providerType == GenericProvider.NZB:
            saveDir = sickbeard.NZB_DIR
            writeMode = 'w'
        elif self.providerType == GenericProvider.TORRENT:
            saveDir = sickbeard.TORRENT_DIR
            writeMode = 'wb'
        else:
            return False

        # use the result name as the filename
        file_name = ek.ek(os.path.join, saveDir, helpers.sanitizeFileName(result.name) + '.' + self.providerType)

        logger.log(u"Saving to " + file_name, logger.DEBUG)

        try:
            with open(file_name, writeMode) as fileOut:
                fileOut.write(data)
            helpers.chmodAsParent(file_name)
        except EnvironmentError, e:
            logger.log("Unable to save the file: " + ex(e), logger.ERROR)
            return False
예제 #6
0
    def add_show(indexer, indexer_id, show_name, status):
        """
        Adds a new show with the default settings
        """
        if not Show.find(sickbeard.showList, int(indexer_id)):
            root_dirs = sickbeard.ROOT_DIRS.split('|')

            location = root_dirs[int(root_dirs[0]) + 1] if root_dirs else None

            if location:
                show_path = ek(os.path.join, location, show_name)
                logger.log(u"Adding show '{}' with ID: '{}' in location: '{}'".format(show_name, indexer_id, show_path))
                dir_exists = helpers.makeDir(show_path)

                if not dir_exists:
                    logger.log(u"Unable to create the folder {}. Unable to add the show {}".format(show_path, show_name), logger.WARNING)
                    return
                else:
                    logger.log(u"Creating the folder '{}'".format(show_path), logger.DEBUG)
                    helpers.chmodAsParent(show_path)

                sickbeard.showQueueScheduler.action.addShow(indexer, indexer_id, show_path,
                                                            default_status=status,
                                                            quality=int(sickbeard.QUALITY_DEFAULT),
                                                            flatten_folders=int(sickbeard.FLATTEN_FOLDERS_DEFAULT),
                                                            paused=sickbeard.TRAKT_START_PAUSED,
                                                            default_status_after=status)
            else:
                logger.log(u"There was an error creating the show, no root directory setting found", logger.WARNING)
                return
예제 #7
0
    def addDefaultShow(self, indexer, indexer_id, name, status):
        """
        Adds a new show with the default settings
        """
        if not helpers.findCertainShow(sickbeard.showList, int(indexer_id)):
            logger.log(u"Adding show " + str(indexer_id))
            root_dirs = sickbeard.ROOT_DIRS.split('|')

            try:
                location = root_dirs[int(root_dirs[0]) + 1]
            except:
                location = None

            if location:
                showPath = ek.ek(os.path.join, location, helpers.sanitizeFileName(name))
                dir_exists = helpers.makeDir(showPath)
                if not dir_exists:
                    logger.log(u"Unable to create the folder " + showPath + ", can't add the show", logger.ERROR)
                    return
                else:
                    helpers.chmodAsParent(showPath)

                sickbeard.showQueueScheduler.action.addShow(int(indexer), int(indexer_id), showPath, status,
                                                            int(sickbeard.QUALITY_DEFAULT),
                                                            int(sickbeard.FLATTEN_FOLDERS_DEFAULT),
                                                            paused=sickbeard.TRAKT_START_PAUSED)
            else:
                logger.log(u"There was an error creating the show, no root directory setting found", logger.ERROR)
                return
예제 #8
0
        def _int_copy(cur_file_path, new_file_path):

            self._log(u"Copying file from " + cur_file_path + " to " + new_file_path, logger.DEBUG)
            try:
                helpers.copyFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
            except (IOError, OSError), e:
                logger.log(u"Unable to copy file " + cur_file_path + " to " + new_file_path + ": " + ex(e), logger.ERROR)
                raise e
예제 #9
0
        def _int_move(cur_file_path, new_file_path):

            self._log(u"Moving file from " + cur_file_path + " to " + new_file_path, logger.DEBUG)
            try:
                helpers.moveFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
            except (IOError, OSError), e:
                self._log(u"Unable to move file " + cur_file_path + " to " + new_file_path + ": " + ex(e), logger.ERROR)
                raise e
예제 #10
0
         def _int_hard_link(cur_file_path, new_file_path):
 
             self._log(u"Hard linking file from " + cur_file_path + " to " + new_file_path, logger.DEBUG)
             try:
                 helpers.hardlinkFile(cur_file_path, new_file_path)
                 helpers.chmodAsParent(new_file_path)
             except (IOError, OSError), e:
                 self._log("Unable to link file " + cur_file_path + " to " + new_file_path + ": "+ex(e), logger.ERROR)
                 raise e
예제 #11
0
        def _int_hard_link(cur_file_path, new_file_path, success_tmpl=u' %s to %s'):

            try:
                helpers.hardlinkFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
                self._log(u'Hard linked file from' + (success_tmpl % (cur_file_path, new_file_path)), logger.DEBUG)
            except (IOError, OSError), e:
                self._log(u'Unable to link file %s<br />.. %s' % (success_tmpl % (cur_file_path, new_file_path), str(e)), logger.ERROR)
                raise e
예제 #12
0
        def _int_copy(cur_file_path, new_file_path, success_tmpl=u' %s to %s'):

            try:
                helpers.copyFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
                self._log(u'Copied file from' + (success_tmpl % (cur_file_path, new_file_path)), logger.DEBUG)
            except (IOError, OSError), e:
                self._log(u'Unable to copy %s<br />.. %s' % (success_tmpl % (cur_file_path, new_file_path), str(e)), logger.ERROR)
                raise e
예제 #13
0
         def _int_move_and_sym_link(cur_file_path, new_file_path):
 
             self._log(u"Moving then symbolic linking file from " + cur_file_path + " to " + new_file_path, logger.DEBUG)
             try:
                 helpers.moveAndSymlinkFile(cur_file_path, new_file_path)
                 helpers.chmodAsParent(new_file_path)
             except (IOError, OSError), e:
                 self._log("Unable to link file " + cur_file_path + " to " + new_file_path + ": " + ex(e), logger.ERROR)
                 raise e
예제 #14
0
        def _int_copy (cur_file_path, new_file_path):

            self._log(u"Copying file from "+cur_file_path+" to "+new_file_path, logger.DEBUG)
            try:
                helpers.copyFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
                if sickbeard.UPDATE_DIRECTORY_TIMESTAMP: helpers.touchPath(helpers.getParentDirectory(new_file_path))
            except (IOError, OSError), e:
                logger.log("Unable to copy file "+cur_file_path+" to "+new_file_path+": "+ex(e), logger.ERROR)
                raise e
예제 #15
0
        def _int_move_and_sym_link(cur_file_path, new_file_path, success_tmpl=u' %s to %s'):

            try:
                helpers.moveAndSymlinkFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
                self._log(u'Moved then symbolic linked file from' + (success_tmpl % (cur_file_path, new_file_path)),
                          logger.DEBUG)
            except (IOError, OSError), e:
                self._log(u'Unable to link file %s<br />.. %s' % (success_tmpl % (cur_file_path, new_file_path), str(e)), logger.ERROR)
                raise e
예제 #16
0
    def dumpHTML(data):
        dumpName = ek(os.path.join, sickbeard.CACHE_DIR, 'custom_torrent.html')

        try:
            fileOut = io.open(dumpName, 'wb')
            fileOut.write(data)
            fileOut.close()
            helpers.chmodAsParent(dumpName)
        except IOError, e:
            logger.log(u"Unable to save the file: %s " % repr(e), logger.ERROR)
            return False
예제 #17
0
    def dumpHTML(self, data):

        dumpName = ek.ek(os.path.join, sickbeard.CACHE_DIR, "custom_torrent.html")

        try:
            fileOut = open(dumpName, "wb")
            fileOut.write(data)
            fileOut.close()
            helpers.chmodAsParent(dumpName)
        except IOError, e:
            logger.log("Unable to save the file: " + ex(e), logger.ERROR)
            return False
예제 #18
0
    def dumpHTML(data):
        dumpName = ek(os.path.join, sickbeard.CACHE_DIR, 'custom_torrent.html')

        try:
            fileOut = ek(io.open, dumpName, 'wb')
            fileOut.write(data)
            fileOut.close()
            helpers.chmodAsParent(dumpName)
        except IOError as e:
            logging.error("Unable to save the file: %s " % repr(e))
            return False
        logging.info("Saved custom_torrent html dump %s " % dumpName)
        return True
예제 #19
0
        def _int_link (cur_file_path, new_file_path):

            self._log(u"Linking file from "+cur_file_path+" to "+new_file_path, logger.DEBUG)
            est = eec.set(self._link, cur_file_path)
            try:
                helpers.moveFile(cur_file_path, new_file_path)
                helpers.linkFile(cur_file_path, new_file_path)
                helpers.chmodAsParent(new_file_path)
            except (IOError, OSError), e:
                logger.log("Unable to link file "+cur_file_path+" to "+new_file_path+": "+ex(e), logger.ERROR)
                logger.log(str(e), logger.ERROR);
                eec.clock(est, False)
                raise e
예제 #20
0
    def dumpHTML(data):
        dumpName = ek(os.path.join, sickbeard.CACHE_DIR, "custom_torrent.html")

        try:
            fileOut = io.open(dumpName, "wb")
            fileOut.write(data)
            fileOut.close()
            helpers.chmodAsParent(dumpName)
        except IOError as e:
            logger.log(u"Unable to save the file: %s " % repr(e), logger.ERROR)
            return False
        logger.log(u"Saved custom_torrent html dump %s " % dumpName, logger.INFO)
        return True
예제 #21
0
    def dumpHTML(data):
        dumpName = ek(os.path.join, sickbeard.CACHE_DIR, 'custom_torrent.html')

        try:
            fileOut = io.open(dumpName, 'wb')
            fileOut.write(data)
            fileOut.close()
            helpers.chmodAsParent(dumpName)
        except IOError as error:
            logger.log('Unable to save the file: {0}'.format(ex(error)), logger.ERROR)
            return False

        logger.log('Saved custom_torrent html dump {0} '.format(dumpName), logger.INFO)
        return True
예제 #22
0
    def execute(self):
        generic_queue.QueueItem.execute(self)
        
        ep_obj = self.ep_obj
        force = self.force
        
        random.shuffle(SUBTITLE_SERVICES)
        logger.log("Searching subtitles for " + ep_obj.prettyName())

        if not ek.ek(os.path.isfile, ep_obj.location):
            logger.log("Can't download subtitles for " + ep_obj.prettyName() + ". Episode file doesn't exist.", logger.DEBUG)
            return
        
        epName = ep_obj.location.rpartition(".")[0]
        subLanguages = []
        if sickbeard.SUBTITLE_LANGUAGES <> '':
            subLanguages = sickbeard.SUBTITLE_LANGUAGES.split(",")
        if len(subLanguages) < 1 and ep_obj.show.lang:
            subLanguages.append(ep_obj.show.lang)
        
        if len(subLanguages) < 1:
            logger.log("Can't download subtitles for " + ep_obj.prettyName() + ". Configure the language to search at post processing options.", logger.DEBUG)
            return
        #for lang in subLanguages:
            #langS = lang.split("-")
            #if len(langS) > 1:
                #subLanguages.append(langS[0])
        try:
            sublimLangs = set()
            for sub in subLanguages:
                bLang = Language.fromietf(sub)
                sublimLangs.add(bLang)
            sublimEpisode = set()
            sublimEpisode.add(Episode.fromname(ep_obj.location))
            downloadedSubs = subliminal.download_best_subtitles(
                videos=sublimEpisode,
                languages=sublimLangs,
                providers=SUBTITLE_SERVICES)

            subliminal.save_subtitles(downloadedSubs, directory = os.path.dirname(ep_obj.location))
            subCount = 0
            for video, video_subtitles in downloadedSubs.items():
                for sub in video_subtitles:
                    subPath = subliminal.subtitle.get_subtitle_path(ep_obj.location, sub.language)
                    helpers.chmodAsParent(subPath)
                    subCount += 1
        except Exception, e:
            logger.log("Error while downloading subtitles for %s: %s" % (ep_obj.prettyName(), str(e)), logger.ERROR)
            traceback.print_exc()
            return False
예제 #23
0
    def write_ep_file(self, ep_obj):
        """
        Generates and writes ep_obj's metadata under the given path with the
        given filename root. Uses the episode's name with the extension in
        _ep_nfo_extension.

        ep_obj: TVEpisode object for which to create the metadata

        file_name_path: The file name to use for this metadata. Note that the extension
                will be automatically added based on _ep_nfo_extension. This should
                include an absolute path.

        Note that this method expects that _ep_data will return an ElementTree
        object. If your _ep_data returns data in another format you'll need to
        override this method.
        """

        data = self._ep_data(ep_obj)

        if not data:
            return False

        nfo_file_path = self.get_episode_file_path(ep_obj)
        nfo_file_dir = ek(os.path.dirname, nfo_file_path)

        try:
            if not ek(os.path.isdir, nfo_file_dir):
                logger.log(u'Metadata directory did not exist, creating it at {path}'.format
                           (path=nfo_file_dir), logger.DEBUG)
                ek(os.makedirs, nfo_file_dir)
                helpers.chmodAsParent(nfo_file_dir)

            logger.log(u'Writing episode nfo file to {path}'.format
                       (path=nfo_file_path), logger.DEBUG)

            with io.open(nfo_file_path, 'wb') as nfo_file:
                # Calling encode directly, b/c often descriptions have wonky characters.
                data.write(nfo_file, encoding='utf-8', xml_declaration=True)

            helpers.chmodAsParent(nfo_file_path)

        except IOError as e:
            logger.log(u'Unable to write file to {path} - '
                       u'are you sure the folder is writable? {exception}'.format
                       (path=nfo_file_path, exception=ex(e)), logger.ERROR)
            return False

        return True
예제 #24
0
def _download_result(result):
    """
    Downloads a result to the appropriate black hole folder.

    Returns a bool representing success.

    result: SearchResult instance to download.
    """

    res_provider = result.provider
    if None is res_provider:
        logger.log(u'Invalid provider name - this is a coding error, report it please', logger.ERROR)
        return False

    # nzbs with an URL can just be downloaded from the provider
    if 'nzb' == result.resultType:
        new_result = res_provider.download_result(result)
    # if it's an nzb data result
    elif 'nzbdata' == result.resultType:

        # get the final file path to the nzb
        file_name = ek.ek(os.path.join, sickbeard.NZB_DIR, u'%s.nzb' % result.name)

        logger.log(u'Saving NZB to %s' % file_name)

        new_result = True

        # save the data to disk
        try:
            data = result.get_data()
            if not data:
                new_result = False
            else:
                with ek.ek(open, file_name, 'w') as file_out:
                    file_out.write(data)

                helpers.chmodAsParent(file_name)

        except EnvironmentError as e:
            logger.log(u'Error trying to save NZB to black hole: %s' % ex(e), logger.ERROR)
            new_result = False
    elif 'torrent' == res_provider.providerType:
        new_result = res_provider.download_result(result)
    else:
        logger.log(u'Invalid provider type - this is a coding error, report it please', logger.ERROR)
        new_result = False

    return new_result
예제 #25
0
    def write_ep_file(self, ep_obj):
        """
        Generates and writes ep_obj's metadata under the given path with the
        given filename root. Uses the episode's name with the extension in
        _ep_nfo_extension.

        ep_obj: TVEpisode object for which to create the metadata

        file_name_path: The file name to use for this metadata. Note that the extension
                will be automatically added based on _ep_nfo_extension. This should
                include an absolute path.

        Note that this method expects that _ep_data will return an ElementTree
        object. If your _ep_data returns data in another format you'll need to
        override this method.
        """

        data = self._ep_data(ep_obj)

        if not data:
            return False

        nfo_file_path = self.get_episode_file_path(ep_obj)
        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)

        try:
            if not ek.ek(os.path.isdir, nfo_file_dir):
                logger.log(
                    u"Metadata dir didn't exist, creating it at " +
                    nfo_file_dir, logger.DEBUG)
                ek.ek(os.makedirs, nfo_file_dir)
                helpers.chmodAsParent(nfo_file_dir)

            logger.log(u"Writing episode nfo file to " + nfo_file_path,
                       logger.DEBUG)

            nfo_file = ek.ek(open, nfo_file_path, 'w')

            data.write(nfo_file, encoding="utf-8")
            nfo_file.close()
            helpers.chmodAsParent(nfo_file_path)
        except IOError, e:
            logger.log(
                u"Unable to write file to " + nfo_file_path +
                " - are you sure the folder is writable? " + ex(e),
                logger.ERROR)
            return False
예제 #26
0
    def write_show_file(self, show_obj):
        """
        Generates and writes show_obj's metadata under the given path to the
        filename given by get_show_file_path()

        show_obj: TVShow object for which to create the metadata

        path: An absolute or relative path where we should put the file. Note that
                the file name will be the default show_file_name.

        Note that this method expects that _show_data will return an ElementTree
        object. If your _show_data returns data in another format you'll need to
        override this method.
        """

        data = self._show_data(show_obj)

        if not data:
            return False

        nfo_file_path = self.get_show_file_path(show_obj)
        nfo_file_dir = ek(os.path.dirname, nfo_file_path)

        try:
            if not ek(os.path.isdir, nfo_file_dir):
                logger.log(u'Metadata directory did not exist, creating it at {path}'.format
                           (path=nfo_file_dir), logger.DEBUG)
                ek(os.makedirs, nfo_file_dir)
                helpers.chmodAsParent(nfo_file_dir)

            logger.log(u'Writing show nfo file to {path}'.format
                       (path=nfo_file_path), logger.DEBUG)

            nfo_file = io.open(nfo_file_path, 'wb')

            data.write(nfo_file, encoding='utf-8', xml_declaration=True)
            nfo_file.close()
            helpers.chmodAsParent(nfo_file_path)
        except IOError as e:
            logger.log(u'Unable to write file to {path} - '
                       u'are you sure the folder is writable? {exception}'.format
                       (path=nfo_file_path, exception=ex(e)),
                       logger.ERROR)
            return False

        return True
예제 #27
0
    def write_show_file(self, show_obj):
        """
        Generates and writes show_obj's metadata under the given path to the
        filename given by get_show_file_path()

        show_obj: TVShow object for which to create the metadata

        path: An absolute or relative path where we should put the file. Note that
                the file name will be the default show_file_name.

        Note that this method expects that _show_data will return an ElementTree
        object. If your _show_data returns data in another format you'll need to
        override this method.
        """

        data = self._show_data(show_obj)

        if not data:
            return False

        nfo_file_path = self.get_show_file_path(show_obj)
        nfo_file_dir = ek.ek(os.path.dirname, nfo_file_path)

        try:
            if not ek.ek(os.path.isdir, nfo_file_dir):
                logger.log(
                    u"Metadata dir didn't exist, creating it at " +
                    nfo_file_dir, logger.DEBUG)
                ek.ek(os.makedirs, nfo_file_dir)
                helpers.chmodAsParent(nfo_file_dir)

            logger.log(u"Writing show nfo file to " + nfo_file_path,
                       logger.DEBUG)

            nfo_file = ek.ek(open, nfo_file_path, 'w')

            data.write(nfo_file, encoding="utf-8")
            nfo_file.close()
            helpers.chmodAsParent(nfo_file_path)
        except IOError, e:
            logger.log(
                u"Unable to write file to " + nfo_file_path +
                " - are you sure the folder is writable? " + ex(e),
                logger.ERROR)
            return False
예제 #28
0
 def downloadResult(self, result):
     try:
         logger.log(u"Downloading a result from " + self.name + " at " + result.url)
         
         torrentFileName = ek.ek(os.path.join, sickbeard.TORRENT_DIR, helpers.sanitizeFileName(result.name) + '.' + self.providerType)
         #add self referer to get application/x-bittorrent from torcache.net
         data = self.getURL(result.url, [("Referer", result.url)])
         if data == None:
             return False
         fileOut = open(torrentFileName, 'wb')
         logger.log(u"Saving to " + torrentFileName, logger.DEBUG)
         fileOut.write(data)
         fileOut.close()
         helpers.chmodAsParent(torrentFileName)
         return self._verify_download(torrentFileName)
     except Exception, e:
         logger.log("Unable to save the file: "+str(e).decode('utf-8'), logger.ERROR)
         return False
예제 #29
0
파일: strm.py 프로젝트: atmorell/Sick-Beard
def _commitSTRM(strmName, strmContents):
    # get the final file path to the strm file
    destinationPath = ek.ek(os.path.join, sickbeard.TV_DOWNLOAD_DIR, strmName)
    helpers.makeDir(destinationPath)
    fileName = ek.ek(os.path.join, destinationPath, strmName + ".strm")
    
    logger.log(u"Saving STRM to " + fileName)

    # save the data to disk
    try:
        fileOut = open(fileName, "w")
        fileOut.write(strmContents)
        fileOut.close()
        helpers.chmodAsParent(fileName)
        return True
    except IOError, e:
        logger.log(u"Error trying to save STRM to TV downloader directory: "+ex(e), logger.ERROR)
        return False
예제 #30
0
def _downloadResult(result):
    """
    Downloads a result to the appropriate black hole folder.

    Returns a bool representing success.

    result: SearchResult instance to download.
    """

    resProvider = result.provider
    if resProvider == None:
        logger.log(u"Invalid provider name - this is a coding error, report it please", logger.ERROR)
        return False

    # nzbs with an URL can just be downloaded from the provider
    if result.resultType == "nzb":
        newResult = resProvider.download_result(result)
    # if it's an nzb data result
    elif result.resultType == "nzbdata":

        # get the final file path to the nzb
        fileName = ek.ek(os.path.join, sickbeard.NZB_DIR, result.name + ".nzb")

        logger.log(u"Saving NZB to " + fileName)

        newResult = True

        # save the data to disk
        try:
            with ek.ek(open, fileName, 'w') as fileOut:
                fileOut.write(result.extraInfo[0])

            helpers.chmodAsParent(fileName)

        except EnvironmentError as e:
            logger.log(u"Error trying to save NZB to black hole: " + ex(e), logger.ERROR)
            newResult = False
    elif resProvider.providerType == "torrent":
        newResult = resProvider.download_result(result)
    else:
        logger.log(u"Invalid provider type - this is a coding error, report it please", logger.ERROR)
        newResult = False

    return newResult
예제 #31
0
    elif result.resultType == "torrentdata":

        # get the final file path to the nzb
        fileName = ek.ek(os.path.join, sickbeard.TORRENT_DIR,
                         result.name + ".torrent")

        logger.log(u"Saving Torrent to " + fileName)

        newResult = True

        # save the data to disk
        try:
            fileOut = open(fileName, "wb")
            fileOut.write(result.extraInfo[0])
            fileOut.close()
            helpers.chmodAsParent(fileName)
        except IOError, e:
            logger.log(u"Error trying to save Torrent to black hole: " + ex(e),
                       logger.ERROR)
            newResult = False

    elif resProvider.providerType == "torrent":
        newResult = resProvider.downloadResult(result)

    else:
        logger.log(
            u"Invalid provider type - this is a coding error, report it please",
            logger.ERROR)
        return False

    if newResult:
예제 #32
0
    def process(self):
        """
        Post-process a given file

        :return: True on success, False on failure
        """

        self._log(u"Processing " + self.file_path + " (" + str(self.nzb_name) + ")")

        if ek(os.path.isdir, self.file_path):
            self._log(u"File %s seems to be a directory" % self.file_path)
            return False

        if not ek(os.path.exists, self.file_path):
            self._log(u"File %s doesn't exist, did unrar fail?" % self.file_path)
            return False

        for ignore_file in self.IGNORED_FILESTRINGS:
            if ignore_file in self.file_path:
                self._log(u"File %s is ignored type, skipping" % self.file_path)
                return False

        # reset per-file stuff
        self.in_history = False

        # reset the anidb episode object
        self.anidbEpisode = None

        # try to find the file info
        (show, season, episodes, quality, version) = self._find_info()
        if not show:
            self._log(u"This show isn't in your list, you need to add it to SR before post-processing an episode")
            raise EpisodePostProcessingFailedException()
        elif season == None or not episodes:
            self._log(u"Not enough information to determine what episode this is. Quitting post-processing")
            return False

        # retrieve/create the corresponding TVEpisode objects
        ep_obj = self._get_ep_obj(show, season, episodes)
        old_ep_status, old_ep_quality = common.Quality.splitCompositeStatus(ep_obj.status)

        # get the quality of the episode we're processing
        if quality and not common.Quality.qualityStrings[quality] == 'Unknown':
            self._log(u"Snatch history had a quality in it, using that: " + common.Quality.qualityStrings[quality],
                      logger.DEBUG)
            new_ep_quality = quality
        else:
            new_ep_quality = self._get_quality(ep_obj)

        logger.log(u"Quality of the episode we're processing: %s" % new_ep_quality, logger.DEBUG)

        # see if this is a priority download (is it snatched, in history, PROPER, or BEST)
        priority_download = self._is_priority(ep_obj, new_ep_quality)
        self._log(u"Is ep a priority download: " + str(priority_download), logger.DEBUG)

        # get the version of the episode we're processing
        if version:
            self._log(u"Snatch history had a version in it, using that: v" + str(version),
                      logger.DEBUG)
            new_ep_version = version
        else:
            new_ep_version = -1

        # check for an existing file
        existing_file_status = self._checkForExistingFile(ep_obj.location)

        # if it's not priority then we don't want to replace smaller files in case it was a mistake
        if not priority_download:

            # Not a priority and the quality is lower than what we already have
            if (new_ep_quality < old_ep_quality and old_ep_quality != common.Quality.UNKNOWN) and not existing_file_status == PostProcessor.DOESNT_EXIST:
                self._log(u"File exists and new file quality is lower than existing, marking it unsafe to replace")
                return False

            # if there's an existing file that we don't want to replace stop here
            if existing_file_status == PostProcessor.EXISTS_LARGER:
                if self.is_proper:
                    self._log(
                        u"File exists and new file is smaller, new file is a proper/repack, marking it safe to replace")
                    return True

                else:
                    self._log(u"File exists and new file is smaller, marking it unsafe to replace")
                    return False

            elif existing_file_status == PostProcessor.EXISTS_SAME:
                self._log(u"File exists and new file is same size, marking it unsafe to replace")
                return False

        # if the file is priority then we're going to replace it even if it exists
        else:
            self._log(
                u"This download is marked a priority download so I'm going to replace an existing file if I find one")

        # try to find out if we have enough space to perform the copy or move action.
        if not helpers.isFileLocked(self.file_path, False):
            if not verify_freespace(self.file_path, ep_obj.show._location, [ep_obj] + ep_obj.relatedEps):
                self._log("Not enough space to continue PP, exiting", logger.WARNING)
                return False
        else:
            self._log("Unable to determine needed filespace as the source file is locked for access")


        # delete the existing file (and company)
        for cur_ep in [ep_obj] + ep_obj.relatedEps:
            try:
                self._delete(cur_ep.location, associated_files=True)

                # clean up any left over folders
                if cur_ep.location:
                    helpers.delete_empty_folders(ek(os.path.dirname, cur_ep.location), keep_dir=ep_obj.show._location)
            except (OSError, IOError):
                raise EpisodePostProcessingFailedException("Unable to delete the existing files")

            # set the status of the episodes
            # for curEp in [ep_obj] + ep_obj.relatedEps:
            #    curEp.status = common.Quality.compositeStatus(common.SNATCHED, new_ep_quality)

        # if the show directory doesn't exist then make it if allowed
        if not ek(os.path.isdir, ep_obj.show._location) and sickbeard.CREATE_MISSING_SHOW_DIRS:
            self._log(u"Show directory doesn't exist, creating it", logger.DEBUG)
            try:
                ek(os.mkdir, ep_obj.show._location)
                helpers.chmodAsParent(ep_obj.show._location)

                # do the library update for synoindex
                notifiers.synoindex_notifier.addFolder(ep_obj.show._location)
            except (OSError, IOError):
                raise EpisodePostProcessingFailedException("Unable to create the show directory: " + ep_obj.show._location)

            # get metadata for the show (but not episode because it hasn't been fully processed)
            ep_obj.show.writeMetadata(True)

        # update the ep info before we rename so the quality & release name go into the name properly
        sql_l = []

        for cur_ep in [ep_obj] + ep_obj.relatedEps:
            with cur_ep.lock:

                if self.release_name:
                    self._log("Found release name " + self.release_name, logger.DEBUG)
                    cur_ep.release_name = self.release_name
                else:
                    cur_ep.release_name = ""

                if ep_obj.status in common.Quality.SNATCHED_BEST:
                    cur_ep.status = common.Quality.compositeStatus(common.ARCHIVED, new_ep_quality)
                else:
                    cur_ep.status = common.Quality.compositeStatus(common.DOWNLOADED, new_ep_quality)

                cur_ep.subtitles = u''

                cur_ep.subtitles_searchcount = 0

                cur_ep.subtitles_lastsearch = '0001-01-01 00:00:00'

                cur_ep.is_proper = self.is_proper

                cur_ep.version = new_ep_version

                if self.release_group:
                    cur_ep.release_group = self.release_group
                else:
                    cur_ep.release_group = ""

                sql_l.append(cur_ep.get_sql())

        # Just want to keep this consistent for failed handling right now
        releaseName = show_name_helpers.determineReleaseName(self.folder_path, self.nzb_name)
        if releaseName is not None:
            failed_history.logSuccess(releaseName)
        else:
            self._log(u"Couldn't find release in snatch history", logger.WARNING)

        # find the destination folder
        try:
            proper_path = ep_obj.proper_path()
            proper_absolute_path = ek(os.path.join, ep_obj.show.location, proper_path)

            dest_path = ek(os.path.dirname, proper_absolute_path)
        except ShowDirectoryNotFoundException:
            raise EpisodePostProcessingFailedException(
                u"Unable to post-process an episode if the show dir doesn't exist, quitting")

        self._log(u"Destination folder for this episode: " + dest_path, logger.DEBUG)

        # create any folders we need
        helpers.make_dirs(dest_path)

        # figure out the base name of the resulting episode file
        if sickbeard.RENAME_EPISODES:
            orig_extension = self.file_name.rpartition('.')[-1]
            new_base_name = ek(os.path.basename, proper_path)
            new_file_name = new_base_name + '.' + orig_extension

        else:
            # if we're not renaming then there's no new base name, we'll just use the existing name
            new_base_name = None
            new_file_name = self.file_name

        # add to anidb
        if ep_obj.show.is_anime and sickbeard.ANIDB_USE_MYLIST:
            self._add_to_anidb_mylist(self.file_path)

        try:
            # move the episode and associated files to the show dir
            if self.process_method == "copy":
                if helpers.isFileLocked(self.file_path, False):
                    raise EpisodePostProcessingFailedException("File is locked for reading")
                self._copy(self.file_path, dest_path, new_base_name, sickbeard.MOVE_ASSOCIATED_FILES,
                           sickbeard.USE_SUBTITLES and ep_obj.show.subtitles)
            elif self.process_method == "move":
                if helpers.isFileLocked(self.file_path, True):
                    raise EpisodePostProcessingFailedException("File is locked for reading/writing")
                self._move(self.file_path, dest_path, new_base_name, sickbeard.MOVE_ASSOCIATED_FILES,
                           sickbeard.USE_SUBTITLES and ep_obj.show.subtitles)
            elif self.process_method == "hardlink":
                self._hardlink(self.file_path, dest_path, new_base_name, sickbeard.MOVE_ASSOCIATED_FILES,
                               sickbeard.USE_SUBTITLES and ep_obj.show.subtitles)
            elif self.process_method == "symlink":
                if helpers.isFileLocked(self.file_path, True):
                    raise EpisodePostProcessingFailedException("File is locked for reading/writing")
                self._moveAndSymlink(self.file_path, dest_path, new_base_name, sickbeard.MOVE_ASSOCIATED_FILES,
                                     sickbeard.USE_SUBTITLES and ep_obj.show.subtitles)
            else:
                logger.log(u"Unknown process method: " + str(self.process_method), logger.ERROR)
                raise EpisodePostProcessingFailedException("Unable to move the files to their new home")
        except (OSError, IOError):
            raise EpisodePostProcessingFailedException("Unable to move the files to their new home")

        # download subtitles
        if sickbeard.USE_SUBTITLES and ep_obj.show.subtitles:
            for cur_ep in [ep_obj] + ep_obj.relatedEps:
                with cur_ep.lock:
                    cur_ep.location = ek(os.path.join, dest_path, new_file_name)
                    cur_ep.refreshSubtitles()
                    cur_ep.downloadSubtitles(force=True)

        # now that processing has finished, we can put the info in the DB. If we do it earlier, then when processing fails, it won't try again.
        if len(sql_l) > 0:
            myDB = db.DBConnection()
            myDB.mass_action(sql_l)

        # put the new location in the database
        sql_l = []
        for cur_ep in [ep_obj] + ep_obj.relatedEps:
            with cur_ep.lock:
                cur_ep.location = ek(os.path.join, dest_path, new_file_name)
                sql_l.append(cur_ep.get_sql())

        if len(sql_l) > 0:
            myDB = db.DBConnection()
            myDB.mass_action(sql_l)

        # set file modify stamp to show airdate
        if sickbeard.AIRDATE_EPISODES:
            for cur_ep in [ep_obj] + ep_obj.relatedEps:
                with cur_ep.lock:
                    cur_ep.airdateModifyStamp()

        # generate nfo/tbn
        ep_obj.createMetaFiles()

        # log it to history
        history.logDownload(ep_obj, self.file_path, new_ep_quality, self.release_group, new_ep_version)

        #If any notification fails, don't stop postProcessor
        try:
            # send notifications
            notifiers.notify_download(ep_obj._format_pattern('%SN - %Sx%0E - %EN - %QN'))

            # do the library update for KODI
            notifiers.kodi_notifier.update_library(ep_obj.show.name)

            # do the library update for Plex
            notifiers.plex_notifier.update_library(ep_obj)

            # do the library update for EMBY
            notifiers.emby_notifier.update_library(ep_obj.show)

            # do the library update for NMJ
            # nmj_notifier kicks off its library update when the notify_download is issued (inside notifiers)

            # do the library update for Synology Indexer
            notifiers.synoindex_notifier.addFile(ep_obj.location)

            # do the library update for pyTivo
            notifiers.pytivo_notifier.update_library(ep_obj)

            # do the library update for Trakt
            notifiers.trakt_notifier.update_library(ep_obj)
        except:
            logger.log(u"Some notifications could not be sent. Continuing with postProcessing...")

        self._run_extra_scripts(ep_obj)

        return True
예제 #33
0
    def run(self):
        # TODO: Put that in the __init__ before starting the thread?
        if not sickbeard.USE_SUBTITLES:
            logger.log(u'Subtitles support disabled', logger.DEBUG)
            return
        if len(sickbeard.subtitles.getEnabledServiceList()) < 1:
            logger.log(
                u'Not enough services selected. At least 1 service is required to search subtitles in the background',
                logger.ERROR)
            return

        logger.log(u'Checking for subtitles', logger.MESSAGE)

        # get episodes on which we want subtitles
        # criteria is:
        #  - show subtitles = 1
        #  - episode subtitles != config wanted languages or SINGLE (depends on config multi)
        #  - search count < 2 and diff(airdate, now) > 1 week : now -> 1d
        #  - search count < 7 and diff(airdate, now) <= 1 week : now -> 4h -> 8h -> 16h -> 1d -> 1d -> 1d

        myDB = db.DBConnection()
        today = datetime.date.today().toordinal()
        # you have 5 minutes to understand that one. Good luck
        sqlResults = myDB.select(
            'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.subtitles, e.subtitles_searchcount AS searchcount, e.subtitles_lastsearch AS lastsearch, e.location, (? - e.airdate) AS airdate_daydiff FROM tv_episodes AS e INNER JOIN tv_shows AS s ON (e.showid = s.tvdb_id) WHERE s.subtitles = 1 AND e.subtitles NOT LIKE (?) AND ((e.subtitles_searchcount <= 2 AND (? - e.airdate) > 7) OR (e.subtitles_searchcount <= 7 AND (? - e.airdate) <= 7)) AND (e.status IN ('
            + ','.join([str(x) for x in Quality.DOWNLOADED + [ARCHIVED]]) +
            ') OR (e.status IN (' + ','.join(
                [str(x) for x in Quality.SNATCHED + Quality.SNATCHED_PROPER]) +
            ') AND e.location != ""))',
            [today, wantedLanguages(True), today, today])
        if len(sqlResults) == 0:
            logger.log('No subtitles to download', logger.MESSAGE)
            return

        rules = self._getRules()
        now = datetime.datetime.now()
        for epToSub in sqlResults:
            if not ek.ek(os.path.isfile, epToSub['location']):
                logger.log(
                    'Episode file does not exist, cannot download subtitles for episode %dx%d of show %s'
                    % (epToSub['season'], epToSub['episode'],
                       epToSub['show_name']), logger.DEBUG)
                continue

            # Old shows rule
            if ((epToSub['airdate_daydiff'] > 7 and epToSub['searchcount'] < 2
                 and now - datetime.datetime.strptime(epToSub['lastsearch'],
                                                      '%Y-%m-%d %H:%M:%S') >
                 datetime.timedelta(hours=rules['old'][epToSub['searchcount']])
                 ) or
                    # Recent shows rule
                (epToSub['airdate_daydiff'] <= 7 and epToSub['searchcount'] < 7
                 and now - datetime.datetime.strptime(epToSub['lastsearch'],
                                                      '%Y-%m-%d %H:%M:%S') >
                 datetime.timedelta(hours=rules['new'][epToSub['searchcount']])
                 )):
                logger.log(
                    'Downloading subtitles for episode %dx%d of show %s' %
                    (epToSub['season'], epToSub['episode'],
                     epToSub['show_name']), logger.DEBUG)

                showObj = helpers.findCertainShow(sickbeard.showList,
                                                  int(epToSub['showid']))
                if not showObj:
                    logger.log(u'Show not found', logger.DEBUG)
                    return

                epObj = showObj.getEpisode(int(epToSub["season"]),
                                           int(epToSub["episode"]))
                if isinstance(epObj, str):
                    logger.log(u'Episode not found', logger.DEBUG)
                    return

                previous_subtitles = epObj.subtitles

                try:
                    subtitles = epObj.downloadSubtitles()

                    if sickbeard.SUBTITLES_DIR:
                        for video in subtitles:
                            subs_new_path = ek.ek(os.path.join,
                                                  os.path.dirname(video.path),
                                                  sickbeard.SUBTITLES_DIR)
                            dir_exists = helpers.makeDir(subs_new_path)
                            if not dir_exists:
                                logger.log(
                                    u"Unable to create subtitles folder " +
                                    subs_new_path, logger.ERROR)
                            else:
                                helpers.chmodAsParent(subs_new_path)

                            for subtitle in subtitles.get(video):
                                new_file_path = ek.ek(
                                    os.path.join, subs_new_path,
                                    os.path.basename(subtitle.path))
                                helpers.moveFile(subtitle.path, new_file_path)
                                helpers.chmodAsParent(new_file_path)
                    else:
                        for video in subtitles:
                            for subtitle in subtitles.get(video):
                                helpers.chmodAsParent(subtitle.path)
                except:
                    logger.log(u'Unable to find subtitles', logger.DEBUG)
                    return
예제 #34
0
class SubtitleQueueItem(generic_queue.QueueItem):
    def __init__(self, ep_obj, force):
        generic_queue.QueueItem.__init__(self, 'Search', SUBTITLE_SEARCH)
        self.priority = generic_queue.QueuePriorities.NORMAL

        self.ep_obj = ep_obj
        self.force = force

        self.success = None

    def execute(self):
        generic_queue.QueueItem.execute(self)

        ep_obj = self.ep_obj
        force = self.force

        random.shuffle(SUBTITLE_SERVICES)
        logger.log("Searching subtitles for " + ep_obj.prettyName())

        if not ek.ek(os.path.isfile, ep_obj.location):
            logger.log(
                "Can't download subtitles for " + ep_obj.prettyName() +
                ". Episode file doesn't exist.", logger.DEBUG)
            return

        epName = ep_obj.location.rpartition(".")[0]
        subLanguages = sickbeard.SUBTITLE_LANGUAGES.split(",")
        if len(subLanguages) < 1 and ep_obj.show.lang:
            subLanguages.append(ep_obj.show.lang)

        if len(subLanguages) < 1:
            logger.log(
                "Can't download subtitles for " + ep_obj.prettyName() +
                ". Configure the language to search at post processing options.",
                logger.DEBUG)
            return
        #for lang in subLanguages:
        #langS = lang.split("-")
        #if len(langS) > 1:
        #subLanguages.append(langS[0])

        try:
            subEpisodes = subliminal.download_subtitles(
                [ep_obj.location],
                languages=subLanguages,
                services=SUBTITLE_SERVICES,
                force=force,
                multi=True,
                cache_dir=sickbeard.CACHE_DIR,
                max_depth=3,
                scan_filter=None,
                order=None)
        except Exception, e:
            logger.log(
                "Error while downloading subtitles for %s: %s" %
                (ep_obj.prettyName(), str(e)), logger.ERROR)
            traceback.print_exc()
            return False
        subCount = 0
        for subEpisode in subEpisodes:
            subtitles = subEpisodes[subEpisode]
            for subtitle in subtitles:
                helpers.chmodAsParent(subtitle.path)
                subCount += 1

        if subCount > 0:
            for subEpisode in subEpisodes:
                subtitles = subEpisodes[subEpisode]
                for item in subtitles:
                    logger.log(
                        "Downloaded subtitle for %s: %s from %s" %
                        (ep_obj.prettyName(), item.language, item.service))

            self.success = True
        else:
            logger.log("No subtitles downloaded for " + ep_obj.prettyName())
            self.success = False
예제 #35
0
        try:
            dest_path = self._find_ep_destination_folder(ep_obj)
        except exceptions.ShowDirNotFoundException:
            raise exceptions.PostProcessingFailed(
                u"Unable to post-process an episode if the show dir doesn't exist, quitting"
            )

        self._log(u"Destination folder for this episode: " + dest_path,
                  logger.DEBUG)

        # if the dir doesn't exist (new season folder) then make it
        if not ek.ek(os.path.isdir, dest_path):
            self._log(u"Season folder didn't exist, creating it", logger.DEBUG)
            try:
                ek.ek(os.mkdir, dest_path)
                helpers.chmodAsParent(dest_path)
                # do the library update for synoindex
                notifiers.synoindex_notifier.addFolder(dest_path)
            except OSError, IOError:
                raise exceptions.PostProcessingFailed(
                    "Unable to create the episode's destination folder: " +
                    dest_path)

        # update the statuses before we rename so the quality goes into the name properly
        for cur_ep in [ep_obj] + ep_obj.relatedEps:
            with cur_ep.lock:
                cur_ep.status = common.Quality.compositeStatus(
                    common.DOWNLOADED, new_ep_quality)
                cur_ep.saveToDB()

        # figure out the base name of the resulting episode file
예제 #36
0
    def addNewShow(self,
                   whichSeries=None,
                   indexerLang=None,
                   rootDir=None,
                   defaultStatus=None,
                   quality_preset=None,
                   anyQualities=None,
                   bestQualities=None,
                   season_folders=None,
                   subtitles=None,
                   subtitles_sr_metadata=None,
                   fullShowPath=None,
                   other_shows=None,
                   skipShow=None,
                   providedIndexer=None,
                   anime=None,
                   scene=None,
                   blacklist=None,
                   whitelist=None,
                   defaultStatusAfter=None):
        """
        Receive tvdb id, dir, and other options and create a show from them. If extra show dirs are
        provided then it forwards back to newShow, if not it goes to /home.
        """

        if not indexerLang:
            indexerLang = sickbeard.INDEXER_DEFAULT_LANGUAGE

        # grab our list of other dirs if given
        if not other_shows:
            other_shows = []
        elif not isinstance(other_shows, list):
            other_shows = [other_shows]

        def finishAddShow():
            # if there are no extra shows then go home
            if not other_shows:
                return self.redirect('/home/')

            # peel off the next one
            next_show_dir = other_shows[0]
            rest_of_show_dirs = other_shows[1:]

            # go to add the next show
            return self.newShow(next_show_dir, rest_of_show_dirs)

        # if we're skipping then behave accordingly
        if skipShow:
            return finishAddShow()

        # sanity check on our inputs
        if (not rootDir and not fullShowPath) or not whichSeries:
            return _(
                "Missing params, no Indexer ID or folder: {show_to_add} and {root_dir}/{show_path}"
            ).format(show_to_add=whichSeries,
                     root_dir=rootDir,
                     show_path=fullShowPath)

        # figure out what show we're adding and where
        series_pieces = whichSeries.split('|')
        if (whichSeries and rootDir) or (whichSeries and fullShowPath
                                         and len(series_pieces) > 1):
            if len(series_pieces) < 6:
                logger.log(
                    "Unable to add show due to show selection. Not enough arguments: {0}"
                    .format((repr(series_pieces))), logger.ERROR)
                ui.notifications.error(
                    _("Unknown error. Unable to add show due to problem with show selection."
                      ))
                return self.redirect('/addShows/existingShows/')

            indexer = int(series_pieces[1])
            indexer_id = int(series_pieces[3])
            # Show name was sent in UTF-8 in the form
            show_name = xhtml_unescape(series_pieces[4]).decode('utf-8')
        else:
            # if no indexer was provided use the default indexer set in General settings
            if not providedIndexer:
                providedIndexer = sickbeard.INDEXER_DEFAULT

            indexer = int(providedIndexer)
            indexer_id = int(whichSeries)
            show_name = ek(os.path.basename,
                           ek(os.path.normpath, xhtml_unescape(fullShowPath)))

        # use the whole path if it's given, or else append the show name to the root dir to get the full show path
        if fullShowPath:
            show_dir = ek(os.path.normpath, xhtml_unescape(fullShowPath))
            extra_check_dir = show_dir
        else:
            folder_name = show_name
            s = sickchill.indexer.series_by_id(indexerid=indexer_id,
                                               indexer=indexer,
                                               language=indexerLang)
            if sickbeard.ADD_SHOWS_WITH_YEAR and s.firstAired:
                try:
                    year = '({0})'.format(
                        dateutil.parser.parse(s.firstAired).year)
                    if year not in folder_name:
                        folder_name = '{0} {1}'.format(s.seriesName, year)
                except (TypeError, ValueError):
                    logger.log(
                        _('Could not append the show year folder for the show: {0}'
                          ).format(folder_name))

            show_dir = ek(os.path.join, rootDir,
                          sanitize_filename(xhtml_unescape(folder_name)))
            extra_check_dir = ek(os.path.join, rootDir,
                                 sanitize_filename(xhtml_unescape(show_name)))

        # blanket policy - if the dir exists you should have used "add existing show" numbnuts
        if (ek(os.path.isdir, show_dir)
                or ek(os.path.isdir, extra_check_dir)) and not fullShowPath:
            ui.notifications.error(
                _("Unable to add show"),
                _("Folder {show_dir} exists already").format(
                    show_dir=show_dir))
            return self.redirect('/addShows/existingShows/')

        # don't create show dir if config says not to
        if sickbeard.ADD_SHOWS_WO_DIR:
            logger.log("Skipping initial creation of " + show_dir +
                       " due to config.ini setting")
        else:
            dir_exists = helpers.makeDir(show_dir)
            if not dir_exists:
                logger.log(
                    "Unable to create the folder " + show_dir +
                    ", can't add the show", logger.ERROR)
                ui.notifications.error(
                    _("Unable to add show"),
                    _("Unable to create the folder {show_dir}, can't add the show"
                      ).format(show_dir=show_dir))
                # Don't redirect to default page because user wants to see the new show
                return self.redirect("/home/")
            else:
                helpers.chmodAsParent(show_dir)

        # prepare the inputs for passing along
        scene = config.checkbox_to_value(scene)
        anime = config.checkbox_to_value(anime)
        season_folders = config.checkbox_to_value(season_folders)
        subtitles = config.checkbox_to_value(subtitles)
        subtitles_sr_metadata = config.checkbox_to_value(subtitles_sr_metadata)

        if whitelist:
            whitelist = short_group_names(whitelist)
        if blacklist:
            blacklist = short_group_names(blacklist)

        if not anyQualities:
            anyQualities = []
        if not bestQualities or try_int(quality_preset, None):
            bestQualities = []
        if not isinstance(anyQualities, list):
            anyQualities = [anyQualities]
        if not isinstance(bestQualities, list):
            bestQualities = [bestQualities]
        newQuality = Quality.combineQualities([int(q) for q in anyQualities],
                                              [int(q) for q in bestQualities])

        # add the show
        sickbeard.showQueueScheduler.action.add_show(
            indexer,
            indexer_id,
            showDir=show_dir,
            default_status=int(defaultStatus),
            quality=newQuality,
            season_folders=season_folders,
            lang=indexerLang,
            subtitles=subtitles,
            subtitles_sr_metadata=subtitles_sr_metadata,
            anime=anime,
            scene=scene,
            paused=None,
            blacklist=blacklist,
            whitelist=whitelist,
            default_status_after=int(defaultStatusAfter),
            root_dir=rootDir)
        ui.notifications.message(
            _('Show added'),
            _('Adding the specified show into {show_dir}').format(
                show_dir=show_dir))

        return finishAddShow()
예제 #37
0
    def run(self):

        ShowQueueItem.run(self)

        logger.log(u"Starting to add show {0}".format(
            "by ShowDir: {0}".format(self.showDir) if self.
            showDir else "by Indexer Id: {0}".format(self.indexer_id)))
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            logger.log(u"" + str(sickbeard.indexerApi(self.indexer).name) +
                       ": " + repr(lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the
            # Indexers provided series name
            if not self.showDir and self.root_dir:
                show_name = get_showname_from_indexer(self.indexer,
                                                      self.indexer_id,
                                                      self.lang)
                if show_name:
                    self.showDir = ek(os.path.join, self.root_dir,
                                      sanitize_filename(show_name))
                    dir_exists = makeDir(self.showDir)
                    if not dir_exists:
                        logger.log(
                            u"Unable to create the folder {0}, can't add the show"
                            .format(self.showDir))
                        return

                    chmodAsParent(self.showDir)
                else:
                    logger.log(
                        u"Unable to get a show {0}, can't add the show".format(
                            self.showDir))
                    return

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                logger.log(
                    u"Show in {} has no name on {}, probably searched with the wrong language."
                    .format(self.showDir,
                            sickbeard.indexerApi(self.indexer).name),
                    logger.ERROR)

                ui.notifications.error(
                    "Unable to add show",
                    "Show in " + self.showDir + " has no name on " +
                    str(sickbeard.indexerApi(self.indexer).name) +
                    ", probably the wrong language. Delete .nfo and add manually in the correct language."
                )
                self._finishEarly()
                return
            # if the show has no episodes/seasons
            if not s:
                logger.log(u"Show " + str(s['seriesname']) + " is on " +
                           str(sickbeard.indexerApi(self.indexer).name) +
                           " but contains no season/episode data.")
                ui.notifications.error(
                    "Unable to add show", "Show " + str(s['seriesname']) +
                    " is on " + str(sickbeard.indexerApi(self.indexer).name) +
                    " but contains no season/episode data.")
                self._finishEarly()
                return
        except Exception as e:
            logger.log(
                u"%s Error while loading information from indexer %s. Error: %r"
                % (self.indexer_id, sickbeard.indexerApi(
                    self.indexer).name, ex(e)), logger.ERROR)
            # logger.log(u"Show name with ID %s doesn't exist on %s anymore. If you are using trakt, it will be removed from your TRAKT watchlist. If you are adding manually, try removing the nfo and adding again" %
            #            (self.indexer_id, sickbeard.indexerApi(self.indexer).name), logger.WARNING)

            ui.notifications.error(
                "Unable to add show",
                "Unable to look up the show in %s on %s using ID %s, not using the NFO. Delete .nfo and try adding manually again."
                % (self.showDir, sickbeard.indexerApi(
                    self.indexer).name, self.indexer_id))

            if sickbeard.USE_TRAKT:

                trakt_id = sickbeard.indexerApi(
                    self.indexer).config['trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY,
                                     sickbeard.TRAKT_TIMEOUT)

                title = self.showDir.split("/")[-1]
                data = {'shows': [{'title': title, 'ids': {}}]}
                if trakt_id == 'tvdb_id':
                    data['shows'][0]['ids']['tvdb'] = self.indexer_id
                else:
                    data['shows'][0]['ids']['tvrage'] = self.indexer_id

                trakt_api.traktRequest("sync/watchlist/remove",
                                       data,
                                       method='POST')

            self._finishEarly()
            return

        try:
            newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders if self.flatten_folders is not None else sickbeard.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            logger.log(
                u"Setting all episodes to the specified default status: " +
                str(self.show.default_ep_status))
            self.show.default_ep_status = self.default_status

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(
                    self.show.indexerid)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

            # # be smartish about this
            # if self.show.genre and "talk show" in self.show.genre.lower():
            #     self.show.air_by_date = 1
            # if self.show.genre and "documentary" in self.show.genre.lower():
            #     self.show.air_by_date = 0
            # if self.show.classification and "sports" in self.show.classification.lower():
            #     self.show.sports = 1

        except sickbeard.indexer_exception as e:
            logger.log(
                u"Unable to add show due to an error with " +
                sickbeard.indexerApi(self.indexer).name + ": " + ex(e),
                logger.ERROR)
            if self.show:
                ui.notifications.error(
                    "Unable to add " + str(self.show.name) +
                    " due to an error with " +
                    sickbeard.indexerApi(self.indexer).name + "")
            else:
                ui.notifications.error(
                    "Unable to add show due to an error with " +
                    sickbeard.indexerApi(self.indexer).name + "")
            self._finishEarly()
            return

        except MultipleShowObjectsException:
            logger.log(
                u"The show in " + self.showDir +
                " is already in your show list, skipping", logger.WARNING)
            ui.notifications.error(
                'Show skipped', "The show in " + self.showDir +
                " is already in your show list")
            self._finishEarly()
            return

        except Exception as e:
            logger.log(u"Error trying to add show: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        logger.log(u"Retrieving show info from IMDb", logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as e:
            logger.log(u" Something wrong on IMDb api: " + ex(e),
                       logger.WARNING)
        except Exception as e:
            logger.log(u"Error loading IMDb info: " + ex(e), logger.ERROR)

        try:
            self.show.saveToDB()
        except Exception as e:
            logger.log(u"Error saving the show to the database: " + ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finishEarly()
            raise

        # add it to the show list
        sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            logger.log(
                u"Error with " + sickbeard.indexerApi(self.show.indexer).name +
                ", not creating episode list: " + ex(e), logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.buildNameCache(self.show)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            logger.log(u"Error searching dir for episodes: " + ex(e),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(
                u"Launching backlog for this show since its episodes are WANTED"
            )
            sickbeard.backlogSearchScheduler.action.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        if sickbeard.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickbeard.traktCheckerScheduler.action.manage_new_show(self.show)

            # add show to trakt.tv library
            if sickbeard.TRAKT_SYNC:
                sickbeard.traktCheckerScheduler.action.add_show_watchlist(
                    self.show)

            if sickbeard.TRAKT_SYNC_WATCHLIST:
                logger.log(u"update watchlist")
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        sickbeard.scene_numbering.xem_refresh(self.show.indexerid,
                                              self.show.indexer,
                                              force=True)

        # check if show has XEM mapping so we can determin if searches should go by scene numbering or indexer numbering.
        if not self.scene and sickbeard.scene_numbering.get_xem_numbering_for_show(
                self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        self.finish()
예제 #38
0
    def downloadResult(self, result):
        """
        Overridden to handle magnet links (using multiple fallbacks), and now libtorrent
        downloads also.
        """
        logger.log(u"Downloading a result from " + self.name + " at " + result.url)

        if sickbeard.USE_LIBTORRENT:
            # libtorrent can download torrent files from urls, but it's probably safer for us
            # to do it first so that we can report errors immediately.
            if result.url and (result.url.startswith('http://') or result.url.startswith('https://')):
                torrent = self.getURL(result.url)
                # and now that we have it, we can check the torrent file too!
                if not self.is_valid_torrent_data(torrent):
                    logger.log(u'The torrent retrieved from "%s" is not a valid torrent file.' % (result.url), logger.ERROR)
                    self.blacklistUrl(result.url)
                    return False
            else:
                torrent = result.url

            if torrent:
                return downloader.download_from_torrent(torrent=torrent, filename=result.name,
                                                        episodes=result.episodes, originalTorrentUrl=result.url,
                                                        blacklistOrigUrlOnFailure=True)
            else:
                logger.log(u'Failed to retrieve torrent from "%s"' % (result.url), logger.ERROR)
                return False
        else:
            # Ye olde way, using blackhole ...

            if result.url and result.url.startswith('magnet:'):
                torrent_hash = self.getHashFromMagnet(result.url)
                if torrent_hash:
                    urls = [url_fmt % torrent_hash for url_fmt in MAGNET_TO_TORRENT_URLS]
                else:
                    logger.log(u"Failed to handle magnet url %s, skipping..." % torrent_hash, logger.DEBUG)
                    self.blacklistUrl(result.url)
                    return False
            else:
                urls = [result.url]

            # use the result name as the filename
            fileName = ek.ek(os.path.join, sickbeard.TORRENT_DIR, helpers.sanitizeFileName(result.name) + '.' + self.providerType)

            for url in urls:
                logger.log(u"Trying d/l url: " + url, logger.DEBUG)
                data = self.getURL(url)

                if data == None:
                    logger.log(u"Got no data for " + url, logger.DEBUG)
                    # fall through to next iteration
                elif not self.is_valid_torrent_data(data):
                    logger.log(u"d/l url %s failed, not a valid torrent file" % (url), logger.MESSAGE)
                    self.blacklistUrl(url)
                else:
                    try:
                        fileOut = open(fileName, 'wb')
                        fileOut.write(data)
                        fileOut.close()
                        helpers.chmodAsParent(fileName)
                    except IOError, e:
                        logger.log("Unable to save the file: "+ex(e), logger.ERROR)
                        return False

                    logger.log(u"Success with url: " + url, logger.DEBUG)
                    return True
            else:
예제 #39
0
    def _combined_file_operation(self,
                                 file_path,
                                 new_path,
                                 new_base_name,
                                 associated_files=False,
                                 action=None,
                                 subtitles=False):
        """
        Performs a generic operation (move or copy) on a file. Can rename the file as well as change its location,
        and optionally move associated files too.
        
        file_path: The full path of the media file to act on
        new_path: Destination path where we want to move/copy the file to 
        new_base_name: The base filename (no extension) to use during the copy. Use None to keep the same name.
        associated_files: Boolean, whether we should copy similarly-named files too
        action: function that takes an old path and new path and does an operation with them (move/copy)
        """

        if not action:
            self._log(
                u"Must provide an action for the combined file operation",
                logger.ERROR)
            return

        file_list = [file_path]
        if associated_files:
            file_list = file_list + self._list_associated_files(file_path)
        elif subtitles:
            file_list = file_list + self._list_associated_files(
                file_path, True)

        if not file_list:
            self._log(
                u"There were no files associated with " + file_path +
                ", not moving anything", logger.DEBUG)
            return

        # create base name with file_path (media_file without .extension)
        old_base_name = file_path.rpartition('.')[0]
        old_base_name_length = len(old_base_name)

        # deal with all files
        for cur_file_path in file_list:

            cur_file_name = ek.ek(os.path.basename, cur_file_path)

            # get the extension without .
            cur_extension = cur_file_path[old_base_name_length + 1:]

            # check if file have subtitles language
            if os.path.splitext(
                    cur_extension)[1][1:] in common.subtitleExtensions:
                cur_lang = os.path.splitext(cur_extension)[0]
                if cur_lang in sickbeard.SUBTITLES_LANGUAGES:
                    cur_extension = cur_lang + os.path.splitext(
                        cur_extension)[1]

            # replace .nfo with .nfo-orig to avoid conflicts
            if cur_extension == 'nfo':
                cur_extension = 'nfo-orig'

            # If new base name then convert name
            if new_base_name:
                new_file_name = new_base_name + '.' + cur_extension
            # if we're not renaming we still want to change extensions sometimes
            else:
                new_file_name = helpers.replaceExtension(
                    cur_file_name, cur_extension)

            if sickbeard.SUBTITLES_DIR and cur_extension in common.subtitleExtensions:
                subs_new_path = ek.ek(os.path.join, new_path,
                                      sickbeard.SUBTITLES_DIR)
                dir_exists = helpers.makeDir(subs_new_path)
                if not dir_exists:
                    logger.log(
                        u"Unable to create subtitles folder " + subs_new_path,
                        logger.ERROR)
                else:
                    helpers.chmodAsParent(subs_new_path)
                new_file_path = ek.ek(os.path.join, subs_new_path,
                                      new_file_name)
            else:
                new_file_path = ek.ek(os.path.join, new_path, new_file_name)

            action(cur_file_path, new_file_path)
예제 #40
0
    def run(self):  # pylint: disable=too-many-branches, too-many-statements, too-many-return-statements

        super(QueueItemAdd, self).run()

        if self.showDir:
            try:
                assert isinstance(self.showDir, six.text_type)
            except AssertionError:
                logger.log(traceback.format_exc(), logger.WARNING)
                self._finish_early()
                return

        logger.log('Starting to add show {0}'.format(
            'by ShowDir: {0}'.format(self.showDir) if self.
            showDir else 'by Indexer Id: {0}'.format(self.indexer_id)))
        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = sickbeard.indexerApi(
                self.indexer).api_params.copy()
            lINDEXER_API_PARMS[
                'language'] = self.lang or sickbeard.INDEXER_DEFAULT_LANGUAGE

            logger.log('{0}: {1!r}'.format(
                sickbeard.indexerApi(self.indexer).name, lINDEXER_API_PARMS))

            t = sickbeard.indexerApi(
                self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the
            # Indexers provided series name
            if self.root_dir and not self.showDir:
                show_name = get_showname_from_indexer(self.indexer,
                                                      self.indexer_id,
                                                      self.lang)
                if not show_name:
                    logger.log(
                        'Unable to get a show {0}, can\'t add the show'.format(
                            self.showDir))
                    self._finish_early()
                    return

                self.showDir = ek(os.path.join, self.root_dir,
                                  sanitize_filename(show_name))

                dir_exists = makeDir(self.showDir)
                if not dir_exists:
                    logger.log(
                        'Unable to create the folder {0}, can\'t add the show'.
                        format(self.showDir))
                    self._finish_early()
                    return

                chmodAsParent(self.showDir)

            # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show
            if getattr(s, 'seriesname', None) is None:
                # noinspection PyPep8
                error_string = 'Show in {0} has no name on {1}, probably searched with the wrong language. Delete .nfo and add manually in the correct language.'.format(
                    self.showDir,
                    sickbeard.indexerApi(self.indexer).name)

                logger.log(error_string, logger.WARNING)
                ui.notifications.error('Unable to add show', error_string)

                self._finish_early()
                return

            # if the show has no episodes/seasons
            if not s:
                error_string = 'Show {0} is on {1} but contains no season/episode data.'.format(
                    s[b'seriesname'],
                    sickbeard.indexerApi(self.indexer).name)

                logger.log(error_string)
                ui.notifications.error('Unable to add show', error_string)

                self._finish_early()
                return
        except Exception as error:
            error_string = 'Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. Delete .nfo and try adding manually again.'.format(
                self.showDir,
                sickbeard.indexerApi(self.indexer).name, self.indexer_id)

            logger.log('{0}: {1}'.format(error_string, error), logger.ERROR)
            ui.notifications.error('Unable to add show', error_string)

            if sickbeard.USE_TRAKT:
                trakt_id = sickbeard.indexerApi(
                    self.indexer).config[b'trakt_id']
                trakt_api = TraktAPI(sickbeard.SSL_VERIFY,
                                     sickbeard.TRAKT_TIMEOUT)

                title = self.showDir.split('/')[-1]
                data = {'shows': [{'title': title, 'ids': {}}]}
                if trakt_id == 'tvdb_id':
                    data['shows'][0]['ids']['tvdb'] = self.indexer_id
                else:
                    data['shows'][0]['ids']['tvrage'] = self.indexer_id

                trakt_api.traktRequest('sync/watchlist/remove',
                                       data,
                                       method='POST')

            self._finish_early()
            return

        try:
            try:
                newShow = TVShow(self.indexer, self.indexer_id, self.lang)
            except MultipleShowObjectsException as error:
                # If we have the show in our list, but the location is wrong, lets fix it and refresh!
                existing_show = Show.find(sickbeard.showList, self.indexer_id)
                # noinspection PyProtectedMember
                if existing_show and not ek(os.path.isdir,
                                            existing_show._location):  # pylint: disable=protected-access
                    newShow = existing_show
                else:
                    raise error

            newShow.loadFromIndexer()

            self.show = newShow

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT
            self.show.subtitles_sr_metadata = self.subtitles_sr_metadata
            self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT
            self.show.season_folders = self.season_folders if self.season_folders is not None else sickbeard.SEASON_FOLDERS_DEFAULT
            self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT
            self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT
            self.show.paused = self.paused if self.paused is not None else False

            # set up default new/missing episode status
            logger.log(
                'Setting all episodes to the specified default status: {0}'.
                format(self.show.default_ep_status))
            self.show.default_ep_status = self.default_status

            if self.show.anime:
                self.show.release_groups = BlackAndWhiteList(
                    self.show.indexerid)
                if self.blacklist:
                    self.show.release_groups.set_black_keywords(self.blacklist)
                if self.whitelist:
                    self.show.release_groups.set_white_keywords(self.whitelist)

            # # be smart-ish about this
            # if self.show.genre and 'talk show' in self.show.genre.lower():
            #     self.show.air_by_date = 1
            # if self.show.genre and 'documentary' in self.show.genre.lower():
            #     self.show.air_by_date = 0
            # if self.show.classification and 'sports' in self.show.classification.lower():
            #     self.show.sports = 1

        except sickbeard.indexer_exception as error:
            error_string = 'Unable to add {0} due to an error with {1}'.format(
                self.show.name if self.show else 'show',
                sickbeard.indexerApi(self.indexer).name)

            logger.log('{0}: {1}'.format(error_string, error), logger.ERROR)
            ui.notifications.error('Unable to add show', error_string)

            self._finish_early()
            return

        except MultipleShowObjectsException:
            error_string = 'The show in {0} is already in your show list, skipping'.format(
                self.showDir)
            logger.log(error_string, logger.WARNING)
            ui.notifications.error('Show skipped', error_string)

            self._finish_early()
            return

        except Exception as error:
            logger.log('Error trying to add show: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finish_early()
            raise

        logger.log('Retrieving show info from IMDb', logger.DEBUG)
        try:
            self.show.loadIMDbInfo()
        except imdb_exceptions.IMDbError as error:
            logger.log(' Something wrong on IMDb api: {0}'.format(error),
                       logger.WARNING)
        except Exception as error:
            logger.log('Error loading IMDb info: {0}'.format(error),
                       logger.ERROR)

        try:
            self.show.saveToDB()
        except Exception as error:
            logger.log(
                'Error saving the show to the database: {0}'.format(error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)
            self._finish_early()
            raise

        # add it to the show list
        if not Show.find(sickbeard.showList, self.indexer_id):
            sickbeard.showList.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as error:
            logger.log(
                'Error with {0}, not creating episode list: {1}'.format(
                    sickbeard.indexerApi(self.show.indexer).name, error),
                logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # update internal name cache
        name_cache.buildNameCache(self.show)

        try:
            self.show.loadEpisodesFromDir()
        except Exception as error:
            logger.log('Error searching dir for episodes: {0}'.format(error),
                       logger.ERROR)
            logger.log(traceback.format_exc(), logger.DEBUG)

        # if they set default ep status to WANTED then run the backlog to search for episodes
        # FIXME: This needs to be a backlog queue item!!!
        if self.show.default_ep_status == WANTED:
            logger.log(
                'Launching backlog for this show since its episodes are WANTED'
            )
            sickbeard.backlogSearchScheduler.action.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        self.show.flushEpisodes()

        if sickbeard.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickbeard.traktCheckerScheduler.action.manageNewShow(self.show)
            # add show to trakt.tv library
            if sickbeard.TRAKT_SYNC:
                sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(
                    self.show)

            if sickbeard.TRAKT_SYNC_WATCHLIST:
                logger.log('update watchlist')
                notifiers.trakt_notifier.update_watchlist(show_obj=self.show)

        # Load XEM data to DB for show
        scene_numbering.xem_refresh(self.show.indexerid,
                                    self.show.indexer,
                                    force=True)

        # check if show has XEM mapping so we can determine if searches should go by scene numbering or indexer numbering.
        if not self.scene and scene_numbering.get_xem_numbering_for_show(
                self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        # After initial add, set to default_status_after.
        self.show.default_ep_status = self.default_status_after

        super(QueueItemAdd, self).finish()
        self.finish()
예제 #41
0
                           logger.ERROR)
                return False

        if not r.status_code == 200:
            return False

        magnetFileName = ek.ek(
            os.path.join, sickbeard.TORRENT_DIR,
            helpers.sanitizeFileName(result.name) + '.' + self.providerType)
        magnetFileContent = r.content

        try:
            with open(magnetFileName, 'wb') as fileOut:
                fileOut.write(magnetFileContent)

            helpers.chmodAsParent(magnetFileName)

        except EnvironmentError, e:
            logger.log("Unable to save the file: " + ex(e), logger.ERROR)
            return False

        logger.log(u"Saved magnet link to " + magnetFileName + " ",
                   logger.MESSAGE)
        return True

    def findPropers(self, search_date=datetime.datetime.today()):

        results = []

        sqlResults = db.DBConnection().select(
            'SELECT s.show_name, e.showid, e.season, e.episode, e.status, e.airdate, s.indexer FROM tv_episodes AS e'