def dtable_asset_file_view(request, workspace_id, dtable_id, path): # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, 'Library does not exist.') dtable = DTables.objects.get_dtable_by_uuid(dtable_id) if not dtable: return render_error(request, 'DTable does not exist.') asset_path = normalize_file_path(os.path.join('/asset', dtable_id, path)) asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not asset_id: return render_error(request, 'Asset file does not exist.') # permission check username = request.user.username if not check_dtable_permission(username, workspace, dtable): return render_permission_error(request, _('Permission denied.')) file_enc = request.GET.get('file_enc', 'auto') if file_enc not in FILE_ENCODING_LIST: file_enc = 'auto' token = seafile_api.get_fileserver_access_token(repo_id, asset_id, 'view', '', use_onetime=False) file_name = os.path.basename(normalize_file_path(path)) file_type, file_ext = get_file_type_and_ext(file_name) inner_path = gen_inner_file_get_url(token, file_name) error_msg, file_content, encoding = get_file_content( file_type, inner_path, file_enc) raw_path = gen_file_get_url(token, file_name) return_dict = { 'repo': repo, 'filename': file_name, 'file_path': asset_path, 'file_type': file_type, 'file_ext': file_ext, 'raw_path': raw_path, 'file_content': file_content, 'err': 'File preview unsupported' if file_type == 'Unknown' else error_msg, } return render(request, 'dtable_asset_file_view_react.html', return_dict)
def dtable_asset_access(request, workspace_id, dtable_id, path): """ Permission: 1. owner 2. group member 3. shared user with `rw` or `admin` permission """ # asset file type check asset_name = os.path.basename(normalize_file_path(path)) file_type, file_ext = get_file_type_and_ext(asset_name) if file_type != IMAGE: err_msg = 'Invalid file type' return render_error(request, err_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: raise Http404 repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: raise Http404 dtable = DTables.objects.get_dtable_by_uuid(dtable_id) if not dtable: raise Http404 asset_path = normalize_file_path(os.path.join('/asset', dtable_id, path)) asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not asset_id: raise Http404 # permission check username = request.user.username owner = workspace.owner if not check_dtable_permission(username, owner) and \ check_dtable_share_permission(dtable, username) not in WRITE_PERMISSION_TUPLE: return render_permission_error(request, _(u'Permission denied.')) dl = request.GET.get('dl', '0') == '1' operation = 'download' if dl else 'view' token = seafile_api.get_fileserver_access_token(repo_id, asset_id, operation, '', use_onetime=False) url = gen_file_get_url(token, asset_name) return HttpResponseRedirect(url)
def add_related_file_uuid(self, o_repo_id, r_repo_id, o_path, r_path): o_file_path = normalize_file_path(o_path) o_filename = os.path.basename(o_file_path) o_parent_path = os.path.dirname(o_file_path) r_file_path = normalize_file_path(r_path) r_filename = os.path.basename(r_file_path) r_parent_path = os.path.dirname(r_file_path) o_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(o_repo_id, o_parent_path, o_filename, is_dir=False) r_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(r_repo_id, r_parent_path, r_filename, is_dir=False) related_file_uuid = self.model(o_uuid=o_uuid, r_uuid=r_uuid) related_file_uuid.save() return related_file_uuid
def get_related_file_uuid(self, o_repo_id, r_repo_id, o_path, r_path): o_file_path = normalize_file_path(o_path) o_filename = os.path.basename(o_file_path) o_parent_path = os.path.dirname(o_file_path) r_file_path = normalize_file_path(r_path) r_filename = os.path.basename(r_file_path) r_parent_path = os.path.dirname(r_file_path) o_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(o_repo_id, o_parent_path, o_filename, is_dir=False) r_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap(r_repo_id, r_parent_path, r_filename, is_dir=False) try: return super(RelatedFilesManager, self).get( Q(o_uuid=o_uuid, r_uuid=r_uuid) | Q(o_uuid=r_uuid, r_uuid=o_uuid)) except self.model.DoesNotExist: return None
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})
def create_file_link(self, username, repo_id, path, password=None, expire_date=None): """Create download link for file. """ path = normalize_file_path(path) return self._add_file_share(username, repo_id, path, 'f', password, expire_date)
def add(self, username, repo, file_path, file_id=None, org_id=-1): 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_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) # create draft repo if any draft_repo_id = self.get_user_draft_repo_id(username) if draft_repo_id is None: draft_repo_id = create_user_draft_repo(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 = '/' + draft_file_name if seafile_api.get_file_id_by_path(draft_repo_id, draft_file_path): raise DraftFileExist seafile_api.copy_file(repo.id, file_uuid.parent_path, file_uuid.filename, draft_repo_id, '/', draft_file_name, username=username, need_progress=0, synchronous=1) draft = self.model(username=username, origin_repo_id=repo.id, origin_file_uuid=file_uuid, origin_file_version=file_id, draft_repo_id=draft_repo_id, draft_file_path=draft_file_path) draft.save(using=self._db) return draft
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
def put(self, request, repo_id): """ Copy a single file/folder to other place. """ # check parameter for src path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: dirent = seafile_api.get_dirent_by_path(repo_id, path) 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 dirent: error_msg = 'File or folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if path == '/': error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # normalize path to '/1/2/3' format # NOT ends with '/' path = normalize_file_path(path) # now get `src_dir` and `obj_name` according to normalized path src_repo_id = repo_id src_dir = os.path.dirname(path) src_obj_name = os.path.basename(path) # check parameter for dst dst_repo_id = request.data.get('dst_repo_id', src_repo_id) if dst_repo_id != src_repo_id and not seafile_api.get_repo(dst_repo_id): error_msg = 'Library %s not found.' % dst_repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dst_dir = request.data.get('dst_dir', '/') if dst_dir != '/': dst_dir = normalize_dir_path(dst_dir) if not seafile_api.get_dir_id_by_path(dst_repo_id, dst_dir): error_msg = 'Folder %s not found.' % dst_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # copy file username = request.user.username dst_obj_name = check_filename_with_rename(dst_repo_id, dst_dir, src_obj_name) try: seafile_api.copy_file(src_repo_id, src_dir, src_obj_name, dst_repo_id, dst_dir, dst_obj_name, 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) return Response({'success': True, 'dst_item_name': dst_obj_name})
def get_draft_file_name(repo_id, file_path): file_path = normalize_file_path(file_path) file_name, file_ext = os.path.splitext(os.path.basename(file_path)) draft_file_name = "%s%s%s" % (file_name, '(draft)', file_ext) return draft_file_name
def get_file_draft(repo_id, file_path, is_draft=False, has_draft=False): draft = {} draft['draft_id'] = None draft['draft_file_path'] = '' draft['draft_origin_file_path'] = '' from .models import Draft if is_draft: d = Draft.objects.get(origin_repo_id=repo_id, draft_file_path=file_path) uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid) file_path = posixpath.join(uuid.parent_path, uuid.filename) draft['draft_id'] = d.id draft['draft_file_path'] = d.draft_file_path draft['draft_origin_file_path'] = file_path if has_draft: 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) d = Draft.objects.get(origin_file_uuid=file_uuid.uuid) draft['draft_id'] = d.id draft['draft_file_path'] = d.draft_file_path return draft
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.filter(origin_file_uuid=file_uuid.uuid) if d: d = d[0] file_id = seafile_api.get_file_id_by_path( repo_id, d.draft_file_path) if file_id: has_draft = True else: Draft.DoesNotExist except Draft.DoesNotExist: pass return has_draft
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)
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)
def get_file_draft(repo_id, file_path, is_draft=False, has_draft=False): draft = {} draft['draft_id'] = None draft['draft_file_path'] = '' draft['draft_origin_file_path'] = '' from .models import Draft if is_draft: d = Draft.objects.get(origin_repo_id=repo_id, draft_file_path=file_path) uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(d.origin_file_uuid) file_path = posixpath.join(uuid.parent_path, uuid.filename) draft['draft_id'] = d.id draft['draft_file_path'] = d.draft_file_path draft['draft_origin_file_path'] = file_path if has_draft: 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) d = Draft.objects.get(origin_file_uuid=file_uuid.uuid) draft['draft_id'] = d.id draft['draft_file_path'] = d.draft_file_path return draft
def get_starred_item(self, email, repo_id, path): path_list = [normalize_file_path(path), normalize_dir_path(path)] starred_items = UserStarredFiles.objects.filter( email=email, repo_id=repo_id).filter(Q(path__in=path_list)) return starred_items[0] if len(starred_items) > 0 else None
def _dtable_asset_access(request, workspace_id, dtable_id, path, asset_name): # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: return render_error(request, 'Workspace does not exist.') repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, 'Library does not exist.') dtable = DTables.objects.get_dtable_by_uuid(dtable_id) if not dtable: return render_error(request, 'DTable does not exist.') # use head method to check asset at 'path' wether exists if request.method == 'HEAD': asset_path = normalize_file_path( os.path.join('/asset', dtable_id, path)) asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not asset_id: return HttpResponse(status=404) return HttpResponse(status=200) asset_path = normalize_file_path(os.path.join('/asset', dtable_id, path)) asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not asset_id: return render_error(request, 'Asset file does not exist.') # permission check username = request.user.username if not (check_dtable_permission(username, workspace, dtable) in WRITE_PERMISSION_TUPLE or \ (get_file_type_and_ext(asset_name)[0] == IMAGE and request.session.get('external_link') and request.session.get('external_link')['dtable_uuid'] == dtable.uuid.hex)): return render_permission_error(request, _('Permission denied.')) dl = request.GET.get('dl', '0') == '1' operation = 'download' if dl else 'view' token = seafile_api.get_fileserver_access_token(repo_id, asset_id, operation, '', use_onetime=False) url = gen_file_get_url(token, asset_name) return HttpResponseRedirect(url)
def get_draft_file_name(repo_id, file_path): file_path = normalize_file_path(file_path) file_name, file_ext = os.path.splitext(os.path.basename(file_path)) draft_file_name = "%s%s%s" % (file_name, '(draft)', file_ext) draft_file_name = check_filename_with_rename(repo_id, '/Drafts', draft_file_name) return draft_file_name
def delete_starred_item(self, email, repo_id, path): path_list = [normalize_file_path(path), normalize_dir_path(path)] starred_items = UserStarredFiles.objects.filter( email=email, repo_id=repo_id).filter(Q(path__in=path_list)) for item in starred_items: item.delete()
def get_private_share_in_file(self, username, repo_id, path): """Get a file that private shared to ``username``. """ path = normalize_file_path(path) ret = super(PrivateFileDirShareManager, self).filter( to_user=username, repo_id=repo_id, path=path, s_type='f') return ret[0] if len(ret) > 0 else None
def get(self, request, workspace_id): """view table file, get table download link """ # argument check table_name = request.GET.get('name', None) if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) reuse = request.GET.get('reuse', '0') if reuse not in ('1', '0'): error_msg = 'reuse invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) table_file_name = table_name + FILE_TYPE table_path = normalize_file_path(table_file_name) table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path) if not table_file_id: error_msg = 'file %s not found.' % table_file_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if not is_group_member(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if username != owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # send stats message send_file_access_msg(request, repo, table_path, 'api') op = request.GET.get('op', 'download') use_onetime = False if reuse == '1' else True return get_repo_file(request, repo_id, table_file_id, table_file_name, op, use_onetime)
def get(self, request, workspace_id, name): """list dtable related users """ table_name = name table_file_name = table_name + FILE_TYPE # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if '@seafile_group' in workspace.owner: group_id = workspace.owner.split('@')[0] group = seaserv.get_group(group_id) if not group: error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) table_path = normalize_file_path(table_file_name) table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path) if not table_file_id: error_msg = 'file %s not found.' % table_file_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if not check_dtable_permission(username, owner) and \ not check_dtable_share_permission(dtable, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # main user_list = list() try: email_list = list_dtable_related_users(workspace, dtable) for email in email_list: user_info = get_user_common_info(email) user_list.append(user_info) except Exception as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') return Response({'user_list': user_list})
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})
def get_dir_starred_files(email, repo_id, parent_dir, org_id=-1): '''Get starred files under parent_dir. ''' starred_files = UserStarredFiles.objects.filter(email=email, repo_id=repo_id, path__startswith=parent_dir, org_id=org_id) return [ normalize_file_path(f.path) for f in starred_files ]
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: related_file = self.get_related_file(file_uuid.r_uuid) related_file["related_id"] = file_uuid.pk related_files.append(related_file) else: related_file = self.get_related_file(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)
def get_dir_starred_files(email, repo_id, parent_dir, org_id=-1): '''Get starred files under parent_dir. ''' starred_files = UserStarredFiles.objects.filter( email=email, repo_id=repo_id, path__startswith=parent_dir, org_id=org_id) return [normalize_file_path(f.path) for f in starred_files]
def add_file_tag(self, repo_id, repo_tag_id, file_path): file_path = normalize_file_path(file_path) filename = os.path.basename(file_path) parent_path = os.path.dirname(file_path) file_uuid = FileUUIDMap.objects.get_or_create_fileuuidmap( repo_id, parent_path, filename, is_dir=False) repo_tag = RepoTags.objects.get_repo_tag_by_id(repo_tag_id) file_tag = self.model(repo_tag=repo_tag, file_uuid=file_uuid) file_tag.save() return file_tag
def add_private_file_share(self, from_user, to_user, repo_id, path, perm): """ """ path = normalize_file_path(path) token = gen_token(max_length=10) pfs = self.model(from_user=from_user, to_user=to_user, repo_id=repo_id, path=path, s_type='f', token=token, permission=perm) pfs.save(using=self._db) return pfs
def dtable_asset_access(request, workspace_id, dtable_id, path): # asset file type check asset_name = os.path.basename(normalize_file_path(path)) file_type, file_ext = get_file_type_and_ext(asset_name) if file_type != IMAGE: err_msg = 'Invalid file type' return render_error(request, err_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: raise Http404 repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: raise Http404 dtable = DTables.objects.get_dtable_by_uuid(dtable_id) if not dtable: raise Http404 asset_path = normalize_file_path(os.path.join('/asset', dtable_id, path)) asset_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not asset_id: raise Http404 # permission check username = request.user.username owner = workspace.owner if username != owner: return render_permission_error(request, 'Permission denied.') token = seafile_api.get_fileserver_access_token(repo_id, asset_id, 'view', '', use_onetime=False) url = gen_file_get_url(token, asset_name) return HttpResponseRedirect(url)
def get(self, request, workspace_id, name): """get dtable access token """ table_name = name table_file_name = table_name + FILE_TYPE # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) table_path = normalize_file_path(table_file_name) table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path) if not table_file_id: error_msg = 'file %s not found.' % table_file_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if not check_dtable_permission(username, owner) and \ not check_dtable_share_permission(dtable, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # generate json web token payload = { 'exp': int(time.time()) + 86400 * 3, 'dtable_uuid': dtable.uuid.hex, 'username': username, } try: access_token = jwt.encode(payload, DTABLE_PRIVATE_KEY, algorithm='HS256') 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({'access_token': access_token})
def put(self, request, token): """ This api only used for refresh OnlineOffice lock when user edit office file via share link. Permission checking: 1, If enable SHARE_LINK_LOGIN_REQUIRED, user must have been authenticated. 2, Share link should have can_edit permission. 3, File must have been locked by OnlineOffice. """ if SHARE_LINK_LOGIN_REQUIRED and \ not request.user.is_authenticated(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: share_link = 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) if share_link.is_expired(): error_msg = 'Share link %s is expired.' % token return api_error(status.HTTP_400_BAD_REQUEST, error_msg) shared_by = share_link.username repo_id = share_link.repo_id path = normalize_file_path(share_link.path) parent_dir = os.path.dirname(path) if seafile_api.check_permission_by_path( repo_id, parent_dir, shared_by) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permissions = share_link.get_permissions() can_edit = permissions['can_edit'] if not can_edit: error_msg = 'Share link %s has no edit permission.' % token return api_error(status.HTTP_403_FORBIDDEN, error_msg) locked_by_online_office = if_locked_by_online_office(repo_id, path) if locked_by_online_office: # refresh lock file try: seafile_api.refresh_file_lock(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) else: error_msg = _("You can not refresh this file's lock.") return api_error(status.HTTP_403_FORBIDDEN, error_msg) return Response({'success': True})
def get(self, request, repo_id): """ get info of a single file/folder in a library """ if not request.user.admin_permissions.can_manage_library(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') repo = seafile_api.get_repo(repo_id) path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = normalize_file_path(path) try: dirent = seafile_api.get_dirent_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not dirent: error_msg = 'File or folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if stat.S_ISDIR(dirent.mode): is_file = False else: is_file = True username = request.user.username if is_file and request.GET.get('dl', '0') == '1': token = seafile_api.get_fileserver_access_token( repo_id, dirent.obj_id, 'download', username, use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY) if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dl_url = gen_file_get_url(token, dirent.obj_name) send_file_access_msg(request, repo, path, 'web') return Response({'download_url': dl_url}) dirent_info = get_dirent_info(dirent) return Response(dirent_info)
def get_file_tag(self, repo_id, repo_tag_id, file_path): file_path = normalize_file_path(file_path) filename = os.path.basename(file_path) parent_path = os.path.dirname(file_path) file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_path( repo_id, parent_path, filename, is_dir=False) try: return super(FileTagsManager, self).get(repo_tag_id=repo_tag_id, file_uuid=file_uuid) except self.model.DoesNotExist: return None
def is_draft_file(repo_id, file_path): is_draft = False file_path = normalize_file_path(file_path) from .models import Draft try: Draft.objects.get(origin_repo_id=repo_id, draft_file_path=file_path) is_draft = True except Draft.DoesNotExist: pass return is_draft
def get_file_draft_and_related_review(repo_id, file_path, is_draft=False, has_draft=False): review = {} review['review_id'] = None review['review_status'] = None review['draft_id'] = None review['draft_file_path'] = '' from .models import Draft, DraftReview if is_draft: d = Draft.objects.get(origin_repo_id=repo_id, draft_file_path=file_path) review['draft_id'] = d.id review['draft_file_path'] = d.draft_file_path # return review (closed / open) try: d_r = DraftReview.objects.get(origin_repo_id=repo_id, draft_file_path=file_path, draft_id=d) review['review_id'] = d_r.id review['review_status'] = d_r.status except DraftReview.DoesNotExist: pass if has_draft: 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) d = Draft.objects.get(origin_file_uuid=file_uuid) # return review (closed / open) if file_uuid: try: d_r = DraftReview.objects.get(origin_file_uuid=file_uuid, draft_id=d) review['review_id'] = d_r.id review['review_status'] = d_r.status except DraftReview.DoesNotExist: pass review['draft_id'] = d.id review['draft_file_path'] = d.draft_file_path return review
def put(self, request, token): """ This api only used for refresh OnlineOffice lock when user edit office file via share link. Permission checking: 1, If enable SHARE_LINK_LOGIN_REQUIRED, user must have been authenticated. 2, Share link should have can_edit permission. 3, File must have been locked by OnlineOffice. """ if SHARE_LINK_LOGIN_REQUIRED and \ not request.user.is_authenticated(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: share_link = 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) if share_link.is_expired(): error_msg = 'Share link %s is expired.' % token return api_error(status.HTTP_400_BAD_REQUEST, error_msg) shared_by = share_link.username repo_id = share_link.repo_id path = normalize_file_path(share_link.path) parent_dir = os.path.dirname(path) if seafile_api.check_permission_by_path(repo_id, parent_dir, shared_by) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permissions = share_link.get_permissions() can_edit = permissions['can_edit'] if not can_edit: error_msg = 'Share link %s has no edit permission.' % token return api_error(status.HTTP_403_FORBIDDEN, error_msg) locked_by_online_office = if_locked_by_online_office(repo_id, path) if locked_by_online_office: # refresh lock file try: seafile_api.refresh_file_lock(repo_id, path) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
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)
def get(self, request, repo_id): """ get info of a single file/folder in a library """ repo = seafile_api.get_repo(repo_id) path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = normalize_file_path(path) try: dirent = seafile_api.get_dirent_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not dirent: error_msg = 'File or folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if stat.S_ISDIR(dirent.mode): is_file = False else: is_file = True username = request.user.username if is_file and request.GET.get('dl', '0') == '1': token = seafile_api.get_fileserver_access_token( repo_id, dirent.obj_id, 'download', username, use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY) if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dl_url = gen_file_get_url(token, dirent.obj_name) send_file_access_msg(request, repo, path, 'web') return Response({'download_url': dl_url}) dirent_info = get_dirent_info(dirent) return Response(dirent_info)
def is_file_starred(email, repo_id, path, org_id=-1): # Should use "get", but here we use "filter" to fix the bug caused by no # unique constraint in the table path_list = [normalize_file_path(path), normalize_dir_path(path)] result = UserStarredFiles.objects.filter(email=email, repo_id=repo_id).filter(Q(path__in=path_list)) n = len(result) if n == 0: return False else: # Fix the bug caused by no unique constraint in the table if n > 1: for r in result[1:]: r.delete() return True
def delete(self, request): """ Unstar a file/folder. Permission checking: 1. all authenticated user can perform this action. 2. r/rw permission """ # argument check repo_id = request.GET.get('repo_id', None) if not 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) # handler path if item exist if seafile_api.get_dir_id_by_path(repo_id, path): path = normalize_dir_path(path) elif seafile_api.get_file_id_by_path(repo_id, path): path = normalize_file_path(path) email = request.user.username # database record check if not UserStarredFiles.objects.get_starred_item(email, repo_id, path): error_msg = 'Item %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # unstar a item try: UserStarredFiles.objects.delete_starred_item(email, repo_id, 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({'success': True})
def get_file_tag_by_path(self, repo_id, file_path): file_path = normalize_file_path(file_path) filename = os.path.basename(file_path) parent_path = os.path.dirname(file_path) file_uuid = FileUUIDMap.objects.get_fileuuidmap_by_path( repo_id, parent_path, filename, is_dir=False) file_tag_list = super(FileTagsManager, self).filter( file_uuid=file_uuid).select_related('repo_tag') file_tags = list() for file_tag in file_tag_list: tag_dict = dict() tag_dict['file_tag_id'] = file_tag.pk tag_dict['repo_tag_id'] = file_tag.repo_tag.pk tag_dict['tag_name'] = file_tag.repo_tag.name tag_dict['tag_color'] = file_tag.repo_tag.color file_tags.append(tag_dict) return file_tags
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.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
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
def put(self, request, repo_id, format=None): """ Currently only support lock, unlock, refresh-lock file. 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) path = normalize_file_path(path) operation = request.data.get('operation', None) if not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('lock', 'unlock', 'refresh-lock'): error_msg = "operation can only be 'lock', 'unlock' or 'refresh-lock'." 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) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) username = request.user.username 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) # check if is locked by online office locked_by_online_office = if_locked_by_online_office(repo_id, path) if operation == 'lock': if is_locked: error_msg = _("File is locked") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # lock file expire = request.data.get('expire', FILE_LOCK_EXPIRATION_DAYS) try: seafile_api.lock_file(repo_id, path, username, expire) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def create_file_link(self, username, repo_id, path): path = normalize_file_path(path) return self._add_file_share(username, repo_id, path, 'f')
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) result = {} result['smart_link'] = smart_link result['smart_link_token'] = dirent_uuid result['name'] = dirent_name return Response(result)
def get_file_link_by_path(self, username, repo_id, path): path = normalize_file_path(path) return self._get_file_share_by_path(username, repo_id, path)
def get(self, request): """ Return file info. """ # argument check doc_id = request.GET.get('doc_id', '') if not doc_id: error_msg = 'doc_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_info = cache.get('BISHENG_OFFICE_' + doc_id) if not file_info: error_msg = 'doc_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) username = file_info.get('username') if not username: error_msg = 'username invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) repo_id = file_info.get('repo_id') if not repo_id: error_msg = 'repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_path = file_info.get('file_path') if not file_path: error_msg = 'file_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) file_path = normalize_file_path(file_path) # resource check try: User.objects.get(email=username) except User.DoesNotExist: error_msg = 'User %s not found.' % username return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not seafile_api.get_repo(repo_id): error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not seafile_api.get_file_id_by_path(repo_id, file_path): error_msg = 'File %s not found.' % file_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check parent_dir = os.path.dirname(file_path) permission = seafile_api.check_permission_by_path(repo_id, parent_dir, username) if not permission: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # get file basic info file_name = os.path.basename(file_path.rstrip('/')) filetype, fileext = get_file_type_and_ext(file_name) # get file raw url file_id = seafile_api.get_file_id_by_path(repo_id, file_path) download_token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'download', username, use_onetime=True) raw_url = gen_file_get_url(download_token, file_name) # get avatar url url, _, _ = api_avatar_url(username, int(72)) # prepare file permission privilege = copy.deepcopy(BISHENG_OFFICE_PRIVILEGE) can_edit = file_info.get('can_edit', False) if not can_edit: privilege.remove('FILE_WRITE') # prepare response file_info = { 'doc': { 'docId': doc_id, 'title': file_name, 'mime_type': BISHENG_OFFICE_MIME_TYPE[fileext], 'fetchUrl': raw_url, 'thumbnail': "", 'fromApi': True }, 'user': { 'uid': username, 'oid': username, 'nickName': email2nickname(username), 'avatar': request.build_absolute_uri(url), 'privilege': privilege }, } return Response(file_info)
def view_priv_shared_file(request, token): """View private shared file. """ try: pfs = PrivateFileDirShare.objects.get_priv_file_dir_share_by_token(token) except PrivateFileDirShare.DoesNotExist: raise Http404 repo_id = pfs.repo_id repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username if username != pfs.from_user and username != pfs.to_user: raise Http404 # permission check path = normalize_file_path(pfs.path) obj_id = seafile_api.get_file_id_by_path(repo.id, path) if not obj_id: raise Http404 filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafile_api.get_fileserver_access_token(repo.id, obj_id, 'view', username) raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} fsize = get_file_size(repo.store_id, repo.version, obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: ret_dict['err'] = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) accessible_repos = get_unencry_rw_repos_by_user(request) save_to_link = reverse('save_private_file_share', args=[pfs.token]) return render_to_response('shared_file_view.html', { 'repo': repo, 'obj_id': obj_id, 'path': path, 'file_name': filename, 'file_size': fsize, 'access_token': access_token, 'fileext': fileext, 'raw_path': raw_path, 'shared_by': pfs.from_user, 'err': ret_dict['err'], 'file_content': ret_dict['file_content'], 'encoding': ret_dict['encoding'], 'file_encoding_list':ret_dict['file_encoding_list'], 'html_exists': ret_dict['html_exists'], 'html_detail': ret_dict.get('html_detail', {}), 'filetype': ret_dict['filetype'], 'use_pdfjs':USE_PDFJS, 'accessible_repos': accessible_repos, 'save_to_link': save_to_link, }, context_instance=RequestContext(request))
def post(self, request, repo_id, format=None): """ Create, rename, move, copy, revert file Permission checking: 1. create: user with 'rw' permission for current parent dir; 2. rename: user with 'rw' permission for current file; 3. move : user with 'rw' permission for current file, 'rw' permission for dst parent dir; 4. copy : user with 'r' permission for current file, 'rw' permission for dst parent dir; 4. revert: user with 'rw' permission for current file's parent dir; """ # argument check path = request.GET.get('p', None) if not path: error_msg = 'p invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = normalize_file_path(path) operation = request.data.get('operation', None) if not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) operation = operation.lower() if operation not in ('create', 'rename', 'move', 'copy', 'revert'): error_msg = "operation can only be 'create', 'rename', 'move', 'copy' or 'revert'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) username = request.user.username parent_dir = os.path.dirname(path) is_draft = request.POST.get('is_draft', '') if operation == 'create': # resource check try: parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not parent_dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if check_folder_permission(request, repo_id, parent_dir) != PERMISSION_READ_WRITE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if is_draft.lower() == 'true': file_name = os.path.basename(path) file_dir = os.path.dirname(path) draft_type = os.path.splitext(file_name)[0][-7:] file_type = os.path.splitext(file_name)[-1] if draft_type != '(draft)': f = os.path.splitext(file_name)[0] path = file_dir + '/' + f + '(draft)' + file_type # create new empty file new_file_name = os.path.basename(path) if not is_valid_dirent_name(new_file_name): return api_error(status.HTTP_400_BAD_REQUEST, 'name invalid.') new_file_name = check_filename_with_rename(repo_id, parent_dir, new_file_name) try: seafile_api.post_empty_file(repo_id, parent_dir, new_file_name, username) except SearpcError, e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if is_draft.lower() == 'true': Draft.objects.add(username, repo, path, file_exist=False) # update office file by template if new_file_name.endswith('.xlsx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.xlsx') elif new_file_name.endswith('.pptx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.pptx') elif new_file_name.endswith('.docx'): empty_file_path = os.path.join(OFFICE_TEMPLATE_ROOT, 'empty.docx') else: empty_file_path = '' if empty_file_path: # get file server update url update_token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'update', username) if not update_token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) update_url = gen_inner_file_upload_url('update-api', update_token) # update file new_file_path = posixpath.join(parent_dir, new_file_name) try: requests.post( update_url, data={'filename': new_file_name, 'target_file': new_file_path}, files={'file': open(empty_file_path, 'rb')} ) except Exception as e: logger.error(e) new_file_path = posixpath.join(parent_dir, new_file_name) file_info = self.get_file_info(username, repo_id, new_file_path) return Response(file_info)