fromConfigParserimportSafeConfigParserimportloggingimportreclassInvalidFilter(Exception):def__init__(self,value):self.value=valuedef__str__(self):return'Invalid Filter: %s'%(self.value,)classOptionFilter:# This list also defines the order in which the filters are# processed. Should go from least specific to most specific.VALID_PARAMETERS=('fstype','uuid',)MATCH_PATTERN=re.compile(r'(\w+)\.(\S+)')def__init__(self,parameter,value,options):self.parameter=parameterself.value=valueself.options=optionsdef__str__(self):return'<OptionFilter: %s=%s, options=%s>'%(self.parameter,self.value,self.options)def__repr__(self):returnstr(self)classFilters:def__init__(self):self.option_filters=[]self.log=logging.getLogger('udiskie.match.Filters')def_parse_option_match(self,match_expression):match=OptionFilter.MATCH_PATTERN.match(match_expression)ifnotmatch:raiseInvalidFilter('format is parameter=value')parameter,value=match.groups()ifparameternotinOptionFilter.VALID_PARAMETERS:raiseInvalidFilter('parameter "%s" is not allowed'%(parameter,))returnparameter,valuedefadd_option_filter(self,match_expression,options):parameter,value=self._parse_option_match(match_expression)options=[S.strip()forSinoptions.split(',')]filt=OptionFilter(parameter,value,options)self.log.debug('loaded filter: %s'%(filt,))self.option_filters.append(filt)defget_option_filters(self,parameter):return[FforFinself.option_filtersifF.parameter==parameter]classFilterMatcher:MOUNT_OPTIONS_SECTION='mount_options'def__init__(self,config_files):self.log=logging.getLogger('udiskie.match.FilterMatcher')self.filters=self._load_filters_from_config_files(config_files)def_load_filters_from_config_files(self,config_files):filters=Filters()self.log.debug('loading filters from %s'%(config_files,))parser=SafeConfigParser()parser.read(config_files)ifparser.has_section(self.MOUNT_OPTIONS_SECTION):for(match,options)inparser.items(self.MOUNT_OPTIONS_SECTION):filters.add_option_filter(match,options)returnfiltersdefget_mount_options(self,device):device_info={'fstype':device.id_type(),'uuid':device.id_uuid().lower()}mount_options=set()formatch_typeinOptionFilter.VALID_PARAMETERS:device_value=device_info.get(match_type)forfiltinself.filters.get_option_filters(match_type):ifdevice_value==filt.value:self.log.info('filter matched: %s'%(filt,))foroptioninfilt.options:mount_options.add(option)returnlist(mount_options)