def __init__(self, name, expires: Optional[int] = 600, locked_by=None, lock_process=None, wait: int = None): """ Create an instance of :class:`.LockMgr`. This class is primarily intended to be used as a context manager (i.e. ``with LockMgr('mylock') as l:``), see the main PyDoc block for :class:`.LockMgr` for more info. :param str name: The lock name to create (when using as a context manager) :param int expires: How many seconds before this lock is considered stale and forcefully released? :param str locked_by: (Optional) Who/what is using this lock. Defaults to system hostname. :param int lock_process: (Optional) The process ID of the app using this lock :param int wait: (Optional) Wait this many seconds for a lock to be released before giving up. If this is ``None`` then waiting will be disabled """ self.expires = int(expires) if expires not in [None, False] else 0 self.wait = None if empty(wait) else int(wait) self.locked_by = socket.gethostname() if empty( locked_by) else locked_by self.name, self.lock_process = name, lock_process self._locks = [] # type: List[Lock] self.main_lock = None
def scan_ip(self, ip: str) -> DictObject: dt = DictObject(country="unknown", city="unknown", asn="unknown", rdns='N/A') dt.rdns = self.get_rdns(ip) if not settings.USE_GEOIP: dt.asn = dt.country = dt.city = 'NO_GEOIP_DB', 'NO_GEOIP_DB', 'NO_GEOIP_DB' return dt dt.asn = self.get_asn(ip) if not empty(dt.asn): self._bump_asn(dt.asn) else: dt.asn = "unknown" dt.country, dt.city = self.get_location(ip) if not empty(dt.country): self._bump_country(dt.country) else: dt.country = "unknown" if not empty(dt.city): self._bump_city(dt.city) else: dt.city = "unknown" return dt
def __post_init__(self): conv_bool_keys = [ 'non_real_time', 'is_api_registerable', 'is_api_renewable', 'is_api_transferable', 'is_epp_required', 'is_disable_mod_contact', 'is_disable_wg_allot', 'is_include_in_extended_search_only', 'is_supports_idn', 'supports_registrar_lock', 'whois_verification', 'provider_api_delete' ] conv_int_keys = [ 'min_register_years', 'max_register_years' 'min_renew_years', 'max_renew_years', 'min_transfer_years', 'max_transfer_years', 'reactivate_max_days', 'add_grace_period_days', 'renewal_min_days', 'renewal_max_days', 'sequence_number', ] for k in conv_bool_keys: v = getattr(self, k, None) if not empty(v): setattr(self, k, is_true(v)) for k in conv_int_keys: v = getattr(self, k, None) if not empty(v) and not isinstance(v, int): setattr(self, k, int(v))
def __post_init__(self): if not empty(self.id, zero=True): self.id = int(self.id) if not empty(self.is_owner, zero=True): self.is_owner = is_true(self.is_owner) if not empty(self.is_premium, zero=True): self.is_premium = is_true(self.is_premium)
def detect_name(obj: Union[callable, View, object, type]) -> Optional[str]: """ Extract a snake-case name from a given object (class, instance, function or other type):: >>> class ExampleView: pass >>> CustomAdmin.detect_name(ExampleView) 'example_view' >>> CustomAdmin.detect_name(ExampleView()) 'example_view' >>> def anotherExample(): pass >>> CustomAdmin.detect_name(anotherExample) 'another_example' >>> class HasAName: ... pvx_name = 'hello_world' >>> CustomAdmin.detect_name(HasAName) 'hello_world' :param obj: The object to extract the snake-case name from :return str|None name: The snake-case name of the object, or ``None`` if failed to detect it. """ if hasattr(obj, 'pvx_name') and not empty(obj.pvx_name): return obj.pvx_name elif hasattr(obj, '__name__'): return camel_to_snake(obj.__name__) elif hasattr(obj, '__class__') and hasattr(obj.__class__, '__name__'): return camel_to_snake(obj.__class__.__name__) elif hasattr(obj, 'name') and not empty(obj.name): return obj.name log.warning( "No name specified by user for view, and cannot infer from view_obj.__name__ or other attributes... obj: %s", obj) return None
async def test_eos_getattribute(eos_api: Api): acc = await eos_api.__getattribute__('get_account')( account_name='someguy12333') assert acc.account_name == 'someguy12333' assert not empty(acc.created) assert not empty(acc.last_code_update) assert 'EOS' in acc.core_liquid_balance
def get_builder(name: str = None, file_handle=None, contents: Union[str, list, tuple] = None, **kwargs) -> CSPBuilder: if empty(name) and file_handle is None and empty(contents, itr=True): name = argv[1] return CSPBuilder(name, file_handle, contents, **kwargs)
def _tpl_add_hosts(host: str = None, v4_host: str = None, v6_host: str = None, **kwargs) -> dict: filter_hosts = kwargs.pop('filter_hosts', settings.FILTER_HOSTS) set_trusted_hosts = kwargs.pop('set_trusted_hosts', True) v4_sub = kwargs.pop('v4_subdomain', settings.V4_SUBDOMAIN) v6_sub = kwargs.pop('v6_subdomain', settings.V6_SUBDOMAIN) main_host = kwargs.pop('main_host', settings.MAIN_HOST) force_main_host = kwargs.pop('force_main_host', settings.FORCE_MAIN_HOST) if set_trusted_hosts: request.trusted_hosts = settings.ALLOWED_HOSTS if filter_hosts else None hst = request.host if empty(host) else host if not any([empty(v4_host), empty(v6_host)]): pass # both v4 and v6_host are set, so we don't want to override them. elif force_main_host: # If force_main_host is true, then we shouldn't use the current requested host from ``hst``, # instead we use the pre-set V4_HOST and V6_HOST from settings (unless v4/v6_host are overridden) v4_host = empty_if(v4_host, settings.V4_HOST) v6_host = empty_if(v6_host, settings.V6_HOST) else: # If the current host is on the v4/v6 subdomain, then we need to trim the subdomain to avoid prepending a second subdomain if hst.startswith(f'{v4_sub}.'): hst = hst.replace(f'{v4_sub}.', '', 1) if hst.startswith(f'{v6_sub}.'): hst = hst.replace(f'{v6_sub}.', '', 1) v4_host, v6_host = empty_if(v4_host, f"{v4_sub}.{hst}"), empty_if(v6_host, f"{v6_sub}.{hst}") return dict(v4_host=v4_host, v6_host=v6_host, host=hst, main_host=main_host)
async def _try_unknown_method(node: str, method: str, params: Union[list, dict] = None, auto_exit=True): params = empty_if(params, []) try: # loop = asyncio.get_event_loop() data = await rpc(host=node, method=method, params=params) if empty(data[0]): log.warning( "Response for method '%s' from '%s' was empty. Marking as broken!", method, node) return sys.exit(settings.BAD_RETURN_CODE) if auto_exit else False return data except RPCError as e: log.error( "Got RPC error in _try_unknown_method() while testing method %s against %s - Ex: %s %s", method, node, type(e), str(e)) return sys.exit(settings.BAD_RETURN_CODE) if auto_exit else False except ServerDead as e: log.error( "Got ServerDead error in _try_unknown_method() while testing method %s against %s - Ex: %s %s", method, node, type(e), str(e)) oe = e.orig_ex if not empty(oe): if isinstance(oe, RPCError): log.error( "ServerDead contained RPCError while testing method %s against %s - Ex: %s %s", method, node, type(oe), str(oe)) return sys.exit(settings.BAD_RETURN_CODE) if auto_exit else False except Exception as e: log.error( "Fatal exception in _try_unknown_method() while testing method %s against %s - Ex: %s %s", method, node, type(e), str(e)) return sys.exit(1) if auto_exit else False
def account_id(self, symbol: str = 'XMR') -> int: """Get the default account ID/index for a given coin symbol""" # First check if we've cached the account ID for this symbol if symbol in self._account_ids: return self._account_ids[symbol] # Next in priority is the `account_id` setting s = self.settings[symbol] if not empty(s.get('account_id')): a_id = self._account_ids[symbol] = int(s.get('account_id')) log.debug("Using setting 'account_id' = '%s' for the monero account ID", a_id) return a_id # If `account` is set, then we search for an account with the label or tag matching `account` aname = s.get('account') if not empty(aname): log.debug("Looking up account label/tag '%s' to find account ID", aname) acc = self.find_account_label(label=aname, symbol=symbol) self._account_ids[symbol] = int(acc['account_index']) log.debug("Account ID for '%s' was: %s", aname, self._account_ids[symbol]) return self._account_ids[symbol] log.warning("WARNING: Both settings 'account' and 'account_id' are empty. Falling back to account ID 0...") self._account_ids[symbol] = 0 return self._account_ids[symbol]
def get_columns(database=None, table=None): """ SELECT COL.TABLE_SCHEMA, COL.TABLE_NAME, COL.COLUMN_NAME, COL.COLLATION_NAME, CCSA.CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLUMNS COL, INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY CCSA WHERE CCSA.collation_name = COL.COLLATION_NAME TABLE_NAME = 't_name'; :return: """ cols = [ 'TABLE_SCHEMA', 'TABLE_NAME', 'COLUMN_NAME', 'COLUMN_DEFAULT', 'IS_NULLABLE', 'DATA_TYPE', 'CHARACTER_MAXIMUM_LENGTH', 'COLUMN_TYPE', 'COLUMN_KEY', 'EXTRA', 'COLLATION_NAME', 'CHARACTER_SET_NAME' ] stmt = f"SELECT {', '.join(cols)} FROM INFORMATION_SCHEMA.COLUMNS" params = [] if any([not empty(database), not empty(table)]): stmt += " WHERE" if not empty(database): stmt += " TABLE_SCHEMA = %s" params += [database] if not empty(table): stmt += ' AND' if not empty(table): stmt += " TABLE_NAME = %s" params += [table] stmt += ';' return [TableColumnResult(*r) for r in query(stmt, *params)]
def do_output(self, out_format=None, out_file=None, *args): if empty(out_format) or empty(out_file): msg('yellow', 'Invalid command usage for \\output.') return self._help_output() fmt_pyre = ['pyre', '.pyre', 'pyrewall'] if out_format in fmt_v4: msg( 'green', f"Outputting session as IPv4 IPTables format to file {out_file}" ) count = self._output_lines(out_file=out_file, lines=self.rendered_rules.v4) elif out_format in fmt_v6: msg( 'green', f"Outputting session as IPv6 IPTables format to file {out_file}" ) count = self._output_lines(out_file=out_file, lines=self.rendered_rules.v6) elif out_format in fmt_pyre: msg( 'green', f"Outputting session as native Pyrewall 'pyre' format to file {out_file}" ) count = self._output_lines(out_file=out_file, lines=self.rendered_rules.pyre) else: msg('yellow', f"Invalid output format '{out_format}' for \\output.") return self._help_output() msg('green', f"Sucessfully wrote {count} lines to file {out_file}")
def __init__(self, filename: str = None, file_handle=None, contents: Union[str, list, tuple] = None, **kwargs): self.config = configparser.ConfigParser() self.conf_file = None if not empty(filename): self.conf_file = Path(filename).resolve() self.config.read(self.conf_file) elif file_handle is not None: self.config.read_file(file_handle) elif not empty(contents, itr=True): if isinstance(contents, (tuple, list)): contents = "\n".join(contents) self.config.read_string(contents) else: raise ValueError( "CSPBuilder expects either a filename, file handle (open()), or config string " "contents to be passed. All 3 are None / empty. Nothing to parse." ) self.groups = {} self.config_dict = {} self.flags = '' self.excluded = kwargs.get('excluded', ['flags', 'groups', 'DEFAULT']) self.cleaned = False # self.section_split = kwargs.get('section_split', ': ') self.section_split = kwargs.get('section_split', ' ')
async def base_get_blocks(steem: SteemAsync, network: str = None): blocks = await steem.get_blocks(START_BLOCK, END_BLOCK) assert isinstance(blocks, list) assert len(blocks) >= TOTAL_BLOCKS assert len(blocks) < TOTAL_BLOCKS + 5 assert not empty(blocks[50].block_id) assert not empty(blocks[60].witness)
async def test_eos_get_account(eos_api: Api): acc = await eos_api.get_account('someguy12333') assert isinstance(acc, EOSAccount) assert acc.account_name == 'someguy12333' assert not acc.privileged assert not empty(acc.created) assert not empty(acc.last_code_update) assert 'EOS' in acc.core_liquid_balance
def __str__(self): f = f"{self.message}" if not empty(self.host): f += f" (host: {self.host})" if not empty(self.error_code, True): f += f" Server error code: {self.error_code}" if not empty(self.error_msg): f += f" Server error message: {self.error_msg}" return f
def avg(*vals: NumberStr, dp: OptNumStr = '8', rounding: str = None) -> Decimal: vals = [conv_dec(v) for v in list(vals) if not empty(v)] if len(vals) == 1: return vals[0] if empty(dp) else dec_round(vals[0], dp, rounding) _avg = conv_dec(sum(vals)) / Decimal(len(vals)) return _avg if empty(dp) else dec_round(_avg, dp, rounding)
def send(self, amount: Decimal, address: str, from_address: str = None, memo: str = None, trigger_data: Union[dict, list] = None) -> dict: # Try from_address first. If that's empty, try using self.coin.our_account. If both are empty, abort. if empty(from_address): if empty(self.coin.our_account): raise AttributeError( "Both 'from_address' and 'coin.our_account' are empty. Cannot send." ) from_address = self.coin.our_account if not self.address_valid(address): raise exceptions.AccountNotFound( f'Account "{address}" does not exist.') if not self.address_valid(from_address): raise exceptions.AccountNotFound( f'Account "{address}" does not exist.') memo = "" if empty(memo) else memo prec = self.precision sym = self.symbol.upper() amount = dec_round(Decimal(amount), dp=prec, rounding=ROUND_DOWN) if amount < Decimal(pow(10, -prec)): log.warning( 'Amount %s was passed, but is lower than precision for %s', amount, sym) raise ArithmeticError( 'Amount {} is lower than token {}s precision of {} DP'.format( amount, sym, prec)) bal = self.balance(from_address) if bal < amount: raise exceptions.NotEnoughBalance( 'Account {} has balance {} but needs {} to send this tx'. format(from_address, bal, amount)) ### # Broadcast the transfer transaction on the network, and return the necessary data ### log.info('Sending %f %s to @%s', amount, sym, address) _, wif = self.get_priv(from_address) t = self.rpc.transfer(to=address, amount=amount, from_account=from_address, memo=memo, asset=sym, wif=wif) return { 'txid': t['id'], 'coin': self.symbol, 'amount': amount, 'fee': Decimal(0), 'from': from_address, 'send_type': 'send' }
def test_notempty(self): # Basic string test self.assertFalse(helpers.empty('hello')) # Integer test self.assertFalse(helpers.empty(1, zero=True)) # Iterable tests self.assertFalse(helpers.empty(['world'], itr=True)) self.assertFalse(helpers.empty(('world', ), itr=True)) self.assertFalse(helpers.empty({'hello': 'world'}, itr=True))
def test_notempty(self): """Test :py:func:`.empty` with non-empty values""" # Basic string test self.assertFalse(helpers.empty('hello')) # Integer test self.assertFalse(helpers.empty(1, zero=True)) # Iterable tests self.assertFalse(helpers.empty(['world'], itr=True)) self.assertFalse(helpers.empty(('world', ), itr=True)) self.assertFalse(helpers.empty({'hello': 'world'}, itr=True))
def lock(self, name, expires: int = None, ret: bool = False, wait: int = None): """ Obtains a lock using :py:func:`.get_lock` and appends it to :py:attr:`._locks` if successful. If the argument ``ret`` is ``False`` (default), it will raise :class:`.Locked` if the lock couldn't be obtained. Otherwise, if ``ret`` is ``True``, it will simply return ``False`` if the requested lock name is already locked. :param str name: A unique name to identify your lock :param int expires: (Default: 600 sec) How long before this lock is considered stale and forcefully released? :param bool ret: (Default: False) Return ``False`` if locked, instead of raising ``Locked``. :param int wait: (Optional) Retry obtaining the lock for this many seconds. MUST be divisible by 5. If not empty, will retry obtaining the lock every 5 seconds until ``wait`` seconds :raises Locked: If the requested lock ``name`` is already locked elsewhere, :class:`.Locked` will be raised :return bool success: ``True`` if successful. If ``ret`` is true then will also return False on failure. """ expires = self.expires if empty(expires) else int(expires) wait = self.wait if empty(wait) else int(wait) log.debug('Attempting to get lock %s with expiry of %s', name, expires) try: lck = get_lock(name=name, locked_by=self.locked_by, lock_process=self.lock_process, expires=expires) if len(self._locks) == 0 or self.main_lock is None: self.main_lock = lck self._locks.append(lck) log.debug('Lock obtained for %s', name) return True except Locked as e: if empty(wait, zero=True): log.info('A lock already exists on %s...', name) if ret: return False raise e wait = int(wait) if wait % 5 != 0: raise ArithmeticError( 'The argument "wait" must be divisible by 5 seconds.') log.info( 'Lock "%s" was locked - waiting up to %s seconds for lock to be released.', name, wait) log.info('Retrying lock in 5 seconds...') sleep(5) return self.lock(name=name, expires=expires, ret=ret, wait=wait - 5)
def to_json_dict(self) -> dict: d = dict(self) if not d['error']: if 'error_code' in d and empty(d['error_code'], True, True): del d['error_code'] if 'messages' in d and empty(d['messages'], True, True): del d['messages'] if 'message' in d and empty(d['message'], True, True): del d['message'] return d
def __post_init__(self): # Namecheap returns dates in US format - MM/DD/YYYY - so we carefully convert them using that format. if not empty(self.created) and isinstance(self.created, str): self.created = datetime.strptime(self.created, "%m/%d/%Y") if not empty(self.expires) and isinstance(self.expires, str): self.expires = datetime.strptime(self.expires, "%m/%d/%Y") self.is_expired = is_true(self.is_expired) self.is_locked = is_true(self.is_locked) self.auto_renew = is_true(self.auto_renew) self.is_premium = is_true(self.is_premium) self.is_our_dns = is_true(self.is_our_dns)
async def provides(self) -> Set[Tuple[str, str]]: """ We cache the provides Set both class-locally in :attr:`._provides`, as well as via the Privex Helpers Cache system - :mod:`privex.helpers.cache` """ if empty(self._provides, itr=True): _prov = await cached.get(f"pvxex:{self.code}:provides") if not empty(_prov): self._provides = _prov else: self._provides = await self._gen_provides() await cached.set(f"pvxex:{self.code}:provides", self._provides) return self._provides
def json_frm(force=True, silent=True, cache=True, fallback: K = dict, req: Request = None, call_fb=True) -> Union[dict, list, K]: """Wrapper around :meth:`.Request.get_json` to allow fallback to ``{}`` or ``[]`` instead of ``None``""" req = request if empty(req) else req j = req.get_json(force=force, silent=silent, cache=cache) if empty(j, itr=True, zero=True): if fallback == dict: return {} if fallback == list: return [] if fallback == tuple: return () return fallback() if call_fb and callable(fallback) else fallback return j
async def test_eos_getblock_range(eos_api: Api): blocks = await eos_api.get_block_range(start=RANGE_START, end=RANGE_END) assert isinstance(blocks, dict) assert isinstance(blocks, OrderedDict) assert len(blocks.keys()) == ((RANGE_END - RANGE_START) + 1) assert RANGE_START in blocks assert RANGE_END in blocks i = RANGE_START for block_num, block in blocks.items(): assert block_num == i assert block.block_num == block_num assert not empty(block.id) assert not empty(block.producer) assert not empty(block.timestamp) i += 1
def detect_human( obj: Union[callable, View, object, type]) -> Optional[str]: """ Extract a humanised name from an object:: >>> class ExampleView: ... pass >>> CustomAdmin.detect_human(ExampleView) 'Example View' >>> CustomAdmin.detect_human(ExampleView()) 'Example View' >>> def another_example(): ... pass >>> CustomAdmin.detect_human(another_example) 'Another Example' >>> class HasAName: ... pvx_human_name = 'This class has a name' >>> CustomAdmin.detect_human(HasAName) 'This class has a name' :param obj: The object to extract the human name from :return str|None name: The human name of the object, or ``None`` if failed to detect it. """ if hasattr(obj, 'pvx_human_name') and not empty(obj.pvx_human_name): return obj.pvx_human_name return human_name(obj)
def load_rules(rules: Union[str, list], ipver='v4'): cmd = [] if is_root() else ['sudo', '-n'] cmd += ['iptables-restore'] if ipver in ['v4', '4', 'ipv4', 4 ] else ['ip6tables-restore'] if isinstance(rules, str): cmd += [rules] log.info("Restoring IPTables file %s using command %s", rules, cmd) res = run_prog(*cmd) # print(f"Rules file {rules} appeared to restore successfully :)\n", file=sys.stderr) else: rule_list = list(rules) rule_list = [ r.strip("\n").strip() for r in rule_list if not empty(r.strip("\n").strip()) ] l_rules = "\n".join(rule_list) res = run_prog(*cmd, write=l_rules) if res.code != 0: log.error( f"ERROR! Non-zero return code ({res.code}) from command: {cmd}") log.error("Command stdout: %s", res.stdout) log.error("Command stderr: %s", res.stderr) raise IPTablesError( f"Non-zero return code ({res.code}) from command: {cmd}") log.debug(f"Got successful (zero) exit code from command: {cmd}") log.debug("Command stdout: %s", res.stdout) log.debug("Command stderr: %s", res.stderr) return res
def __init__(self, symbol, name="", issuer="", metadata: Union[str, dict] = None, **kwargs): self.raw_data = { **kwargs, **dict(symbol=symbol, issuer=issuer, name=name, metadata=metadata) } self.issuer, self.name, self.symbol = issuer, name, symbol # type: str meta = metadata meta = {} if empty(meta, itr=True) else ( json.loads(meta) if type(meta) is str else meta) self.metadata = TokenMetadata(**meta) # type: TokenMetadata self.precision = int(kwargs.get('precision', 0)) # type: int _circ = _maxs = Decimal(0) if 'maxSupply' in kwargs: _maxs = Decimal(kwargs['maxSupply']) if 'max_supply' in kwargs: _maxs = Decimal(kwargs['max_supply']) self.max_supply = self.maxSupply = _maxs # type: Decimal if 'circulatingSupply' in kwargs: _circ = Decimal(kwargs['circulatingSupply']) if 'circulating_supply' in kwargs: _circ = Decimal(kwargs['circulating_supply']) self.circulating_supply = self.circulatingSupply = _circ # type: Decimal self.supply = Decimal(kwargs.get('supply', '0')) # type: Decimal
def handle(self, *args, **options): print() print("==========================================================#\n" "# #\n" "# EOS Block History Scanner #\n" "# (C) 2019 Privex Inc. Released under GNU AGPLv3 #\n" "# #\n" "# github.com/Privex/EOSHistory #\n" "# #\n" "#=========================================================#\n") print() # last_block, start_type = options['start_block'], options['start_type'] # if options['start_block'] is None: # Command.queue = options.pop('queue', settings.DEFAULT_CELERY_QUEUE) Command.queue = settings.DEFAULT_CELERY_QUEUE if empty( Command.queue) else Command.queue Command.lock_sync_blocks = f'eoshist_sync:{Command.queue}:{getpass.getuser()}' Command.lock_fill_gaps = f'eoshist_gaps:{Command.queue}:{getpass.getuser()}' log.info(' >>> Using Celery queue "%s"', Command.queue) log.info( ' >>> Started SYNC_BLOCKS Django command. Booting up AsyncIO event loop. ' ) asyncio.run(self.sync_blocks(**options))