コード例 #1
0
ファイル: models.py プロジェクト: haiwen/seahub
    def publish(self, operator):
        # check whether origin file is updated
        r_repo = seafile_api.get_repo(self.origin_repo_id)
        if not r_repo:
            raise DraftFileConflict

        file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(self.origin_file_uuid)
        if not file_uuid:
            # TODO update error msg
            raise DraftFileConflict

        if file_uuid.parent_path == '/':
            origin_file_path = file_uuid.parent_path + file_uuid.filename
        else:
            origin_file_path = file_uuid.parent_path + '/' + file_uuid.filename

        file_id = seafile_api.get_file_id_by_path(self.origin_repo_id,
                                                  origin_file_path)

        draft_file_name = os.path.basename(self.draft_file_path)
        draft_file_path = os.path.dirname(self.draft_file_path)
        file_name = file_uuid.filename
        if file_id:
            if file_id != self.origin_file_version and self.draft_file_path != origin_file_path:
                raise DraftFileConflict

            if self.draft_file_path == origin_file_path:
                f = os.path.splitext(draft_file_name)[0][:-7]
                file_type = os.path.splitext(draft_file_name)[-1]
                file_name = f + file_type

            # move draft file to origin file
            seafile_api.move_file(
                self.origin_repo_id, draft_file_path, draft_file_name,
                self.origin_repo_id, file_uuid.parent_path,
                file_name, replace=1,
                username=operator, need_progress=0, synchronous=1
            )

        else:

            # move draft file to origin file
            seafile_api.move_file(
                self.origin_repo_id, draft_file_path, draft_file_name,
                self.origin_repo_id, file_uuid.parent_path,
                file_name, replace=1,
                username=operator, need_progress=0, synchronous=1
            )

        published_file_path = posixpath.join(file_uuid.parent_path, file_name)

        # get draft published version
        file_id = seafile_api.get_file_id_by_path(self.origin_repo_id, published_file_path)

        self.publish_file_version = file_id
        self.status = 'published'
        self.save()

        return published_file_path
コード例 #2
0
ファイル: utils.py プロジェクト: haiwen/seahub
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
コード例 #3
0
ファイル: views.py プロジェクト: Pi3R1k/seahub
def list_shared_links(request):
    """List share links, and remove invalid links(file/dir is deleted or moved).
    """
    username = request.user.username

    fileshares = FileShare.objects.filter(username=username)
    p_fileshares = []           # personal file share
    for fs in fileshares:
        if is_personal_repo(fs.repo_id):  # only list files in personal repos
            r = seafile_api.get_repo(fs.repo_id)
            if not r:
                fs.delete()
                continue

            if fs.s_type == 'f':
                if seafile_api.get_file_id_by_path(r.id, fs.path) is None:
                    fs.delete()
                    continue
                fs.filename = os.path.basename(fs.path)
                fs.shared_link = gen_file_share_link(fs.token) 
            else:
                if seafile_api.get_dir_id_by_path(r.id, fs.path) is None:
                    fs.delete()
                    continue
                fs.filename = os.path.basename(fs.path.rstrip('/'))
                fs.shared_link = gen_dir_share_link(fs.token)
            fs.repo = r
            p_fileshares.append(fs)
    
    return render_to_response('repo/shared_links.html', {
            "fileshares": p_fileshares,
            }, context_instance=RequestContext(request))
コード例 #4
0
ファイル: drafts.py プロジェクト: haiwen/seahub
    def post(self, request, org_id, format=None):
        """Create a file draft if the user has read-write permission to the origin file
        """
        repo_id = request.POST.get('repo_id', '')
        file_path = request.POST.get('file_path', '')

        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)

        # perm check
        perm = check_folder_permission(request, repo.id, file_path)
        if perm != PERMISSION_READ_WRITE:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        file_id = seafile_api.get_file_id_by_path(repo.id, file_path)
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND,
                             "File %s not found" % file_path)

        username = request.user.username
        try:
            d = Draft.objects.add(username, repo, file_path, file_id)

            return Response(d.to_dict())
        except DraftFileExist:
            return api_error(status.HTTP_409_CONFLICT, 'Draft already exists.')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
コード例 #5
0
ファイル: models.py プロジェクト: haiwen/seahub
    def format_file_comment_msg(self):
        try:
            d = json.loads(self.detail)
        except Exception as e:
            logger.error(e)
            return _(u"Internal error")

        repo_id = d['repo_id']
        file_path = d['file_path']
        author = d['author']
        comment = d['comment']

        repo = seafile_api.get_repo(repo_id)
        if repo is None or not seafile_api.get_file_id_by_path(repo.id,
                                                               file_path):
            self.delete()
            return None

        file_name = os.path.basename(file_path)
        msg = _("File <a href='%(file_url)s'>%(file_name)s</a> has a new comment from user %(author)s") % {
            'file_url': reverse('view_lib_file', args=[repo_id, file_path]),
            'file_name': escape(file_name),
            'author': escape(email2nickname(author)),
        }
        return msg
コード例 #6
0
ファイル: file_comments.py プロジェクト: shoeper/seahub
    def post(self, request, repo_id, format=None):
        """Post a comments of a file.
        """
        path = request.GET.get('p', '/').rstrip('/')
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.')

        try:
            avatar_size = int(request.GET.get('avatar_size',
                                              AVATAR_DEFAULT_SIZE))
        except ValueError:
            avatar_size = AVATAR_DEFAULT_SIZE

        try:
            obj_id = seafile_api.get_file_id_by_path(repo_id,
                                                     path)
        except SearpcError as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal error.')
        if not obj_id:
            return api_error(status.HTTP_404_NOT_FOUND, 'File not found.')

        comment = request.data.get('comment', '')
        if not comment:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Comment can not be empty.')

        username = request.user.username
        o = FileComment.objects.add_by_file_path(
            repo_id=repo_id, file_path=path, author=username, comment=comment)
        comment = o.to_dict()
        comment.update(user_to_dict(request.user.username, request=request,
                                    avatar_size=avatar_size))
        return Response(comment, status=201)
コード例 #7
0
ファイル: utils.py プロジェクト: haiwen/seahub
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)
コード例 #8
0
    def handleMove(self, destPath):
        if self.provider.readonly:
            raise DAVError(HTTP_FORBIDDEN)

        parts = destPath.strip("/").split("/", 1)
        if len(parts) <= 1:
            raise DAVError(HTTP_BAD_REQUEST)
        repo_name = parts[0]
        rel_path = parts[1]

        dest_dir, dest_file = os.path.split(rel_path)
        dest_repo = getRepoByName(repo_name, self.username, self.org_id, self.is_guest)

        if seafile_api.check_permission_by_path(dest_repo.id, self.rel_path, self.username) != "rw":
            raise DAVError(HTTP_FORBIDDEN)

        src_dir, src_file = os.path.split(self.rel_path)
        if not src_file:
            raise DAVError(HTTP_BAD_REQUEST)

        if not seafile_api.is_valid_filename(dest_repo.id, dest_file):
            raise DAVError(HTTP_BAD_REQUEST)

        # some clients such as GoodReader requires "overwrite" semantics
        file_id_dest = seafile_api.get_file_id_by_path(dest_repo.id, rel_path)
        if file_id_dest != None:
            seafile_api.del_file(dest_repo.id, dest_dir, dest_file, self.username)

        seafile_api.move_file(self.repo.id, src_dir, src_file,
                              dest_repo.id, dest_dir, dest_file, self.username, NEED_PROGRESS, SYNCHRONOUS)

        return True
コード例 #9
0
ファイル: utils.py プロジェクト: haiwen/seahub
def prepare_starred_files(files):
    array = []
    for f in files:
        sfile = {'org' : f.org_id,
                 'repo' : f.repo.id,
                 'repo_id' : f.repo.id,
                 'repo_name' : f.repo.name,
                 'path' : f.path,
                 'icon_path' : file_icon_filter(f.path),
                 'file_name' : os.path.basename(f.path),
                 'mtime' : f.last_modified,
                 'mtime_relative': translate_seahub_time(f.last_modified),
                 'dir' : f.is_dir,
                 'repo_encrypted' : f.repo.encrypted
                 }
        if not f.is_dir:
            try:
                file_id = seafile_api.get_file_id_by_path(f.repo.id, f.path)
                sfile['oid'] = file_id
                sfile['size'] = get_file_size(f.repo.store_id, f.repo.version, file_id)
            except SearpcError as e:
                logger.error(e)
                pass

        array.append(sfile)

    return array
コード例 #10
0
ファイル: library_dirents.py プロジェクト: haiwen/seahub
    def delete(self, request, repo_id):
        """ delete a single file/folder in a library
        """

        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)

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

        if not file_id and not dir_id:
            return Response({'success': True})

        parent_dir = os.path.dirname(path)
        file_name = os.path.basename(path)
        try:
            seafile_api.del_file(repo_id,
                    parent_dir, file_name, request.user.username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({'success': True})
コード例 #11
0
ファイル: file_tag.py プロジェクト: haiwen/seahub
    def get(self, request, repo_id):
        """list all tags of a file.
        """
        # argument check
        file_path = request.GET.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
        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)

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

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

        try:
            file_tags = FileTags.objects.get_file_tag_by_path(repo_id, file_path)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({"file_tags": file_tags}, status=status.HTTP_200_OK)
コード例 #12
0
ファイル: models.py プロジェクト: chu888chu888/Seafile-seahub
    def get_file_last_modified(self, repo_id, file_path):
        """
        
        Arguments:
        - `self`:
        - `repo_id`:
        - `file_path`:
        """
        last_modified = 0
        file_path_hash = calc_file_path_hash(file_path)
        file_id = seafile_api.get_file_id_by_path(repo_id, file_path)
        try:
            fc = super(FileLastModifiedInfoManager, self).get(
                repo_id=repo_id, file_path_hash=file_path_hash)
        except self.model.DoesNotExist:
            # has no cache yet
            user, last_modified = self._calc_file_last_modified(
                repo_id, file_path, file_path_hash, file_id)
        else:
            # cache found
            if fc.file_id != file_id:
                # but cache is outdated
                fc.delete()
                user, last_modified = self._calc_file_last_modified(
                    repo_id, file_path, file_path_hash, file_id)
            else:
                # cache is valid
                user, last_modified = fc.email, fc.last_modified

        return user, last_modified
コード例 #13
0
ファイル: file.py プロジェクト: datawerk/seahub
def view_shared_file(request, token):
    """
    Preview file via shared link.
    """
    assert token is not None    # Checked by URLconf

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

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

    path = fileshare.path.rstrip('/') # Normalize file path 
    obj_id = seafile_api.get_file_id_by_path(repo_id, path)
    if not obj_id:
        return render_error(request, _(u'File does not exist'))
    file_size = seafile_api.get_file_size(obj_id)
    
    filename = os.path.basename(path)
    filetype, fileext = get_file_type_and_ext(filename)
    access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id,
                                                     'view', '')
    raw_path = gen_file_get_url(access_token, filename)
    inner_path = gen_inner_file_get_url(access_token, filename)

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

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

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

        # send statistic messages
        if ret_dict['filetype'] != 'Unknown':
            try:
                obj_size = seafserv_threaded_rpc.get_file_size(obj_id)
                send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                             (repo.id, shared_by, obj_id, obj_size))
            except SearpcError, e:
                logger.error('Error when sending file-view message: %s' % str(e))
コード例 #14
0
ファイル: file.py プロジェクト: AviorAlong/haiwen-5.1.3
    def delete(self, request, repo_id, format=None):
        # delete file
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            return Response({'success': True})

        parent_dir = os.path.dirname(path)
        if check_folder_permission(request, repo_id, parent_dir) != 'rw':
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        parent_dir = os.path.dirname(path)
        file_name = os.path.basename(path)
        try:
            seafile_api.del_file(repo_id, parent_dir,
                                 file_name, request.user.username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if request.GET.get('reloaddir', '').lower() == 'true':
            return reloaddir(request, repo, parent_dir)
        else:
            return Response({'success': True})
コード例 #15
0
ファイル: utils.py プロジェクト: rominf/seahub
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
コード例 #16
0
    def test_can_get_file_downloadblks_info(self):
        file_id = seafile_api.get_file_id_by_path(self.repo_id, self.file_path)

        self.login_as(self.user)
        resp = self.client.get(self.url + '?p=' + self.file_path + '&op=downloadblks')
        self.assertEqual(200, resp.status_code)
        json_resp = json.loads(resp.content)
        assert json_resp['file_id'] == file_id
コード例 #17
0
    def test_can_download(self):
        obj_id = seafile_api.get_file_id_by_path(self.repo.id, self.file)

        resp = self.client.get(reverse('download_file', args=[
            self.repo.id, obj_id]))

        self.assertEqual(302, resp.status_code)
        assert '8082' in resp.get('location')
コード例 #18
0
    def test_can_get(self):
        obj_id = seafile_api.get_file_id_by_path(self.repo.id, self.file)

        rst = get_file_view_path_and_perm(self.request, self.repo.id, obj_id,
                                          self.file)
        assert '8082' in rst[0]
        assert '8082' in rst[1]
        assert rst[2] == 'rw'
コード例 #19
0
ファイル: file.py プロジェクト: swpd/seahub
def view_file_via_shared_dir(request, token):
    assert token is not None    # Checked by URLconf

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

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

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

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

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

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

        # send statistic messages
        try:
            obj_size = seafserv_threaded_rpc.get_file_size(obj_id)
            send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \
                         (repo.id, shared_by, obj_id, obj_size))
        except SearpcError, e:
            logger.error('Error when sending file-view message: %s' % str(e))
コード例 #20
0
ファイル: file.py プロジェクト: haiwen/seahub
    def delete(self, request, repo_id, format=None):
        """ Delete file.

        Permission checking:
        1. user with 'rw' permission.
        """

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

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

        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            return Response({'success': True})

        # permission check
        parent_dir = os.path.dirname(path)

        username = request.user.username
        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)

        # check file lock
        try:
            is_locked, locked_by_me = check_file_lock(repo_id, path, 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 is_locked and not locked_by_me:
            error_msg = _("File is locked")
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # delete file
        file_name = os.path.basename(path)
        try:
            seafile_api.del_file(repo_id, parent_dir,
                                 file_name, request.user.username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({'success': True})
コード例 #21
0
ファイル: file.py プロジェクト: RaphaelWimmer/seahub
    def put(self, request, repo_id, format=None):
        """ Currently only for lock and unlock file operation.

        Permission checking:
        1. user with 'rw' permission for current file;
        """

        if not is_pro_version():
            error_msg = 'file lock feature only supported in professional edition.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

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

        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 ('lock', 'unlock'):
            error_msg = "operation can only be 'lock', or 'unlock'."
            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)

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

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

        username = request.user.username
        is_locked, locked_by_me = check_file_lock(repo_id, path, username)
        if operation == 'lock':
            if not is_locked:
                # lock file
                expire = request.data.get('expire', FILE_LOCK_EXPIRATION_DAYS)
                try:
                    seafile_api.lock_file(repo_id, path.lstrip('/'), username, expire)
                except SearpcError, e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
コード例 #22
0
ファイル: starred_items.py プロジェクト: haiwen/seahub
    def get(self, request):
        """ List all starred file/folder.

        Permission checking:
        1. all authenticated user can perform this action.
        """

        email = request.user.username
        all_starred_items = UserStarredFiles.objects.filter(email=email)

        repo_dict = {}
        for starred_item in all_starred_items:
            repo_id = starred_item.repo_id
            if repo_id not in repo_dict:
                repo = seafile_api.get_repo(repo_id)
                if repo:
                    repo_dict[repo_id] = repo

        starred_repos = []
        starred_folders = []
        starred_files = []
        for starred_item in all_starred_items:

            repo_id = starred_item.repo_id
            if repo_id not in repo_dict:
                continue

            path = starred_item.path
            if starred_item.is_dir:
                if not seafile_api.get_dir_id_by_path(repo_id, path):
                    continue
            else:
                if not seafile_api.get_file_id_by_path(repo_id, path):
                    continue

            repo = repo_dict[repo_id]
            item_info = self.get_starred_item_info(repo, starred_item)

            email = starred_item.email
            item_info['user_email'] = email
            item_info['user_name'] = email2nickname(email)
            item_info['user_contact_email'] = email2contact_email(email)

            if path == '/':
                starred_repos.append(item_info)
            elif starred_item.is_dir:
                starred_folders.append(item_info)
            else:
                starred_files.append(item_info)

        starred_repos.sort(lambda x, y: cmp(y['mtime'], x['mtime']))
        starred_folders.sort(lambda x, y: cmp(y['mtime'], x['mtime']))
        starred_files.sort(lambda x, y: cmp(y['mtime'], x['mtime']))

        return Response({'starred_item_list': starred_repos + \
                starred_folders + starred_files})
コード例 #23
0
ファイル: file_comments.py プロジェクト: haiwen/seahub
    def post(self, request, repo_id, format=None):
        """Post a comments of a file.
        """
        # argument check
        path = request.GET.get('p', '/').rstrip('/')
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Wrong path.')

        comment = request.data.get('comment', '')
        if not comment:
            return api_error(status.HTTP_400_BAD_REQUEST, 'Comment can not be empty.')

        try:
            avatar_size = int(request.GET.get('avatar_size',
                                              AVATAR_DEFAULT_SIZE))
        except ValueError:
            avatar_size = AVATAR_DEFAULT_SIZE

        # resource check
        try:
            file_id = seafile_api.get_file_id_by_path(repo_id, path)
        except SearpcError as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal error.')
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND, 'File not found.')

        # permission check
        if check_folder_permission(request, repo_id, '/') is None:
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        detail = request.data.get('detail', '')
        username = request.user.username
        file_comment = FileComment.objects.add_by_file_path(
            repo_id=repo_id, file_path=path, author=username, comment=comment, detail=detail)
        repo = seafile_api.get_repo(repo_id)
        repo_owner = get_repo_owner(request, repo.id)

        if is_draft_file(repo_id, path):
            draft = Draft.objects.get(origin_repo_id=repo_id, draft_file_path=path)
            comment_draft_successful.send(sender=None,
                                          draft=draft,
                                          comment=comment,
                                          author=username)
        else:
            comment_file_successful.send(sender=None,
                                         repo=repo,
                                         repo_owner=repo_owner,
                                         file_path=path,
                                         comment=comment,
                                         author=username)

        comment = file_comment.to_dict()
        comment.update(user_to_dict(username, request=request, avatar_size=avatar_size))
        return Response(comment, status=201)
コード例 #24
0
ファイル: share_links.py プロジェクト: TanLian/seahub
    def _generate_obj_id_and_type_by_path(self, repo_id, path):

        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if file_id:
            return (file_id, 'f')

        dir_id = seafile_api.get_dir_id_by_path(repo_id, path)
        if dir_id:
            return (dir_id, 'd')

        return (None, None)
コード例 #25
0
    def setUp(self):
        share_file_info = {
            'username': '******',
            'repo_id': self.repo.id,
            'path': '/',
            'password': '******',
            'expire_date': None,
        }

        self.fs = FileShare.objects.create_dir_link(**share_file_info)
        self.file_id = seafile_api.get_file_id_by_path(self.repo.id, self.file)
        self.filename= os.path.basename(self.file)
コード例 #26
0
ファイル: views.py プロジェクト: haiwen/seahub
def draft(request, pk):
    d = get_object_or_404(Draft, pk=pk)

    # check perm
    uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid)
    origin_repo_id = d.origin_repo_id
    permission = check_folder_permission(request, origin_repo_id, '/')
    if not permission:
        return render_permission_error(request, _(u'Permission denied.'))

    origin_file_path = posixpath.join(uuid.parent_path, uuid.filename)
    origin_file = seafile_api.get_file_id_by_path(origin_repo_id, origin_file_path)
    origin_file_exists = True
    if not origin_file:
        origin_file_exists = False

    draft_file = seafile_api.get_file_id_by_path(origin_repo_id, d.draft_file_path)
    draft_file_exists = True
    if not draft_file:
        draft_file_exists = False

    draft_file_name = os.path.basename(d.draft_file_path)

    author_info = user_to_dict(d.username, avatar_size=32)

    return render(request, "draft.html", {
        "draft_id": d.id,
        "draft_repo_id": origin_repo_id,
        "draft_origin_file_path": origin_file_path,
        "draft_file_path": d.draft_file_path,
        "draft_file_name": draft_file_name,
        "permission": permission,
        "author": author_info['user_name'],
        "author_avatar_url": author_info['avatar_url'],
        "origin_file_exists": origin_file_exists,
        "draft_file_exists": draft_file_exists,
        "draft_status": d.status,
        "publish_file_version": d.publish_file_version,
        "origin_file_version": d.origin_file_version
    })
コード例 #27
0
ファイル: utils.py プロジェクト: rominf/seahub
def prepare_starred_files(files):
    array = []
    for f in files:
        sfile = {"org": f.org_id, "repo": f.repo.id, "path": f.path, "mtime": f.last_modified, "dir": f.is_dir}
        if not f.is_dir:
            try:
                file_id = seafile_api.get_file_id_by_path(f.repo.id, f.path)
                sfile["oid"] = file_id
                sfile["size"] = get_file_size(f.repo.store_id, f.repo.version, file_id)
            except SearpcError, e:
                pass

        array.append(sfile)
コード例 #28
0
ファイル: views.py プロジェクト: allo-/seahub
def list_shared_links(request):
    """List shared links, and remove invalid links(file/dir is deleted or moved).
    """
    username = request.user.username

    # download links
    fileshares = FileShare.objects.filter(username=username)
    p_fileshares = []           # personal file share
    for fs in fileshares:
        r = seafile_api.get_repo(fs.repo_id)
        if not r:
            fs.delete()
            continue

        if fs.s_type == 'f':
            if seafile_api.get_file_id_by_path(r.id, fs.path) is None:
                fs.delete()
                continue
            fs.filename = os.path.basename(fs.path)
            fs.shared_link = gen_file_share_link(fs.token)
        else:
            if seafile_api.get_dir_id_by_path(r.id, fs.path) is None:
                fs.delete()
                continue
            fs.filename = os.path.basename(fs.path.rstrip('/'))
            fs.shared_link = gen_dir_share_link(fs.token)
        fs.repo = r
        p_fileshares.append(fs)

    # upload links
    uploadlinks = UploadLinkShare.objects.filter(username=username)
    p_uploadlinks = []
    for link in uploadlinks:
        r = seafile_api.get_repo(link.repo_id)
        if not r:
            link.delete()
            continue
        if seafile_api.get_dir_id_by_path(r.id, link.path) is None:
            link.delete()
            continue
        link.dir_name = os.path.basename(link.path.rstrip('/'))
        link.shared_link = gen_shared_upload_link(link.token)
        link.repo = r
        p_uploadlinks.append(link)

    return render_to_response('share/links.html', {
            "fileshares": p_fileshares,
            "uploadlinks": p_uploadlinks,
            }, context_instance=RequestContext(request))
コード例 #29
0
ファイル: file_tag.py プロジェクト: haiwen/seahub
    def post(self, request, repo_id):
        """add a tag for a file.
        """
        # argument check
        file_path = request.data.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)
        repo_tag_id = request.data.get('repo_tag_id')

        if not repo_tag_id:
            error_msg = 'repo_tag_id invalid.'
            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)

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

        repo_tag = RepoTags.objects.get_repo_tag_by_id(repo_tag_id)
        if not repo_tag:
            error_msg = 'repo_tag not found.'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        file_tag = FileTags.objects.get_file_tag(repo_id, repo_tag_id, file_path)
        if file_tag:
            error_msg = 'file tag %s already exist.' % repo_tag_id
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # permission check
        if check_folder_permission(request, repo_id, '/') != PERMISSION_READ_WRITE:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)
        try:
            file_tag = FileTags.objects.add_file_tag(repo_id, repo_tag_id, file_path)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({"file_tag": file_tag.to_dict()}, status=status.HTTP_201_CREATED)
コード例 #30
0
ファイル: models.py プロジェクト: haiwen/seahub
    def create_exist_file_draft(self, repo, username, file_uuid, file_path):
        # create drafts dir if does not exist
        draft_dir_id = seafile_api.get_dir_id_by_path(repo.id, '/Drafts')
        if draft_dir_id is None:
            seafile_api.post_dir(repo.id, '/', 'Drafts', username)

        # check draft file does not exists and copy origin file content to
        # draft file
        draft_file_name = get_draft_file_name(repo.id, file_path)
        draft_file_path = '/Drafts/' + draft_file_name

        try:
            # Determine if there is a draft of the file
            d = self.get(origin_file_uuid=file_uuid.uuid)
        except Draft.DoesNotExist:
            try:
                # Determine if there is a draft with the same name as
                # the generated draft file path
                d_2 = self.get(origin_repo_id=repo.id, draft_file_path=draft_file_path)
                d_2.delete(operator=username)
            except Draft.DoesNotExist:
                pass

            # copy file to draft dir
            seafile_api.copy_file(repo.id, file_uuid.parent_path, file_uuid.filename,
                                  repo.id, '/Drafts', draft_file_name,
                                  username=username, need_progress=0, synchronous=1)

            return draft_file_path

        if d:
            file_id = seafile_api.get_file_id_by_path(repo.id, d.draft_file_path)
            # If the database entry exists and the draft file exists,
            # then raise DraftFileExist
            if file_id:
                raise DraftFileExist
            # If the database entry exists and the draft file does not exist,
            # delete the database entry
            else:
                d.delete(operator=username)

                # copy file to draft dir
                seafile_api.copy_file(repo.id, file_uuid.parent_path, file_uuid.filename,
                                      repo.id, '/Drafts', draft_file_name,
                                      username=username, need_progress=0, synchronous=1)

                return draft_file_path
コード例 #31
0
    def put(self, request, repo_id, format=None):
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

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

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

        username = request.user.username
        operation = request.data.get('operation', '')
        if operation.lower() == 'lock':
            is_locked, locked_by_me = check_file_lock(repo_id, path, username)
            if is_locked:
                error_msg = 'File is already locked.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # lock file
            expire = request.data.get('expire', FILE_LOCK_EXPIRATION_DAYS)
            try:
                seafile_api.lock_file(repo_id, path.lstrip('/'), username,
                                      expire)
                return Response({'success': True})
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)
コード例 #32
0
ファイル: utils.py プロジェクト: InfoTestStg/seahub
def prepare_starred_files(files):
    array = []
    for f in files:
        sfile = {'org' : f.org_id,
                 'repo' : f.repo.id,
                 'repo_name' : f.repo.name,
                 'path' : f.path,
                 'icon_path' : file_icon_filter(f.path),
                 'file_name' : os.path.basename(f.path),
                 'mtime' : f.last_modified,
                 'mtime_relative': translate_seahub_time(f.last_modified),
                 'dir' : f.is_dir
                 }
        if not f.is_dir:
            try:
                file_id = seafile_api.get_file_id_by_path(f.repo.id, f.path)
                sfile['oid'] = file_id
                sfile['size'] = get_file_size(f.repo.store_id, f.repo.version, file_id)
            except SearpcError, e:
                pass

        array.append(sfile)
コード例 #33
0
ファイル: models.py プロジェクト: luojun13/seahub
    def add(self, username, repo, file_path, file_exist=True, file_id=None, org_id=-1, status='open'):
        file_path = normalize_file_path(file_path)
        parent_path = os.path.dirname(file_path)
        filename = os.path.basename(file_path)
        # origin file uuid
        file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(
            repo.id, parent_path, filename, is_dir=False)

        if file_id is None:
            file_id = seafile_api.get_file_id_by_path(repo.id, file_path)

        if file_exist:
            file_path = self.create_exist_file_draft(repo, username, file_uuid, file_path)

        draft = self.model(username=username,
                           origin_repo_id=repo.id,
                           origin_file_uuid=file_uuid.uuid,
                           status=status,
                           origin_file_version=file_id,
                           draft_file_path=file_path)
        draft.save(using=self._db)
        return draft
コード例 #34
0
ファイル: file_participants.py プロジェクト: ysf002/seahub
    def delete(self, request, repo_id, format=None):
        """Delete a participant
        """
        # argument check
        path = request.data.get('path')
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid.')
        path = normalize_file_path(path)

        email = request.data.get('email')
        if not email or not is_valid_username(email):
            return api_error(status.HTTP_400_BAD_REQUEST, 'email invalid.')

        # resource check
        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'File %s not found.' % path)

        # permission check
        if not check_folder_permission(request, repo_id, '/'):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        # main
        try:
            file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap_by_path(
                repo_id, path, False)

            if not FileParticipant.objects.get_participant(file_uuid, email):
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'Participant %s not found.' % email)

            FileParticipant.objects.delete_participant(file_uuid, email)
        except Exception as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal Server Error')

        return Response({'success': True})
コード例 #35
0
    def delete(self, request, repo_id):
        """ delete 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.')

        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)

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

        if not file_id and not dir_id:
            return Response({'success': True})

        parent_dir = os.path.dirname(path)
        file_name = os.path.basename(path)
        try:
            seafile_api.del_file(repo_id, parent_dir, file_name,
                                 request.user.username)
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({'success': True})
コード例 #36
0
ファイル: file.py プロジェクト: nyflxy/seahub
    def get(self, request, repo_id, format=None):
        """ Get file info.

        Permission checking:
        1. user with either 'r' or 'rw' permission.
        """

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

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

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

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

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

        file_info = self.get_file_info(request.user.username, repo_id, path)
        return Response(file_info)
コード例 #37
0
def latest_entry(request, workspace_id, dtable_uuid, path):
    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        return None
    repo_id = workspace.repo_id
    path = normalize_file_path(os.path.join('/asset', dtable_uuid, path))
    file_id = seafile_api.get_file_id_by_path(repo_id, path)
    if file_id:
        try:
            size = request.GET.get('size')
            thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), file_id)
            last_modified_time = os.path.getmtime(thumbnail_file)
            # convert float to datatime obj
            return datetime.datetime.fromtimestamp(last_modified_time)
        except os.error:
            # no thumbnail file exists
            return None
        except Exception as e:
            # catch all other errors
            logger.error(e, exc_info=True)
            return None
    else:
        return None
コード例 #38
0
def view_lib_as_wiki(request, repo_id, path):

    if not path.startswith('/'):
        path = '/' + path

    repo = seafile_api.get_repo(repo_id)

    is_dir = None
    file_id = seafile_api.get_file_id_by_path(repo.id, path)
    if file_id:
        is_dir = False

    dir_id = seafile_api.get_dir_id_by_path(repo.id, path)
    if dir_id:
        is_dir = True

    user_perm = check_folder_permission(request, repo.id, '/')
    if user_perm is None:
        return render_error(request, _('Permission denied'))

    if user_perm == 'rw':
        user_can_write = True
    else:
        user_can_write = False

    return render(
        request, 'view_lib_as_wiki.html', {
            'seafile_collab_server': SEAFILE_COLLAB_SERVER,
            'repo_id': repo_id,
            'service_url': get_service_url().rstrip('/'),
            'initial_path': path,
            'is_dir': is_dir,
            'repo_name': repo.name,
            'permission': user_can_write,
            'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
            'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
        })
コード例 #39
0
    def get(self, request, repo_id, format=None):
        """List all participants of a file.
        """
        # argument check
        path = request.GET.get('path')
        if not path:
            return api_error(status.HTTP_400_BAD_REQUEST, 'path invalid.')
        path = normalize_file_path(path)

        # resource check
        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'File %s not found.' % path)

        # permission check
        if not check_folder_permission(request, repo_id, '/'):
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        # main
        try:
            file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap_by_path(
                repo_id, path, False)

            participant_list = []
            participant_queryset = FileParticipant.objects.get_participants(
                file_uuid)

            for participant in participant_queryset:
                participant_info = get_user_common_info(participant.username)
                participant_list.append(participant_info)
        except Exception as e:
            logger.error(e)
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                             'Internal Server Error.')

        return Response({'participant_list': participant_list})
コード例 #40
0
    def get(self, request, format=None):
        """ get file content
        """

        token = request.GET.get('access_token', None)
        info_dict = cache.get('thirdparty_editor_access_token_' + token)
        repo_id = info_dict['repo_id']
        file_path = info_dict['file_path']

        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)

        if not fileserver_token:
            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 = urllib.request.urlopen(inner_path).read()
        except urllib.error.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")
コード例 #41
0
def view_raw_shared_file(request, token, obj_id, file_name):
    """Returns raw content of a shared file.
    
    Arguments:
    - `request`:
    - `token`:
    - `obj_id`:
    - `file_name`:
    """
    fileshare = FileShare.objects.get_valid_file_link_by_token(token)
    if fileshare is None:
        raise Http404

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

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

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

    if real_obj_id != obj_id:  # perm check
        raise Http404

    filename = os.path.basename(file_path)
    username = request.user.username
    token = web_get_access_token(repo_id, real_obj_id, 'view', username)
    outer_url = gen_file_get_url(token, filename)
    return HttpResponseRedirect(outer_url)
コード例 #42
0
ファイル: models.py プロジェクト: borisblack/seahub
    def publish(self):
        # check whether origin file is updated
        r_repo = seafile_api.get_repo(self.origin_repo_id)
        if not r_repo:
            raise DraftFileConflict

        origin_file_path = self.origin_file_uuid.parent_path + self.origin_file_uuid.filename
        file_id = seafile_api.get_file_id_by_path(self.origin_repo_id,
                                                  origin_file_path)
        if not file_id:
            raise DraftFileConflict

        if file_id != self.origin_file_version:
            raise DraftFileConflict

        # move draft file to origin file
        seafile_api.move_file(
            self.draft_repo_id, '/', self.draft_file_path.lstrip('/'),
            self.origin_repo_id, self.origin_file_uuid.parent_path,
            self.origin_file_uuid.filename, replace=1,
            username=self.username, need_progress=0, synchronous=1
        )

        self.delete()
コード例 #43
0
    def publish(self):
        # check whether origin file is updated
        r_repo = seafile_api.get_repo(self.origin_repo_id)
        if not r_repo:
            raise DraftFileConflict

        if self.origin_file_uuid.parent_path == '/':
            origin_file_path = self.origin_file_uuid.parent_path + self.origin_file_uuid.filename
        else:
            origin_file_path = self.origin_file_uuid.parent_path + '/' + self.origin_file_uuid.filename

        file_id = seafile_api.get_file_id_by_path(self.origin_repo_id,
                                                  origin_file_path)
        if not file_id:
            raise DraftFileConflict

        draft_file_name = os.path.basename(self.draft_file_path)
        draft_file_path = os.path.dirname(self.draft_file_path)

        file_name = self.origin_file_uuid.filename

        if file_id != self.origin_file_version and self.draft_file_path != origin_file_path:
            raise DraftFileConflict

        if self.draft_file_path == origin_file_path:
            f = os.path.splitext(draft_file_name)[0][:-7]
            file_type = os.path.splitext(draft_file_name)[-1]
            file_name = f + file_type

        # move draft file to origin file
        seafile_api.move_file(
            self.origin_repo_id, draft_file_path, draft_file_name,
            self.origin_repo_id, self.origin_file_uuid.parent_path,
            file_name, replace=1,
            username=self.username, need_progress=0, synchronous=1
        )
コード例 #44
0
ファイル: utils.py プロジェクト: yehuangcn/seahub
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)

    return _create_thumbnail_common(extracted_xmind_image_str,
                                    local_xmind_image, size)
コード例 #45
0
    def handle_move(self, dest_path):
        if self.provider.readonly:
            raise DAVError(HTTP_FORBIDDEN)

        parts = dest_path.strip("/").split("/", 1)
        if len(parts) <= 1:
            raise DAVError(HTTP_BAD_REQUEST)
        repo_name = parts[0]
        rel_path = parts[1]

        dest_dir, dest_file = os.path.split(rel_path)
        dest_repo = getRepoByName(repo_name, self.username, self.org_id,
                                  self.is_guest)

        if seafile_api.check_permission_by_path(dest_repo.id, self.rel_path,
                                                self.username) != "rw":
            raise DAVError(HTTP_FORBIDDEN)

        src_dir, src_file = os.path.split(self.rel_path)
        if not src_file:
            raise DAVError(HTTP_BAD_REQUEST)

        if not seafile_api.is_valid_filename(dest_repo.id, dest_file):
            raise DAVError(HTTP_BAD_REQUEST)

        # some clients such as GoodReader requires "overwrite" semantics
        file_id_dest = seafile_api.get_file_id_by_path(dest_repo.id, rel_path)
        if file_id_dest != None:
            seafile_api.del_file(dest_repo.id, dest_dir, dest_file,
                                 self.username)

        seafile_api.move_file(self.repo.id, src_dir, src_file, dest_repo.id,
                              dest_dir, dest_file, 1, self.username,
                              NEED_PROGRESS, SYNCHRONOUS)

        return True
コード例 #46
0
    def delete(self, request, org_id, dtable_id):
        error, _ = _check_org(org_id)
        if error:
            return error
        # resource check
        dtable = DTables.objects.filter(
            id=dtable_id, deleted=False,
            workspace__org_id=org_id).select_related('workspace').first()
        if not dtable:
            error_msg = 'table not found.'
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        username = request.user.username
        repo_id = dtable.workspace.repo_id
        # rename .dtable file
        new_dtable_name, old_dtable_file_name, new_dtable_file_name = convert_dtable_trash_names(
            dtable)

        table_path = normalize_file_path(old_dtable_file_name)
        table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path)
        # if has .dtable file, then rename, else skip
        if table_file_id:
            seafile_api.rename_file(repo_id, '/', old_dtable_file_name,
                                    new_dtable_file_name, username)

        try:
            DTables.objects.filter(id=dtable.id).update(
                deleted=True,
                delete_time=datetime.utcnow(),
                name=new_dtable_name)
        except Exception as e:
            logger.error('delete dtable: %s error: %s', dtable.id, e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({'success': True})
コード例 #47
0
ファイル: utils.py プロジェクト: gzy403999903/seahub
def has_draft_file(repo_id, file_path):
    has_draft = False
    file_path = normalize_file_path(file_path)
    parent_path = os.path.dirname(file_path)
    filename = os.path.basename(file_path)

    file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_path(repo_id,
                                                            parent_path,
                                                            filename,
                                                            is_dir=False)

    from .models import Draft
    if file_uuid:
        try:
            d = Draft.objects.get(origin_file_uuid=file_uuid)
            file_id = seafile_api.get_file_id_by_path(repo_id,
                                                      d.draft_file_path)
            if file_id:
                has_draft = True

        except Draft.DoesNotExist:
            pass

    return has_draft
コード例 #48
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
コード例 #49
0
    def get(self, request, slug):
        """Get content of a wiki
        """
        path = request.GET.get('p', '/')
        try:
            wiki = Wiki.objects.get(slug=slug)
        except Wiki.DoesNotExist:
            error_msg = "Wiki not found."
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # perm check
        if not wiki.check_access_wiki(request):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if request.user.username:
            parent_dir = os.path.dirname(path)
            permission = check_folder_permission(request, wiki.repo_id,
                                                 parent_dir)
        else:
            permission = 'r'

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

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

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

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

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

        url = gen_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,
        })
コード例 #50
0
ファイル: file.py プロジェクト: nyflxy/seahub
class FileView(APIView):
    """
    Support uniform interface for file related operations,
    including create/delete/rename/view, etc.
    """

    authentication_classes = (TokenAuthentication, SessionAuthentication)
    permission_classes = (IsAuthenticated, )
    throttle_classes = (UserRateThrottle, )

    def get_file_info(self, username, repo_id, file_path):

        file_obj = seafile_api.get_dirent_by_path(repo_id, file_path)
        is_locked, locked_by_me = check_file_lock(repo_id, file_path, username)
        file_info = {
            'type': 'file',
            'repo_id': repo_id,
            'parent_dir': os.path.dirname(file_path),
            'obj_name': file_obj.obj_name,
            'obj_id': file_obj.obj_id,
            'size': file_obj.size,
            'mtime': timestamp_to_isoformat_timestr(file_obj.mtime),
            'is_locked': is_locked,
        }

        return file_info

    def get(self, request, repo_id, format=None):
        """ Get file info.

        Permission checking:
        1. user with either 'r' or 'rw' permission.
        """

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

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

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

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

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

        file_info = self.get_file_info(request.user.username, repo_id, path)
        return Response(file_info)

    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 or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        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)

        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) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # create file
            new_file_name = os.path.basename(path)
            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)

            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)

        if operation == 'rename':
            # argument check
            new_file_name = request.data.get('newname', None)
            if not new_file_name:
                error_msg = 'newname invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if len(new_file_name) > MAX_UPLOAD_FILE_NAME_LEN:
                error_msg = 'newname is too long.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            oldname = os.path.basename(path)
            if oldname == new_file_name:
                error_msg = 'The new name is the same to the old'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

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

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

            # rename file
            new_file_name = check_filename_with_rename(repo_id, parent_dir,
                                                       new_file_name)
            try:
                seafile_api.rename_file(repo_id, parent_dir, oldname,
                                        new_file_name, username)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            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)

        if operation == 'move':
            # argument check
            dst_repo_id = request.data.get('dst_repo', None)
            dst_dir = request.data.get('dst_dir', None)
            if not dst_repo_id:
                error_msg = 'dst_repo invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

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

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

            # resource check for dst repo and dir
            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # permission check for source file
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if check_folder_permission(request, src_repo_id, src_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # permission check for dst dir
            if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # move file
            if dst_dir[
                    -1] != '/':  # Append '/' to the end of directory if necessary
                dst_dir += '/'

            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                file_info = self.get_file_info(username, repo_id, path)
                return Response(file_info)

            filename = os.path.basename(path)
            new_file_name = check_filename_with_rename(dst_repo_id, dst_dir,
                                                       filename)
            try:
                seafile_api.move_file(src_repo_id,
                                      src_dir,
                                      filename,
                                      dst_repo_id,
                                      dst_dir,
                                      new_file_name,
                                      replace=False,
                                      username=username,
                                      need_progress=0,
                                      synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            dst_file_path = posixpath.join(dst_dir, new_file_name)
            dst_file_info = self.get_file_info(username, dst_repo_id,
                                               dst_file_path)
            return Response(dst_file_info)

        if operation == 'copy':
            # argument check
            dst_repo_id = request.data.get('dst_repo', None)
            dst_dir = request.data.get('dst_dir', None)
            if not dst_repo_id:
                error_msg = 'dst_repo_id invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

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

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

            # resource check for dst repo and dir
            dst_repo = seafile_api.get_repo(dst_repo_id)
            if not dst_repo:
                error_msg = 'Library %s not found.' % dst_repo_id
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            dst_dir_id = seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir)
            if not dst_dir_id:
                error_msg = 'Folder %s not found.' % dst_dir
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            # permission check for source file
            src_repo_id = repo_id
            src_dir = os.path.dirname(path)
            if not check_folder_permission(request, src_repo_id, src_dir):
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # permission check for dst dir
            if check_folder_permission(request, dst_repo_id, dst_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            # copy file
            if dst_dir[
                    -1] != '/':  # Append '/' to the end of directory if necessary
                dst_dir += '/'

            if src_repo_id == dst_repo_id and src_dir == dst_dir:
                file_info = self.get_file_info(username, repo_id, path)
                return Response(file_info)

            filename = os.path.basename(path)
            new_file_name = check_filename_with_rename(dst_repo_id, dst_dir,
                                                       filename)
            try:
                seafile_api.copy_file(src_repo_id,
                                      src_dir,
                                      filename,
                                      dst_repo_id,
                                      dst_dir,
                                      new_file_name,
                                      username,
                                      0,
                                      synchronous=1)
            except SearpcError as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            dst_file_path = posixpath.join(dst_dir, new_file_name)
            dst_file_info = self.get_file_info(username, dst_repo_id,
                                               dst_file_path)
            return Response(dst_file_info)

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

            if seafile_api.get_file_id_by_path(repo_id, path):
                # file exists in repo
                if check_folder_permission(request, repo_id,
                                           parent_dir) != 'rw':
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                is_locked, locked_by_me = check_file_lock(
                    repo_id, path, username)
                if (is_locked, locked_by_me) == (None, None):
                    error_msg = _("Check file lock error")
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                     error_msg)

                if is_locked and not locked_by_me:
                    error_msg = _("File is locked")
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            else:
                # file NOT exists in repo
                if check_folder_permission(request, repo_id, '/') != 'rw':
                    error_msg = 'Permission denied.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            try:
                seafile_api.revert_file(repo_id, commit_id, path, username)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            return Response({'success': True})
コード例 #51
0
def slug(request, slug, file_path="home.md"):
    """Show wiki page.
    """
    # get wiki object or 404
    wiki = get_object_or_404(Wiki, slug=slug)
    file_path = "/" + file_path

    is_dir = None
    file_id = seafile_api.get_file_id_by_path(wiki.repo_id, file_path)
    if file_id:
        is_dir = False

    dir_id = seafile_api.get_dir_id_by_path(wiki.repo_id, file_path)
    if dir_id:
        is_dir = True

    # compatible with old wiki url
    if is_dir is None:
        if len(file_path.split('.')) == 1:
            new_path = file_path[1:] + '.md'
            return HttpResponseRedirect(reverse('wiki:slug', args=[slug, new_path]))

    # perm check
    req_user = request.user.username

    if not req_user and not wiki.has_read_perm(request):
        return redirect('auth_login')
    else:
        if not wiki.has_read_perm(request):
            return render_permission_error(request, _('Unable to view Wiki'))

    file_type, ext = get_file_type_and_ext(posixpath.basename(file_path))
    if file_type == IMAGE:
        file_url = reverse('view_lib_file', args=[wiki.repo_id, file_path])
        return HttpResponseRedirect(file_url + "?raw=1")

    if not req_user:
        user_can_write = False
    elif req_user == wiki.username or check_folder_permission(
            request, wiki.repo_id, '/') == 'rw':
        user_can_write = True
    else:
        user_can_write = False

    is_public_wiki = False
    if wiki.permission == 'public':
        is_public_wiki = True

    has_index = False
    dirs = seafile_api.list_dir_by_path(wiki.repo_id, '/')
    for dir_obj in dirs:
        if dir_obj.obj_name == 'index.md':
            has_index = True
            break

    try:
        fs = FileShare.objects.get(repo_id=wiki.repo_id, path='/')
    except FileShare.DoesNotExist:
        fs = FileShare.objects.create_dir_link(wiki.username, wiki.repo_id, '/',
                                               permission='view_download')
        wiki.permission = 'public'
        wiki.save()
        is_public_wiki = True

    repo = seafile_api.get_repo(wiki.repo_id)

    return render(request, "wiki/wiki.html", {
        "wiki": wiki,
        "repo_name": repo.name if repo else '',
        "page_name": file_path,
        "shared_token": fs.token,
        "shared_type": fs.s_type,
        "user_can_write": user_can_write,
        "file_path": file_path,
        "filename": os.path.splitext(os.path.basename(file_path))[0],
        "repo_id": wiki.repo_id,
        "search_repo_id": wiki.repo_id,
        "search_wiki": True,
        "is_public_wiki": is_public_wiki,
        "is_dir": is_dir,
        "has_index": has_index,
    })
コード例 #52
0
    def get(self, request, file_id, format=None):
        """ WOPI endpoint for check file info
        """

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

        try:
            file_size = seafile_api.get_file_size(repo.store_id, repo.version,
                                                  obj_id)
        except SearpcError as e:
            logger.error(e)
            return HttpResponse(json.dumps({}),
                                status=500,
                                content_type=json_content_type)

        if file_size == -1:
            logger.error('File %s not found.') % file_path
            return HttpResponse(json.dumps({}),
                                status=401,
                                content_type=json_content_type)

        result = {}
        # necessary
        result['BaseFileName'] = os.path.basename(file_path)
        result['OwnerId'] = seafile_api.get_repo_owner(repo_id)
        result['Size'] = file_size
        result['UserId'] = request_user
        result['Version'] = obj_id

        # optional
        result['UserFriendlyName'] = email2nickname(request_user)
        absolute_uri = request.build_absolute_uri('/')
        result['PostMessageOrigin'] = urlparse.urljoin(absolute_uri,
                                                       SITE_ROOT).strip('/')
        result['HidePrintOption'] = False
        result['HideSaveOption'] = False
        result['HideExportOption'] = False
        result['EnableOwnerTermination'] = True
        result['SupportsLocks'] = True
        result['SupportsGetLock'] = True
        result['SupportsUpdate'] = True

        filename = os.path.basename(file_path)
        filetype, fileext = get_file_type_and_ext(filename)
        is_locked, locked_by_me = check_file_lock(repo_id, file_path,
                                                  request_user)
        perm = seafile_api.check_permission_by_path(repo_id, file_path,
                                                    request_user)

        if ENABLE_OFFICE_WEB_APP_EDIT and not repo.encrypted and \
            perm == 'rw' and ((not is_locked) or (is_locked and locked_by_me)) and \
                fileext in OFFICE_WEB_APP_EDIT_FILE_EXTENSION:

            result['UserCanWrite'] = True

        return HttpResponse(json.dumps(result),
                            status=200,
                            content_type=json_content_type)
コード例 #53
0
    def post(self, request, format=None):
        """Add a new wiki.
        """
        username = request.user.username

        org_id = -1
        if is_org_context(request):
            org_id = request.user.org.org_id

        repo_id = request.POST.get('repo_id', '')
        if not repo_id:
            msg = 'Repo id is invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        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)

        # check perm
        if not (request.user.permissions.can_publish_repo() and request.user.permissions.can_generate_share_link()):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        is_owner = is_repo_owner(request, repo_id, username)

        if not is_owner:
            repo_admin = is_repo_admin(username, repo_id)

            if not repo_admin:
                is_group_repo_admin = is_group_repo_staff(request, repo_id, username)

                if not is_group_repo_admin:
                    error_msg = _('Permission denied.')
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            wiki = Wiki.objects.add(wiki_name=repo.repo_name, username=username,
                    repo_id=repo.repo_id, org_id=org_id, permission='public')
        except DuplicateWikiNameError:
            msg = _('%s is taken by others, please try another name.') % repo.repo_name
            return api_error(status.HTTP_400_BAD_REQUEST, msg)
        except IntegrityError:
            msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

        # create home page if not exist
        page_name = "home.md"
        if not seafile_api.get_file_id_by_path(repo_id, "/" + page_name):
            try:
                seafile_api.post_empty_file(repo_id, '/', page_name, username)
            except SearpcError as e:
                logger.error(e)
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

        fs = FileShare.objects.get_dir_link_by_path(username, repo_id, '/')
        if not fs:
            fs = FileShare.objects.create_dir_link(username, repo_id, '/',
                    permission='view_download', org_id=org_id)

        return Response(wiki.to_dict())
コード例 #54
0
    def post(self, request):
        """ Copy/move file/dir, and return task id.

        Permission checking:
        1. move: user with 'rw' permission for current file, 'rw' permission for dst parent dir;
        2. copy: user with 'r' permission for current file, 'rw' permission for dst parent dir;
        """
        src_repo_id = request.data.get('src_repo_id', None)
        src_parent_dir = request.data.get('src_parent_dir', None)
        src_dirent_name = request.data.get('src_dirent_name', None)
        dst_repo_id = request.data.get('dst_repo_id', None)
        dst_parent_dir = request.data.get('dst_parent_dir', None)
        operation = request.data.get('operation', None)
        dirent_type = request.data.get('dirent_type', None)

        # argument check
        if not src_repo_id:
            error_msg = 'src_repo_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

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

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

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

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

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

        if src_repo_id == dst_repo_id and src_parent_dir == dst_parent_dir:
            error_msg = _('Invalid destination path')
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if len(dst_parent_dir + src_dirent_name) > MAX_PATH:
            error_msg = _('Destination path is too long.')
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        dirent_type = dirent_type.lower()
        if dirent_type not in ('file', 'dir'):
            error_msg = "operation can only be 'file' or 'dir'."
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # src resource check
        src_dirent_path = posixpath.join(src_parent_dir, src_dirent_name)
        if dirent_type == 'file':
            if not seafile_api.get_file_id_by_path(src_repo_id,
                                                   src_dirent_path):
                error_msg = 'File %s not found.' % src_dirent_path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if dirent_type == 'dir':
            if not seafile_api.get_dir_id_by_path(src_repo_id,
                                                  src_dirent_path):
                error_msg = 'Folder %s not found.' % src_dirent_path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # dst resource check
        if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_parent_dir):
            error_msg = 'Folder %s not found.' % dst_parent_dir
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check for dst parent dir
        if check_folder_permission(request, dst_repo_id,
                                   dst_parent_dir) != 'rw':
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        new_dirent_name = check_filename_with_rename(dst_repo_id,
                                                     dst_parent_dir,
                                                     src_dirent_name)

        username = request.user.username
        if operation == 'move':
            # permission check for src parent dir
            if check_folder_permission(request, src_repo_id,
                                       src_parent_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            if dirent_type == 'dir' and src_repo_id == dst_repo_id and \
                    dst_parent_dir.startswith(src_dirent_path + '/'):

                error_msg = _(u'Can not move directory %(src)s to its subdirectory %(des)s') \
                    % {'src': escape(src_dirent_path), 'des': escape(dst_parent_dir)}
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if dirent_type == 'file':
                # check file lock
                try:
                    is_locked, locked_by_me = check_file_lock(
                        src_repo_id, src_dirent_path, 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 is_locked and not locked_by_me:
                    error_msg = _("File is locked")
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            try:
                res = seafile_api.move_file(src_repo_id,
                                            src_parent_dir,
                                            src_dirent_name,
                                            dst_repo_id,
                                            dst_parent_dir,
                                            new_dirent_name,
                                            replace=False,
                                            username=username,
                                            need_progress=1)
                is_dir = True if dirent_type == 'dir' else False
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        if operation == 'copy':
            # permission check for src parent dir
            if not check_folder_permission(request, src_repo_id,
                                           src_parent_dir):
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            try:
                res = seafile_api.copy_file(src_repo_id,
                                            src_parent_dir,
                                            src_dirent_name,
                                            dst_repo_id,
                                            dst_parent_dir,
                                            new_dirent_name,
                                            username=username,
                                            need_progress=1)
            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 res:
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        result = {}
        if res.background:
            result['task_id'] = res.task_id

        return Response(result)
コード例 #55
0
    def get(self, request):
        """list all related files of a file.
        """
        # argument check
        repo_id = request.GET.get('repo_id')
        if not repo_id:
            error_msg = 'repo_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        
        file_path = request.GET.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
        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)

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

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

        filename = os.path.basename(file_path)
        parent_path = os.path.dirname(file_path)
        uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(repo_id, parent_path, filename, is_dir=False)
        try:
            file_uuid_list = RelatedFiles.objects.get_related_files_uuid(uuid)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        related_files = list()
        for file_uuid in file_uuid_list:
            if file_uuid.o_uuid == uuid:
                r_path = posixpath.join(file_uuid.r_uuid.parent_path, file_uuid.r_uuid.filename)
                r_repo_id = file_uuid.r_uuid.repo_id
                r_file_id = seafile_api.get_file_id_by_path(r_repo_id, r_path)
                if not r_file_id:
                    continue
                related_file = self.get_related_file(r_repo_id, r_path, file_uuid.r_uuid)
                related_file["related_id"] = file_uuid.pk
                related_files.append(related_file)
            else:
                r_path = posixpath.join(file_uuid.o_uuid.parent_path, file_uuid.o_uuid.filename)
                r_repo_id = file_uuid.o_uuid.repo_id
                r_file_id = seafile_api.get_file_id_by_path(r_repo_id, r_path)
                if not r_file_id:
                    continue
                related_file = self.get_related_file(r_repo_id, r_path, file_uuid.o_uuid)
                related_file["related_id"] = file_uuid.pk
                related_files.append(related_file)

        return Response({"related_files": related_files}, status=status.HTTP_200_OK)
コード例 #56
0
ファイル: share_links.py プロジェクト: flazx/dtable-web
    def get(self, request, token):
        """ Get FileServer download url of the shared file/dir.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                result['download_link'] = gen_dir_zip_download_url(zip_token)

        return Response(result)
コード例 #57
0
ファイル: wikis.py プロジェクト: bougault/seahub
    def post(self, request, format=None):
        """Add a new wiki.
        """
        use_exist_repo = request.POST.get('use_exist_repo', '')
        if not use_exist_repo:
            msg = 'Use exist repo is invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        name = request.POST.get('name', '')
        if not name:
            msg = 'Name is invalid'
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        if not is_valid_wiki_name(name):
            msg = _('Name can only contain letters, numbers, blank, hyphen or underscore.')
            return api_error(status.HTTP_400_BAD_REQUEST, msg)

        username = request.user.username

        org_id = -1
        if is_org_context(request):
            org_id = request.user.org.org_id

        if use_exist_repo == 'false':
            try:
                wiki = Wiki.objects.add(name, username, org_id=org_id)
            except DuplicateWikiNameError:
                msg = _('%s is taken by others, please try another name.') % name
                return api_error(status.HTTP_400_BAD_REQUEST, msg)
            except IntegrityError:
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

            # create home page
            page_name = "home.md"
            try:
                seafile_api.post_empty_file(wiki.repo_id, '/',
                                            page_name, request.user.username)
            except SearpcError as e:
                logger.error(e)
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

            return Response(wiki.to_dict())

        if use_exist_repo == 'true':
            repo_id = request.POST.get('repo_id', '')
            if not repo_id:
                msg = 'Repo id is invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, msg)

            repo = seafile_api.get_repo(repo_id)

            if check_folder_permission(request, repo_id, '/') != 'rw':
                error_msg = _('Permission denied.')
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)
            try:
                wiki = Wiki.objects.add(wiki_name=repo.repo_name, username=username, 
                        repo_id=repo.repo_id, org_id=org_id)
            except DuplicateWikiNameError:
                msg = _('%s is taken by others, please try another name.') % repo.repo_name
                return api_error(status.HTTP_400_BAD_REQUEST, msg)
            except IntegrityError:
                msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)

            # create home page if not exist
            page_name = "home.md"
            if not seafile_api.get_file_id_by_path(repo_id, "/" + page_name):
                try:
                    seafile_api.post_empty_file(repo_id, '/', page_name, username)
                except SearpcError as e:
                    logger.error(e)
                    msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, msg)


            return Response(wiki.to_dict()) 
コード例 #58
0
    def get(self, request):
        """ Get smart link of a file/dir.
        """

        # argument check
        repo_id = request.GET.get('repo_id', None)
        if not repo_id or not is_valid_repo_id_format(repo_id):
            error_msg = 'repo_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, 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)

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

        is_dir = is_dir.lower()
        if is_dir not in ('true', 'false'):
            error_msg = "is_dir can only be 'true' or 'false'."
            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)

        is_dir = to_python_boolean(is_dir)
        if is_dir:
            if not seafile_api.get_dir_id_by_path(repo_id, normalize_dir_path(path)):
                error_msg = 'Folder %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        else:
            if not seafile_api.get_file_id_by_path(repo_id, normalize_file_path(path)):
                error_msg = 'File %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        # make sure path:
        # 1. starts with '/'
        # 2. NOT ends with '/'
        path = normalize_file_path(path)
        parent_dir = os.path.dirname(path)
        dirent_name = os.path.basename(path)

        # get file/dir uuid
        if repo.is_virtual:
            repo_id = repo.origin_repo_id
            path = posixpath.join(repo.origin_path, path.strip('/'))

            path = normalize_file_path(path)
            parent_dir = os.path.dirname(path)
            dirent_name = os.path.basename(path)

        try:
            uuid_map = FileUUIDMap.objects.get_or_create_fileuuidmap(repo_id,
                    parent_dir, dirent_name, is_dir)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        dirent_uuid = uuid_map.uuid
        smart_link = gen_smart_link(dirent_uuid, dirent_name)

        result = {}
        result['smart_link'] = smart_link
        result['smart_link_token'] = dirent_uuid

        return Response(result)
コード例 #59
0
    def put(self, request, pk, format=None):
        """update review status 
        Close: the user has read permission to the repo
        Publish: the user has read-write permission to the repo
        """

        st = request.data.get('status', '')
        if not st:
            return api_error(status.HTTP_400_BAD_REQUEST,
                             'Status %s invalid.')

        try:
            r = DraftReview.objects.get(pk=pk)
        except DraftReview.DoesNotExist:
            return api_error(status.HTTP_404_NOT_FOUND,
                             'Review %s not found' % pk)

        uuid = r.origin_file_uuid
        origin_file_path = posixpath.join(uuid.parent_path, uuid.filename)

        perm = check_folder_permission(request, r.origin_repo_id, '/')

        # Close: the user has read permission to the repo
        if st == 'closed':
            if perm is None:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            r.status = st
            r.save()

        # Publish: the user has read-write permission to the repo
        if st == 'finished':
            if perm != PERMISSION_READ_WRITE:
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            try:
                d = Draft.objects.get(pk=r.draft_id_id)
            except Draft.DoesNotExist:
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'Draft %s not found.' % pk)

            try:
                d.publish()
            except (DraftFileConflict, IntegrityError):
                return api_error(status.HTTP_409_CONFLICT,
                             'There is a conflict between the draft and the original file')

            # if it is a new draft
            # case1. '/path/test(draft).md' ---> '/path/test.md'
            # case2. '/path/test(dra.md' ---> '/path/test(dra.md'
            if d.draft_file_path == origin_file_path:
                new_draft_dir = os.path.dirname(origin_file_path)
                new_draft_name = os.path.basename(origin_file_path)

                draft_flag = os.path.splitext(new_draft_name)[0][-7:]

                # remove `(draft)` from file name
                if draft_flag == '(draft)':
                    f = os.path.splitext(new_draft_name)[0][:-7]
                    file_type = os.path.splitext(new_draft_name)[-1]
                    new_draft_name = f + file_type

                if new_draft_dir == '/':
                    origin_file_path = new_draft_dir + new_draft_name
                else:
                    origin_file_path = new_draft_dir + '/' + new_draft_name

                r.draft_file_path = origin_file_path

            # get draft published version
            file_id = seafile_api.get_file_id_by_path(r.origin_repo_id, origin_file_path)
            r.publish_file_version = file_id
            r.status = st
            r.save()
            d.delete()

        reviewers = ReviewReviewer.objects.filter(review_id=r)
        # send notice to other reviewers if has
        if reviewers:
            for i in reviewers:
                #  If it is a reviewer operation, exclude it.
                if i.reviewer == request.user.username:
                    continue

                update_review_successful.send(sender=None, from_user=request.user.username,
                                              to_user=i.reviewer, review_id=r.id, status=st)

        # send notice to review owner
        if request.user.username != r.creator:
            update_review_successful.send(sender=None, from_user=request.user.username,
                                          to_user=r.creator, review_id=r.id, status=st)

        result = r.to_dict()

        return Response(result)
コード例 #60
0
    def post(self, request):
        """add a related file for a file
        """
        # argument check
        o_repo_id = request.data.get('o_repo_id')
        if not o_repo_id:
            error_msg = 'o_repo_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        o_path = request.data.get('o_path')
        if not o_path:
            error_msg = 'o_file_path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        o_path = normalize_file_path(o_path)

        r_path = request.data.get('r_path')
        if not r_path:
            error_msg = 'r_file_path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        r_path = normalize_file_path(r_path)

        if o_repo_id == r_repo_id and o_path == r_path:
            error_msg = 'Cannot relate itself.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        o_repo = seafile_api.get_repo(o_repo_id)
        r_repo = seafile_api.get_repo(r_repo_id)
        if not o_repo:
            error_msg = 'Library %s not found.' % o_repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        if not r_repo:
            error_msg = 'Library %s not found.' % r_repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        o_file_id = seafile_api.get_file_id_by_path(o_repo_id, o_path)
        r_file_id = seafile_api.get_file_id_by_path(r_repo_id, r_path)
        if not o_file_id:
            error_msg = 'File %s not found.' % o_path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)
        if not r_file_id:
            error_msg = 'File %s not found.' % r_path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        related_file_uuid = RelatedFiles.objects.get_related_file_uuid(o_repo_id, r_repo_id, o_path, r_path)
        if related_file_uuid:
            error_msg = 'related file already exist.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

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

        try:
            related_file_uuid = RelatedFiles.objects.add_related_file_uuid(o_repo_id, r_repo_id, o_path, r_path)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        related_file = self.get_related_file(r_repo_id, r_path, related_file_uuid.r_uuid)
        related_file["related_id"] = related_file_uuid.pk

        return Response({"related_file": related_file}, status.HTTP_201_CREATED)