Exemplo n.º 1
0
    def _addMovie(self, movie, quality, year=None):

        if self._checkMovieExists(movie=movie, qualityId=quality):
            return

        log.info('Adding movie to database: %s' % movie.name)

        if movie.id:
            exists = Db.query(Movie).filter_by(movieDb=movie.id).first()
        else:
            exists = Db.query(Movie).filter_by(imdb=movie.imdb).first()

        if exists:
            log.info('Movie already exists, do update.')

            # Delete old qualities
            for x in exists.queue:
                x.active = False
                Db.flush()

            new = exists
        else:
            new = Movie()
            Db.add(new)

        # Update the stuff
        new.status = u'want'
        new.name = movie.name
        new.imdb = movie.imdb
        new.movieDb = movie.id
        new.quality = quality
        new.year = year if year and movie.year == 'None' else movie.year
        Db.flush()

        # Add qualities to the queue
        quality = Db.query(QualityTemplate).filter_by(id=quality).one()
        for type in quality.types:
            queue = MovieQueue()
            queue.qualityType = type.type
            queue.movieId = new.id
            queue.order = type.order
            queue.active = True
            queue.completed = False
            queue.waitFor = 0 if type.markComplete else quality.waitFor
            queue.markComplete = type.markComplete
            Db.add(queue)
            Db.flush()

        #Get xml from themoviedb and save to cache
        self.searchers.get('movie').getExtraInfo(new.id, overwrite=True)

        #gogo find nzb for added movie via Cron
        self.cron.get('yarr').forceCheck(new.id)

        self.flash.add('movie-' + str(new.id),
                       '"%s" (%s) added.' % (new.name, new.year))
Exemplo n.º 2
0
    def _addMovie(self, movie, quality, year = None):

        if self._checkMovieExists(movie=movie):
           return

        log.info('Adding movie to database: %s' % movie.name)

        if movie.id:
            exists = Db.query(Movie).filter_by(movieDb = movie.id).first()
        else:
            exists = Db.query(Movie).filter_by(imdb = movie.imdb).first()

        if exists:
            log.info('Movie already exists, do update.')

            # Delete old qualities
            for x in exists.queue:
                x.active = False
                Db.flush()

            new = exists
        else:
            new = Movie()
            Db.add(new)

        # Update the stuff
        new.status = u'want'
        new.name = movie.name
        new.imdb = movie.imdb
        new.movieDb = movie.id
        new.quality = quality
        new.year = year if year and movie.year == 'None' else movie.year
        Db.flush()

        # Add qualities to the queue
        quality = Db.query(QualityTemplate).filter_by(id = quality).one()
        for type in quality.types:
            queue = MovieQueue()
            queue.qualityType = type.type
            queue.movieId = new.id
            queue.order = type.order
            queue.active = True
            queue.completed = False
            queue.waitFor = 0 if type.markComplete else quality.waitFor
            queue.markComplete = type.markComplete
            Db.add(queue)
            Db.flush()

        #Get xml from themoviedb and save to cache
        self.searchers.get('movie').getExtraInfo(new.id, overwrite = True)

        #gogo find nzb for added movie via Cron
        self.cron.get('yarr').forceCheck(new.id)

        self.flash.add('movie-' + str(new.id), '"%s" (%s) added.' % (new.name, new.year))
Exemplo n.º 3
0
    def saveExtra(self, id, name, value):

        exists = Db.query(MovieExtra).filter(and_(MovieExtra.movieId == id, MovieExtra.name == name)).first()
        if not exists:
            exists = MovieExtra()
            Db.add(exists)

        exists.movieId = id
        exists.name = name
        exists.value = value
        Db.flush()
Exemplo n.º 4
0
    def saveExtra(self, id, name, value):

        exists = Db.query(MovieExtra).filter(and_(MovieExtra.movieId == id, MovieExtra.name == name)).first()
        if not exists:
            exists = MovieExtra()
            Db.add(exists)

        exists.movieId = id
        exists.name = name
        exists.value = value
        Db.flush()
Exemplo n.º 5
0
    def save(self, movie, result):

        row = Db.query(MovieETA).filter_by(movieId=movie.id).first()
        if not row:
            row = MovieETA()
            Db.add(row)

        row.movieId = movie.id
        row.theater = result.get('theater')
        row.dvd = result.get('dvd')
        row.bluray = result.get('bluray')
        row.lastCheck = result.get('expires')
        Db.flush()
Exemplo n.º 6
0
    def addToHistory(self, movie, file, key, data):
        key = self.getKey(key)
        movieId = 0 if not movie else movie.id

        new = SubtitleHistory()
        new.movie = movieId
        new.file = latinToAscii(file)
        new.subtitle = key
        new.status = u'downloaded'
        new.data = str(data)
        Db.add(new)

        Db.flush()
Exemplo n.º 7
0
    def save(self, movie, result):

        row = Db.query(MovieETA).filter_by(movieId = movie.id).first()
        if not row:
            row = MovieETA()
            Db.add(row)

        row.movieId = movie.id
        row.theater = result.get('theater')
        row.dvd = result.get('dvd')
        row.bluray = result.get('bluray')
        row.lastCheck = result.get('expires')
        Db.flush()
Exemplo n.º 8
0
    def save(self, movie, result):

        row = Db.query(MovieETA).filter_by(movieId = movie.id).first()
        if not row:
            row = MovieETA()
            Db.add(row)

        row.movieId = movie.id
        row.videoEtaId = result.get('id', 0)
        row.theater = result.get('theater', 0)
        row.dvd = result.get('dvd', 0)
        row.bluray = result.get('bluray', 0)
        row.lastCheck = int(time.time())
        Db.flush()
Exemplo n.º 9
0
    def create(self, name, label, types, waitFor=0, custom=True, order=0):

        newQ = QualityTemplate()
        exists = Db.query(QualityTemplate).filter(
            or_(QualityTemplate.name == name,
                QualityTemplate.id == name)).first()
        if not exists:
            log.info('Creating custom=%s quality: %s' % (custom, name))
            newQ.name = name
            newQ.label = label
            newQ.custom = custom
            newQ.waitFor = waitFor
            newQ.order = order
            Db.add(newQ)
            Db.flush()
            exists = Db.query(QualityTemplate).filter_by(name=name).first()
        else:
            exists.label = label
            exists.waitFor = waitFor
            Db.flush()

        nr = 1
        for type in types:

            # Update if needed
            newT = Db.query(QualityTemplateType).filter_by(
                quality=exists.id, type=type['type']).first()
            if not newT:
                newT = QualityTemplateType()

            newT.quality = exists.id
            newT.order = nr
            newT.type = type['type']
            newT.markComplete = type['markComplete']
            nr += 1
            Db.add(newT)
            Db.flush()

        return True
Exemplo n.º 10
0
    def create(self, name, label, types, waitFor = 0, custom = True, order = 0):

        newQ = QualityTemplate()
        exists = Db.query(QualityTemplate).filter(or_(QualityTemplate.name == name, QualityTemplate.id == name)).first()
        if not exists:
            log.info('Creating custom=%s quality: %s' % (custom, name))
            newQ.name = name
            newQ.label = label
            newQ.custom = custom
            newQ.waitFor = waitFor
            newQ.order = order
            Db.add(newQ)
            Db.flush()
            exists = Db.query(QualityTemplate).filter_by(name = name).first()
        else:
            exists.label = label
            exists.waitFor = waitFor
            Db.flush()

        nr = 1
        for type in types:

            # Update if needed
            newT = Db.query(QualityTemplateType).filter_by(quality = exists.id, type = type['type']).first()
            if not newT:
                newT = QualityTemplateType()

            newT.quality = exists.id
            newT.order = nr
            newT.type = type['type']
            newT.markComplete = type['markComplete']
            nr += 1
            Db.add(newT)
            Db.flush()

        return True
Exemplo n.º 11
0
    def renameFiles(self, files, movie, queue = None):
        '''
        rename files based on movie data & conf
        '''

        multiple = False
        if len(files['files']) > 1:
            multiple = True

        destination = self.conf('destination')
        folderNaming = self.conf('foldernaming')
        fileNaming = self.conf('filenaming')

        # Remove weird chars from moviename
        moviename = re.sub(r"[\x00\/\\:\*\?\"<>\|]", '', movie.name)

        # Put 'The' at the end
        namethe = moviename
        if moviename[:3].lower() == 'the':
            namethe = moviename[3:] + ', The'

        #quality
        if not queue:
            queue = self.getQueue(movie)

        if not queue:
            quality = Qualities().guess(files['files'])
            queueId = 0
        else:
            quality = Qualities.types[queue.qualityType]['label']
            queueId = queue.id

        replacements = {
             'cd': '',
             'cdNr': '',
             'ext': '.mkv',
             'namethe': namethe.strip(),
             'thename': moviename.strip(),
             'year': movie.year,
             'first': namethe[0].upper(),
             'quality': quality,
        }
        if multiple:
            cd = 1

        justAdded = []

        totalSize = 0
        for file in files['files']:
            fullPath = os.path.join(file['path'], file['filename'])
            totalSize += os.path.getsize(fullPath)

            # Do something with ISO, as they should be between DVDRip and BRRIP
            ext = os.path.splitext(file['filename'])[1].lower()[1:]
            if ext == 'iso':
                totalSize -= (os.path.getsize(fullPath) / 1.6)
        log.info('Total size of new files is %s.' % int(totalSize / 1024 / 1024))

        finalDestination = None
        finalFilename = self.doReplace(fileNaming, replacements)
        for file in sorted(files['files']):
            log.info('Trying to find a home for: %s' % latinToAscii(file['filename']))

            replacements['ext'] = file['ext']

            if multiple:
                replacements['cd'] = ' cd' + str(cd)
                replacements['cdNr'] = ' ' + str(cd)

            replacements['original'] = file['root']
            replacements['video'] = self.getCodec(file['filename'], RenamerCron.videoCodecs)
            replacements['audio'] = self.getCodec(file['filename'], RenamerCron.audioCodecs)
            replacements['group'] = self.getGroup(file['root'])

            folder = self.doReplace(folderNaming, replacements)
            filename = self.doReplace(fileNaming, replacements)

            old = os.path.join(file['path'], file['filename'])
            dest = os.path.join(destination, folder, filename)

            finalDestination = os.path.dirname(dest)
            if not os.path.isdir(finalDestination):

                # Use same permissions as conf('destination') folder
                try:
                    #mode = os.stat(destination)
                    #chmod = mode[ST_MODE] & 07777
                    log.info('Creating directory %s' % finalDestination)
                    os.makedirs(finalDestination)
                    shutil.copymode(destination, finalDestination)
                    #os.chmod(finalDestination, chmod)
                except OSError:
                    log.error('Failed setting permissions for %s' % finalDestination)
                    os.makedirs(finalDestination)

            # Remove old if better quality
            removed = self.removeOld(os.path.join(destination, folder), justAdded, totalSize)

            if not os.path.isfile(dest) and removed:
                log.info('Moving file "%s" to %s.' % (latinToAscii(old), dest))
                shutil.move(old, dest)
                justAdded.append(dest)
            else:
                try:
                    path = file['path'].split(os.sep)
                    path.extend(['_EXISTS_' + path.pop()])
                    shutil.move(file['path'], os.sep.join(path))
                except IOError:
                    pass
                log.error('File %s already exists or not better.' % latinToAscii(filename))
                break

            #get subtitle if any & move
            if len(files['subtitles']) > 0:
                log.info('Moving matching subtitle.')
                subtitle = files['subtitles'].pop(0)
                replacements['ext'] = subtitle['ext']
                subFilename = self.doReplace(fileNaming, replacements)
                shutil.move(os.path.join(subtitle['path'], subtitle['filename']), os.path.join(destination, folder, subFilename))

            # Add to renaming history
            h = RenameHistory()
            h.movieId = movie.id
            h.movieQueue = queueId
            h.old = unicode(old.decode('utf-8'))
            h.new = unicode(dest.decode('utf-8'))
            Db.add(h)
            Db.flush()

            if multiple:
                cd += 1

        # Mark movie downloaded
        if queueId > 0:
            if queue.markComplete:
                movie.status = u'downloaded'

            queue.completed = True
            Db.flush()

        return {
            'directory': finalDestination,
            'filename': finalFilename
        }
Exemplo n.º 12
0
    def _search(self, movie, force = False):

        # Stop caching ffs!
        Db.expire_all()

        # Check release date and search for appropriate qualities
        preReleaseSearch = False
        dvdReleaseSearch = False
        now = int(time.time())

        # Search all if ETA is unknow, but try update ETA for next time.
        log.debug('Calculate ETA')
        checkETA = False
        if not movie.eta:
            checkETA = True
            preReleaseSearch = True
            dvdReleaseSearch = True
        else:
            # Prerelease 1 week before theaters
            if movie.eta.theater <= now + 604800:
                preReleaseSearch = True

            # dvdRelease 6 weeks before dvd release
            if movie.eta.dvd <= now + 3628800:
                preReleaseSearch = True
                dvdReleaseSearch = True

            # Dvd date is unknown but movie is in theater already
            if movie.eta.dvd == 0 and movie.eta.theater > now:
                dvdReleaseSearch = False

            # Force ETA check
            if movie.eta.lastCheck < now:
                checkETA = True

        # Minimal week interval for ETA check
        if checkETA and self.config.get('MovieETA', 'enabled'):
            cherrypy.config.get('searchers').get('etaQueue').put({'id':movie.id})

        for queue in movie.queue:

            # Movie already found, don't search further
            if queue.completed:
                log.debug('%s already completed for "%s". Not searching for any qualities below.' % (queue.qualityType, movie.name))
                return True

            # only search for active and not completed, minimal 1 min since last search
            if queue.active and not queue.completed and not self.abort and not self.stop:

                #skip if no search is set
                log.debug('Needs a search?')
                if (not ((preReleaseSearch and queue.qualityType in Qualities.preReleases) or (dvdReleaseSearch and not queue.qualityType in Qualities.preReleases))) and not queue.lastCheck < (now - int(self.config.get('Intervals', 'search')) * 7200):
                    continue

                log.debug('Start searching for movie: %s' % movie.name)
                highest = self.provider.find(movie, queue)
                log.debug('End searching for movie: %s' % movie.name)

                #send highest to SABnzbd & mark as snatched
                if highest:
                    log.debug('Found highest')

                    #update what I found
                    queue.name = latinToAscii(highest.name)
                    queue.link = highest.detailUrl
                    Db.flush()

                    waitFor = queue.waitFor * (60 * 60 * 24)

                    if queue.markComplete or (not queue.markComplete and highest.date + waitFor < time.time()):
                        time.sleep(10) # Give these APIs air!
                        if self.config.get('NZB', 'sendTo') == 'Sabnzbd' and highest.type == 'nzb':
                            success = self.sabNzbd.send(highest, movie.imdb)
                        elif self.config.get('NZB', 'sendTo') == 'Nzbget' and highest.type == 'nzb':
                            success = self.nzbGet.send(highest)
                        elif self.config.get('Torrents', 'sendTo') == 'Transmission' and highest.type == 'torrent':
                            success = self.transmission.send(highest, movie.imdb)
                        else:
                            success = self.blackHole(highest)

                    else:
                        success = False
                        log.info('Found %s but waiting for %d hours.' % (highest.name, ((highest.date + waitFor) - time.time()) / (60 * 60)))

                    # Set status
                    if success:
                        log.debug('Success')
                        movie.status = u'snatched' if queue.markComplete else u'waiting'
                        movie.dateChanged = datetime.datetime.now()
                        queue.lastCheck = now
                        queue.completed = True
                        Db.flush()

                        # Add to history
                        h = History()
                        h.movie = movie.id
                        h.value = str(highest.id) + '-' + str(highest.size)
                        h.status = u'snatched'
                        Db.add(h)
                        Db.flush()

                        # Notify PROWL
                        if self.config.get('PROWL', 'onSnatch'):
                            log.debug('PROWL')
                            prowl = PROWL()
                            prowl.notify(highest.name, 'Download Started')

                        # Notify XBMC
                        if self.config.get('XBMC', 'onSnatch'):
                            log.debug('XBMC')
                            xbmc = XBMC()
                            xbmc.notify('Snatched %s' % highest.name)

                        # Notify GROWL
                        if self.config.get('GROWL', 'onSnatch'):
                            log.debug('GROWL')
                            growl = GROWL()
                            growl.notify('Snatched %s' % highest.name, 'Download Started')

                        # Notify Notifo
                        if self.config.get('Notifo', 'onSnatch'):
                            log.debug('Notifo')
                            notifo = Notifo()
                            notifo.notify('%s' % highest.name, "Snatched:")

                        # Notify NotifyMyAndroid
                        if self.config.get('NMA', 'onSnatch'):
                            log.debug('NotifyMyAndroid')
                            nma = NMA()
                            nma.notify('Download Started', 'Snatched %s' % highest.name)

                        # Notify Twitter
                        if self.config.get('Twitter', 'onSnatch'):
                            log.debug('Twitter')
                            twitter = Twitter()
                            twitter.notify('Download Started', 'Snatched %s' % highest.name)

                    return True

                queue.lastCheck = now
                Db.flush()

        return False
Exemplo n.º 13
0
    def renameFiles(self, movie):
        """
        rename files based on movie data & conf
        """

        multiple = False
        if len(movie["files"]) > 1:
            multiple = True

        destination = self.conf("destination")
        folderNaming = self.conf("foldernaming")
        fileNaming = self.conf("filenaming")

        # Remove weird chars from moviename
        moviename = re.sub(r"[\x00\/\\:\*\?\"<>\|]", "", movie["info"].get("name"))

        # Put 'The' at the end
        namethe = moviename
        if moviename[:4].lower() == "the ":
            namethe = moviename[4:] + ", The"

        replacements = {
            "cd": "",
            "cdNr": "",
            "ext": "mkv",
            "namethe": namethe.strip(),
            "thename": moviename.strip(),
            "year": movie["info"]["year"],
            "first": namethe[0].upper(),
            "quality": movie["info"]["quality"],
            "video": movie["info"]["codec"]["video"],
            "audio": movie["info"]["codec"]["audio"],
            "group": movie["info"]["group"],
            "resolution": movie["info"]["resolution"],
            "sourcemedia": movie["info"]["sourcemedia"],
        }

        if multiple:
            cd = 1

        justAdded = []
        finalDestination = None

        # clean up post-processing script
        ppScriptName = movie["info"].get("ppScriptName")
        ppDirName = self.config.get("Sabnzbd", "ppDir")
        if ppScriptName:
            if ppDirName:
                ppPath = os.path.join(ppDirName, ppScriptName)
                try:
                    os.remove(ppPath)
                    log.info("Removed post-processing script: %s" % ppPath)
                except:
                    log.info("Couldn't remove post-processing script: %s" % ppPath)
            else:
                log.info("Don't know where the post processing script is located, not removing %s" % ppScriptName)

        filenames = []

        for file in movie["files"]:
            log.info("Trying to find a home for: %s" % latinToAscii(file["filename"]))

            replacements["ext"] = file["ext"]

            if multiple:
                replacements["cd"] = " cd" + str(cd)
                replacements["cdNr"] = " " + str(cd)

            replacements["original"] = file["filename"]

            folder = self.doReplace(folderNaming, replacements)
            filename = self.doReplace(fileNaming, replacements)
            filenames.append(filename)

            old = os.path.join(movie["path"], file["filename"])
            dest = os.path.join(destination, folder, filename)

            finalDestination = os.path.dirname(dest)
            if not os.path.isdir(finalDestination):

                try:
                    log.info("Creating directory %s" % finalDestination)
                    os.makedirs(finalDestination)
                    shutil.copymode(destination, finalDestination)
                except OSError:
                    log.error("Failed changing permissions %s" % finalDestination)

            # Remove old if better quality
            removed = self.removeOld(os.path.join(destination, folder), justAdded, movie["info"]["size"])

            if not os.path.isfile(dest) and removed:
                log.info('Moving file "%s" to %s.' % (latinToAscii(old), dest))

                if not _move(old, dest):
                    break
                justAdded.append(dest)
            else:
                log.error("File %s already exists or not better." % latinToAscii(filename))
                path = file["path"].split(os.sep)
                path.extend(["_EXISTS_" + path.pop()])
                old = file["path"]
                dest = os.sep.join(path)
                _move(old, dest)
                # Break in any case, why did you do that Ruud?
                break

            # get subtitle if any & move
            for type in movie["subtitles"]:
                if len(movie["subtitles"][type]) > 0:
                    log.info("Moving matching subtitle.")

                    subtitle = movie["subtitles"][type].pop(0)

                    replacements["original"] = subtitle["filename"]
                    replacements["ext"] = subtitle["ext"]

                    subDest = os.path.join(destination, folder, self.doReplace(fileNaming, replacements))
                    old = os.path.join(movie["path"], subtitle["filename"])
                    if not _move(old, subDest):
                        break
                    justAdded.append(subDest)  # Add to ignore list when removing stuff.

            # Add to renaming history
            log.debug("renamehistory start")
            h = RenameHistory()
            Db.add(h)

            try:
                h.movieQueue = movie["queue"].id
            except:
                h.movieQueue = 0

            h.old = unicode(old.decode("utf-8"))
            h.new = unicode(dest.decode("utf-8"))
            Db.flush()
            log.debug("renamehistory end")

            if multiple:
                cd += 1

        # Mark movie downloaded
        log.debug("queue downloaded start")
        if movie["queue"] and movie["queue"].id > 0:
            if movie["queue"].markComplete:
                movie["movie"].status = u"downloaded"

            movie["queue"].completed = True
            Db.flush()
        log.debug("queue downloaded end")

        return {"directory": finalDestination, "filenames": filenames}
Exemplo n.º 14
0
    def _addMovie(self, movie, quality, year = None):

        if cherrypy.config.get('config').get('XBMC', 'dbpath'):
            for root, dirs, files in os.walk(cherrypy.config.get('config').get('XBMC', 'dbpath')):
                for file in files:
                    if file.startswith('MyVideos'):
                        dbfile = os.path.join(root, file)

            if dbfile:
                #------Opening connection to XBMC DB------
                connXbmc = MySqlite.connect(dbfile)
                if connXbmc:
                    log.debug('Checking if movie exists in XBMC by IMDB id:' + movie.imdb)
                    connXbmc.row_factory = MySqlite.Row
                    cXbmc = connXbmc.cursor()
                    cXbmc.execute('select c09 from movie where c09="' + movie.imdb + '"')
                    #------End of Opening connection to XBMC DB------
                    inXBMC = False
                    for rowXbmc in cXbmc: # do a final check just to be sure
                        log.debug('Found in XBMC:' + rowXbmc["c09"])
                        if movie.imdb == rowXbmc["c09"]:
                            inXBMC = True
                        else:
                            inXBMC = False

                    cXbmc.close()

                    if inXBMC:
                        log.info('Movie already exists in XBMC, skipping.')
                        return
                else:
                    log.info('Could not connect to the XBMC database at ' + cherrypy.config.get('config').get('XBMC', 'dbpath'))
            else:
                log.info('Could not find the XBMC MyVideos db at ' + cherrypy.config.get('config').get('XBMC', 'dbpath'))

        log.info('Adding movie to database: %s' % movie.name)

        if movie.id:
            exists = Db.query(Movie).filter_by(movieDb = movie.id).first()
        else:
            exists = Db.query(Movie).filter_by(imdb = movie.imdb).first()

        if exists:
            log.info('Movie already exists, do update.')

            # Delete old qualities
            for x in exists.queue:
                x.active = False
                Db.flush()

            new = exists
        else:
            new = Movie()
            Db.add(new)

        # Update the stuff
        new.status = u'want'
        new.name = movie.name
        new.imdb = movie.imdb
        new.movieDb = movie.id
        new.quality = quality
        new.year = year if year and movie.year == 'None' else movie.year
        Db.flush()

        # Add qualities to the queue
        quality = Db.query(QualityTemplate).filter_by(id = quality).one()
        for type in quality.types:
            queue = MovieQueue()
            queue.qualityType = type.type
            queue.movieId = new.id
            queue.order = type.order
            queue.active = True
            queue.completed = False
            queue.waitFor = 0 if type.markComplete else quality.waitFor
            queue.markComplete = type.markComplete
            Db.add(queue)
            Db.flush()

        #Get xml from themoviedb and save to cache
        self.searchers.get('movie').getExtraInfo(new.id, overwrite = True)

        #gogo find nzb for added movie via Cron
        self.cron.get('yarr').forceCheck(new.id)

        self.flash.add('movie-' + str(new.id), '"%s" (%s) added.' % (new.name, new.year))
Exemplo n.º 15
0
    def determineMovie(self, movie):
        result = False

        movieName = self.cleanName(movie['folder'])
        movieYear = self.findYear(movie['folder'])

        #check to see if the downloaded movie nfo file agrees with what we thought we were downloading
        if movie['info']['cpnfoImdb'] and movie['info']['imdb']:
            cpnfoimdb = 'tt' + movie['info']['cpnfoImdb'].replace("tt", '')
            nfoimdb = 'tt' + movie['info']['imdb'].replace("tt", '')
            if cpnfoimdb != nfoimdb:
                log.info(
                    "Downloaded movie's nfo has imdb id that doesn't match what we though we downloaded"
                )
            movie['info']['imdb'] = cpnfoimdb

        if movie['info']['imdb']:
            byImdb = self.getMovieByIMDB(movie['info']['imdb'])
            if byImdb:
                return byImdb
            else:
                result = cherrypy.config['searchers']['movie'].findByImdbId(
                    movie['info']['imdb'])

        if not result:

            # Check and see if name is in queue
            try:
                queue = Db.query(MovieQueue).filter_by(
                    name=movie['folder']).first()
                if queue:
                    log.info('Found movie via MovieQueue.')
                    return queue.Movie
            except:
                pass

            # Find movie via movie name
            try:
                m = Db.query(Movie).filter_by(name=movieName).first()
                if m:
                    log.info('Found movie via moviename.')
                    return m
            except:
                pass

            # Try and match the movies via filenaming
            for file in movie['files']:
                dirnames = movie['path'].lower().replace(
                    unicode(self.config.get('Renamer', 'download')).lower(),
                    '').split(os.path.sep)
                dirnames.append(file['filename'])
                dirnames.reverse()

                for dir in dirnames:
                    dir = self.cleanName(dir)

                    # last resort, match every word in path to db
                    lastResort = {}
                    dirSplit = re.split('\W+', dir.lower())
                    for s in dirSplit:
                        if s:
                            results = Db.query(Movie).filter(
                                Movie.name.like('%' + s + '%')).filter_by(
                                    year=movieYear).all()
                            for r in results:
                                lastResort[r.id] = r

                    for l in lastResort.itervalues():
                        wordCount = 0
                        for word in dirSplit:
                            if word in l.name.lower():
                                wordCount += 1

                        if wordCount == len(dirSplit) and len(dirSplit) > 0:
                            return l

            # Search tMDB
            if movieName and not movieName in ['movie']:
                log.info('Searching for "%s".' % movie['folder'])
                result = cherrypy.config['searchers']['movie'].find(
                    movieName + ' ' + movieYear, limit=1)

        if result:
            movie = self.getMovieByIMDB(result.imdb)

            if not movie:
                new = Movie()
                Db.add(new)

                try:
                    # Add found movie as downloaded
                    new.status = u'downloaded'
                    new.name = result.name
                    new.imdb = result.imdb
                    new.movieDb = result.id
                    new.year = result.year
                    Db.flush()

                    return new
                except Exception, e:
                    log.error('Movie could not be added to database %s. %s' %
                              (result, e))
            else:
                return movie
Exemplo n.º 16
0
    def _search(self, movie, force = False):

        # Stop caching ffs!
        Db.expire_all()

        # Check release date and search for appropriate qualities
        preReleaseSearch = False
        dvdReleaseSearch = False
        now = int(time.time())

        # Search all if ETA is unknow, but try update ETA for next time.
        checkETA = False
        if not movie.eta or force:
            checkETA = True
            preReleaseSearch = True
            dvdReleaseSearch = True
        else:
            # Prerelease 1 week before theaters
            if movie.eta.theater <= now + 604800:
                preReleaseSearch = True

            # dvdRelease 6 weeks before dvd release
            if movie.eta.dvd <= now + 3628800:
                preReleaseSearch = True
                dvdReleaseSearch = True

            # Dvd date is unknown but movie is in theater already
            if movie.eta.dvd == 0 and movie.eta.theater > now:
                checkETA = True
                dvdReleaseSearch = False

            # Force ETA check once a week or 3 weeks
            if ((movie.eta.dvd == 0 or movie.eta.theater == 0) and movie.eta.lastCheck < now - 604800) or (movie.eta.lastCheck < now - 1814400):
                checkETA = True

        # Minimal week interval for ETA check
        if checkETA:
            cherrypy.config.get('searchers').get('etaQueue').put({'id':movie.id})

        for queue in movie.queue:

            # Movie already found, don't search further 
            if queue.completed:
                log.debug('%s already completed for "%s". Not searching for any qualities below.' % (queue.qualityType, movie.name))
                return True

            # only search for active and not completed, minimal 1 min since last search
            if queue.active and not queue.completed and not self.abort and not self.stop:

                #skip if no search is set
                if (not ((preReleaseSearch and queue.qualityType in Qualities.preReleases) or (dvdReleaseSearch and not queue.qualityType in Qualities.preReleases))) and not queue.lastCheck < (now - int(self.config.get('Intervals', 'search')) * 7200):
                    continue

                highest = self.provider.find(movie, queue)

                #send highest to SABnzbd & mark as snatched
                if highest:

                    #update what I found
                    queue.name = latinToAscii(highest.name)
                    queue.link = highest.detailUrl
                    Db.flush()

                    waitFor = queue.waitFor * (60 * 60 * 24)

                    if queue.markComplete or (not queue.markComplete and highest.date + waitFor < time.time()):
                        time.sleep(10) # Give these APIs air!
                        if self.config.get('NZB', 'sendTo') == 'Sabnzbd' and highest.type == 'nzb':
                            success = self.sabNzbd.send(highest, movie.imdb)
                        else:
                            success = self.blackHole(highest)
                    else:
                        success = False
                        log.info('Found %s but waiting for %d hours.' % (highest.name, ((highest.date + waitFor) - time.time()) / (60 * 60)))

                    # Set status
                    if success:
                        movie.status = u'snatched' if queue.markComplete else u'waiting'
                        movie.dateChanged = datetime.datetime.now()
                        queue.lastCheck = now
                        queue.completed = True
                        Db.flush()

                        # Add to history
                        h = History()
                        h.movie = movie.id
                        h.value = str(highest.id) + '-' + str(highest.size)
                        h.status = u'snatched'
                        Db.add(h)
                        Db.flush()

                    return True

                queue.lastCheck = now
                Db.flush()

        return False
Exemplo n.º 17
0
    def determineMovie(self, movie):

        movieName = self.cleanName(movie['folder'])
        movieYear = self.findYear(movie['folder'])

        if movie['nfo']:
            for nfo in movie['nfo']:
                nfoFile = open(os.path.join(movie['path'], nfo), 'r').read()
                imdbId = self.getImdb(nfoFile)
                if imdbId:
                    m = cherrypy.config['searchers']['movie'].findByImdbId(imdbId)
                    if m:
                        return m

        # check and see if name is in queue
        queue = Db.query(MovieQueue).filter_by(name = movieName).first()
        if queue:
            log.info('Found movie via MovieQueue.')
            return queue.Movie

        for file in movie['files']:
            dirnames = movie['path'].split(os.path.sep)
            dirnames.append(file['filename'])
            dirnames.reverse()

            for dir in dirnames:
                dir = self.cleanName(dir)

                # last resort, match every word in path to db
                lastResort = {}
                dirSplit = re.split('\W+', dir.lower())
                for s in dirSplit:
                    if s:
                        results = Db.query(Movie).filter(Movie.name.like('%' + s + '%')).filter_by(year = movieYear).all()
                        for r in results:
                            lastResort[r.id] = r

                for l in lastResort.itervalues():
                    wordCount = 0
                    for word in dirSplit:
                        if word in l.name.lower():
                            wordCount += 1

                    if wordCount == len(dirSplit) and len(dirSplit) > 0:
                        return l

        # Search tMDB
        if movieName:
            log.info('Searching for "%s".' % movie['folder'])
            result = cherrypy.config['searchers']['movie'].find(movieName + ' ' + movieYear, limit = 1)
            if result:
                movie = self.getMovieByIMDB(result.imdb)

                if not movie:
                    new = Movie()
                    Db.add(new)

                    try:
                        # Add found movie as downloaded
                        new.status = u'downloaded'
                        new.name = result.name
                        new.imdb = result.imdb
                        new.movieDb = result.id
                        new.year = result.year
                        Db.flush()

                        return new
                    except Exception, e:
                        log.error('Movie could not be added to database %s. %s' % (result, e))
                else:
                    return movie
Exemplo n.º 18
0
    def renameFiles(self, movie):
        '''
        rename files based on movie data & conf
        '''

        multiple = False
        if len(movie['files']) > 1:
            multiple = True

        destination = self.conf('destination')
        folderNaming = self.conf('foldernaming')
        fileNaming = self.conf('filenaming')

        # Remove weird chars from moviename
        moviename = re.sub(r"[\x00\/\\:\*\?\"<>\|]", '', movie['info'].get('name'))

        # Put 'The' at the end
        namethe = moviename
        if moviename[:3].lower() == 'the':
            namethe = moviename[3:] + ', The'

        replacements = {
             'cd': '',
             'cdNr': '',
             'ext': '.mkv',
             'namethe': namethe.strip(),
             'thename': moviename.strip(),
             'year': movie['info']['year'],
             'first': namethe[0].upper(),
             'quality': movie['info']['quality'],
             'video': movie['info']['codec']['video'],
             'audio': movie['info']['codec']['audio'],
             'group': movie['info']['group'],
             'resolution': movie['info']['resolution'],
             'sourcemedia': movie['info']['sourcemedia']
        }

        if multiple:
            cd = 1

        justAdded = []
        finalDestination = None
        finalFilename = self.doReplace(fileNaming, replacements)

        for file in movie['files']:
            log.info('Trying to find a home for: %s' % latinToAscii(file['filename']))

            replacements['ext'] = file['ext']

            if multiple:
                replacements['cd'] = ' cd' + str(cd)
                replacements['cdNr'] = ' ' + str(cd)

            replacements['original'] = file['filename']

            folder = self.doReplace(folderNaming, replacements)
            filename = self.doReplace(fileNaming, replacements)

            old = os.path.join(movie['path'], file['filename'])
            dest = os.path.join(destination, folder, filename)

            finalDestination = os.path.dirname(dest)
            if not os.path.isdir(finalDestination):

                try:
                    log.info('Creating directory %s' % finalDestination)
                    os.makedirs(finalDestination)
                    shutil.copymode(destination, finalDestination)
                except OSError:
                    log.error('Failed changing permissions %s' % finalDestination)

            # Remove old if better quality
            removed = self.removeOld(os.path.join(destination, folder), justAdded, movie['info']['size'])

            if not os.path.isfile(dest) and removed:
                log.info('Moving file "%s" to %s.' % (latinToAscii(old), dest))
                shutil.move(old, dest)
                justAdded.append(dest)
            else:
                try:
                    path = file['path'].split(os.sep)
                    path.extend(['_EXISTS_' + path.pop()])
                    shutil.move(file['path'], os.sep.join(path))
                except IOError:
                    pass
                log.error('File %s already exists or not better.' % latinToAscii(filename))
                break

            #get subtitle if any & move
            for type in movie['subtitles']:
                if len(movie['subtitles'][type]) > 0:
                    log.info('Moving matching subtitle.')

                    subtitle = movie['subtitles'][type].pop(0)
                    replacements['ext'] = subtitle['ext']
                    subDest = os.path.join(destination, folder, self.doReplace(fileNaming, replacements))

                    shutil.move(os.path.join(movie['path'], subtitle['filename']), subDest)
                    justAdded.append(subDest) # Add to ignore list when removing stuff.

            # Add to renaming history
            h = RenameHistory()
            h.movieId = movie['movie'].id
            h.movieQueue = movie['history'].movieQueue if movie['history'] else 0
            h.old = unicode(old.decode('utf-8'))
            h.new = unicode(dest.decode('utf-8'))
            Db.add(h)
            Db.flush()

            if multiple:
                cd += 1

        # Mark movie downloaded
        if movie['queue'] and movie['queue'].id > 0:
            if movie['queue'].markComplete:
                movie['movie'].status = u'downloaded'

            movie['queue'].completed = True
            Db.flush()

        return {
            'directory': finalDestination,
            'filename': finalFilename
        }
Exemplo n.º 19
0
    def renameFiles(self, movie):
        """
        rename files based on movie data & conf
        """

        multiple = False
        if len(movie["files"]) > 1:
            multiple = True

        destination = self.conf("destination")
        folderNaming = self.conf("foldernaming")
        fileNaming = self.conf("filenaming")

        # Remove weird chars from moviename
        moviename = re.sub(r"[\x00\/\\:\*\?\"<>\|]", "", movie["info"].get("name"))

        # Put 'The' at the end
        namethe = moviename
        if moviename[:4].lower() == "the ":
            namethe = moviename[4:] + ", The"

        replacements = {
            "cd": "",
            "cdNr": "",
            "ext": ".mkv",
            "namethe": namethe.strip(),
            "thename": moviename.strip(),
            "year": movie["info"]["year"],
            "first": namethe[0].upper(),
            "quality": movie["info"]["quality"],
            "video": movie["info"]["codec"]["video"],
            "audio": movie["info"]["codec"]["audio"],
            "group": movie["info"]["group"],
            "resolution": movie["info"]["resolution"],
            "sourcemedia": movie["info"]["sourcemedia"],
        }

        if multiple:
            cd = 1

        justAdded = []
        finalDestination = None
        finalFilename = self.doReplace(fileNaming, replacements)

        for file in movie["files"]:
            log.info("Trying to find a home for: %s" % latinToAscii(file["filename"]))

            replacements["ext"] = file["ext"]

            if multiple:
                replacements["cd"] = " cd" + str(cd)
                replacements["cdNr"] = " " + str(cd)

            replacements["original"] = file["filename"]

            folder = self.doReplace(folderNaming, replacements)
            filename = self.doReplace(fileNaming, replacements)

            old = os.path.join(movie["path"], file["filename"])
            dest = os.path.join(destination, folder, filename)

            finalDestination = os.path.dirname(dest)
            if not os.path.isdir(finalDestination):

                try:
                    log.info("Creating directory %s" % finalDestination)
                    os.makedirs(finalDestination)
                    shutil.copymode(destination, finalDestination)
                except OSError:
                    log.error("Failed changing permissions %s" % finalDestination)

            # Remove old if better quality
            removed = self.removeOld(os.path.join(destination, folder), justAdded, movie["info"]["size"])

            if not os.path.isfile(dest) and removed:
                log.info('Moving file "%s" to %s.' % (latinToAscii(old), dest))

                shutil.move(old, dest)
                justAdded.append(dest)
            else:
                try:
                    path = file["path"].split(os.sep)
                    path.extend(["_EXISTS_" + path.pop()])
                    shutil.move(file["path"], os.sep.join(path))
                except IOError:
                    pass
                log.error("File %s already exists or not better." % latinToAscii(filename))
                break

            # get subtitle if any & move
            for type in movie["subtitles"]:
                if len(movie["subtitles"][type]) > 0:
                    log.info("Moving matching subtitle.")

                    subtitle = movie["subtitles"][type].pop(0)
                    replacements["ext"] = subtitle["ext"]
                    subDest = os.path.join(destination, folder, self.doReplace(fileNaming, replacements))

                    shutil.move(os.path.join(movie["path"], subtitle["filename"]), subDest)
                    justAdded.append(subDest)  # Add to ignore list when removing stuff.

            # Add to renaming history
            h = RenameHistory()
            Db.add(h)

            h.movieQueue = movie["queue"].id if movie["queue"] else 0
            h.old = unicode(old.decode("utf-8"))
            h.new = unicode(dest.decode("utf-8"))
            Db.flush()

            if multiple:
                cd += 1

        # Mark movie downloaded
        if movie["queue"] and movie["queue"].id > 0:
            if movie["queue"].markComplete:
                movie["movie"].status = u"downloaded"

            movie["queue"].completed = True
            Db.flush()

        return {"directory": finalDestination, "filename": finalFilename}
Exemplo n.º 20
0
    def determineMovie(self, movie):
        result = False

        movieName = self.cleanName(movie["folder"])
        movieYear = self.findYear(movie["folder"])

        # check to see if the downloaded movie nfo file agrees with what we thought we were downloading
        if movie["info"]["cpnfoImdb"] and movie["info"]["imdb"]:
            cpnfoimdb = movie["info"]["cpnfoImdb"].replace("tt", "")
            nfoimdb = movie["info"]["imdb"].replace("tt", "")
            if cpnfoimdb != nfoimdb:
                log.info("Downloaded movie's nfo has imdb id that doesn't match what we though we downloaded")
                # Would be nice to develop some sort of 'holding area' for "iffy" movies like this
                # For now, assume the movie's nfo is wrong...
                movie["info"]["imdb"] = cpnfoimdb
            else:
                movie["info"]["imdb"] = cpnfoimdb

        if movie["info"]["imdb"]:
            byImdb = self.getMovieByIMDB(movie["info"]["imdb"])
            if byImdb:
                return byImdb
            else:
                result = cherrypy.config["searchers"]["movie"].findByImdbId(movie["info"]["imdb"])

        if not result:

            # Check and see if name is in queue
            try:
                queue = Db.query(MovieQueue).filter_by(name=movie["folder"]).first()
                if queue:
                    log.info("Found movie via MovieQueue.")
                    return queue.Movie
            except:
                pass

            # Find movie via movie name
            try:
                m = Db.query(Movie).filter_by(name=movieName).first()
                if m:
                    log.info("Found movie via moviename.")
                    return m
            except:
                pass

            # Try and match the movies via filenaming
            for file in movie["files"]:
                dirnames = movie["path"].replace(unicode(self.config.get("Renamer", "download")), "").split(os.path.sep)
                dirnames.append(file["filename"])
                dirnames.reverse()

                for dir in dirnames:
                    dir = self.cleanName(dir)

                    # last resort, match every word in path to db
                    lastResort = {}
                    dirSplit = re.split("\W+", dir.lower())
                    for s in dirSplit:
                        if s:
                            results = (
                                Db.query(Movie).filter(Movie.name.like("%" + s + "%")).filter_by(year=movieYear).all()
                            )
                            for r in results:
                                lastResort[r.id] = r

                    for l in lastResort.itervalues():
                        wordCount = 0
                        for word in dirSplit:
                            if word in l.name.lower():
                                wordCount += 1

                        if wordCount == len(dirSplit) and len(dirSplit) > 0:
                            return l

            # Search tMDB
            if movieName and not movieName in ["movie"]:
                log.info('Searching for "%s".' % movie["folder"])
                result = cherrypy.config["searchers"]["movie"].find(movieName + " " + movieYear, limit=1)

        if result:
            movie = self.getMovieByIMDB(result.imdb)

            if not movie:
                new = Movie()
                Db.add(new)

                try:
                    # Add found movie as downloaded
                    new.status = u"downloaded"
                    new.name = result.name
                    new.imdb = result.imdb
                    new.movieDb = result.id
                    new.year = result.year
                    Db.flush()

                    return new
                except Exception, e:
                    log.error("Movie could not be added to database %s. %s" % (result, e))
            else:
                return movie
Exemplo n.º 21
0
    def renameFiles(self, movie):
        '''
        rename files based on movie data & conf
        '''

        multiple = False
        if len(movie['files']) > 1:
            multiple = True

        destination = self.conf('destination')
        folderNaming = self.conf('foldernaming')
        fileNaming = self.conf('filenaming')

        # Remove weird chars from moviename
        moviename = re.sub(r"[\x00\/\\:\*\?\"<>\|]", '', movie['info'].get('name'))

        # Put 'The' at the end
        namethe = moviename
        if moviename[:4].lower() == 'the ':
            namethe = moviename[4:] + ', The'

        replacements = {
             'cd': '',
             'cdNr': '',
             'ext': 'mkv',
             'namethe': namethe.strip(),
             'thename': moviename.strip(),
             'year': movie['info']['year'],
             'first': namethe[0].upper(),
             'quality': movie['info']['quality'],
             'video': movie['info']['codec']['video'],
             'audio': movie['info']['codec']['audio'],
             'group': movie['info']['group'],
             'resolution': movie['info']['resolution'],
             'sourcemedia': movie['info']['sourcemedia']
        }

        if multiple:
            cd = 1

        justAdded = []
        finalDestination = None

        #clean up post-processing script
        ppScriptName = movie['info'].get('ppScriptName')
        ppDirName = self.config.get('Sabnzbd', 'ppDir')
        if ppScriptName:
            if ppDirName:
                ppPath = os.path.join(ppDirName, ppScriptName)
                try:
                    os.remove(ppPath)
                    log.info("Removed post-processing script: %s" % ppPath)
                except:
                    log.info("Couldn't remove post-processing script: %s" % ppPath)
            else:
                log.info("Don't know where the post processing script is located, not removing %s" % ppScriptName)

        filenames = []

        for file in movie['files']:
            log.info('Trying to find a home for: %s' % latinToAscii(file['filename']))

            replacements['ext'] = file['ext']

            if multiple:
                replacements['cd'] = ' cd' + str(cd)
                replacements['cdNr'] = ' ' + str(cd)

            replacements['original'] = file['filename']

            folder = self.doReplace(folderNaming, replacements)
            filename = self.doReplace(fileNaming, replacements)
            filenames.append(filename)

            old = os.path.join(movie['path'], file['filename'])
            dest = os.path.join(destination, folder, filename)

            finalDestination = os.path.dirname(dest)
            if not os.path.isdir(finalDestination):

                try:
                    log.info('Creating directory %s' % finalDestination)
                    os.makedirs(finalDestination)
                    shutil.copymode(destination, finalDestination)
                except OSError:
                    log.error('Failed changing permissions %s' % finalDestination)

            # Remove old if better quality
            removed = self.removeOld(os.path.join(destination, folder), justAdded, movie['info']['size'])

            if not os.path.isfile(dest) and removed:
                log.info('Moving file "%s" to %s.' % (latinToAscii(old), dest))

                if not _move(old, dest):
                    break
                justAdded.append(dest)
            else:
                try:
                    log.error('File %s already exists or not better.' % latinToAscii(filename))
                    path = file['path'].split(os.sep)
                    path.extend(['_EXISTS_' + path.pop()])
                    old = file['path']
                    dest = os.sep.join(path)
                    _move(old, dest)
                except:
                    log.error('Could not extend path name.')
                break

            #get subtitle if any & move
            for type in movie['subtitles']:
                if len(movie['subtitles'][type]) > 0:
                    log.info('Moving matching subtitle.')

                    subtitle = movie['subtitles'][type].pop(0)

                    replacements['original'] = subtitle['filename']
                    replacements['ext'] = subtitle['ext']

                    subDest = os.path.join(destination, folder, self.doReplace(fileNaming, replacements))
                    old = os.path.join(movie['path'], subtitle['filename'])
                    if not _move(old, subDest):
                        break
                    justAdded.append(subDest) # Add to ignore list when removing stuff.

            # Add to renaming history
            log.debug('renamehistory start')
            h = RenameHistory()
            Db.add(h)

            try:
                h.movieQueue = movie['queue'].id
            except:
                h.movieQueue = 0

            h.old = unicode(old.decode('utf-8'))
            h.new = unicode(dest.decode('utf-8'))
            Db.flush()
            log.debug('renamehistory end')

            if multiple:
                cd += 1

        # Mark movie downloaded
        log.debug('queue downloaded start')
        if movie['queue'] and movie['queue'].id > 0:
            if movie['queue'].markComplete:
                movie['movie'].status = u'downloaded'

            movie['queue'].completed = True
            Db.flush()
        log.debug('queue downloaded end')

        return {
            'directory': finalDestination,
            'filenames': filenames
        }
Exemplo n.º 22
0
    def determineMovie(self, movie):
        result = False

        movieName = self.cleanName(movie['folder'])
        movieYear = self.findYear(movie['folder'])

        #check to see if the downloaded movie nfo file agrees with what we thought we were downloading
        if movie['info']['cpnfoImdb'] and movie['info']['imdb']:
            cpnfoimdb = 'tt' + movie['info']['cpnfoImdb'].replace("tt", '')
            nfoimdb = 'tt' + movie['info']['imdb'].replace("tt", '')
            if cpnfoimdb != nfoimdb:
                log.info("Downloaded movie's nfo has imdb id that doesn't match what we though we downloaded")
            movie['info']['imdb'] = cpnfoimdb

        if movie['info']['imdb']:
            byImdb = self.getMovieByIMDB(movie['info']['imdb'])
            if byImdb:
                return byImdb
            else:
                result = cherrypy.config['searchers']['movie'].findByImdbId(movie['info']['imdb'])

        if not result:

            # Check and see if name is in queue
            try:
                queue = Db.query(MovieQueue).filter_by(name = movie['folder']).first()
                if queue:
                    log.info('Found movie via MovieQueue.')
                    return queue.Movie
            except:
                pass

            # Find movie via movie name
            try:
                m = Db.query(Movie).filter_by(name = movieName).first()
                if m:
                    log.info('Found movie via moviename.')
                    return m
            except:
                pass

            # Try and match the movies via filenaming
            for file in movie['files']:
                dirnames = movie['path'].lower().replace(unicode(self.config.get('Renamer', 'download')).lower(), '').split(os.path.sep)
                dirnames.append(file['filename'])
                dirnames.reverse()

                for dir in dirnames:
                    dir = self.cleanName(dir)

                    # last resort, match every word in path to db
                    lastResort = {}
                    dirSplit = re.split('\W+', dir.lower())
                    for s in dirSplit:
                        if s:
                            results = Db.query(Movie).filter(Movie.name.like('%' + s + '%')).filter_by(year = movieYear).all()
                            for r in results:
                                lastResort[r.id] = r

                    for l in lastResort.itervalues():
                        wordCount = 0
                        for word in dirSplit:
                            if word in l.name.lower():
                                wordCount += 1

                        if wordCount == len(dirSplit) and len(dirSplit) > 0:
                            return l

            # Search tMDB
            if movieName and not movieName in ['movie']:
                log.info('Searching for "%s".' % movie['folder'])
                result = cherrypy.config['searchers']['movie'].find(movieName + ' ' + movieYear, limit = 1)

        if result:
            movie = self.getMovieByIMDB(result.imdb)

            if not movie:
                new = Movie()
                Db.add(new)

                try:
                    # Add found movie as downloaded
                    new.status = u'downloaded'
                    new.name = result.name
                    new.imdb = result.imdb
                    new.movieDb = result.id
                    new.year = result.year
                    Db.flush()

                    return new
                except Exception, e:
                    log.error('Movie could not be added to database %s. %s' % (result, e))
            else:
                return movie
Exemplo n.º 23
0
    def _addMovie(self, movie, quality, year=None):

        if cherrypy.config.get("config").get("XBMC", "dbpath"):
            log.debug("Checking if movie exists in XBMC by IMDB id:" + movie.imdb)
            dbfile = os.path.join(cherrypy.config.get("config").get("XBMC", "dbpath"), "MyVideos34.db")
            # ------Opening connection to XBMC DB------
            connXbmc = MySqlite.connect(dbfile)
            if connXbmc:
                connXbmc.row_factory = MySqlite.Row
                cXbmc = connXbmc.cursor()
                cXbmc.execute('select c09 from movie where c09="' + movie.imdb + '"')
                # ------End of Opening connection to XBMC DB------
                inXBMC = False
                for rowXbmc in cXbmc:  # do a final check just to be sure
                    log.debug("Found in XBMC:" + rowXbmc["c09"])
                    if movie.imdb == rowXbmc["c09"]:
                        inXBMC = True
                    else:
                        inXBMC = False

                cXbmc.close()

                if inXBMC:
                    log.info("Movie already exists in XBMC, skipping.")
                    return
            else:
                log.info(
                    "Could not connect to the XBMC database at " + cherrypy.config.get("config").get("XBMC", "dbpath")
                )

        log.info("Adding movie to database: %s" % movie.name)

        if movie.id:
            exists = Db.query(Movie).filter_by(movieDb=movie.id).first()
        else:
            exists = Db.query(Movie).filter_by(imdb=movie.imdb).first()

        if exists:
            log.info("Movie already exists, do update.")

            # Delete old qualities
            for x in exists.queue:
                x.active = False
                Db.flush()

            new = exists
        else:
            new = Movie()
            Db.add(new)

        # Update the stuff
        new.status = u"want"
        new.name = movie.name
        new.imdb = movie.imdb
        new.movieDb = movie.id
        new.quality = quality
        new.year = year if year and movie.year == "None" else movie.year
        Db.flush()

        # Add qualities to the queue
        quality = Db.query(QualityTemplate).filter_by(id=quality).one()
        for type in quality.types:
            queue = MovieQueue()
            queue.qualityType = type.type
            queue.movieId = new.id
            queue.order = type.order
            queue.active = True
            queue.completed = False
            queue.waitFor = 0 if type.markComplete else quality.waitFor
            queue.markComplete = type.markComplete
            Db.add(queue)
            Db.flush()

        # Get xml from themoviedb and save to cache
        self.searchers.get("movie").getExtraInfo(new.id, overwrite=True)

        # gogo find nzb for added movie via Cron
        self.cron.get("yarr").forceCheck(new.id)

        self.flash.add("movie-" + str(new.id), '"%s" (%s) added.' % (new.name, new.year))
Exemplo n.º 24
0
    def _addMovie(self, movie, quality, year=None):

        if cherrypy.config.get('config').get('XBMC', 'dbpath'):
            for root, dirs, files in os.walk(
                    cherrypy.config.get('config').get('XBMC', 'dbpath')):
                for file in files:
                    if file.startswith('MyVideos'):
                        dbfile = os.path.join(root, file)

            if dbfile:
                #------Opening connection to XBMC DB------
                connXbmc = MySqlite.connect(dbfile)
                if connXbmc:
                    log.debug('Checking if movie exists in XBMC by IMDB id:' +
                              movie.imdb)
                    connXbmc.row_factory = MySqlite.Row
                    cXbmc = connXbmc.cursor()
                    cXbmc.execute('select c09 from movie where c09="' +
                                  movie.imdb + '"')
                    #------End of Opening connection to XBMC DB------
                    inXBMC = False
                    for rowXbmc in cXbmc:  # do a final check just to be sure
                        log.debug('Found in XBMC:' + rowXbmc["c09"])
                        if movie.imdb == rowXbmc["c09"]:
                            inXBMC = True
                        else:
                            inXBMC = False

                    cXbmc.close()

                    if inXBMC:
                        log.info('Movie already exists in XBMC, skipping.')
                        return
                else:
                    log.info(
                        'Could not connect to the XBMC database at ' +
                        cherrypy.config.get('config').get('XBMC', 'dbpath'))
            else:
                log.info('Could not find the XBMC MyVideos db at ' +
                         cherrypy.config.get('config').get('XBMC', 'dbpath'))

        log.info('Adding movie to database: %s' % movie.name)

        if movie.id:
            exists = Db.query(Movie).filter_by(movieDb=movie.id).first()
        else:
            exists = Db.query(Movie).filter_by(imdb=movie.imdb).first()

        if exists:
            log.info('Movie already exists, do update.')

            # Delete old qualities
            for x in exists.queue:
                x.active = False
                Db.flush()

            new = exists
        else:
            new = Movie()
            Db.add(new)

        # Update the stuff
        new.status = u'want'
        new.name = movie.name
        new.imdb = movie.imdb
        new.movieDb = movie.id
        new.quality = quality
        new.year = year if year and movie.year == 'None' else movie.year
        Db.flush()

        # Add qualities to the queue
        quality = Db.query(QualityTemplate).filter_by(id=quality).one()
        for type in quality.types:
            queue = MovieQueue()
            queue.qualityType = type.type
            queue.movieId = new.id
            queue.order = type.order
            queue.active = True
            queue.completed = False
            queue.waitFor = 0 if type.markComplete else quality.waitFor
            queue.markComplete = type.markComplete
            Db.add(queue)
            Db.flush()

        #Get xml from themoviedb and save to cache
        self.searchers.get('movie').getExtraInfo(new.id, overwrite=True)

        #gogo find nzb for added movie via Cron
        self.cron.get('yarr').forceCheck(new.id)

        self.flash.add('movie-' + str(new.id),
                       '"%s" (%s) added.' % (new.name, new.year))
Exemplo n.º 25
0
    def renameFiles(self, movie):
        '''
        rename files based on movie data & conf
        '''

        multiple = False
        if len(movie['files']) > 1:
            multiple = True

        destination = self.conf('destination')
        folderNaming = self.conf('foldernaming')
        fileNaming = self.conf('filenaming')

        # Remove weird chars from moviename
        moviename = re.sub(r"[\x00\/\\:\*\?\"<>\|]", '', movie['info'].get('name'))

        # Put 'The' at the end
        namethe = moviename
        if moviename[:4].lower() == 'the ':
            namethe = moviename[4:] + ', The'

        replacements = {
             'cd': '',
             'cdNr': '',
             'ext': 'mkv',
             'namethe': namethe.strip(),
             'thename': moviename.strip(),
             'year': movie['info']['year'],
             'first': namethe[0].upper(),
             'quality': movie['info']['quality'],
             'video': movie['info']['codec']['video'],
             'audio': movie['info']['codec']['audio'],
             'group': movie['info']['group'],
             'resolution': movie['info']['resolution'],
             'sourcemedia': movie['info']['sourcemedia']
        }

        if multiple:
            cd = 1

        justAdded = []
        finalDestination = None

        #clean up post-processing script
        ppScriptName = movie['info'].get('ppScriptName')
        ppDirName = self.config.get('Sabnzbd', 'ppDir')
        if ppScriptName:
            if ppDirName:
                ppPath = os.path.join(ppDirName, ppScriptName)
                try:
                    os.remove(ppPath)
                    log.info("Removed post-processing script: %s" % ppPath)
                except:
                    log.info("Couldn't remove post-processing script: %s" % ppPath)
            else:
                log.info("Don't know where the post processing script is located, not removing %s" % ppScriptName)

        filenames = []

        for file in movie['files']:
            log.info('Trying to find a home for: %s' % latinToAscii(file['filename']))

            replacements['ext'] = file['ext']

            if multiple:
                replacements['cd'] = ' cd' + str(cd)
                replacements['cdNr'] = ' ' + str(cd)

            replacements['original'] = file['filename']

            folder = self.doReplace(folderNaming, replacements)
            filename = self.doReplace(fileNaming, replacements)
            filenames.append(filename)

            old = os.path.join(movie['path'], file['filename'])
            dest = os.path.join(destination, folder, filename)

            finalDestination = os.path.dirname(dest)
            if not os.path.isdir(finalDestination):

                try:
                    log.info('Creating directory %s' % finalDestination)
                    os.makedirs(finalDestination)
                    shutil.copymode(destination, finalDestination)
                except OSError:
                    log.error('Failed changing permissions %s' % finalDestination)

            # Remove old if better quality
            removed = self.removeOld(os.path.join(destination, folder), justAdded, movie['info']['size'])

            if not os.path.isfile(dest) and removed:
                log.info('Moving file "%s" to %s.' % (latinToAscii(old), dest))

                if not _move(old, dest):
                    break
                justAdded.append(dest)
            else:
                try:
                    log.error('File %s already exists or not better.' % latinToAscii(filename))
                    path = movie['path'].split(os.sep)
                    path.extend(['_EXISTS_' + path.pop()])
                    old = movie['path']
                    dest = os.sep.join(path)
                    _move(old, dest)
                except:
                    log.error('Could not extend path name.')
                break

            #get subtitle if any & move
            for type in movie['subtitles']:
                if len(movie['subtitles'][type]) > 0:
                    log.info('Moving matching subtitle.')

                    subtitle = movie['subtitles'][type].pop(0)

                    replacements['original'] = subtitle['filename']
                    replacements['ext'] = subtitle['ext']

                    subDest = os.path.join(destination, folder, self.doReplace(fileNaming, replacements))
                    old = os.path.join(movie['path'], subtitle['filename'])
                    if not _move(old, subDest):
                        break
                    justAdded.append(subDest) # Add to ignore list when removing stuff.

            # Add to renaming history
            log.debug('renamehistory start')
            h = RenameHistory()
            Db.add(h)

            try:
                h.movieQueue = movie['queue'].id
            except:
                h.movieQueue = 0

            h.old = unicode(old.decode('utf-8'))
            h.new = unicode(dest.decode('utf-8'))
            Db.flush()
            log.debug('renamehistory end')

            if multiple:
                cd += 1

        # Mark movie downloaded
        log.debug('queue downloaded start')
        if movie['queue'] and movie['queue'].id > 0:
            if movie['queue'].markComplete:
                movie['movie'].status = u'downloaded'

            movie['queue'].completed = True
            Db.flush()
        log.debug('queue downloaded end')

        return {
            'directory': finalDestination,
            'filenames': filenames
        }
Exemplo n.º 26
0
    def _search(self, movie, force=False):

        # Stop caching ffs!
        Db.expire_all()

        # Check release date and search for appropriate qualities
        preReleaseSearch = False
        dvdReleaseSearch = False
        now = int(time.time())

        # Search all if ETA is unknow, but try update ETA for next time.
        log.debug('Calculate ETA')
        checkETA = False
        if not movie.eta:
            checkETA = True
            preReleaseSearch = True
            dvdReleaseSearch = True
        else:
            # Prerelease 1 week before theaters
            if movie.eta.theater <= now + 604800:
                preReleaseSearch = True

            # dvdRelease 6 weeks before dvd release
            if movie.eta.dvd <= now + 3628800:
                preReleaseSearch = True
                dvdReleaseSearch = True

            # Dvd date is unknown but movie is in theater already
            if movie.eta.dvd == 0 and movie.eta.theater > now:
                dvdReleaseSearch = False

            # Force ETA check
            if movie.eta.lastCheck < now:
                checkETA = True

        # Minimal week interval for ETA check
        if checkETA and self.config.get('MovieETA', 'enabled'):
            cherrypy.config.get('searchers').get('etaQueue').put(
                {'id': movie.id})

        for queue in movie.queue:

            # Movie already found, don't search further
            if queue.completed:
                log.debug(
                    '%s already completed for "%s". Not searching for any qualities below.'
                    % (queue.qualityType, movie.name))
                return True

            # only search for active and not completed, minimal 1 min since last search
            if queue.active and not queue.completed and not self.abort and not self.stop:

                #skip if no search is set
                log.debug('Needs a search?')
                if (not ((preReleaseSearch
                          and queue.qualityType in Qualities.preReleases) or
                         (dvdReleaseSearch
                          and not queue.qualityType in Qualities.preReleases))
                    ) and not queue.lastCheck < (now - int(
                        self.config.get('Intervals', 'search')) * 7200):
                    continue

                log.debug('Start searching for movie: %s' % movie.name)
                highest = self.provider.find(movie, queue)
                log.debug('End searching for movie: %s' % movie.name)

                #send highest to SABnzbd & mark as snatched
                if highest:
                    log.debug('Found highest')

                    #update what I found
                    queue.name = latinToAscii(highest.name)
                    queue.link = highest.detailUrl
                    Db.flush()

                    waitFor = queue.waitFor * (60 * 60 * 24)

                    if queue.markComplete or (
                            not queue.markComplete
                            and highest.date + waitFor < time.time()):
                        time.sleep(10)  # Give these APIs air!
                        if self.config.get(
                                'NZB', 'sendTo'
                        ) == 'Sabnzbd' and highest.type == 'nzb':
                            success = self.sabNzbd.send(highest, movie.imdb)
                        elif self.config.get(
                                'NZB', 'sendTo'
                        ) == 'Nzbget' and highest.type == 'nzb':
                            success = self.nzbGet.send(highest)
                        elif self.config.get(
                                'Torrents', 'sendTo'
                        ) == 'Transmission' and highest.type == 'torrent':
                            success = self.transmission.send(
                                highest, movie.imdb)
                        else:
                            success = self.blackHole(highest)

                    else:
                        success = False
                        log.info('Found %s but waiting for %d hours.' %
                                 (highest.name,
                                  ((highest.date + waitFor) - time.time()) /
                                  (60 * 60)))

                    # Set status
                    if success:
                        log.debug('Success')
                        movie.status = u'snatched' if queue.markComplete else u'waiting'
                        movie.dateChanged = datetime.datetime.now()
                        queue.lastCheck = now
                        queue.completed = True
                        Db.flush()

                        # Add to history
                        h = History()
                        h.movie = movie.id
                        h.value = str(highest.id) + '-' + str(highest.size)
                        h.status = u'snatched'
                        Db.add(h)
                        Db.flush()

                        # Notify PROWL
                        if self.config.get('PROWL', 'onSnatch'):
                            log.debug('PROWL')
                            prowl = PROWL()
                            prowl.notify(highest.name, 'Download Started')

                        # Notify XBMC
                        if self.config.get('XBMC', 'onSnatch'):
                            log.debug('XBMC')
                            xbmc = XBMC()
                            xbmc.notify('Snatched %s' % highest.name)

                        # Notify GROWL
                        if self.config.get('GROWL', 'onSnatch'):
                            log.debug('GROWL')
                            growl = GROWL()
                            growl.notify('Snatched %s' % highest.name,
                                         'Download Started')

                        # Notify Notifo
                        if self.config.get('Notifo', 'onSnatch'):
                            log.debug('Notifo')
                            notifo = Notifo()
                            notifo.notify('%s' % highest.name, "Snatched:")

                        # Notify SNS
                        if self.config.get('SNS', 'onSnatch'):
                            log.debug('SNS')
                            sns = SNS()
                            sns.notify('%s' % highest.name, "Snatched:")

                        # Notify Boxcar
                        if self.config.get('Boxcar', 'onSnatch'):
                            log.debug('Boxcar')
                            boxcar = Boxcar()
                            boxcar.notify('%s' % highest.name, "Snatched:")

                        # Notify NotifyMyAndroid
                        if self.config.get('NMA', 'onSnatch'):
                            log.debug('NotifyMyAndroid')
                            nma = NMA()
                            nma.notify('Download Started',
                                       'Snatched %s' % highest.name)

                        # Notify NotifyMyWindowsPhone
                        if self.config.get('NMWP', 'onSnatch'):
                            log.debug('NotifyMyWindowsPhone')
                            nmwp = NMWP()
                            nmwp.notify('Download Started',
                                        'Snatched %s' % highest.name)

                        # Notify Twitter
                        if self.config.get('Twitter', 'onSnatch'):
                            log.debug('Twitter')
                            twitter = Twitter()
                            twitter.notify('Download Started',
                                           'Snatched %s' % highest.name)

                    return True

                queue.lastCheck = now
                Db.flush()

        return False