Example #1
0
def generate_thumbnail(request, repo_id, size, path):
    """ generate and save thumbnail if not exist

    before generate thumbnail, you should check:
    1. if repo exist: should exist;
    2. if repo is encrypted: not encrypted;
    3. if ENABLE_THUMBNAIL: enabled;
    """

    try:
        size = int(size)
    except ValueError as e:
        logger.error(e)
        return (False, 400)

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

    file_id = get_file_id_by_path(repo_id, path)
    if not file_id:
        return (False, 400)

    thumbnail_file = os.path.join(thumbnail_dir, file_id)
    if os.path.exists(thumbnail_file):
        return (True, 200)

    repo = get_repo(repo_id)
    file_size = get_file_size(repo.store_id, repo.version, file_id)
    if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2:
        return (False, 403)

    token = seafile_api.get_fileserver_access_token(repo_id,
                                                    file_id,
                                                    'view',
                                                    '',
                                                    use_onetime=True)

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    try:
        image_file = urllib2.urlopen(inner_path)
        f = StringIO(image_file.read())
        image = Image.open(f)

        # check image memory cost size limit
        # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask)
        # every pixel will cost 4 byte in RGBA mode
        width, height = image.size
        image_memory_cost = width * height * 4 / 1024 / 1024
        if image_memory_cost > THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT:
            return (False, 403)

        if image.mode not in ["1", "L", "P", "RGB", "RGBA"]:
            image = image.convert("RGB")
        image.thumbnail((size, size), Image.ANTIALIAS)
        image.save(thumbnail_file, THUMBNAIL_EXTENSION)
        return (True, 200)
    except Exception as e:
        logger.error(e)
        return (False, 500)
Example #2
0
def create_video_thumbnails(repo, file_id, path, size, thumbnail_file, file_size):

    t1 = timeit.default_timer()
    token = seafile_api.get_fileserver_access_token(repo.id,
            file_id, 'view', '', use_onetime=False)

    if not token:
        return (False, 500)

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    clip = VideoFileClip(inner_path)
    tmp_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id[:8]))

    clip.save_frame(tmp_path, t=THUMBNAIL_VIDEO_FRAME_TIME)
    t2 = timeit.default_timer()
    logger.debug('Create thumbnail of [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1)))

    try:
        ret = _create_thumbnail_common(tmp_path, thumbnail_file, size)
        os.unlink(tmp_path)
        return ret
    except Exception as e:
        logger.error(e)
        os.unlink(tmp_path)
        return (False, 500)
Example #3
0
def extract_xmind_image(repo_id, path, size=XMIND_IMAGE_SIZE):

    # get inner path
    file_name = os.path.basename(path)
    file_id = seafile_api.get_file_id_by_path(repo_id, path)
    fileserver_token = seafile_api.get_fileserver_access_token(repo_id,
            file_id, 'view', '')
    inner_path = gen_inner_file_get_url(fileserver_token, file_name)

    # extract xmind image
    xmind_file = urllib2.urlopen(inner_path)
    xmind_file_str = StringIO(xmind_file.read())
    xmind_zip_file = zipfile.ZipFile(xmind_file_str, 'r')
    extracted_xmind_image = xmind_zip_file.read('Thumbnails/thumbnail.png')
    extracted_xmind_image_str = StringIO(extracted_xmind_image)

    # save origin xmind image to thumbnail folder
    thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size))
    if not os.path.exists(thumbnail_dir):
        os.makedirs(thumbnail_dir)
    local_xmind_image = os.path.join(thumbnail_dir, file_id)

    try:
        ret = _create_thumbnail_common(extracted_xmind_image_str, local_xmind_image, size)
        return ret
    except Exception as e:
        logger.error(e)
        return (False, 500)
Example #4
0
def generate_thumbnail(request, repo_id, size, path):
    """ generate and save thumbnail if not exist

    before generate thumbnail, you should check:
    1. if repo exist: should exist;
    2. if repo is encrypted: not encrypted;
    3. if ENABLE_THUMBNAIL: enabled;
    """

    try:
        size = int(size)
    except ValueError as e:
        logger.error(e)
        return (False, 400)

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

    file_id = get_file_id_by_path(repo_id, path)
    if not file_id:
        return (False, 400)

    thumbnail_file = os.path.join(thumbnail_dir, file_id)
    if os.path.exists(thumbnail_file):
        return (True, 200)

    repo = get_repo(repo_id)
    file_size = get_file_size(repo.store_id, repo.version, file_id)
    filetype, fileext = get_file_type_and_ext(os.path.basename(path))

    if filetype == VIDEO:
        # video thumbnails
        if ENABLE_VIDEO_THUMBNAIL:
            return create_video_thumbnails(repo, file_id, path, size,
                                           thumbnail_file, file_size)
        else:
            return (False, 400)

    # image thumbnails
    if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2:
        return (False, 403)

    token = seafile_api.get_fileserver_access_token(repo_id,
                                                    file_id,
                                                    'view',
                                                    '',
                                                    use_onetime=True)

    if not token:
        return (False, 500)

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    try:
        image_file = urllib2.urlopen(inner_path)
        f = StringIO(image_file.read())
        return _create_thumbnail_common(f, thumbnail_file, size)
    except Exception as e:
        logger.error(e)
        return (False, 500)
Example #5
0
def create_video_thumbnails(repo, file_id, path, size, thumbnail_file,
                            file_size):

    t1 = timeit.default_timer()
    token = seafile_api.get_fileserver_access_token(repo.id,
                                                    file_id,
                                                    'view',
                                                    '',
                                                    use_onetime=False)

    if not token:
        return (False, 500)

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    clip = VideoFileClip(inner_path)
    tmp_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id[:8]))

    clip.save_frame(tmp_path, t=THUMBNAIL_VIDEO_FRAME_TIME)
    t2 = timeit.default_timer()
    logger.debug('Create thumbnail of [%s](size: %s) takes: %s' %
                 (path, file_size, (t2 - t1)))

    try:
        ret = _create_thumbnail_common(tmp_path, thumbnail_file, size)
        os.unlink(tmp_path)
        return ret
    except Exception as e:
        logger.error(e)
        os.unlink(tmp_path)
        return (False, 500)
Example #6
0
    def get(self, request, file_id, format=None):
        """ WOPI endpoint for get file content
        """

        token = request.GET.get('access_token', None)
        request_user, repo_id, file_path = get_file_info_by_token(token=token)
        obj_id = seafile_api.get_file_id_by_path(repo_id, file_path)

        file_name = os.path.basename(file_path)
        try:
            fileserver_token = seafile_api.get_fileserver_access_token(
                repo_id, obj_id, 'view', '', use_onetime=False)
        except SearpcError as e:
            logger.error(e)
            return HttpResponse(json.dumps({}),
                                status=500,
                                content_type=json_content_type)

        inner_path = gen_inner_file_get_url(fileserver_token, file_name)

        try:
            file_content = urllib2.urlopen(inner_path).read()
        except urllib2.URLError as e:
            logger.error(e)
            return HttpResponse(json.dumps({}),
                                status=500,
                                content_type=json_content_type)

        return HttpResponse(file_content,
                            content_type="application/octet-stream")
Example #7
0
def generate_thumbnail(request, repo_id, size, path):
    """ generate and save thumbnail if not exist
    """

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

    file_id = get_file_id_by_path(repo_id, path)
    thumbnail_file = os.path.join(thumbnail_dir, file_id)

    if os.path.exists(thumbnail_file):
        return True

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

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    try:
        image_file = urllib2.urlopen(inner_path)
        f = StringIO(image_file.read())
        image = Image.open(f)
        if image.mode not in ["1", "L", "P", "RGB", "RGBA"]:
            image = image.convert("RGB")
        image.thumbnail((size, size), Image.ANTIALIAS)
        image.save(thumbnail_file, THUMBNAIL_EXTENSION)
        return True
    except Exception as e:
        logger.error(e)
        return False
Example #8
0
    def post(self, request, file_id, format=None):

        token = request.GET.get('access_token', None)
        request_user, repo_id, file_path = get_file_info_by_token(token=token)

        try:
            file_obj = request.read()

            # get file update url
            token = seafile_api.get_fileserver_access_token(
                repo_id, 'dummy', 'update', request_user)
            update_url = gen_file_upload_url(token, 'update-api')

            # update file
            files = {
                'file': file_obj,
                'file_name': os.path.basename(file_path),
                'target_file': file_path,
            }
            requests.post(update_url, files=files)
        except Exception as e:
            logger.error(e)
            return HttpResponse(json.dumps({}),
                                status=500,
                                content_type=json_content_type)

        return HttpResponse(json.dumps({}),
                            status=200,
                            content_type=json_content_type)
Example #9
0
    def get(self, request, workspace_id):
        """get table file upload link
        """
        # argument check
        table_name = request.GET.get('name', None)
        if not table_name:
            error_msg = 'name invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        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)

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

        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            'dummy',
                                                            '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')

        # create asset dir
        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:
            seafile_api.mkdir_with_parents(repo_id, '/', asset_dir_path[1:],
                                           owner)

        dtable.modifier = username
        dtable.save()

        res = dict()
        res['upload_link'] = upload_link
        res['parent_path'] = asset_dir_path
        return Response(res)
Example #10
0
def get_upload_url(request, repo_id):
    username = request.user.username
    if check_repo_access_permission(repo_id, request.user) == "rw":
        token = seafile_api.get_fileserver_access_token(repo_id, "dummy", "upload", username)
        return gen_file_upload_url(token, "upload")
    else:
        return ""
Example #11
0
def get_file_view_path_and_perm(
        request,
        repo_id,
        obj_id,
        path,
        use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY):
    """ 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 = check_folder_permission(request, repo_id, '/')
    if user_perm is None:
        return ('', '', user_perm)
    else:
        # Get a token to visit file
        token = seafile_api.get_fileserver_access_token(
            repo_id, obj_id, 'view', username, use_onetime=use_onetime)

        if not token:
            return ('', '', None)

        outer_url = gen_file_get_url(token, filename)
        inner_url = gen_inner_file_get_url(token, filename)
        return (outer_url, inner_url, user_perm)
Example #12
0
def download_enc_file(request, repo_id, file_id):
    content_type = 'application/json; charset=utf-8'
    result = {}

    op = 'downloadblks'
    blklist = []

    if file_id == EMPTY_SHA1:
        result = { 'blklist':blklist, 'url':None, }
        return HttpResponse(json.dumps(result), content_type=content_type)

    try:
        blks = seafile_api.list_blocks_by_file_id(repo_id, file_id)
    except SearpcError as e:
        logger.error(e)
        result['error'] = _(u'Failed to get file block list')
        return HttpResponse(json.dumps(result), content_type=content_type)

    blklist = blks.split('\n')
    blklist = [i for i in blklist if len(i) == 40]
    token = seafile_api.get_fileserver_access_token(repo_id, file_id,
                                                    op, request.user.username)
    url = gen_block_get_url(token, None)
    result = {
        'blklist':blklist,
        'url':url,
        }
    return HttpResponse(json.dumps(result), content_type=content_type)
Example #13
0
def extract_xmind_image(repo_id, path, size=XMIND_IMAGE_SIZE):

    # get inner path
    file_name = os.path.basename(path)
    file_id = seafile_api.get_file_id_by_path(repo_id, path)
    fileserver_token = seafile_api.get_fileserver_access_token(
        repo_id, file_id, 'view', '')
    inner_path = gen_inner_file_get_url(fileserver_token, file_name)

    # extract xmind image
    xmind_file = urllib.request.urlopen(inner_path)
    xmind_file_str = BytesIO(xmind_file.read())
    xmind_zip_file = zipfile.ZipFile(xmind_file_str, 'r')
    extracted_xmind_image = xmind_zip_file.read('Thumbnails/thumbnail.png')
    extracted_xmind_image_str = BytesIO(extracted_xmind_image)

    # save origin xmind image to thumbnail folder
    thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size))
    if not os.path.exists(thumbnail_dir):
        os.makedirs(thumbnail_dir)
    local_xmind_image = os.path.join(thumbnail_dir, file_id)

    try:
        ret = _create_thumbnail_common(extracted_xmind_image_str,
                                       local_xmind_image, size)
        return ret
    except Exception as e:
        logger.error(e)
        return (False, 500)
Example #14
0
def download_files_to_path(username,
                           repo_id,
                           dtable_uuid,
                           files,
                           path,
                           files_map=None):
    """
    download dtable's asset files to path
    """
    valid_file_obj_ids = []
    base_path = os.path.join('/asset', dtable_uuid)
    for file in files:
        full_path = os.path.join(base_path, *file.split('/'))
        obj_id = seafile_api.get_file_id_by_path(repo_id, full_path)
        if not obj_id:
            continue
        valid_file_obj_ids.append((file, obj_id))

    tmp_file_list = []
    for file, obj_id in valid_file_obj_ids:
        token = seafile_api.get_fileserver_access_token(repo_id,
                                                        obj_id,
                                                        'download',
                                                        username,
                                                        use_onetime=False)
        file_name = os.path.basename(file)
        if files_map and files_map.get(file, None):
            file_name = files_map.get(file)
        file_url = gen_inner_file_get_url(token, file_name)
        content = requests.get(file_url).content
        filename_by_path = os.path.join(path, file_name)
        with open(filename_by_path, 'wb') as f:
            f.write(content)
        tmp_file_list.append(filename_by_path)
    return tmp_file_list
Example #15
0
def prepare_dtable_json(repo_id, dtable_uuid, table_name, dtable_file_dir_id):
    """
    used in export dtable
    create dtable json file at /tmp/dtable-io/<dtable_uuid>/dtable_asset/content.json,
    so that we can zip /tmp/dtable-io/<dtable_uuid>/dtable_asset

    :param repo_id:            repo of this dtable
    :param table_name:         name of dtable
    :param dtable_file_dir_id: xxx.dtable's file dir id
    :return:                   file stream
    """
    try:
        token = seafile_api.get_fileserver_access_token(repo_id,
                                                        dtable_file_dir_id,
                                                        'download',
                                                        '',
                                                        use_onetime=False)
    except Exception as e:
        raise e

    json_url = gen_inner_file_get_url(token, table_name + '.dtable')
    content_json = requests.get(json_url).content
    if content_json:
        dtable_content = convert_dtable_export_file_and_image_url(
            json.loads(content_json))
    else:
        dtable_content = ''
    content_json = json.dumps(dtable_content).encode('utf-8')
    path = os.path.join('/tmp/dtable-io', dtable_uuid, 'dtable_asset',
                        'content.json')

    with open(path, 'wb') as f:
        f.write(content_json)
Example #16
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
Example #17
0
    def get(self, request, token):
        # resource check
        form_obj = DTableForms.objects.get_form_by_token(token)
        if not form_obj:
            error_msg = 'Form %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        workspace_id = form_obj.workspace_id
        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)

        repo_id = workspace.repo_id

        dtable_uuid = form_obj.dtable_uuid
        dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
        if not dtable:
            error_msg = 'Table %s not found.' % dtable_uuid
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        if not check_form_submit_permission(request, form_obj):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if not check_user_workspace_quota(workspace):
            error_msg = 'Asset quota exceeded.'
            return api_error(HTTP_443_ABOVE_QUOTA, error_msg)

        # create asset dir
        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:
            seafile_api.mkdir_with_parents(repo_id, '/', asset_dir_path[1:],
                                           '')

        # get token
        obj_id = json.dumps({'parent_dir': asset_dir_path})
        try:
            token = seafile_api.get_fileserver_access_token(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')

        res = dict()
        res['upload_link'] = upload_link
        res['parent_path'] = asset_dir_path
        res['img_relative_path'] = FORM_UPLOAD_IMG_RELATIVE_PATH
        res['file_relative_path'] = os.path.join(UPLOAD_FILE_RELATIVE_PATH,
                                                 str(datetime.today())[:7])
        return Response(res)
Example #18
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
Example #19
0
def generate_thumbnail(request, repo_id, size, path):
    """ generate and save thumbnail if not exist

    before generate thumbnail, you should check:
    1. if repo exist: should exist;
    2. if repo is encrypted: not encrypted;
    3. if ENABLE_THUMBNAIL: enabled;
    """

    try:
        size = int(size)
    except ValueError as e:
        logger.error(e)
        return (False, 400)

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

    file_id = get_file_id_by_path(repo_id, path)
    if not file_id:
        return (False, 400)

    thumbnail_file = os.path.join(thumbnail_dir, file_id)
    if os.path.exists(thumbnail_file):
        return (True, 200)

    repo = get_repo(repo_id)
    file_size = get_file_size(repo.store_id, repo.version, file_id)
    if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2:
        return (False, 403)

    token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view',
                                                    '', use_onetime = True)

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    try:
        image_file = urllib2.urlopen(inner_path)
        f = StringIO(image_file.read())
        image = Image.open(f)

        # check image memory cost size limit
        # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask)
        # every pixel will cost 4 byte in RGBA mode
        width, height = image.size
        image_memory_cost = width * height * 4 / 1024 / 1024
        if image_memory_cost > THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT:
            return (False, 403)

        if image.mode not in ["1", "L", "P", "RGB", "RGBA"]:
            image = image.convert("RGB")

        image = get_rotated_image(image)
        image.thumbnail((size, size), Image.ANTIALIAS)
        image.save(thumbnail_file, THUMBNAIL_EXTENSION)
        return (True, 200)
    except Exception as e:
        logger.error(e)
        return (False, 500)
Example #20
0
def get_upload_url(request, repo_id):
    username = request.user.username
    if check_repo_access_permission(repo_id, request.user) == 'rw':
        token = seafile_api.get_fileserver_access_token(
            repo_id, 'dummy', 'upload', username)
        return gen_file_upload_url(token, 'upload')
    else:
        return ''
Example #21
0
def get_upload_url(request, repo_id):
    username = request.user.username
    if check_folder_permission(request, repo_id, '/') == 'rw':
        token = seafile_api.get_fileserver_access_token(repo_id, 'dummy',
                                                        'upload', username)
        return gen_file_upload_url(token, 'upload')
    else:
        return ''
Example #22
0
def dtable_asset_file_view(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)

    return_dict = {
        'repo': repo,
        'filename': file_name,
        'file_path': asset_path,
        'file_type': file_type,
        'file_ext': file_ext,
        'raw_path': raw_path,
        '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)
Example #23
0
def view_shared_upload_link(request, token):
    assert token is not None  # Checked by URLconf

    uploadlink = UploadLinkShare.objects.get_valid_upload_link_by_token(token)
    if uploadlink is None:
        raise Http404

    if uploadlink.is_encrypted():
        if not check_share_link_access(request.user.username, token):
            d = {"token": token, "view_name": "view_shared_upload_link"}
            if request.method == "POST":
                post_values = request.POST.copy()
                post_values["enc_password"] = uploadlink.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))

    username = uploadlink.username
    repo_id = uploadlink.repo_id
    path = uploadlink.path
    dir_name = os.path.basename(path[:-1])

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

    uploadlink.view_cnt = F("view_cnt") + 1
    uploadlink.save()

    no_quota = True if seaserv.check_quota(repo_id) < 0 else False

    token = seafile_api.get_fileserver_access_token(repo_id, "dummy", "upload", request.user.username)
    ajax_upload_url = gen_file_upload_url(token, "upload-aj")

    return render_to_response(
        "view_shared_upload_link.html",
        {
            "repo": repo,
            "token": token,
            "path": path,
            "username": username,
            "dir_name": dir_name,
            "max_upload_file_size": seaserv.MAX_UPLOAD_FILE_SIZE,
            "no_quota": no_quota,
            "ajax_upload_url": ajax_upload_url,
            "uploadlink": uploadlink,
        },
        context_instance=RequestContext(request),
    )
Example #24
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)

            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)
Example #25
0
def dtable_external_link_plugin_asset_view(request, token, workspace_id, name,
                                           plugin_id, path):
    """
    used in external page
    """
    dtable_external_link = DTableExternalLinks.objects.filter(
        token=token).first()
    if not dtable_external_link:
        raise Http404

    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)

    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)

    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
Example #26
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)
Example #27
0
    def post(self, request):
        """ Save file.
        """

        # 在默认情况下,所有的编辑参与者退出编辑5分钟之后,毕升Office会触发回存逻辑;
        # 或者在所以用户退出编辑之后,如果有用户再打开预览,也会触发回存。

        # {u'action': u'saveBack',
        #  u'data': {u'changesUrl': u'2bd816895cb7a72dffa4810d2ba5c474/changes.zip',
        #            u'delta': 10,
        #            u'docId': u'2bd816895cb7a72dffa4810d2ba5c474',
        #            u'docURL': u'/s3/draft/...',
        #            u'modifyBy': [{u'avatar': u'http://192.168.1.113:8000/media/avatars/default.png',
        #                           u'nickName': u'lian',
        #                           u'oid': u'*****@*****.**',
        #                           u'privilege': None,
        #                           u'uid': u'*****@*****.**'}],
        #            u'unchanged': False},
        #  u'docId': u'2bd816895cb7a72dffa4810d2ba5c474'}

        post_data = json.loads(request.body)

        # check action from bisheng server
        action = post_data.get('action')
        if action != 'saveBack':
            return Response()

        # ger file basic info
        doc_id = post_data.get('docId')
        file_info = cache.get('BISHENG_OFFICE_' + doc_id)

        username = file_info.get('username')
        repo_id = file_info.get('repo_id')
        file_path = file_info.get('file_path')

        # get content of new editted file
        data = post_data.get('data')
        file_url = urllib.parse.urljoin(BISHENG_OFFICE_HOST_DOMAIN,
                                        data.get('docURL'))
        files = {
            'file': requests.get(file_url).content,
            'file_name': os.path.basename(file_path),
            'target_file': file_path,
        }

        # prepare update token for seafhttp
        fake_obj_id = {
            'online_office_update': True,
        }
        update_token = seafile_api.get_fileserver_access_token(
            repo_id, json.dumps(fake_obj_id), 'update', username)

        # update file
        update_url = gen_inner_file_upload_url('update-api', update_token)
        requests.post(update_url, files=files)

        return Response()
Example #28
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)

        # argument checking
        parent_dir = request.GET.get('parent_dir', None)
        dirent_name_string = request.GET.get('dirents', None)

        if not parent_dir:
            error_msg = 'parent_dir invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if not dirent_name_string:
            error_msg = 'dirents invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # folder exist checking
        if not seafile_api.get_dir_id_by_path(repo_id, parent_dir):
            error_msg = 'Folder %s not found.' % parent_dir
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        dirent_name_list = string2list(dirent_name_string)
        dirent_list = []
        for dirent_name in dirent_name_list:
            dirent_list.append(dirent_name.strip('/'))

        fake_obj_id = {}
        fake_obj_id['file_list'] = dirent_list
        fake_obj_id['parent_dir'] = parent_dir

        username = request.user.username
        try:
            token = seafile_api.get_fileserver_access_token(
                repo_id, json.dumps(fake_obj_id), 'download-multi', username,
                False)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if len(dirent_list) > 10:
            send_file_access_msg(request, repo, parent_dir, 'web')
        else:
            for dirent_name in dirent_list:
                full_dirent_path = posixpath.join(parent_dir, dirent_name)
                send_file_access_msg(request, repo, full_dirent_path, 'web')

        download_url = '%s/files/%s' % (get_fileserver_root(), token)
        return Response({'url': download_url})
Example #29
0
def view_shared_upload_link(request, token):
    assert token is not None    # Checked by URLconf

    uploadlink = UploadLinkShare.objects.get_valid_upload_link_by_token(token)
    if uploadlink is None:
        raise Http404

    if uploadlink.is_encrypted():
        if not check_share_link_access(request.user.username, token):
            d = {'token': token, 'view_name': 'view_shared_upload_link', }
            if request.method == 'POST':
                post_values = request.POST.copy()
                post_values['enc_password'] = uploadlink.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))

    username = uploadlink.username
    repo_id = uploadlink.repo_id
    path = uploadlink.path
    dir_name = os.path.basename(path[:-1])

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

    uploadlink.view_cnt = F('view_cnt') + 1
    uploadlink.save()

    no_quota = True if seaserv.check_quota(repo_id) < 0 else False

    token = seafile_api.get_fileserver_access_token(repo_id, 'dummy',
                                                    'upload', request.user.username)
    ajax_upload_url = gen_file_upload_url(token, 'upload-aj')

    return render_to_response('view_shared_upload_link.html', {
            'repo': repo,
            'token': token,
            'path': path,
            'username': username,
            'dir_name': dir_name,
            'max_upload_file_size': seaserv.MAX_UPLOAD_FILE_SIZE,
            'no_quota': no_quota,
            'ajax_upload_url': ajax_upload_url,
            'uploadlink': uploadlink,
            'enable_upload_folder': ENABLE_UPLOAD_FOLDER,
            }, context_instance=RequestContext(request))
Example #30
0
    def get(self, request, workspace_id):
        """get table file update link
        """
        # argument check
        table_name = request.GET.get('name', None)
        if not table_name:
            error_msg = 'name invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        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)

        # permission check
        username = request.user.username
        owner = workspace.owner
        if '@seafile_group' in owner:
            group_id = int(owner.split('@')[0])
            if not is_group_member(group_id, username):
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)
        else:
            if username != owner:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            'dummy',
                                                            'update',
                                                            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)

        dtable.modifier = username
        dtable.save()

        url = gen_file_upload_url(token, 'update-api')
        return Response(url)
Example #31
0
    def get(self, request):
        """get table file update link
        Permission:
        1. use dtable_uuid verify jwt from dtable-server
        """
        # argument check
        dtable_uuid = request.GET.get('dtable_uuid', None)
        if not dtable_uuid:
            error_msg = 'dtable_uuid invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # permission check
        auth = request.META.get('HTTP_AUTHORIZATION', '').split()
        if not is_valid_jwt(auth, dtable_uuid):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # resource check
        dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
        if not dtable:
            error_msg = 'dtable %s not found.' % dtable_uuid
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        workspace = Workspaces.objects.get_workspace_by_id(dtable.workspace.id)
        if not workspace:
            error_msg = 'Workspace not found.'
            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)

        username = request.user.username
        # get token
        obj_id = json.dumps({'parent_dir': '/'})
        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            obj_id,
                                                            'upload',
                                                            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)

        update_link = '%s/%s/%s' % (get_fileserver_root(), 'upload-api', token)

        res = dict()
        res['update_link'] = update_link
        res['file_name'] = dtable.name + FILE_TYPE

        return Response(res)
Example #32
0
def view_shared_upload_link(request, token):
    assert token is not None    # Checked by URLconf

    uploadlink = UploadLinkShare.objects.get_valid_upload_link_by_token(token)
    if uploadlink is None:
        raise Http404

    if uploadlink.is_encrypted():
        if not check_share_link_access(request.user.username, token):
            d = {'token': token, 'view_name': 'view_shared_upload_link', }
            if request.method == 'POST':
                post_values = request.POST.copy()
                post_values['enc_password'] = uploadlink.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))

    username = uploadlink.username
    repo_id = uploadlink.repo_id
    path = uploadlink.path
    dir_name = os.path.basename(path[:-1])

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

    uploadlink.view_cnt = F('view_cnt') + 1
    uploadlink.save()

    no_quota = True if seaserv.check_quota(repo_id) < 0 else False

    token = seafile_api.get_fileserver_access_token(repo_id, 'dummy',
                                                    'upload', request.user.username)
    ajax_upload_url = gen_file_upload_url(token, 'upload-aj')

    return render_to_response('view_shared_upload_link.html', {
            'repo': repo,
            'token': token,
            'path': path,
            'username': username,
            'dir_name': dir_name,
            'max_upload_file_size': seaserv.MAX_UPLOAD_FILE_SIZE,
            'no_quota': no_quota,
            'ajax_upload_url': ajax_upload_url,
            'uploadlink': uploadlink,
            }, context_instance=RequestContext(request))
Example #33
0
    def get(self, request, repo_id):
        """ get info of a single file/folder in a library
        """

        if not request.user.admin_permissions.can_manage_library():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        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)
Example #34
0
    def post(self, request):
        """ Save file.
        """

        # 在默认情况下,所有的编辑参与者退出编辑5分钟之后,毕升Office会触发回存逻辑;
        # 或者在所以用户退出编辑之后,如果有用户再打开预览,也会触发回存。

        # {u'action': u'saveBack',
        #  u'data': {u'changesUrl': u'2bd816895cb7a72dffa4810d2ba5c474/changes.zip',
        #            u'delta': 10,
        #            u'docId': u'2bd816895cb7a72dffa4810d2ba5c474',
        #            u'docURL': u'/s3/draft/...',
        #            u'modifyBy': [{u'avatar': u'http://192.168.1.113:8000/media/avatars/default.png',
        #                           u'nickName': u'lian',
        #                           u'oid': u'*****@*****.**',
        #                           u'privilege': None,
        #                           u'uid': u'*****@*****.**'}],
        #            u'unchanged': False},
        #  u'docId': u'2bd816895cb7a72dffa4810d2ba5c474'}

        post_data = json.loads(request.body)

        # check action from bisheng server
        action = post_data.get('action')
        if action != 'saveBack':
            return Response()

        # ger file basic info
        doc_id = post_data.get('docId')
        file_info = cache.get('BISHENG_OFFICE_' + doc_id)

        username = file_info.get('username')
        repo_id = file_info.get('repo_id')
        file_path = file_info.get('file_path')

        # get content of new editted file
        data = post_data.get('data')
        file_url = urlparse.urljoin(BISHENG_OFFICE_HOST_DOMAIN, data.get('docURL'))
        files = {
            'file': requests.get(file_url).content,
            'file_name': os.path.basename(file_path),
            'target_file': file_path,
        }

        # prepare update token for seafhttp
        fake_obj_id = {'online_office_update': True,}
        update_token = seafile_api.get_fileserver_access_token(
            repo_id, json.dumps(fake_obj_id), 'update', username)

        # update file
        update_url = gen_inner_file_upload_url('update-api', update_token)
        requests.post(update_url, files=files)

        return Response()
Example #35
0
def dtable_asset_access(request, workspace_id, dtable_id, path):
    """

    Permission:
    1. owner
    2. group member
    3. shared user with `rw` or `admin` permission
    """
    # asset file type check
    asset_name = os.path.basename(normalize_file_path(path))
    file_type, file_ext = get_file_type_and_ext(asset_name)
    if file_type != IMAGE:
        err_msg = 'Invalid file type'
        return render_error(request, err_msg)

    # resource check
    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        raise Http404

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

    dtable = DTables.objects.get_dtable_by_uuid(dtable_id)
    if not dtable:
        raise Http404

    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:
        raise Http404

    # permission check
    username = request.user.username
    owner = workspace.owner
    if not check_dtable_permission(username, owner) and \
            check_dtable_share_permission(dtable, username) not in WRITE_PERMISSION_TUPLE:
        return render_permission_error(request, _(u'Permission denied.'))

    dl = request.GET.get('dl', '0') == '1'
    operation = 'download' if dl else 'view'

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

    url = gen_file_get_url(token, asset_name)

    return HttpResponseRedirect(url)
Example #36
0
def get_inner_path(repo_id, file_id, file_name):
    token = seafile_api.get_fileserver_access_token(repo_id,
                                                    file_id,
                                                    'view',
                                                    '',
                                                    use_onetime=True)
    if not token:
        raise ValueError(404, 'token not found.')
    inner_path = '%s/files/%s/%s' % (settings.INNER_FILE_SERVER_ROOT.rstrip(
        '/'), token, urllib.parse.quote(file_name))

    return inner_path
Example #37
0
def onlyoffice_editor_callback(request):
    #request.body:
    # {"key":"Khirz6zTPdfd7","status":1,
    # "users":["uid-1488351242769"],
    # "actions":[{"type":1,"userid":"uid-1488351242769"}]}

    # "key":"Khirz6zTPdfd8","status":2,"url":"https://13.113.111.2/cache/files/Khirz6zTPdfd8_6379/output.docx/output.docx?md5=5oL0qGUqXw72D85f28JaFg==&expires=1488956681&disposition=attachment&ooname=output.docx","changesurl":"https://13.113.111.2/cache/files/Khirz6zTPdfd8_6379/changes.zip/changes.zip?md5=vx3VYwaPEOxtZDA_3yuVrg==&expires=1488956681&disposition=attachment&ooname=output.zip","history":{"serverVersion":"4.2.10","changes":[{"created":"2017-03-01 07:03:11","user":{"id":"uid-1488351774447","name":"Anonymous"}}]},"users":["uid-1488351774447"],"actions":[{"type":0,"userid":"uid-1488351774447"}]}
    logger.debug(request.body)

    if request.method != 'POST':
        return HttpResponse('{"error": 0}')

    post_data = json.loads(request.body)
    status = int(post_data.get('status', -1))
    if status == 2:  # document is ready for saving
        # the link to the edited document to be saved with the document storage
        # service. The link is present when the status value is equal to 2 or 3 only.
        url = post_data.get('url')

        context = None
        if VERIFY_ONLYOFFICE_CERTIFICATE is False:
            import ssl
            context = ssl._create_unverified_context()

        try:
            file_content = urllib2.urlopen(url, context=context).read()
        except urllib2.URLError as e:
            logger.error(e)
        else:
            # update file
            doc_key = post_data.get('key')
            doc_info = json.loads(cache.get("ONLYOFFICE_%s" % doc_key))
            repo_id = doc_info['repo_id']
            file_path = doc_info['file_path']
            username = doc_info['username']

            update_token = seafile_api.get_fileserver_access_token(
                repo_id, 'dummy', 'update', username)

            if not update_token:
                return HttpResponse('{"error": 0}')

            update_url = gen_inner_file_upload_url('update-api', update_token)

            files = {
                'file': file_content,
                'file_name': os.path.basename(file_path),
                'target_file': file_path,
            }
            requests.post(update_url, files=files)
            logger.info('%s updated by %s' % (repo_id + file_path, username))

    return HttpResponse('{"error": 0}')
Example #38
0
    def get(self, request):
        """get table file download link
        Permission:
        1. use dtable_uuid verify jwt from dtable-server
        """
        # argument check
        dtable_uuid = request.GET.get('dtable_uuid', None)
        if not dtable_uuid:
            error_msg = 'dtable_uuid invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # permission check
        auth = request.META.get('HTTP_AUTHORIZATION', '').split()
        if not is_valid_jwt(auth, dtable_uuid):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # resource check
        dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
        if not dtable:
            error_msg = 'dtable %s not found.' % dtable_uuid
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        table_name = dtable.name

        workspace = Workspaces.objects.get_workspace_by_id(dtable.workspace.id)
        if not workspace:
            error_msg = 'Workspace not found.'
            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)

        username = request.user.username
        table_file_name = table_name + FILE_TYPE
        try:
            file_path = '/' + table_file_name
            file_id = seafile_api.get_file_id_by_path(repo_id, file_path)
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            file_id,
                                                            'download',
                                                            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)

        download_link = gen_file_get_url(token, table_name)

        return Response({'download_link': download_link})
Example #39
0
    def get(self, request, workspace_id):
        """get table file update link

        Permission:
        1. owner
        2. group member
        3. shared user with `rw` or `admin` permission
        """
        # argument check
        table_name = request.GET.get('name', None)
        if not table_name:
            error_msg = 'name invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        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)

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

        try:
            token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'update',
                                                            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)

        dtable.modifier = username
        dtable.save()

        url = gen_file_upload_url(token, 'update-api')
        return Response(url)
Example #40
0
def get_excel_json_file(repo_id, file_name):
    file_path = EXCEL_DIR_PATH + file_name + '.json'
    file_id = seafile_api.get_file_id_by_path(repo_id, file_path)
    if not file_id:
        raise FileExistsError('file %s not found' % file_path)
    token = seafile_api.get_fileserver_access_token(repo_id,
                                                    file_id,
                                                    'download',
                                                    '',
                                                    use_onetime=True)
    url = gen_inner_file_get_url(token, file_name + '.json')
    json_file = requests.get(url).content
    return json_file
Example #41
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)
Example #42
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)
Example #43
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, 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)
Example #44
0
    def get(self, request, token):
        """ Get file upload url according to upload link token.

        Permission checking:
        1. anyone has the upload link token can perform this action;
        """

        try:
            uls = UploadLinkShare.objects.get(token=token)
        except UploadLinkShare.DoesNotExist:
            error_msg = 'token %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # currently not support encrypted upload link
        if uls.is_encrypted():
            error_msg = 'Upload link %s is encrypted.' % token
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        repo_id = uls.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)

        path = uls.path
        dir_id = seafile_api.get_dir_id_by_path(repo_id, path)
        if not dir_id:
            error_msg = 'Folder %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if repo.encrypted or \
                seafile_api.check_permission_by_path(repo_id, '/', uls.username) != 'rw':
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        token = seafile_api.get_fileserver_access_token(repo_id,
                dir_id, 'upload-link', uls.username, use_onetime=False)

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

        result = {}
        result['upload_link'] = gen_file_upload_url(token, 'upload-api')
        return Response(result)
Example #45
0
def repo_download_dir(request, repo_id):
    repo = get_repo(repo_id)
    if not repo:
        return render_error(request, _(u'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 = True if check_folder_permission(request, repo_id, '/') else False

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

        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)
Example #46
0
def allow_generate_thumbnail(request, repo_id, path):
    """check if thumbnail is allowed
    """

    # get file type
    obj_name = os.path.basename(path)
    file_type, file_ext = get_file_type_and_ext(obj_name)

    # get file size
    file_id = get_file_id_by_path(repo_id, path)
    if not file_id:
        return False

    repo = get_repo(repo_id)
    file_size = get_file_size(repo.store_id, repo.version, file_id)

    if repo.encrypted or file_type != IMAGE or not ENABLE_THUMBNAIL:
        return False

    # check image compressed size limit
    if file_size < THUMBNAIL_IMAGE_COMPRESSED_SIZE_LIMIT * 1024**2:
        return True

    # get image memory cost
    token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view',
                                                    '', use_onetime = True)

    inner_path = gen_inner_file_get_url(token, obj_name)
    try:
        image_file = urllib2.urlopen(inner_path)
        f = StringIO(image_file.read())
        image = Image.open(f)
        width, height = image.size

        # check image memory cost size limit
        # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask)
        # every pixel will cost 4 byte in RGBA mode
        image_memory_cost = width * height * 4 / 1024 / 1024
        if image_memory_cost < THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT:
            return True

    except Exception as e:
        logger.error(e)
        return False
Example #47
0
    def get(self, request):

        # argument check
        req_from = request.GET.get('from', 'web')
        if req_from not in ('web', 'api'):
            error_msg = 'from invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # recourse check
        try:
            repo_id = seafile_api.get_system_default_repo_id()
            repo = seafile_api.get_repo(repo_id)
        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 repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        parent_dir = request.GET.get('path', '/')
        parent_dir = normalize_dir_path(parent_dir)
        dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
        if not dir_id:
            error_msg = 'Folder %s not found.' % parent_dir
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        token = seafile_api.get_fileserver_access_token(repo_id,
                'dummy', 'upload', 'system', use_onetime=False)

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

        if req_from == 'api':
            url = gen_file_upload_url(token, 'upload-api')
        else:
            url = gen_file_upload_url(token, 'upload-aj')

        result = {}
        result['upload_link'] = url
        return Response(result)
Example #48
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))
Example #49
0
def create_psd_thumbnails(repo, file_id, path, size, thumbnail_file, file_size):
    try:
        from psd_tools import PSDImage
    except ImportError:
        logger.error("Could not find psd_tools installed. "
                     "Please install by 'pip install psd_tools'")
        return (False, 500)

    token = seafile_api.get_fileserver_access_token(
        repo.id, file_id, 'view', '', use_onetime=False)
    if not token:
        return (False, 500)

    tmp_img_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id))
    t1 = timeit.default_timer()

    inner_path = gen_inner_file_get_url(token, os.path.basename(path))
    tmp_file = os.path.join(tempfile.gettempdir(), file_id)
    urlretrieve(inner_path, tmp_file)
    psd = PSDImage.load(tmp_file)

    merged_image = psd.as_PIL()
    merged_image.save(tmp_img_path)
    os.unlink(tmp_file)     # remove origin psd file

    t2 = timeit.default_timer()
    logger.debug('Extract psd image [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1)))

    try:
        ret = _create_thumbnail_common(tmp_img_path, thumbnail_file, size)
        os.unlink(tmp_img_path)
        return ret
    except Exception as e:
        logger.error(e)
        os.unlink(tmp_img_path)
        return (False, 500)
Example #50
0
    def get(self, request, token):
        """ Get FileServer url of the shared folder.

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

        try:
            uploadlink = UploadLinkShare.objects.get(token=token)
        except UploadLinkShare.DoesNotExist:
            error_msg = 'Upload link %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        repo_id = uploadlink.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)

        path = uploadlink.path
        obj_id = seafile_api.get_dir_id_by_path(repo_id, path)
        if not obj_id:
            error_msg = 'Folder not found.'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        upload_token = seafile_api.get_fileserver_access_token(repo_id,
                obj_id, 'upload-link', uploadlink.username, use_onetime=False)

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

        result = {}
        result['upload_link'] = gen_file_upload_url(upload_token, 'upload-api')

        return Response(result)
Example #51
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)
Example #52
0
    def get(self, request, format=None):
        """ Only used for download dir when view dir share link from web.


        Permission checking:
        1. authenticated user OR anonymous user has passed email code check(if necessary);
        """

        # permission check
        if is_pro_version() and settings.ENABLE_SHARE_LINK_AUDIT:
            if not request.user.is_authenticated() and \
                not request.session.get('anonymous_email'):
                # if anonymous user has passed email code check,
                # then his/her email info will be in session.

                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # argument check
        share_link_token = request.GET.get('share_link_token', None)
        if not share_link_token:
            error_msg = 'share_link_token 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)

        # recourse check
        fileshare = FileShare.objects.get_valid_dir_link_by_token(share_link_token)
        if not fileshare:
            error_msg = 'share_link_token %s not found.' % share_link_token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if req_path[-1] != '/':
            req_path += '/'

        if req_path == '/':
            real_path = fileshare.path
        else:
            real_path = posixpath.join(fileshare.path, req_path.lstrip('/'))

        if real_path[-1] != '/':
            real_path += '/'

        repo_id = fileshare.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)

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

        # get file server access token
        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, dir_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)

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

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

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

        if request.session.get('anonymous_email'):
            request.user.username = request.session.get('anonymous_email')

        send_file_access_msg(request, repo, real_path, 'share-link')

        return Response({'zip_token': zip_token})
Example #53
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),
    )
Example #54
0
def get_inner_file_url(repo, obj_id, file_name):
    repo_id = repo.id
    access_token = seafile_api.get_fileserver_access_token(repo_id, obj_id, "view", "")
    url = gen_inner_file_get_url(access_token, file_name)
    return url
Example #55
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))
Example #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)

        # argument checking
        parent_dir = request.GET.get('parent_dir', None)
        dirent_name_string = request.GET.get('dirents', None)

        if not parent_dir:
            error_msg = 'parent_dir invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if not dirent_name_string:
            error_msg = 'dirents invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # folder exist checking
        if not seafile_api.get_dir_id_by_path(repo_id, parent_dir):
            error_msg = 'Folder %s not found.' % parent_dir
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        dirent_name_list = string2list(dirent_name_string)
        dirent_list = []
        total_size = 0
        for dirent_name in dirent_name_list:
            dirent_name = dirent_name.strip('/')
            dirent_list.append(dirent_name)

            full_dirent_path = posixpath.join(parent_dir, dirent_name)
            current_dirent = seafile_api.get_dirent_by_path(repo_id, full_dirent_path)
            if stat.S_ISDIR(current_dirent.mode):
                total_size += seafile_api.get_dir_size(repo.store_id,
                    repo.version, current_dirent.obj_id)
            else:
                total_size += current_dirent.size

        if total_size > seaserv.MAX_DOWNLOAD_DIR_SIZE:
            error_msg = _('Total size exceeds limit.')
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        fake_obj_id = {}
        fake_obj_id['file_list'] = dirent_list
        fake_obj_id['parent_dir'] = parent_dir

        username = request.user.username
        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                json.dumps(fake_obj_id), 'download-multi', username, False)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if len(dirent_list) > 10:
            send_file_access_msg(request, repo, parent_dir, 'web')
        else:
            for dirent_name in dirent_list:
                full_dirent_path = posixpath.join(parent_dir, dirent_name)
                send_file_access_msg(request, repo, full_dirent_path, 'web')

        download_url = '%s/files/%s' % (get_fileserver_root(), token)
        return Response({'url': download_url})
Example #57
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.has_read_perm(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_inner_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,
            })
Example #58
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)
Example #59
0
    def post(self, request, repo_id, format=None):
        """ Create, rename, move, copy, revert file

        Permission checking:
        1. create: user with 'rw' permission for current parent dir;
        2. rename: user with 'rw' permission for current file;
        3. move  : user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        4. copy  : user with 'r' permission for current file, 'rw' permission for dst parent dir;
        4. revert: user with 'rw' permission for current file's parent dir;
        """

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

        path = normalize_file_path(path)

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

        operation = operation.lower()
        if operation not in ('create', 'rename', 'move', 'copy', 'revert'):
            error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        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)

        username = request.user.username
        parent_dir = os.path.dirname(path)

        is_draft = request.POST.get('is_draft', '')

        if operation == 'create':
            # resource check
            try:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
            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 parent_dir_id:
                error_msg = 'Folder %s not found.' % parent_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # permission check
            if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            if is_draft.lower() == 'true':
                file_name = os.path.basename(path)
                file_dir = os.path.dirname(path)

                draft_type = os.path.splitext(file_name)[0][-7:]
                file_type = os.path.splitext(file_name)[-1]

                if draft_type != '(draft)':
                    f = os.path.splitext(file_name)[0]
                    path = file_dir + '/' + f + '(draft)' + file_type

            # create new empty file
            new_file_name = os.path.basename(path)

            if not is_valid_dirent_name(new_file_name):
                return api_error(status.HTTP_400_BAD_REQUEST,
                                 'name invalid.')

            new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name)

            try:
                seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username)
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if is_draft.lower() == 'true':
                Draft.objects.add(username, repo, path, file_exist=False)

            # update office file by template
            if new_file_name.endswith('.xlsx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx')
            elif new_file_name.endswith('.pptx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx')
            elif new_file_name.endswith('.docx'):
                empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx')
            else:
                empty_file_path = ''

            if empty_file_path:
                # get file server update url
                update_token = seafile_api.get_fileserver_access_token(
                        repo_id, 'dummy', 'update', username)

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

                update_url = gen_inner_file_upload_url('update-api', update_token)
                # update file
                new_file_path = posixpath.join(parent_dir, new_file_name)
                try:
                    requests.post(
                        update_url,
                        data={'filename': new_file_name, 'target_file': new_file_path},
                        files={'file': open(empty_file_path, 'rb')}
                    )
                except Exception as e:
                    logger.error(e)

            new_file_path = posixpath.join(parent_dir, new_file_name)
            file_info = self.get_file_info(username, repo_id, new_file_path)
            return Response(file_info)