本文整理汇总了Python中swift.common.utils.cache_from_env函数的典型用法代码示例。如果您正苦于以下问题:Python cache_from_env函数的具体用法?Python cache_from_env怎么用?Python cache_from_env使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了cache_from_env函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Python代码示例。
示例1: __init__
def __init__(self, path, req):
# Database defination
#self.conn = MySQLdb.connect(host="127.0.0.1", user="root", passwd='root', db="auth", charset="utf8")
#self.cur = self.conn.cursor()
self.mc_meta = cache_from_env(req.environ)
obj = self.get_conobj_from_path(path)
#obj = self.get_objname_from_path(path)
if self.mc_meta.get(path):
self.object_id, self.object_name, self.parent_secl_id, self.seclevel, self.path, self.response = self.mc_meta.get(path).split(',')
else:
meta = self.get_metadata_from_objname(obj)
if meta:
self.object_id = meta['object_id']
self.object_name = meta['object_name'].encode("utf8")
self.parent_secl_id = meta['parent_secl_id']
self.seclevel = meta['obj_seclevel']
self.author = meta['author'].encode("utf8") if meta['author'] else None
self.path = meta['path'].encode("utf8")
self.subject = meta['subject'].encode("utf8") if meta['subject'] else None
self.description = meta['description'].encode("utf8") if meta['description'] else None
self.source = meta['source'].encode("utf8") if meta['source'] else None
self.response = 'True'
self.mc_meta.set(self.path, (('%s,%s,%s,%s,%s,%s') % (self.object_id, self.object_name, self.parent_secl_id, self.seclevel, self.path, self.response)))
elif not self.response:
self.response = ['Forbidden']
开发者ID:hbhdytf,项目名称:mac2,代码行数:25,代码来源:mac.py
示例2: __call__
def __call__(self, env, start_response):
"""
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
try:
if self.memcache is None:
self.memcache = cache_from_env(env)
# Remove any x-backend-* headers since those are reserved for use
# by backends communicating with each other; no end user should be
# able to send those into the cluster.
for key in list(k for k in env if k.startswith('HTTP_X_BACKEND_')):
del env[key]
req = self.update_request(Request(env))
return self.handle_request(req)(env, start_response)
except UnicodeError:
err = HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL')
return err(env, start_response)
except (Exception, Timeout):
start_response('500 Server Error',
[('Content-Type', 'text/plain')])
return ['Internal server error.\n']
开发者ID:afliu,项目名称:swift,代码行数:26,代码来源:server.py
示例3: handle_quota_object
def handle_quota_object(self, env, start_response, version, account,
container, obj):
""" Handle quota of container usage and object count. """
memcache_client = cache_from_env(env)
object_size = int(env.get('CONTENT_LENGTH') or 0)
container_count, quota_level = self._get_account_meta(
env, version, account, memcache_client)
try:
container_usage_quota = self.container_usage[quota_level]
object_count_quota = self.object_count[quota_level]
except Exception:
self.logger.warn('Invalid quota_leve %s/%s quota_level[%s].' % (
account, container, quota_level))
container_usage_quota = None
object_count_quota = None
container_usage, object_count = self._get_container_meta(
env, version, account, container, memcache_client)
if container_usage_quota and container_usage >= container_usage_quota:
self.logger.notice("Container usage over quota, "
"request[PUT %s/%s/%s], container_usage[%s] "
"object_size[%s] quota[%s]" % (
account, container, obj, container_usage,
object_size, container_usage_quota))
return HTTPForbidden(body="The usage of container is over quota")(
env, start_response)
elif container_usage_quota and (container_usage + object_size >
container_usage_quota):
self.logger.notice("Container usage over quota, "
"request[PUT %s/%s/%s], container_usage[%s] "
"object_size[%s] quota[%s]" % (
account, container, obj, container_usage,
object_size, container_usage_quota))
return HTTPForbidden(body="The usage of container is over quota")(
env, start_response)
elif object_count_quota and object_count + 1 > object_count_quota:
self.logger.notice("Object count over quota, request[PUT %s/%s/%s],"
"object_count[%s] quota[%s]" % (
account, container, obj, object_count + 1,
object_count_quota))
return HTTPForbidden(body="The count of object is over quota")(
env, start_response)
elif self.precise_mode and memcache_client:
res = [None, None, None]
result_code = None
def _start_response(response_status, response_headers,
exc_info=None):
res[0] = response_status
res[1] = response_headers
res[2] = exc_info
resp = self.app(env, _start_response)
result_code = self._get_status_int(res[0])
if is_success(result_code):
memcache_client.delete(
get_container_memcache_key(account, container))
start_response(res[0], res[1], res[2])
return resp
else:
return self.app(env, start_response)
开发者ID:NewpTone,项目名称:StackLab-swift,代码行数:60,代码来源:quota.py
示例4: __call__
def __call__(self, env, start_response):
"""
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
try:
if self.memcache is None:
self.memcache = cache_from_env(env, True)
#更新headers的x-auth-token部分
req = self.update_request(Request(env))
#根据path的不同请求返回不同的controller
#最终会调用swob.Response.__call__方法处理这个wsig
return self.handle_request(req)(env, start_response)
except UnicodeError:
err = HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL')
return err(env, start_response)
except (Exception, Timeout):
start_response('500 Server Error',
[('Content-Type', 'text/plain')])
return ['Internal server error.\n']
开发者ID:sunzz679,项目名称:swift-2.4.0--source-read,代码行数:26,代码来源:server.py
示例5: handle_delete
def handle_delete(self, env, start_response, version, account, container,
obj):
""" Handle delete request. """
memcache_client = cache_from_env(env)
if not memcache_client:
return self.app(env, start_response)
res = [None, None, None]
result_code = None
def _start_response(response_status, response_headers, exc_info=None):
res[0] = response_status
res[1] = response_headers
res[2] = exc_info
resp = self.app(env, _start_response)
result_code = self._get_status_int(res[0])
try:
if is_success(result_code):
if obj:
memcache_client.delete(
get_container_memcache_key(account, container))
else:
memcache_client.delete(get_account_memcache_key(account))
except Exception, err:
self.logger.error(
'Error in [Quota] delete cache: %s' % (err.message))
开发者ID:NewpTone,项目名称:StackLab-swift,代码行数:27,代码来源:quota.py
示例6: __call__
def __call__(self, env, start_response):
"""
Main hook into the WSGI paste.deploy filter/app pipeline.
:param env: The WSGI environment dict.
:param start_response: The WSGI start_response hook.
"""
env["staticweb.start_time"] = time.time()
try:
(version, account, container, obj) = split_path(env["PATH_INFO"], 2, 4, True)
except ValueError:
return self.app(env, start_response)
if env["REQUEST_METHOD"] in ("PUT", "POST") and container and not obj:
memcache_client = cache_from_env(env)
if memcache_client:
memcache_key = "/staticweb/%s/%s/%s" % (version, account, container)
memcache_client.delete(memcache_key)
return self.app(env, start_response)
if env["REQUEST_METHOD"] not in ("HEAD", "GET"):
return self.app(env, start_response)
if env.get("REMOTE_USER") and env.get("HTTP_X_WEB_MODE", "f").lower() not in TRUE_VALUES:
return self.app(env, start_response)
if not container:
return self.app(env, start_response)
context = _StaticWebContext(self, version, account, container, obj)
if obj:
return context.handle_object(env, start_response)
return context.handle_container(env, start_response)
开发者ID:ngtuna,项目名称:swift,代码行数:28,代码来源:staticweb.py
示例7: __call__
def __call__(self, env, start_response):
"""
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
print '**** in __call__ of proxy server start *********'
print 'env',env
print 'start_response',start_response
try:
if self.memcache is None:
self.memcache = cache_from_env(env, True)
req = self.update_request(Request(env))
print '**** in __call__ of proxy server end by returning self.handle_request(req)(env, start_response) *********'
return self.handle_request(req)(env, start_response)
except UnicodeError:
err = HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL')
return err(env, start_response)
except (Exception, Timeout):
start_response('500 Server Error',
[('Content-Type', 'text/plain')])
return ['Internal server error.\n']
开发者ID:jannatunnoor,项目名称:test_swift,代码行数:25,代码来源:server.py
示例8: get_container_info
def get_container_info(env, app, swift_source=None):
"""
Get the info structure for a container, based on env and app.
This is useful to middlewares.
"""
cache = cache_from_env(env)
if not cache:
return None
(version, account, container, obj) = \
split_path(env['PATH_INFO'], 2, 4, True)
cache_key = get_container_memcache_key(account, container)
# Use a unique environment cache key per container. If you copy this env
# to make a new request, it won't accidentally reuse the old container info
env_key = 'swift.%s' % cache_key
if env_key not in env:
container_info = cache.get(cache_key)
if not container_info:
resp = make_pre_authed_request(
env, 'HEAD', '/%s/%s/%s' % (version, account, container),
swift_source=swift_source,
).get_response(app)
container_info = headers_to_container_info(
resp.headers, resp.status_int)
env[env_key] = container_info
return env[env_key]
开发者ID:hanxinboy,项目名称:swift,代码行数:25,代码来源:base.py
示例9: __call__
def __call__(self, env, start_response):
"""
这是 proxy server 的入口,上层 middleware 将参数传到这里进入 proxy server 的处理流程。
+ 最终返回的时候调用的是 swift.common.swob.Response。
+ 在 Response 里会调用 start_response 函数(返回 head),并返回(body)。
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
try:
if self.memcache is None:
self.memcache = cache_from_env(env, True)
req = self.update_request(Request(env))
# 下列返回的值中,self.handle_request(req)为一个Response类的实例。
# Response类包含方法 __call__(evn,start_response)
return self.handle_request(req)(env, start_response)
except UnicodeError:
err = HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL')
return err(env, start_response)
except (Exception, Timeout):
start_response('500 Server Error',
[('Content-Type', 'text/plain')])
return ['Internal server error.\n']
开发者ID:laventech,项目名称:swift,代码行数:27,代码来源:server.py
示例10: __init__
def __init__(self, token=None, username=None, request=None):
# Database defination
self.conn = MySQLdb.connect(host="127.0.0.1", user="root", passwd="root", db="auth", charset="utf8")
self.cur = self.conn.cursor()
self.mc_user = cache_from_env(request.environ)
# Initialze user information by token or usernames
if token is None and username is None:
self.denied_response("token")
# TO DO: get user from db (web update user, not read from cache , temparily )
if self.mc_user.get(username) and False:
self.tu_id, self.username, self.seclevel, self.login_name, self.response = self.mc_user.get(username).split(
","
)
else:
if token:
info = self.get_user_info_from_token(token=token)
elif username:
info = self.get_user_info_from_db(user_name=username)
if info:
# set each info
self.tu_id = info["tu_id"]
self.username = info["username"]
self.login_name = info["login_name"]
self.seclevel = info["seclevel"]
self.email = info["email"]
self.password = info["password"]
self.mobile = info["mobile"]
self.response = "True"
self.mc_user.set(
self.username,
(("%s,%s,%s,%s,%s") % (self.tu_id, self.username, self.seclevel, self.login_name, self.response)),
)
elif not self.response:
self.response = ["Forbidden"]
开发者ID:hbhdytf,项目名称:mac2,代码行数:34,代码来源:mac.py
示例11: __call__
def __call__(self, env, start_response):
if self.enable_caching:
self.memcache = cache_from_env(env)
else:
self.memcache = None
start_time = time.time()
req = Request(env)
self.logger.txn_id = req.headers.get('x-trans-id', None)
if not check_utf8(req.path_info):
res = HTTPPreconditionFailed(body='Invalid UTF8')
else:
try:
if hasattr(self, req.method):
res = getattr(self, req.method)(req)
else:
res = HTTPMethodNotAllowed()
except Exception:
self.logger.exception(_('ERROR __call__ error with %(method)s'
' %(path)s '), {'method': req.method, 'path': req.path})
res = HTTPInternalServerError(body=traceback.format_exc())
trans_time = '%.4f' % (time.time() - start_time)
log_message = '%s - - [%s] "%s %s" %s %s "%s" "%s" "%s" %s' % (
req.remote_addr,
time.strftime('%d/%b/%Y:%H:%M:%S +0000',
time.gmtime()),
req.method, req.path,
res.status.split()[0], res.content_length or '-',
req.headers.get('x-trans-id', '-'),
req.referer or '-', req.user_agent or '-',
trans_time)
if req.method.upper() == 'REPLICATE':
self.logger.debug(log_message)
else:
self.logger.info(log_message)
return res(env, start_response)
开发者ID:Gaurav-Gangalwar,项目名称:UFO,代码行数:35,代码来源:server.py
示例12: __call__
def __call__(self, env, start_response):
"""
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
try:
if self.memcache is None:
self.memcache = cache_from_env(env)
req = self.update_request(Request(env))
return self.handle_request(req)(env, start_response)
except UnicodeError:
err = HTTPPreconditionFailed(
request=req, body='Invalid UTF8 or contains NULL')
return err(env, start_response)
except (Exception, Timeout):
# P3
fp = open("/tmp/dump","a")
fp.write("====== status 500 in __call__\n")
fp.write(traceback.format_exc())
fp.write("====== done\n")
fp.close()
start_response('500 Server Error',
[('Content-Type', 'text/plain')])
return ['Internal server error.\n']
开发者ID:kururu-lu,项目名称:swift-lfs,代码行数:27,代码来源:server.py
示例13: __call__
def __call__(self, env, start_response):
"""
Main hook into the WSGI paste.deploy filter/app pipeline.
:param env: The WSGI environment dict.
:param start_response: The WSGI start_response hook.
"""
env['staticweb.start_time'] = time.time()
try:
(self.version, self.account, self.container, self.obj) = \
split_path(env['PATH_INFO'], 2, 4, True)
except ValueError:
return self.app(env, start_response)
memcache_client = cache_from_env(env)
if memcache_client:
if env['REQUEST_METHOD'] in ('PUT', 'POST'):
if not self.obj and self.container:
memcache_key = '/staticweb/%s/%s/%s' % \
(self.version, self.account, self.container)
memcache_client.delete(memcache_key)
return self.app(env, start_response)
if (env['REQUEST_METHOD'] not in ('HEAD', 'GET') or
(env.get('REMOTE_USER') and
env.get('HTTP_X_WEB_MODE', 'f').lower() not in TRUE_VALUES) or
(not env.get('REMOTE_USER') and
env.get('HTTP_X_WEB_MODE', 't').lower() not in TRUE_VALUES)):
return self.app(env, start_response)
if self.obj:
return self._handle_object(env, start_response)
elif self.container:
return self._handle_container(env, start_response)
return self.app(env, start_response)
开发者ID:OpenStack-Kha,项目名称:swift,代码行数:32,代码来源:staticweb.py
示例14: __call__
def __call__(self, env, start_response):
"""
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
req = Request(env)
if self.memcache_client is None:
# 在pipline中memcache middleware应该在前面
# memcache为每一个请求建立一个memcache client,并把这个client放入env中
self.memcache_client = cache_from_env(env)
if not self.memcache_client:
self.logger.warning(
_('Warning: Cannot ratelimit without a memcached client'))
return self.app(env, start_response)
try:
version, account, container, obj = req.split_path(1, 4, True)
except ValueError:
return self.app(env, start_response)
ratelimit_resp = self.handle_ratelimit(req, account, container, obj)
# ratelimit_resp 为 None 或者 Response 对象,Response 对象是可调用的。
# ratelimit 操作正常执行,或者不需要执行,返回 None,接着向下调用。
if ratelimit_resp is None:
return self.app(env, start_response)
else:
# ratelimit 执行失败,或者需要返回错误信息,返回 Response 对象。
# 不用向下调用,直接返回。
return ratelimit_resp(env, start_response)
开发者ID:laventech,项目名称:swift,代码行数:30,代码来源:ratelimit.py
示例15: _get_container_info
def _get_container_info(self, env):
"""
Retrieves x-container-meta-web-index, x-container-meta-web-error,
x-container-meta-web-listings, and x-container-meta-web-listings-css
from memcache or from the cluster and stores the result in memcache and
in self._index, self._error, self._listings, and self._listings_css.
:param env: The WSGI environment dict.
"""
self._index = self._error = self._listings = self._listings_css = None
memcache_client = cache_from_env(env)
if memcache_client:
memcache_key = "/staticweb/%s/%s/%s" % (self.version, self.account, self.container)
cached_data = memcache_client.get(memcache_key)
if cached_data:
(self._index, self._error, self._listings, self._listings_css) = cached_data
return
resp = make_pre_authed_request(
env, "HEAD", "/%s/%s/%s" % (self.version, self.account, self.container), agent=self.agent
).get_response(self.app)
if is_success(resp.status_int):
self._index = resp.headers.get("x-container-meta-web-index", "").strip()
self._error = resp.headers.get("x-container-meta-web-error", "").strip()
self._listings = resp.headers.get("x-container-meta-web-listings", "").strip()
self._listings_css = resp.headers.get("x-container-meta-web-listings-css", "").strip()
if memcache_client:
memcache_client.set(
memcache_key,
(self._index, self._error, self._listings, self._listings_css),
timeout=self.cache_timeout,
)
开发者ID:ngtuna,项目名称:swift,代码行数:31,代码来源:staticweb.py
示例16: __call__
def __call__(self, env, start_response):
"""
WSGI entry point.
Wraps env in swob.Request object and passes it down.
:param env: WSGI environment dictionary
:param start_response: WSGI callable
"""
req = Request(env)
if self.memcache_client is None:
self.memcache_client = cache_from_env(env)
if not self.memcache_client:
self.logger.warning(
_('Warning: Cannot ratelimit without a memcached client'))
return self.app(env, start_response)
try:
version, account, container, obj = req.split_path(1, 4, True)
except ValueError:
return self.app(env, start_response)
if not valid_api_version(version):
return self.app(env, start_response)
ratelimit_resp = self.handle_ratelimit(req, account, container, obj)
if ratelimit_resp is None:
return self.app(env, start_response)
else:
return ratelimit_resp(env, start_response)
开发者ID:jgmerritt,项目名称:swift,代码行数:26,代码来源:ratelimit.py
示例17: get_account_info
def get_account_info(env, app, swift_source=None):
"""
Get the info structure for an account, based on env and app.
This is useful to middlewares.
Note: This call bypasses auth. Success does not imply that the
request has authorization to the account_info.
"""
cache = cache_from_env(env)
if not cache:
return None
(version, account, _junk, _junk) = \
split_path(env['PATH_INFO'], 2, 4, True)
cache_key = get_account_memcache_key(account)
# Use a unique environment cache key per account. If you copy this env
# to make a new request, it won't accidentally reuse the old account info
env_key = 'swift.%s' % cache_key
if env_key not in env:
account_info = cache.get(cache_key)
if not account_info:
resp = make_pre_authed_request(
env, 'HEAD', '/%s/%s' % (version, account),
swift_source=swift_source,
).get_response(app)
account_info = headers_to_account_info(
resp.headers, resp.status_int)
env[env_key] = account_info
return env[env_key]
开发者ID:CiscoAS,项目名称:swift,代码行数:27,代码来源:base.py
示例18: __call__
def __call__(self, env, start_response):
"""
Main hook into the WSGI paste.deploy filter/app pipeline.
:param env: The WSGI environment dict.
:param start_response: The WSGI start_response hook.
"""
env['staticweb.start_time'] = time.time()
try:
(version, account, container, obj) = \
split_path(env['PATH_INFO'], 2, 4, True)
except ValueError:
return self.app(env, start_response)
if env['REQUEST_METHOD'] in ('PUT', 'POST') and container and not obj:
memcache_client = cache_from_env(env)
if memcache_client:
memcache_key = \
'/staticweb/%s/%s/%s' % (version, account, container)
memcache_client.delete(memcache_key)
return self.app(env, start_response)
if env['REQUEST_METHOD'] not in ('HEAD', 'GET'):
return self.app(env, start_response)
if env.get('REMOTE_USER') and \
not config_true_value(env.get('HTTP_X_WEB_MODE', 'f')):
return self.app(env, start_response)
if not container:
return self.app(env, start_response)
context = _StaticWebContext(self, version, account, container, obj)
if obj:
return context.handle_object(env, start_response)
return context.handle_container(env, start_response)
开发者ID:CiscoAS,项目名称:swift,代码行数:31,代码来源:staticweb.py
示例19: __call__
def __call__(self, env, start_response):
if not self.storage_domain:
return self.app(env, start_response)
given_domain = env['HTTP_HOST']
port = ''
if ':' in given_domain:
given_domain, port = given_domain.rsplit(':', 1)
if given_domain == self.storage_domain[1:]: # strip initial '.'
return self.app(env, start_response)
a_domain = given_domain
if not a_domain.endswith(self.storage_domain):
if self.memcache is None:
self.memcache = cache_from_env(env)
error = True
for tries in xrange(self.lookup_depth):
found_domain = None
if self.memcache:
memcache_key = ''.join(['cname-', a_domain])
found_domain = self.memcache.get(memcache_key)
if not found_domain:
ttl, found_domain = lookup_cname(a_domain)
if self.memcache:
memcache_key = ''.join(['cname-', given_domain])
self.memcache.set(memcache_key, found_domain,
timeout=ttl)
if found_domain is None or found_domain == a_domain:
# no CNAME records or we're at the last lookup
error = True
found_domain = None
break
elif found_domain.endswith(self.storage_domain):
# Found it!
self.logger.info(
_('Mapped %(given_domain)s to %(found_domain)s') %
{'given_domain': given_domain,
'found_domain': found_domain})
if port:
env['HTTP_HOST'] = ':'.join([found_domain, port])
else:
env['HTTP_HOST'] = found_domain
error = False
break
else:
# try one more deep in the chain
self.logger.debug(
_('Following CNAME chain for '
'%(given_domain)s to %(found_domain)s') %
{'given_domain': given_domain,
'found_domain': found_domain})
a_domain = found_domain
if error:
if found_domain:
msg = 'CNAME lookup failed after %d tries' % \
self.lookup_depth
else:
msg = 'CNAME lookup failed to resolve to a valid domain'
resp = HTTPBadRequest(request=Request(env), body=msg,
content_type='text/plain')
return resp(env, start_response)
return self.app(env, start_response)
开发者ID:ChicoTeam,项目名称:swift,代码行数:60,代码来源:cname_lookup.py
示例20: __call__
def __call__(self, env, start_response):
"""
Main hook into the WSGI paste.deploy filter/app pipeline.
:param env: The WSGI environment dict.
:param start_response: The WSGI start_response hook.
"""
try:
(version, account, container, obj) = \
split_path(env['PATH_INFO'], 2, 4, True)
except ValueError:
return self.app(env, start_response)
if not self._cache:
self._cache = cache_from_env(env)
# Don't handle non-GET requests.
if env['REQUEST_METHOD'] not in ('HEAD', 'GET'):
# flush cache if we expect the container metadata being changed.
if container and not obj and self._cache:
memcache_key = 'better_static/%s/%s' % (account, container)
self._cache.delete(memcache_key)
return self.app(env, start_response)
# If non-html was explicitly requested, don't bother trying to format
# the html
params = urlparse.parse_qs(env.get('QUERY_STRING', ''))
if 'format' in params and params['format'] != ['html']:
return self.app(env, start_response)
context = Context(self, env, account, container, obj)
return context(env, start_response)
开发者ID:CloudVPS,项目名称:better-staticweb,代码行数:35,代码来源:better_staticweb.py
注:本文中的swift.common.utils.cache_from_env函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论