コード例 #1
0
ファイル: sync.py プロジェクト: OpenMipsel/project-valerie
	def run(self):
		
		self.doAbort = False
		
		self.output(_("Loading Config"))
		Blacklist.load()
		printl(str(len(Blacklist.get())) +" entrys")
			   
		self.output(_("Loading Data"))
		printl("Loading Data", self)

		db = Database().getInstance()
		
		if self.mode == self.UPDATE:
			from   Manager import Manager
			Manager().updateAll(self.output, self.progress, self.range)
			
			self.output(_("Saving database"))
			printl("Saving database", self)
			db.save()
			
			
			self.output(_("Done"))
			printl("Done", self)
			self.output("---------------------------------------------------")
			self.output(_("Press Exit / Back"))
			
			self.finished(True)
			return
		
		#temporarly - there are only failed, missing webif
		#db.deleteMediaFilesNotOk()
		
		if self.mode != self.FAST and SyncConfig().getInstance().get("delete") is True:
			db.deleteMissingFiles()
		
		if self.mode != self.FAST:
			db.transformGenres()
		
		printl("Entries: " + str(db), self)
		
		self.output(_("Loading Replacements"))
		printl("Loading Replacements", self)
		replace.load()
		
		posterSize = Arts.posterResolution[0]
		if self.dSize.width() == 720 and self.dSize.height() == 576:
			posterSize = Arts.posterResolution[0]
		elif self.dSize.width() == 1024 and self.dSize.height() == 576:
			posterSize = Arts.posterResolution[1]
		elif self.dSize.width() == 1280 and self.dSize.height() == 720:
			posterSize = Arts.posterResolution[2]
		
		self.output(_("Loading Filesystem"))
		printl("Loading Filesystem", self)
		ds = DirectoryScanner.DirectoryScanner()
		ds.clear()
		if self.mode == self.FAST:
			ds.load()
		
		pathsConfig = PathsConfig().getInstance()
		filetypes = pathsConfig.getFileTypes()
		self.output(_("Extensions:") + ' ' + str(filetypes))
		printl("Extensions: " + str(filetypes), self)
		
		self.output(_("Searching for media files"))
		printl("Searching for media files", self)
		start_time = time.time()
		
		folderList  = []
		elementList = [] 	# if there are no folder it will crash on » del elementlist	#Zuki
		elementListFileCounter = 0
		
		for searchpath in pathsConfig.getPaths(): 
			if searchpath["enabled"] is False:
				continue
			
			path = searchpath["directory"]
			folderType = searchpath["type"]
			useFolder = searchpath["usefolder"]

			if os.path.isdir(path) is False:
				continue
			
			ds.setDirectory(Utf8.utf8ToLatin(path))
			ds.listDirectory(filetypes, "(sample)|(VTS)|(^\\.)")
			filelist = ds.getFileList()
			elementListFileCounter += len(filelist)
			folderList.append((filelist, folderType, useFolder, ))
		
		elapsed_time = time.time() - start_time
		printl("Searching for media files took: " + str(elapsed_time), self)
		
		if elementListFileCounter == 0:
			self.output(_("Found") + ' ' + str(0) + ' ' + _("media files"))
			printl("Found 0 media files", self)
		else:
			self.output(_("Found") + ' ' + str(elementListFileCounter) + ' ' + _("media files"))
			printl("Found " + str(elementListFileCounter) + " media files", self)
			
			self.range(elementListFileCounter)
			
			i = 0
			for folder in folderList:
				#print "folder", folder
				elementList = folder[0]
				folderType  = folder[1]
				useFolder   = folder[2]
				
				if self.doAbort:
					break
				
				for element in elementList:
					i += 1
					self.progress(i)
					
					pathOrig	  = element[0].replace("\\", "/")
					filenameOrig  = element[1]
					extensionOrig = element[2]
					
					printl("*"*100, self, "I")
					printl("* Next file to sync: " + str(pathOrig) + "/" + str(filenameOrig) + "." + str(extensionOrig), self, "I")
					printl("*"*100, self, "I")
					
					path	  = Utf8.stringToUtf8(pathOrig)
					filename  = Utf8.stringToUtf8(filenameOrig)
					extension = Utf8.stringToUtf8(extensionOrig)
					
					if self.doAbort:
						break
					
					if path is None or filename is None or extension is None:
						printl("Path or filename or extension is None => skip!", self, "I")
						continue
					
					if "RECYCLE.BIN" in path or ".AppleDouble" in path:
						printl("Special directory => skip!", self, "I")
						continue
					
					if (filename + u"." + extension) in Blacklist.get():
						printl("File is blacklisted => skip!", self, "I")
						continue
					#printl("testing 1", self)
						
					printl("Checking for duplicates...", self, "I")
					retCheckDuplicate= db.checkDuplicate(path, filename, extension)

					mediaInDb = retCheckDuplicate["mediafile"]
					# if never sync with success delete db entry and resync
					if mediaInDb is not None and retCheckDuplicate["mediafile"].syncErrNo == MediaInfo.STATUS_INFONOTFOUND: # exist
						printl("Deleting and resync FailedItem", self)
						db.deleteMedia(retCheckDuplicate["mediafile"].Id)
						mediaInDb = None
						
					if mediaInDb is not None:
						printl("Media exists in database...", self, "I")
						if retCheckDuplicate["reason"] == 1: # exist
							m2 = retCheckDuplicate["mediafile"]
							if m2.syncErrNo == 0 and m2.MediaStatus != MediaInfo.STATUS_OK:
								#printl("Sync - Duplicate Found :" + str(m2.Path) + "/" + str(m2.Filename) + "." + str(m2.Extension), self)	
								key_value_dict = {}
								key_value_dict["Id"] = m2.Id
								key_value_dict["MediaStatus"]  = MediaInfo.STATUS_OK
								#key_value_dict["syncErrNo"]	= 0
								key_value_dict["syncFailedCause"] = u""
								printl("Sync - Update Media 1", self)	
								if not db.updateMediaWithDict(key_value_dict):
									printl("Sync - Update Media 1 - Failed", self)	
						
						elif retCheckDuplicate["reason"] == 2: # exist on other path, change record path
							m2 = retCheckDuplicate["mediafile"]
							if m2.syncErrNo == 0:
								printl("Sync - Duplicate Found on other path:" + str(m2.Path) + "/" + str(m2.Filename) + "." + str(m2.Extension), self)
								key_value_dict = {}
								key_value_dict["Id"] = m2.Id
								key_value_dict["Path"] = path
								key_value_dict["MediaStatus"]  = MediaInfo.STATUS_OK
								#key_value_dict["syncErrNo"]	= 0
								key_value_dict["syncFailedCause"] = u""
								printl("Sync - Update Media 2", self)	
								if not db.updateMediaWithDict(key_value_dict):
									printl("Sync - Update Media 2 - Failed", self)	
					
							
						# take lots of time to write on screen, we have the progressbar
						#self.output("Already in db [ " + Utf8.utf8ToLatin(filename) + " ]")
						
						#printl("testing 2", self)
						if Arts().isMissing(mediaInDb):
							printl("=> Arts missing in Db!...", self, "I")
							#self.output("Downloading missing poster")
							tmp = None
							if mediaInDb.isTypeMovie():
								tmp = TheMovieDbProvider().getArtByImdbId(mediaInDb)
							elif mediaInDb.isTypeEpisode():
								tvshow = db.getMediaWithTheTvDbId(mediaInDb.TheTvDbId)
								#printl(str(tvshow.SeasonPoster), self, "E")
								tvshow.SeasonPoster.clear() # Make sure that there are no residues
								tmp = TheTvDbProvider().getArtByTheTvDbId(tvshow)
								if tmp is not None:
									printl(str(tmp.SeasonPoster), self, "E")
							
							if tmp is not None:
								Arts().download(tmp)
								
								if mediaInDb.isTypeMovie():
									self.info(str(mediaInDb.ImdbId) + "_poster_" + posterSize + ".png", 
										"", "")
								elif mediaInDb.isTypeSerie() or mediaInDb.isTypeEpisode():
									self.info(str(mediaInDb.TheTvDbId) + "_poster_" + posterSize + ".png", 
										"", "")
								del tmp
						
						del mediaInDb
						continue
					
					outStr = "(" + str(i) + "/" + str(elementListFileCounter)  + ")"
					
					self.output(outStr + " -> " + getStringShrinked(pathOrig) + " >> " + filenameOrig + "." + extensionOrig)
					printl("#"*30, self)
					printl("(" + str(i) + "/" + str(elementListFileCounter)  + ")", self)
					printl("#"*6, self)
					printl("  -> " + pathOrig + "\n	" + filenameOrig + "." + extensionOrig, self)
					
					elementInfo = MediaInfo(path, filename, extension)
					
					printl("FOLDERTYPE: " + str(folderType), self)
					printl("USEFOLDER: " + str(useFolder), self)
					
					if folderType == u"MOVIE":
						elementInfo.setMediaType(MediaInfo.MOVIE)
					elif folderType == u"TV":
						elementInfo.setMediaType(MediaInfo.SERIE)
					else:
						elementInfo.setMediaType(MediaInfo.UNKNOWN)
					
					result = elementInfo.parse(useFolder)
						
					if result == False:
						continue
					
					printl("TheTvDbId: " + elementInfo.TheTvDbId, self, "I")
					
					if elementInfo.isXbmcNfo == False:	
						printl("isXbmcNfo == False => checking for E2 recorded TV show... ", self, "I")
						if elementInfo.isTypeSerie() and elementInfo.isEnigma2MetaRecording:
							if elementInfo.Season == None or elementInfo.Episode == None:
								printl("E2-recorded TV-Show => trying to get season and episode from E2 episodename... ", self, "I")
								tmp = GoogleProvider().getSeasonAndEpisodeFromEpisodeName(elementInfo)
								if (tmp[0] is True) and (tmp[1] is None):
									#Issue #474 => Don't fall back if foldertype is not explicitely "MOVIE_AND_TV"
									if folderType == u"MOVIE_AND_TV":
										printl("E2-recording not recognized as TV show => trying to parse as movie... ", self, "I")
										elementInfo.setMediaType(MediaInfo.MOVIE)
									else:
										elementInfo.MediaType = MediaInfo.UNKNOWN # avoid create serie
										elementInfo.MediaStatus = MediaInfo.STATUS_INFONOTFOUND
										elementInfo.syncErrNo   = 3
										elementInfo.syncFailedCause = u"Info Not Found"# cause
										printl("Failed to detect TV show and folder type set to 'TV' => adding media as failed...", self, "I")
										db.insertMedia(elementInfo)
										continue
								elif tmp[0] is True:
									# Issue #205, efo => use tmp[1] instead of tmp...
									elementInfo = tmp[1]
									printl("Result from google => Season=" + str(elementInfo.Season) + " / Episode=" + str(elementInfo.Episode), self, "I")
							else:
								printl("E2-recorded TV-Show: season and episode already set... ", self, "I")
							searchStringSplitted = elementInfo.SearchString.split("::")
							if len(searchStringSplitted) >= 2:
								elementInfo.SearchString = searchStringSplitted[0]
								printl("New searchString after split: " + elementInfo.SearchString, self, "I")
						printl("Get IMDb ID from title using searchString: " + elementInfo.SearchString, self, "I")
						tmp = MobileImdbComProvider().getMoviesByTitle(elementInfo)
						if tmp is None:
							# validate if user use valerie.info with imdb or tvdb
							if (elementInfo.isTypeSerie() and elementInfo.TheTvDbId == MediaInfo.TheTvDbIdNull) or (elementInfo.isTypeMovie() and elementInfo.ImdbId == MediaInfo.ImdbIdNull): 
								printl("=> nothing found :-( " + elementInfo.SearchString, self, "I")
								#db.addFailed(FailedEntry(path, filename, extension, FailedEntry.UNKNOWN))
								#elementInfo.MediaType = MediaInfo.FAILEDSYNC
								elementInfo.MediaType = MediaInfo.UNKNOWN # avoid create serie
								elementInfo.MediaStatus = MediaInfo.STATUS_INFONOTFOUND
								elementInfo.syncErrNo   = 3
								elementInfo.syncFailedCause = u"Info Not Found"# cause
								db.insertMedia(elementInfo)
								continue
						else:
							elementInfo = tmp
						printl("Finally about to sync element... ", self, "I")
						results = Sync().syncWithId(elementInfo)
					else:
						printl("isXbmcNfo == True => using data from nfo:\n" + str(elementInfo), self, "I")
						results = (elementInfo, )
					
					if results is not None:
						printl("results: "+str(results), self)
						for result in results:
							result.MediaStatus = MediaInfo.STATUS_OK
							result.syncErrNo   = 0
							result.syncFailedCause = u""
							#printl("INSERT: "+result.Filename+ " type: " + str(result.MediaType) , self, "I")
							ret = db.insertMedia(result)
							if ret["status"] > 0:
								#result.Title = self.encodeMe(result.Title)
								if result.isTypeMovie():
									self.info(str(result.ImdbId) + "_poster_" + posterSize + ".png", 
										result.Title, result.Year)
									printl("my_title " + result.Title, self, "I")
								else:
									self.info(str(result.TheTvDbId) + "_poster_" + posterSize + ".png", 
										result.Title, result.Year)
									printl("my_title " + result.Title, self, "I")
							else:
								# ??????
								
								#cause = db.getAddFailedCauseOf()
								#db.addFailed(FailedEntry(path, filename, extension, FailedEntry.ALREADY_IN_DB,cause))
								#if result.syncFailedCause == u"":
								#	result.syncFailedCause = "DB Insert Error ??"
								result.MediaType = MediaInfo.FAILEDSYNC
								try:
									db.insertMedia(result)
								except Exception, ex:
									printl("DB Insert Error ??", self, "W")
					
					#self.output("(" + str(i) + "/" + str(elementListFileCounter) + ")")
					#printl("(" + str(i) + "/" + str(elementListFileCounter) + ")", self)
					self.progress(i)
コード例 #2
0
ファイル: Manager.py プロジェクト: Rikitik/project-valerie
class Manager:
    # make ID's equal in MediaInfo & Manager, hope there is nothing hardcoded...
    MOVIES = 1
    TVSHOWS = 2
    TVSHOWSEPISODES = 3
    MUSIC = 4

    # TVSHOWSSEASONS = 5 #not USED
    FAILED = 6
    FAILED_ALL = 7

    ORDER_TITLE = 1
    ORDER_YEAR = 2
    Session = None

    def __init__(self, origin="N/A", session=None):
        printl("Init called from: " + origin, self, "S")
        # try:
        if True:
            self.db = Database().getInstance("Manager-" + origin, session)
            replace.load()
            # except Exception, ex:
            # 	printl ("Exception on Init Ex:"+str(ex), self)
            # 	from Plugins.Extensions.ProjectValerie.DMC_Plugins.DMC_SyncExtras.sync import checkDefaults
            # 	checkDefaults()
            # 	self.db = Database().getInstance("Manager (by exception)-"+origin, session)
            # 	replace.load()

    def finish(self):
        printl("", self)
        self.db.save()

    def getAll(self, type, param=None):
        printl("type=" + str(type) + " param=" + str(param), self)

        # deprecated use getMoviesValues, getSeriesValues
        if type == self.MOVIES:
            return self.getMoviesValues()
        elif type == self.TVSHOWS:
            return self.getSeriesValues()
        elif type == self.TVSHOWSEPISODES:
            list = []
            if param is not None:
                ### todo: CONVERT TO ID, don't use tvdbid
                list = self.getEpisodesWithTheTvDbId(param)
            else:
                list = self.getAllEpisodes()
            return list

        elif type == self.FAILED or type == self.FAILED_ALL:
            return self.getFailedValues()
        else:
            return None

    #
    ###############################   MEDIA FILES   ###############################
    #
    def getMedia(self, id):
        return self.db.getMediaWithId(id)

    def insertMedia(self, media):
        return self.db.insertMedia(media)

    def insertMediaWithDict(self, type, key_value_dict):
        key_value_dict["MediaType"] = type
        ret = self.db.insertMediaWithDict(key_value_dict)
        if ret["status"] <= 0:
            printl("Insert Media - Failed " + ret["message"], self)

        return ret

    def updateMediaWithDict(self, type, key_value_dict):
        key_value_dict["MediaType"] = type
        if not self.db.updateMediaWithDict(key_value_dict):
            printl("Update Media - Failed", self)
            return False
        return True

    def deleteMedia(self, id):
        if not self.db.deleteMedia(id):
            printl("Delete Media - Failed", self)
            return False
        return True

    def getMediaPaths(self):
        return self.db.getMediaPaths()

    def getMediaValuesForFolder(self, type, path, order=None, firstRecord=0, numberOfRecords=9999999):
        return self.db.getMediaValuesForFolder(type, path, order=None, firstRecord=0, numberOfRecords=9999999)

    #
    #################################   MOVIES   #################################
    #
    # Pass throught functions
    def getMoviesValues(self, order=None, firstRecord=0, numberOfRecords=9999999):
        return self.db.getMediaValues(MediaInfo.MOVIE, order, firstRecord, numberOfRecords)

        # def getMoviesValuesByGroup(self, order=None, firstRecord=0, numberOfRecords=9999999):
        # 	return self.db.getMediaValues(MediaInfo.MOVIE, order, firstRecord, numberOfRecords)
        #

    def getMoviesCount(self):
        return self.db.getMediaCount(MediaInfo.MOVIE)

    #
    #################################   SERIES   #################################
    #
    # Pass throught functions
    def getSeriesValues(self, order=None, firstRecord=0, numberOfRecords=9999999):
        return self.db.getMediaValues(MediaInfo.SERIE, order, firstRecord, numberOfRecords)

    def getSeriesCount(self):
        return self.db.getMediaCount(MediaInfo.SERIE)

    def getEpisodes(self, parentId=None, season=None):
        return self.db.getEpisodes(parentId, season)

    def getAllEpisodes(self):  # DANGER
        return self.db.getEpisodes()

    def getEpisodesWithTheTvDbId(self, theTvDbId):
        return self.db.getEpisodesWithTheTvDbId(theTvDbId)

    def getEpisodesCount(self, parentId=None, season=None):
        return self.db.getMediaCount(MediaInfo.EPISODE, parentId, season)

    #
    #################################   FAILED   #################################
    #
    def getFailedValues(self):
        return self.db.getFailedValues()

    def getFailedCount(self):
        return self.db.getFailedCount()

    #
    ##########################           SEEN            ##########################
    #
    def isMediaSeen(self, id, Season=None, user=9999):
        return self.db.isMediaSeen(id, user)
        # return self.isEntrySeen(primary_key)
        # return self.isSeasonSeen(primary_key)
        # return self.isShowSeen(primary_key)

    def MarkAsSeen(self, id, user=9999):
        self.db.MarkAsSeen(id, user)

    def MarkAsUnseen(self, id, user=9999):
        self.db.MarkAsUnseen(id, user)

    #
    ###################################  UTILS  ###################################
    #
    def getDbDump(self):
        return self.db.getDbDump()

    def dbIsCommited(self):
        return self.db.dbIsCommited()

    def moveToFailedSection(self, id, type):
        printl("move to failed section", self)
        m = None
        m = self.db.getMediaWithId(id)

        if m is None:
            printl("Moving to failed section failed - DB Error - Not found", self)
            return False

            # convert MediaInfo object to dictionary
        key_value_dict = m.__dict__

        # remove some elements from dictionary - this results in error in (_fillMediaInfo)
        Fields = ["Plot", "Writers", "Directors", "SeasonPoster", "Alternatives", "Path", "Extension", "Poster"]
        for key in Fields:
            if key in key_value_dict:
                key_value_dict.pop(key)

                # change needed values in dictionary
        key_value_dict["MediaStatus"] = 3
        key_value_dict["syncFailedCause"] = u"Info Not Found"
        key_value_dict["syncErrNo"] = 3
        key_value_dict["isMovie"] = 0
        key_value_dict["isSerie"] = 0
        key_value_dict["isEpisode"] = 0
        key_value_dict["TmDbId"] = u""
        key_value_dict["ImdbId"] = u""
        key_value_dict["type"] = u""
        key_value_dict["MediaType"] = 0

        # make some debug :-)
        printl(key_value_dict, self)

        self.db.updateMediaWithDict(key_value_dict, False)
        return True

    def changeMediaArts(self, type, id, overwrite=False, backdrop=None, poster=None):
        printl("start changing arts", self, "I")
        m = None
        if type == self.MOVIES:
            m = self.db.getMediaWithId(id)
        elif type == self.TVSHOWS:
            m = self.db.getMediaWithId(id)
        elif type == self.TVSHOWSEPISODES:
            m = self.db.getMediaWithId(id)
        elif type == self.MUSIC:
            pass
            # m = self.db.getMediaWithId(id)
            return False
        else:
            return None

        if m is None:
            printl("Change Media Art - DB Error - Not found", self)
            return False

        if backdrop is not None:
            m.Backdrop = backdrop
        if poster is not None:
            m.Poster = poster

        if m.Backdrop is not None or m.Poster is not None:
            printl("downloading arts", self)
            # printl("overwrite => " + str(overwrite), self, "I")
            Arts().download(m, overwrite)
            return True
        else:
            return False

        return False

    def searchAlternatives(self, oldElement, searchstring=None):
        element = MediaInfo(oldElement.Path, oldElement.Filename, oldElement.Extension)
        if type(oldElement) is MediaInfo:
            element.isMovie = oldElement.isMovie
            element.isSerie = oldElement.isSerie

        if searchstring is not None:
            element.SearchString = searchstring

        element.parse()

        printl("SEARCH=" + str(element.SearchString), self)
        return MobileImdbComProvider().getAlternatives(element)

    def syncElement(self, path, filename, extension, imdbid, istvshow, oldelement=None):
        printl(str(path) + " " + str(filename) + " " + str(extension) + " " + str(imdbid) + " " + str(istvshow), self)

        element = None

        if oldelement is None:
            element = MediaInfo(path, filename, extension)
            element.parse()
            element.ImdbId = imdbid
        else:
            element = oldelement  # .copy()

        if istvshow:
            element.setMediaType(MediaInfo.SERIE)
        else:
            element.setMediaType(MediaInfo.MOVIE)

        results = Sync().syncWithId(element)
        if results is not None:
            return results
        else:
            if istvshow is False:
                element.setMediaType(MediaInfo.SERIE)
            else:
                element.setMediaType(MediaInfo.MOVIE)

            results = Sync().syncWithId(element)
            if results is not None:
                return results
        return None

    def updateAll(self, notifyOutput=None, notifyProgress=None, notifyRange=None):
        episodes = self.getAll(self.TVSHOWSEPISODES)
        total = len(episodes)
        progress = 0

        if notifyRange is not None:
            notifyRange(total)

        if notifyProgress is not None:
            notifyProgress(0)

        for episode in episodes:
            if episode.Title is None or episode.Season is None or episode.Episode is None:
                continue
            tvshow = self.getMedia(episode.ParentId)
            if episode.Title == tvshow.Title:
                printl(
                    "Episode has same title as tvshow so probably update needed (%s %dx%d)"
                    % (episode.Title, episode.Season, episode.Episode),
                    self,
                    "I",
                )
                if notifyOutput is not None:
                    notifyOutput(
                        Utf8.utf8ToLatin("Updating %s %dx%d" % (episode.Title, episode.Season, episode.Episode))
                    )
                id = episode.Id
                seen = self.isMediaSeen(episode.Id)
                episode.setMediaType(episode.SERIE)
                newElement = Sync().syncWithId(episode)
                if newElement is not None:
                    if len(newElement) == 2:
                        episode = newElement[1]
                    else:
                        episode = newElement[0]

                    self.deleteMedia(id)
                    ret = self.insertMedia(episode)
                    if seen:
                        self.MarkAsSeen(ret["id"])
            progress = progress + 1
            printl("Update progress %.2f (%d/%d)" % ((progress / total) * 100.0, progress, total), self, "I")
            if notifyProgress is not None:
                notifyProgress(progress)

        notifyProgress(total)
コード例 #3
0
ファイル: Manager.py プロジェクト: steve4744/project-valerie
class Manager():
    # make ID's equal in MediaInfo & Manager, hope there is nothing hardcoded...
    MOVIES = 1
    TVSHOWS = 2
    TVSHOWSEPISODES = 3
    MUSIC = 4

    # TVSHOWSSEASONS = 5 #not USED
    FAILED = 6
    FAILED_ALL = 7

    ORDER_TITLE = 1
    ORDER_YEAR = 2
    Session = None

    def __init__(self, origin="N/A", session=None):
        printl("Init called from: " + origin, self, "S")
        #try:
        if True:
            self.db = Database().getInstance("Manager-" + origin, session)
            replace.load()
        #except Exception, ex:
        #	printl ("Exception on Init Ex:"+str(ex), self)
        #	from Plugins.Extensions.ProjectValerie.DMC_Plugins.DMC_SyncExtras.sync import checkDefaults
        #	checkDefaults()
        #	self.db = Database().getInstance("Manager (by exception)-"+origin, session)
        #	replace.load()

    def finish(self):
        printl("", self)
        self.db.save()

    def getAll(self, type, param=None):
        printl("type=" + str(type) + " param=" + str(param), self)

        #deprecated use getMoviesValues, getSeriesValues
        if type == self.MOVIES:
            return self.getMoviesValues()
        elif type == self.TVSHOWS:
            return self.getSeriesValues()
        elif type == self.TVSHOWSEPISODES:
            list = []
            if param is not None:
                ### todo: CONVERT TO ID, don't use tvdbid
                list = self.getEpisodesWithTheTvDbId(param)
            else:
                list = self.getAllEpisodes()
            return list

        elif type == self.FAILED or type == self.FAILED_ALL:
            return self.getFailedValues()
        else:
            return None
#
###############################   MEDIA FILES   ###############################
#

    def getMedia(self, id):
        return self.db.getMediaWithId(id)

    def insertMedia(self, media):
        return self.db.insertMedia(media)

    def insertMediaWithDict(self, type, key_value_dict):
        key_value_dict["MediaType"] = type
        ret = self.db.insertMediaWithDict(key_value_dict)
        if ret["status"] <= 0:
            printl("Insert Media - Failed " + ret["message"], self)

        return ret

    def updateMediaWithDict(self, type, key_value_dict):
        key_value_dict["MediaType"] = type
        if not self.db.updateMediaWithDict(key_value_dict):
            printl("Update Media - Failed", self)
            return False
        return True

    def deleteMedia(self, id):
        if not self.db.deleteMedia(id):
            printl("Delete Media - Failed", self)
            return False
        return True

    def getMediaPaths(self):
        return self.db.getMediaPaths()

    def getMediaValuesForFolder(self,
                                type,
                                path,
                                order=None,
                                firstRecord=0,
                                numberOfRecords=9999999):
        return self.db.getMediaValuesForFolder(type,
                                               path,
                                               order=None,
                                               firstRecord=0,
                                               numberOfRecords=9999999)
#
#################################   MOVIES   #################################
#
# Pass throught functions

    def getMoviesValues(self,
                        order=None,
                        firstRecord=0,
                        numberOfRecords=9999999):
        return self.db.getMediaValues(MediaInfo.MOVIE, order, firstRecord,
                                      numberOfRecords)

    #def getMoviesValuesByGroup(self, order=None, firstRecord=0, numberOfRecords=9999999):
    #	return self.db.getMediaValues(MediaInfo.MOVIE, order, firstRecord, numberOfRecords)
    #

    def getMoviesCount(self):
        return self.db.getMediaCount(MediaInfo.MOVIE)
#
#################################   SERIES   #################################
#
# Pass throught functions

    def getSeriesValues(self,
                        order=None,
                        firstRecord=0,
                        numberOfRecords=9999999):
        return self.db.getMediaValues(MediaInfo.SERIE, order, firstRecord,
                                      numberOfRecords)

    def getSeriesCount(self):
        return self.db.getMediaCount(MediaInfo.SERIE)

    def getEpisodes(self, parentId=None, season=None):
        return self.db.getEpisodes(parentId, season)

    def getAllEpisodes(self):  # DANGER
        return self.db.getEpisodes()

    def getEpisodesWithTheTvDbId(self, theTvDbId):
        return self.db.getEpisodesWithTheTvDbId(theTvDbId)

    def getEpisodesCount(self, parentId=None, season=None):
        return self.db.getMediaCount(MediaInfo.EPISODE, parentId, season)
#
#################################   FAILED   #################################
#

    def getFailedValues(self):
        return self.db.getFailedValues()

    def getFailedCount(self):
        return self.db.getFailedCount()

#
##########################           SEEN            ##########################
#

    def isMediaSeen(self, id, Season=None, user=9999):
        return self.db.isMediaSeen(id, user)
        #return self.isEntrySeen(primary_key)
        #return self.isSeasonSeen(primary_key)
        #return self.isShowSeen(primary_key)

    def MarkAsSeen(self, id, user=9999):
        self.db.MarkAsSeen(id, user)

    def MarkAsUnseen(self, id, user=9999):
        self.db.MarkAsUnseen(id, user)
#
###################################  UTILS  ###################################
#

    def getDbDump(self):
        return self.db.getDbDump()

    def dbIsCommited(self):
        return self.db.dbIsCommited()

    def moveToFailedSection(self, id, type):
        printl("move to failed section", self)
        m = None
        m = self.db.getMediaWithId(id)

        if m is None:
            printl("Moving to failed section failed - DB Error - Not found",
                   self)
            return False

        #convert MediaInfo object to dictionary
        key_value_dict = m.__dict__

        #remove some elements from dictionary - this results in error in (_fillMediaInfo)
        Fields = [
            'Plot', 'Writers', 'Directors', 'SeasonPoster', 'Alternatives',
            'Path', 'Extension', 'Poster'
        ]
        for key in Fields:
            if key in key_value_dict:
                key_value_dict.pop(key)

        #change needed values in dictionary
        key_value_dict["MediaStatus"] = 3
        key_value_dict["syncFailedCause"] = u"Info Not Found"
        key_value_dict["syncErrNo"] = 3
        key_value_dict["isMovie"] = 0
        key_value_dict["isSerie"] = 0
        key_value_dict["isEpisode"] = 0
        key_value_dict["TmDbId"] = u""
        key_value_dict["ImdbId"] = u""
        key_value_dict["type"] = u""
        key_value_dict["MediaType"] = 0

        #make some debug :-)
        printl(key_value_dict, self)

        self.db.updateMediaWithDict(key_value_dict, False)
        return True

    def changeMediaArts(self,
                        type,
                        id,
                        overwrite=False,
                        backdrop=None,
                        poster=None):
        printl("start changing arts", self, "I")
        m = None
        if type == self.MOVIES:
            m = self.db.getMediaWithId(id)
        elif type == self.TVSHOWS:
            m = self.db.getMediaWithId(id)
        elif type == self.TVSHOWSEPISODES:
            m = self.db.getMediaWithId(id)
        elif type == self.MUSIC:
            pass
            #m = self.db.getMediaWithId(id)
            return False
        else:
            return None

        if m is None:
            printl("Change Media Art - DB Error - Not found", self)
            return False

        if backdrop is not None:
            m.Backdrop = backdrop
        if poster is not None:
            m.Poster = poster

        if m.Backdrop is not None or m.Poster is not None:
            printl("downloading arts", self)
            #printl("overwrite => " + str(overwrite), self, "I")
            Arts().download(m, overwrite)
            return True
        else:
            return False

        return False

    def searchAlternatives(self, oldElement, searchstring=None):
        element = MediaInfo(oldElement.Path, oldElement.Filename,
                            oldElement.Extension)
        if type(oldElement) is MediaInfo:
            element.isMovie = oldElement.isMovie
            element.isSerie = oldElement.isSerie

        if searchstring is not None:
            element.SearchString = searchstring

        element.parse()

        printl("SEARCH=" + str(element.SearchString), self)
        return MobileImdbComProvider().getAlternatives(element)

    def syncElement(self,
                    path,
                    filename,
                    extension,
                    imdbid,
                    istvshow,
                    oldelement=None):
        printl(
            str(path) + " " + str(filename) + " " + str(extension) + " " +
            str(imdbid) + " " + str(istvshow), self)

        element = None

        if oldelement is None:
            element = MediaInfo(path, filename, extension)
            element.parse()
            element.ImdbId = imdbid
        else:
            element = oldelement  #.copy()

        if istvshow:
            element.setMediaType(MediaInfo.SERIE)
        else:
            element.setMediaType(MediaInfo.MOVIE)

        results = Sync().syncWithId(element)
        if results is not None:
            return results
        else:
            if istvshow is False:
                element.setMediaType(MediaInfo.SERIE)
            else:
                element.setMediaType(MediaInfo.MOVIE)

            results = Sync().syncWithId(element)
            if results is not None:
                return results
        return None

    def updateAll(self,
                  notifyOutput=None,
                  notifyProgress=None,
                  notifyRange=None):
        episodes = self.getAll(self.TVSHOWSEPISODES)
        total = len(episodes)
        progress = 0

        if notifyRange is not None:
            notifyRange(total)

        if notifyProgress is not None:
            notifyProgress(0)

        for episode in episodes:
            if episode.Title is None or episode.Season is None or episode.Episode is None:
                continue
            tvshow = self.getMedia(episode.ParentId)
            if episode.Title == tvshow.Title:
                printl(
                    "Episode has same title as tvshow so probably update needed (%s %dx%d)"
                    % (episode.Title, episode.Season, episode.Episode), self,
                    "I")
                if notifyOutput is not None:
                    notifyOutput(
                        Utf8.utf8ToLatin(
                            "Updating %s %dx%d" %
                            (episode.Title, episode.Season, episode.Episode)))
                id = episode.Id
                seen = self.isMediaSeen(episode.Id)
                episode.setMediaType(episode.SERIE)
                newElement = Sync().syncWithId(episode)
                if newElement is not None:
                    if len(newElement) == 2:
                        episode = newElement[1]
                    else:
                        episode = newElement[0]

                    self.deleteMedia(id)
                    ret = self.insertMedia(episode)
                    if seen:
                        self.MarkAsSeen(ret["id"])
            progress = progress + 1
            printl(
                "Update progress %.2f (%d/%d)" %
                ((progress / total) * 100.0, progress, total), self, "I")
            if notifyProgress is not None:
                notifyProgress(progress)

        notifyProgress(total)
コード例 #4
0
ファイル: sync.py プロジェクト: steve4744/project-valerie
    def run(self):

        self.doAbort = False

        self.output(_("Loading Config"))
        Blacklist.load()
        printl(str(len(Blacklist.get())) + " entrys")

        self.output(_("Loading Data"))
        printl("Loading Data", self)

        db = Database().getInstance()

        if self.mode == self.UPDATE:
            from Manager import Manager
            Manager().updateAll(self.output, self.progress, self.range)

            self.output(_("Saving database"))
            printl("Saving database", self)
            db.save()

            self.output(_("Done"))
            printl("Done", self)
            self.output("---------------------------------------------------")
            self.output(_("Press Exit / Back"))

            self.finished(True)
            return

        #temporarly - there are only failed, missing webif
        #db.deleteMediaFilesNotOk()

        if self.mode != self.FAST and SyncConfig().getInstance().get(
                "delete") is True:
            db.deleteMissingFiles()

        if self.mode != self.FAST:
            db.transformGenres()

        printl("Entries: " + str(db), self)

        self.output(_("Loading Replacements"))
        printl("Loading Replacements", self)
        replace.load()

        posterSize = Arts.posterResolution[0]
        if self.dSize.width() == 720 and self.dSize.height() == 576:
            posterSize = Arts.posterResolution[0]
        elif self.dSize.width() == 1024 and self.dSize.height() == 576:
            posterSize = Arts.posterResolution[1]
        elif self.dSize.width() == 1280 and self.dSize.height() == 720:
            posterSize = Arts.posterResolution[2]

        self.output(_("Loading Filesystem"))
        printl("Loading Filesystem", self)
        ds = DirectoryScanner.DirectoryScanner()
        ds.clear()
        if self.mode == self.FAST:
            ds.load()

        pathsConfig = PathsConfig().getInstance()
        filetypes = pathsConfig.getFileTypes()
        self.output(_("Extensions:") + ' ' + str(filetypes))
        printl("Extensions: " + str(filetypes), self)

        self.output(_("Searching for media files"))
        printl("Searching for media files", self)
        start_time = time.time()

        folderList = []
        elementList = [
        ]  # if there are no folder it will crash on » del elementlist	#Zuki
        elementListFileCounter = 0

        for searchpath in pathsConfig.getPaths():
            if searchpath["enabled"] is False:
                continue

            path = searchpath["directory"]
            folderType = searchpath["type"]
            useFolder = searchpath["usefolder"]

            if os.path.isdir(path) is False:
                continue

            ds.setDirectory(Utf8.utf8ToLatin(path))
            ds.listDirectory(filetypes, "(sample)|(VTS)|(^\\.)")
            filelist = ds.getFileList()
            elementListFileCounter += len(filelist)
            folderList.append((
                filelist,
                folderType,
                useFolder,
            ))

        elapsed_time = time.time() - start_time
        printl("Searching for media files took: " + str(elapsed_time), self)

        if elementListFileCounter == 0:
            self.output(_("Found") + ' ' + str(0) + ' ' + _("media files"))
            printl("Found 0 media files", self)
        else:
            self.output(
                _("Found") + ' ' + str(elementListFileCounter) + ' ' +
                _("media files"))
            printl("Found " + str(elementListFileCounter) + " media files",
                   self)

            self.range(elementListFileCounter)

            i = 0
            for folder in folderList:
                #print "folder", folder
                elementList = folder[0]
                folderType = folder[1]
                useFolder = folder[2]

                if self.doAbort:
                    break

                for element in elementList:
                    i += 1
                    self.progress(i)

                    pathOrig = element[0].replace("\\", "/")
                    filenameOrig = element[1]
                    extensionOrig = element[2]

                    printl("*" * 100, self, "I")
                    printl(
                        "* Next file to sync: " + str(pathOrig) + "/" +
                        str(filenameOrig) + "." + str(extensionOrig), self,
                        "I")
                    printl("*" * 100, self, "I")

                    path = Utf8.stringToUtf8(pathOrig)
                    filename = Utf8.stringToUtf8(filenameOrig)
                    extension = Utf8.stringToUtf8(extensionOrig)

                    if self.doAbort:
                        break

                    if path is None or filename is None or extension is None:
                        printl(
                            "Path or filename or extension is None => skip!",
                            self, "I")
                        continue

                    if "RECYCLE.BIN" in path or ".AppleDouble" in path:
                        printl("Special directory => skip!", self, "I")
                        continue

                    if (filename + u"." + extension) in Blacklist.get():
                        printl("File is blacklisted => skip!", self, "I")
                        continue
                    #printl("testing 1", self)

                    printl("Checking for duplicates...", self, "I")
                    retCheckDuplicate = db.checkDuplicate(
                        path, filename, extension)

                    mediaInDb = retCheckDuplicate["mediafile"]
                    # if never sync with success delete db entry and resync
                    if mediaInDb is not None and retCheckDuplicate[
                            "mediafile"].syncErrNo == MediaInfo.STATUS_INFONOTFOUND:  # exist
                        printl("Deleting and resync FailedItem", self)
                        db.deleteMedia(retCheckDuplicate["mediafile"].Id)
                        mediaInDb = None

                    if mediaInDb is not None:
                        printl("Media exists in database...", self, "I")
                        if retCheckDuplicate["reason"] == 1:  # exist
                            m2 = retCheckDuplicate["mediafile"]
                            if m2.syncErrNo == 0 and m2.MediaStatus != MediaInfo.STATUS_OK:
                                #printl("Sync - Duplicate Found :" + str(m2.Path) + "/" + str(m2.Filename) + "." + str(m2.Extension), self)
                                key_value_dict = {}
                                key_value_dict["Id"] = m2.Id
                                key_value_dict[
                                    "MediaStatus"] = MediaInfo.STATUS_OK
                                #key_value_dict["syncErrNo"]	= 0
                                key_value_dict["syncFailedCause"] = u""
                                printl("Sync - Update Media 1", self)
                                if not db.updateMediaWithDict(key_value_dict):
                                    printl("Sync - Update Media 1 - Failed",
                                           self)

                        elif retCheckDuplicate[
                                "reason"] == 2:  # exist on other path, change record path
                            m2 = retCheckDuplicate["mediafile"]
                            if m2.syncErrNo == 0:
                                printl(
                                    "Sync - Duplicate Found on other path:" +
                                    str(m2.Path) + "/" + str(m2.Filename) +
                                    "." + str(m2.Extension), self)
                                key_value_dict = {}
                                key_value_dict["Id"] = m2.Id
                                key_value_dict["Path"] = path
                                key_value_dict[
                                    "MediaStatus"] = MediaInfo.STATUS_OK
                                #key_value_dict["syncErrNo"]	= 0
                                key_value_dict["syncFailedCause"] = u""
                                printl("Sync - Update Media 2", self)
                                if not db.updateMediaWithDict(key_value_dict):
                                    printl("Sync - Update Media 2 - Failed",
                                           self)

                        # take lots of time to write on screen, we have the progressbar
                        #self.output("Already in db [ " + Utf8.utf8ToLatin(filename) + " ]")

                        #printl("testing 2", self)
                        if Arts().isMissing(mediaInDb):
                            printl("=> Arts missing in Db!...", self, "I")
                            #self.output("Downloading missing poster")
                            tmp = None
                            if mediaInDb.isTypeMovie():
                                tmp = TheMovieDbProvider().getArtByImdbId(
                                    mediaInDb)
                            elif mediaInDb.isTypeEpisode():
                                tvshow = db.getMediaWithTheTvDbId(
                                    mediaInDb.TheTvDbId)
                                #printl(str(tvshow.SeasonPoster), self, "E")
                                tvshow.SeasonPoster.clear(
                                )  # Make sure that there are no residues
                                tmp = TheTvDbProvider().getArtByTheTvDbId(
                                    tvshow)
                                if tmp is not None:
                                    printl(str(tmp.SeasonPoster), self, "E")

                            if tmp is not None:
                                Arts().download(tmp)

                                if mediaInDb.isTypeMovie():
                                    self.info(
                                        str(mediaInDb.ImdbId) + "_poster_" +
                                        posterSize + ".png", "", "")
                                elif mediaInDb.isTypeSerie(
                                ) or mediaInDb.isTypeEpisode():
                                    self.info(
                                        str(mediaInDb.TheTvDbId) + "_poster_" +
                                        posterSize + ".png", "", "")
                                del tmp

                        del mediaInDb
                        continue

                    outStr = "(" + str(i) + "/" + str(
                        elementListFileCounter) + ")"

                    self.output(outStr + " -> " + getStringShrinked(pathOrig) +
                                " >> " + filenameOrig + "." + extensionOrig)
                    printl("#" * 30, self)
                    printl(
                        "(" + str(i) + "/" + str(elementListFileCounter) + ")",
                        self)
                    printl("#" * 6, self)
                    printl(
                        "  -> " + pathOrig + "\n	" + filenameOrig + "." +
                        extensionOrig, self)

                    elementInfo = MediaInfo(path, filename, extension)

                    printl("FOLDERTYPE: " + str(folderType), self)
                    printl("USEFOLDER: " + str(useFolder), self)

                    if folderType == u"MOVIE":
                        elementInfo.setMediaType(MediaInfo.MOVIE)
                    elif folderType == u"TV":
                        elementInfo.setMediaType(MediaInfo.SERIE)
                    else:
                        elementInfo.setMediaType(MediaInfo.UNKNOWN)

                    result = elementInfo.parse(useFolder)

                    if result == False:
                        continue

                    printl("TheTvDbId: " + elementInfo.TheTvDbId, self, "I")

                    if elementInfo.isXbmcNfo == False:
                        printl(
                            "isXbmcNfo == False => checking for E2 recorded TV show... ",
                            self, "I")
                        if elementInfo.isTypeSerie(
                        ) and elementInfo.isEnigma2MetaRecording:
                            if elementInfo.Season == None or elementInfo.Episode == None:
                                printl(
                                    "E2-recorded TV-Show => trying to get season and episode from E2 episodename... ",
                                    self, "I")
                                tmp = GoogleProvider(
                                ).getSeasonAndEpisodeFromEpisodeName(
                                    elementInfo)
                                if (tmp[0] is True) and (tmp[1] is None):
                                    #Issue #474 => Don't fall back if foldertype is not explicitely "MOVIE_AND_TV"
                                    if folderType == u"MOVIE_AND_TV":
                                        printl(
                                            "E2-recording not recognized as TV show => trying to parse as movie... ",
                                            self, "I")
                                        elementInfo.setMediaType(
                                            MediaInfo.MOVIE)
                                    else:
                                        elementInfo.MediaType = MediaInfo.UNKNOWN  # avoid create serie
                                        elementInfo.MediaStatus = MediaInfo.STATUS_INFONOTFOUND
                                        elementInfo.syncErrNo = 3
                                        elementInfo.syncFailedCause = u"Info Not Found"  # cause
                                        printl(
                                            "Failed to detect TV show and folder type set to 'TV' => adding media as failed...",
                                            self, "I")
                                        db.insertMedia(elementInfo)
                                        continue
                                elif tmp[0] is True:
                                    # Issue #205, efo => use tmp[1] instead of tmp...
                                    elementInfo = tmp[1]
                                    printl(
                                        "Result from google => Season=" +
                                        str(elementInfo.Season) +
                                        " / Episode=" +
                                        str(elementInfo.Episode), self, "I")
                            else:
                                printl(
                                    "E2-recorded TV-Show: season and episode already set... ",
                                    self, "I")
                            searchStringSplitted = elementInfo.SearchString.split(
                                "::")
                            if len(searchStringSplitted) >= 2:
                                elementInfo.SearchString = searchStringSplitted[
                                    0]
                                printl(
                                    "New searchString after split: " +
                                    elementInfo.SearchString, self, "I")
                        printl(
                            "Get IMDb ID from title using searchString: " +
                            elementInfo.SearchString, self, "I")
                        tmp = MobileImdbComProvider().getMoviesByTitle(
                            elementInfo)
                        if tmp is None:
                            # validate if user use valerie.info with imdb or tvdb
                            if (elementInfo.isTypeSerie()
                                    and elementInfo.TheTvDbId
                                    == MediaInfo.TheTvDbIdNull) or (
                                        elementInfo.isTypeMovie()
                                        and elementInfo.ImdbId
                                        == MediaInfo.ImdbIdNull):
                                printl(
                                    "=> nothing found :-( " +
                                    elementInfo.SearchString, self, "I")
                                #db.addFailed(FailedEntry(path, filename, extension, FailedEntry.UNKNOWN))
                                #elementInfo.MediaType = MediaInfo.FAILEDSYNC
                                elementInfo.MediaType = MediaInfo.UNKNOWN  # avoid create serie
                                elementInfo.MediaStatus = MediaInfo.STATUS_INFONOTFOUND
                                elementInfo.syncErrNo = 3
                                elementInfo.syncFailedCause = u"Info Not Found"  # cause
                                db.insertMedia(elementInfo)
                                continue
                        else:
                            elementInfo = tmp
                        printl("Finally about to sync element... ", self, "I")
                        results = Sync().syncWithId(elementInfo)
                    else:
                        printl(
                            "isXbmcNfo == True => using data from nfo:\n" +
                            str(elementInfo), self, "I")
                        results = (elementInfo, )

                    if results is not None:
                        printl("results: " + str(results), self)
                        for result in results:
                            result.MediaStatus = MediaInfo.STATUS_OK
                            result.syncErrNo = 0
                            result.syncFailedCause = u""
                            #printl("INSERT: "+result.Filename+ " type: " + str(result.MediaType) , self, "I")
                            ret = db.insertMedia(result)
                            if ret["status"] > 0:
                                #result.Title = self.encodeMe(result.Title)
                                if result.isTypeMovie():
                                    self.info(
                                        str(result.ImdbId) + "_poster_" +
                                        posterSize + ".png", result.Title,
                                        result.Year)
                                    printl("my_title " + result.Title, self,
                                           "I")
                                else:
                                    self.info(
                                        str(result.TheTvDbId) + "_poster_" +
                                        posterSize + ".png", result.Title,
                                        result.Year)
                                    printl("my_title " + result.Title, self,
                                           "I")
                            else:
                                # ??????

                                #cause = db.getAddFailedCauseOf()
                                #db.addFailed(FailedEntry(path, filename, extension, FailedEntry.ALREADY_IN_DB,cause))
                                #if result.syncFailedCause == u"":
                                #	result.syncFailedCause = "DB Insert Error ??"
                                result.MediaType = MediaInfo.FAILEDSYNC
                                try:
                                    db.insertMedia(result)
                                except Exception, ex:
                                    printl("DB Insert Error ??", self, "W")

                    #self.output("(" + str(i) + "/" + str(elementListFileCounter) + ")")
                    #printl("(" + str(i) + "/" + str(elementListFileCounter) + ")", self)
                    self.progress(i)