예제 #1
0
class FsSeriesStore(SeriesStore):
	""" Base class model for a set of Series managed by a bash store """

	config_file_season_name = ".play_conf"	
	config_file_serie_name = ".play_season"
	default_config_file_abs_name = Config.config_file_abs_name 

	path_to_series_var = "BASE"
	play_current_episode_var = "CUR"
	skip_time_var = "GENERICTIME"
	decay_time_var = "DECALAGESUB"
	serie_name_var = "NAME"
	fps_var = "SUBFPS"

	def __init__(self, config_file = default_config_file_abs_name):
		#pylint:disable=W0231
		self.executer = CommandExecuter()
		self.config_file_abs_name = config_file 
		self.config_manager = ConfigManager( config_file )
		self.config = Config(config_file) 

# paths generator
	def get_global_config_file(self):
		""" Get Path to global user config file """
		return os.path.expanduser(self.config_file_abs_name)

	def get_absolute_path(self):
		""" Get Root Path for Series storing"""
		base = self.config_manager.read_conf_var(self.get_global_config_file(), \
						self.path_to_series_var)
		base = os.path.expanduser(base)
		info("reading conf from file : {0}".format(base))
		debug("base path : {}".format(base))
		if not os.path.exists(base):
			raise FileNameError(base)
		return base

	def get_path_to_serie(self, name):
		""" Get path to serie @name
		"""
		base = self.get_absolute_path()
		return os.path.join(base, name)

	def get_path_to_current_season(self):
		""" Get path to current season of currently viewed serie
		"""
		name = self.get_current_serie_name()
		return self.get_path_to_current_season_of(name) 

	def get_serie_configfile(self, name):
		""" Returns configfile for serie name @name """
		return os.path.join(self.get_path_to_serie(name), self.config_file_serie_name)

	def get_season_configfile(self, name, season):
		""" returns season configfile for serie 'name' season 'season' """
		return os.path.join(self.get_path_to_season(name, season), 
				self.config_file_season_name)

	def get_path_to_current_season_of(self, name):
		""" Get path to current season of a particular serie @name
		"""
		num = self.get_stored_current_season_number(name)
		return self.get_path_to_season(name, num)

	def get_path_to_season(self, name, numseason):
		""" Get path to season @numseason of serie @name
		"""
		serie_path = self.get_path_to_serie(name)
		pattern = '[Ss]*{}'.format(numseason)

		full_pattern = os.path.join(serie_path, pattern)
		candidates = glob.glob(full_pattern)
		if len(candidates) == 0:
			return os.path.join(serie_path, "Saison {}".format(numseason))
			# raise Exception("Season {} path not found for '{}'".format(numsaison, name))

		return candidates[0]

	
# config management 
	def read_conf_var(self, config_file_path, var_name, default=None):
		""" Gets a value in a 'key=value' file format 
		@config_file_path : the file
		@var_name : the key
		"""
		try:
			return self.config_manager.read_conf_var(config_file_path, var_name)
		finally:
			pass
		return default
	
	def write_conf_var(self, config_file_path, var_name, value):
		""" Writes a value in a 'key=value' file format 
		@config_file_path : the file
		@var_name : the key
		@value : the value
		"""
		return self.config_manager.write_conf_var(config_file_path, var_name, value)
		
	def read_num_conf_var(self, config_file_path, var_name, default = None):
		""" Reads a numeric value in a 'key=value' file format 
		@config_file_path : the file
		@var_name : the key
		"""
		value = default
		try:
			value = self.config_manager.read_num_conf_var(config_file_path, var_name)
		except Exception:
			pass
		return value 

		# finally:
		#	return default

	def get_conf_variable(self, name, numseason, var_name):
		""" Gets value of a variable stored for a specified @numseason season
		of a specified serie @name. """
		return self.read_conf_var(self.get_path_to_season(name, numseason), var_name)

	def get_num_conf_variable(self, name, numseason, var_name):
		""" same as get_conf_variable for a Numeric value """
		return self.read_num_conf_var(
				self.get_path_to_season(name, numseason), 
				var_name)


# useful data getters
	def get_current_serie_name(self):
		""" Returns the name of current serie """
		return self.config_manager.read_var("NAME")

	def get_stored_current_season_number(self, name):
		""" Returns season number of current serie """

		serie_conf_file = self.get_serie_configfile(name)
		num = self.read_num_conf_var(serie_conf_file, "SEASON", 1)
	
		return num

	def get_serie_list(self):
		""" Returns the list of series name
		on the directory """
		serie_path = self.get_absolute_path()
		dirs = [ x for x in os.listdir(serie_path) 
				if os.path.isdir(os.path.join(serie_path, x)) ]
		return dirs

	def create_season_storage(self, serie_name, season_num):
		""" Create season directory for serie 'serie_name' season 'season_num'"""
		serie_path = self.get_path_to_serie(serie_name)
		dir_name = "Saison {}".format(season_num)
		
		full_season_path = os.path.join(serie_path, dir_name)
		os.mkdir(full_season_path)

		with open( self.get_season_configfile(serie_name, \
				season_num) ,'w') as fic:
			fic.write("""CUR='1'\nGENERICTIME='0'""")
		

	def get_current_stored_episode(self, serie_name, season_num):
		""" Returns current episode number in disk store
		"""
		ficname = ""
		season_path = None
		try:
			season_path = self.get_path_to_season(serie_name, \
				season_num)
		except Exception :
			self.create_season_storage(serie_name, season_num)
			season_path = self.get_path_to_season(serie_name, 
				season_num)

		ficname = os.path.join( season_path, \
				self.config_file_season_name )

		if os.path.exists(ficname):
			return self.read_num_conf_var(ficname, \
					self.play_current_episode_var)
		return None
		# raise Exception("Unexisting config file {}".format(ficname))

	def get_subtitle_candidates(self, serie_name, season_num, num_ep):
		""" Returns the list of filename candidates for subtitles
		for @serie_name, for season number @season_num, episode @num_ep
		"""
		extensions = self.config.get_sub_extensions()
		
		result = self._get_candidates(serie_name, season_num, num_ep, extensions)
		return result
	
	def get_video_candidates(self, serie_name, season_num, num_ep):
		""" Returns the list of filename candidates for video
		for @serie_name, for season number @season_num, episode @num_ep
		""" 
		extensions = self.config.get_video_extensions()
		result = self._get_candidates(serie_name, season_num, num_ep, extensions)

		assert(len(result)>=0)
		return result

	def get_glob_pattern(self, season_num, num_ep, ext_list = None):
		""" Get globbing pattern
		"""
		patterns =  ['({season:02d}|{season:d}).*{ep:02d}[^0-9]',
				'[sS]{season:02d}[^0-9]( )?[xeE]{ep:02d}[^0-9]'
			]
		

		pattern = "({})".format("|".join(patterns))

		pattern = pattern.format(season = season_num, \
				ep = num_ep)


		if ext_list:
			pattern = '({}.*)\.({})'.format(pattern, "|".join(ext_list))

		return pattern

	def _get_candidates_in_path(self, path, season_num, num_ep, option):
		""" return matching filenames in path 'path' as "path/filename" list """
		result = []
		if(os.path.exists(path)):
			re_pattern = self.get_glob_pattern(season_num, num_ep, option)
			regex = re.compile(re_pattern)
			all_files = os.listdir(path)

			direct = [ os.path.join(path, x) for x in all_files 
					if regex.search(x) ]
			result = direct

		return result

	def _get_candidates(self, serie_name, season_num, num_ep, option):
		"""  calls candidates finder bash script """
		path = self.get_path_to_season(serie_name, season_num)
		result = []
		if os.path.exists(path):

			all_files = os.listdir(path)

			direct = self._get_candidates_in_path(
					path, 
					season_num, num_ep, option) #[ x for x in all_files 
					#if regex.search(x) ]

			re_dir_pattern = re.compile(self.get_glob_pattern(season_num, num_ep))
			sub_dirs = [ os.path.join(path, x) for x in all_files 
					if os.path.isdir(os.path.join(path, x)) 
						and re_dir_pattern.search(x) ]
			subdir_candidates = [ candidate for dirs in sub_dirs 
					for candidate in \
							self._get_candidates_in_path(dirs, season_num, num_ep, option)
				]
			
			result = direct + subdir_candidates

		assert(len(result)>=0)
		return result
예제 #2
0
class FsSeriesStore(SeriesStore):
    """ Base class model for a set of Series managed by a bash store """

    config_file_season_name = ".play_conf"
    config_file_serie_name = ".play_season"
    default_config_file_abs_name = Config.config_file_abs_name

    path_to_series_var = "BASE"
    play_current_episode_var = "CUR"
    skip_time_var = "GENERICTIME"
    decay_time_var = "DECALAGESUB"
    serie_name_var = "NAME"
    fps_var = "SUBFPS"

    def __init__(self, config_file=default_config_file_abs_name):
        #pylint:disable=W0231
        self.executer = CommandExecuter()
        self.config_file_abs_name = config_file
        self.config_manager = ConfigManager(config_file)
        self.config = Config(config_file)

# paths generator

    def get_global_config_file(self):
        """ Get Path to global user config file """
        return os.path.expanduser(self.config_file_abs_name)

    def get_absolute_path(self):
        """ Get Root Path for Series storing"""
        base = self.config_manager.read_conf_var(self.get_global_config_file(), \
            self.path_to_series_var)
        base = os.path.expanduser(base)
        info("reading conf from file : {0}".format(base))
        debug("base path : {}".format(base))
        if not os.path.exists(base):
            raise FileNameError(base)
        return base

    def get_path_to_serie(self, name):
        """ Get path to serie @name
		"""
        base = self.get_absolute_path()
        return os.path.join(base, name)

    def get_path_to_current_season(self):
        """ Get path to current season of currently viewed serie
		"""
        name = self.get_current_serie_name()
        return self.get_path_to_current_season_of(name)

    def get_serie_configfile(self, name):
        """ Returns configfile for serie name @name """
        return os.path.join(self.get_path_to_serie(name),
                            self.config_file_serie_name)

    def get_season_configfile(self, name, season):
        """ returns season configfile for serie 'name' season 'season' """
        return os.path.join(self.get_path_to_season(name, season),
                            self.config_file_season_name)

    def get_path_to_current_season_of(self, name):
        """ Get path to current season of a particular serie @name
		"""
        num = self.get_stored_current_season_number(name)
        return self.get_path_to_season(name, num)

    def get_path_to_season(self, name, numseason):
        """ Get path to season @numseason of serie @name
		"""
        serie_path = self.get_path_to_serie(name)
        pattern = '[Ss]*{}'.format(numseason)

        full_pattern = os.path.join(serie_path, pattern)
        candidates = glob.glob(full_pattern)
        if len(candidates) == 0:
            return os.path.join(serie_path, "Saison {}".format(numseason))
            # raise Exception("Season {} path not found for '{}'".format(numsaison, name))

        return candidates[0]

# config management

    def read_conf_var(self, config_file_path, var_name, default=None):
        """ Gets a value in a 'key=value' file format 
		@config_file_path : the file
		@var_name : the key
		"""
        try:
            return self.config_manager.read_conf_var(config_file_path,
                                                     var_name)
        finally:
            pass
        return default

    def write_conf_var(self, config_file_path, var_name, value):
        """ Writes a value in a 'key=value' file format 
		@config_file_path : the file
		@var_name : the key
		@value : the value
		"""
        return self.config_manager.write_conf_var(config_file_path, var_name,
                                                  value)

    def read_num_conf_var(self, config_file_path, var_name, default=None):
        """ Reads a numeric value in a 'key=value' file format 
		@config_file_path : the file
		@var_name : the key
		"""
        value = default
        try:
            value = self.config_manager.read_num_conf_var(
                config_file_path, var_name)
        except Exception:
            pass
        return value

        # finally:
        #	return default

    def get_conf_variable(self, name, numseason, var_name):
        """ Gets value of a variable stored for a specified @numseason season
		of a specified serie @name. """
        return self.read_conf_var(self.get_path_to_season(name, numseason),
                                  var_name)

    def get_num_conf_variable(self, name, numseason, var_name):
        """ same as get_conf_variable for a Numeric value """
        return self.read_num_conf_var(self.get_path_to_season(name, numseason),
                                      var_name)


# useful data getters

    def get_current_serie_name(self):
        """ Returns the name of current serie """
        return self.config_manager.read_var("NAME")

    def get_stored_current_season_number(self, name):
        """ Returns season number of current serie """

        serie_conf_file = self.get_serie_configfile(name)
        num = self.read_num_conf_var(serie_conf_file, "SEASON", 1)

        return num

    def get_serie_list(self):
        """ Returns the list of series name
		on the directory """
        serie_path = self.get_absolute_path()
        dirs = [
            x for x in os.listdir(serie_path)
            if os.path.isdir(os.path.join(serie_path, x))
        ]
        return dirs

    def create_season_storage(self, serie_name, season_num):
        """ Create season directory for serie 'serie_name' season 'season_num'"""
        serie_path = self.get_path_to_serie(serie_name)
        dir_name = "Saison {}".format(season_num)

        full_season_path = os.path.join(serie_path, dir_name)
        os.mkdir(full_season_path)

        with open( self.get_season_configfile(serie_name, \
          season_num) ,'w') as fic:
            fic.write("""CUR='1'\nGENERICTIME='0'""")

    def get_current_stored_episode(self, serie_name, season_num):
        """ Returns current episode number in disk store
		"""
        ficname = ""
        season_path = None
        try:
            season_path = self.get_path_to_season(serie_name, \
             season_num)
        except Exception:
            self.create_season_storage(serie_name, season_num)
            season_path = self.get_path_to_season(serie_name, season_num)

        ficname = os.path.join( season_path, \
          self.config_file_season_name )

        if os.path.exists(ficname):
            return self.read_num_conf_var(ficname, \
              self.play_current_episode_var)
        return None
        # raise Exception("Unexisting config file {}".format(ficname))

    def get_subtitle_candidates(self, serie_name, season_num, num_ep):
        """ Returns the list of filename candidates for subtitles
		for @serie_name, for season number @season_num, episode @num_ep
		"""
        extensions = self.config.get_sub_extensions()

        result = self._get_candidates(serie_name, season_num, num_ep,
                                      extensions)
        return result

    def get_video_candidates(self, serie_name, season_num, num_ep):
        """ Returns the list of filename candidates for video
		for @serie_name, for season number @season_num, episode @num_ep
		"""
        extensions = self.config.get_video_extensions()
        result = self._get_candidates(serie_name, season_num, num_ep,
                                      extensions)

        assert (len(result) >= 0)
        return result

    def get_glob_pattern(self, season_num, num_ep, ext_list=None):
        """ Get globbing pattern
		"""
        patterns = [
            '({season:02d}|{season:d}).*{ep:02d}[^0-9]',
            '[sS]{season:02d}[^0-9]( )?[xeE]{ep:02d}[^0-9]'
        ]

        pattern = "({})".format("|".join(patterns))

        pattern = pattern.format(season = season_num, \
          ep = num_ep)

        if ext_list:
            pattern = '({}.*)\.({})'.format(pattern, "|".join(ext_list))

        return pattern

    def _get_candidates_in_path(self, path, season_num, num_ep, option):
        """ return matching filenames in path 'path' as "path/filename" list """
        result = []
        if (os.path.exists(path)):
            re_pattern = self.get_glob_pattern(season_num, num_ep, option)
            regex = re.compile(re_pattern)
            all_files = os.listdir(path)

            direct = [
                os.path.join(path, x) for x in all_files if regex.search(x)
            ]
            result = direct

        return result

    def _get_candidates(self, serie_name, season_num, num_ep, option):
        """  calls candidates finder bash script """
        path = self.get_path_to_season(serie_name, season_num)
        result = []
        if os.path.exists(path):

            all_files = os.listdir(path)

            direct = self._get_candidates_in_path(
                path, season_num, num_ep, option)  #[ x for x in all_files
            #if regex.search(x) ]

            re_dir_pattern = re.compile(
                self.get_glob_pattern(season_num, num_ep))
            sub_dirs = [
                os.path.join(path, x) for x in all_files
                if os.path.isdir(os.path.join(path, x))
                and re_dir_pattern.search(x)
            ]
            subdir_candidates = [ candidate for dirs in sub_dirs
              for candidate in \
                self._get_candidates_in_path(dirs, season_num, num_ep, option)
             ]

            result = direct + subdir_candidates

        assert (len(result) >= 0)
        return result