mirror of https://github.com/dnomd343/ProxyC
				
				
			
				 3 changed files with 87 additions and 41 deletions
			
			
		@ -1,85 +1,120 @@ | 
				
			|||||
#!/usr/bin/env python3 | 
					#!/usr/bin/env python3 | 
				
			||||
# -*- coding: utf-8 -*- | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import copy | 
				
			||||
 | 
					
 | 
				
			||||
filterObject = { | 
					filterObject = { | 
				
			||||
    'optional': { | 
					    'optional': { | 
				
			||||
 | 
					        'type': bool, | 
				
			||||
        'optional': True,  # `optional` is not force require | 
					        'optional': True,  # `optional` is not force require | 
				
			||||
        'default': False,  # disable `optional` option in default | 
					        'default': False,  # disable `optional` option in default | 
				
			||||
        'allowNone': False,  # `optional` couldn't be None | 
					        'allowNone': False,  # `optional` couldn't be None | 
				
			||||
        'type': bool, | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `optional` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'default': { | 
					    'default': { | 
				
			||||
 | 
					        'type': any,  # skip type check | 
				
			||||
        'optional': True,  # `default` is not force require | 
					        'optional': True,  # `default` is not force require | 
				
			||||
        'default': None, | 
					        'default': None, | 
				
			||||
        'allowNone': True,  # `default` can be None | 
					        'allowNone': True,  # `default` can be None | 
				
			||||
        'type': any,  # skip type check | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `default` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'allowNone': { | 
					    'allowNone': { | 
				
			||||
 | 
					        'type': bool, | 
				
			||||
        'optional': True,  # `allowNone` is not force require | 
					        'optional': True,  # `allowNone` is not force require | 
				
			||||
        'default': False,  # disable `allowNone` option in default | 
					        'default': False,  # disable `allowNone` option in default | 
				
			||||
        'allowNone': False,  # `allowNone` couldn't be None | 
					        'allowNone': False,  # `allowNone` couldn't be None | 
				
			||||
        'type': bool, | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `allowNone` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'type': { | 
					    'type': { | 
				
			||||
 | 
					        'type': [any, type, list, dict], | 
				
			||||
        'optional': False,  # `type` is force require | 
					        'optional': False,  # `type` is force require | 
				
			||||
        'allowNone': False,  # `type` couldn't be None | 
					        'allowNone': False,  # `type` couldn't be None | 
				
			||||
        'type': [any, type, list, dict], | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `type` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'multiSub': { | 
					    'multiSub': { | 
				
			||||
 | 
					        'type': bool, | 
				
			||||
        'optional': True,  # `multiSub` is not force require | 
					        'optional': True,  # `multiSub` is not force require | 
				
			||||
        'default': False,  # disable `multiSub` option in default | 
					        'default': False,  # disable `multiSub` option in default | 
				
			||||
        'allowNone': False,  # `multiSub` couldn't be None | 
					        'allowNone': False,  # `multiSub` couldn't be None | 
				
			||||
        'type': bool, | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `multiSub` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'indexKey': { | 
					    'indexKey': { | 
				
			||||
 | 
					        'type': str, | 
				
			||||
        'optional': True,  # `indexKey` is not force require | 
					        'optional': True,  # `indexKey` is not force require | 
				
			||||
        'default': 'type', | 
					        'default': 'type', | 
				
			||||
        'allowNone': False,  # `indexKey` couldn't be None | 
					        'allowNone': False,  # `indexKey` couldn't be None | 
				
			||||
        'type': str, | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `indexKey` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'format': { | 
					    'format': { | 
				
			||||
 | 
					        'type': any, | 
				
			||||
        'optional': True,  # `format` is not force require | 
					        'optional': True,  # `format` is not force require | 
				
			||||
        'default': lambda x: x,  # don't change anything | 
					        'default': lambda x: x,  # don't change anything | 
				
			||||
        'allowNone': False,  # `format` couldn't be None | 
					        'allowNone': False,  # `format` couldn't be None | 
				
			||||
        'type': any, | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `format` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'filter': { | 
					    'filter': { | 
				
			||||
 | 
					        'type': any, | 
				
			||||
        'optional': True,  # `filter` is not force require | 
					        'optional': True,  # `filter` is not force require | 
				
			||||
        'default': lambda x: True,  # always pass filter | 
					        'default': lambda x: True,  # always pass filter | 
				
			||||
        'allowNone': False,  # `filter` couldn't be None | 
					        'allowNone': False,  # `filter` couldn't be None | 
				
			||||
        'type': any, | 
					 | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `filter` key' | 
					 | 
				
			||||
    }, | 
					    }, | 
				
			||||
    'errMsg': { | 
					    'errMsg': { | 
				
			||||
 | 
					        'type': str, | 
				
			||||
        'optional': True,  # `errMsg` is not force require | 
					        'optional': True,  # `errMsg` is not force require | 
				
			||||
        'default': 'filter error', | 
					        'default': 'filter error', | 
				
			||||
        'allowNone': False,  # `errMsg` couldn't be None | 
					        'allowNone': False,  # `errMsg` couldn't be None | 
				
			||||
        'type': str, | 
					    } | 
				
			||||
        'format': lambda x: x,  # return same value | 
					 | 
				
			||||
        'filter': lambda b: True,  # always return True | 
					 | 
				
			||||
        'errMsg': 'Invalid `errMsg` key' | 
					 | 
				
			||||
    }, | 
					 | 
				
			||||
} | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					for field in filterObject: | 
				
			||||
 | 
					    filterObject[field]['errMsg'] = 'Invalid `%s` key' % field | 
				
			||||
 | 
					    filterObject[field]['format'] = filterObject['format']['default']  # return same value | 
				
			||||
 | 
					    filterObject[field]['filter'] = filterObject['filter']['default']  # always return True | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					def Filter(raw: dict, rules: dict) -> dict: | 
				
			||||
 | 
					    if type(raw) != dict: | 
				
			||||
 | 
					        raise RuntimeError('Invalid input for filter') | 
				
			||||
 | 
					    data = {} | 
				
			||||
 | 
					    raw = copy.deepcopy(raw) | 
				
			||||
 | 
					    rules = copy.deepcopy(rules) | 
				
			||||
 | 
					    for key, rule in rules.items(): | 
				
			||||
 | 
					        # pretreatment process (raw --[copy / default value]--> data) | 
				
			||||
 | 
					        if key not in raw:  # key not exist | 
				
			||||
 | 
					            if not rule['optional']:  # force require key not exist | 
				
			||||
 | 
					                raise RuntimeError('Miss `%s` field' % key) | 
				
			||||
 | 
					            data[key] = rule['default']  # set default value | 
				
			||||
 | 
					        else:  # key exist | 
				
			||||
 | 
					            data[key] = raw[key] | 
				
			||||
 | 
					        # format process (data --[format]--> data) | 
				
			||||
 | 
					        try: | 
				
			||||
 | 
					            data[key] = rule['format'](data[key])  # run format | 
				
			||||
 | 
					        except: | 
				
			||||
 | 
					            raise RuntimeError(rule['errMsg'])  # format error | 
				
			||||
 | 
					        if data[key] is None:  # key content is None | 
				
			||||
 | 
					            if not rule['allowNone']:  # key is not allow None | 
				
			||||
 | 
					                raise RuntimeError('Field `%s` shouldn\'t be None' % key) | 
				
			||||
 | 
					            continue  # skip following process | 
				
			||||
 | 
					        # filter process (data --[type check (& filter check)]--> pass / non-pass) | 
				
			||||
 | 
					        if type(rule['type']) == type:  # str / int / bool / ... | 
				
			||||
 | 
					            rule['type'] = [rule['type']]  # str -> [str] / int -> [int] / ... | 
				
			||||
 | 
					        if type(rule['type']) == list:  # [str, int, bool, ...] | 
				
			||||
 | 
					            if data[key] == any and any in rule['type']:  # special case -> skip type filter | 
				
			||||
 | 
					                pass | 
				
			||||
 | 
					            elif type(data[key]) not in rule['type']:  # type not in allow list | 
				
			||||
 | 
					                raise RuntimeError('Invalid `%s` field' % key) | 
				
			||||
 | 
					        elif type(rule['type']) == dict:  # check subObject | 
				
			||||
 | 
					            if not rule['multiSub']:  # single subObject | 
				
			||||
 | 
					                data[key] = Filter(data[key], rule['type']) | 
				
			||||
 | 
					            else:  # multi subObject | 
				
			||||
 | 
					                # TODO: multi sub filter | 
				
			||||
 | 
					                pass | 
				
			||||
 | 
					            continue | 
				
			||||
 | 
					        elif rule['type'] != any:  # type == any -> skip type filter | 
				
			||||
 | 
					            raise RuntimeError('Unknown `type` in rules') | 
				
			||||
 | 
					        if not rule['filter'](data[key]):  # run filter | 
				
			||||
 | 
					            raise RuntimeError(rule['errMsg']) | 
				
			||||
 | 
					    return data | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					def rulesFilter(rules: dict) -> dict: | 
				
			||||
 | 
					    result = {} | 
				
			||||
 | 
					    for key, rule in rules.items():  # filter by basic rules | 
				
			||||
 | 
					        result[key] = Filter(rule, filterObject) | 
				
			||||
 | 
					    return result | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					filterObject = rulesFilter(filterObject)  # format itself | 
				
			||||
 | 
				
			|||||
@ -0,0 +1,7 @@ | 
				
			|||||
 | 
					#!/usr/bin/env python | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import Filter.Shadowsocks | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					# from pprint import pprint | 
				
			||||
 | 
					# from Basis.Filter import filterObject | 
				
			||||
 | 
					# pprint(filterObject, sort_dicts = False) | 
				
			||||
					Loading…
					
					
				
		Reference in new issue