mirror of
				https://github.com/Jonny007-MKD/OTR-SaneRename
				synced 2025-11-03 16:15:35 +01:00 
			
		
		
		
	Added support for manual.json
This commit is contained in:
		
							parent
							
								
									197086a236
								
							
						
					
					
						commit
						7dae8c24be
					
				
					 3 changed files with 148 additions and 48 deletions
				
			
		
							
								
								
									
										160
									
								
								saneRenamix.py
									
									
									
									
									
								
							
							
						
						
									
										160
									
								
								saneRenamix.py
									
									
									
									
									
								
							| 
						 | 
					@ -15,6 +15,7 @@ import os
 | 
				
			||||||
import csv
 | 
					import csv
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import requests
 | 
					import requests
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
from datetime import datetime
 | 
					from datetime import datetime
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
	import urllib
 | 
						import urllib
 | 
				
			||||||
| 
						 | 
					@ -54,19 +55,25 @@ def parseArgs():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EpisodeInfo:
 | 
					class EpisodeInfo:
 | 
				
			||||||
	def __init__(self):
 | 
						def __init__(self):
 | 
				
			||||||
		self.season = None				# int
 | 
							self.season = None				# int, number of Season
 | 
				
			||||||
		self.episode = None				# int
 | 
							self.episode = None				# int, number of Episode in Season
 | 
				
			||||||
		self.seriesName = None			# str
 | 
							self.seriesId = None			# int, TvDB ID of Series
 | 
				
			||||||
		self.episodeTitle = None		# str
 | 
							self.seriesName = None			# str, Name of series. Taken from filename and replaced with the nice name from TvDB
 | 
				
			||||||
		self.maybeEpisodeTitle = None	# str
 | 
							self.episodeTitle = None		# str, Title of Episode. Taken from filename (if possible), replaced with name from TvDB
 | 
				
			||||||
		self.datetime = None			# datetime
 | 
							self.maybeEpisodeTitle = None	# str, Indicator whether the Episode title is a guess
 | 
				
			||||||
 | 
							self.datetime = None			# datetime, When the file was aired/recorded
 | 
				
			||||||
		self.sender = None				# str
 | 
							self.sender = None				# str
 | 
				
			||||||
		self.description = None 		# str
 | 
							self.description = None 		# str, Description from EPG data. Can be used to search the Episode
 | 
				
			||||||
		self.fileSuffix = None			# str
 | 
							self.fileSuffix = None			# str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def __str__(self):
 | 
						def __str__(self):
 | 
				
			||||||
		result = ""
 | 
							result = ""
 | 
				
			||||||
		if self.seriesName: result += self.seriesName + " "
 | 
							if self.seriesName:
 | 
				
			||||||
 | 
								result += self.seriesName + " "
 | 
				
			||||||
 | 
								if self.seriesId: result += " (" + self.seriesId + ")"
 | 
				
			||||||
 | 
							else:
 | 
				
			||||||
 | 
								if self.seriesId: result += "Series#" + self.seriesId
 | 
				
			||||||
 | 
							if result: result += " "
 | 
				
			||||||
		if self.season:  result += f"S{self.season:02d}"
 | 
							if self.season:  result += f"S{self.season:02d}"
 | 
				
			||||||
		if self.episode: result += f"E{self.episode:02d}"
 | 
							if self.episode: result += f"E{self.episode:02d}"
 | 
				
			||||||
		if result: result += " "
 | 
							if result: result += " "
 | 
				
			||||||
| 
						 | 
					@ -106,6 +113,40 @@ def analyzeFilename(filename: str):
 | 
				
			||||||
	logging.info(f"  found info: {result.seriesName}, {result.datetime}, {result.sender}, S{result.season}E{result.episode}, {result.fileSuffix}")
 | 
						logging.info(f"  found info: {result.seriesName}, {result.datetime}, {result.sender}, S{result.season}E{result.episode}, {result.fileSuffix}")
 | 
				
			||||||
	return result
 | 
						return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def readManualInfo(filename: str, info: EpisodeInfo):
 | 
				
			||||||
 | 
						logging.debug(f"readManualInfo({filename})")
 | 
				
			||||||
 | 
						file = os.path.join(workingDir, "manual.json")
 | 
				
			||||||
 | 
						if not os.path.isfile(file): return
 | 
				
			||||||
 | 
						with open(file) as json_file:
 | 
				
			||||||
 | 
							try:
 | 
				
			||||||
 | 
								data = json.load(json_file)
 | 
				
			||||||
 | 
							except Exception as e:
 | 
				
			||||||
 | 
								logging.warn(f"  Cannot read JSON file: {e}")
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parts = filename.split('.')
 | 
				
			||||||
 | 
						for i in range(len(parts), 3, -1):
 | 
				
			||||||
 | 
							filename2 = '.'.join(parts[0:i])
 | 
				
			||||||
 | 
							if filename2 in data:
 | 
				
			||||||
 | 
								data = data[filename2]
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
						else:
 | 
				
			||||||
 | 
							logging.debug("  No data found")
 | 
				
			||||||
 | 
							return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def get(keys: list):
 | 
				
			||||||
 | 
							for k in keys + [ k.lower() for k in keys ]:
 | 
				
			||||||
 | 
								if k in data: return data[k]
 | 
				
			||||||
 | 
							return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						series = get([ "Series" ])
 | 
				
			||||||
 | 
						if series:
 | 
				
			||||||
 | 
							if type(series) == int: info.seriesId = series
 | 
				
			||||||
 | 
							if type(series) == str: info.seriesName = series
 | 
				
			||||||
 | 
						if not info.season:  info.season  = get([ "Season",  "S" ])
 | 
				
			||||||
 | 
						if not info.episode: info.episode = get([ "Episode", "E" ])
 | 
				
			||||||
 | 
						return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def convertTitle(title: str, lang: str):
 | 
					def convertTitle(title: str, lang: str):
 | 
				
			||||||
	title = title.replace(" s ", "'s ")
 | 
						title = title.replace(" s ", "'s ")
 | 
				
			||||||
	if title.endswith(" s"): title = title[0:-2] + "'s"
 | 
						if title.endswith(" s"): title = title[0:-2] + "'s"
 | 
				
			||||||
| 
						 | 
					@ -132,11 +173,12 @@ def getSeriesId(info: EpisodeInfo, args: dict):
 | 
				
			||||||
			logging.debug(f"    pickle load failed: {e}")
 | 
								logging.debug(f"    pickle load failed: {e}")
 | 
				
			||||||
			return None
 | 
								return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def fromCache(cache):
 | 
						def fromCacheWithName(cache: dict, seriesName: str):
 | 
				
			||||||
		logging.debug(f"  fromCache()")
 | 
							""" Return tuple (id, niceName) when series is found in Cache, otherwise (None, None) """
 | 
				
			||||||
 | 
							logging.debug(f"  fromCacheWithName({seriesName})")
 | 
				
			||||||
		if not cache: return (None, None)
 | 
							if not cache: return (None, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		words = info.seriesName.split(' ')
 | 
							words = seriesName.split(' ')
 | 
				
			||||||
		for i in range(len(words), 0, -1):
 | 
							for i in range(len(words), 0, -1):
 | 
				
			||||||
			title2 = " ".join(words[0:i])
 | 
								title2 = " ".join(words[0:i])
 | 
				
			||||||
			titles = set([title2, convertTitle(title2, args.language)])
 | 
								titles = set([title2, convertTitle(title2, args.language)])
 | 
				
			||||||
| 
						 | 
					@ -150,10 +192,24 @@ def getSeriesId(info: EpisodeInfo, args: dict):
 | 
				
			||||||
		logging.debug(f"    found nothing")
 | 
							logging.debug(f"    found nothing")
 | 
				
			||||||
		return (None, None)
 | 
							return (None, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def fromTvdb():
 | 
						def fromCacheWithId(cache: dict, id: int):
 | 
				
			||||||
		logging.debug(f"  fromTvdb()")
 | 
							""" Return nice series name when id is found in cache, otherwise None """
 | 
				
			||||||
 | 
							logging.debug(f"  fromCacheWithId({id})")
 | 
				
			||||||
 | 
							if not cache: return None
 | 
				
			||||||
 | 
							for key, value in cache.items():
 | 
				
			||||||
 | 
								if value[0] == id:
 | 
				
			||||||
 | 
									logging.debug(f"    found {value[1]}")
 | 
				
			||||||
 | 
									return value[1]
 | 
				
			||||||
 | 
							return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		words = info.seriesName.split(' ')
 | 
						def fromTvdbWithName(name: str):
 | 
				
			||||||
 | 
							"""
 | 
				
			||||||
 | 
							Search TvDB for a series with the specified name (or a subset of it)
 | 
				
			||||||
 | 
							Return a tuple (SeriesID, Nice Name) if a unique result was found, otherwise exit.
 | 
				
			||||||
 | 
							"""
 | 
				
			||||||
 | 
							logging.debug(f"  fromTvdbWithName({name})")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							words = name.split(' ')
 | 
				
			||||||
		regex = re.compile("[^a-zA-Z0-9 ]")
 | 
							regex = re.compile("[^a-zA-Z0-9 ]")
 | 
				
			||||||
		allResults = []
 | 
							allResults = []
 | 
				
			||||||
		for i in range(len(words), 0, -1):
 | 
							for i in range(len(words), 0, -1):
 | 
				
			||||||
| 
						 | 
					@ -195,6 +251,20 @@ def getSeriesId(info: EpisodeInfo, args: dict):
 | 
				
			||||||
		logging.debug(f"    nothing found")
 | 
							logging.debug(f"    nothing found")
 | 
				
			||||||
		sys.exit(ExitCode.SeriesNotFoundInTvDB)
 | 
							sys.exit(ExitCode.SeriesNotFoundInTvDB)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						def fromTvdbWithId(id: int):
 | 
				
			||||||
 | 
							logging.debug(f"  fromTvdbWithId({id})")
 | 
				
			||||||
 | 
							"""
 | 
				
			||||||
 | 
							Return the nice series name from TvDB.
 | 
				
			||||||
 | 
							If the series doesn't exist, exit.
 | 
				
			||||||
 | 
							"""
 | 
				
			||||||
 | 
							try:
 | 
				
			||||||
 | 
								series = tvdb.series.Series(id, language=args.language).info()
 | 
				
			||||||
 | 
								logging.debug(f"    found {series['seriesName']}")
 | 
				
			||||||
 | 
								return series["seriesName"]
 | 
				
			||||||
 | 
							except Exception as e:
 | 
				
			||||||
 | 
								logging.error(f"    Exception: {e}")
 | 
				
			||||||
 | 
								sys.exit(ExitCode.SeriesNotFoundInTvDB)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def writeCache(id: int, names: list, cache: dict):
 | 
						def writeCache(id: int, names: list, cache: dict):
 | 
				
			||||||
		if args.nocache: return
 | 
							if args.nocache: return
 | 
				
			||||||
		logging.debug(f"  writeCache({id}, {names})")
 | 
							logging.debug(f"  writeCache({id}, {names})")
 | 
				
			||||||
| 
						 | 
					@ -226,13 +296,25 @@ def getSeriesId(info: EpisodeInfo, args: dict):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# Load good series name. First from cache, then from TvDB
 | 
						# ID already known (probably input from user), so load series name
 | 
				
			||||||
 | 
						if info.seriesId:
 | 
				
			||||||
		cache = loadCache()
 | 
							cache = loadCache()
 | 
				
			||||||
	(id, niceName) = fromCache(cache)
 | 
							niceName = fromCacheWithId(cache, info.seriesId)
 | 
				
			||||||
 | 
							if not niceName:
 | 
				
			||||||
 | 
								niceName = fromTvdbWithId(info.seriesId)
 | 
				
			||||||
 | 
							if niceName:
 | 
				
			||||||
 | 
								writeCache(info.seriesId, [ info.seriesName, niceName ], cache)
 | 
				
			||||||
 | 
								info.seriesName = niceName
 | 
				
			||||||
 | 
							return	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# Load good series name and id. First from cache, then from TvDB
 | 
				
			||||||
 | 
						if not info.seriesId:
 | 
				
			||||||
 | 
							cache = loadCache()
 | 
				
			||||||
 | 
							(id, niceName) = fromCacheWithName(cache, info.seriesName)
 | 
				
			||||||
		if id:
 | 
							if id:
 | 
				
			||||||
			checkWhetherSeriesNameContainsEpisodeName(niceName)
 | 
								checkWhetherSeriesNameContainsEpisodeName(niceName)
 | 
				
			||||||
		else:
 | 
							else:
 | 
				
			||||||
		(id, niceName) = fromTvdb()
 | 
								(id, niceName) = fromTvdbWithName(info.seriesName)
 | 
				
			||||||
			if id:
 | 
								if id:
 | 
				
			||||||
				names = [ niceName ]
 | 
									names = [ niceName ]
 | 
				
			||||||
				thirdName = checkWhetherSeriesNameContainsEpisodeName(niceName)
 | 
									thirdName = checkWhetherSeriesNameContainsEpisodeName(niceName)
 | 
				
			||||||
| 
						 | 
					@ -240,13 +322,10 @@ def getSeriesId(info: EpisodeInfo, args: dict):
 | 
				
			||||||
				else: names.append(info.seriesName)
 | 
									else: names.append(info.seriesName)
 | 
				
			||||||
				writeCache(id, names, cache)
 | 
									writeCache(id, names, cache)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if not id: return None
 | 
							if not id: return
 | 
				
			||||||
 | 
							else: info.seriesName = niceName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if id:
 | 
						info.seriesId = id
 | 
				
			||||||
		info.seriesName = niceName
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return id
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getEpgData(info: EpisodeInfo):
 | 
					def getEpgData(info: EpisodeInfo):
 | 
				
			||||||
	logging.debug("getEpgData()")
 | 
						logging.debug("getEpgData()")
 | 
				
			||||||
| 
						 | 
					@ -306,10 +385,10 @@ def getEpgData(info: EpisodeInfo):
 | 
				
			||||||
		logging.debug("  set: {info.description}")
 | 
							logging.debug("  set: {info.description}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Episodes:
 | 
					class Episodes:
 | 
				
			||||||
	def __init__(self, seriesID: int, args: dict):
 | 
						def __init__(self, seriesId: int, args: dict):
 | 
				
			||||||
		self.seriesID = seriesID
 | 
							self.seriesId = seriesId
 | 
				
			||||||
		self.args = args
 | 
							self.args = args
 | 
				
			||||||
		self.path = os.path.join(workingDir, f"episode-{seriesID}.cache")
 | 
							self.path = os.path.join(workingDir, f"episode-{seriesId}.cache")
 | 
				
			||||||
		self.fromCache = None
 | 
							self.fromCache = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def _loadCache(self):
 | 
						def _loadCache(self):
 | 
				
			||||||
| 
						 | 
					@ -328,7 +407,7 @@ class Episodes:
 | 
				
			||||||
		logging.debug(f"  fromTvdb()")
 | 
							logging.debug(f"  fromTvdb()")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try:
 | 
							try:
 | 
				
			||||||
			episodes = tvdb.series.Series_Episodes(self.seriesID, language=self.args.language).all()
 | 
								episodes = tvdb.series.Series_Episodes(self.seriesId, language=self.args.language).all()
 | 
				
			||||||
			return episodes
 | 
								return episodes
 | 
				
			||||||
		except Exception as e:
 | 
							except Exception as e:
 | 
				
			||||||
			logging.error(f"    Exception: {e}")
 | 
								logging.error(f"    Exception: {e}")
 | 
				
			||||||
| 
						 | 
					@ -355,12 +434,12 @@ class Episodes:
 | 
				
			||||||
		return episodes
 | 
							return episodes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getEpisodeTitleFromEpgData(info: EpisodeInfo, seriesID: int, args: dict):
 | 
					def getEpisodeTitleFromEpgData(info: EpisodeInfo, args: dict):
 | 
				
			||||||
	logging.debug(f"getEpisodeTitleFromEpgData()")
 | 
						logging.debug(f"getEpisodeTitleFromEpgData()")
 | 
				
			||||||
	if not info.description:
 | 
						if not info.description:
 | 
				
			||||||
		logging.debug(f"  no description")
 | 
							logging.debug(f"  no description")
 | 
				
			||||||
		return # Nothing we can do about it :(
 | 
							return # Nothing we can do about it :(
 | 
				
			||||||
	E = Episodes(seriesID, args)
 | 
						E = Episodes(info.seriesId, args)
 | 
				
			||||||
	regex = re.compile("[^a-zA-Z0-9 ]")
 | 
						regex = re.compile("[^a-zA-Z0-9 ]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def get(dct: dict, keys: list):
 | 
						def get(dct: dict, keys: list):
 | 
				
			||||||
| 
						 | 
					@ -396,7 +475,7 @@ def getEpisodeTitleFromEpgData(info: EpisodeInfo, seriesID: int, args: dict):
 | 
				
			||||||
	for i in range(2): # Try once from cache and once from TvDB
 | 
						for i in range(2): # Try once from cache and once from TvDB
 | 
				
			||||||
		episodes = E.get()
 | 
							episodes = E.get()
 | 
				
			||||||
		if not episodes: continue# Nothing we can do about it :(
 | 
							if not episodes: continue# Nothing we can do about it :(
 | 
				
			||||||
		episodesByName = { e["episodeName"].strip(): e for e in episodes }
 | 
							episodesByName = { e["episodeName"].strip(): e for e in episodes if e is not None and e["episodeName"] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if info.maybeEpisodeTitle and info.maybeEpisodeTitle in episodesByName:
 | 
							if info.maybeEpisodeTitle and info.maybeEpisodeTitle in episodesByName:
 | 
				
			||||||
			saveInfo(episodesByName[info.maybeEpisodeTitle])
 | 
								saveInfo(episodesByName[info.maybeEpisodeTitle])
 | 
				
			||||||
| 
						 | 
					@ -411,7 +490,7 @@ def getEpisodeTitleFromEpgData(info: EpisodeInfo, seriesID: int, args: dict):
 | 
				
			||||||
		if found: return
 | 
							if found: return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		logging.debug("  searching for a matching episode name more liberally")
 | 
							logging.debug("  searching for a matching episode name more liberally")
 | 
				
			||||||
		episodesByName2 = { regex.sub("", e["episodeName"]).lower().strip(): e for e in episodes }
 | 
							episodesByName2 = { regex.sub("", e["episodeName"]).lower().strip(): e for e in episodes if e is not None }
 | 
				
			||||||
		def searchByName2(title: str):
 | 
							def searchByName2(title: str):
 | 
				
			||||||
			title = regex.sub("", title).lower().strip()
 | 
								title = regex.sub("", title).lower().strip()
 | 
				
			||||||
			logging.debug(f'    trying "{title}"')
 | 
								logging.debug(f'    trying "{title}"')
 | 
				
			||||||
| 
						 | 
					@ -422,7 +501,7 @@ def getEpisodeTitleFromEpgData(info: EpisodeInfo, seriesID: int, args: dict):
 | 
				
			||||||
		logging.debug("  searching for a matching description (startswith)")
 | 
							logging.debug("  searching for a matching description (startswith)")
 | 
				
			||||||
		def searchByOverview(overview: str):
 | 
							def searchByOverview(overview: str):
 | 
				
			||||||
			logging.debug(f'    trying "{overview}"')
 | 
								logging.debug(f'    trying "{overview}"')
 | 
				
			||||||
			results = [ e for e in episodes if e["overview"] and e["overview"].strip().startswith(overview) ]
 | 
								results = [ e for e in episodes if e is not None and e["overview"] and e["overview"].strip().startswith(overview) ]
 | 
				
			||||||
			if len(results) == 1: return results[0]
 | 
								if len(results) == 1: return results[0]
 | 
				
			||||||
			return None
 | 
								return None
 | 
				
			||||||
		found = doSearch(searchByOverview)
 | 
							found = doSearch(searchByOverview)
 | 
				
			||||||
| 
						 | 
					@ -432,7 +511,7 @@ def getEpisodeTitleFromEpgData(info: EpisodeInfo, seriesID: int, args: dict):
 | 
				
			||||||
		def searchByOverview2(overview: str):
 | 
							def searchByOverview2(overview: str):
 | 
				
			||||||
			overview = regex.sub("", overview).lower().strip()
 | 
								overview = regex.sub("", overview).lower().strip()
 | 
				
			||||||
			logging.debug(f'    trying "{overview}"')
 | 
								logging.debug(f'    trying "{overview}"')
 | 
				
			||||||
			results = [ e for e in episodes if e["overview"] and regex.sub("", e["overview"]).lower().strip().startswith(overview) ]
 | 
								results = [ e for e in episodes if e is not None and e["overview"] and regex.sub("", e["overview"]).lower().strip().startswith(overview) ]
 | 
				
			||||||
			if len(results) == 1: return results[0]
 | 
								if len(results) == 1: return results[0]
 | 
				
			||||||
			return None
 | 
								return None
 | 
				
			||||||
		found = doSearch(searchByOverview2)
 | 
							found = doSearch(searchByOverview2)
 | 
				
			||||||
| 
						 | 
					@ -440,9 +519,9 @@ def getEpisodeTitleFromEpgData(info: EpisodeInfo, seriesID: int, args: dict):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def getEpisodeTitleFromTvdb(info: EpisodeInfo, seriesID: int, args: dict):
 | 
					def getEpisodeTitleFromTvdb(info: EpisodeInfo, args: dict):
 | 
				
			||||||
	logging.debug("getEpisodeTitleFromTvdb()")
 | 
						logging.debug("getEpisodeTitleFromTvdb()")
 | 
				
			||||||
	episodes = Episodes(seriesID, args).get()
 | 
						episodes = Episodes(info.seriesId, args).get()
 | 
				
			||||||
	if not episodes: return # Nothing we can do :(
 | 
						if not episodes: return # Nothing we can do :(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def get(dct: dict, keys: list):
 | 
						def get(dct: dict, keys: list):
 | 
				
			||||||
| 
						 | 
					@ -461,6 +540,7 @@ def getEpisodeTitleFromTvdb(info: EpisodeInfo, seriesID: int, args: dict):
 | 
				
			||||||
def printResult(info: EpisodeInfo):
 | 
					def printResult(info: EpisodeInfo):
 | 
				
			||||||
	if info.seriesName and info.season and info.episode:
 | 
						if info.seriesName and info.season and info.episode:
 | 
				
			||||||
		episodeTitle = info.episodeTitle.replace(' ', '.') if info.episodeTitle else ""
 | 
							episodeTitle = info.episodeTitle.replace(' ', '.') if info.episodeTitle else ""
 | 
				
			||||||
 | 
							episodeTitle = episodeTitle.replace('?', '')		# Remove ? because Samba doesn't like them
 | 
				
			||||||
		print(f"{info.seriesName.replace(' ', '.')}..S{info.season:02d}E{info.episode:02d}..{episodeTitle}.{info.fileSuffix}")
 | 
							print(f"{info.seriesName.replace(' ', '.')}..S{info.season:02d}E{info.episode:02d}..{episodeTitle}.{info.fileSuffix}")
 | 
				
			||||||
		sys.exit(0)
 | 
							sys.exit(0)
 | 
				
			||||||
	else:
 | 
						else:
 | 
				
			||||||
| 
						 | 
					@ -471,12 +551,14 @@ if __name__ == '__main__':
 | 
				
			||||||
	logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(message)s")
 | 
						logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(message)s")
 | 
				
			||||||
	args = parseArgs()
 | 
						args = parseArgs()
 | 
				
			||||||
	info = analyzeFilename(args.file)
 | 
						info = analyzeFilename(args.file)
 | 
				
			||||||
	id = getSeriesId(info, args)
 | 
						manual = readManualInfo(args.file, info)
 | 
				
			||||||
	if not id: sys.exit(ExitCode.SeriesNotFoundInTvDB)
 | 
						if manual or not info.seriesId or not info.seriesName:
 | 
				
			||||||
 | 
							getSeriesId(info, args)
 | 
				
			||||||
 | 
						if not info.seriesId: sys.exit(ExitCode.SeriesNotFoundInTvDB)
 | 
				
			||||||
	if not info.season or not info.episode:
 | 
						if not info.season or not info.episode:
 | 
				
			||||||
		getEpgData(info)
 | 
							getEpgData(info)
 | 
				
			||||||
		getEpisodeTitleFromEpgData(info, id, args)
 | 
							getEpisodeTitleFromEpgData(info, args)
 | 
				
			||||||
	if not info.episodeTitle:
 | 
						if not info.episodeTitle:
 | 
				
			||||||
		getEpisodeTitleFromTvdb(info, id, args)
 | 
							getEpisodeTitleFromTvdb(info, args)
 | 
				
			||||||
	printResult(info)
 | 
						printResult(info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										7
									
								
								testing/manual.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								testing/manual.json
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"Die_Bruecke_Transit_in_den_Tod_18.09.22_00-45_zdf_115_TVOON_DE.mpg.HD.avi": {
 | 
				
			||||||
 | 
							"Series": 252019,
 | 
				
			||||||
 | 
							"Season": 1,
 | 
				
			||||||
 | 
							"Episode": 1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,8 @@ files=(
 | 
				
			||||||
	["Irene_Huss_Kripo_Goeteborg_Der_im_Dunkeln_wacht_S02E01_15.08.08_22-55_ard_90_TVOON_DE.mpg.HQ.avi"]="Irene.Huss,.Kripo.Göteborg..S02E01..Der.im.Dunkeln.wacht.mpg.HQ.avi"
 | 
						["Irene_Huss_Kripo_Goeteborg_Der_im_Dunkeln_wacht_S02E01_15.08.08_22-55_ard_90_TVOON_DE.mpg.HQ.avi"]="Irene.Huss,.Kripo.Göteborg..S02E01..Der.im.Dunkeln.wacht.mpg.HQ.avi"
 | 
				
			||||||
# Difficult search for series
 | 
					# Difficult search for series
 | 
				
			||||||
	["Ein_Fall_fuer_TKKG_S01E01_15.11.16_13-20_kika_20_TVOON_DE.mpg.avi"]="Ein.Fall.für.TKKG..S01E01..Das.leere.Grab.im.Moor.mpg.avi"
 | 
						["Ein_Fall_fuer_TKKG_S01E01_15.11.16_13-20_kika_20_TVOON_DE.mpg.avi"]="Ein.Fall.für.TKKG..S01E01..Das.leere.Grab.im.Moor.mpg.avi"
 | 
				
			||||||
 | 
					# Take Season and Episode info from manual.json
 | 
				
			||||||
 | 
						["Die_Bruecke_Transit_in_den_Tod_18.09.22_00-45_zdf_115_TVOON_DE.mpg.HD.avi.otrkey"]="Die.Brücke.–.Transit.in.den.Tod..S01E01..Teil.1.mpg.HD.avi.otrkey"
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [ -f test.sh ]; then
 | 
					if [ -f test.sh ]; then
 | 
				
			||||||
| 
						 | 
					@ -38,6 +40,10 @@ fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function finish {
 | 
					function finish {
 | 
				
			||||||
	pushd $path
 | 
						pushd $path
 | 
				
			||||||
 | 
						# Restore manual.json
 | 
				
			||||||
 | 
						if [ -f "manual.json.orig" ]; then
 | 
				
			||||||
 | 
							mv "manual.json.orig" "manual.json"
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
	# Restore *.cache
 | 
						# Restore *.cache
 | 
				
			||||||
	for f in `ls *.cache.orig`; do
 | 
						for f in `ls *.cache.orig`; do
 | 
				
			||||||
		mv "$f" "${f::-5}"
 | 
							mv "$f" "${f::-5}"
 | 
				
			||||||
| 
						 | 
					@ -48,6 +54,11 @@ trap finish EXIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function init {
 | 
					function init {
 | 
				
			||||||
	pushd $path
 | 
						pushd $path
 | 
				
			||||||
 | 
						# Backup and replace manual.json
 | 
				
			||||||
 | 
						if [ -f "$path/manual.json" ]; then
 | 
				
			||||||
 | 
							mv "$path/manual.json" "$path/manual.json.orig"
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						cp "$(dirname $0)/manual.json" "$path/manual.json"
 | 
				
			||||||
	# Remove caches
 | 
						# Remove caches
 | 
				
			||||||
	for f in `ls *.cache`; do
 | 
						for f in `ls *.cache`; do
 | 
				
			||||||
		mv "$f" "$f.orig"
 | 
							mv "$f" "$f.orig"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue