2021SC@SDUSC
seahub_db.py:主要是负责数据库初始化,以及数据库连接
def create_seahub_db_engine()#创建seahub数据库的连接
def ping_connection(dbapi_connection, connection_record, connection_proxy)
主要用来解决“MySQL已经中断”的问题,因为空闲太长时间,当MySQL服务器重启或池连接被MySQL服务器关闭时,MySQL会中断
def ping_connection(dbapi_connection, connection_record, connection_proxy): # pylint: disable=unused-argument
cursor = dbapi_connection.cursor()
try:
cursor.execute("SELECT 1")
cursor.close()
except:
logger.info('fail to ping database server, disposing all cached connections')
connection_proxy._pool.dispose() # pylint: disable=protected-access
# 引发DisconnectionError,因此池将创建一个新连接
raise DisconnectionError()
simple_dc.py:使用领域/用户名/密码映射的域控制器的实现 来自配置文件并使用共享路径作为领域名称,其中主要的类SimpleDomainController 满足 DomainController 的要求,因为 用于使用http_authenticator.HTTPAuthenticator 进行身份验证 WsgiDAV 应用程序。
文件结构及主要功能
class SimpleDomainController:
def __init__(self, wsgidav_app, config)#初始化
def __str__(self)#格式化
def _get_realm_entry(self, realm, user_name=None)#返回匹配的 user_map 条目(如果有,则回退到默认的 '*')
def get_domain_realm(self, path_info, environ)#将相对 url 解析为适当的领域名称
def require_authentication(self, realm, environ)#如果此领域需要身份验证,则返回 True(否则授予匿名访问权限)
def basic_auth_user(self, realm, user_name, password, environ)#如果此用户名/密码对对领域有效,则返回 True,否则返回 False。 用于基本认证
def supports_http_digest_auth(self)
def digest_auth_user(self, realm, user_name, environ)#计算摘要哈希 A1 部分
_dir_browser.py:处理集合上的 GET 请求以显示目录的 WSGI 中间件
def __init__(self, wsgidav_app, next_app, config):
super(WsgiDavDirBrowser, self).__init__(wsgidav_app, next_app, config)
self.htdocs_path = os.path.join(os.path.dirname(__file__), "htdocs")
# Add an additional read-only FS provider that serves the dir_browser assets
self.wsgidav_app.add_provider(ASSET_SHARE, self.htdocs_path, readonly=True)
# and make sure we have anonymous access there
config.get("simple_dc", {}).get("user_mapping", {}).setdefault(
ASSET_SHARE, True
)
# Prepare a Jinja2 template
templateLoader = FileSystemLoader(searchpath=self.htdocs_path)
templateEnv = Environment(loader=templateLoader)
self.template = templateEnv.get_template("template.html")
self.dir_config = config.get("dir_browser", {})
def _fail(self, value, context_info=None, src_exception=None, err_condition=None)#用于引发(并记录)DAVError 的包装器
def _fail(self, value, context_info=None, src_exception=None, err_condition=None):
"""Wrapper to raise (and log) DAVError."""
e = DAVError(value, context_info, src_exception, err_condition)
if self.verbose >= 4:
_logger.warning(
"Raising DAVError {}".format(
safe_re_encode(e.get_user_info(), sys.stdout.encoding)
)
)
raise e
couch_property_manager.py:实现一个基于 CouchDB 的属性管理器,包含一个类class CouchPropertyManager
主要方法
def _find(self, url):#返回路径的属性文档
# Query the permanent view to find a url
vr = self.db.view("properties/by_url", key=url, include_docs=True)
_logger.debug("find(%r) returned %s" % (url, len(vr)))
assert len(vr) <= 1, "Found multiple matches for %r" % url
for row in vr:
assert row.doc
return row.doc
return None
def _find_descendents(self, url):#返回 url 和所有子项的属性文档
#以前缀开头的 URL 的即席查询
map_fun = """function(doc) {
var url = doc.url + "/";
if(doc.type === 'properties' && url.indexOf('%s') === 0) {
emit(doc.url, { 'id': doc._id, 'url': doc.url });
}
}""" % (
url + "/"
)
vr = self.db.query(map_fun, include_docs=True)
for row in vr:
yield row.doc
return
mongo_property_manager.py:实现了一个基于 MongoDB 的属性管理器。
主要函数
def encode_mongo_key(s):#返回可用作 MongoDB 键的 `s` 的编码版本
assert DOT_ESCAPE not in s
return s.replace(".", DOT_ESCAPE)
def decode_mongo_key(key):#解码一个由encode_mongo_key()编码的字符串。
return key.replace(DOT_ESCAPE, ".")
此外还包含了一个类MongoPropertyManager用来实现实现一个基于MongoDB的属性管理器 。
property_manager.py:实现两个属性管理器:一个在内存中(基于字典),一个 使用搁置的持久性低性能变体。
属性字典的构建方式如下:
{ ref-url1: {propname1: value1, propname2: value2, }, ref-url2: {propname1: value1, propname2: value2, }, }
包含类PropertyManager、ShelvePropertyManager
使用字典的内存中属性管理器实现。这显然不是持久的,但在某些情况下应该足够了
PropertyManager主要函数:
def get_property(self, norm_url, name, environ=None):
_logger.debug("get_property({}, {})".format(norm_url, name))
self._lock.acquire_read()
try:
if not self._loaded:
self._lazy_open()
if norm_url not in self._dict:
return None
try:
resourceprops = self._dict[norm_url]
except Exception as e:
_logger.exception(
"get_property({}, {}) failed : {}".format(norm_url, name, e)
)
raise
return resourceprops.get(name)
finally:
self._lock.release()
def remove_property(self, norm_url, name, dry_run=False, environ=None):#指定删除不存在的属性不是错误
_logger.debug(
"remove_property({}, {}, dry_run={})".format(norm_url, name, dry_run)
)
if dry_run:
# TODO: can we check anything here?
return
self._lock.acquire_write()
try:
if not self._loaded:
self._lazy_open()
if norm_url in self._dict:
locatordict = self._dict[norm_url]
if name in locatordict:
del locatordict[name]
# This re-assignment is important, so Shelve realizes the
# change:
self._dict[norm_url] = locatordict
self._sync()
if __debug__ and self._verbose >= 4:
self._check()
finally:
self._lock.release()
ShelvePropertyManager:使用搁置的低性能属性管理器实现
主要函数
def _sync(self):将持久字典写入disc
_logger.debug("_sync()")
self._lock.acquire_write() # TODO: read access is enough?
try:
if self._loaded:
self._dict.sync()
finally:
self._lock.release()
def clear(self):#删除所有条目
self._lock.acquire_write()
try:
was_closed = self._dict is None
if was_closed:
self.open()
if len(self._dict):
self._dict.clear()
self._dict.sync()
if was_closed:
self.close()
finally:
self._lock.release()