当前位置: 首页>>代码示例>>Python>>正文


Python safe.trim_dict函数代码示例

本文整理汇总了Python中sentry.utils.safe.trim_dict函数的典型用法代码示例。如果您正苦于以下问题:Python trim_dict函数的具体用法?Python trim_dict怎么用?Python trim_dict使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了trim_dict函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。

示例1: to_python

    def to_python(cls, data):
        data = data.copy()

        extra_data = data.pop('data', data)
        if not isinstance(extra_data, dict):
            extra_data = {}

        try:
            name = trim(data.pop('name'), 64)
        except KeyError:
            raise InterfaceValidationError("Missing or invalid value for 'name'")

        try:
            version = trim(data.pop('version'), 64)
        except KeyError:
            raise InterfaceValidationError("Missing or invalid value for 'version'")

        build = trim(data.pop('build', None), 64)

        kwargs = {
            'name': name,
            'version': version,
            'build': build,
            'data': trim_dict(data),
        }
        kwargs['data'] = trim_dict(data)
        return cls(**kwargs)
开发者ID:Andy-hpliu,项目名称:sentry,代码行数:27,代码来源:device.py

示例2: to_python

    def to_python(cls, data):
        data = data.copy()

        extra_data = data.pop("data", data)
        if not isinstance(extra_data, dict):
            extra_data = {}

        ident = trim(data.pop("id", None), 128)
        if ident:
            ident = unicode(ident)
        try:
            email = trim(validate_email(data.pop("email", None), False), 128)
        except ValueError:
            raise InterfaceValidationError("Invalid value for 'email'")
        username = trim(data.pop("username", None), 128)
        if username:
            username = unicode(username)

        try:
            ip_address = validate_ip(data.pop("ip_address", None), False)
        except ValueError:
            raise InterfaceValidationError("Invalid value for 'ip_address'")

        # TODO(dcramer): patch in fix to deal w/ old data but not allow new
        # if not (ident or email or username or ip_address):
        #     raise ValueError('No identifying value')

        kwargs = {"id": ident, "email": email, "username": username, "ip_address": ip_address}

        kwargs["data"] = trim_dict(extra_data)
        return cls(**kwargs)
开发者ID:pombredanne,项目名称:django-sentry,代码行数:31,代码来源:user.py

示例3: to_python

    def to_python(cls, data):
        if not data.get('url'):
            raise InterfaceValidationError("No value for 'url'")

        kwargs = {}

        if data.get('method'):
            method = data['method'].upper()
            if method not in HTTP_METHODS:
                raise InterfaceValidationError("Invalid value for 'method'")
            kwargs['method'] = method
        else:
            kwargs['method'] = None

        scheme, netloc, path, query_bit, fragment_bit = urlsplit(data['url'])

        query_string = data.get('query_string') or query_bit
        if query_string:
            # if querystring was a dict, convert it to a string
            if isinstance(query_string, dict):
                query_string = urlencode([(to_bytes(k), to_bytes(v))
                                          for k, v in query_string.items()])
            else:
                query_string = query_string
                if query_string[0] == '?':
                    # remove '?' prefix
                    query_string = query_string[1:]
            kwargs['query_string'] = trim(query_string, 4096)
        else:
            kwargs['query_string'] = ''

        fragment = data.get('fragment') or fragment_bit

        cookies = data.get('cookies')
        # if cookies were [also] included in headers we
        # strip them out
        headers = data.get('headers')
        if headers:
            headers, cookie_header = format_headers(headers)
            if not cookies and cookie_header:
                cookies = cookie_header
        else:
            headers = ()

        body = data.get('data')
        if isinstance(body, dict):
            body = json.dumps(body)

        if body:
            body = trim(body, settings.SENTRY_MAX_HTTP_BODY_SIZE)

        kwargs['cookies'] = trim_pairs(format_cookies(cookies))
        kwargs['env'] = trim_dict(data.get('env') or {})
        kwargs['headers'] = trim_pairs(headers)
        kwargs['data'] = body
        kwargs['url'] = urlunsplit((scheme, netloc, path, '', ''))
        kwargs['fragment'] = trim(fragment, 1024)

        return cls(**kwargs)
开发者ID:derekey,项目名称:sentry,代码行数:59,代码来源:http.py

示例4: to_python

    def to_python(cls, data):
        abs_path = data.get('abs_path')
        filename = data.get('filename')

        if not abs_path:
            abs_path = filename

        if not filename:
            filename = abs_path

        if abs_path and is_url(abs_path):
            urlparts = urlparse(abs_path)
            if urlparts.path:
                filename = urlparts.path

        assert filename or data.get('function') or data.get('module')

        context_locals = data.get('vars') or {}
        if isinstance(context_locals, (list, tuple)):
            context_locals = dict(enumerate(context_locals))
        elif not isinstance(context_locals, dict):
            context_locals = {}
        context_locals = trim_dict(context_locals)

        # extra data is used purely by internal systems,
        # so we dont trim it
        extra_data = data.get('data') or {}
        if isinstance(extra_data, (list, tuple)):
            extra_data = dict(enumerate(extra_data))

        kwargs = {
            'abs_path': trim(abs_path, 256),
            'filename': trim(filename, 256),
            'module': trim(data.get('module'), 256),
            'function': trim(data.get('function'), 256),
            'in_app': validate_bool(data.get('in_app'), False),
            'context_line': trim(data.get('context_line'), 256),
            # TODO(dcramer): trim pre/post_context
            'pre_context': data.get('pre_context'),
            'post_context': data.get('post_context'),
            'vars': context_locals,
            'data': extra_data,
            'errors': data.get('errors'),
        }

        if data.get('lineno') is not None:
            lineno = int(data['lineno'])
            if lineno < 0:
                lineno = None
            kwargs['lineno'] = lineno
        else:
            kwargs['lineno'] = None

        if data.get('colno') is not None:
            kwargs['colno'] = int(data['colno'])
        else:
            kwargs['colno'] = None

        return cls(**kwargs)
开发者ID:dragon788,项目名称:sentry,代码行数:59,代码来源:stacktrace.py

示例5: to_python

    def to_python(cls, data):
        abs_path = data.get("abs_path")
        filename = data.get("filename")

        if not abs_path:
            abs_path = filename

        if not filename:
            filename = abs_path

        if abs_path and is_url(abs_path):
            urlparts = urlparse(abs_path)
            if urlparts.path:
                filename = urlparts.path

        assert filename or data.get("function") or data.get("module")

        context_locals = data.get("vars") or {}
        if isinstance(context_locals, (list, tuple)):
            context_locals = dict(enumerate(context_locals))
        elif not isinstance(context_locals, dict):
            context_locals = {}
        context_locals = trim_dict(context_locals)

        # extra data is used purely by internal systems,
        # so we dont trim it
        extra_data = data.get("data") or {}
        if isinstance(extra_data, (list, tuple)):
            extra_data = dict(enumerate(extra_data))

        kwargs = {
            "abs_path": trim(abs_path, 256),
            "filename": trim(filename, 256),
            "module": trim(data.get("module"), 256),
            "function": trim(data.get("function"), 256),
            "in_app": validate_bool(data.get("in_app"), False),
            "context_line": trim(data.get("context_line"), 256),
            # TODO(dcramer): trim pre/post_context
            "pre_context": data.get("pre_context"),
            "post_context": data.get("post_context"),
            "vars": context_locals,
            "data": extra_data,
        }

        if data.get("lineno") is not None:
            kwargs["lineno"] = int(data["lineno"])
        else:
            kwargs["lineno"] = None

        if data.get("colno") is not None:
            kwargs["colno"] = int(data["colno"])
        else:
            kwargs["colno"] = None

        return cls(**kwargs)
开发者ID:GrasIdevels,项目名称:sentry,代码行数:55,代码来源:stacktrace.py

示例6: to_python

    def to_python(cls, data):
        data = data.copy()

        kwargs = {
            'id': trim(data.pop('id', None), 128),
            'email': trim(data.pop('email', None), 128),
            'username': trim(data.pop('username', None), 128),
            'ip_address': validate_ip(data.pop('ip_address', None), False),
        }
        kwargs['data'] = trim_dict(data.pop('data', data))
        return cls(**kwargs)
开发者ID:alex-tools,项目名称:sentry,代码行数:11,代码来源:user.py

示例7: to_python

    def to_python(cls, data):
        data = data.copy()

        ident = data.pop('id', None)
        if ident is not None:
            ident = trim(six.text_type(ident), 128)

        try:
            email = trim(validate_email(data.pop('email', None), False), MAX_EMAIL_FIELD_LENGTH)
        except ValueError:
            raise InterfaceValidationError("Invalid value for 'email'")

        username = data.pop('username', None)
        if username is not None:
            username = trim(six.text_type(username), 128)

        name = data.pop('name', None)
        if name is not None:
            name = trim(six.text_type(name), 128)

        try:
            ip_address = validate_ip(data.pop('ip_address', None), False)
        except ValueError:
            raise InterfaceValidationError("Invalid value for 'ip_address'")

        geo = data.pop('geo', None)
        if not geo and ip_address:
            geo = Geo.from_ip_address(ip_address)
        elif geo:
            geo = Geo.to_python(geo)

        extra_data = data.pop('data', None)
        if not isinstance(extra_data, dict):
            extra_data = {}
        extra_data.update(data)

        # TODO(dcramer): patch in fix to deal w/ old data but not allow new
        # if not (ident or email or username or ip_address):
        #     raise ValueError('No identifying value')

        kwargs = {
            'id': ident,
            'email': email,
            'username': username,
            'ip_address': ip_address,
            'name': name,
            'geo': geo,
            'data': trim_dict(extra_data)
        }

        return cls(**kwargs)
开发者ID:Kayle009,项目名称:sentry,代码行数:51,代码来源:user.py

示例8: to_python

    def to_python(cls, data):
        data = data.copy()

        extra_data = data.pop('data', data)
        if not isinstance(extra_data, dict):
            extra_data = {}

        kwargs = {
            'id': trim(data.pop('id', None), 128),
            'email': trim(data.pop('email', None), 128),
            'username': trim(data.pop('username', None), 128),
            'ip_address': validate_ip(data.pop('ip_address', None), False),
        }

        kwargs['data'] = trim_dict(extra_data)
        return cls(**kwargs)
开发者ID:KinKir,项目名称:sentry,代码行数:16,代码来源:user.py

示例9: to_python

    def to_python(cls, data):
        data = data.copy()

        extra_data = data.pop("data", data)
        if not isinstance(extra_data, dict):
            extra_data = {}

        ident = trim(data.pop("id", None), 128)
        email = trim(validate_email(data.pop("email", None), False), 128)
        username = trim(data.pop("username", None), 128)
        ip_address = validate_ip(data.pop("ip_address", None), False)

        if not (ident or email or username or ip_address):
            raise ValueError("No identifying value")

        kwargs = {"id": ident, "email": email, "username": username, "ip_address": ip_address}

        kwargs["data"] = trim_dict(extra_data)
        return cls(**kwargs)
开发者ID:vitaliyf,项目名称:sentry,代码行数:19,代码来源:user.py

示例10: to_python

    def to_python(cls, data):
        is_valid, errors = validate_and_default_interface(data, cls.path)
        if not is_valid:
            raise InterfaceValidationError("Invalid device")

        data = data.copy()

        extra_data = data.pop('data', data)
        name = trim(data.pop('name'), 64)
        version = trim(data.pop('version'), 64)
        build = trim(data.pop('build', None), 64)

        kwargs = {
            'name': name,
            'version': version,
            'build': build,
            'data': trim_dict(extra_data),
        }
        return cls(**kwargs)
开发者ID:alexandrul,项目名称:sentry,代码行数:19,代码来源:device.py

示例11: to_python

    def to_python(cls, data):
        data = data.copy()

        extra_data = data.pop('data', data)
        if not isinstance(extra_data, dict):
            extra_data = {}

        ident = trim(data.pop('id', None), 128)
        if ident:
            ident = six.text_type(ident)
        try:
            email = trim(validate_email(data.pop('email', None), False), MAX_EMAIL_FIELD_LENGTH)
        except ValueError:
            raise InterfaceValidationError("Invalid value for 'email'")

        username = trim(data.pop('username', None), 128)
        if username:
            username = six.text_type(username)

        name = trim(data.pop('name', None), 128)
        if name:
            name = six.text_type(name)

        try:
            ip_address = validate_ip(data.pop('ip_address', None), False)
        except ValueError:
            raise InterfaceValidationError("Invalid value for 'ip_address'")

        # TODO(dcramer): patch in fix to deal w/ old data but not allow new
        # if not (ident or email or username or ip_address):
        #     raise ValueError('No identifying value')

        kwargs = {
            'id': ident,
            'email': email,
            'username': username,
            'ip_address': ip_address,
            'name': name,
        }

        kwargs['data'] = trim_dict(extra_data)
        return cls(**kwargs)
开发者ID:duanshuaimin,项目名称:sentry,代码行数:42,代码来源:user.py

示例12: to_python

    def to_python(cls, data):
        data = data.copy()

        extra_data = data.pop('data', data)
        if not isinstance(extra_data, dict):
            extra_data = {}

        ident = trim(data.pop('id', None), 128)
        email = trim(validate_email(data.pop('email', None), False), 128)
        username = trim(data.pop('username', None), 128)
        ip_address = validate_ip(data.pop('ip_address', None), False)

        assert ident or email or username or ip_address

        kwargs = {
            'id': ident,
            'email': email,
            'username': username,
            'ip_address': ip_address,
        }

        kwargs['data'] = trim_dict(extra_data)
        return cls(**kwargs)
开发者ID:Natim,项目名称:sentry,代码行数:23,代码来源:user.py

示例13: normalize

    def normalize(self):
        # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip
        # First we pull out our top-level (non-data attr) kwargs
        data = self.data

        if not isinstance(data.get('level'), (six.string_types, int)):
            data['level'] = logging.ERROR
        elif data['level'] not in LOG_LEVELS:
            data['level'] = logging.ERROR

        if not data.get('logger'):
            data['logger'] = DEFAULT_LOGGER_NAME
        else:
            logger = trim(data['logger'].strip(), 64)
            if TagKey.is_valid_key(logger):
                data['logger'] = logger
            else:
                data['logger'] = DEFAULT_LOGGER_NAME

        if data.get('platform'):
            data['platform'] = trim(data['platform'], 64)

        timestamp = data.get('timestamp')
        if not timestamp:
            timestamp = timezone.now()

        if isinstance(timestamp, datetime):
            # We must convert date to local time so Django doesn't mess it up
            # based on TIME_ZONE
            if settings.TIME_ZONE:
                if not timezone.is_aware(timestamp):
                    timestamp = timestamp.replace(tzinfo=timezone.utc)
            elif timezone.is_aware(timestamp):
                timestamp = timestamp.replace(tzinfo=None)
            timestamp = float(timestamp.strftime('%s'))

        data['timestamp'] = timestamp

        if not data.get('event_id'):
            data['event_id'] = uuid4().hex

        data.setdefault('message', '')
        data.setdefault('culprit', None)
        data.setdefault('time_spent', None)
        data.setdefault('server_name', None)
        data.setdefault('site', None)
        data.setdefault('checksum', None)
        data.setdefault('fingerprint', None)
        data.setdefault('platform', None)
        data.setdefault('environment', None)
        data.setdefault('extra', {})
        data.setdefault('errors', [])

        tags = data.get('tags')
        if not tags:
            tags = []
        # full support for dict syntax
        elif isinstance(tags, dict):
            tags = tags.items()
        # prevent [tag, tag, tag] (invalid) syntax
        elif not all(len(t) == 2 for t in tags):
            tags = []
        else:
            tags = list(tags)

        data['tags'] = []
        for key, value in tags:
            key = six.text_type(key).strip()
            value = six.text_type(value).strip()
            if not (key and value):
                continue

            data['tags'].append((key, value))

        if not isinstance(data['extra'], dict):
            # throw it away
            data['extra'] = {}

        trim_dict(
            data['extra'], max_size=settings.SENTRY_MAX_EXTRA_VARIABLE_SIZE)

        # TODO(dcramer): more of validate data needs stuffed into the manager
        for key in data.keys():
            if key in CLIENT_RESERVED_ATTRS:
                continue

            value = data.pop(key)

            try:
                interface = get_interface(key)()
            except ValueError:
                continue

            try:
                inst = interface.to_python(value)
                data[inst.get_path()] = inst.to_json()
            except Exception:
                pass

        data['version'] = self.version
#.........这里部分代码省略.........
开发者ID:delkyd,项目名称:sentry,代码行数:101,代码来源:event_manager.py

示例14: normalize


#.........这里部分代码省略.........
                errors.append({'type': EventError.INVALID_DATA, 'name': k, 'value': value})

        # Additional data coercion and defaulting
        level = data.get('level') or DEFAULT_LOG_LEVEL
        if isinstance(level, int) or (isinstance(level, six.string_types) and level.isdigit()):
            level = LOG_LEVELS.get(int(level), DEFAULT_LOG_LEVEL)
        data['level'] = LOG_LEVELS_MAP.get(level, LOG_LEVELS_MAP[DEFAULT_LOG_LEVEL])

        if data.get('dist') and not data.get('release'):
            data['dist'] = None

        timestamp = data.get('timestamp')
        if not timestamp:
            timestamp = timezone.now()

        # TODO (alex) can this all be replaced by utcnow?
        # it looks like the only time that this would even be hit is when timestamp
        # is not defined, as the earlier process_timestamp already converts existing
        # timestamps to floats.
        if isinstance(timestamp, datetime):
            # We must convert date to local time so Django doesn't mess it up
            # based on TIME_ZONE
            if settings.TIME_ZONE:
                if not timezone.is_aware(timestamp):
                    timestamp = timestamp.replace(tzinfo=timezone.utc)
            elif timezone.is_aware(timestamp):
                timestamp = timestamp.replace(tzinfo=None)
            timestamp = float(timestamp.strftime('%s'))

        data['timestamp'] = timestamp
        data['received'] = float(timezone.now().strftime('%s'))

        data.setdefault('checksum', None)
        data.setdefault('culprit', None)
        data.setdefault('dist', None)
        data.setdefault('environment', None)
        data.setdefault('extra', {})
        data.setdefault('fingerprint', None)
        data.setdefault('logger', DEFAULT_LOGGER_NAME)
        data.setdefault('platform', None)
        data.setdefault('server_name', None)
        data.setdefault('site', None)
        data.setdefault('tags', [])
        data.setdefault('transaction', None)

        # Fix case where legacy apps pass 'environment' as a tag
        # instead of a top level key.
        # TODO (alex) save() just reinserts the environment into the tags
        if not data.get('environment'):
            tagsdict = dict(data['tags'])
            if 'environment' in tagsdict:
                data['environment'] = tagsdict['environment']
                del tagsdict['environment']
                data['tags'] = tagsdict.items()

        # the SDKs currently do not describe event types, and we must infer
        # them from available attributes
        data['type'] = eventtypes.infer(data).key
        data['version'] = self.version

        exception = data.get('sentry.interfaces.Exception')
        stacktrace = data.get('sentry.interfaces.Stacktrace')
        if exception and len(exception['values']) == 1 and stacktrace:
            exception['values'][0]['stacktrace'] = stacktrace
            del data['sentry.interfaces.Stacktrace']

        # Exception mechanism needs SDK information to resolve proper names in
        # exception meta (such as signal names). "SDK Information" really means
        # the operating system version the event was generated on. Some
        # normalization still works without sdk_info, such as mach_exception
        # names (they can only occur on macOS).
        if exception:
            sdk_info = get_sdk_from_event(data)
            for ex in exception['values']:
                if 'mechanism' in ex:
                    normalize_mechanism_meta(ex['mechanism'], sdk_info)

        # If there is no User ip_addres, update it either from the Http interface
        # or the client_ip of the request.
        auth = request_env.get('auth')
        is_public = auth and auth.is_public
        add_ip_platforms = ('javascript', 'cocoa', 'objc')

        http_ip = data.get('sentry.interfaces.Http', {}).get('env', {}).get('REMOTE_ADDR')
        if http_ip:
            data.setdefault('sentry.interfaces.User', {}).setdefault('ip_address', http_ip)
        elif client_ip and (is_public or data.get('platform') in add_ip_platforms):
            data.setdefault('sentry.interfaces.User', {}).setdefault('ip_address', client_ip)

        # Trim values
        data['logger'] = trim(data['logger'].strip(), 64)
        trim_dict(data['extra'], max_size=settings.SENTRY_MAX_EXTRA_VARIABLE_SIZE)

        if data['culprit']:
            data['culprit'] = trim(data['culprit'], MAX_CULPRIT_LENGTH)

        if data['transaction']:
            data['transaction'] = trim(data['transaction'], MAX_CULPRIT_LENGTH)

        return data
开发者ID:mjumbewu,项目名称:sentry,代码行数:101,代码来源:event_manager.py

示例15: normalize_event_data

    def normalize_event_data(self, data):
        # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip
        # First we pull out our top-level (non-data attr) kwargs
        if not isinstance(data.get('level'), (basestring, int)):
            data['level'] = logging.ERROR
        elif data['level'] not in LOG_LEVELS:
            data['level'] = logging.ERROR

        if not data.get('logger'):
            data['logger'] = DEFAULT_LOGGER_NAME
        else:
            data['logger'] = trim(data['logger'], 64)

        if data.get('platform'):
            data['platform'] = trim(data['platform'], 64)

        timestamp = data.get('timestamp')
        if not timestamp:
            timestamp = timezone.now()

        # We must convert date to local time so Django doesn't mess it up
        # based on TIME_ZONE
        if settings.TIME_ZONE:
            if not timezone.is_aware(timestamp):
                timestamp = timestamp.replace(tzinfo=timezone.utc)
        elif timezone.is_aware(timestamp):
            timestamp = timestamp.replace(tzinfo=None)
        data['timestamp'] = timestamp

        if not data.get('event_id'):
            data['event_id'] = uuid.uuid4().hex

        data.setdefault('message', None)
        data.setdefault('culprit', None)
        data.setdefault('time_spent', None)
        data.setdefault('server_name', None)
        data.setdefault('site', None)
        data.setdefault('checksum', None)
        data.setdefault('platform', None)
        data.setdefault('extra', {})

        tags = data.get('tags')
        if not tags:
            tags = []
        # full support for dict syntax
        elif isinstance(tags, dict):
            tags = tags.items()
        # prevent [tag, tag, tag] (invalid) syntax
        elif not all(len(t) == 2 for t in tags):
            tags = []
        else:
            tags = list(tags)

        data['tags'] = tags

        if not isinstance(data['extra'], dict):
            # throw it away
            data['extra'] = {}

        trim_dict(
            data['extra'], max_size=settings.SENTRY_MAX_EXTRA_VARIABLE_SIZE)

        # TODO: each interface should describe its own normalization logic
        if 'sentry.interfaces.Exception' in data:
            if 'values' not in data['sentry.interfaces.Exception']:
                data['sentry.interfaces.Exception'] = {
                    'values': [data['sentry.interfaces.Exception']]
                }

            # convert stacktrace + exception into expanded exception
            if 'sentry.interfaces.Stacktrace' in data:
                data['sentry.interfaces.Exception']['values'][0]['stacktrace'] = data.pop('sentry.interfaces.Stacktrace')

            for exc_data in data['sentry.interfaces.Exception']['values']:
                for key in ('type', 'module', 'value'):
                    value = exc_data.get(key)
                    if value:
                        exc_data[key] = trim(value)

                if exc_data.get('stacktrace'):
                    trim_frames(exc_data['stacktrace'])
                    for frame in exc_data['stacktrace']['frames']:
                        stack_vars = frame.get('vars', {})
                        trim_dict(stack_vars)
                        for key, value in frame.iteritems():
                            if key not in ('vars', 'data'):
                                frame[key] = trim(value)

        if 'sentry.interfaces.Stacktrace' in data:
            trim_frames(data['sentry.interfaces.Stacktrace'])
            for frame in data['sentry.interfaces.Stacktrace']['frames']:
                stack_vars = frame.get('vars', {})
                trim_dict(stack_vars)
                for key, value in frame.iteritems():
                    if key not in ('vars', 'data'):
                        frame[key] = trim(value)

        if 'sentry.interfaces.Message' in data:
            msg_data = data['sentry.interfaces.Message']
            trim(msg_data['message'], 1024)
#.........这里部分代码省略.........
开发者ID:Tug,项目名称:sentry,代码行数:101,代码来源:manager.py


注:本文中的sentry.utils.safe.trim_dict函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。