コード例 #1
0
def add_defaults(parser: ArgumentParser, remove_defaults: Union[List[str], Set[str], tuple] = None, **overrides):
    """
    Add the defaults from :func:`.get_arg_defaults` to the argument parser ``parser``.
    
    New defaults can be added, and existing defaults from :func:`.get_arg_defaults` can be overrided by specifying
    new/override defaults as kwargs.
    
    If you need to prevent certain defaults from :func:`.get_arg_defaults` or the passed ``overrides` kwargs from
    being set on ``parser``,  pass their keys as a :class:`list` / :class:`set` / :class:`tuple` via the
    ``remove_defaults`` argument.
    
    Below is an example - create an arg parser, add ``--plugins`` to ``parser``, then add the common defaults to it. Remove the
    default for ``nodefile``, and override the default ``skip_apis`` to contain ``'bridge.get_trending_topics'``.
    
    Example::
    
        >>> parser = ArgumentParser(description="my arg parser")
        >>> add_plugins(parser)
        >>> add_defaults(parser, remove_defaults=['nodefile'], skip_apis='bridge.get_trending_topics')
    
    :param ArgumentParser parser: A :class:`.ArgumentParser` instance
    :param List[str]|Set[str]|tuple remove_defaults: An optional list, set or tuple containing keys to remove from the defaults
                                                     before adding them to ``parser``
    :param overrides: Keyword arguments containing any additional defaults to add, or pre-existing defaults from :func:`.get_arg_default`
                      to override (replace).
    :return DictObject defs: A :class:`.DictObject` containing the defaults which were set on ``parser``
    """
    defs = DictObject({**get_arg_defaults(), **overrides})
    if not empty(remove_defaults, itr=True):
        for k in defs.keys():
            if k not in remove_defaults:
                continue
            del defs[k]
    parser.set_defaults(**defs)
    return defs
コード例 #2
0
 def test_set_attr(self):
     """Test setting a dictionary key via an attribute ``x.y = 123``"""
     x = DictObject()
     x.testing = 'testattr'
     x.other_test = 'example'
     self.assertEqual(x['testing'], 'testattr')
     self.assertEqual(x['other_test'], 'example')
     self.assertEqual(x.testing, 'testattr')
     self.assertEqual(x.other_test, 'example')
コード例 #3
0
 def test_json_dumps_nested(self):
     """Test serializing a :class:`.DictObject` with a nested :class:`.DictObject` into JSON"""
     x = DictObject(hello='world', example='testing')
     x.layer = DictObject(test=True)
     j = json.dumps(x)
     self.assertEqual(
         j,
         '{"hello": "world", "example": "testing", "layer": {"test": true}}'
     )
コード例 #4
0
    async def test_all(
            self,
            whitelist: List[str] = None,
            blacklist: List[str] = None) -> Union[DictObject, Dict[str, dict]]:
        """
        Tests all supported RPC methods by :class:`.MethodTests` against :attr:`.host`, optionally specifying either a
        ``whitelist`` or ``blacklist``
        
        This method returns a :class:`.DictObject` containing three keys::
        
         - ``methods`` - A :class:`.dict` of JSONRPC string methods mapped to booleans, with ``True`` meaning the
            method was tested without any problems, while ``False`` means that an error occurred while testing this method.
        
         - ``errors`` - A :class:`.dict` which contains JSONRPC string methods mapped to the :class:`.Exception` which they raised.
                        Only methods which raised an exception (i.e. those marked ``False`` in the ``methods`` dict) will be present here.
        
         - ``results`` - A :class:`.dict` which contains JSONRPC string methods mapped to the result their class testing method returned.
                        This is usually a ``Tuple[Union[list,dict], float, int]``, which contains ``(response, time_taken_sec, tries)``
        
        :param List[str] whitelist: A list of JSONRPC methods to exclusively test, e.g.
                                    ``['account_history_api.get_account_history', 'condenser_api.get_accounts']``
        :param List[str] blacklist: A list of JSONRPC methods to skip testing, e.g.  ``['bridge.get_trending_topics']``
        :return Union[DictObject,Dict[str, dict]] res: A :class:`.DictObject` containing three :class:`.dict`'s: ``methods``, ``errors``,
                                                        and ``results``. Full explanation of returned object in main pydoc body for this
                                                        method :meth:`.test_all`
        """
        res = DictObject(methods={}, errors={}, results={})
        tasks = []
        for meth, func in METHOD_MAP.items():
            if whitelist is not None and meth not in whitelist:
                log.debug(
                    "Skipping RPC method %s against host %s as method is not present in whitelist.",
                    meth, self.host)
                continue
            # Skip APIs listed in SKIP_API_LIST only if we're not using a whitelist. If a whitelist was passed, then we should follow
            # the whitelist, and ignore the SKIP_API_list.
            if empty(whitelist) and meth in settings.SKIP_API_LIST:
                log.debug(
                    "Skipping RPC method %s against host %s as method is in SKIP_API_LIST + no whitelist used.",
                    meth, self.host)
                continue
            if blacklist is not None and meth in blacklist:
                log.debug(
                    "Skipping RPC method %s against host %s as method is present in blacklist.",
                    meth, self.host)
                continue
            tasks.append(self.loop.create_task(self._test_meth(func, meth)))

        for t in tasks:
            status, result, error, meth = await t
            res.methods[meth] = status
            if result is not None: res.results[meth] = result
            if error is not None: res.errors[meth] = error
        return res
コード例 #5
0
ファイル: neighbors.py プロジェクト: Privex/iota-tools
def _neighbor_row(neighbor: Neighbor):
    n = DictObject(
        address=neighbor.address,
        domain=neighbor.domain,
        alias=empty_if(neighbor.alias, 'N/A'),
        connectionType=neighbor.connectionType,
        autopeeringId=empty_if(neighbor.autopeeringId, 'N/A'),
        numberOfAllTransactions=str(neighbor.numberOfAllTransactions),
        numberOfReceivedMilestoneReq=str(
            neighbor.numberOfReceivedMilestoneReq),
        numberOfSentHeartbeats=str(neighbor.numberOfSentHeartbeats),
    )
    n.connected = f"{Fore.GREEN}YES{Fore.RESET}" if neighbor.connected else f"{Fore.RED}NO{Fore.RESET}"
    return NeighborTableRow(**n)
コード例 #6
0
    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
コード例 #7
0
ファイル: sqlite.py プロジェクト: Privex/python-db
def _zip_cols(cursor: Union[sqlite3.Cursor, GenericCursor, GenericAsyncCursor],
              row: iter):
    # combine the column names with the row data
    # so it can be used like a dict
    col_names = list(map(lambda x: x[0], cursor.description))
    res = DictObject(zip(col_names, row))
    return res
コード例 #8
0
 def test_convert_to_dict(self):
     """Test converting a :class:`.DictObject` into a :class:`dict`"""
     x = DictObject(hello='world', example='testing')
     y = dict(x)
     self.assertEqual(x, y)
     self.assertEqual(y['hello'], 'world')
     self.assertEqual(y['example'], 'testing')
コード例 #9
0
def get_arg_defaults() -> DictObject:
    """
    Generates a :class:`.DictObject` containing sane argument defaults for use with a :class:`.ArgumentParser` instance.
    """
    return DictObject(
        skip_apis='', plugins=settings.plugins, nodefile=settings.node_file, verbose=settings.verbose,
        quiet=settings.quiet, params='[]'
    )
コード例 #10
0
ファイル: repl.py プロジェクト: Privex/pyrewall
 def __init__(self, *args, **kwargs):
     self.buffer = []
     self.hist_file = os.path.expanduser(f'~/{self.hist_file_name}')
     self.should_exit = False
     self.keywords = list(self.pyre.control_handlers.keys()) + list(
         self.pyre.rp.rule_handlers.keys())
     self.completer = WordCompleter(self.keywords)
     open(self.hist_file, 'a').close()
     self.session = PromptSession(history=FileHistory(self.hist_file))
     self._rendered_rules = DictObject(v4=[], v6=[], pyre=[])
     self.rendered_at = len(self.buffer)
コード例 #11
0
ファイル: node.py プロジェクト: Privex/eos-python
def _node_to_row(node: Node):
    """
    Convert a :class:`.Node` object into a dictionary which is safe for passing to an insert row function.
    
    :param Node node: The :class:`.Node` to convert
    :return DictObject node_dict: The node, converted into a dictionary.
    """
    d = DictObject(url=node.url, network=node.network, enabled=node.enabled,
                   fail_count=node.fail_count, last_fail=node.last_fail)
    if node.id is not None:
        d['id'] = node.id
    
    return d
コード例 #12
0
ファイル: app.py プロジェクト: Privex/whats-my-ip
def _safe_geo(
    d: Union[GeoIPResult, Dict[str, Any]], force_safe=False, str_network=True, trim_geoasn=True,
    trim_geocity=True, **kwargs
) -> Union[dict, DictObject]:
    if force_safe or not isinstance(d, (DictObject, dict)):
        d = _safe_dict(d, **kwargs)
    d = DictObject(d)
    if str_network and not isinstance(d.network, str):
        d.network = str(d.network)
    if trim_geoasn and 'geoasn_data' in d:
        del d['geoasn_data']
    if trim_geocity and 'geocity_data' in d:
        del d['geocity_data']
    return d
コード例 #13
0
async def handle_error(err_code='UNKNOWN_ERROR', err_msg=None, code: int = None, exc: Exception = None, **kwargs):
    tpl = empty_if(kwargs.get('template'), 'api_error.html')
    
    res, extra = DictObject(error_code=err_code), {}
    if exc is not None:
        res.exc_name, res.exc_msg, res.traceback = str(type(exc)), str(exc), traceback.format_exc()
        log.warning("_handle_error exception type / msg: %s / %s", res.exc_name, res.exc_msg)
        log.warning("_handle_error traceback: %s", res.traceback)
    err: AppError = ERRORS.get(err_code, ERRORS['UNKNOWN_ERROR'])
    res.error_msg = err.message if err_msg is None else err_msg
    res.status_code = err.status if code is None else code
    
    if settings.DEBUG and exc is not None:
        extra: Dict[str, Any] = dict(exception=filter_form(res, 'traceback', 'exc_name', 'exc_msg'))
        if 'traceback' in extra['exception']: extra['exception']['traceback'] = res.traceback.split("\n")
    
    if await wants_json():
        return error(res.error_code, msg=res.error_msg, code=res.status_code, extra=extra)
    
    tpl = await render_template(
        tpl, **res, data=json.dumps(error_dict(res.error_code, msg=res.error_msg, extra=extra), indent=4)
    )
    return tpl, res.status_code
コード例 #14
0
ファイル: app.py プロジェクト: Privex/whats-my-ip
def geo_view(ip: Union[str, IPv4Address, IPv4Address], ua: str = None, **extra) -> GeoResult:
    # data = DictObject(geo=DictObject(), hostname='', messages=[], ip_valid=False)
    # data = DictObject({**data, **extra})
    data = GeoResult(ip=None, ua=ua, **extra)
    # data.geo = DictObject()
    try:
        data.init_ip(ip)
        data.ip_valid = True
        gdata = get_geodata(ip)
        if gdata is None:
            raise geoip2.errors.AddressNotFoundError(f"GeoIPResult was empty!")
        data.geo = DictObject(_safe_geo(get_geodata(ip)))
        data.geo.error = False
    except geoip2.errors.AddressNotFoundError:
        msg = f"IP address '{ip}' not found in GeoIP database."
        log.info(msg)
        data.geo = DictObject(error=True, message=msg)
        data.error = True
        data.messages += [msg]
    except ValueError:
        log.warning(f'The IP address "{ip}" was not valid... Use header: {cf["USE_IP_HEADER"]} / Header: "{cf["IP_HEADER"]}"')
        data.messages += ['Invalid IP address detected']
        data.ip_valid = False
    return data
コード例 #15
0
ファイル: app.py プロジェクト: Privex/whats-my-ip
def _index(bformat=None):
    h = request.headers
    ip = get_ip()
    ua = h.get('User-Agent', 'Empty User Agent')
    q = merge_frm(req=request)
    data = DictObject(geo_view(ip, ua=ua))
    wanted = wants_type() if 'format' in q else wants_type(fmt=bformat)
    if wanted == 'json':
        return jsonify(data)
    if wanted == 'text':
        fres = get_flat(ip, ua=ua, dtype=q.get('type', q.get('dtype', 'all')))
        return Response(fres + "\n", status=200, content_type='text/plain')
    if wanted == 'yaml':
        return Response(dump_yaml(data), status=200, content_type='text/yaml')
    # return render_template('index.html', v4_host=cf['V4_HOST'], v6_host=cf['V6_HOST'], main_host=settings.MAIN_HOST, **data)
    return render_template('index.html', **data)
コード例 #16
0
ファイル: objects.py プロジェクト: Privex/steem-async
def add_known_asset_symbols(obj: Dict[str, Asset]) -> DictObject:
    """
    For each :class:`.Asset` in ``obj``, make sure every asset type can be matched by both asset ID (i.e. IDs starting with "@@0000"),
    and their symbol (e.g. "HIVE").
    
    :param Dict[str,Asset] obj: A :class:`.dict` or :class:`.DictObject` mapping asset IDs / symbols to :class:`.Asset` objects.
    :return DictObject new_assets: A new :class:`.DictObject` with both asset IDs (if applicable) and symbols mapped to :class:`.Asset`'s
    """
    new_assets = DictObject(obj)

    # Iterable over each dict key + value, only handling keys which appear to be asset ID's starting with "@".
    # Create/update a key for the asset's symbol in new_assets to point to the asset_id's Asset object.
    for assetID, assetObject in obj.items():
        # If this asset's ID doesn't start with an @, then we don't need to duplicate it into it's symbol.
        if assetID[0] != '@':
            continue
        # If the :class:`.Asset` object doesn't have an asset_id set, then set it to match the dictionary key
        assetObject.asset_id = assetID if empty(
            assetObject.asset_id) else assetObject.asset_id
        # Map the asset's symbol (e.g. HIVE) to the Asset object, so it can be matched by both asset ID and symbol.
        new_assets[assetObject.symbol] = assetObject

    return new_assets
コード例 #17
0
ファイル: objects.py プロジェクト: Privex/python-steemengine
    def __post_init__(self):
        kwargs = DictObject(self.raw_data)
        _maxs, _circ = self.max_supply, self.circulating_supply

        self.max_supply = conv_dec(kwargs.get('maxSupply', self.max_supply))
        self.max_supply = conv_dec(kwargs.get('max_supply', self.max_supply))

        self.circulating_supply = conv_dec(
            kwargs.get('circulatingSupply', self.circulating_supply))
        self.circulating_supply = conv_dec(
            kwargs.get('circulating_supply', self.circulating_supply))

        self.supply = Decimal(kwargs.get('supply', self.supply))

        meta = self.metadata
        try:
            meta = {} if empty(meta, itr=True) else (
                json.loads(meta) if isinstance(meta, str) else meta)
        except json.JSONDecodeError:
            log.warning("Failed to decode Token metadata as JSON: %s", meta)
            meta = {}
        self.metadata = TokenMetadata.from_dict(meta)
コード例 #18
0
ファイル: app.py プロジェクト: Privex/whats-my-ip
def _safe_dict(d: Union[T, Dict[str, Any], list], safe_types: tuple = None, **kwargs) -> Union[T, list, dict, DictObject]:
    safe_types = tuple(empty_if(safe_types, (str, int, float), itr=True, zero=True))
    iter_types = tuple(empty_if(kwargs.pop('iter_types', None), (dict, list, tuple, set), itr=True, zero=True))
    unsafe_cast = kwargs.get('unsafe_cast', _try_dict)
    
    def _call_self(xdx):
        return _safe_dict(xdx, safe_types=safe_types, **kwargs)
    
    def _so(xdx):
        return _safe_obj(xdx, safe_types=safe_types, iter_types=iter_types, unsafe_cast=unsafe_cast, **kwargs)
    
    if isinstance(d, dict):
        log.debug(f"(_safe_dict) Object {d!r} appears to be a dict(-like) object - iterating over it, and recursively calling"
                  f" _safe_obj.")
        safex = {k: _so(v) for k, v in d.items()}
        for k, v in safex.items():
            if isinstance(v, dict) and not isinstance(d[k], dict):
                log.debug(f"(_safe_dict) Found new dict - converting it's contents to be safe by calling self (_safe_dict). "
                          f"This new dict is (key: {k!r}): {v!r}")
                safex[k] = _call_self(v)
        
        # return DictObject({**safex, **unsafex, **objsafe})
        return DictObject(safex)
    
    if isinstance(d, iter_types):
        itr_cast = type(d)
        log.debug(f"(_safe_dict) Object {d!r} appears to be a iterable object - iterating over it, and recursively calling"
                  f" _safe_obj. iter_types: {iter_types!r}")
        return itr_cast([_so(v) for v in d])
    log.debug(f"(_safe_dict) Object {d!r} doesn't match known types. Passing it to _safe_obj then calling self (_safe_dict)"
              f"with it's result")
    res_so = _so(d)
    log.debug(f"Result from _safe_obj: {res_so} (original object: {d!r})")
    res_self = _call_self(_so(d))
    log.debug(f"Result from _safe_dict(_safe_obj(d)): {res_so} (original object: {d!r})")
    return res_self
コード例 #19
0
ファイル: health.py プロジェクト: symbiotes/steem-rpc-scanner
async def _test_methods(node: str,
                        *methods: str,
                        params='[]',
                        auto_exit=True) -> Union[DictObject, Dict[str, dict]]:
    # mt = MethodTests(node)
    # loop = asyncio.get_event_loop()
    sup_methods = [meth for meth in methods if meth in get_supported_methods()]
    unsup_methods = [
        meth for meth in methods if meth not in get_supported_methods()
    ]
    if len(unsup_methods) > 0:
        log.error(
            f"CAUTION: The RPC API method(s) '{unsup_methods}' are not supported yet. This means a proper, thorough, example "
            f"request + response test - has NOT been created for these method(s). Despite this, we'll try querying '{node}' "
            f"using the unsupported method(s) using the parameters '{params}', and checking for a non-empty 'result' key in the response."
        )
        log.error(
            "You can use the CLI argument '--params' to change the parameters used for unsupported RPC methods."
        )

    res = DictObject(methods={}, errors={}, results={})
    if len(sup_methods) > 0:
        res = await MethodTests(node).test_all(whitelist=list(sup_methods))

    if not empty(params):
        params = json.loads(params)
    else:
        params = []

    for m in unsup_methods:
        ures = await _try_unknown_method(node=node,
                                         method=m,
                                         params=params,
                                         auto_exit=auto_exit)
        if ures is False:
            res.methods[m] = False
            res.errors[m] = "unknown error"
            continue
        res.methods[m] = True
        res.results[m] = ures[0]

    # return loop.run_until_complete(MethodTests(node).test_all(whitelist=list(methods)))
    return res
コード例 #20
0
ファイル: admin.py プロジェクト: Privex/adminplus
class CustomAdmin(admin.AdminSite):
    """
    To allow for custom admin views, we override AdminSite, so we can add custom URLs, among other things.
    """
    custom_urls: List[PATH_TYPES] = []
    custom_url_map: Dict[str, DictObject] = DictObject()

    _ct_admins = {}
    _sngl_lock = threading.Lock()

    def __init__(self, name='custom_admin'):
        # self.custom_urls = []
        # self.custom_url_map = DictObject()
        super().__init__(name)

    @classmethod
    def admin_singleton(cls, singleton_name='default', *args, **kwargs):
        with cls._sngl_lock:
            n = singleton_name
            if empty(cls._ct_admins.get(n, None)):
                log.debug(
                    "Creating new CustomAdmin singleton '%s'... args: %s | kwargs: %s",
                    n, args, kwargs)
                cls._ct_admins[n] = cls(*args, **kwargs)
        return cls._ct_admins[n]

    def get_urls(self) -> List[PATH_TYPES]:
        """Returns a list of merged URLs by combining :meth:`.get_urls` via superclass with :attr:`.custom_urls`"""
        _urls = super(CustomAdmin, self).get_urls()
        urls = self.custom_urls
        return _urls + urls

    @property
    def custom_urls_reverse(self):
        """
        Iterates over :attr:`.custom_url_map` and ensures all URL dictionaries have a ``url`` field, which
        points to their reversed URL based on their ``name``
        """
        for _, obj in self.custom_url_map.items():
            if obj.hidden:
                continue
            if 'url' not in obj:
                obj['url'] = reverse(f"admin:{obj.name}")

        return self.custom_url_map

    # def each_context(self, request):
    #     ctx = super().each_context(request)
    #     ctx['custom_urls'] = self.custom_urls_reverse
    #     return ctx

    def url_is_registered(self, url: str, fail=False) -> bool:
        """Returns ``True`` if the URL ``url`` exists within :attr:`.custom_urls` otherwise ``False``"""
        if url is None:
            return False
        for u in self.custom_urls:
            # noinspection PyProtectedMember
            if u.pattern._route == url:
                log.warning(
                    "URL %s is already registered with CustomAdmin... Not registering!",
                    url)
                if fail:
                    raise FileExistsError(
                        f"URL '{url}' is already registered with CustomAdmin!")
                return True
        return False

    @staticmethod
    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)

    @staticmethod
    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

    @staticmethod
    def regex_has_params(url: str) -> bool:
        """Check if a URL contains view parameters"""
        if _RE_ANGLE_PARAMS.search(url) is not None:
            # log.debug("URL '%s' contains angle bracket (<str:example>) parameters", url)
            return True
        if _RE_BRACKET_PARAMS.search(url) is not None:
            # log.debug("URL '%s' contains round bracket ( (?P<x>()) ) parameters", url)
            return True
        return False

    def add_url(self, view_obj, url: URL_TYPES, human: str = None, hidden: bool = False, name: str = None, **kwargs) \
            -> Optional[List[PATH_TYPES]]:
        """
        Register a custom admin view with :class:`.CustomAdmin`
        
        **URL Types**:
            
            With :class:`.str` form, a single URL will be registered under ``/admin/`` with that URL.
            
            **In str form**::
                
                >>> CustomAdmin().add_url(View(), 'someview/')
            
            With :class:`.list` form, simply specify a list of string URLs. Each URL will be given a name with
            a number appended to the end (based on URL position). For the below example, assuming this was a function
            view named ``my_view``, then the first URL would get the name ``my_view_1``, and the second ``my_view_2``.
            
            **In list form**::
                
                >>> CustomAdmin().add_url(View(), ['myview/', 'myview/<int:id>/'])
            
            With :class:`.dict` form, URLs are specified as keys, mapped to a unique name for the URL. This allows you
            to specify arbitrary names for each URL, which will be stable (under the ``admin:`` prefix), allowing you
            to safely reference them from within templates, e.g. ``{% url 'admin:user_info_by_username' user.username %}``
            
            **In dict form**::
            
                >>> CustomAdmin().add_url(View(), {
                ...     'user_info/': 'user_info_index',
                ...     'user_info/<str:username>': 'user_info_by_username'
                ... })
            
            
        
        :param callable|View view_obj: A Django view (function-based or class-based) to register a URL for
        
        :param str url: An individual URL as a string to register the view under
        
        :param List[str] url: With :class:`.list` form, simply specify a list of string URLs. Each URL will be given a name with
                              a number appended to the end (based on URL position). For the below example, assuming this was a function
                              view named ``my_view``, then the first URL would get the name ``my_view_1``, and the second ``my_view_2``.
                              
                              In list form: ``['myview/', 'myview/<int:id>/']``
        
        :param dict url: With :class:`.dict` form, URLs are specified as keys, mapped to a unique name for the URL. This allows you
                         to specify arbitrary names for each URL, which will be stable (under the ``admin:`` prefix), allowing you
                         to safely reference them from within templates, e.g. ``{% url 'admin:user_info_by_username' user.username %}``
                        
                         In dict form: ``{'user_info/': 'user_info_index', 'user_info/<str:username>': 'user_info_by_username'}``
        
        :param str human: A human readable link name/title for the page - which would be shown in the admin panel
        :param bool hidden: (Default: ``False``) Whether or not to hide this URL from the admin page list
        :param str name: A unique URL name for referencing with Django URL name lookups
        :param kwargs: Additional options
        
        :keyword bool hide_extras: (Default: ``True``) When more than one URL is specified in ``url`` using a list/dict, if
                                    hide_extra is True, then only the first URL in the list/dict of URLs will use the
                                    user-specified ``hidden`` parameter. The rest of the URLs will have ``hidden=True``
        
        :keyword bool hide_params: If hide_params is True, URLs which contain route parameters (e.g. ``<str:username>``) will be hidden
                                   by default, to prevent errors caused by trying to reverse their URL in the admin panel custom view list.
        
        :return List[PATH_TYPES] custom_urls: If successful, returns the current list of URLs from :attr:`.custom_urls`
        """
        if empty(view_obj):
            log.error(
                f"view_obj is empty, cannot register! url: {url} | human: {human} | hidden: {hidden} | name: {name} | kwargs: {kwargs}"
            )
            return None
        url = camel_to_snake(view_obj.__name__) + '/' if empty(url) else url
        # When more than one URL is specified in ``url`` using a list/dict, if hide_extra is True, then only the first URL
        # in the list/dict of URLs will use the user-specified ``hidden`` parameter.
        # The rest of the URLs will have hidden=True
        hide_extra = kwargs.get('hide_extra', True)
        # If hide_params is True, URLs which contain route parameters (e.g. ``<str:username>``) will be hidden by default, to prevent
        # errors caused by trying to reverse their URL in the admin panel custom view list.
        hide_params = kwargs.get('hide_params', True)

        name = name if not empty(name) else self.detect_name(view_obj)
        human = human if not empty(human) else self.detect_human(
            empty_if(view_obj, name))

        ####
        # Handle URLs specified as a list
        ####
        if isinstance(url, list):
            url = [u for u in list(url) if not self.url_is_registered(u)]
            name_number = 1
            orig_name = name
            orig_hidden = hidden
            for u in url:
                if name_number > 1:
                    name = f"{orig_name}_{name_number}"
                    if hide_extra:
                        hidden = True
                if self.regex_has_params(u) and hide_params:
                    hidden = True

                self.add_url(view_obj,
                             url=u,
                             human=human,
                             hidden=hidden,
                             name=name,
                             **kwargs)
                name_number += 1
                hidden = orig_hidden

            return self.custom_urls
        ####
        # Handle URLs specified as a dict of url:name
        ####
        elif isinstance(url, dict):
            # url = {u: n for u, n in dict(url).items() if not self.url_is_registered(u)}
            orig_hidden = hidden
            name_number = 1
            for u, n in url.items():
                if self.url_is_registered(u):
                    continue
                if name_number > 1 and hide_extra:
                    hidden = True
                if self.regex_has_params(u) and hide_params:
                    hidden = True
                self.add_url(view_obj,
                             url=u,
                             human=human,
                             hidden=hidden,
                             name=n,
                             **kwargs)
                name_number += 1
                hidden = orig_hidden
            return self.custom_urls
        ####
        # Handle a plain string URL
        ####
        elif isinstance(url, str):
            if self.url_is_registered(url):
                return self.custom_urls

        ####
        # String URL handling continued
        ####
        if empty(name):
            # if hasattr(view_obj, '__name__'):
            #     name = camel_to_snake(view_obj.__name__)
            # else:
            log.warning(
                "No name specified by user for view, and cannot infer from view_obj.__name__ ..."
            )
            name = None

        # If a URL contains Django route parameters e.g. ``<str:example>``, it's best to hide them by default, otherwise
        # they'll cause issues when they're reversed in .custom_urls_reverse
        if self.regex_has_params(url) and hide_params:
            hidden = True

        # Class-based views need to be registered using .as_view()
        view_obj = view_obj.as_view() if isclass(view_obj) else view_obj

        self.custom_urls.append(path(url, view_obj, name=name))
        self.custom_url_map[url] = DictObject(
            name=name,
            route=url,
            human=empty_if(human,
                           human_name(empty_if(name, "unknown_custom_view"))),
            hidden=hidden)
        return self.custom_urls

    def wrap_register(self,
                      view,
                      model: Model = None,
                      url: URL_TYPES = None,
                      human: str = None,
                      hidden: bool = False,
                      name: str = None,
                      **kwargs):
        """
        This is a wrapper method which routes calls from :func:`.register_url` / :func:`.ct_register` to the correct
        method, depending on whether a Django :class:`.ModelAdmin` view is being registered, or whether
        a custom user function/class admin view is being registered.
        
        See :meth:`.add_url` for full docs. Most params are just passed through to :meth:`.add_url`.
        
        :param callable|type|Type[View]|View view: The function/class view to register, or a :class:`.ModelAdmin`
        :param Model model: Only applicable when registering :class:`.ModelAdmin`'s
        :param str|list|dict url: The URL or multiple URLs to register ``view`` under
        :param str human: The human friendly name for the view - displayed on the admin index list of custom views
        :param bool hidden: (Default: ``False``) Whether or not to hide this URL from the admin page list
        :param str name: A unique URL name for referencing with Django URL name lookups
        :param kwargs:
        :return:
        """
        if url is None:
            if isclass(view) and issubclass(view, admin.ModelAdmin):
                if empty(model):
                    raise ValueError(
                        f"Wrapped ModelAdmin {view.__name__} but no model passed to ct_register..."
                    )
                # log.debug("Registering ModelAdmin view: %s", view.__name__)
                self.register(model, view)
                return
            raise ValueError(
                "Wrapped classes without url's must subclass admin.ModelAdmin."
            )

        self.add_url(view_obj=view,
                     url=url,
                     human=human,
                     hidden=hidden,
                     name=name,
                     **kwargs)
コード例 #21
0
ファイル: admin.py プロジェクト: Privex/adminplus
    def add_url(self, view_obj, url: URL_TYPES, human: str = None, hidden: bool = False, name: str = None, **kwargs) \
            -> Optional[List[PATH_TYPES]]:
        """
        Register a custom admin view with :class:`.CustomAdmin`
        
        **URL Types**:
            
            With :class:`.str` form, a single URL will be registered under ``/admin/`` with that URL.
            
            **In str form**::
                
                >>> CustomAdmin().add_url(View(), 'someview/')
            
            With :class:`.list` form, simply specify a list of string URLs. Each URL will be given a name with
            a number appended to the end (based on URL position). For the below example, assuming this was a function
            view named ``my_view``, then the first URL would get the name ``my_view_1``, and the second ``my_view_2``.
            
            **In list form**::
                
                >>> CustomAdmin().add_url(View(), ['myview/', 'myview/<int:id>/'])
            
            With :class:`.dict` form, URLs are specified as keys, mapped to a unique name for the URL. This allows you
            to specify arbitrary names for each URL, which will be stable (under the ``admin:`` prefix), allowing you
            to safely reference them from within templates, e.g. ``{% url 'admin:user_info_by_username' user.username %}``
            
            **In dict form**::
            
                >>> CustomAdmin().add_url(View(), {
                ...     'user_info/': 'user_info_index',
                ...     'user_info/<str:username>': 'user_info_by_username'
                ... })
            
            
        
        :param callable|View view_obj: A Django view (function-based or class-based) to register a URL for
        
        :param str url: An individual URL as a string to register the view under
        
        :param List[str] url: With :class:`.list` form, simply specify a list of string URLs. Each URL will be given a name with
                              a number appended to the end (based on URL position). For the below example, assuming this was a function
                              view named ``my_view``, then the first URL would get the name ``my_view_1``, and the second ``my_view_2``.
                              
                              In list form: ``['myview/', 'myview/<int:id>/']``
        
        :param dict url: With :class:`.dict` form, URLs are specified as keys, mapped to a unique name for the URL. This allows you
                         to specify arbitrary names for each URL, which will be stable (under the ``admin:`` prefix), allowing you
                         to safely reference them from within templates, e.g. ``{% url 'admin:user_info_by_username' user.username %}``
                        
                         In dict form: ``{'user_info/': 'user_info_index', 'user_info/<str:username>': 'user_info_by_username'}``
        
        :param str human: A human readable link name/title for the page - which would be shown in the admin panel
        :param bool hidden: (Default: ``False``) Whether or not to hide this URL from the admin page list
        :param str name: A unique URL name for referencing with Django URL name lookups
        :param kwargs: Additional options
        
        :keyword bool hide_extras: (Default: ``True``) When more than one URL is specified in ``url`` using a list/dict, if
                                    hide_extra is True, then only the first URL in the list/dict of URLs will use the
                                    user-specified ``hidden`` parameter. The rest of the URLs will have ``hidden=True``
        
        :keyword bool hide_params: If hide_params is True, URLs which contain route parameters (e.g. ``<str:username>``) will be hidden
                                   by default, to prevent errors caused by trying to reverse their URL in the admin panel custom view list.
        
        :return List[PATH_TYPES] custom_urls: If successful, returns the current list of URLs from :attr:`.custom_urls`
        """
        if empty(view_obj):
            log.error(
                f"view_obj is empty, cannot register! url: {url} | human: {human} | hidden: {hidden} | name: {name} | kwargs: {kwargs}"
            )
            return None
        url = camel_to_snake(view_obj.__name__) + '/' if empty(url) else url
        # When more than one URL is specified in ``url`` using a list/dict, if hide_extra is True, then only the first URL
        # in the list/dict of URLs will use the user-specified ``hidden`` parameter.
        # The rest of the URLs will have hidden=True
        hide_extra = kwargs.get('hide_extra', True)
        # If hide_params is True, URLs which contain route parameters (e.g. ``<str:username>``) will be hidden by default, to prevent
        # errors caused by trying to reverse their URL in the admin panel custom view list.
        hide_params = kwargs.get('hide_params', True)

        name = name if not empty(name) else self.detect_name(view_obj)
        human = human if not empty(human) else self.detect_human(
            empty_if(view_obj, name))

        ####
        # Handle URLs specified as a list
        ####
        if isinstance(url, list):
            url = [u for u in list(url) if not self.url_is_registered(u)]
            name_number = 1
            orig_name = name
            orig_hidden = hidden
            for u in url:
                if name_number > 1:
                    name = f"{orig_name}_{name_number}"
                    if hide_extra:
                        hidden = True
                if self.regex_has_params(u) and hide_params:
                    hidden = True

                self.add_url(view_obj,
                             url=u,
                             human=human,
                             hidden=hidden,
                             name=name,
                             **kwargs)
                name_number += 1
                hidden = orig_hidden

            return self.custom_urls
        ####
        # Handle URLs specified as a dict of url:name
        ####
        elif isinstance(url, dict):
            # url = {u: n for u, n in dict(url).items() if not self.url_is_registered(u)}
            orig_hidden = hidden
            name_number = 1
            for u, n in url.items():
                if self.url_is_registered(u):
                    continue
                if name_number > 1 and hide_extra:
                    hidden = True
                if self.regex_has_params(u) and hide_params:
                    hidden = True
                self.add_url(view_obj,
                             url=u,
                             human=human,
                             hidden=hidden,
                             name=n,
                             **kwargs)
                name_number += 1
                hidden = orig_hidden
            return self.custom_urls
        ####
        # Handle a plain string URL
        ####
        elif isinstance(url, str):
            if self.url_is_registered(url):
                return self.custom_urls

        ####
        # String URL handling continued
        ####
        if empty(name):
            # if hasattr(view_obj, '__name__'):
            #     name = camel_to_snake(view_obj.__name__)
            # else:
            log.warning(
                "No name specified by user for view, and cannot infer from view_obj.__name__ ..."
            )
            name = None

        # If a URL contains Django route parameters e.g. ``<str:example>``, it's best to hide them by default, otherwise
        # they'll cause issues when they're reversed in .custom_urls_reverse
        if self.regex_has_params(url) and hide_params:
            hidden = True

        # Class-based views need to be registered using .as_view()
        view_obj = view_obj.as_view() if isclass(view_obj) else view_obj

        self.custom_urls.append(path(url, view_obj, name=name))
        self.custom_url_map[url] = DictObject(
            name=name,
            route=url,
            human=empty_if(human,
                           human_name(empty_if(name, "unknown_custom_view"))),
            hidden=hidden)
        return self.custom_urls
コード例 #22
0
ファイル: admin.py プロジェクト: Privex/adminplus
import copy
import re
import threading
from inspect import isclass
from typing import List, Optional, Union, Dict
from django.contrib import admin
from django.db.models import Model
from django.http import HttpRequest
from django.urls import URLResolver, URLPattern, path, reverse
from django.views import View
from privex.helpers import camel_to_snake, empty, human_name, empty_if, DictObject
import logging

log = logging.getLogger(__name__)

STORE = DictObject(is_setup=False)

_RE_ANGLE_PARAMS = re.compile(r'<[a-zA-Z0-9_:-]+>')
_RE_BRACKET_PARAMS = re.compile(r'\(\?P.*\)')

URL_TYPES = Optional[Union[str, List[str], Dict[str, str]]]

PATH_TYPES = Union[URLResolver, URLPattern]


class CustomAdmin(admin.AdminSite):
    """
    To allow for custom admin views, we override AdminSite, so we can add custom URLs, among other things.
    """
    custom_urls: List[PATH_TYPES] = []
    custom_url_map: Dict[str, DictObject] = DictObject()
コード例 #23
0
ファイル: neighbors.py プロジェクト: Privex/iota-tools
NeighborTableRow = namedtuple(
    'NodeTableRow',
    'address connected domain alias connectionType autopeeringId numberOfAllTransactions '
    'numberOfReceivedMilestoneReq numberOfSentHeartbeats',
)
NeighborTableColumn = namedtuple('NeighborTableColumn',
                                 'title title_padding content_padding',
                                 defaults=(25, 25))

# Mapping of NeighborTableRow key, to a tuple of (column_title, title_padding, content_padding)
table_columns: Dict[str, NeighborTableColumn] = DictObject(
    address=NeighborTableColumn('Address', 55, 55),
    connected=NeighborTableColumn('Connected?', 22, 32),
    domain=NeighborTableColumn('Domain', 40, 40),
    alias=NeighborTableColumn('Alias', 40, 40),
    connectionType=NeighborTableColumn('Proto', 20, 20),
    autopeeringId=NeighborTableColumn('Peer ID', 35, 35),
    numberOfAllTransactions=NeighborTableColumn('Total TX', 25, 25),
    numberOfReceivedMilestoneReq=NeighborTableColumn('Recv Milestones', 30,
                                                     30),
    numberOfSentHeartbeats=NeighborTableColumn('Heartbeats', 25, 25),
)


def _neighbor_row(neighbor: Neighbor):
    n = DictObject(
        address=neighbor.address,
        domain=neighbor.domain,
        alias=empty_if(neighbor.alias, 'N/A'),
        connectionType=neighbor.connectionType,
        autopeeringId=empty_if(neighbor.autopeeringId, 'N/A'),
        numberOfAllTransactions=str(neighbor.numberOfAllTransactions),
コード例 #24
0
from privex.helpers import DictObject

from privex.steemengine import SteemEngineToken, SteemEngineHistory

__all__ = [
    'st', 'SEBase', 'SteemBaseTests', 'HiveBaseTests', 'NetworkBaseTests',
    'FAKE_TOKEN', 'REAL_TOKEN', 'ACTIVE_TOKENS', 'TEST_ACC', 'FAKE_ACC'
]

# SteemEngineToken.custom_beem(node=['https://api.steemit.com'])

st = SteemEngineToken()
FAKE_TOKEN = 'NONEXISTANTTOKEN'
REAL_TOKEN = 'SGTK'
ACTIVE_TOKENS = DictObject(steem='ENG', hive='BEE')
TEST_ACC = 'someguy123'
FAKE_ACC = 'non-existent-account999'

class SEBase(unittest.TestCase):
    s_nodes = ['https://api.steemit.com']
    s_kwargs = dict(network='steem')
    
    @classmethod
    def setUpClass(cls) -> None:
        cls.stoken = SteemEngineToken()


class SteemBaseTests(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
コード例 #25
0
from decimal import Decimal

import pytest
from privex.helpers import DictObject, empty

from privex.eos.lib import Api, EOSBlock, Node
from privex.eos.node import NodeManager, DEFAULT_ADAPTER
from privex.eos.objects import EOSAccount

EXAMPLE_BLOCK_NUM = 94000000
EXAMPLE_BLOCK_DATA = DictObject(
    timestamp='2019-12-08T23:19:55.000',
    producer='eoshuobipool',
    block_num=94000000,
    ref_block_prefix=3607919330,
    previous='059a537fa917845911fc05e8f6b305e90a837eaba935ae65617125291cb307b4',
    id='059a5380852aef1ee27a0cd75953f76bb334ad402b4e0360dada1a17ee486357',
    producer_signature=
    'SIG_K1_K9EoSbEcLaeXgJWwwQTiL9k4RsQW2DwS7nng77v6y8nZ8gJYC6qBknumsnq'
    'Q3vXChsK2KpkgzKVcPEC8YgT8RUxWrHJatP',
    _total_txs=13)

RANGE_START = EXAMPLE_BLOCK_NUM
RANGE_END = RANGE_START + 20


@pytest.fixture()
async def eos_api():
    Api().node_manager.adapter.recreate_schemas()
    eos = Api()
    yield eos
コード例 #26
0
ファイル: objects.py プロジェクト: Privex/steem-async
CHAIN_ASSETS = DictObject(HIVE=DictObject({
    '@@000000013':
    Asset(symbol='HBD', precision=3, asset_id='@@000000013'),
    '@@000000021':
    Asset(symbol='HIVE', precision=3, asset_id='@@000000021'),
    '@@000000037':
    Asset(symbol='VESTS', precision=6, asset_id='@@000000037'),
}),
                          BLURT=DictObject({
                              '@@000000021':
                              Asset(symbol='BLURT',
                                    precision=3,
                                    asset_id='@@000000021'),
                              '@@000000037':
                              Asset(symbol='VESTS',
                                    precision=6,
                                    asset_id='@@000000037'),
                          }),
                          STEEM=DictObject({
                              '@@000000013':
                              Asset(symbol='SBD',
                                    precision=3,
                                    asset_id='@@000000013'),
                              '@@000000021':
                              Asset(symbol='STEEM',
                                    precision=3,
                                    asset_id='@@000000021'),
                              '@@000000037':
                              Asset(symbol='VESTS',
                                    precision=6,
                                    asset_id='@@000000037'),
                          }),
                          GOLOS=DictObject({
                              'GOLOS':
                              Asset(symbol='GOLOS',
                                    precision=3,
                                    network=CHAIN.GOLOS.value),
                              'GBG':
                              Asset(symbol='GBG',
                                    precision=3,
                                    network=CHAIN.GOLOS.value),
                              'GESTS':
                              Asset(symbol='GESTS',
                                    precision=6,
                                    network=CHAIN.GOLOS.value),
                          }))
コード例 #27
0
ファイル: objects.py プロジェクト: Privex/steem-async
 def as_dict(cls) -> Union[DictObject, Dict[str, str]]:
     """Return this enum as a :class:`.DictObject` - chain names mapped to their string chain ID"""
     # noinspection PyTypeChecker
     return DictObject({chain.name: chain.value for chain in list(cls)})
コード例 #28
0
ファイル: app.py プロジェクト: Privex/whats-my-ip
    except Exception:
        if try_class:
            cld = d.__class__ if isinstance(d, object) else d
            if cld.__name__ not in dir(__builtins__):
                try:
                    return _class_dict(d)
                except Exception:
                    pass
        return fb_cast(d)


CONVERTERS = {
    bytes: stringify,
    GeoIPResult: DictObject,
    GeoData: DictObject,
    geoip2.models.ASN: lambda a: DictObject(a.raw),
    geoip2.models.City: lambda a: DictObject(a.raw),
    geoip2.models.Country: lambda a: DictObject(a.raw),
    GeoType: lambda a: a.value,
    IPv4Address: str, IPv6Address: str, IPv4Network: str, IPv6Network: str,
}


def _do_convert(d, fallback=None, fail=False):
    for k, v in CONVERTERS.items():
        if not isinstance(d, k) and not type(d) == k: continue
        try:
            log.debug(f"Found converter for {d!r} - calling converter function (key: {k!r}): {v!r} ")
            res = v(d)
            log.debug(f"Result after passing {d!r} to converter is: {res!r}")
            return res
コード例 #29
0
 async def _q_summary(self, from_coin: str, to_coin: str) -> DictObject:
     from_coin, to_coin = from_coin.upper(), to_coin.upper()
     res = await self._query(from_coin, to_coin, endpoint='/summary')
     return DictObject(high=res['high'],
                       low=res['low'],
                       volume=res['volume'])
コード例 #30
0
 async def _q_ticker(self, from_coin: str, to_coin: str) -> DictObject:
     from_coin, to_coin = from_coin.upper(), to_coin.upper()
     res = await self._query(from_coin, to_coin, endpoint='/ticker')
     return DictObject(last=res['lastTradeRate'],
                       bid=res['bidRate'],
                       ask=res['askRate'])