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


Python MultiDict.items方法代码示例

本文整理汇总了Python中werkzeug.datastructures.MultiDict.items方法的典型用法代码示例。如果您正苦于以下问题:Python MultiDict.items方法的具体用法?Python MultiDict.items怎么用?Python MultiDict.items使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在werkzeug.datastructures.MultiDict的用法示例。


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

示例1: build_query_suffix

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def build_query_suffix(**repl):
    searching = repl.pop('_searching', False)

    normalized_version = str(g.version1) + (','+str(g.version2) if g.version2 else '')
    normalized_cursor = str(g.cursor) if g.cursor is not None else ''

    newquery = MultiDict(request.args)

    # unlike others, search may reset `v` (and try to redirect) according to the query,
    # but if the explicit `v` is set it should NOT alter that.
    if normalized_version and (searching or normalized_version != mappings.DEFAULT_VER):
        newquery['v'] = normalized_version
    else:
        newquery.poplist('v')
    if normalized_cursor:
        newquery['c'] = normalized_cursor
    else:
        newquery.poplist('c')

    kvs = [(k, v.encode('utf-8')) for k, v in newquery.items(multi=True) if k not in repl]
    kvs += [(k, unicode(v).encode('utf-8')) for k, v in repl.items() if v is not None]
    newquery = urllib.urlencode(kvs)
    if newquery:
        return '?' + newquery
    else:
        return ''
开发者ID:lifthrasiir,项目名称:bible.mearie.org,代码行数:28,代码来源:bible.py

示例2: IdentityInfo

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
class IdentityInfo(object):
    """Stores user identity information for the application.

    :param provider: The identity provider instance providing the data.
    :param identifier: A unique identifier string that can later be
                       used to retrieve identity information for the
                       same user.
    :param multipass_data: A dict containing additional data the
                           identity provider needs e.g. to refresh the
                           identity information for the same user,
                           without him authenticating again by keeping a
                           long-lived token.
    :param data: Any data the identity provider wants to pass on the
                 application.
    """

    def __init__(self, provider, identifier, multipass_data=None, **data):
        self.provider = provider
        self.identifier = text_type(identifier)
        if not provider.supports_refresh:
            assert multipass_data is None
            self.multipass_data = None
        else:
            self.multipass_data = dict(multipass_data or {}, _provider=provider.name)
        mapping = provider.settings.get('mapping')
        self.data = MultiDict(convert_provider_data(data, mapping or {}, self.provider.settings['identity_info_keys']))

    def __repr__(self):
        data = ', '.join('{}={!r}'.format(k, v) for k, v in sorted(self.data.items()))
        return '<IdentityInfo({}, {}, {})>'.format(self.provider, self.identifier, data or None)
开发者ID:OmeGak,项目名称:flask-multipass,代码行数:32,代码来源:data.py

示例3: get

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
    def get(self, parameters: MultiDict):
        # Prevent multikeys with for loop
        for default_key, default_value in self._defaults.items():
            parameters[default_key] = default_value

        parameters['service'] = self._service
        parameters['status'] = self._status

        # Prevent multikeys with for loop
        for forced_key, forced_value in self._forced.items():
            parameters[forced_key] = forced_value

        param_list = []
        for key, value in parameters.items(multi=True):
            param_list.append(('afs:{0}'.format(key), value))

        url = '{0}?{1}'.format(self.service_address, urlencode(param_list))
        logger.info('Antidot request: {}'.format(url))
        
        response = requests.get(url)
        object_response = response.json()

        if isinstance(object_response, dict):
            return self._response_class(Bunch(object_response))
        elif isinstance(object_response, list):
            return self._response_class(Bunch({
                DEFAULT_ACP_FEED_NAME: object_response
            }))
开发者ID:algoo,项目名称:python-antidot,代码行数:30,代码来源:request.py

示例4: _get_bound_parameters

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
 def _get_bound_parameters(self, parameters: MultiDict):
     for search_param_name, search_param_convert in self._bind.items():
         search_param_convert_name, search_param_convert_value \
             = search_param_convert
         for parameter_name, parameter_value in list(
                 parameters.items(True)):
             matches = re.search(search_param_name, parameter_name)
             if matches is not None:
                 # expression matches but no groups defined
                 if not matches.groups():
                     yield search_param_convert_name, \
                         search_param_convert_value.format(
                             value=parameter_value
                         )
                 # expression matches with groups defined
                 # e.g. ^([a-zA-Z-_]+)_foo$
                 else:
                     yield (
                         search_param_convert_name.format(
                             *matches.groups()
                         ),
                         search_param_convert_value.format(
                             *matches.groups(),
                             value=parameter_value
                         )
                     )
开发者ID:algoo,项目名称:python-antidot,代码行数:28,代码来源:manager.py

示例5: CardFormTest

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
class CardFormTest(FormTests):
    def setUp(self):
        from werkzeug.datastructures import MultiDict

        super(CardFormTest, self).setUp()
        self.Form = self._get_target_class()
        self.required_data = {
            'key': u'CMSIF-199',
            'title': u'You gotta lock that down',
            'backlog_date': u"06/11/2011",
            'category': u'Bug',
            'state': u'Doing',
            'team': u'Team 1',
        }
        self.post_data = MultiDict(self.required_data)

    def _get_target_class(self):
        from kardboard.forms import get_card_form
        return get_card_form(new=True)

    def _test_form(self, post_data):
        f = self.Form(post_data)
        f.validate()
        self.assertEquals(0, len(f.errors))

        card = self._get_card_class()()
        f.populate_obj(card)
        card.save()

        for key, value in self.post_data.items():
            self.assertNotEqual(
                None,
                getattr(card, key, None))

    def test_fields(self):
        self.optional_data = {
            'start_date': u'06/11/2011',
            'done_date': u'06/12/2011',
            'priority': u'2',
        }
        self.post_data.update(self.optional_data)
        self._test_form(self.post_data)

    def test_datetime_coercing(self):
        f = self.Form(self.post_data)
        data = f.backlog_date.data
        self.assertEqual(6, data.month)

    def test_key_uniqueness(self):
        klass = self._get_card_class()
        c = klass(**self.required_data)
        c.backlog_date = datetime.datetime.now()
        c.save()

        f = self.Form(self.post_data)
        f.validate()
        self.assertIn('key', f.errors.keys())
开发者ID:marksqrd,项目名称:kardboard-testing,代码行数:59,代码来源:test_forms.py

示例6: post

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
    def post(self):
        if not self.modify:
            abort(403)

        data = MultiDict(request.json).to_dict(False) if request.json is not None else request.form
        newdata = {}
        if data:
            for k, v in data.items():
                newdata[k] = v[0] if isinstance(v, (list, tuple)) and len(v) == 1 else v
        if self.is_mgo:
            current_session["data"].update(**data)
        else:
            current_session.update(**data)
        return jsonify(success=True, session=self.model_to_json(current_session))
开发者ID:UmaW5RTC,项目名称:JavaScript,代码行数:16,代码来源:blueprint.py

示例7: indico_request

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def indico_request(path):
    request_values = MultiDict(request.values)
    method = request_values.pop('_method', request.method).upper()
    params = request_values.items(multi=True)
    data = build_indico_request(path, params, app.config['INDICO_API_KEY'], app.config['INDICO_SECRET_KEY'])
    request_args = {'params': data} if method == 'GET' else {'data': data}
    try:
        response = requests.request(method, app.config['INDICO_URL'] + path, verify=False, **request_args)
    except requests.HTTPError as e:
        response = e.response
    except requests.ConnectionError as e:
        return 'text/plain', str(e)
    content_type = response.headers.get('Content-Type', '').split(';')[0]
    with closing(response):
        return content_type, response.text
开发者ID:DirkHoffmann,项目名称:indico,代码行数:17,代码来源:apiProxy.py

示例8: get_cors_headers

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def get_cors_headers(options, request_headers, request_method):
    origins_to_set = get_cors_origins(options, request_headers.get('Origin'))
    headers = MultiDict()

    if not origins_to_set:  # CORS is not enabled for this route
        return headers

    for origin in origins_to_set:
        headers.add(ACL_ORIGIN, origin)

    headers[ACL_EXPOSE_HEADERS] = options.get('expose_headers')

    if options.get('supports_credentials'):
        headers[ACL_CREDENTIALS] = 'true'  # case sensative

    # This is a preflight request
    # http://www.w3.org/TR/cors/#resource-preflight-requests
    if request_method == 'OPTIONS':
        acl_request_method = request_headers.get(ACL_REQUEST_METHOD, '').upper()

        # If there is no Access-Control-Request-Method header or if parsing
        # failed, do not set any additional headers
        if acl_request_method and acl_request_method in options.get('methods'):

            # If method is not a case-sensitive match for any of the values in
            # list of methods do not set any additional headers and terminate
            # this set of steps.
            headers[ACL_ALLOW_HEADERS] = get_allow_headers(options, request_headers.get(ACL_REQUEST_HEADERS))
            headers[ACL_MAX_AGE] = options.get('max_age')
            headers[ACL_METHODS] = options.get('methods')
        else:
            LOG.info("The request's Access-Control-Request-Method header does not match allowed methods. CORS headers will not be applied.")

    # http://www.w3.org/TR/cors/#resource-implementation
    if options.get('vary_header'):
        # Only set header if the origin returned will vary dynamically,
        # i.e. if we are not returning an asterisk, and there are multiple
        # origins that can be matched.
        if headers[ACL_ORIGIN] == '*':
            pass
        elif (len(options.get('origins')) > 1 or
              len(origins_to_set) > 1 or
              any(map(probably_regex, options.get('origins')))):
            headers.add('Vary', 'Origin')

    return MultiDict((k, v) for k, v in headers.items() if v)
开发者ID:Ddfulton,项目名称:SDE,代码行数:48,代码来源:core.py

示例9: response_headers

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def response_headers():
    """Returns a set of response headers from the query string """
    headers = MultiDict(request.args.items(multi=True))
    response = jsonify(headers.lists())

    while True:
        content_len_shown = response.headers['Content-Length']
        d = {}
        for key in response.headers.keys():
            value = response.headers.get_all(key)
            if len(value) == 1:
                value = value[0]
            d[key] = value
        response = jsonify(d)
        for key, value in headers.items(multi=True):
            response.headers.add(key, value)
        if response.headers['Content-Length'] == content_len_shown:
            break
    return response
开发者ID:paradisesunny,项目名称:httpbin,代码行数:21,代码来源:core.py

示例10: response_headers

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def response_headers():
    """Returns a set of response headers from the query string """
    headers = MultiDict(request.args.items(multi=True))
    response = jsonify(list(headers.lists()))

    while True:
        original_data = response.data
        d = {}
        for key in response.headers.keys():
            value = response.headers.get_all(key)
            if len(value) == 1:
                value = value[0]
            d[key] = value
        response = jsonify(d)
        for key, value in headers.items(multi=True):
            response.headers.add(key, value)
        response_has_changed = response.data != original_data
        if not response_has_changed:
            break
    return response
开发者ID:siddthota,项目名称:httpbin,代码行数:22,代码来源:core.py

示例11: response_headers

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def response_headers():
    """Returns a set of response headers from the query string.
    ---
    tags:
      - Response inspection
    parameters:
      - in: query
        name: freeform
        explode: true
        allowEmptyValue: true
        schema:
          type: object
          additionalProperties:
            type: string
        style: form
    produces:
      - application/json
    responses:
      200:
        description: Response headers
    """
    # Pending swaggerUI update
    # https://github.com/swagger-api/swagger-ui/issues/3850
    headers = MultiDict(request.args.items(multi=True))
    response = jsonify(list(headers.lists()))

    while True:
        original_data = response.data
        d = {}
        for key in response.headers.keys():
            value = response.headers.get_all(key)
            if len(value) == 1:
                value = value[0]
            d[key] = value
        response = jsonify(d)
        for key, value in headers.items(multi=True):
            response.headers.add(key, value)
        response_has_changed = response.data != original_data
        if not response_has_changed:
            break
    return response
开发者ID:Lucretiel,项目名称:httpbin,代码行数:43,代码来源:core.py

示例12: __init__

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
 def __init__(self, formdata=None, *args, **kwargs):
     if formdata is not None:
         formdata = MultiDict(formdata.items())
     super(AjaxForm, self).__init__(formdata, *args, **kwargs)
开发者ID:carriercomm,项目名称:Bookmark-v2,代码行数:6,代码来源:__init__.py

示例13: document_query

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def document_query(args, fields=DEFAULT_FIELDS, sources=None, lists=None,
                   facets=True):
    if not isinstance(args, MultiDict):
        args = MultiDict(args)
    qstr = args.get('q', '').strip()
    if len(qstr):
        filtered_q = {
            "bool": {
                "must": {
                    "multi_match": {
                        "query": qstr,
                        "fields": QUERY_FIELDS,
                        "type": "best_fields",
                        "cutoff_frequency": 0.0007,
                        "operator": "and",
                    },
                },
                "should": {
                    "multi_match": {
                        "query": qstr,
                        "fields": QUERY_FIELDS,
                        "type": "phrase"
                    },
                }
            }
        }
    else:
        filtered_q = {'match_all': {}}

    # entities filter
    for entity in args.getlist('entity'):
        cf = {'term': {'entities.id': entity}}
        filtered_q = add_filter(filtered_q, cf)

    for key, value in args.items():
        if not key.startswith('attribute-'):
            continue
        _, attr = key.split('attribute-', 1)
        af = {
            "nested": {
                "path": "attributes",
                "query": {
                    "bool": {
                        "must": [
                            {"term": {"attributes.name": attr}},
                            {"term": {"attributes.value": value}}
                        ]
                    }
                }
            }
        }
        filtered_q = add_filter(filtered_q, af)

    q = deepcopy(filtered_q)

    # collections filter
    if sources is not None:
        srcs = args.getlist('source') or sources
        srcs = [c for c in srcs if c in sources]
        if not len(srcs):
            srcs = ['none']
        cf = {'terms': {'collection': srcs}}
        q = add_filter(q, cf)

        all_coll_f = {'terms': {'collection': sources}}
        filtered_q = add_filter(filtered_q, all_coll_f)

    aggs = {}

    # query facets
    if facets:
        aggs = {
            'all': {
                'global': {},
                'aggs': {
                    'ftr': {
                        'filter': {'query': filtered_q},
                        'aggs': {
                            'collections': {
                                'terms': {'field': 'collection'}
                            }
                        }
                    }
                }
            }
        }

        for list_id in get_list_facets(args):
            if list_id not in lists:
                continue

            list_facet = {
                'nested': {
                    'path': 'entities'
                },
                'aggs': {
                    'inner': {
                        'filter': {'term': {'entities.list': list_id}},
                        'aggs': {
                            'entities': {
#.........这里部分代码省略.........
开发者ID:nightsh,项目名称:aleph,代码行数:103,代码来源:queries.py

示例14: test_multidict

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def test_multidict():
    """Multidict behavior"""
    md = MultiDict()
    assert isinstance(md, dict)

    mapping = [('a', 1), ('b', 2), ('a', 2), ('d', 3),
               ('a', 1), ('a', 3), ('d', 4), ('c', 3)]
    md = MultiDict(mapping)

    # simple getitem gives the first value
    assert md['a'] == 1
    assert md['c'] == 3
    assert_raises(KeyError, lambda: md['e'])
    assert md.get('a') == 1

    # list getitem
    assert md.getlist('a') == [1, 2, 1, 3]
    assert md.getlist('d') == [3, 4]
    # do not raise if key not found
    assert md.getlist('x') == []

    # simple setitem overwrites all values
    md['a'] = 42
    assert md.getlist('a') == [42]

    # list setitem
    md.setlist('a', [1, 2, 3])
    assert md['a'] == 1
    assert md.getlist('a') == [1, 2, 3]

    # verify that it does not change original lists
    l1 = [1, 2, 3]
    md.setlist('a', l1)
    del l1[:]
    assert md['a'] == 1

    # setdefault, setlistdefault
    assert md.setdefault('u', 23) == 23
    assert md.getlist('u') == [23]
    del md['u']

    assert md.setlistdefault('u', [-1, -2]) == [-1, -2]
    assert md.getlist('u') == [-1, -2]
    assert md['u'] == -1

    # delitem
    del md['u']
    assert_raises(KeyError, lambda: md['u'])
    del md['d']
    assert md.getlist('d') == []

    # keys, values, items, lists
    assert list(sorted(md.keys())) == ['a', 'b', 'c']
    assert list(sorted(md.iterkeys())) == ['a', 'b', 'c']

    assert list(sorted(md.values())) == [1, 2, 3]
    assert list(sorted(md.itervalues())) == [1, 2, 3]

    assert list(sorted(md.items())) == [('a', 1), ('b', 2), ('c', 3)]
    assert list(sorted(md.items(multi=True))) == \
           [('a', 1), ('a', 2), ('a', 3), ('b', 2), ('c', 3)]
    assert list(sorted(md.iteritems())) == [('a', 1), ('b', 2), ('c', 3)]
    assert list(sorted(md.iteritems(multi=True))) == \
           [('a', 1), ('a', 2), ('a', 3), ('b', 2), ('c', 3)]

    assert list(sorted(md.lists())) == [('a', [1, 2, 3]), ('b', [2]), ('c', [3])]
    assert list(sorted(md.iterlists())) == [('a', [1, 2, 3]), ('b', [2]), ('c', [3])]

    # copy method
    copy = md.copy()
    assert copy['a'] == 1
    assert copy.getlist('a') == [1, 2, 3]

    # update with a multidict
    od = MultiDict([('a', 4), ('a', 5), ('y', 0)])
    md.update(od)
    assert md.getlist('a') == [1, 2, 3, 4, 5]
    assert md.getlist('y') == [0]

    # update with a regular dict
    md = copy
    od = {'a': 4, 'y': 0}
    md.update(od)
    assert md.getlist('a') == [1, 2, 3, 4]
    assert md.getlist('y') == [0]

    # pop, poplist, popitem, popitemlist
    assert md.pop('y') == 0
    assert 'y' not in md
    assert md.poplist('a') == [1, 2, 3, 4]
    assert 'a' not in md
    assert md.poplist('missing') == []

    # remaining: b=2, c=3
    popped = md.popitem()
    assert popped in [('b', 2), ('c', 3)]
    popped = md.popitemlist()
    assert popped in [('b', [2]), ('c', [3])]

    # type conversion
#.........这里部分代码省略.........
开发者ID:d1on,项目名称:werkzeug,代码行数:103,代码来源:test_datastructures.py

示例15: test_multidict

# 需要导入模块: from werkzeug.datastructures import MultiDict [as 别名]
# 或者: from werkzeug.datastructures.MultiDict import items [as 别名]
def test_multidict():
    """Multidict behavior"""
    md = MultiDict()
    assert isinstance(md, dict)

    mapping = [('a', 1), ('b', 2), ('a', 2), ('d', 3),
               ('a', 1), ('a', 3), ('d', 4), ('c', 3)]
    md = MultiDict(mapping)

    # simple getitem gives the first value
    assert md['a'] == 1
    assert md['c'] == 3
    assert_raises(KeyError, lambda: md['e'])
    assert md.get('a') == 1

    # list getitem
    assert md.getlist('a') == [1, 2, 1, 3]
    assert md.getlist('d') == [3, 4]
    # do not raise if key not found
    assert md.getlist('x') == []

    # simple setitem overwrites all values
    md['a'] = 42
    assert md.getlist('a') == [42]

    # list setitem
    md.setlist('a', [1, 2, 3])
    assert md['a'] == 1
    assert md.getlist('a') == [1, 2, 3]

    # verify that it does not change original lists
    l1 = [1, 2, 3]
    md.setlist('a', l1)
    del l1[:]
    assert md['a'] == 1

    # setdefault, setlistdefault
    assert md.setdefault('u', 23) == 23
    assert md.getlist('u') == [23]
    del md['u']

    assert md.setlistdefault('u', [-1, -2]) == [-1, -2]
    assert md.getlist('u') == [-1, -2]
    assert md['u'] == -1

    # delitem
    del md['u']
    assert_raises(KeyError, lambda: md['u'])
    del md['d']
    assert md.getlist('d') == []

    # keys, values, items, lists
    assert list(sorted(md.keys())) == ['a', 'b', 'c']
    assert list(sorted(md.iterkeys())) == ['a', 'b', 'c']

    assert list(sorted(md.values())) == [1, 2, 3]
    assert list(sorted(md.itervalues())) == [1, 2, 3]

    assert list(sorted(md.items())) == [('a', 1), ('b', 2), ('c', 3)]
    assert list(sorted(md.items(multi=True))) == \
           [('a', 1), ('a', 2), ('a', 3), ('b', 2), ('c', 3)]
    assert list(sorted(md.iteritems())) == [('a', 1), ('b', 2), ('c', 3)]
    assert list(sorted(md.iteritems(multi=True))) == \
           [('a', 1), ('a', 2), ('a', 3), ('b', 2), ('c', 3)]

    assert list(sorted(md.lists())) == [('a', [1, 2, 3]), ('b', [2]), ('c', [3])]
    assert list(sorted(md.iterlists())) == [('a', [1, 2, 3]), ('b', [2]), ('c', [3])]

    # copy method
    copy = md.copy()
    assert copy['a'] == 1
    assert copy.getlist('a') == [1, 2, 3]

    # update with a multidict
    od = MultiDict([('a', 4), ('a', 5), ('y', 0)])
    md.update(od)
    assert md.getlist('a') == [1, 2, 3, 4, 5]
    assert md.getlist('y') == [0]

    # update with a regular dict
    md = copy
    od = {'a': 4, 'y': 0}
    md.update(od)
    assert md.getlist('a') == [1, 2, 3, 4]
    assert md.getlist('y') == [0]

    # pop, poplist, popitem, popitemlist
    assert md.pop('y') == 0
    assert 'y' not in md
    assert md.poplist('a') == [1, 2, 3, 4]
    assert 'a' not in md
    assert md.poplist('missing') == []

    # remaining: b=2, c=3
    popped = md.popitem()
    assert popped in [('b', 2), ('c', 3)]
    popped = md.popitemlist()
    assert popped in [('b', [2]), ('c', [3])]

    # type conversion
#.........这里部分代码省略.........
开发者ID:t11e,项目名称:werkzeug,代码行数:103,代码来源:test_datastructures.py


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