Exemple #1
0
def unenc_rw_repos(request):
    """Get a user's unencrypt repos that he/she can read-write.

    Arguments:
    - `request`:
    """
    content_type = 'application/json; charset=utf-8'
    acc_repos = get_unencry_rw_repos_by_user(request)

    repo_list = []
    acc_repos = filter(lambda r: not r.is_virtual, acc_repos)
    for repo in acc_repos:
        repo_list.append({"name": repo.name, "id": repo.id})

    repo_list.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
    return HttpResponse(json.dumps(repo_list), content_type=content_type)
Exemple #2
0
def unenc_rw_repos(request):
    """Get a user's unencrypt repos that he/she can read-write.
    
    Arguments:
    - `request`:
    """
    if not request.is_ajax():
        raise Http404
    
    content_type = 'application/json; charset=utf-8'
    username = request.user.username
    acc_repos = get_unencry_rw_repos_by_user(username)

    repo_list = []
    for repo in acc_repos:
        repo_list.append({"name": repo.name, "id": repo.id})
    return HttpResponse(json.dumps(repo_list), content_type=content_type)
Exemple #3
0
def unenc_rw_repos(request):
    """Get a user's unencrypt repos that he/she can read-write.
    
    Arguments:
    - `request`:
    """
    if not request.is_ajax():
        raise Http404

    content_type = 'application/json; charset=utf-8'
    username = request.user.username
    acc_repos = get_unencry_rw_repos_by_user(username)

    repo_list = []
    for repo in acc_repos:
        repo_list.append({"name": repo.name, "id": repo.id})
    return HttpResponse(json.dumps(repo_list), content_type=content_type)
Exemple #4
0
def render_repo(request, repo):
    """Steps to show repo page:
    If user has permission to view repo
      If repo is encrypt and password is not set on server
        return decrypt repo page
      If repo is not encrypt or password is set on server
        Show repo direntries based on requested path
    If user does not have permission to view repo
      return permission deny page
    """
    username = request.user.username
    path = get_path_from_request(request)
    user_perm = check_repo_access_permission(repo.id, username)
    if user_perm is None:
        return render_to_response('repo_access_deny.html', {
            'repo': repo,
        },
                                  context_instance=RequestContext(request))

    server_crypto = False
    if repo.encrypted:
        try:
            server_crypto = UserOptions.objects.is_server_crypto(username)
        except CryptoOptionNotSetError:
            return render_to_response('options/set_user_options.html', {},
                                      context_instance=RequestContext(request))

        if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
                and not is_password_set(repo.id, username):
            return render_to_response('decrypt_repo_form.html', {
                    'repo': repo,
                    'next': get_next_url_from_request(request) or \
                        reverse('repo', args=[repo.id])
                    }, context_instance=RequestContext(request))

    # query context args
    applet_root = get_ccnetapplet_root()
    httpserver_root = get_httpserver_root()
    max_upload_file_size = MAX_UPLOAD_FILE_SIZE

    protocol = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain

    contacts = Contact.objects.get_contacts_by_user(username)
    accessible_repos = [
        repo
    ] if repo.encrypted else get_unencry_rw_repos_by_user(username)

    head_commit = get_commit(repo.head_cmmt_id)
    if not head_commit:
        raise Http404
    repo_size = get_repo_size(repo.id)
    no_quota = is_no_quota(repo.id)
    search_repo_id = None if repo.encrypted else repo.id
    repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False

    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request,
                                                        repo.id,
                                                        head_commit,
                                                        path,
                                                        offset=0,
                                                        limit=100)
    if dirent_more:
        more_start = 100
    zipped = get_nav_path(path, repo.name)
    repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
    if len(repo_groups) > 1:
        repo_group_str = render_to_string("snippets/repo_group_list.html",
                                          {'groups': repo_groups})
    else:
        repo_group_str = ''
    upload_url = get_upload_url(request, repo.id)

    if repo.encrypted and repo.enc_version == 2 and not server_crypto:
        ajax_upload_url = get_blks_upload_url(request, repo.id)
        ajax_update_url = get_blks_update_url(request, repo.id)
    else:
        ajax_upload_url = get_ajax_upload_url(request, repo.id)
        ajax_update_url = get_ajax_update_url(request, repo.id)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_dir_share_link(fileshare)

    joined_groups = get_personal_groups_by_user(request.user.username)

    return render_to_response('repo.html', {
        'repo': repo,
        'user_perm': user_perm,
        'repo_owner': repo_owner,
        'is_repo_owner': is_repo_owner,
        'current_commit': head_commit,
        'password_set': True,
        'repo_size': repo_size,
        'dir_list': dir_list,
        'file_list': file_list,
        'dirent_more': dirent_more,
        'more_start': more_start,
        'path': path,
        'zipped': zipped,
        'accessible_repos': accessible_repos,
        'applet_root': applet_root,
        'groups': repo_groups,
        'joined_groups': joined_groups,
        'repo_group_str': repo_group_str,
        'no_quota': no_quota,
        'max_upload_file_size': max_upload_file_size,
        'upload_url': upload_url,
        'ajax_upload_url': ajax_upload_url,
        'ajax_update_url': ajax_update_url,
        'httpserver_root': httpserver_root,
        'protocol': protocol,
        'domain': domain,
        'contacts': contacts,
        'fileshare': fileshare,
        'dir_shared_link': dir_shared_link,
        'search_repo_id': search_repo_id,
        'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
        'server_crypto': server_crypto,
    },
                              context_instance=RequestContext(request))
Exemple #5
0
    def test_anonymous_user(self):
        self.request.user = AnonymousUser()

        unenc_repos = get_unencry_rw_repos_by_user(self.request)
        assert len(unenc_repos) == 0
Exemple #6
0
    def test_can_get(self):
        repo = self.repo

        unenc_repos = get_unencry_rw_repos_by_user(self.request)
        assert len(unenc_repos) > 0
Exemple #7
0
def view_priv_shared_file(request, token):
    """View private shared file.
    """
    try:
        pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(
            token)
    except PrivateFileDirShare.DoesNotExist:
        raise Http404

    repo_id = pfs.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    username = request.user.username
    if username != pfs.from_user and username != pfs.to_user:
        raise Http404  # permission check

    path = normalize_file_path(pfs.path)
    obj_id = seafile_api.get_file_id_by_path(repo.id, path)
    if not obj_id:
        raise Http404

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)

    access_token = seafile_api.get_fileserver_access_token(
        repo.id, obj_id, 'view', username)
    raw_path = gen_file_get_url(access_token, filename)
    inner_path = gen_inner_file_get_url(access_token, filename)

    # get file content
    ret_dict = {
        'err': '',
        'file_content': '',
        'encoding': '',
        'file_enc': '',
        'file_encoding_list': [],
        'html_exists': False,
        'filetype': filetype
    }
    fsize = get_file_size(repo.store_id, repo.version, obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        ret_dict['err'] = err_msg
    else:
        """Choose different approach when dealing with different type of file."""

        if is_textual_file(file_type=filetype):
            handle_textual_file(request, filetype, inner_path, ret_dict)
        elif filetype == DOCUMENT:
            handle_document(inner_path, obj_id, fileext, ret_dict)
        elif filetype == SPREADSHEET:
            handle_spreadsheet(inner_path, obj_id, fileext, ret_dict)
        elif filetype == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

    accessible_repos = get_unencry_rw_repos_by_user(request)
    save_to_link = reverse('save_private_file_share', args=[pfs.token])

    return render_to_response(
        'shared_file_view.html', {
            'repo': repo,
            'obj_id': obj_id,
            'path': path,
            'file_name': filename,
            'file_size': fsize,
            'access_token': access_token,
            'fileext': fileext,
            'raw_path': raw_path,
            'shared_by': pfs.from_user,
            'err': ret_dict['err'],
            'file_content': ret_dict['file_content'],
            'encoding': ret_dict['encoding'],
            'file_encoding_list': ret_dict['file_encoding_list'],
            'html_exists': ret_dict['html_exists'],
            'html_detail': ret_dict.get('html_detail', {}),
            'filetype': ret_dict['filetype'],
            'use_pdfjs': USE_PDFJS,
            'accessible_repos': accessible_repos,
            'save_to_link': save_to_link,
        },
        context_instance=RequestContext(request))
Exemple #8
0
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

        # Increase file shared link view_cnt, this operation should be atomic
        fileshare.view_cnt = F('view_cnt') + 1
        fileshare.save()

        # send statistic messages
        if ret_dict['filetype'] != 'Unknown':
            try:
                send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                             (repo.id, shared_by, obj_id, file_size))
            except SearpcError, e:
                logger.error('Error when sending file-view message: %s' %
                             str(e))

    accessible_repos = get_unencry_rw_repos_by_user(request)
    save_to_link = reverse('save_shared_link') + '?t=' + token
    traffic_over_limit = user_traffic_over_limit(shared_by)

    return render_to_response(
        'shared_file_view.html', {
            'repo': repo,
            'obj_id': obj_id,
            'path': path,
            'file_name': filename,
            'file_size': file_size,
            'shared_token': token,
            'access_token': access_token,
            'fileext': fileext,
            'raw_path': raw_path,
            'shared_by': shared_by,
Exemple #9
0
def render_repo(request, repo):
    """Steps to show repo page:
    If user has permission to view repo
      If repo is encrypt and password is not set on server
        return decrypt repo page
      If repo is not encrypt or password is set on server
        Show repo direntries based on requested path
    If user does not have permission to view repo
      return permission deny page
    """
    username = request.user.username
    path = get_path_from_request(request)
    user_perm = check_repo_access_permission(repo.id, username)
    if user_perm is None:
        return render_to_response("repo_access_deny.html", {"repo": repo}, context_instance=RequestContext(request))

    if (
        repo.encrypted
        and (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO))
        and not is_password_set(repo.id, username)
    ):
        return render_to_response(
            "decrypt_repo_form.html",
            {"repo": repo, "next": get_next_url_from_request(request) or reverse("repo", args=[repo.id])},
            context_instance=RequestContext(request),
        )

    # query context args
    applet_root = get_ccnetapplet_root()
    httpserver_root = get_httpserver_root()
    max_upload_file_size = MAX_UPLOAD_FILE_SIZE

    protocol = request.is_secure() and "https" or "http"
    domain = RequestSite(request).domain

    contacts = Contact.objects.get_contacts_by_user(username)
    accessible_repos = [repo] if repo.encrypted else get_unencry_rw_repos_by_user(username)

    head_commit = get_commit(repo.head_cmmt_id)
    if not head_commit:
        raise Http404
    repo_size = get_repo_size(repo.id)
    no_quota = is_no_quota(repo.id)
    search_repo_id = None if repo.encrypted else repo.id
    repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False

    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset=0, limit=100)
    if dirent_more:
        more_start = 100
    zipped = get_nav_path(path, repo.name)
    repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
    if len(repo_groups) > 1:
        repo_group_str = render_to_string("snippets/repo_group_list.html", {"groups": repo_groups})
    else:
        repo_group_str = ""
    upload_url = get_upload_url(request, repo.id)

    if repo.encrypted and repo.enc_version == 2 and not SERVER_CRYPTO:
        ajax_upload_url = get_blks_upload_url(request, repo.id)
        ajax_update_url = get_blks_update_url(request, repo.id)
    else:
        ajax_upload_url = get_ajax_upload_url(request, repo.id)
        ajax_update_url = get_ajax_update_url(request, repo.id)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_dir_share_link(fileshare)

    joined_groups = get_personal_groups_by_user(request.user.username)

    return render_to_response(
        "repo.html",
        {
            "repo": repo,
            "user_perm": user_perm,
            "repo_owner": repo_owner,
            "is_repo_owner": is_repo_owner,
            "current_commit": head_commit,
            "password_set": True,
            "repo_size": repo_size,
            "dir_list": dir_list,
            "file_list": file_list,
            "dirent_more": dirent_more,
            "more_start": more_start,
            "path": path,
            "zipped": zipped,
            "accessible_repos": accessible_repos,
            "applet_root": applet_root,
            "groups": repo_groups,
            "joined_groups": joined_groups,
            "repo_group_str": repo_group_str,
            "no_quota": no_quota,
            "max_upload_file_size": max_upload_file_size,
            "upload_url": upload_url,
            "ajax_upload_url": ajax_upload_url,
            "ajax_update_url": ajax_update_url,
            "httpserver_root": httpserver_root,
            "protocol": protocol,
            "domain": domain,
            "contacts": contacts,
            "fileshare": fileshare,
            "dir_shared_link": dir_shared_link,
            "search_repo_id": search_repo_id,
            "ENABLE_SUB_LIBRARY": ENABLE_SUB_LIBRARY,
        },
        context_instance=RequestContext(request),
    )
Exemple #10
0
def view_priv_shared_file(request, token):
    """View private shared file.
    """
    try:
        pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(token)
    except PrivateFileDirShare.DoesNotExist:
        raise Http404

    repo_id = pfs.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404
    
    username = request.user.username
    if username != pfs.from_user and username != pfs.to_user:
        raise Http404           # permission check

    path = normalize_file_path(pfs.path)
    obj_id = seafile_api.get_file_id_by_path(repo.id, path)
    if not obj_id:
        raise Http404

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    
    access_token = seafile_api.get_fileserver_access_token(repo.id, obj_id,
                                                           'view', username)
    raw_path = gen_file_get_url(access_token, filename)
    inner_path = gen_inner_file_get_url(access_token, filename)

    # get file content
    ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '',
                'file_encoding_list': [], 'html_exists': False,
                'filetype': filetype}
    fsize = get_file_size(repo.store_id, repo.version, obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        ret_dict['err'] = err_msg
    else:
        """Choose different approach when dealing with different type of file."""

        if is_textual_file(file_type=filetype):
            handle_textual_file(request, filetype, inner_path, ret_dict)
        elif filetype == DOCUMENT:
            handle_document(inner_path, obj_id, fileext, ret_dict)
        elif filetype == SPREADSHEET:
            handle_spreadsheet(inner_path, obj_id, fileext, ret_dict)
        elif filetype == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

    accessible_repos = get_unencry_rw_repos_by_user(request)
    save_to_link = reverse('save_private_file_share', args=[pfs.token])

    return render_to_response('shared_file_view.html', {
            'repo': repo,
            'obj_id': obj_id,
            'path': path,
            'file_name': filename,
            'file_size': fsize,
            'access_token': access_token,
            'fileext': fileext,
            'raw_path': raw_path,
            'shared_by': pfs.from_user,
            'err': ret_dict['err'],
            'file_content': ret_dict['file_content'],
            'encoding': ret_dict['encoding'],
            'file_encoding_list':ret_dict['file_encoding_list'],
            'html_exists': ret_dict['html_exists'],
            'html_detail': ret_dict.get('html_detail', {}),
            'filetype': ret_dict['filetype'],
            'use_pdfjs':USE_PDFJS,
            'accessible_repos': accessible_repos,
            'save_to_link': save_to_link,
            }, context_instance=RequestContext(request))
Exemple #11
0
        elif filetype == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

        # Increase file shared link view_cnt, this operation should be atomic
        fileshare.view_cnt = F('view_cnt') + 1
        fileshare.save()

        # send statistic messages
        if ret_dict['filetype'] != 'Unknown':
            try:
                send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                             (repo.id, shared_by, obj_id, file_size))
            except SearpcError, e:
                logger.error('Error when sending file-view message: %s' % str(e))

    accessible_repos = get_unencry_rw_repos_by_user(request)
    save_to_link = reverse('save_shared_link') + '?t=' + token
    traffic_over_limit = user_traffic_over_limit(shared_by)

    return render_to_response('shared_file_view.html', {
            'repo': repo,
            'obj_id': obj_id,
            'path': path,
            'file_name': filename,
            'file_size': file_size,
            'shared_token': token,
            'access_token': access_token,
            'fileext': fileext,
            'raw_path': raw_path,
            'shared_by': shared_by,
            'err': ret_dict['err'],
Exemple #12
0
def render_repo(request, repo):
    """Steps to show repo page:
    If user has permission to view repo
      If repo is encrypt and password is not set on server
        return decrypt repo page
      If repo is not encrypt or password is set on server
        Show repo direntries based on requested path
    If user does not have permission to view repo
      return permission deny page
    """
    username = request.user.username
    path = get_path_from_request(request)
    user_perm = check_repo_access_permission(repo.id, username)
    if user_perm is None:
        return render_to_response('repo_access_deny.html', {
                'repo': repo,
                }, context_instance=RequestContext(request))

    server_crypto = False
    if repo.encrypted:
        try:
            server_crypto = UserOptions.objects.is_server_crypto(username)
        except CryptoOptionNotSetError:
            return render_to_response('options/set_user_options.html', {
                    }, context_instance=RequestContext(request))
            
        if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
                and not is_password_set(repo.id, username):
            return render_to_response('decrypt_repo_form.html', {
                    'repo': repo,
                    'next': get_next_url_from_request(request) or \
                        reverse('repo', args=[repo.id])
                    }, context_instance=RequestContext(request))

    # query context args
    applet_root = get_ccnetapplet_root()
    httpserver_root = get_httpserver_root()
    max_upload_file_size = MAX_UPLOAD_FILE_SIZE
    
    protocol = request.is_secure() and 'https' or 'http'
    domain = RequestSite(request).domain

    contacts = Contact.objects.get_contacts_by_user(username)
    accessible_repos = [repo] if repo.encrypted else get_unencry_rw_repos_by_user(username)
    joined_groups = get_personal_groups_by_user(request.user.username)

    head_commit = get_commit(repo.head_cmmt_id)
    if not head_commit:
        raise Http404
    repo_size = get_repo_size(repo.id)
    no_quota = is_no_quota(repo.id)
    search_repo_id = None if repo.encrypted else repo.id
    repo_owner = seafile_api.get_repo_owner(repo.id)
    is_repo_owner = True if repo_owner == username else False
    
    more_start = None
    file_list, dir_list, dirent_more = get_repo_dirents(request, repo.id, head_commit, path, offset=0, limit=100)
    if dirent_more:
        more_start = 100
    zipped = get_nav_path(path, repo.name)
    repo_groups = get_shared_groups_by_repo_and_user(repo.id, username)
    if len(repo_groups) > 1:
        repo_group_str = render_to_string("snippets/repo_group_list.html",
                                          {'groups': repo_groups})
    else:
        repo_group_str = ''
    upload_url = get_upload_url(request, repo.id)

    if repo.encrypted and repo.enc_version == 2 and not server_crypto:
        ajax_upload_url = get_blks_upload_url(request, repo.id)
        ajax_update_url = get_blks_update_url(request, repo.id)
    else:
        ajax_upload_url = get_ajax_upload_url(request, repo.id)
        ajax_update_url = get_ajax_update_url(request, repo.id)
    fileshare = get_fileshare(repo.id, username, path)
    dir_shared_link = get_dir_share_link(fileshare)
    uploadlink = get_uploadlink(repo.id, username, path)
    dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)

    return render_to_response('repo.html', {
            'repo': repo,
            'user_perm': user_perm,
            'repo_owner': repo_owner,
            'is_repo_owner': is_repo_owner,
            'current_commit': head_commit,
            'password_set': True,
            'repo_size': repo_size,
            'dir_list': dir_list,
            'file_list': file_list,
            'dirent_more': dirent_more,
            'more_start': more_start,
            'path': path,
            'zipped': zipped,
            'accessible_repos': accessible_repos,
            'applet_root': applet_root,
            'groups': repo_groups,
            'joined_groups': joined_groups,
            'repo_group_str': repo_group_str,
            'no_quota': no_quota,
            'max_upload_file_size': max_upload_file_size,
            'upload_url': upload_url,
            'ajax_upload_url': ajax_upload_url,
            'ajax_update_url': ajax_update_url,
            'httpserver_root': httpserver_root,
            'protocol': protocol,
            'domain': domain,
            'contacts': contacts,
            'fileshare': fileshare,
            'dir_shared_link': dir_shared_link,
            'uploadlink': uploadlink,
            'dir_shared_upload_link': dir_shared_upload_link,
            'search_repo_id': search_repo_id,
            'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
            'server_crypto': server_crypto,
            }, context_instance=RequestContext(request))
Exemple #13
0
def view_priv_shared_file(request, token):
    """View private shared file.
    """
    try:
        pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(token)
    except PrivateFileDirShare.DoesNotExist:
        raise Http404

    repo_id = pfs.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    username = request.user.username
    if username != pfs.from_user and username != pfs.to_user:
        raise Http404  # permission check

    path = normalize_file_path(pfs.path)
    obj_id = seafile_api.get_file_id_by_path(repo.id, path)
    if not obj_id:
        raise Http404

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)

    access_token = seafile_api.get_fileserver_access_token(repo.id, obj_id, "view", username)
    raw_path = gen_file_get_url(access_token, filename)
    inner_path = gen_inner_file_get_url(access_token, filename)

    # get file content
    ret_dict = {
        "err": "",
        "file_content": "",
        "encoding": "",
        "file_enc": "",
        "file_encoding_list": [],
        "html_exists": False,
        "filetype": filetype,
    }
    fsize = get_file_size(repo.store_id, repo.version, obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        ret_dict["err"] = err_msg
    else:
        """Choose different approach when dealing with different type of file."""

        if is_textual_file(file_type=filetype):
            handle_textual_file(request, filetype, inner_path, ret_dict)
        elif filetype == DOCUMENT:
            handle_document(inner_path, obj_id, fileext, ret_dict)
        elif filetype == SPREADSHEET:
            handle_spreadsheet(inner_path, obj_id, fileext, ret_dict)
        elif filetype == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

    accessible_repos = get_unencry_rw_repos_by_user(request)
    save_to_link = reverse("save_private_file_share", args=[pfs.token])

    return render_to_response(
        "shared_file_view.html",
        {
            "repo": repo,
            "obj_id": obj_id,
            "path": path,
            "file_name": filename,
            "file_size": fsize,
            "access_token": access_token,
            "fileext": fileext,
            "raw_path": raw_path,
            "shared_by": pfs.from_user,
            "err": ret_dict["err"],
            "file_content": ret_dict["file_content"],
            "encoding": ret_dict["encoding"],
            "file_encoding_list": ret_dict["file_encoding_list"],
            "html_exists": ret_dict["html_exists"],
            "html_detail": ret_dict.get("html_detail", {}),
            "filetype": ret_dict["filetype"],
            "use_pdfjs": USE_PDFJS,
            "accessible_repos": accessible_repos,
            "save_to_link": save_to_link,
        },
        context_instance=RequestContext(request),
    )