【山大智云项目日志】(十一)源码分析之seahub-extra

2021SC@SDUSC

在seahub-extra-setting中我们了解到extra相比原seahub多了什么内容。对于krb5_auth和cas等和身份认证以及单点登录有关的内容,前两次已经分析。这次主要接上一次源码分析,对seahub-extra剩下的几个文件夹下的代码进行分析。

EXTRA_INSTALLED_APPS = [
    "seahub_extra.search",
    "seahub_extra.sysadmin_extra",
    'seahub_extra.organizations',
    'seahub_extra.krb5_auth',
    'seahub_extra.django_cas_ng',
]

EXTRA_MIDDLEWARE = [
    'seahub_extra.organizations.middleware.RedirectMiddleware',
]

EXTRA_AUTHENTICATION_BACKENDS = (
    'seahub_extra.django_cas_ng.backends.CASBackend',
)

首先对setting文件中指明的EXTRA_MIDDLEWARE文件夹里的Middleware内容进行分析。
文档给的描述是:将非“www”子域请求重定向到指定URL或业务的中间件类。例如:http://xyzsite.com到http://www.xyzsite.com,之所以要将非"www"的域转到“www”的域,这是便于SEO优化,因为带www与不带www搜索引擎看来,是两个不同的站,如果不跳转,即搜索引擎会视为两个内容完成相同的网站,权重将会分散甚至降低或降权。所以需要把其中一个301重定向,这样有利于收录和搜索引擎排名。
示意图:
在这里插入图片描述
主要进行处理的代码:
process_request()函数为包括非“www”子域的请求返回HTTP重定向响应。

    def process_request(self, request):
   
        if getattr(settings, 'MULTI_TENANCY', False) is False:
            return None

        if ORG_REDIRECT is False:
            return None

        path = request.get_full_path()
        domain = request.META.get('HTTP_HOST') or request.META.get('SERVER_NAME')

        if request.user.is_anonymous:
            return None

        if request.user.org is None: # 个体用户的请求
            sub_domain = get_subdomain(domain)
            if sub_domain is not None:
                return HttpResponseRedirect(get_site_scheme_and_netloc() + path)
            else:
                return None
        else:                   # 组织机构的请求
            url_prefix = request.user.org.url_prefix
            sub_domain = get_subdomain(domain)
            if sub_domain is None or sub_domain != url_prefix:
                return HttpResponseRedirect(construct_org_url(url_prefix,path))
            else:
                return None

子域是创建测试或登台站点的好方法,以便在不创建其他域的情况下进行某些测试。
下面是获取子域的代码:

def get_subdomain(domain):
    service_url_netloc = urlparse(get_service_url()).netloc
    domain_remaining = domain.replace(service_url_netloc, '')

    if domain_remaining == '':
        return None
    elif domain_remaining[-1] == '.':
        return domain_remaining[:-1]
    else:
        logger.warn('Invalid domain: %s, service_url: %s' % (domain, service_url_netloc))
        return None

最后是构建新的URL然后传给客户端重定向到www域:

def construct_org_url(url_prefix, path):
    service_url = get_service_url()
    p = urlparse(service_url)
    scheme = p.scheme
    netloc = p.netloc
    return "%s://%s.%s%s" % (scheme, url_prefix, netloc, path)

form.py主要是一个用于组织用户注册的表单。
包括限制字段长度,判断邮箱是否valid,是否有人占用,还有URL prefix can only be letters(a-z), numbers, and the underscore character,即必须是小写字母,数字,下划线。还有两次密码判断是否一致。代码过于简单,这里不用再展示。

search文件夹

对于search文件夹来说,这里面是用Elasticsearch框架,对整个库建立了索引,从而更快速的得到搜索结果。

示意图:
在这里插入图片描述
主要方法:

通过username获取拥有的私有仓库列表

def get_owned_repos(username, org_id=None)

通过username获取共享仓库列表

def get_shared_repos(username, org_id=None):

通过username获取群组仓库列表

def get_group_repos(username, org_id=None):

通过username获取公共仓库列表

def get_public_repos(username, org_id=None):

通过上面获取的仓库列表调用es search的方法接口进行搜索,结果以数组形式返回。

def search_files(repos_map, search_path, keyword, obj_desc, start, size, org_id=None):
    # search file
    if len(repos_map) > 1:
        search_path = None
    files_found, total = es_search(repos_map, search_path, keyword, obj_desc, start, size)

    result = []
    for f in files_found:
        repo = repos_map.get(f['repo_id'], None)
        if not repo:
            continue

        if repo.origin_path:
            if not f['fullpath'].startswith(repo.origin_path):
                # this operation will reduce the result items, but it will not happen now
                continue
            else:
                f['repo_id'] = repo.repo_id
                f['fullpath'] = f['fullpath'].split(repo.origin_path)[-1]

        if not repo.owner:
            if org_id:
                repo.owner = seafile_api.get_org_repo_owner(repo.id)
            else:
                repo.owner = seafile_api.get_repo_owner(repo.id)

        # if match multiple files, keep the lookup only once.
        if not hasattr(repo, 'owner_nickname') or not repo.owner_nickname:
            repo.owner_nickname = email2nickname(repo.owner)

        if not hasattr(repo, 'owner_contact_email') or not repo.owner_contact_email:
            repo.owner_contact_email = email2contact_email(repo.owner)

        if f['fullpath'] == '/':
            f['last_modified_by'] = repo.last_modifier
            f['last_modified'] = repo.last_modify
            f['size'] = repo.size
        else:
            try:
                dirent = seafile_api.get_dirent_by_path(f['repo_id'], f['fullpath'])
            except Exception as e:
                logger.error(e)
                continue

            if not dirent:
                continue

            f['last_modified_by'] = dirent.modifier
            f['last_modified'] = dirent.mtime
            f['size'] = dirent.size

        f['repo'] = repo
        f['repo_name'] = repo.name
        f['repo_owner_email'] = repo.owner
        f['repo_owner_name'] = repo.owner_nickname
        f['repo_owner_contact_email'] = repo.owner_contact_email

        result.append(f)

    return result, total
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值