【山大智云开发日志】seafdav分析(4)

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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值