Ejemplo n.º 1
0
def view_shared_file(request, token):
    """
    Preview file via shared link.
    """
    assert token is not None    # Checked by URLconf

    try:
        fileshare = FileShare.objects.get(token=token)
    except FileShare.DoesNotExist:
        raise Http404

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = fileshare.path.rstrip('/') # Normalize file path 
    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(obj_id)
    
    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id,
                                                     'view', '')
    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(obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        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 == 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:
                obj_size = seafserv_threaded_rpc.get_file_size(obj_id)
                send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                             (repo.id, shared_by, obj_id, obj_size))
            except SearpcError, e:
                logger.error('Error when sending file-view message: %s' % str(e))
Ejemplo n.º 2
0
def get_file_content_by_commit_and_path(request, repo_id, commit_id, path, file_enc):
    try:
        obj_id = seafserv_threaded_rpc.get_file_id_by_commit_and_path( \
                                        commit_id, path)
    except:
        return None, 'bad path'

    if not obj_id or obj_id == EMPTY_SHA1:
        return '', None
    else:
        permission = get_user_permission(request, repo_id)
        if permission:
            # Get a token to visit file
            token = seafserv_rpc.web_get_access_token(repo_id,
                                                      obj_id,
                                                      'view',
                                                      request.user.username)
        else:
            return None, 'permission denied'

        filename = os.path.basename(path)
        raw_path = gen_file_get_url(token, urllib2.quote(filename))

        try:
            err, file_content, encoding = repo_file_get(raw_path, file_enc)
        except Exception, e:
            return None, 'error when read file from httpserver: %s' % e
        return file_content, err
Ejemplo n.º 3
0
def get_onlyoffice_dict(username, repo_id, file_path,
        file_id='', can_edit=False, can_download=True):

    repo = seafile_api.get_repo(repo_id)
    if repo.is_virtual:
        origin_repo_id = repo.origin_repo_id
        origin_file_path = posixpath.join(repo.origin_path, file_path.strip('/'))
        # for view history/trash/snapshot file
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(origin_repo_id,
                    origin_file_path)
    else:
        origin_repo_id = repo_id
        origin_file_path = file_path
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(repo_id,
                    file_path)

    dl_token = seafile_api.get_fileserver_access_token(repo_id,
            file_id, 'download', username, use_onetime=True)
    if not dl_token:
        return None

    filetype, fileext = get_file_type_and_ext(file_path)
    if fileext in ('xls', 'xlsx', 'ods', 'fods', 'csv'):
        document_type = 'spreadsheet'
    elif fileext in ('pptx', 'ppt', 'odp', 'fodp', 'ppsx', 'pps'):
        document_type = 'presentation'
    else:
        document_type = 'text'

    doc_info = json.dumps({'repo_id': repo_id, 'file_path': file_path, 'username': username})
    doc_key = hashlib.md5(force_bytes(origin_repo_id + origin_file_path + file_id)).hexdigest()[:20]
    cache.set("ONLYOFFICE_%s" % doc_key, doc_info, None)

    file_name = os.path.basename(file_path.rstrip('/'))
    doc_url = gen_file_get_url(dl_token, file_name)

    base_url = get_site_scheme_and_netloc()
    onlyoffice_editor_callback_url = reverse('onlyoffice_editor_callback')
    calllback_url = urlparse.urljoin(base_url, onlyoffice_editor_callback_url)

    return_dict = {
        'repo_id': repo_id,
        'path': file_path,
        'ONLYOFFICE_APIJS_URL': ONLYOFFICE_APIJS_URL,
        'file_type': fileext,
        'doc_key': doc_key,
        'doc_title': file_name,
        'doc_url': doc_url,
        'document_type': document_type,
        'callback_url': calllback_url,
        'can_edit': can_edit,
        'can_download': can_download,
        'username': username,
        'enable_watermark': ENABLE_WATERMARK and not can_edit,
    }

    return return_dict
Ejemplo n.º 4
0
def get_group_msgs(groupid, page, username):

    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(group_id=groupid).order_by("-timestamp"), 15)

    # If page request (9999) is out of range, return None
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [r.reply_to_id for r in msg_replies]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        for att in attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == "/":
                repo = seafile_api.get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip("/")  # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == "file" and att.src == "recommend":
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = seafile_api.get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = "File does not exist"
                    else:
                        att.token = seafile_api.get_fileserver_access_token(att.repo_id, att.obj_id, "view", username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachment = att

    return group_msgs
Ejemplo n.º 5
0
def get_file_url(repo_id, path, filename):
    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        raise WikiPageMissing
    access_token = seafserv_rpc.web_get_access_token(repo_id, obj_id,
                                                     'view', '')
    url = gen_file_get_url(access_token, filename)
    return url, obj_id
Ejemplo n.º 6
0
Archivo: file.py Proyecto: swpd/seahub
def view_file_via_shared_dir(request, token):
    assert token is not None    # Checked by URLconf

    try:
        fileshare = FileShare.objects.get(token=token)
    except FileShare.DoesNotExist:
        raise Http404

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404
    
    path = request.GET.get('p', '').rstrip('/')
    if not path:
        raise Http404
    if not path.startswith(fileshare.path): # Can not view upper dir of shared dir
        raise Http404
    zipped = gen_path_link(path, '')

    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(obj_id)

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id,
                                                     'view', '')
    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(obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        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 == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

        # send statistic messages
        try:
            obj_size = seafserv_threaded_rpc.get_file_size(obj_id)
            send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                         (repo.id, shared_by, obj_id, obj_size))
        except SearpcError, e:
            logger.error('Error when sending file-view message: %s' % str(e))
Ejemplo n.º 7
0
def get_file_view_path_and_perm(request, repo_id, obj_id, filename):
    """
    Return raw path of a file and the permission to view file.
    """
    username = request.user.username
    # check permission
    perm = get_user_permission(request, repo_id)
    if perm:
        # Get a token to visit file
        token = web_get_access_token(repo_id, obj_id, 'view', username)
        return (gen_file_get_url(token, filename), perm)
    else:
        return ('', perm)
Ejemplo n.º 8
0
def get_repo_file(request, repo_id, file_id, file_name, op):
    if op == 'download':
        token = seafserv_rpc.web_get_access_token(repo_id, file_id,
                                                  op, request.user.username)
        redirect_url = gen_file_get_url(token, file_name)
        response = HttpResponse(json.dumps(redirect_url), status=200,
                                content_type=json_content_type)
        response["oid"] = file_id
        return response

    if op == 'sharelink':
        path = request.GET.get('p', None)
        assert path, 'path must be passed in the url'
        return get_shared_link(request, repo_id, path)
Ejemplo n.º 9
0
    def get(self, request, repo_id):
        """ get info of a single file/folder in a library
        """

        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if not can_view_sys_admin_repo(repo):
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        path = request.GET.get('path', None)
        if not path:
            error_msg = 'path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if path[0] != '/':
            path = '/' + path

        try:
            dirent = seafile_api.get_dirent_by_path(repo_id, path)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if not dirent:
            error_msg = 'file/folder %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if stat.S_ISDIR(dirent.mode):
            is_file = False
        else:
            is_file = True

        username = request.user.username
        if is_file and request.GET.get('dl', '0') == '1':

            token = seafile_api.get_fileserver_access_token(repo_id,
                dirent.obj_id, 'download', username, use_onetime=True)
            dl_url = gen_file_get_url(token, dirent.obj_name)
            send_file_access_msg(request, repo, path, 'web')
            return Response({'download_url': dl_url})

        dirent_info = get_dirent_info(dirent)

        return Response(dirent_info)
Ejemplo n.º 10
0
    def repl(matchobj):
        if matchobj.group(2):  # return origin string in backquotes
            return matchobj.group(2)

        page_alias = page_name = matchobj.group(1).strip()
        if len(page_name.split("|")) > 1:
            page_alias = page_name.split("|")[0]
            page_name = page_name.split("|")[1]

        filetype, fileext = get_file_type_and_ext(page_name)
        if fileext == "":
            # convert page_name that extension is missing to a markdown page
            try:
                dirent = get_wiki_dirent(repo_id, page_name)
                a_tag = "<a href='%s'>%s</a>"
                return a_tag % (smart_str(url_prefix + normalize_page_name(page_name) + "/"), page_alias)
            except (WikiDoesNotExist, WikiPageMissing):
                a_tag = """<a class="wiki-page-missing" href='%s'>%s</a>"""
                return a_tag % (smart_str(url_prefix + page_name.replace("/", "-") + "/"), page_alias)
        elif filetype == IMAGE:
            # load image to wiki page
            path = "/" + page_name
            filename = os.path.basename(path)
            obj_id = seaserv.get_file_id_by_path(repo_id, path)
            if not obj_id:
                # Replace '/' in page_name to '-', since wiki name can not
                # contain '/'.
                return """<a class="wiki-page-missing" href='%s'>%s</a>""" % (
                    url_prefix + "/" + page_name.replace("/", "-"),
                    page_name,
                )

            token = seaserv.web_get_access_token(repo_id, obj_id, "view", username)
            ret = '<img class="wiki-image" src="%s" alt="%s" />' % (gen_file_get_url(token, filename), filename)
            return smart_str(ret)
        else:
            from seahub.base.templatetags.seahub_tags import file_icon_filter
            from django.conf import settings

            # convert other types of filelinks to clickable links
            path = "/" + page_name
            icon = file_icon_filter(page_name)
            s = reverse("repo_view_file", args=[repo_id]) + "?p=" + urlquote(path)
            a_tag = (
                """<img src="%simg/file/%s" alt="%s" class="vam" /> <a href='%s' target='_blank' class="vam">%s</a>"""
            )
            ret = a_tag % (settings.MEDIA_URL, icon, icon, smart_str(s), page_name)
            return smart_str(ret)
Ejemplo n.º 11
0
    def get(self, request, repo_id):
        """ get info of a single file/folder in a library
        """

        repo = seafile_api.get_repo(repo_id)

        path = request.GET.get('path', None)
        if not path:
            error_msg = 'path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        path = normalize_file_path(path)

        try:
            dirent = seafile_api.get_dirent_by_path(repo_id, path)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if not dirent:
            error_msg = 'File or folder %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if stat.S_ISDIR(dirent.mode):
            is_file = False
        else:
            is_file = True

        username = request.user.username
        if is_file and request.GET.get('dl', '0') == '1':

            token = seafile_api.get_fileserver_access_token(
                repo_id, dirent.obj_id, 'download', username,
                use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY)

            if not token:
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            dl_url = gen_file_get_url(token, dirent.obj_name)
            send_file_access_msg(request, repo, path, 'web')
            return Response({'download_url': dl_url})

        dirent_info = get_dirent_info(dirent)

        return Response(dirent_info)
Ejemplo n.º 12
0
    def repl(matchobj):
        if matchobj.group(2):   # return origin string in backquotes
            return matchobj.group(2)

        page_alias = page_name = matchobj.group(1).strip()
        if len(page_name.split('|')) > 1:
            page_alias = page_name.split('|')[0]
            page_name = page_name.split('|')[1]
        
        filetype, fileext = get_file_type_and_ext(page_name)
        if fileext == '':
            # convert page_name that extension is missing to a markdown page
            try:
                dirent = get_wiki_dirent(repo_id, page_name)
                a_tag = '''<a href="%s">%s</a>'''
                return a_tag % (smart_str(url_prefix + normalize_page_name(page_name) + '/'), page_alias)
            except (WikiDoesNotExist, WikiPageMissing):
                a_tag = '''<a href="%s" class="wiki-page-missing">%s</a>'''
                return a_tag % (smart_str(url_prefix + normalize_page_name(page_name) + '/'), page_alias)
        elif filetype == IMAGE:
            # load image to wiki page
            path = "/" + page_name
            filename = os.path.basename(path)
            obj_id = seaserv.get_file_id_by_path(repo_id, path)
            if not obj_id:
                # Replace '/' in page_name to '-', since wiki name can not
                # contain '/'.
                return '''<a href="%s" class="wiki-page-missing">%s</a>''' % \
                    (url_prefix + '/' + page_name.replace('/', '-'), page_name)

            token = seafile_api.get_fileserver_access_token(repo_id, obj_id,
                                                            'view', username)
            ret = '<img src="%s" alt="%s" class="wiki-image" />' % (gen_file_get_url(token, filename), filename)
            return smart_str(ret)
        else:
            from seahub.base.templatetags.seahub_tags import file_icon_filter
            from django.conf import settings
            
            # convert other types of filelinks to clickable links
            path = "/" + page_name
            icon = file_icon_filter(page_name)
            s = reverse('view_lib_file', args=[repo_id, urlquote(path)])
            a_tag = '''<img src="%simg/file/%s" alt="%s" class="file-icon vam" /> <a href="%s" class="vam" target="_blank">%s</a>'''
            ret = a_tag % (settings.MEDIA_URL, icon, icon, smart_str(s), page_name)
            return smart_str(ret)
Ejemplo n.º 13
0
def _download_dir_from_share_link(request, fileshare, repo, real_path):
    # check whether owner's traffic over the limit
    if user_traffic_over_limit(fileshare.username):
        return render_error(
            request,
            _(u'Unable to access file: share link traffic is used up.'))

    shared_by = fileshare.username
    if real_path == '/':
        dirname = repo.name
    else:
        dirname = os.path.basename(real_path.rstrip('/'))

    dir_id = seafile_api.get_dir_id_by_path(repo.id, real_path)
    if not dir_id:
        return render_error(request,
                            _(u'Unable to download: folder not found.'))

    try:
        total_size = seaserv.seafserv_threaded_rpc.get_dir_size(
            repo.store_id, repo.version, dir_id)
    except Exception as e:
        logger.error(str(e))
        return render_error(request, _(u'Internal Error'))

    if total_size > seaserv.MAX_DOWNLOAD_DIR_SIZE:
        return render_error(
            request,
            _(u'Unable to download directory "%s": size is too large.') %
            dirname)

    token = seafile_api.get_fileserver_access_token(
        repo.id, dir_id, 'download-dir', request.user.username)

    try:
        seaserv.send_message(
            'seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' %
            (repo.id, shared_by, dir_id, total_size))
    except Exception as e:
        logger.error('Error when sending dir-download message: %s' % str(e))

    return HttpResponseRedirect(gen_file_get_url(token, dirname))
Ejemplo n.º 14
0
    def repl(matchobj):
        if matchobj.group(2):  # return origin string in backquotes
            return matchobj.group(2)

        link_alias = link_name = matchobj.group(1).strip()
        if len(link_name.split("|")) > 1:
            link_alias = link_name.split("|")[0]
            link_name = link_name.split("|")[1]

        filetype, fileext = get_file_type_and_ext(link_name)
        if fileext == "":
            # convert link_name that extension is missing to a markdown page
            try:
                dirent = get_wiki_dirent(repo_id, link_name)
                path = "/" + dirent.obj_name
                href = reverse("repo_view_file", args=[repo_id]) + "?p=" + urlquote(path)
                a_tag = """<a href="%s">%s</a>"""
                return a_tag % (href, link_alias)
            except (WikiDoesNotExist, WikiPageMissing):
                a_tag = """<p class="wiki-page-missing">%s</p>"""
                return a_tag % (link_alias)
        elif filetype == IMAGE:
            # load image to current page
            path = "/" + link_name
            filename = os.path.basename(path)
            obj_id = get_file_id_by_path(repo_id, path)
            if not obj_id:
                return """<p class="wiki-page-missing">%s</p>""" % link_name

            token = web_get_access_token(repo_id, obj_id, "view", username)
            return '<img class="wiki-image" src="%s" alt="%s" />' % (gen_file_get_url(token, filename), filename)
        else:
            from seahub.base.templatetags.seahub_tags import file_icon_filter

            # convert other types of filelinks to clickable links
            path = "/" + link_name
            icon = file_icon_filter(link_name)
            s = reverse("repo_view_file", args=[repo_id]) + "?p=" + urlquote(path)
            a_tag = (
                """<img src="%simg/file/%s" alt="%s" class="vam" /> <a href="%s" target="_blank" class="vam">%s</a>"""
            )
            return a_tag % (MEDIA_URL, icon, icon, s, link_name)
Ejemplo n.º 15
0
def get_file_view_path_and_perm(request, repo_id, obj_id, path):
    """ Get path and the permission to view file.

    Returns:
    	outer fileserver file url, inner fileserver file url, permission
    """
    username = request.user.username
    filename = os.path.basename(path)

    # user_perm = get_file_access_permission(repo_id, path, username) or \
    #     get_repo_access_permission(repo_id, username)
    user_perm = check_repo_access_permission(repo_id, request.user)
    if user_perm is None:
        return ('', '', user_perm)
    else:
        # Get a token to visit file
        token = web_get_access_token(repo_id, obj_id, 'view', username)
        outer_url = gen_file_get_url(token, filename)
        inner_url = gen_inner_file_get_url(token, filename)
        return (outer_url, inner_url, user_perm)
Ejemplo n.º 16
0
    def repl(matchobj):
        if matchobj.group(2):   # return origin string in backquotes
            return matchobj.group(2)

        linkname = matchobj.group(1).strip()
        filetype, fileext = get_file_type_and_ext(linkname)
        filetype = filetype.lower()
        if fileext == '':
            # convert linkname that extension is missing to a markdown page
            filename = linkname + ".md"
            path = "/" + filename
            if get_file_id_by_path(repo_id, path):
                a_tag = "<a href='%s'>%s</a>"
                return a_tag % (reverse('group_wiki', args=[group.id, linkname]), linkname)                                
            else:
                a_tag = '''<a class="wiki-page-missing" href='%s'>%s</a>'''
                return a_tag % (reverse('group_wiki', args=[group.id, linkname.replace('/', '-')]), linkname)                                
        elif filetype == 'image':
            # load image to wiki page
            path = "/" + linkname
            filename = os.path.basename(path)
            obj_id = get_file_id_by_path(repo_id, path)
            if not obj_id:
                # Replace '/' in linkname to '-', since wiki name can not
                # contain '/'.
                return '''<a class="wiki-page-missing" href='%s'>%s</a>''' % \
                    (reverse('group_wiki', args=[group.id, linkname.replace('/', '-')]), linkname)

            token = web_get_access_token(repo_id, obj_id, 'view', username)
            return '<img src="%s" alt="%s" />' % (gen_file_get_url(token, filename), filename)
        else:
            from base.templatetags.seahub_tags import file_icon_filter
            
            # convert other types of filelinks to clickable links
            path = "/" + linkname
            icon = file_icon_filter(linkname)
            s = reverse('repo_view_file', args=[repo_id]) + '?p=' + path
            a_tag = '''<img src="%simg/file/%s" alt="%s" class="vam" /> <a href='%s' target='_blank' class="vam">%s</a>'''
            return a_tag % (MEDIA_URL, icon, icon, s, linkname)
Ejemplo n.º 17
0
    def repl(matchobj):
        if matchobj.group(2):   # return origin string in backquotes
            return matchobj.group(2)

        page_name = matchobj.group(1).strip()
        filetype, fileext = get_file_type_and_ext(page_name)
        if fileext == '':
            # convert page_name that extension is missing to a markdown page
            dirent = get_wiki_dirent(repo_id, page_name)
            if dirent is not None:
                a_tag = "<a href='%s'>%s</a>"
                return a_tag % (url_prefix + '/' + normalize_page_name(page_name), page_name)
            else:
                a_tag = '''<a class="wiki-page-missing" href='%s'>%s</a>'''
                return a_tag % (url_prefix + '/' + page_name.replace('/', '-'), page_name)                                
        elif filetype == IMAGE:
            # load image to wiki page
            path = "/" + page_name
            filename = os.path.basename(path)
            obj_id = get_file_id_by_path(repo_id, path)
            if not obj_id:
                # Replace '/' in page_name to '-', since wiki name can not
                # contain '/'.
                return '''<a class="wiki-page-missing" href='%s'>%s</a>''' % \
                    (url_prefix + '/' + page_name.replace('/', '-'), page_name)

            token = seaserv.web_get_access_token(repo_id, obj_id, 'view', username)
            return '<img src="%s" alt="%s" />' % (gen_file_get_url(token, filename), filename)
        else:
            from base.templatetags.seahub_tags import file_icon_filter
            
            # convert other types of filelinks to clickable links
            path = "/" + page_name
            icon = file_icon_filter(page_name)
            s = reverse('repo_view_file', args=[repo_id]) + \
                '?p=' + urllib2.quote(smart_str(path))
            a_tag = '''<img src="%simg/file/%s" alt="%s" class="vam" /> <a href='%s' target='_blank' class="vam">%s</a>'''
            return a_tag % (MEDIA_URL, icon, icon, s, page_name)
Ejemplo n.º 18
0
def view_raw_shared_file(request, token, obj_id, file_name):
    """Returns raw content of a shared file.
    
    Arguments:
    - `request`:
    - `token`:
    - `obj_id`:
    - `file_name`:
    """
    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

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

    # Normalize file path based on file or dir share link
    if fileshare.is_file_share_link():
        file_path = fileshare.path.rstrip('/')
    else:
        file_path = fileshare.path.rstrip('/') + '/' + file_name

    real_obj_id = seafile_api.get_file_id_by_path(repo_id, file_path)
    if not real_obj_id:
        raise Http404

    if real_obj_id != obj_id:  # perm check
        raise Http404

    filename = os.path.basename(file_path)
    username = request.user.username
    token = web_get_access_token(repo_id, real_obj_id, 'view', username)
    outer_url = gen_file_get_url(token, filename)
    return HttpResponseRedirect(outer_url)
Ejemplo n.º 19
0
def view_raw_shared_file(request, token, obj_id, file_name):
    """Returns raw content of a shared file.
    
    Arguments:
    - `request`:
    - `token`:
    - `obj_id`:
    - `file_name`:
    """
    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

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

    # Normalize file path based on file or dir share link
    if fileshare.is_file_share_link():
        file_path = fileshare.path.rstrip("/")
    else:
        file_path = fileshare.path.rstrip("/") + "/" + file_name

    real_obj_id = seafile_api.get_file_id_by_path(repo_id, file_path)
    if not real_obj_id:
        raise Http404

    if real_obj_id != obj_id:  # perm check
        raise Http404

    filename = os.path.basename(file_path)
    username = request.user.username
    token = web_get_access_token(repo_id, real_obj_id, "view", username)
    outer_url = gen_file_get_url(token, filename)
    return HttpResponseRedirect(outer_url)
Ejemplo n.º 20
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))
Ejemplo n.º 21
0
    def get(self, request, workspace_id, name, commit_id):
        """Get dtable snapshot by commit_id
        """
        table_name = name
        table_file_name = table_name + FILE_TYPE

        # resource check
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if '@seafile_group' in workspace.owner:
            group_id = workspace.owner.split('@')[0]
            group = ccnet_api.get_group(int(group_id))
            if not group:
                error_msg = 'Group %s not found.' % group_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        repo_id = workspace.repo_id
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        dtable = DTables.objects.get_dtable(workspace, table_name)
        if not dtable:
            error_msg = 'dtable %s not found.' % table_name
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # check for get download link
        table_path = normalize_file_path(table_file_name)
        table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path)
        if not table_file_id:
            error_msg = 'file %s not found.' % table_file_name
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        username = request.user.username
        if not check_dtable_permission(username, workspace, dtable):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # main
        try:
            snapshot = DTableSnapshot.objects.get_by_commit_id(commit_id)

            # check
            if not snapshot:
                error_msg = 'commit_id not found.'
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            dtable_uuid = str(dtable.uuid.hex)
            if dtable_uuid != snapshot.dtable_uuid:
                error_msg = 'commit_id invalid.'
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # get by commit
            snapshot_table_path = normalize_file_path(snapshot.dtable_name)
            obj_id = seafile_api.get_file_id_by_commit_and_path(
                repo_id, commit_id, snapshot_table_path)
            if not obj_id:
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'snapshot not found.')

        except Exception as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal Server Error')

        # download url
        token = seafile_api.get_fileserver_access_token(
            repo_id, obj_id, 'download', username, FILESERVER_TOKEN_ONCE_ONLY)

        if not token:
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        redirect_url = gen_file_get_url(token, snapshot.dtable_name)
        return Response(redirect_url)
Ejemplo n.º 22
0
    def get(self, request):
        """ Return file info.
        """

        # argument check
        doc_id = request.GET.get('doc_id', '')
        if not doc_id:
            error_msg = 'doc_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_info = cache.get('BISHENG_OFFICE_' + doc_id)
        if not file_info:
            error_msg = 'doc_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        username = file_info.get('username')
        if not username:
            error_msg = 'username invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        repo_id = file_info.get('repo_id')
        if not repo_id:
            error_msg = 'repo_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_path = file_info.get('file_path')
        if not file_path:
            error_msg = 'file_path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_path = normalize_file_path(file_path)

        # resource check
        try:
            User.objects.get(email=username)
        except User.DoesNotExist:
            error_msg = 'User %s not found.' % username
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if not seafile_api.get_repo(repo_id):
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if not seafile_api.get_file_id_by_path(repo_id, file_path):
            error_msg = 'File %s not found.' % file_path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        parent_dir = os.path.dirname(file_path)
        permission = seafile_api.check_permission_by_path(repo_id, parent_dir, username)
        if not permission:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # get file basic info
        file_name = os.path.basename(file_path.rstrip('/'))
        filetype, fileext = get_file_type_and_ext(file_name)

        # get file raw url
        file_id = seafile_api.get_file_id_by_path(repo_id, file_path)
        download_token = seafile_api.get_fileserver_access_token(repo_id,
                file_id, 'download', username, use_onetime=True)
        raw_url = gen_file_get_url(download_token, file_name)

        # get avatar url
        url, _, _ = api_avatar_url(username, int(72))

        # prepare file permission
        privilege = copy.deepcopy(BISHENG_OFFICE_PRIVILEGE)
        can_edit = file_info.get('can_edit', False)
        if not can_edit:
            privilege.remove('FILE_WRITE')

        # prepare response
        file_info = {
            'doc': {
                'docId': doc_id,
                'title': file_name,
                'mime_type': BISHENG_OFFICE_MIME_TYPE[fileext],
                'fetchUrl': raw_url,
                'thumbnail': "",
                'fromApi': True
            },
            'user': {
                'uid': username,
                'oid': username,
                'nickName': email2nickname(username),
                'avatar': request.build_absolute_uri(url),
                'privilege': privilege
            },
        }

        return Response(file_info)
Ejemplo n.º 23
0
def get_file_url(repo, obj_id, file_name):
    repo_id = repo.id
    access_token = seaserv.seafserv_rpc.web_get_access_token(repo_id, obj_id, "view", "")
    url = gen_file_get_url(access_token, file_name)
    return url
Ejemplo n.º 24
0
def file_edit(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if request.method == "POST":
        return file_edit_submit(request, repo_id)

    if get_user_permission(request, repo_id) != "rw":
        return render_permission_error(request, _(u"Unable to edit file"))

    path = request.GET.get("p", "/")
    if path[-1] == "/":
        path = path[:-1]
    u_filename = os.path.basename(path)
    filename = urllib2.quote(u_filename.encode("utf-8"))

    head_id = repo.head_cmmt_id

    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u"The file does not exist."))

    token = web_get_access_token(repo_id, obj_id, "view", request.user.username)

    # generate path and link
    zipped = gen_path_link(path, repo.name)

    filetype, fileext = get_file_type_and_ext(filename)

    op = None
    err = ""
    file_content = None
    encoding = None
    file_encoding_list = FILE_ENCODING_LIST
    if filetype == TEXT or filetype == MARKDOWN or filetype == SF:
        if repo.encrypted:
            repo.password_set = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
            if not repo.password_set:
                op = "decrypt"
        if not op:
            raw_path = gen_file_get_url(token, filename)
            file_enc = request.GET.get("file_enc", "auto")
            if not file_enc in FILE_ENCODING_LIST:
                file_enc = "auto"
            err, file_content, encoding = repo_file_get(raw_path, file_enc)
            if encoding and encoding not in FILE_ENCODING_LIST:
                file_encoding_list.append(encoding)
    else:
        err = _(u"Edit online is not offered for this type of file.")

    return render_to_response(
        "file_edit.html",
        {
            "repo": repo,
            "u_filename": u_filename,
            "wiki_name": os.path.splitext(u_filename)[0],
            "path": path,
            "zipped": zipped,
            "filetype": filetype,
            "fileext": fileext,
            "op": op,
            "err": err,
            "file_content": file_content,
            "encoding": encoding,
            "file_encoding_list": file_encoding_list,
            "head_id": head_id,
            "from": request.GET.get("from", ""),
            "gid": request.GET.get("gid", ""),
        },
        context_instance=RequestContext(request),
    )
Ejemplo n.º 25
0
def view_file_via_shared_dir(request, token):
    assert token is not None    # Checked by URLconf

    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404
    
    path = request.GET.get('p', '').rstrip('/')
    if not path:
        raise Http404
    if not path.startswith(fileshare.path): # Can not view upper dir of shared dir
        raise Http404
    zipped = gen_path_link(path, '')

    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)

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

    img_prev = None
    img_next = None

    # get file content
    ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '',
                'file_encoding_list': [], 'html_exists': False,
                'filetype': filetype}
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(file_size, 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)
        elif filetype == IMAGE:
            current_commit = get_commits(repo_id, 0, 1)[0]
            parent_dir = os.path.dirname(path)
            dirs = seafile_api.list_dir_by_commit_and_path(current_commit.repo_id,
                                                           current_commit.id, parent_dir)
            if not dirs:
                raise Http404

            img_list = []
            for dirent in dirs:
                if not stat.S_ISDIR(dirent.props.mode):
                    fltype, flext = get_file_type_and_ext(dirent.obj_name)
                    if fltype == 'Image':
                        img_list.append(dirent.obj_name)

            if len(img_list) > 1:
                img_list.sort(lambda x, y : cmp(x.lower(), y.lower()))
                cur_img_index = img_list.index(filename) 
                if cur_img_index != 0:
                    img_prev = posixpath.join(parent_dir, img_list[cur_img_index - 1])
                if cur_img_index != len(img_list) - 1:
                    img_next = posixpath.join(parent_dir, img_list[cur_img_index + 1])

        # 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))
Ejemplo n.º 26
0
    if from_shared_link:
        try:
            file_size = seafile_api.get_file_size(repo.store_id, repo.version,
                                                  obj_id)
            send_message(
                'seahub.stats', 'file-download\t%s\t%s\t%s\t%s' %
                (repo.id, shared_by, obj_id, file_size))
        except Exception, e:
            logger.error('Error when sending file-download message: %s' %
                         str(e))
    else:
        # send stats message
        send_file_download_msg(request, repo, path, 'web')

    file_name = os.path.basename(path.rstrip('/'))
    redirect_url = gen_file_get_url(token, file_name)
    return HttpResponseRedirect(redirect_url)


########## text diff
def get_file_content_by_commit_and_path(request, repo_id, commit_id, path,
                                        file_enc):
    try:
        obj_id = seafserv_threaded_rpc.get_file_id_by_commit_and_path( \
                                        repo_id, commit_id, path)
    except:
        return None, 'bad path'

    if not obj_id or obj_id == EMPTY_SHA1:
        return '', None
    else:
Ejemplo n.º 27
0
def repo_download_dir(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        return render_error(request, _('Library does not exist'))

    path = request.GET.get('p', '/')
    if path[-1] != '/':  # Normalize dir path
        path += '/'

    if not seafile_api.get_dir_id_by_path(repo.id, path):
        return render_error(request, _('"%s" does not exist.') % path)

    if len(path) > 1:
        dirname = os.path.basename(
            path.rstrip('/'))  # Here use `rstrip` to cut out last '/' in path
    else:
        dirname = repo.name

    allow_download = parse_repo_perm(
        check_folder_permission(request, repo_id, '/')).can_download

    if allow_download:

        dir_id = seafile_api.get_dir_id_by_commit_and_path(
            repo.id, repo.head_cmmt_id, path)
        try:
            total_size = seafile_api.get_dir_size(repo.store_id, repo.version,
                                                  dir_id)
        except Exception as e:
            logger.error(str(e))
            return render_error(request, _('Internal Server Error'))

        if total_size > MAX_DOWNLOAD_DIR_SIZE:
            return render_error(
                request,
                _('Unable to download directory "%s": size is too large.') %
                dirname)

        is_windows = 0
        if is_windows_operating_system(request):
            is_windows = 1

        fake_obj_id = {
            'obj_id': dir_id,
            'dir_name': dirname,
            'is_windows': is_windows
        }

        token = seafile_api.get_fileserver_access_token(
            repo_id, json.dumps(fake_obj_id), 'download-dir',
            request.user.username)

        if not token:
            return render_error(request, _('Internal Server Error'))

    else:
        return render_error(request, _('Unable to download "%s"') % dirname)

    url = gen_file_get_url(token, dirname)
    from seahub.views.file import send_file_access_msg
    send_file_access_msg(request, repo, path, 'web')
    return redirect(url)
Ejemplo n.º 28
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))
Ejemplo n.º 29
0
def view_file_via_shared_dir(request, token):
    assert token is not None  # Checked by URLconf

    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = request.GET.get('p', '').rstrip('/')
    if not path:
        raise Http404
    if not path.startswith(
            fileshare.path):  # Can not view upper dir of shared dir
        raise Http404
    zipped = gen_path_link(path, '')

    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)

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

    img_prev = None
    img_next = None

    # get file content
    ret_dict = {
        'err': '',
        'file_content': '',
        'encoding': '',
        'file_enc': '',
        'file_encoding_list': [],
        'html_exists': False,
        'filetype': filetype
    }
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(
        file_size, 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)
        elif filetype == IMAGE:
            current_commit = get_commits(repo_id, 0, 1)[0]
            parent_dir = os.path.dirname(path)
            dirs = seafile_api.list_dir_by_commit_and_path(
                current_commit.repo_id, current_commit.id, parent_dir)
            if not dirs:
                raise Http404

            img_list = []
            for dirent in dirs:
                if not stat.S_ISDIR(dirent.props.mode):
                    fltype, flext = get_file_type_and_ext(dirent.obj_name)
                    if fltype == 'Image':
                        img_list.append(dirent.obj_name)

            if len(img_list) > 1:
                img_list.sort(lambda x, y: cmp(x.lower(), y.lower()))
                cur_img_index = img_list.index(filename)
                if cur_img_index != 0:
                    img_prev = posixpath.join(parent_dir,
                                              img_list[cur_img_index - 1])
                if cur_img_index != len(img_list) - 1:
                    img_next = posixpath.join(parent_dir,
                                              img_list[cur_img_index + 1])

        # 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))
Ejemplo n.º 30
0
    def post(self, request, workspace_id, name):
        # arguments check
        path = request.data.get('path')
        if not path:
            error_msg = 'path is invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        angle = request.data.get('angle')
        if not angle or angle not in ('90', '180', '270'):
            error_msg = 'angle is invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        angle = {'90': 2, '180': 3, '270': 4}[angle]

        # resource check
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % (workspace_id, )
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        dtable = DTables.objects.get_dtable(workspace, name)
        if not dtable:
            error_msg = 'Table %s not found.' % (name, )
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        parent_dir = os.path.join('/asset', str(dtable.uuid))
        asset_path = os.path.join(parent_dir, path.lstrip('/'))
        asset_id = seafile_api.get_file_id_by_path(workspace.repo_id,
                                                   asset_path)
        if not asset_id:
            error_msg = 'Picture %s not found.' % (path, )
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        asset_name = os.path.basename(path)
        file_type, _ = get_file_type_and_ext(asset_name)
        if file_type != file_types.IMAGE:
            error_msg = '%s is not a picture.' % (path, )
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # permission check
        user = request.user
        if check_dtable_permission(user.username, workspace,
                                   dtable) != PERMISSION_READ_WRITE:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # get token
        try:
            token = seafile_api.get_fileserver_access_token(workspace.repo_id,
                                                            asset_id,
                                                            'view',
                                                            '',
                                                            use_onetime=False)
        except Exception as e:
            logger.error('get view token error: %s', e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
        asset_url = gen_file_get_url(token, asset_name)

        # request pic
        try:
            response = requests.get(asset_url)
            if response.status_code != 200:
                logger.error('request asset url: %s response code: %s',
                             asset_url, response.status_code)
                error_msg = 'Internal Server Error.'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)
        except Exception as e:
            logger.error('request: %s error: %s', asset_url, e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
        img = response.content

        # get upload link
        old_img = Image.open(BytesIO(img))
        obj_id = json.dumps({'parent_dir': parent_dir})
        try:
            token = seafile_api.get_fileserver_access_token(workspace.repo_id,
                                                            obj_id,
                                                            'upload',
                                                            '',
                                                            use_onetime=False)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
        upload_link = gen_file_upload_url(token, 'upload-api')

        # upload
        try:
            # rotate and save to fp
            fp = BytesIO()
            content_type = response.headers['Content-Type']
            old_img.transpose(angle).save(fp, content_type.split('/')[1])
            response = requests.post(
                upload_link,
                data={
                    'parent_dir': parent_dir,
                    'relative_path': os.path.dirname(path.strip('/')),
                    'replace': 1
                },
                files={'file': (asset_name, fp.getvalue(), content_type)})
            if response.status_code != 200:
                logger.error('upload: %s status code: %s', upload_link,
                             response.status_code)
                error_msg = 'Internal Server Error.'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)
        except Exception as e:
            logger.error('upload rotated image error: %s', e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # remove thumbnails
        remove_thumbnail_by_id(asset_id)

        return Response({'success': True})
Ejemplo n.º 31
0
def get_onlyoffice_dict(request,
                        username,
                        repo_id,
                        file_path,
                        file_id='',
                        can_edit=False,
                        can_download=True):

    repo = seafile_api.get_repo(repo_id)
    if repo.is_virtual:
        origin_repo_id = repo.origin_repo_id
        origin_file_path = posixpath.join(repo.origin_path,
                                          file_path.strip('/'))
        # for view history/trash/snapshot file
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(origin_repo_id,
                                                      origin_file_path)
    else:
        origin_repo_id = repo_id
        origin_file_path = file_path
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(repo_id, file_path)

    dl_token = seafile_api.get_fileserver_access_token(repo_id,
                                                       file_id,
                                                       'download',
                                                       username,
                                                       use_onetime=True)
    if not dl_token:
        return None

    filetype, fileext = get_file_type_and_ext(file_path)
    if fileext in ('xls', 'xlsx', 'ods', 'fods', 'csv'):
        document_type = 'spreadsheet'
    elif fileext in ('pptx', 'ppt', 'odp', 'fodp', 'ppsx', 'pps'):
        document_type = 'presentation'
    else:
        document_type = 'text'

    cache_key = generate_onlyoffice_cache_key(repo_id, file_path)
    doc_key = cache.get(cache_key)

    # temporary solution when failed to get data from cache(django_pylibmc)
    # when init process for the first time
    if not doc_key:
        doc_key = cache.get(cache_key)

    if not doc_key:
        info_bytes = force_bytes(origin_repo_id + origin_file_path + file_id)
        doc_key = hashlib.md5(info_bytes).hexdigest()[:20]

    doc_info = json.dumps({
        'repo_id': repo_id,
        'file_path': file_path,
        'username': username
    })
    cache.set("ONLYOFFICE_%s" % doc_key, doc_info, None)

    file_name = os.path.basename(file_path.rstrip('/'))
    doc_url = gen_file_get_url(dl_token, file_name)

    base_url = get_site_scheme_and_netloc()
    onlyoffice_editor_callback_url = reverse('onlyoffice_editor_callback')
    callback_url = urllib.parse.urljoin(base_url,
                                        onlyoffice_editor_callback_url)

    return_dict = {
        'repo_id': repo_id,
        'path': file_path,
        'ONLYOFFICE_APIJS_URL': ONLYOFFICE_APIJS_URL,
        'file_type': fileext,
        'doc_key': doc_key,
        'doc_title': file_name,
        'doc_url': doc_url,
        'document_type': document_type,
        'callback_url': callback_url,
        'can_edit': can_edit,
        'can_download': can_download,
        'username': username,
        'onlyoffice_force_save': ONLYOFFICE_FORCE_SAVE,
        'enable_watermark': ENABLE_WATERMARK and not can_edit,
    }

    if ONLYOFFICE_JWT_SECRET:
        import jwt
        config = {
            "document": {
                "fileType": fileext,
                "key": doc_key,
                "title": file_name,
                "url": doc_url,
                "permissions": {
                    "download": can_download,
                    "edit": can_edit,
                    "print": can_download,
                    "review": True
                }
            },
            "documentType": document_type,
            "editorConfig": {
                "callbackUrl": callback_url,
                "lang": request.LANGUAGE_CODE,
                "mode": can_edit,
                "customization": {
                    "forcesave": ONLYOFFICE_FORCE_SAVE,
                },
                "user": {
                    "name": email2nickname(username)
                }
            }
        }

        return_dict['onlyoffice_jwt_token'] = jwt.encode(
            config, ONLYOFFICE_JWT_SECRET)

    return return_dict
Ejemplo n.º 32
0
    def get(self, request, slug):
        """Get content of a wiki
        """
        path = request.GET.get('p', '/')
        try:
            wiki = Wiki.objects.get(slug=slug)
        except Wiki.DoesNotExist:
            error_msg = "Wiki not found."
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # perm check
        if not wiki.check_access_wiki(request):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)
        
        if request.user.username:
            parent_dir = os.path.dirname(path)
            permission = check_folder_permission(request, wiki.repo_id, parent_dir)
        else:
            permission = 'r'

        try:
            repo = seafile_api.get_repo(wiki.repo_id)
            if not repo:
                error_msg = "Wiki library not found."
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        except SearpcError:
            error_msg = _("Internal Server Error")
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        file_id = None
        try:
            file_id = seafile_api.get_file_id_by_path(repo.repo_id, path)
        except SearpcError as e:
            logger.error(e)
            return api_error(HTTP_520_OPERATION_FAILED,
                             "Failed to get file id by path.")
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND, "File not found")

        # send stats message
        send_file_access_msg(request, repo, path, 'api')

        file_name = os.path.basename(path)
        token = seafile_api.get_fileserver_access_token(repo.repo_id,
                file_id, 'download', request.user.username, 'False')

        if not token:
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        url = gen_file_get_url(token, file_name)
        file_response = urllib2.urlopen(url)
        content = file_response.read()
        
        try:
            dirent = seafile_api.get_dirent_by_path(repo.repo_id, path)
            if dirent:
                latest_contributor, last_modified = dirent.modifier, dirent.mtime
            else:
                latest_contributor, last_modified = None, 0
        except SearpcError as e:
            logger.error(e)
            latest_contributor, last_modified = None, 0

        return Response({
            "content": content,
            "latest_contributor": email2nickname(latest_contributor),
            "last_modified": last_modified,
            "permission": permission,
            })
Ejemplo n.º 33
0
def view_shared_file(request, token):
    """
    Preview file via shared link.
    """
    assert token is not None  # Checked by URLconf

    try:
        fileshare = FileShare.objects.get(token=token)
    except FileShare.DoesNotExist:
        raise Http404

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = fileshare.path.rstrip('/')  # Normalize file path
    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(obj_id)

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view',
                                                     '')
    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(obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        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)

        # 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:
                obj_size = seafserv_threaded_rpc.get_file_size(obj_id)
                send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                             (repo.id, shared_by, obj_id, obj_size))
            except SearpcError, e:
                logger.error('Error when sending file-view message: %s' %
                             str(e))
Ejemplo n.º 34
0
            'obj_id': dir_id,
            'dir_name': dirname,
            'is_windows': is_windows
        }

        token = seafile_api.get_fileserver_access_token(
            repo_id, json.dumps(fake_obj_id), 'download-dir',
            request.user.username)

        if not token:
            return render_error(request, _(u'Internal Server Error'))

    else:
        return render_error(request, _(u'Unable to download "%s"') % dirname)

    url = gen_file_get_url(token, dirname)
    from seahub.views.file import send_file_access_msg
    send_file_access_msg(request, repo, path, 'web')
    return redirect(url)


def group_events_data(events):
    """
    Group events according to the date.
    """
    event_groups = []
    for e in events:
        e.time = utc_to_local(e.timestamp)
        e.date = e.time.strftime("%Y-%m-%d")
        if e.etype == 'repo-update':
            e.author = e.commit.creator_name
Ejemplo n.º 35
0
def view_shared_file(request, token):
    """
    Preview file via shared link.
    """
    assert token is not None    # Checked by URLconf

    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

    if fileshare.is_encrypted():
        if not check_share_link_access(request.user.username, token):
            d = {'token': token, 'view_name': 'view_shared_file', }
            if request.method == 'POST':
                post_values = request.POST.copy()
                post_values['enc_password'] = fileshare.password
                form = SharedLinkPasswordForm(post_values)
                d['form'] = form
                if form.is_valid():
                    # set cache for non-anonymous user
                    if request.user.is_authenticated():
                        set_share_link_access(request.user.username, token)
                else:
                    return render_to_response('share_access_validation.html', d,
                                              context_instance=RequestContext(request))
            else:
                return render_to_response('share_access_validation.html', d,
                                          context_instance=RequestContext(request))
    
    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = fileshare.path.rstrip('/') # Normalize file path 
    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id,
                                                     'view', '')
    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}
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(file_size, 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 == OPENDOCUMENT:
            if file_size == 0:
                ret_dict['err'] = _(u'Invalid file format.')
        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))
Ejemplo n.º 36
0
def group_discuss(request, group):
    if group.is_pub:
        raise Http404

    username = request.user.username
    form = MessageForm()

    # remove user notifications
    UserNotification.objects.seen_group_msg_notices(username, group.id)

    # Get all group members.
    members = get_group_members(group.id)

    """group messages"""
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(group_id=group.id).order_by("-timestamp"), 15)

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get("page", "1"))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        group_msgs = paginator.page(paginator.num_pages)

    group_msgs.page_range = paginator.get_page_range(group_msgs.number)

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    msg_attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [r.reply_to_id for r in msg_replies]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        msg.attachments = []
        for att in msg_attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == "/":
                repo = get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip("/")  # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == "file" and att.src == "recommend":
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = _(u"File does not exist")
                    else:
                        att.token = seafile_api.get_fileserver_access_token(att.repo_id, att.obj_id, "view", username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachments.append(att)

    # get available modules(wiki, etc)
    mods_available = get_available_mods_by_group(group.id)
    mods_enabled = get_enabled_mods_by_group(group.id)

    return render_to_response(
        "group/group_discuss.html",
        {
            "group": group,
            "is_staff": group.is_staff,
            "group_msgs": group_msgs,
            "form": form,
            "mods_enabled": mods_enabled,
            "mods_available": mods_available,
        },
        context_instance=RequestContext(request),
    )
Ejemplo n.º 37
0
def get_onlyoffice_dict(request,
                        username,
                        repo_id,
                        file_path,
                        file_id='',
                        can_edit=False,
                        can_download=True):

    logger.info('{} open file {} in repo {} with can_edit {}'.format(
        username, file_path, repo_id, can_edit))

    repo = seafile_api.get_repo(repo_id)
    if repo.is_virtual:
        origin_repo_id = repo.origin_repo_id
        origin_file_path = posixpath.join(repo.origin_path,
                                          file_path.strip('/'))
    else:
        origin_repo_id = repo_id
        origin_file_path = file_path

    # for view history/trash/snapshot file
    if not file_id:
        file_id = seafile_api.get_file_id_by_path(origin_repo_id,
                                                  origin_file_path)

    dl_token = seafile_api.get_fileserver_access_token(repo_id,
                                                       file_id,
                                                       'download',
                                                       username,
                                                       use_onetime=False)
    if not dl_token:
        return None

    filetype, fileext = get_file_type_and_ext(file_path)
    if fileext in ('xls', 'xlsx', 'ods', 'fods', 'csv'):
        document_type = 'cell'
    elif fileext in ('pptx', 'ppt', 'odp', 'fodp', 'ppsx', 'pps'):
        document_type = 'slide'
    else:
        document_type = 'word'

    if not can_edit:
        doc_key = generate_onlyoffice_doc_key(origin_repo_id, origin_file_path,
                                              file_id)
    else:
        doc_key = get_doc_key_by_repo_id_file_path(origin_repo_id,
                                                   origin_file_path)
        if doc_key:
            logger.info(
                'get doc_key {} from database by repo_id {} file_path {}'.
                format(doc_key, origin_repo_id, origin_file_path))
        else:
            doc_key = generate_onlyoffice_doc_key(origin_repo_id,
                                                  origin_file_path, file_id)
            save_doc_key(doc_key, username, origin_repo_id, origin_file_path)
            logger.info('save doc_key {} to database'.format(doc_key))

    # for render onlyoffice html
    file_name = os.path.basename(file_path.rstrip('/'))
    doc_url = gen_file_get_url(dl_token, file_name)

    base_url = get_site_scheme_and_netloc()
    onlyoffice_editor_callback_url = reverse('onlyoffice_editor_callback')
    callback_url = urllib.parse.urljoin(base_url,
                                        onlyoffice_editor_callback_url)

    return_dict = {
        'repo_id':
        repo_id,
        'path':
        file_path,
        'ONLYOFFICE_APIJS_URL':
        ONLYOFFICE_APIJS_URL,
        'file_type':
        fileext,
        'doc_key':
        doc_key,
        'doc_title':
        file_name,
        'doc_url':
        doc_url,
        'document_type':
        document_type,
        'callback_url':
        callback_url,
        'can_edit':
        can_edit,
        'can_download':
        can_download,
        'username':
        username,
        'onlyoffice_force_save':
        ONLYOFFICE_FORCE_SAVE,
        'enable_watermark':
        ENABLE_WATERMARK,
        'request_from_onlyoffice_desktop_editor':
        ONLYOFFICE_DESKTOP_EDITOR_HTTP_USER_AGENT
        in request.META.get('HTTP_USER_AGENT', ''),
    }

    if ONLYOFFICE_JWT_SECRET:
        import jwt
        config = {
            "document": {
                "fileType": fileext,
                "key": doc_key,
                "title": file_name,
                "url": doc_url,
                "permissions": {
                    "download": can_download,
                    "edit": can_edit,
                    "print": can_download,
                    "review": True
                }
            },
            "documentType": document_type,
            "editorConfig": {
                "callbackUrl": callback_url,
                "lang": request.LANGUAGE_CODE,
                "mode": can_edit,
                "customization": {
                    "forcesave": ONLYOFFICE_FORCE_SAVE,
                },
            }
        }

        if request.user.is_authenticated:
            user_dict = {"id": username, "name": email2nickname(username)}
            config['editorConfig']['user'] = user_dict
        else:
            anonymous_dict = {"request": True, "label": "Guest"}
            config['editorConfig']['customization'][
                'anonymous'] = anonymous_dict

        return_dict['onlyoffice_jwt_token'] = jwt.encode(
            config, ONLYOFFICE_JWT_SECRET)

    return return_dict
Ejemplo n.º 38
0
    def get(self, request, repo_id, format=None):

        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        path = request.GET.get('p', None)
        if not path:
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            file_id = seafile_api.get_file_id_by_path(repo_id, path)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if not file_id:
            error_msg = 'File %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if check_folder_permission(request, repo_id, path) is None:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # send stats message
        send_file_access_msg(request, repo, path, 'api')
        op = request.GET.get('op', 'download')
        if op == 'download':
            reuse = request.GET.get('reuse', '0')
            if reuse not in ('1', '0'):
                error_msg = "If you want to reuse file server access token for download file, you should set 'reuse' argument as '1'."
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
            use_onetime = False if reuse == '1' else True

            file_name = os.path.basename(path)
            token = seafile_api.get_fileserver_access_token(repo_id,
                file_id, op, request.user.username, use_onetime)
            redirect_url = gen_file_get_url(token, file_name)

            return Response({"url": redirect_url})

        elif op == 'downloadblks':
            blklist = []
            encrypted = False
            enc_version = 0
            if file_id != EMPTY_SHA1:
                try:
                    blks = seafile_api.list_blocks_by_file_id(repo_id, file_id)
                    blklist = blks.split('\n')
                except SearpcError as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            blklist = [i for i in blklist if len(i) == 40]
            if len(blklist) > 0:
                repo = seafile_api.get_repo(repo_id)
                encrypted = repo.encrypted
                enc_version = repo.enc_version

            res = {
                'file_id': file_id,
                'blklist': blklist,
                'encrypted': encrypted,
                'enc_version': enc_version,
                }

            return Response(res)

        elif op == 'sharelink':
            link = get_shared_link(request, repo_id, path)
            return Response({"link": link})

        else:
            error_msg = 'op invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
Ejemplo n.º 39
0
def file_edit(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    if request.method == 'POST':
        return file_edit_submit(request, repo_id)

    if get_user_permission(request, repo_id) != 'rw':
        return render_permission_error(request, _(u'Unable to edit file'))

    path = request.GET.get('p', '/')
    if path[-1] == '/':
        path = path[:-1]
    u_filename = os.path.basename(path)
    filename = urllib2.quote(u_filename.encode('utf-8'))

    head_id = repo.head_cmmt_id

    obj_id = get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'The file does not exist.'))

    token = web_get_access_token(repo_id, obj_id, 'view', request.user.username)

    # generate path and link
    zipped = gen_path_link(path, repo.name)

    filetype, fileext = get_file_type_and_ext(filename)

    op = None
    err = ''
    file_content = None
    encoding = None
    file_encoding_list = FILE_ENCODING_LIST
    if filetype == TEXT or filetype == MARKDOWN or filetype == SF: 
        if repo.encrypted:
            repo.password_set = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
            if not repo.password_set:
                op = 'decrypt'
        if not op:
            raw_path = gen_file_get_url(token, filename)
            file_enc = request.GET.get('file_enc', 'auto')
            if not file_enc in FILE_ENCODING_LIST:
                file_enc = 'auto'
            err, file_content, encoding = repo_file_get(raw_path, file_enc)
            if encoding and encoding not in FILE_ENCODING_LIST:
                file_encoding_list.append(encoding)
    else:
        err = _(u'Edit online is not offered for this type of file.')

    # Redirect to different place according to from page when user click
    # cancel button on file edit page.
    cancel_url = reverse('repo_view_file', args=[repo.id]) + '?p=' + urlquote(path)
    page_from = request.GET.get('from', '')
    gid = request.GET.get('gid', '')
    wiki_name = os.path.splitext(u_filename)[0]
    if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new':
        cancel_url = reverse('group_wiki', args=[gid, wiki_name])
    elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new':
        cancel_url = reverse('personal_wiki', args=[wiki_name])

    search_repo_id = None
    if not repo.encrypted:
        search_repo_id = repo.id

    return render_to_response('file_edit.html', {
        'repo':repo,
        'u_filename':u_filename,
        'wiki_name': wiki_name,
        'path':path,
        'zipped':zipped,
        'filetype':filetype,
        'fileext':fileext,
        'op':op,
        'err':err,
        'file_content':file_content,
        'encoding': encoding,
        'file_encoding_list':file_encoding_list,
        'head_id': head_id,
        'from': page_from,
        'gid': gid,
        'cancel_url': cancel_url,
        'search_repo_id': search_repo_id,
    }, context_instance=RequestContext(request))
Ejemplo n.º 40
0
def group_discuss(request, group):
    if group.is_pub:
        raise Http404

    username = request.user.username
    form = MessageForm()

    # remove user notifications
    UserNotification.objects.seen_group_msg_notices(username, group.id)

    # Get all group members.
    members = get_group_members(group.id)

    """group messages"""
    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(
            group_id=group.id).order_by('-timestamp'), 15)

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        group_msgs = paginator.page(paginator.num_pages)

    group_msgs.page_range = paginator.get_page_range(group_msgs.number)

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    msg_attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [ r.reply_to_id for r in msg_replies ]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        msg.attachments = []
        for att in msg_attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == '/':
                repo = get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip('/') # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == 'file' and att.src == 'recommend':
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = _(u'File does not exist')
                    else:
                        att.token = seafile_api.get_fileserver_access_token(
                            att.repo_id, att.obj_id, 'view', username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachments.append(att)

    # get available modules(wiki, etc)
    mods_available = get_available_mods_by_group(group.id)
    mods_enabled = get_enabled_mods_by_group(group.id)

    return render_to_response("group/group_discuss.html", {
            "group" : group,
            "is_staff": group.is_staff,
            "group_msgs": group_msgs,
            "form": form,
            "mods_enabled": mods_enabled,
            "mods_available": mods_available,
            }, context_instance=RequestContext(request))
Ejemplo n.º 41
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),
    )
Ejemplo n.º 42
0
    def get(self, request):
        """get file download link by dtable api token

        Permission:
        1. valid token
        """

        # argument check
        auth = request.META.get('HTTP_AUTHORIZATION', '').split()
        if not auth or auth[0].lower() != 'token' or len(auth) != 2:
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
        api_token = auth[1]

        path = request.GET.get('path', '/')

        # resource check
        try:
            api_token_obj = DTableAPIToken.objects.get_by_token(api_token)
            if not api_token_obj:
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'api token not found.')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        dtable = api_token_obj.dtable
        table_name = dtable.name
        workspace_id = dtable.workspace_id

        error, workspace, dtable = _resource_check(workspace_id, table_name)
        if error:
            return error

        repo_id = workspace.repo_id
        asset_dir_path = '/asset/' + str(dtable.uuid)
        asset_dir_id = seafile_api.get_dir_id_by_path(repo_id, asset_dir_path)
        if not asset_dir_id:
            error_msg = 'asset not found.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        target_path = os.path.join(
            asset_dir_path, path.strip('/'))  # target_path is path inside repo

        file_id = seafile_api.get_file_id_by_path(repo_id,
                                                  target_path.strip('/'))
        if not file_id:
            error_msg = 'path %s not found.' % path
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            download_token = seafile_api.get_fileserver_access_token(
                repo_id,
                file_id,
                'download-link',
                request.user.username,
                use_onetime=False)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        file_name = os.path.basename(path.rstrip('/'))
        download_link = gen_file_get_url(download_token, file_name)

        return Response({'download_link': download_link})
Ejemplo n.º 43
0
Archivo: file.py Proyecto: swpd/seahub
def view_file_via_shared_dir(request, token):
    assert token is not None  # Checked by URLconf

    try:
        fileshare = FileShare.objects.get(token=token)
    except FileShare.DoesNotExist:
        raise Http404

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = request.GET.get('p', '').rstrip('/')
    if not path:
        raise Http404
    if not path.startswith(
            fileshare.path):  # Can not view upper dir of shared dir
        raise Http404
    zipped = gen_path_link(path, '')

    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(obj_id)

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view',
                                                     '')
    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(obj_id)
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype)
    if exceeds_limit:
        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 == PDF:
            handle_pdf(inner_path, obj_id, fileext, ret_dict)

        # send statistic messages
        try:
            obj_size = seafserv_threaded_rpc.get_file_size(obj_id)
            send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                         (repo.id, shared_by, obj_id, obj_size))
        except SearpcError, e:
            logger.error('Error when sending file-view message: %s' % str(e))
Ejemplo n.º 44
0
def thumbnail_create(request, repo_id):

    content_type = 'application/json; charset=utf-8'
    result = {}

    if not request.is_ajax():
        err_msg = _(u"Permission denied.")
        return HttpResponse(json.dumps({"err_msg": err_msg}),
                            status=403,
                            content_type=content_type)

    if not ENABLE_THUMBNAIL:
        err_msg = _(u"Thumbnail function is not enabled.")
        return HttpResponse(json.dumps({"err_msg": err_msg}),
                            status=403,
                            content_type=content_type)

    repo = get_repo(repo_id)
    if not repo:
        err_msg = _(u"Library does not exist.")
        return HttpResponse(json.dumps({"err_msg": err_msg}),
                            status=403,
                            content_type=content_type)

    if repo.encrypted:
        err_msg = _(
            u"Image thumbnail is not supported in encrypted libraries.")
        return HttpResponse(json.dumps({"err_msg": err_msg}),
                            status=403,
                            content_type=content_type)

    path = request.GET.get('path', None)
    obj_id = get_file_id_by_path(repo_id, path)

    if path is None or obj_id is None:
        err_msg = _(u"Wrong path.")
        return HttpResponse(json.dumps({"err_msg": err_msg}),
                            status=403,
                            content_type=content_type)

    # permission check
    token = request.GET.get('t', None)
    if token:
        fileshare = FileShare.objects.get_valid_file_link_by_token(token)
        if not fileshare or not path.startswith(fileshare.path) or \
            fileshare.repo_id != repo_id:
            # check if is valid download link share token and
            # if is a valid repo/dir belonged to this file share
            err_msg = _(u"Permission denied.")
            return HttpResponse(json.dumps({"err_msg": err_msg}),
                                status=403,
                                content_type=content_type)
    else:
        if not request.user.is_authenticated():
            err_msg = _(u"Please login first.")
            return HttpResponse(json.dumps({"err_msg": err_msg}),
                                status=403,
                                content_type=content_type)
        elif check_repo_access_permission(repo_id, request.user) is None:
            err_msg = _(u"Permission denied.")
            return HttpResponse(json.dumps({"err_msg": err_msg}),
                                status=403,
                                content_type=content_type)

    # get image file from url
    size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE)
    file_name = os.path.basename(path)
    access_token = seafile_api.get_fileserver_access_token(
        repo_id, obj_id, 'view', request.user.username)
    raw_path = gen_file_get_url(access_token, file_name)
    open_file = urllib2.urlopen(raw_path)
    file_size = int(open_file.info()['Content-Length'])

    # image file size limit check
    if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2:
        err_msg = _(u"Image file is too large.")
        return HttpResponse(json.dumps({"err_msg": err_msg}),
                            status=520,
                            content_type=content_type)

    thumbnail_dir = os.path.join(THUMBNAIL_ROOT, size)
    if not os.path.exists(thumbnail_dir):
        os.makedirs(thumbnail_dir)

    thumbnail_file = os.path.join(thumbnail_dir, obj_id)
    if not os.path.exists(thumbnail_file):
        try:
            f = StringIO(open_file.read())
            image = Image.open(f)
            if image.mode not in ["1", "L", "P", "RGB", "RGBA"]:
                image = image.convert("RGB")
            image.thumbnail((int(size), int(size)), Image.ANTIALIAS)
            image.save(thumbnail_file, THUMBNAIL_EXTENSION)
        except Exception as e:
            logger.error(e)
            err_msg = _('Failed to create thumbnail.')
            return HttpResponse(json.dumps({'err_msg': err_msg}),
                                status=500,
                                content_type=content_type)

    result['thumbnail_src'] = get_thumbnail_src(repo_id, obj_id, size)
    return HttpResponse(json.dumps(result), content_type=content_type)
Ejemplo n.º 45
0
def get_onlyoffice_dict(username, repo_id, file_path,
        file_id='', can_edit=False, can_download=True):

    repo = seafile_api.get_repo(repo_id)
    if repo.is_virtual:
        origin_repo_id = repo.origin_repo_id
        origin_file_path = posixpath.join(repo.origin_path, file_path.strip('/'))
        # for view history/trash/snapshot file
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(origin_repo_id,
                    origin_file_path)
    else:
        origin_repo_id = repo_id
        origin_file_path = file_path
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(repo_id,
                    file_path)

    dl_token = seafile_api.get_fileserver_access_token(repo_id,
            file_id, 'download', username, use_onetime=True)
    if not dl_token:
        return None

    filetype, fileext = get_file_type_and_ext(file_path)
    if fileext in ('xls', 'xlsx', 'ods', 'fods', 'csv'):
        document_type = 'spreadsheet'
    elif fileext in ('pptx', 'ppt', 'odp', 'fodp', 'ppsx', 'pps'):
        document_type = 'presentation'
    else:
        document_type = 'text'

    cache_key = generate_onlyoffice_cache_key(repo_id, file_path)
    doc_key = cache.get(cache_key)

    # temporary solution when failed to get data from cache(django_pylibmc)
    # when init process for the first time
    if not doc_key:
        doc_key = cache.get(cache_key)

    if not doc_key:
        doc_key = hashlib.md5(force_bytes(origin_repo_id + origin_file_path + file_id)).hexdigest()[:20]

    doc_info = json.dumps({'repo_id': repo_id, 'file_path': file_path, 'username': username})
    cache.set("ONLYOFFICE_%s" % doc_key, doc_info, None)

    file_name = os.path.basename(file_path.rstrip('/'))
    doc_url = gen_file_get_url(dl_token, file_name)

    base_url = get_site_scheme_and_netloc()
    onlyoffice_editor_callback_url = reverse('onlyoffice_editor_callback')
    calllback_url = urllib.parse.urljoin(base_url, onlyoffice_editor_callback_url)

    return_dict = {
        'repo_id': repo_id,
        'path': file_path,
        'ONLYOFFICE_APIJS_URL': ONLYOFFICE_APIJS_URL,
        'file_type': fileext,
        'doc_key': doc_key,
        'doc_title': file_name,
        'doc_url': doc_url,
        'document_type': document_type,
        'callback_url': calllback_url,
        'can_edit': can_edit,
        'can_download': can_download,
        'username': username,
        'onlyoffice_force_save': ONLYOFFICE_FORCE_SAVE,
        'enable_watermark': ENABLE_WATERMARK and not can_edit,
    }

    return return_dict
Ejemplo n.º 46
0
    def get(self, request):
        """ Return file info.
        """

        # argument check
        doc_id = request.GET.get('doc_id', '')
        if not doc_id:
            error_msg = 'doc_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_info = cache.get('BISHENG_OFFICE_' + doc_id)
        if not file_info:
            error_msg = 'doc_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        username = file_info.get('username')
        if not username:
            error_msg = 'username invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        repo_id = file_info.get('repo_id')
        if not repo_id:
            error_msg = 'repo_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_path = file_info.get('file_path')
        if not file_path:
            error_msg = 'file_path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_path = normalize_file_path(file_path)

        # resource check
        try:
            User.objects.get(email=username)
        except User.DoesNotExist:
            error_msg = 'User %s not found.' % username
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if not seafile_api.get_repo(repo_id):
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if not seafile_api.get_file_id_by_path(repo_id, file_path):
            error_msg = 'File %s not found.' % file_path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        parent_dir = os.path.dirname(file_path)
        permission = seafile_api.check_permission_by_path(repo_id, parent_dir, username)
        if not permission:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # get file basic info
        file_name = os.path.basename(file_path.rstrip('/'))
        filetype, fileext = get_file_type_and_ext(file_name)

        # get file raw url
        file_id = seafile_api.get_file_id_by_path(repo_id, file_path)
        download_token = seafile_api.get_fileserver_access_token(repo_id,
                file_id, 'download', username, use_onetime=True)
        raw_url = gen_file_get_url(download_token, file_name)

        # get avatar url
        url, _, _ = api_avatar_url(username, int(72))

        # prepare file permission
        privilege = copy.deepcopy(BISHENG_OFFICE_PRIVILEGE)
        can_edit = file_info.get('can_edit', False)
        if not can_edit:
            privilege.remove('FILE_WRITE')

        # prepare response
        file_info = {
            'doc': {
                'docId': doc_id,
                'title': file_name,
                'mime_type': BISHENG_OFFICE_MIME_TYPE[fileext],
                'fetchUrl': raw_url,
                'thumbnail': "",
                'fromApi': True
            },
            'user': {
                'uid': username,
                'oid': username,
                'nickName': email2nickname(username),
                'avatar': url,
                'privilege': privilege
            },
        }

        return Response(file_info)
Ejemplo n.º 47
0
def view_shared_file(request, token):
    """
    Preview file via shared link.
    """
    assert token is not None  # Checked by URLconf

    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

    if fileshare.is_encrypted():
        if not check_share_link_access(request.user.username, token):
            d = {
                'token': token,
                'view_name': 'view_shared_file',
            }
            if request.method == 'POST':
                post_values = request.POST.copy()
                post_values['enc_password'] = fileshare.password
                form = SharedLinkPasswordForm(post_values)
                d['form'] = form
                if form.is_valid():
                    # set cache for non-anonymous user
                    if request.user.is_authenticated():
                        set_share_link_access(request.user.username, token)
                else:
                    return render_to_response(
                        'share_access_validation.html',
                        d,
                        context_instance=RequestContext(request))
            else:
                return render_to_response(
                    'share_access_validation.html',
                    d,
                    context_instance=RequestContext(request))

    shared_by = fileshare.username
    repo_id = fileshare.repo_id
    repo = get_repo(repo_id)
    if not repo:
        raise Http404

    path = fileshare.path.rstrip('/')  # Normalize file path
    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id)

    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view',
                                                     '')
    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
    }
    exceeds_limit, err_msg = file_size_exceeds_preview_limit(
        file_size, 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 == OPENDOCUMENT:
            if file_size == 0:
                ret_dict['err'] = _(u'Invalid file format.')
        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))
Ejemplo n.º 48
0
def dtable_asset_preview(request, workspace_id, dtable_id, path):

    # resource check
    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        return render_error(request, 'Workspace does not exist.')

    repo_id = workspace.repo_id
    repo = seafile_api.get_repo(repo_id)
    if not repo:
        return render_error(request, 'Library does not exist.')

    dtable = DTables.objects.get_dtable_by_uuid(dtable_id)
    if not dtable:
        return render_error(request, 'DTable does not exist.')

    asset_path = normalize_file_path(os.path.join('/asset', dtable_id, path))
    asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path)
    if not asset_id:
        return render_error(request, 'Asset file does not exist.')

    # permission check
    username = request.user.username
    if not check_dtable_permission(username, workspace, dtable):
        return render_permission_error(request, _('Permission denied.'))

    file_enc = request.GET.get('file_enc', 'auto')
    if file_enc not in FILE_ENCODING_LIST:
        file_enc = 'auto'

    token = seafile_api.get_fileserver_access_token(repo_id,
                                                    asset_id,
                                                    'view',
                                                    '',
                                                    use_onetime=False)

    file_name = os.path.basename(normalize_file_path(path))
    file_type, file_ext = get_file_type_and_ext(file_name)

    inner_path = gen_inner_file_get_url(token, file_name)
    error_msg, file_content, encoding = get_file_content(
        file_type, inner_path, file_enc)

    raw_path = gen_file_get_url(token, file_name)
    download_url = '%s/workspace/%s/asset/%s/%s?dl=1' % (
        DTABLE_WEB_SERVICE_URL.strip('/'), workspace_id, dtable_id, path)

    return_dict = {
        'repo': repo,
        'filename': file_name,
        'file_path': asset_path,
        'file_type': file_type,
        'file_ext': file_ext,
        'raw_path': raw_path,
        'download_url': download_url,
        'file_content': file_content,
        'err':
        'File preview unsupported' if file_type == 'Unknown' else error_msg,
    }

    return render(request, 'dtable_asset_file_view_react.html', return_dict)
Ejemplo n.º 49
0
def get_group_msgs(groupid, page, username):

    # Show 15 group messages per page.
    paginator = Paginator(GroupMessage.objects.filter(
            group_id=groupid).order_by('-timestamp'), 15)

    # If page request (9999) is out of range, return None
    try:
        group_msgs = paginator.page(page)
    except (EmptyPage, InvalidPage):
        return None

    # Force evaluate queryset to fix some database error for mysql.
    group_msgs.object_list = list(group_msgs.object_list)

    attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list)

    msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list)
    reply_to_list = [ r.reply_to_id for r in msg_replies ]

    for msg in group_msgs.object_list:
        msg.reply_cnt = reply_to_list.count(msg.id)
        msg.replies = []
        for r in msg_replies:
            if msg.id == r.reply_to_id:
                msg.replies.append(r)
        msg.replies = msg.replies[-3:]

        for att in attachments:
            if att.group_message_id != msg.id:
                continue

            # Attachment name is file name or directory name.
            # If is top directory, use repo name instead.
            path = att.path
            if path == '/':
                repo = seafile_api.get_repo(att.repo_id)
                if not repo:
                    # TODO: what should we do here, tell user the repo
                    # is no longer exists?
                    continue
                att.name = repo.name
            else:
                path = path.rstrip('/') # cut out last '/' if possible
                att.name = os.path.basename(path)

            # Load to discuss page if attachment is a image and from recommend.
            if att.attach_type == 'file' and att.src == 'recommend':
                att.filetype, att.fileext = get_file_type_and_ext(att.name)
                if att.filetype == IMAGE:
                    att.obj_id = seafile_api.get_file_id_by_path(att.repo_id, path)
                    if not att.obj_id:
                        att.err = 'File does not exist'
                    else:
                        att.token = seafile_api.get_fileserver_access_token(
                            att.repo_id, att.obj_id, 'view', username)
                        att.img_url = gen_file_get_url(att.token, att.name)

            msg.attachment = att

    return group_msgs
Ejemplo n.º 50
0
def dtable_plugin_asset_view(request, workspace_id, name, plugin_id, path):
    """
    Permission:
    1. owner
    2. group member
    3. shared user
    """

    try:
        plugin_record = DTablePlugins.objects.get(pk=plugin_id)
    except DTablePlugins.DoesNotExist:
        error_msg = 'Plugin %s not found.' % plugin_id
        return render_error(request, error_msg)

    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        error_msg = 'Workspace %s not found.' % workspace_id
        return render_error(request, error_msg)

    if '@seafile_group' in workspace.owner:
        group_id = workspace.owner.split('@')[0]
        group = ccnet_api.get_group(int(group_id))
        if not group:
            error_msg = 'Group %s not found.' % group_id
            return render_error(request, error_msg)
    table_name = name
    dtable = DTables.objects.get_dtable(workspace, table_name)
    if not dtable:
        error_msg = 'DTable %s not found.' % table_name
        return render_error(request, error_msg)

    # permission check
    username = request.user.username
    permission = check_dtable_permission(username, workspace, dtable)
    if not permission:
        error_msg = 'Permission denied.'
        return render_error(request, error_msg)

    repo_id = workspace.repo_id
    repo = seafile_api.get_repo(repo_id)
    if not repo:
        error_msg = 'Library %s not found.' % repo_id
        return render_error(request, error_msg)

    plugin_file_path = os.path.join('/asset', str(dtable.uuid), 'plugins',
                                    plugin_record.name)
    asset_path = os.path.join(plugin_file_path, path)

    plugin_file_dir_id = seafile_api.get_file_id_by_path(repo_id, asset_path)
    if not plugin_file_dir_id:
        return render_error(request, 'Asset file does not exist.')

    token = seafile_api.get_fileserver_access_token(workspace.repo_id,
                                                    plugin_file_dir_id,
                                                    'view',
                                                    '',
                                                    use_onetime=False)

    url = gen_file_get_url(token, asset_path)
    import requests
    r = requests.get(url)
    response = HttpResponse(r.content)

    content_type = mimetypes.guess_type(path)
    if type:
        response['Content-Type'] = content_type[0]

    return response
Ejemplo n.º 51
0
    def get(self, request, token):
        """ Get FileServer download url of the shared file/dir.

        Permission checking:
        1. only admin can perform this action.
        """

        try:
            sharelink = FileShare.objects.get(token=token)
        except FileShare.DoesNotExist:
            error_msg = 'Share link %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        repo_id = sharelink.repo_id
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library not found.'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        result = {}
        obj_path = sharelink.path
        if sharelink.s_type == 'f':
            # download shared file
            obj_id = seafile_api.get_file_id_by_path(repo_id, obj_path)
            if not obj_id:
                error_msg = 'File not found.'
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            try:
                # `username` parameter only used for encrypted repo
                download_token = seafile_api.get_fileserver_access_token(
                    repo_id,
                    obj_id,
                    'download-link',
                    sharelink.username,
                    use_onetime=False)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if not download_token:
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            obj_name = os.path.basename(obj_path.rstrip('/'))
            result['download_link'] = gen_file_get_url(download_token,
                                                       obj_name)
        else:
            # download (sub) file/folder in shared dir
            obj_id = seafile_api.get_dir_id_by_path(repo_id, obj_path)
            if not obj_id:
                error_msg = 'Folder not found.'
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            download_type = request.GET.get('type', None)
            if not download_type or download_type not in ('file', 'folder'):
                error_msg = 'type invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            req_path = request.GET.get('path', None)
            if not req_path:
                error_msg = 'path invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if req_path == '/':
                real_path = obj_path
            else:
                real_path = posixpath.join(obj_path, req_path.strip('/'))

            if download_type == 'file':
                # download sub file in shared dir
                real_obj_id = seafile_api.get_file_id_by_path(
                    repo_id, real_path)
                if not real_obj_id:
                    error_msg = 'File not found.'
                    return api_error(status.HTTP_404_NOT_FOUND, error_msg)

                try:
                    download_token = seafile_api.get_fileserver_access_token(
                        repo_id,
                        real_obj_id,
                        'download-link',
                        sharelink.username,
                        use_onetime=False)
                except Exception as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     error_msg)

                if not download_token:
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     error_msg)

                file_name = os.path.basename(real_path.rstrip('/'))
                result['download_link'] = gen_file_get_url(
                    download_token, file_name)
            else:
                # download sub folder in shared dir
                if real_path[-1] != '/':
                    real_path += '/'

                real_obj_id = seafile_api.get_dir_id_by_path(
                    repo_id, real_path)
                if not real_obj_id:
                    error_msg = 'Folder %s not found.' % req_path
                    return api_error(status.HTTP_404_NOT_FOUND, error_msg)

                dir_name = repo.name if real_path == '/' else \
                        os.path.basename(real_path.rstrip('/'))

                dir_size = seafile_api.get_dir_size(repo.store_id,
                                                    repo.version, real_obj_id)
                if dir_size > seaserv.MAX_DOWNLOAD_DIR_SIZE:
                    error_msg = 'Unable to download directory "%s": size is too large.' % dir_name
                    return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

                # get file server access token
                is_windows = 0
                if is_windows_operating_system(request):
                    is_windows = 1

                fake_obj_id = {
                    'obj_id': real_obj_id,
                    'dir_name': dir_name,
                    'is_windows': is_windows
                }

                try:
                    zip_token = seafile_api.get_fileserver_access_token(
                        repo_id,
                        json.dumps(fake_obj_id),
                        'download-dir-link',
                        sharelink.username,
                        use_onetime=False)
                except Exception as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     error_msg)

                result['download_link'] = gen_dir_zip_download_url(zip_token)

        return Response(result)
Ejemplo n.º 52
0
def get_onlyoffice_dict(request,
                        username,
                        repo_id,
                        file_path,
                        file_id='',
                        can_edit=False,
                        can_download=True):

    logger.info('{} open file {} in repo {} with can_edit {}'.format(
        username, file_path, repo_id, can_edit))

    repo = seafile_api.get_repo(repo_id)
    if repo.is_virtual:
        origin_repo_id = repo.origin_repo_id
        origin_file_path = posixpath.join(repo.origin_path,
                                          file_path.strip('/'))
        # for view history/trash/snapshot file
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(origin_repo_id,
                                                      origin_file_path)
    else:
        origin_repo_id = repo_id
        origin_file_path = file_path
        if not file_id:
            file_id = seafile_api.get_file_id_by_path(repo_id, file_path)

    dl_token = seafile_api.get_fileserver_access_token(repo_id,
                                                       file_id,
                                                       'download',
                                                       username,
                                                       use_onetime=False)
    if not dl_token:
        return None

    filetype, fileext = get_file_type_and_ext(file_path)
    if fileext in ('xls', 'xlsx', 'ods', 'fods', 'csv'):
        document_type = 'spreadsheet'
    elif fileext in ('pptx', 'ppt', 'odp', 'fodp', 'ppsx', 'pps'):
        document_type = 'presentation'
    else:
        document_type = 'text'

    if not can_edit:
        info_bytes = force_bytes(origin_repo_id + origin_file_path + file_id)
        doc_key = hashlib.md5(info_bytes).hexdigest()[:20]
    else:
        cache_key = generate_onlyoffice_cache_key(origin_repo_id,
                                                  origin_file_path)
        doc_key = cache.get(cache_key)

        # temporary solution when failed to get data from cache(django_pylibmc)
        # when init process for the first time
        if not doc_key:
            doc_key = cache.get(cache_key)

        if doc_key:
            logger.info('get doc_key {} from cache by cache_key {}'.format(
                doc_key, cache_key))
        else:
            # In theory, file is unlocked when editing finished.
            # This can happend if memcache is restarted or memcache is full and doc key is deleted.
            if if_locked_by_online_office(repo_id, file_path):
                logger.warning(
                    'no doc_key in cache, but file {} in {} is locked by online office'
                    .format(file_path, repo_id))

            # generate doc_key
            info_bytes = force_bytes(origin_repo_id + origin_file_path +
                                     file_id)
            doc_key = hashlib.md5(info_bytes).hexdigest()[:20]
            logger.info(
                'generate new doc_key {} by repo_id {} file_path {} file_id {}'
                .format(doc_key, origin_repo_id, origin_file_path, file_id))
            logger.info('set cache_key {} and doc_key {} to cache'.format(
                cache_key, doc_key))
            cache.set(cache_key, doc_key, None)

        if not cache.get("ONLYOFFICE_%s" % doc_key):

            doc_info = json.dumps({
                'repo_id': origin_repo_id,
                'file_path': origin_file_path,
                'username': username
            })

            cache.set("ONLYOFFICE_%s" % doc_key, doc_info, None)
            logger.info('set doc_key {} and doc_info {} to cache'.format(
                doc_key, doc_info))

    # for render onlyoffice html
    file_name = os.path.basename(file_path.rstrip('/'))
    doc_url = gen_file_get_url(dl_token, file_name)

    base_url = get_site_scheme_and_netloc()
    onlyoffice_editor_callback_url = reverse('onlyoffice_editor_callback')
    callback_url = urllib.parse.urljoin(base_url,
                                        onlyoffice_editor_callback_url)

    return_dict = {
        'repo_id': repo_id,
        'path': file_path,
        'ONLYOFFICE_APIJS_URL': ONLYOFFICE_APIJS_URL,
        'file_type': fileext,
        'doc_key': doc_key,
        'doc_title': file_name,
        'doc_url': doc_url,
        'document_type': document_type,
        'callback_url': callback_url,
        'can_edit': can_edit,
        'can_download': can_download,
        'username': username,
        'onlyoffice_force_save': ONLYOFFICE_FORCE_SAVE,
        'enable_watermark': ENABLE_WATERMARK,
    }

    if ONLYOFFICE_JWT_SECRET:
        import jwt
        config = {
            "document": {
                "fileType": fileext,
                "key": doc_key,
                "title": file_name,
                "url": doc_url,
                "permissions": {
                    "download": can_download,
                    "edit": can_edit,
                    "print": can_download,
                    "review": True
                }
            },
            "documentType": document_type,
            "editorConfig": {
                "callbackUrl": callback_url,
                "lang": request.LANGUAGE_CODE,
                "mode": can_edit,
                "customization": {
                    "forcesave": ONLYOFFICE_FORCE_SAVE,
                },
                "user": {
                    "name": email2nickname(username)
                }
            }
        }

        return_dict['onlyoffice_jwt_token'] = jwt.encode(
            config, ONLYOFFICE_JWT_SECRET)

    return return_dict
Ejemplo n.º 53
0
        except Exception, e:
            logger.error(str(e))
            return render_error(request, _(u'Internal Error'))

        if total_size > MAX_DOWNLOAD_DIR_SIZE:
            return render_error(request, _(u'Unable to download directory "%s": size is too large.') % dirname)

        token = seafile_api.get_fileserver_access_token(repo_id,
                                                        dir_id,
                                                        'download-dir',
                                                        request.user.username)

    else:
        return render_error(request, _(u'Unable to download "%s"') % dirname )

    url = gen_file_get_url(token, dirname)
    from seahub.views.file import send_file_access_msg
    send_file_access_msg(request, repo, path, 'web')
    return redirect(url)

def group_events_data(events):
    """
    Group events according to the date.
    """
    event_groups = []
    for e in events:
        e.time = utc_to_local(e.timestamp)
        e.date = e.time.strftime("%Y-%m-%d")
        if e.etype == 'repo-update':
            e.author = e.commit.creator_name
        elif e.etype == 'repo-create':
Ejemplo n.º 54
0
def get_file_url(repo, obj_id, file_name):
    repo_id = repo.id
    access_token = seaserv.seafserv_rpc.web_get_access_token(repo_id, obj_id,
                                                     'view', '')
    url = gen_file_get_url(access_token, file_name)
    return url
Ejemplo n.º 55
0
def thumbnail_create(request, repo_id):

    content_type = 'application/json; charset=utf-8'
    result = {}

    if not request.is_ajax():
        err_msg = _(u"Permission denied.")
        return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                            content_type=content_type)

    if not ENABLE_THUMBNAIL:
        err_msg = _(u"Thumbnail function is not enabled.")
        return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                            content_type=content_type)

    repo = get_repo(repo_id)
    if not repo:
        err_msg = _(u"Library does not exist.")
        return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                            content_type=content_type)

    if repo.encrypted:
        err_msg = _(u"Image thumbnail is not supported in encrypted libraries.")
        return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                            content_type=content_type)

    path = request.GET.get('path', None)
    obj_id = get_file_id_by_path(repo_id, path)

    if path is None or obj_id is None:
        err_msg = _(u"Wrong path.")
        return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                            content_type=content_type)

    # permission check
    token = request.GET.get('t', None)
    if token:
        fileshare = FileShare.objects.get_valid_file_link_by_token(token)
        if not fileshare or not path.startswith(fileshare.path) or \
            fileshare.repo_id != repo_id:
            # check if is valid download link share token and
            # if is a valid repo/dir belonged to this file share
            err_msg = _(u"Permission denied.")
            return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                                content_type=content_type)
    else:
        if not request.user.is_authenticated():
            err_msg = _(u"Please login first.")
            return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                                content_type=content_type)
        elif check_repo_access_permission(repo_id, request.user) is None:
            err_msg = _(u"Permission denied.")
            return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
                                content_type=content_type)

    # get image file from url
    size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE)
    file_name = os.path.basename(path)
    access_token = seafile_api.get_fileserver_access_token(repo_id,
                                                           obj_id,
                                                           'view',
                                                           request.user.username)
    raw_path = gen_file_get_url(access_token, file_name)
    open_file = urllib2.urlopen(raw_path)
    file_size = int(open_file.info()['Content-Length'])

    # image file size limit check
    if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2:
        err_msg = _(u"Image file is too large.")
        return HttpResponse(json.dumps({"err_msg": err_msg}), status=520,
                            content_type=content_type)

    thumbnail_dir = os.path.join(THUMBNAIL_ROOT, size)
    if not os.path.exists(thumbnail_dir):
        os.makedirs(thumbnail_dir)

    thumbnail_file = os.path.join(thumbnail_dir, obj_id)
    if not os.path.exists(thumbnail_file):
        try:
            f = StringIO(open_file.read())
            image = Image.open(f)
            if image.mode not in ["1", "L", "P", "RGB", "RGBA"]:
                image = image.convert("RGB")
            image.thumbnail((int(size), int(size)), Image.ANTIALIAS)
            image.save(thumbnail_file, THUMBNAIL_EXTENSION)
        except Exception as e:
            logger.error(e)
            err_msg = _('Failed to create thumbnail.')
            return HttpResponse(json.dumps({'err_msg': err_msg}), status=500,
                                content_type=content_type)

    result['thumbnail_src'] = get_thumbnail_src(repo_id, obj_id, size)
    return HttpResponse(json.dumps(result), content_type=content_type)
Ejemplo n.º 56
0
    def get(self, request, repo_id, format=None):

        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        path = request.GET.get('p', None)
        if not path:
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        try:
            file_id = seafile_api.get_file_id_by_path(repo_id, path)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if not file_id:
            error_msg = 'File %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if check_folder_permission(request, repo_id, path) is None:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # send stats message
        send_file_access_msg(request, repo, path, 'api')
        op = request.GET.get('op', 'download')
        if op == 'download':
            reuse = request.GET.get('reuse', '0')
            if reuse not in ('1', '0'):
                error_msg = "If you want to reuse file server access token for download file, you should set 'reuse' argument as '1'."
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
            use_onetime = False if reuse == '1' else True

            file_name = os.path.basename(path)
            token = seafile_api.get_fileserver_access_token(
                repo_id, file_id, op, request.user.username, use_onetime)
            redirect_url = gen_file_get_url(token, file_name)

            return Response({"url": redirect_url})

        elif op == 'downloadblks':
            blklist = []
            encrypted = False
            enc_version = 0
            if file_id != EMPTY_SHA1:
                try:
                    blks = seafile_api.list_blocks_by_file_id(repo_id, file_id)
                    blklist = blks.split('\n')
                except SearpcError as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     error_msg)

            blklist = [i for i in blklist if len(i) == 40]
            if len(blklist) > 0:
                repo = seafile_api.get_repo(repo_id)
                encrypted = repo.encrypted
                enc_version = repo.enc_version

            res = {
                'file_id': file_id,
                'blklist': blklist,
                'encrypted': encrypted,
                'enc_version': enc_version,
            }

            return Response(res)

        elif op == 'sharelink':
            link = get_shared_link(request, repo_id, path)
            return Response({"link": link})

        else:
            error_msg = 'op invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)