def generate_thumbnail(request, repo_id, size, path): """ generate and save thumbnail if not exist before generate thumbnail, you should check: 1. if repo exist: should exist; 2. if repo is encrypted: not encrypted; 3. if ENABLE_THUMBNAIL: enabled; """ try: size = int(size) except ValueError as e: logger.error(e) return (False, 400) thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size)) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) file_id = get_file_id_by_path(repo_id, path) if not file_id: return (False, 400) thumbnail_file = os.path.join(thumbnail_dir, file_id) if os.path.exists(thumbnail_file): return (True, 200) repo = get_repo(repo_id) file_size = get_file_size(repo.store_id, repo.version, file_id) if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: return (False, 403) token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view', '', use_onetime=True) inner_path = gen_inner_file_get_url(token, os.path.basename(path)) try: image_file = urllib2.urlopen(inner_path) f = StringIO(image_file.read()) image = Image.open(f) # check image memory cost size limit # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask) # every pixel will cost 4 byte in RGBA mode width, height = image.size image_memory_cost = width * height * 4 / 1024 / 1024 if image_memory_cost > THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT: return (False, 403) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") image.thumbnail((size, size), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) return (True, 200) except Exception as e: logger.error(e) return (False, 500)
def create_video_thumbnails(repo, file_id, path, size, thumbnail_file, file_size): t1 = timeit.default_timer() token = seafile_api.get_fileserver_access_token(repo.id, file_id, 'view', '', use_onetime=False) if not token: return (False, 500) inner_path = gen_inner_file_get_url(token, os.path.basename(path)) clip = VideoFileClip(inner_path) tmp_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id[:8])) clip.save_frame(tmp_path, t=THUMBNAIL_VIDEO_FRAME_TIME) t2 = timeit.default_timer() logger.debug('Create thumbnail of [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1))) try: ret = _create_thumbnail_common(tmp_path, thumbnail_file, size) os.unlink(tmp_path) return ret except Exception as e: logger.error(e) os.unlink(tmp_path) return (False, 500)
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)
def generate_thumbnail(request, repo_id, size, path): """ generate and save thumbnail if not exist before generate thumbnail, you should check: 1. if repo exist: should exist; 2. if repo is encrypted: not encrypted; 3. if ENABLE_THUMBNAIL: enabled; """ try: size = int(size) except ValueError as e: logger.error(e) return (False, 400) thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size)) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) file_id = get_file_id_by_path(repo_id, path) if not file_id: return (False, 400) thumbnail_file = os.path.join(thumbnail_dir, file_id) if os.path.exists(thumbnail_file): return (True, 200) repo = get_repo(repo_id) file_size = get_file_size(repo.store_id, repo.version, file_id) filetype, fileext = get_file_type_and_ext(os.path.basename(path)) if filetype == VIDEO: # video thumbnails if ENABLE_VIDEO_THUMBNAIL: return create_video_thumbnails(repo, file_id, path, size, thumbnail_file, file_size) else: return (False, 400) # image thumbnails if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: return (False, 403) token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view', '', use_onetime=True) if not token: return (False, 500) inner_path = gen_inner_file_get_url(token, os.path.basename(path)) try: image_file = urllib2.urlopen(inner_path) f = StringIO(image_file.read()) return _create_thumbnail_common(f, thumbnail_file, size) except Exception as e: logger.error(e) return (False, 500)
def get(self, request, file_id, format=None): """ WOPI endpoint for get file content """ token = request.GET.get('access_token', None) request_user, repo_id, file_path = get_file_info_by_token(token=token) obj_id = seafile_api.get_file_id_by_path(repo_id, file_path) file_name = os.path.basename(file_path) try: fileserver_token = seafile_api.get_fileserver_access_token( repo_id, obj_id, 'view', '', use_onetime=False) except SearpcError as e: logger.error(e) return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) inner_path = gen_inner_file_get_url(fileserver_token, file_name) try: file_content = urllib2.urlopen(inner_path).read() except urllib2.URLError as e: logger.error(e) return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) return HttpResponse(file_content, content_type="application/octet-stream")
def generate_thumbnail(request, repo_id, size, path): """ generate and save thumbnail if not exist """ thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size)) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) file_id = get_file_id_by_path(repo_id, path) thumbnail_file = os.path.join(thumbnail_dir, file_id) if os.path.exists(thumbnail_file): return True token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view', '', use_onetime = False) inner_path = gen_inner_file_get_url(token, os.path.basename(path)) try: image_file = urllib2.urlopen(inner_path) f = StringIO(image_file.read()) image = Image.open(f) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") image.thumbnail((size, size), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) return True except Exception as e: logger.error(e) return False
def post(self, request, file_id, format=None): token = request.GET.get('access_token', None) request_user, repo_id, file_path = get_file_info_by_token(token=token) try: file_obj = request.read() # get file update url token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'update', request_user) update_url = gen_file_upload_url(token, 'update-api') # update file files = { 'file': file_obj, 'file_name': os.path.basename(file_path), 'target_file': file_path, } requests.post(update_url, files=files) except Exception as e: logger.error(e) return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) return HttpResponse(json.dumps({}), status=200, content_type=json_content_type)
def get(self, request, workspace_id): """get table file upload link """ # argument check table_name = request.GET.get('name', None) if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if username != owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'upload', '', use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) upload_link = gen_file_upload_url(token, 'upload-api') # create asset dir asset_dir_path = '/asset/' + str(dtable.uuid) asset_dir_id = seafile_api.get_dir_id_by_path(repo_id, asset_dir_path) if not asset_dir_id: seafile_api.mkdir_with_parents(repo_id, '/', asset_dir_path[1:], owner) dtable.modifier = username dtable.save() res = dict() res['upload_link'] = upload_link res['parent_path'] = asset_dir_path return Response(res)
def get_upload_url(request, repo_id): username = request.user.username if check_repo_access_permission(repo_id, request.user) == "rw": token = seafile_api.get_fileserver_access_token(repo_id, "dummy", "upload", username) return gen_file_upload_url(token, "upload") else: return ""
def get_file_view_path_and_perm( request, repo_id, obj_id, path, use_onetime=settings.FILESERVER_TOKEN_ONCE_ONLY): """ Get path and the permission to view file. Returns: outer fileserver file url, inner fileserver file url, permission """ username = request.user.username filename = os.path.basename(path) user_perm = check_folder_permission(request, repo_id, '/') if user_perm is None: return ('', '', user_perm) else: # Get a token to visit file token = seafile_api.get_fileserver_access_token( repo_id, obj_id, 'view', username, use_onetime=use_onetime) if not token: return ('', '', None) outer_url = gen_file_get_url(token, filename) inner_url = gen_inner_file_get_url(token, filename) return (outer_url, inner_url, user_perm)
def download_enc_file(request, repo_id, file_id): content_type = 'application/json; charset=utf-8' result = {} op = 'downloadblks' blklist = [] if file_id == EMPTY_SHA1: result = { 'blklist':blklist, 'url':None, } return HttpResponse(json.dumps(result), content_type=content_type) try: blks = seafile_api.list_blocks_by_file_id(repo_id, file_id) except SearpcError as e: logger.error(e) result['error'] = _(u'Failed to get file block list') return HttpResponse(json.dumps(result), content_type=content_type) blklist = blks.split('\n') blklist = [i for i in blklist if len(i) == 40] token = seafile_api.get_fileserver_access_token(repo_id, file_id, op, request.user.username) url = gen_block_get_url(token, None) result = { 'blklist':blklist, 'url':url, } return HttpResponse(json.dumps(result), content_type=content_type)
def extract_xmind_image(repo_id, path, size=XMIND_IMAGE_SIZE): # get inner path file_name = os.path.basename(path) file_id = seafile_api.get_file_id_by_path(repo_id, path) fileserver_token = seafile_api.get_fileserver_access_token( repo_id, file_id, 'view', '') inner_path = gen_inner_file_get_url(fileserver_token, file_name) # extract xmind image xmind_file = urllib.request.urlopen(inner_path) xmind_file_str = BytesIO(xmind_file.read()) xmind_zip_file = zipfile.ZipFile(xmind_file_str, 'r') extracted_xmind_image = xmind_zip_file.read('Thumbnails/thumbnail.png') extracted_xmind_image_str = BytesIO(extracted_xmind_image) # save origin xmind image to thumbnail folder thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size)) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) local_xmind_image = os.path.join(thumbnail_dir, file_id) try: ret = _create_thumbnail_common(extracted_xmind_image_str, local_xmind_image, size) return ret except Exception as e: logger.error(e) return (False, 500)
def download_files_to_path(username, repo_id, dtable_uuid, files, path, files_map=None): """ download dtable's asset files to path """ valid_file_obj_ids = [] base_path = os.path.join('/asset', dtable_uuid) for file in files: full_path = os.path.join(base_path, *file.split('/')) obj_id = seafile_api.get_file_id_by_path(repo_id, full_path) if not obj_id: continue valid_file_obj_ids.append((file, obj_id)) tmp_file_list = [] for file, obj_id in valid_file_obj_ids: token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'download', username, use_onetime=False) file_name = os.path.basename(file) if files_map and files_map.get(file, None): file_name = files_map.get(file) file_url = gen_inner_file_get_url(token, file_name) content = requests.get(file_url).content filename_by_path = os.path.join(path, file_name) with open(filename_by_path, 'wb') as f: f.write(content) tmp_file_list.append(filename_by_path) return tmp_file_list
def prepare_dtable_json(repo_id, dtable_uuid, table_name, dtable_file_dir_id): """ used in export dtable create dtable json file at /tmp/dtable-io/<dtable_uuid>/dtable_asset/content.json, so that we can zip /tmp/dtable-io/<dtable_uuid>/dtable_asset :param repo_id: repo of this dtable :param table_name: name of dtable :param dtable_file_dir_id: xxx.dtable's file dir id :return: file stream """ try: token = seafile_api.get_fileserver_access_token(repo_id, dtable_file_dir_id, 'download', '', use_onetime=False) except Exception as e: raise e json_url = gen_inner_file_get_url(token, table_name + '.dtable') content_json = requests.get(json_url).content if content_json: dtable_content = convert_dtable_export_file_and_image_url( json.loads(content_json)) else: dtable_content = '' content_json = json.dumps(dtable_content).encode('utf-8') path = os.path.join('/tmp/dtable-io', dtable_uuid, 'dtable_asset', 'content.json') with open(path, 'wb') as f: f.write(content_json)
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
def get(self, request, token): # resource check form_obj = DTableForms.objects.get_form_by_token(token) if not form_obj: error_msg = 'Form %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) workspace_id = form_obj.workspace_id workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id dtable_uuid = form_obj.dtable_uuid dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid) if not dtable: error_msg = 'Table %s not found.' % dtable_uuid return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check if not check_form_submit_permission(request, form_obj): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not check_user_workspace_quota(workspace): error_msg = 'Asset quota exceeded.' return api_error(HTTP_443_ABOVE_QUOTA, error_msg) # create asset dir asset_dir_path = '/asset/' + str(dtable.uuid) asset_dir_id = seafile_api.get_dir_id_by_path(repo_id, asset_dir_path) if not asset_dir_id: seafile_api.mkdir_with_parents(repo_id, '/', asset_dir_path[1:], '') # get token obj_id = json.dumps({'parent_dir': asset_dir_path}) try: token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'upload', '', use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) upload_link = gen_file_upload_url(token, 'upload-api') res = dict() res['upload_link'] = upload_link res['parent_path'] = asset_dir_path res['img_relative_path'] = FORM_UPLOAD_IMG_RELATIVE_PATH res['file_relative_path'] = os.path.join(UPLOAD_FILE_RELATIVE_PATH, str(datetime.today())[:7]) return Response(res)
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
def generate_thumbnail(request, repo_id, size, path): """ generate and save thumbnail if not exist before generate thumbnail, you should check: 1. if repo exist: should exist; 2. if repo is encrypted: not encrypted; 3. if ENABLE_THUMBNAIL: enabled; """ try: size = int(size) except ValueError as e: logger.error(e) return (False, 400) thumbnail_dir = os.path.join(THUMBNAIL_ROOT, str(size)) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) file_id = get_file_id_by_path(repo_id, path) if not file_id: return (False, 400) thumbnail_file = os.path.join(thumbnail_dir, file_id) if os.path.exists(thumbnail_file): return (True, 200) repo = get_repo(repo_id) file_size = get_file_size(repo.store_id, repo.version, file_id) if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: return (False, 403) token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view', '', use_onetime = True) inner_path = gen_inner_file_get_url(token, os.path.basename(path)) try: image_file = urllib2.urlopen(inner_path) f = StringIO(image_file.read()) image = Image.open(f) # check image memory cost size limit # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask) # every pixel will cost 4 byte in RGBA mode width, height = image.size image_memory_cost = width * height * 4 / 1024 / 1024 if image_memory_cost > THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT: return (False, 403) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") image = get_rotated_image(image) image.thumbnail((size, size), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) return (True, 200) except Exception as e: logger.error(e) return (False, 500)
def get_upload_url(request, repo_id): username = request.user.username if check_repo_access_permission(repo_id, request.user) == 'rw': token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'upload', username) return gen_file_upload_url(token, 'upload') else: return ''
def get_upload_url(request, repo_id): username = request.user.username if check_folder_permission(request, repo_id, '/') == 'rw': token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'upload', username) return gen_file_upload_url(token, 'upload') else: return ''
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 view_shared_upload_link(request, token): assert token is not None # Checked by URLconf uploadlink = UploadLinkShare.objects.get_valid_upload_link_by_token(token) if uploadlink is None: raise Http404 if uploadlink.is_encrypted(): if not check_share_link_access(request.user.username, token): d = {"token": token, "view_name": "view_shared_upload_link"} if request.method == "POST": post_values = request.POST.copy() post_values["enc_password"] = uploadlink.password form = SharedLinkPasswordForm(post_values) d["form"] = form if form.is_valid(): # set cache for non-anonymous user if request.user.is_authenticated(): set_share_link_access(request.user.username, token) else: return render_to_response( "share_access_validation.html", d, context_instance=RequestContext(request) ) else: return render_to_response("share_access_validation.html", d, context_instance=RequestContext(request)) username = uploadlink.username repo_id = uploadlink.repo_id path = uploadlink.path dir_name = os.path.basename(path[:-1]) repo = get_repo(repo_id) if not repo: raise Http404 uploadlink.view_cnt = F("view_cnt") + 1 uploadlink.save() no_quota = True if seaserv.check_quota(repo_id) < 0 else False token = seafile_api.get_fileserver_access_token(repo_id, "dummy", "upload", request.user.username) ajax_upload_url = gen_file_upload_url(token, "upload-aj") return render_to_response( "view_shared_upload_link.html", { "repo": repo, "token": token, "path": path, "username": username, "dir_name": dir_name, "max_upload_file_size": seaserv.MAX_UPLOAD_FILE_SIZE, "no_quota": no_quota, "ajax_upload_url": ajax_upload_url, "uploadlink": uploadlink, }, context_instance=RequestContext(request), )
def get(self, request, repo_id): """ get info of a single file/folder in a library """ repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not can_view_sys_admin_repo(repo): error_msg = 'Feature disabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path[0] != '/': path = '/' + path try: dirent = seafile_api.get_dirent_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not dirent: error_msg = 'file/folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if stat.S_ISDIR(dirent.mode): is_file = False else: is_file = True username = request.user.username if is_file and request.GET.get('dl', '0') == '1': token = seafile_api.get_fileserver_access_token(repo_id, dirent.obj_id, 'download', username, use_onetime=True) if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dl_url = gen_file_get_url(token, dirent.obj_name) send_file_access_msg(request, repo, path, 'web') return Response({'download_url': dl_url}) dirent_info = get_dirent_info(dirent) return Response(dirent_info)
def dtable_external_link_plugin_asset_view(request, token, workspace_id, name, plugin_id, path): """ used in external page """ dtable_external_link = DTableExternalLinks.objects.filter( token=token).first() if not dtable_external_link: raise Http404 try: plugin_record = DTablePlugins.objects.get(pk=plugin_id) except DTablePlugins.DoesNotExist: error_msg = 'Plugin %s not found.' % plugin_id return render_error(request, error_msg) workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return render_error(request, error_msg) table_name = name dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'DTable %s not found.' % table_name return render_error(request, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return render_error(request, error_msg) plugin_file_path = os.path.join('/asset', str(dtable.uuid), 'plugins', plugin_record.name) asset_path = os.path.join(plugin_file_path, path) plugin_file_dir_id = seafile_api.get_file_id_by_path(repo_id, asset_path) if not plugin_file_dir_id: return render_error(request, 'Asset file does not exist.') token = seafile_api.get_fileserver_access_token(workspace.repo_id, plugin_file_dir_id, 'view', '', use_onetime=False) url = gen_file_get_url(token, asset_path) import requests r = requests.get(url) response = HttpResponse(r.content) content_type = mimetypes.guess_type(path) if type: response['Content-Type'] = content_type[0] return response
def repo_download_dir(request, repo_id): repo = get_repo(repo_id) if not repo: return render_error(request, _('Library does not exist')) path = request.GET.get('p', '/') if path[-1] != '/': # Normalize dir path path += '/' if not seafile_api.get_dir_id_by_path(repo.id, path): return render_error(request, _('"%s" does not exist.') % path) if len(path) > 1: dirname = os.path.basename(path.rstrip('/')) # Here use `rstrip` to cut out last '/' in path else: dirname = repo.name allow_download = parse_repo_perm(check_folder_permission( request, repo_id, '/')).can_download if allow_download: dir_id = seafile_api.get_dir_id_by_commit_and_path(repo.id, repo.head_cmmt_id, path) try: total_size = seafile_api.get_dir_size(repo.store_id, repo.version, dir_id) except Exception as e: logger.error(str(e)) return render_error(request, _('Internal Server Error')) if total_size > MAX_DOWNLOAD_DIR_SIZE: return render_error(request, _('Unable to download directory "%s": size is too large.') % dirname) is_windows = 0 if is_windows_operating_system(request): is_windows = 1 fake_obj_id = { 'obj_id': dir_id, 'dir_name': dirname, 'is_windows': is_windows } token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'download-dir', request.user.username) if not token: return render_error(request, _('Internal Server Error')) else: return render_error(request, _('Unable to download "%s"') % dirname ) url = gen_file_get_url(token, dirname) from seahub.views.file import send_file_access_msg send_file_access_msg(request, repo, path, 'web') return redirect(url)
def post(self, request): """ Save file. """ # 在默认情况下,所有的编辑参与者退出编辑5分钟之后,毕升Office会触发回存逻辑; # 或者在所以用户退出编辑之后,如果有用户再打开预览,也会触发回存。 # {u'action': u'saveBack', # u'data': {u'changesUrl': u'2bd816895cb7a72dffa4810d2ba5c474/changes.zip', # u'delta': 10, # u'docId': u'2bd816895cb7a72dffa4810d2ba5c474', # u'docURL': u'/s3/draft/...', # u'modifyBy': [{u'avatar': u'http://192.168.1.113:8000/media/avatars/default.png', # u'nickName': u'lian', # u'oid': u'*****@*****.**', # u'privilege': None, # u'uid': u'*****@*****.**'}], # u'unchanged': False}, # u'docId': u'2bd816895cb7a72dffa4810d2ba5c474'} post_data = json.loads(request.body) # check action from bisheng server action = post_data.get('action') if action != 'saveBack': return Response() # ger file basic info doc_id = post_data.get('docId') file_info = cache.get('BISHENG_OFFICE_' + doc_id) username = file_info.get('username') repo_id = file_info.get('repo_id') file_path = file_info.get('file_path') # get content of new editted file data = post_data.get('data') file_url = urllib.parse.urljoin(BISHENG_OFFICE_HOST_DOMAIN, data.get('docURL')) files = { 'file': requests.get(file_url).content, 'file_name': os.path.basename(file_path), 'target_file': file_path, } # prepare update token for seafhttp fake_obj_id = { 'online_office_update': True, } update_token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'update', username) # update file update_url = gen_inner_file_upload_url('update-api', update_token) requests.post(update_url, files=files) return Response()
def get(self, request, repo_id, format=None): repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # argument checking parent_dir = request.GET.get('parent_dir', None) dirent_name_string = request.GET.get('dirents', None) if not parent_dir: error_msg = 'parent_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dirent_name_string: error_msg = 'dirents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # folder exist checking if not seafile_api.get_dir_id_by_path(repo_id, parent_dir): error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission checking if check_folder_permission(request, repo_id, parent_dir) is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) dirent_name_list = string2list(dirent_name_string) dirent_list = [] for dirent_name in dirent_name_list: dirent_list.append(dirent_name.strip('/')) fake_obj_id = {} fake_obj_id['file_list'] = dirent_list fake_obj_id['parent_dir'] = parent_dir username = request.user.username try: token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'download-multi', username, False) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if len(dirent_list) > 10: send_file_access_msg(request, repo, parent_dir, 'web') else: for dirent_name in dirent_list: full_dirent_path = posixpath.join(parent_dir, dirent_name) send_file_access_msg(request, repo, full_dirent_path, 'web') download_url = '%s/files/%s' % (get_fileserver_root(), token) return Response({'url': download_url})
def view_shared_upload_link(request, token): assert token is not None # Checked by URLconf uploadlink = UploadLinkShare.objects.get_valid_upload_link_by_token(token) if uploadlink is None: raise Http404 if uploadlink.is_encrypted(): if not check_share_link_access(request.user.username, token): d = {'token': token, 'view_name': 'view_shared_upload_link', } if request.method == 'POST': post_values = request.POST.copy() post_values['enc_password'] = uploadlink.password form = SharedLinkPasswordForm(post_values) d['form'] = form if form.is_valid(): # set cache for non-anonymous user if request.user.is_authenticated(): set_share_link_access(request.user.username, token) else: return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) else: return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) username = uploadlink.username repo_id = uploadlink.repo_id path = uploadlink.path dir_name = os.path.basename(path[:-1]) repo = get_repo(repo_id) if not repo: raise Http404 uploadlink.view_cnt = F('view_cnt') + 1 uploadlink.save() no_quota = True if seaserv.check_quota(repo_id) < 0 else False token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'upload', request.user.username) ajax_upload_url = gen_file_upload_url(token, 'upload-aj') return render_to_response('view_shared_upload_link.html', { 'repo': repo, 'token': token, 'path': path, 'username': username, 'dir_name': dir_name, 'max_upload_file_size': seaserv.MAX_UPLOAD_FILE_SIZE, 'no_quota': no_quota, 'ajax_upload_url': ajax_upload_url, 'uploadlink': uploadlink, 'enable_upload_folder': ENABLE_UPLOAD_FOLDER, }, context_instance=RequestContext(request))
def get(self, request, workspace_id): """get table file update link """ # argument check table_name = request.GET.get('name', None) if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if not is_group_member(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if username != owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'update', username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dtable.modifier = username dtable.save() url = gen_file_upload_url(token, 'update-api') return Response(url)
def get(self, request): """get table file update link Permission: 1. use dtable_uuid verify jwt from dtable-server """ # argument check dtable_uuid = request.GET.get('dtable_uuid', None) if not dtable_uuid: error_msg = 'dtable_uuid invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check auth = request.META.get('HTTP_AUTHORIZATION', '').split() if not is_valid_jwt(auth, dtable_uuid): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # resource check dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid) if not dtable: error_msg = 'dtable %s not found.' % dtable_uuid return api_error(status.HTTP_404_NOT_FOUND, error_msg) workspace = Workspaces.objects.get_workspace_by_id(dtable.workspace.id) if not workspace: error_msg = 'Workspace not found.' return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) username = request.user.username # get token obj_id = json.dumps({'parent_dir': '/'}) try: token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'upload', username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) update_link = '%s/%s/%s' % (get_fileserver_root(), 'upload-api', token) res = dict() res['update_link'] = update_link res['file_name'] = dtable.name + FILE_TYPE return Response(res)
def view_shared_upload_link(request, token): assert token is not None # Checked by URLconf uploadlink = UploadLinkShare.objects.get_valid_upload_link_by_token(token) if uploadlink is None: raise Http404 if uploadlink.is_encrypted(): if not check_share_link_access(request.user.username, token): d = {'token': token, 'view_name': 'view_shared_upload_link', } if request.method == 'POST': post_values = request.POST.copy() post_values['enc_password'] = uploadlink.password form = SharedLinkPasswordForm(post_values) d['form'] = form if form.is_valid(): # set cache for non-anonymous user if request.user.is_authenticated(): set_share_link_access(request.user.username, token) else: return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) else: return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) username = uploadlink.username repo_id = uploadlink.repo_id path = uploadlink.path dir_name = os.path.basename(path[:-1]) repo = get_repo(repo_id) if not repo: raise Http404 uploadlink.view_cnt = F('view_cnt') + 1 uploadlink.save() no_quota = True if seaserv.check_quota(repo_id) < 0 else False token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'upload', request.user.username) ajax_upload_url = gen_file_upload_url(token, 'upload-aj') return render_to_response('view_shared_upload_link.html', { 'repo': repo, 'token': token, 'path': path, 'username': username, 'dir_name': dir_name, 'max_upload_file_size': seaserv.MAX_UPLOAD_FILE_SIZE, 'no_quota': no_quota, 'ajax_upload_url': ajax_upload_url, 'uploadlink': uploadlink, }, context_instance=RequestContext(request))
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 post(self, request): """ Save file. """ # 在默认情况下,所有的编辑参与者退出编辑5分钟之后,毕升Office会触发回存逻辑; # 或者在所以用户退出编辑之后,如果有用户再打开预览,也会触发回存。 # {u'action': u'saveBack', # u'data': {u'changesUrl': u'2bd816895cb7a72dffa4810d2ba5c474/changes.zip', # u'delta': 10, # u'docId': u'2bd816895cb7a72dffa4810d2ba5c474', # u'docURL': u'/s3/draft/...', # u'modifyBy': [{u'avatar': u'http://192.168.1.113:8000/media/avatars/default.png', # u'nickName': u'lian', # u'oid': u'*****@*****.**', # u'privilege': None, # u'uid': u'*****@*****.**'}], # u'unchanged': False}, # u'docId': u'2bd816895cb7a72dffa4810d2ba5c474'} post_data = json.loads(request.body) # check action from bisheng server action = post_data.get('action') if action != 'saveBack': return Response() # ger file basic info doc_id = post_data.get('docId') file_info = cache.get('BISHENG_OFFICE_' + doc_id) username = file_info.get('username') repo_id = file_info.get('repo_id') file_path = file_info.get('file_path') # get content of new editted file data = post_data.get('data') file_url = urlparse.urljoin(BISHENG_OFFICE_HOST_DOMAIN, data.get('docURL')) files = { 'file': requests.get(file_url).content, 'file_name': os.path.basename(file_path), 'target_file': file_path, } # prepare update token for seafhttp fake_obj_id = {'online_office_update': True,} update_token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'update', username) # update file update_url = gen_inner_file_upload_url('update-api', update_token) requests.post(update_url, files=files) return Response()
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 get_inner_path(repo_id, file_id, file_name): token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view', '', use_onetime=True) if not token: raise ValueError(404, 'token not found.') inner_path = '%s/files/%s/%s' % (settings.INNER_FILE_SERVER_ROOT.rstrip( '/'), token, urllib.parse.quote(file_name)) return inner_path
def onlyoffice_editor_callback(request): #request.body: # {"key":"Khirz6zTPdfd7","status":1, # "users":["uid-1488351242769"], # "actions":[{"type":1,"userid":"uid-1488351242769"}]} # "key":"Khirz6zTPdfd8","status":2,"url":"https://13.113.111.2/cache/files/Khirz6zTPdfd8_6379/output.docx/output.docx?md5=5oL0qGUqXw72D85f28JaFg==&expires=1488956681&disposition=attachment&ooname=output.docx","changesurl":"https://13.113.111.2/cache/files/Khirz6zTPdfd8_6379/changes.zip/changes.zip?md5=vx3VYwaPEOxtZDA_3yuVrg==&expires=1488956681&disposition=attachment&ooname=output.zip","history":{"serverVersion":"4.2.10","changes":[{"created":"2017-03-01 07:03:11","user":{"id":"uid-1488351774447","name":"Anonymous"}}]},"users":["uid-1488351774447"],"actions":[{"type":0,"userid":"uid-1488351774447"}]} logger.debug(request.body) if request.method != 'POST': return HttpResponse('{"error": 0}') post_data = json.loads(request.body) status = int(post_data.get('status', -1)) if status == 2: # document is ready for saving # the link to the edited document to be saved with the document storage # service. The link is present when the status value is equal to 2 or 3 only. url = post_data.get('url') context = None if VERIFY_ONLYOFFICE_CERTIFICATE is False: import ssl context = ssl._create_unverified_context() try: file_content = urllib2.urlopen(url, context=context).read() except urllib2.URLError as e: logger.error(e) else: # update file doc_key = post_data.get('key') doc_info = json.loads(cache.get("ONLYOFFICE_%s" % doc_key)) repo_id = doc_info['repo_id'] file_path = doc_info['file_path'] username = doc_info['username'] update_token = seafile_api.get_fileserver_access_token( repo_id, 'dummy', 'update', username) if not update_token: return HttpResponse('{"error": 0}') update_url = gen_inner_file_upload_url('update-api', update_token) files = { 'file': file_content, 'file_name': os.path.basename(file_path), 'target_file': file_path, } requests.post(update_url, files=files) logger.info('%s updated by %s' % (repo_id + file_path, username)) return HttpResponse('{"error": 0}')
def get(self, request): """get table file download link Permission: 1. use dtable_uuid verify jwt from dtable-server """ # argument check dtable_uuid = request.GET.get('dtable_uuid', None) if not dtable_uuid: error_msg = 'dtable_uuid invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check auth = request.META.get('HTTP_AUTHORIZATION', '').split() if not is_valid_jwt(auth, dtable_uuid): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # resource check dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid) if not dtable: error_msg = 'dtable %s not found.' % dtable_uuid return api_error(status.HTTP_404_NOT_FOUND, error_msg) table_name = dtable.name workspace = Workspaces.objects.get_workspace_by_id(dtable.workspace.id) if not workspace: error_msg = 'Workspace not found.' return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) username = request.user.username table_file_name = table_name + FILE_TYPE try: file_path = '/' + table_file_name file_id = seafile_api.get_file_id_by_path(repo_id, file_path) token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'download', username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) download_link = gen_file_get_url(token, table_name) return Response({'download_link': download_link})
def get(self, request, workspace_id): """get table file update link Permission: 1. owner 2. group member 3. shared user with `rw` or `admin` permission """ # argument check table_name = request.GET.get('name', None) if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if not check_dtable_permission(username, owner) and \ check_dtable_share_permission(dtable, username) not in WRITE_PERMISSION_TUPLE: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'update', username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dtable.modifier = username dtable.save() url = gen_file_upload_url(token, 'update-api') return Response(url)
def get_excel_json_file(repo_id, file_name): file_path = EXCEL_DIR_PATH + file_name + '.json' file_id = seafile_api.get_file_id_by_path(repo_id, file_path) if not file_id: raise FileExistsError('file %s not found' % file_path) token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'download', '', use_onetime=True) url = gen_inner_file_get_url(token, file_name + '.json') json_file = requests.get(url).content return json_file
def get(self, request, repo_id): """ get info of a single file/folder in a library """ repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not can_view_sys_admin_repo(repo): error_msg = 'Feature disabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) path = request.GET.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if path[0] != '/': path = '/' + path try: dirent = seafile_api.get_dirent_by_path(repo_id, path) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not dirent: error_msg = 'file/folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if stat.S_ISDIR(dirent.mode): is_file = False else: is_file = True username = request.user.username if is_file and request.GET.get('dl', '0') == '1': token = seafile_api.get_fileserver_access_token(repo_id, dirent.obj_id, 'download', username, use_onetime=True) dl_url = gen_file_get_url(token, dirent.obj_name) send_file_access_msg(request, repo, path, 'web') return Response({'download_url': dl_url}) dirent_info = get_dirent_info(dirent) return Response(dirent_info)
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 repl(matchobj): if matchobj.group(2): # return origin string in backquotes return matchobj.group(2) page_alias = page_name = matchobj.group(1).strip() if len(page_name.split("|")) > 1: page_alias = page_name.split("|")[0] page_name = page_name.split("|")[1] filetype, fileext = get_file_type_and_ext(page_name) if fileext == "": # convert page_name that extension is missing to a markdown page try: dirent = get_wiki_dirent(repo_id, page_name) a_tag = """<a href="%s">%s</a>""" return a_tag % (smart_str(url_prefix + normalize_page_name(page_name) + "/"), page_alias) except (WikiDoesNotExist, WikiPageMissing): a_tag = """<a href="%s" class="wiki-page-missing">%s</a>""" return a_tag % (smart_str(url_prefix + normalize_page_name(page_name) + "/"), page_alias) elif filetype == IMAGE: # load image to wiki page path = "/" + page_name filename = os.path.basename(path) obj_id = seaserv.get_file_id_by_path(repo_id, path) if not obj_id: # Replace '/' in page_name to '-', since wiki name can not # contain '/'. return """<a href="%s" class="wiki-page-missing">%s</a>""" % ( url_prefix + "/" + page_name.replace("/", "-"), page_name, ) token = seafile_api.get_fileserver_access_token(repo_id, obj_id, "view", username) ret = '<img src="%s" alt="%s" class="wiki-image" />' % (gen_file_get_url(token, filename), filename) return smart_str(ret) else: from seahub.base.templatetags.seahub_tags import file_icon_filter from django.conf import settings # convert other types of filelinks to clickable links path = "/" + page_name icon = file_icon_filter(page_name) s = reverse("view_lib_file", args=[repo_id, path]) a_tag = """<img src="%simg/file/%s" alt="%s" class="file-icon vam" /> <a href="%s" class="vam" target="_blank">%s</a>""" ret = a_tag % (settings.MEDIA_URL, icon, icon, smart_str(s), page_name) return smart_str(ret)
def get(self, request, token): """ Get file upload url according to upload link token. Permission checking: 1. anyone has the upload link token can perform this action; """ try: uls = UploadLinkShare.objects.get(token=token) except UploadLinkShare.DoesNotExist: error_msg = 'token %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) # currently not support encrypted upload link if uls.is_encrypted(): error_msg = 'Upload link %s is encrypted.' % token return api_error(status.HTTP_403_FORBIDDEN, error_msg) repo_id = uls.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) path = uls.path dir_id = seafile_api.get_dir_id_by_path(repo_id, path) if not dir_id: error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if repo.encrypted or \ seafile_api.check_permission_by_path(repo_id, '/', uls.username) != 'rw': error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) token = seafile_api.get_fileserver_access_token(repo_id, dir_id, 'upload-link', uls.username, use_onetime=False) if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = {} result['upload_link'] = gen_file_upload_url(token, 'upload-api') return Response(result)
def repo_download_dir(request, repo_id): repo = get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) path = request.GET.get('p', '/') if path[-1] != '/': # Normalize dir path path += '/' if not seafile_api.get_dir_id_by_path(repo.id, path): return render_error(request, _('"%s" does not exist.') % path) if len(path) > 1: dirname = os.path.basename(path.rstrip('/')) # Here use `rstrip` to cut out last '/' in path else: dirname = repo.name allow_download = True if check_folder_permission(request, repo_id, '/') else False if allow_download: dir_id = seafile_api.get_dir_id_by_commit_and_path(repo.id, repo.head_cmmt_id, path) try: total_size = seafile_api.get_dir_size(repo.store_id, repo.version, dir_id) except Exception, e: logger.error(str(e)) return render_error(request, _(u'Internal Error')) if total_size > MAX_DOWNLOAD_DIR_SIZE: return render_error(request, _(u'Unable to download directory "%s": size is too large.') % dirname) is_windows = 0 if is_windows_operating_system(request): is_windows = 1 fake_obj_id = { 'obj_id': dir_id, 'dir_name': dirname, 'is_windows': is_windows } token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'download-dir', request.user.username)
def allow_generate_thumbnail(request, repo_id, path): """check if thumbnail is allowed """ # get file type obj_name = os.path.basename(path) file_type, file_ext = get_file_type_and_ext(obj_name) # get file size file_id = get_file_id_by_path(repo_id, path) if not file_id: return False repo = get_repo(repo_id) file_size = get_file_size(repo.store_id, repo.version, file_id) if repo.encrypted or file_type != IMAGE or not ENABLE_THUMBNAIL: return False # check image compressed size limit if file_size < THUMBNAIL_IMAGE_COMPRESSED_SIZE_LIMIT * 1024**2: return True # get image memory cost token = seafile_api.get_fileserver_access_token(repo_id, file_id, 'view', '', use_onetime = True) inner_path = gen_inner_file_get_url(token, obj_name) try: image_file = urllib2.urlopen(inner_path) f = StringIO(image_file.read()) image = Image.open(f) width, height = image.size # check image memory cost size limit # use RGBA as default mode(4x8-bit pixels, true colour with transparency mask) # every pixel will cost 4 byte in RGBA mode image_memory_cost = width * height * 4 / 1024 / 1024 if image_memory_cost < THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT: return True except Exception as e: logger.error(e) return False
def get(self, request): # argument check req_from = request.GET.get('from', 'web') if req_from not in ('web', 'api'): error_msg = 'from invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # recourse check try: repo_id = seafile_api.get_system_default_repo_id() repo = seafile_api.get_repo(repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) parent_dir = request.GET.get('path', '/') parent_dir = normalize_dir_path(parent_dir) dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir) if not dir_id: error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'upload', 'system', use_onetime=False) if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if req_from == 'api': url = gen_file_upload_url(token, 'upload-api') else: url = gen_file_upload_url(token, 'upload-aj') result = {} result['upload_link'] = url return Response(result)
def _download_dir_from_share_link(request, fileshare, repo, real_path): # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): return render_error( request, _(u'Unable to access file: share link traffic is used up.')) shared_by = fileshare.username if real_path == '/': dirname = repo.name else: dirname = os.path.basename(real_path.rstrip('/')) dir_id = seafile_api.get_dir_id_by_path(repo.id, real_path) if not dir_id: return render_error(request, _(u'Unable to download: folder not found.')) try: total_size = seaserv.seafserv_threaded_rpc.get_dir_size( repo.store_id, repo.version, dir_id) except Exception as e: logger.error(str(e)) return render_error(request, _(u'Internal Error')) if total_size > seaserv.MAX_DOWNLOAD_DIR_SIZE: return render_error( request, _(u'Unable to download directory "%s": size is too large.') % dirname) token = seafile_api.get_fileserver_access_token( repo.id, dir_id, 'download-dir', request.user.username) try: seaserv.send_message( 'seahub.stats', 'dir-download\t%s\t%s\t%s\t%s' % (repo.id, shared_by, dir_id, total_size)) except Exception as e: logger.error('Error when sending dir-download message: %s' % str(e)) return HttpResponseRedirect(gen_file_get_url(token, dirname))
def create_psd_thumbnails(repo, file_id, path, size, thumbnail_file, file_size): try: from psd_tools import PSDImage except ImportError: logger.error("Could not find psd_tools installed. " "Please install by 'pip install psd_tools'") return (False, 500) token = seafile_api.get_fileserver_access_token( repo.id, file_id, 'view', '', use_onetime=False) if not token: return (False, 500) tmp_img_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id)) t1 = timeit.default_timer() inner_path = gen_inner_file_get_url(token, os.path.basename(path)) tmp_file = os.path.join(tempfile.gettempdir(), file_id) urlretrieve(inner_path, tmp_file) psd = PSDImage.load(tmp_file) merged_image = psd.as_PIL() merged_image.save(tmp_img_path) os.unlink(tmp_file) # remove origin psd file t2 = timeit.default_timer() logger.debug('Extract psd image [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1))) try: ret = _create_thumbnail_common(tmp_img_path, thumbnail_file, size) os.unlink(tmp_img_path) return ret except Exception as e: logger.error(e) os.unlink(tmp_img_path) return (False, 500)
def get(self, request, token): """ Get FileServer url of the shared folder. Permission checking: 1. only admin can perform this action. """ try: uploadlink = UploadLinkShare.objects.get(token=token) except UploadLinkShare.DoesNotExist: error_msg = 'Upload link %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = uploadlink.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library not found.' return api_error(status.HTTP_404_NOT_FOUND, error_msg) path = uploadlink.path obj_id = seafile_api.get_dir_id_by_path(repo_id, path) if not obj_id: error_msg = 'Folder not found.' return api_error(status.HTTP_404_NOT_FOUND, error_msg) upload_token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'upload-link', uploadlink.username, use_onetime=False) if not upload_token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = {} result['upload_link'] = gen_file_upload_url(upload_token, 'upload-api') return Response(result)
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 get(self, request, format=None): """ Only used for download dir when view dir share link from web. Permission checking: 1. authenticated user OR anonymous user has passed email code check(if necessary); """ # permission check if is_pro_version() and settings.ENABLE_SHARE_LINK_AUDIT: if not request.user.is_authenticated() and \ not request.session.get('anonymous_email'): # if anonymous user has passed email code check, # then his/her email info will be in session. error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # argument check share_link_token = request.GET.get('share_link_token', None) if not share_link_token: error_msg = 'share_link_token invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) req_path = request.GET.get('path', None) if not req_path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # recourse check fileshare = FileShare.objects.get_valid_dir_link_by_token(share_link_token) if not fileshare: error_msg = 'share_link_token %s not found.' % share_link_token return api_error(status.HTTP_404_NOT_FOUND, error_msg) if req_path[-1] != '/': req_path += '/' if req_path == '/': real_path = fileshare.path else: real_path = posixpath.join(fileshare.path, req_path.lstrip('/')) if real_path[-1] != '/': real_path += '/' repo_id = fileshare.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dir_id = seafile_api.get_dir_id_by_path(repo_id, real_path) if not dir_id: error_msg = 'Folder %s not found.' % real_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # get file server access token dir_name = repo.name if real_path == '/' else \ os.path.basename(real_path.rstrip('/')) dir_size = seafile_api.get_dir_size( repo.store_id, repo.version, dir_id) if dir_size > seaserv.MAX_DOWNLOAD_DIR_SIZE: error_msg = 'Unable to download directory "%s": size is too large.' % dir_name return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_windows = 0 if is_windows_operating_system(request): is_windows = 1 fake_obj_id = { 'obj_id': dir_id, 'dir_name': dir_name, 'is_windows': is_windows } username = request.user.username try: zip_token = seafile_api.get_fileserver_access_token( repo_id, json.dumps(fake_obj_id), 'download-dir', username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if request.session.get('anonymous_email'): request.user.username = request.session.get('anonymous_email') send_file_access_msg(request, repo, real_path, 'share-link') return Response({'zip_token': zip_token})
def group_discuss(request, group): if group.is_pub: raise Http404 username = request.user.username form = MessageForm() # remove user notifications UserNotification.objects.seen_group_msg_notices(username, group.id) # Get all group members. members = get_group_members(group.id) """group messages""" # Show 15 group messages per page. paginator = Paginator(GroupMessage.objects.filter(group_id=group.id).order_by("-timestamp"), 15) # Make sure page request is an int. If not, deliver first page. try: page = int(request.GET.get("page", "1")) except ValueError: page = 1 # If page request (9999) is out of range, deliver last page of results. try: group_msgs = paginator.page(page) except (EmptyPage, InvalidPage): group_msgs = paginator.page(paginator.num_pages) group_msgs.page_range = paginator.get_page_range(group_msgs.number) # Force evaluate queryset to fix some database error for mysql. group_msgs.object_list = list(group_msgs.object_list) msg_attachments = MessageAttachment.objects.filter(group_message__in=group_msgs.object_list) msg_replies = MessageReply.objects.filter(reply_to__in=group_msgs.object_list) reply_to_list = [r.reply_to_id for r in msg_replies] for msg in group_msgs.object_list: msg.reply_cnt = reply_to_list.count(msg.id) msg.replies = [] for r in msg_replies: if msg.id == r.reply_to_id: msg.replies.append(r) msg.replies = msg.replies[-3:] msg.attachments = [] for att in msg_attachments: if att.group_message_id != msg.id: continue # Attachment name is file name or directory name. # If is top directory, use repo name instead. path = att.path if path == "/": repo = get_repo(att.repo_id) if not repo: # TODO: what should we do here, tell user the repo # is no longer exists? continue att.name = repo.name else: path = path.rstrip("/") # cut out last '/' if possible att.name = os.path.basename(path) # Load to discuss page if attachment is a image and from recommend. if att.attach_type == "file" and att.src == "recommend": att.filetype, att.fileext = get_file_type_and_ext(att.name) if att.filetype == IMAGE: att.obj_id = get_file_id_by_path(att.repo_id, path) if not att.obj_id: att.err = _(u"File does not exist") else: att.token = seafile_api.get_fileserver_access_token(att.repo_id, att.obj_id, "view", username) att.img_url = gen_file_get_url(att.token, att.name) msg.attachments.append(att) # get available modules(wiki, etc) mods_available = get_available_mods_by_group(group.id) mods_enabled = get_enabled_mods_by_group(group.id) return render_to_response( "group/group_discuss.html", { "group": group, "is_staff": group.is_staff, "group_msgs": group_msgs, "form": form, "mods_enabled": mods_enabled, "mods_available": mods_available, }, context_instance=RequestContext(request), )
def get_inner_file_url(repo, obj_id, file_name): repo_id = repo.id access_token = seafile_api.get_fileserver_access_token(repo_id, obj_id, "view", "") url = gen_inner_file_get_url(access_token, file_name) return url
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 get(self, request, repo_id, format=None): repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # argument checking parent_dir = request.GET.get('parent_dir', None) dirent_name_string = request.GET.get('dirents', None) if not parent_dir: error_msg = 'parent_dir invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not dirent_name_string: error_msg = 'dirents invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # folder exist checking if not seafile_api.get_dir_id_by_path(repo_id, parent_dir): error_msg = 'Folder %s not found.' % parent_dir return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission checking if check_folder_permission(request, repo_id, parent_dir) is None: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) dirent_name_list = string2list(dirent_name_string) dirent_list = [] total_size = 0 for dirent_name in dirent_name_list: dirent_name = dirent_name.strip('/') dirent_list.append(dirent_name) full_dirent_path = posixpath.join(parent_dir, dirent_name) current_dirent = seafile_api.get_dirent_by_path(repo_id, full_dirent_path) if stat.S_ISDIR(current_dirent.mode): total_size += seafile_api.get_dir_size(repo.store_id, repo.version, current_dirent.obj_id) else: total_size += current_dirent.size if total_size > seaserv.MAX_DOWNLOAD_DIR_SIZE: error_msg = _('Total size exceeds limit.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) fake_obj_id = {} fake_obj_id['file_list'] = dirent_list fake_obj_id['parent_dir'] = parent_dir username = request.user.username try: token = seafile_api.get_fileserver_access_token(repo_id, json.dumps(fake_obj_id), 'download-multi', username, False) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if len(dirent_list) > 10: send_file_access_msg(request, repo, parent_dir, 'web') else: for dirent_name in dirent_list: full_dirent_path = posixpath.join(parent_dir, dirent_name) send_file_access_msg(request, repo, full_dirent_path, 'web') download_url = '%s/files/%s' % (get_fileserver_root(), token) return Response({'url': download_url})
def get(self, request, slug): """Get content of a wiki """ path = request.GET.get('p', '/') try: wiki = Wiki.objects.get(slug=slug) except Wiki.DoesNotExist: error_msg = "Wiki not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) # perm check if not wiki.has_read_perm(request): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if request.user.username: parent_dir = os.path.dirname(path) permission = check_folder_permission(request, wiki.repo_id, parent_dir) else: permission = 'r' try: repo = seafile_api.get_repo(wiki.repo_id) if not repo: error_msg = "Wiki library not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) except SearpcError: error_msg = _("Internal Server Error") return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) file_id = None try: file_id = seafile_api.get_file_id_by_path(repo.repo_id, path) except SearpcError as e: logger.error(e) return api_error(HTTP_520_OPERATION_FAILED, "Failed to get file id by path.") if not file_id: return api_error(status.HTTP_404_NOT_FOUND, "File not found") # send stats message send_file_access_msg(request, repo, path, 'api') file_name = os.path.basename(path) token = seafile_api.get_fileserver_access_token(repo.repo_id, file_id, 'download', request.user.username, 'False') if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) url = gen_inner_file_get_url(token, file_name) file_response = urllib2.urlopen(url) content = file_response.read() try: dirent = seafile_api.get_dirent_by_path(repo.repo_id, path) if dirent: latest_contributor, last_modified = dirent.modifier, dirent.mtime else: latest_contributor, last_modified = None, 0 except SearpcError as e: logger.error(e) latest_contributor, last_modified = None, 0 return Response({ "content": content, "latest_contributor": email2nickname(latest_contributor), "last_modified": last_modified, "permission": permission, })
def thumbnail_create(request, repo_id): content_type = 'application/json; charset=utf-8' result = {} if not request.is_ajax(): err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if not ENABLE_THUMBNAIL: err_msg = _(u"Thumbnail function is not enabled.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) repo = get_repo(repo_id) if not repo: err_msg = _(u"Library does not exist.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if repo.encrypted: err_msg = _(u"Image thumbnail is not supported in encrypted libraries.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) path = request.GET.get('path', None) obj_id = get_file_id_by_path(repo_id, path) if path is None or obj_id is None: err_msg = _(u"Wrong path.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) # permission check token = request.GET.get('t', None) if token: fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare or not path.startswith(fileshare.path) or \ fileshare.repo_id != repo_id: # check if is valid download link share token and # if is a valid repo/dir belonged to this file share err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) else: if not request.user.is_authenticated(): err_msg = _(u"Please login first.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) elif check_repo_access_permission(repo_id, request.user) is None: err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) # get image file from url size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE) file_name = os.path.basename(path) access_token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'view', request.user.username) raw_path = gen_file_get_url(access_token, file_name) open_file = urllib2.urlopen(raw_path) file_size = int(open_file.info()['Content-Length']) # image file size limit check if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: err_msg = _(u"Image file is too large.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=520, content_type=content_type) thumbnail_dir = os.path.join(THUMBNAIL_ROOT, size) if not os.path.exists(thumbnail_dir): os.makedirs(thumbnail_dir) thumbnail_file = os.path.join(thumbnail_dir, obj_id) if not os.path.exists(thumbnail_file): try: f = StringIO(open_file.read()) image = Image.open(f) if image.mode not in ["1", "L", "P", "RGB", "RGBA"]: image = image.convert("RGB") image.thumbnail((int(size), int(size)), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) except Exception as e: logger.error(e) err_msg = _('Failed to create thumbnail.') return HttpResponse(json.dumps({'err_msg': err_msg}), status=500, content_type=content_type) result['thumbnail_src'] = get_thumbnail_src(repo_id, obj_id, size) return HttpResponse(json.dumps(result), content_type=content_type)
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)