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 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 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 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 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 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 view_shared_file(request, token): """ Preview file via shared link. """ assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = fileshare.path.rstrip('/') # Normalize file path obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # Increase file shared link view_cnt, this operation should be atomic fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() # send statistic messages if ret_dict['filetype'] != 'Unknown': try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def get_file_content_by_commit_and_path(request, repo_id, commit_id, path, file_enc): try: obj_id = seafserv_threaded_rpc.get_file_id_by_commit_and_path( \ repo_id, commit_id, path) except: return None, 'bad path' if not obj_id or obj_id == EMPTY_SHA1: return '', None else: permission = check_repo_access_permission(repo_id, request.user) if permission: # Get a token to visit file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, 'view', request.user.username) else: return None, 'permission denied' filename = os.path.basename(path) inner_path = gen_inner_file_get_url(token, filename) try: err, file_content, encoding = repo_file_get(inner_path, file_enc) except Exception, e: return None, 'error when read file from fileserver: %s' % e return file_content, err
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 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 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 view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '').rstrip('/') if not path: raise Http404 if not path.startswith(fileshare.path): # Can not view upper dir of shared dir raise Http404 zipped = gen_path_link(path, '') obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # send statistic messages try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
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 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 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_file_view_path_and_perm(request, repo_id, obj_id, path): """ Get path and the permission to view file. Returns: outer fileserver file url, inner fileserver file url, permission """ username = request.user.username filename = os.path.basename(path) # user_perm = get_file_access_permission(repo_id, path, username) or \ # get_repo_access_permission(repo_id, username) user_perm = check_repo_access_permission(repo_id, request.user) if user_perm is None: return ('', '', user_perm) else: # Get a token to visit file token = web_get_access_token(repo_id, obj_id, 'view', username) outer_url = gen_file_get_url(token, filename) inner_url = gen_inner_file_get_url(token, filename) return (outer_url, inner_url, user_perm)
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, format=None): """ get file content """ token = request.GET.get('access_token', None) info_dict = cache.get('thirdparty_editor_access_token_' + token) repo_id = info_dict['repo_id'] file_path = info_dict['file_path'] obj_id = seafile_api.get_file_id_by_path(repo_id, file_path) file_name = os.path.basename(file_path) try: fileserver_token = seafile_api.get_fileserver_access_token( repo_id, obj_id, 'view', '', use_onetime=False) except SearpcError as e: logger.error(e) return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) if not fileserver_token: return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) inner_path = gen_inner_file_get_url(fileserver_token, file_name) try: file_content = urllib.request.urlopen(inner_path).read() except urllib.error.URLError as e: logger.error(e) return HttpResponse(json.dumps({}), status=500, content_type=json_content_type) return HttpResponse(file_content, content_type="application/octet-stream")
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 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 file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == "POST": return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != "rw": return render_permission_error(request, _(u"Unable to edit file")) path = request.GET.get("p", "/") if path[-1] == "/": path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode("utf-8")) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u"The file does not exist.")) token = web_get_access_token(repo_id, obj_id, "view", request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = "" file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, request.user.username) if not repo.password_set: op = "decrypt" if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get("file_enc", "auto") if not file_enc in FILE_ENCODING_LIST: file_enc = "auto" err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u"Edit online is not offered for this type of file.") # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse("repo_view_file", args=[repo.id]) + "?p=" + urlquote(path) page_from = request.GET.get("from", "") gid = request.GET.get("gid", "") wiki_name = os.path.splitext(u_filename)[0] if page_from == "wiki_page_edit" or page_from == "wiki_page_new": cancel_url = reverse("group_wiki", args=[gid, wiki_name]) elif page_from == "personal_wiki_page_edit" or page_from == "personal_wiki_page_new": cancel_url = reverse("personal_wiki", args=[wiki_name]) return render_to_response( "file_edit.html", { "repo": repo, "u_filename": u_filename, "wiki_name": wiki_name, "path": path, "zipped": zipped, "filetype": filetype, "fileext": fileext, "op": op, "err": err, "file_content": file_content, "encoding": encoding, "file_encoding_list": file_encoding_list, "head_id": head_id, "from": page_from, "gid": gid, "cancel_url": cancel_url, }, context_instance=RequestContext(request), )
def main(): cmd_parser = argparse.ArgumentParser(description="check document preview") cmd_parser.add_argument("repo", help="repo/library uuid") cmd_parser.add_argument("file", help="file path") cmd_parser.add_argument("-t", '--type', dest="type", default='pdf', help="file type") cmd_parser.add_argument("-u", '--user', dest="user", default='admin', help="repo owner") cmd_parser.add_argument("-w", dest="warn_time", default="10", help="warning time in seconds", type=int) cmd_parser.add_argument("-c", dest="crit_time", default="30", help="critical time in seconds", type=int) cmd_parser.add_argument('-V', '--verbose', action="store_true", dest="verbose", help="Give detailed information, if possible") args = cmd_parser.parse_args() repo = seafile_api.get_repo(args.repo) file_id = seafile_api.get_file_id_by_path(repo.id, args.file) token = seafile_api.get_fileserver_access_token(repo.id, file_id, 'view', args.user, use_onetime=True) inner_url = gen_inner_file_get_url(token, os.path.basename(args.file)) add_office_convert_task(file_id, args.type, inner_url, internal=True) start_time = time.time() while time.time() < start_time + args.crit_time: status = delegate_query_office_convert_status(file_id, 1)['status'] if status == 'DONE': break time.sleep(1) end_time = time.time() if start_time + args.warn_time < end_time < start_time + args.crit_time: print 'WARN - %d seconds' % (end_time - start_time) sys.exit(1) elif end_time >= start_time + args.crit_time: print 'CRIT - %d seconds' % (end_time - start_time) sys.exit(2) else: print 'OK - %d seconds' % (end_time - start_time)
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) if filetype == XMIND: return extract_xmind_image(repo_id, path, size) # image thumbnails if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: return (False, 400) if fileext.lower() == 'psd': return create_psd_thumbnails(repo, file_id, path, size, thumbnail_file, file_size) 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_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 get(self, request, format=None): """ get file content """ # parameter check repo_id = request.GET.get('repo_id', None) file_path = request.GET.get('file_path', None) if not repo_id: error_msg = 'repo_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not file_path: error_msg = 'file_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check 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) obj_id = seafile_api.get_file_id_by_path(repo_id, file_path) if not obj_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) # process dwg and ocf file base_filename = "{}_{}_{}".format(repo_id, file_path, obj_id) base_filename = urllib.parse.quote(base_filename, safe='') dwg_filename = "{}.dwg".format(base_filename) dwg_filepath = posixpath.join(WEBCAD_ROOT_FOLDER, WEBCAD_DWG_PATH, dwg_filename) if not os.path.exists(dwg_filepath): try: fileserver_token = seafile_api.get_fileserver_access_token( repo_id, obj_id, 'download', request.user.username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if not fileserver_token: logger.error('No fileserver token') error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) file_name = os.path.basename(file_path) inner_path = gen_inner_file_get_url(fileserver_token, file_name) try: file_content = urllib.request.urlopen(inner_path).read() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) with open(dwg_filepath, 'wb') as f: f.write(file_content) ocf_filename = "{}.ocf".format(base_filename) ocf_filepath = posixpath.join(WEBCAD_ROOT_FOLDER, WEBCAD_OCF_PATH, ocf_filename) if not os.path.exists(ocf_filepath): success = dwg_to_ocf(dwg_filename, ocf_filename) if not success: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) with open(ocf_filepath, 'rb') as f: ocf_file_content = f.read() return HttpResponse(ocf_file_content, content_type="application/octet-stream")
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == 'POST': return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != 'rw': return render_permission_error(request, _(u'Unable to edit file')) path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode('utf-8')) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'The file does not exist.')) token = web_get_access_token(repo_id, obj_id, 'view', request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = '' file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set(repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u'Edit online is not offered for this type of file.') # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse('repo_view_file', args=[repo.id]) + '?p=' + urlquote(path) page_from = request.GET.get('from', '') gid = request.GET.get('gid', '') wiki_name = os.path.splitext(u_filename)[0] if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new': cancel_url = reverse('group_wiki', args=[gid, wiki_name]) elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new': cancel_url = reverse('personal_wiki', args=[wiki_name]) return render_to_response('file_edit.html', { 'repo':repo, 'u_filename':u_filename, 'wiki_name': wiki_name, 'path':path, 'zipped':zipped, 'filetype':filetype, 'fileext':fileext, 'op':op, 'err':err, 'file_content':file_content, 'encoding': encoding, 'file_encoding_list':file_encoding_list, 'head_id': head_id, 'from': page_from, 'gid': gid, 'cancel_url': cancel_url, }, context_instance=RequestContext(request))
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 view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf fileshare = FileShare.objects.get_valid_file_link_by_token(token) if fileshare is None: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '').rstrip('/') if not path: raise Http404 if not path.startswith( fileshare.path): # Can not view upper dir of shared dir raise Http404 zipped = gen_path_link(path, '') obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) img_prev = None img_next = None # get file content ret_dict = { 'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype } exceeds_limit, err_msg = file_size_exceeds_preview_limit( file_size, filetype) if exceeds_limit: ret_dict['err'] = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) elif filetype == IMAGE: current_commit = get_commits(repo_id, 0, 1)[0] parent_dir = os.path.dirname(path) dirs = seafile_api.list_dir_by_commit_and_path( current_commit.repo_id, current_commit.id, parent_dir) if not dirs: raise Http404 img_list = [] for dirent in dirs: if not stat.S_ISDIR(dirent.props.mode): fltype, flext = get_file_type_and_ext(dirent.obj_name) if fltype == 'Image': img_list.append(dirent.obj_name) if len(img_list) > 1: img_list.sort(lambda x, y: cmp(x.lower(), y.lower())) cur_img_index = img_list.index(filename) if cur_img_index != 0: img_prev = posixpath.join(parent_dir, img_list[cur_img_index - 1]) if cur_img_index != len(img_list) - 1: img_next = posixpath.join(parent_dir, img_list[cur_img_index + 1]) # send statistic messages if ret_dict['filetype'] != 'Unknown': try: send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, file_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
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 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) # permission check path = request.GET.get('path', None) image_path = None if not path or '../' in path: err_msg = _(u"Invalid arguments.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) token = request.GET.get('t', None) if token: fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare or fileshare.repo_id != repo_id: err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) if fileshare.path == '/': image_path = path else: image_path = posixpath.join(fileshare.path, path.lstrip('/')) 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) if not image_path: image_path = path obj_id = get_file_id_by_path(repo_id, image_path) if obj_id is None: err_msg = _(u"Wrong path.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) username = request.user.username token = seafile_api.get_fileserver_access_token(repo_id, obj_id, 'view', username, use_onetime=True) inner_url = gen_inner_file_get_url(token, os.path.basename(image_path)) open_file = urllib2.urlopen(inner_url) 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) size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE) 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 view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf try: fileshare = FileShare.objects.get(token=token) except FileShare.DoesNotExist: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '').rstrip('/') if not path: raise Http404 if not path.startswith( fileshare.path): # Can not view upper dir of shared dir raise Http404 zipped = gen_path_link(path, '') obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = { 'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype } fsize = get_file_size(obj_id) exceeds_limit, err_msg = file_size_exceeds_preview_limit(fsize, filetype) if exceeds_limit: err = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # send statistic messages try: obj_size = seafserv_threaded_rpc.get_file_size(obj_id) send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, obj_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
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 view_shared_file(request, token): """ Preview file via shared link. """ assert token is not None # Checked by URLconf fileshare = FileShare.objects.get_valid_file_link_by_token(token) if fileshare is None: raise Http404 if fileshare.is_encrypted(): if not check_share_link_access(request.user.username, token): d = { 'token': token, 'view_name': 'view_shared_file', } if request.method == 'POST': post_values = request.POST.copy() post_values['enc_password'] = fileshare.password form = SharedLinkPasswordForm(post_values) d['form'] = form if form.is_valid(): # set cache for non-anonymous user if request.user.is_authenticated(): set_share_link_access(request.user.username, token) else: return render_to_response( 'share_access_validation.html', d, context_instance=RequestContext(request)) else: return render_to_response( 'share_access_validation.html', d, context_instance=RequestContext(request)) shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = fileshare.path.rstrip('/') # Normalize file path obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = { 'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype } exceeds_limit, err_msg = file_size_exceeds_preview_limit( file_size, filetype) if exceeds_limit: ret_dict['err'] = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == OPENDOCUMENT: if file_size == 0: ret_dict['err'] = _(u'Invalid file format.') elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # Increase file shared link view_cnt, this operation should be atomic fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() # send statistic messages if ret_dict['filetype'] != 'Unknown': try: send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, file_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def view_shared_file(request, token): """ Preview file via shared link. """ assert token is not None # Checked by URLconf fileshare = FileShare.objects.get_valid_file_link_by_token(token) if fileshare is None: raise Http404 if fileshare.is_encrypted(): if not check_share_link_access(request.user.username, token): d = {'token': token, 'view_name': 'view_shared_file', } if request.method == 'POST': post_values = request.POST.copy() post_values['enc_password'] = fileshare.password form = SharedLinkPasswordForm(post_values) d['form'] = form if form.is_valid(): # set cache for non-anonymous user if request.user.is_authenticated(): set_share_link_access(request.user.username, token) else: return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) else: return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = fileshare.path.rstrip('/') # Normalize file path obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} exceeds_limit, err_msg = file_size_exceeds_preview_limit(file_size, filetype) if exceeds_limit: ret_dict['err'] = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == OPENDOCUMENT: if file_size == 0: ret_dict['err'] = _(u'Invalid file format.') elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) # Increase file shared link view_cnt, this operation should be atomic fileshare.view_cnt = F('view_cnt') + 1 fileshare.save() # send statistic messages if ret_dict['filetype'] != 'Unknown': try: send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, file_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def file_edit(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 if request.method == 'POST': return file_edit_submit(request, repo_id) if check_repo_access_permission(repo_id, request.user) != 'rw': return render_permission_error(request, _(u'Unable to edit file')) path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) filename = urllib2.quote(u_filename.encode('utf-8')) head_id = repo.head_cmmt_id obj_id = get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'The file does not exist.')) token = web_get_access_token(repo_id, obj_id, 'view', request.user.username) # generate path and link zipped = gen_path_link(path, repo.name) filetype, fileext = get_file_type_and_ext(filename) op = None err = '' file_content = None encoding = None file_encoding_list = FILE_ENCODING_LIST if filetype == TEXT or filetype == MARKDOWN or filetype == SF: if repo.encrypted: repo.password_set = seafile_api.is_password_set( repo_id, request.user.username) if not repo.password_set: op = 'decrypt' if not op: inner_path = gen_inner_file_get_url(token, filename) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' err, file_content, encoding = repo_file_get(inner_path, file_enc) if encoding and encoding not in FILE_ENCODING_LIST: file_encoding_list.append(encoding) else: err = _(u'Edit online is not offered for this type of file.') # Redirect to different place according to from page when user click # cancel button on file edit page. cancel_url = reverse('repo_view_file', args=[repo.id ]) + '?p=' + urlquote(path) page_from = request.GET.get('from', '') gid = request.GET.get('gid', '') wiki_name = os.path.splitext(u_filename)[0] if page_from == 'wiki_page_edit' or page_from == 'wiki_page_new': cancel_url = reverse('group_wiki', args=[gid, wiki_name]) elif page_from == 'personal_wiki_page_edit' or page_from == 'personal_wiki_page_new': cancel_url = reverse('personal_wiki', args=[wiki_name]) return render_to_response('file_edit.html', { 'repo': repo, 'u_filename': u_filename, 'wiki_name': wiki_name, 'path': path, 'zipped': zipped, 'filetype': filetype, 'fileext': fileext, 'op': op, 'err': err, 'file_content': file_content, 'encoding': encoding, 'file_encoding_list': file_encoding_list, 'head_id': head_id, 'from': page_from, 'gid': gid, 'cancel_url': cancel_url, }, context_instance=RequestContext(request))
def view_file_via_shared_dir(request, token): assert token is not None # Checked by URLconf fileshare = FileShare.objects.get_valid_file_link_by_token(token) if fileshare is None: raise Http404 shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: raise Http404 path = request.GET.get('p', '').rstrip('/') if not path: raise Http404 if not path.startswith(fileshare.path): # Can not view upper dir of shared dir raise Http404 zipped = gen_path_link(path, '') obj_id = seafile_api.get_file_id_by_path(repo_id, path) if not obj_id: return render_error(request, _(u'File does not exist')) file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) access_token = seafserv_rpc.web_get_access_token(repo.id, obj_id, 'view', '') raw_path = gen_file_get_url(access_token, filename) inner_path = gen_inner_file_get_url(access_token, filename) img_prev = None img_next = None # get file content ret_dict = {'err': '', 'file_content': '', 'encoding': '', 'file_enc': '', 'file_encoding_list': [], 'html_exists': False, 'filetype': filetype} exceeds_limit, err_msg = file_size_exceeds_preview_limit(file_size, filetype) if exceeds_limit: ret_dict['err'] = err_msg else: """Choose different approach when dealing with different type of file.""" if is_textual_file(file_type=filetype): handle_textual_file(request, filetype, inner_path, ret_dict) elif filetype == DOCUMENT: handle_document(inner_path, obj_id, fileext, ret_dict) elif filetype == SPREADSHEET: handle_spreadsheet(inner_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(inner_path, obj_id, fileext, ret_dict) elif filetype == IMAGE: current_commit = get_commits(repo_id, 0, 1)[0] parent_dir = os.path.dirname(path) dirs = seafile_api.list_dir_by_commit_and_path(current_commit.repo_id, current_commit.id, parent_dir) if not dirs: raise Http404 img_list = [] for dirent in dirs: if not stat.S_ISDIR(dirent.props.mode): fltype, flext = get_file_type_and_ext(dirent.obj_name) if fltype == 'Image': img_list.append(dirent.obj_name) if len(img_list) > 1: img_list.sort(lambda x, y : cmp(x.lower(), y.lower())) cur_img_index = img_list.index(filename) if cur_img_index != 0: img_prev = posixpath.join(parent_dir, img_list[cur_img_index - 1]) if cur_img_index != len(img_list) - 1: img_next = posixpath.join(parent_dir, img_list[cur_img_index + 1]) # send statistic messages if ret_dict['filetype'] != 'Unknown': try: send_message('seahub.stats', 'file-view\t%s\t%s\t%s\t%s' % \ (repo.id, shared_by, obj_id, file_size)) except SearpcError, e: logger.error('Error when sending file-view message: %s' % str(e))
def get_inner_file_url(repo, obj_id, file_name): repo_id = repo.id access_token = seaserv.seafserv_rpc.web_get_access_token(repo_id, obj_id, 'view', '') url = gen_inner_file_get_url(access_token, file_name) return 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.check_access_wiki(request): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if request.user.username: parent_dir = os.path.dirname(path) permission = check_folder_permission(request, wiki.repo_id, parent_dir) else: permission = 'r' try: repo = seafile_api.get_repo(wiki.repo_id) if not repo: error_msg = "Wiki library not found." return api_error(status.HTTP_404_NOT_FOUND, error_msg) except SearpcError: error_msg = _("Internal Server Error") return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) file_id = None try: file_id = seafile_api.get_file_id_by_path(repo.repo_id, path) except SearpcError as e: logger.error(e) return api_error(HTTP_520_OPERATION_FAILED, "Failed to get file id by path.") if not file_id: return api_error(status.HTTP_404_NOT_FOUND, "File not found") # send stats message send_file_access_msg(request, repo, path, 'api') file_name = os.path.basename(path) token = seafile_api.get_fileserver_access_token( repo.repo_id, file_id, 'download', request.user.username, 'False') if not token: error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) url = gen_inner_file_get_url(token, file_name) file_response = urllib2.urlopen(url) content = file_response.read() try: dirent = seafile_api.get_dirent_by_path(repo.repo_id, path) if dirent: latest_contributor, last_modified = dirent.modifier, dirent.mtime else: latest_contributor, last_modified = None, 0 except SearpcError as e: logger.error(e) latest_contributor, last_modified = None, 0 return Response({ "content": content, "latest_contributor": email2nickname(latest_contributor), "last_modified": last_modified, "permission": permission, })
def copy_dtable(src_workspace, src_dtable, dst_workspace, name, username): # create dtable try: dst_dtable = DTables.objects.create_dtable(username, dst_workspace, name) except Exception as e: logger.error('create table: %s in dst workspace: %s, error: %s', name, dst_workspace.id, e) error_msg = 'Internal Server Error' return None, api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) clear_tmp_files_and_dirs(str(dst_dtable.uuid)) dtable_file_name = name + FILE_TYPE cur_dtable_path = os.path.join(TMP_PATH, str(dst_dtable.uuid)) try: # .dtable src_dtable_file_id = seafile_api.get_file_id_by_path( src_workspace.repo_id, '/' + dtable_file_name) token = seafile_api.get_fileserver_access_token(src_workspace.repo_id, src_dtable_file_id, 'view', '', use_onetime=False) json_url = gen_inner_file_get_url(token, name + FILE_TYPE) response = requests.get(json_url) if response.status_code != 200: logger.error('request dtable url response error status: %s', response.status_code) return None, api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') if response.content: # rebuild asset images files url dtable_content = response.json() dtable_content = rebuild_content_asset(dtable_content, dst_dtable) # save content to local os.makedirs(cur_dtable_path) dtable_save_path = os.path.join(cur_dtable_path, dtable_file_name) with open(dtable_save_path, 'w') as f: json.dump(dtable_content, f) # upload content seafile_api.post_file(dst_workspace.repo_id, dtable_save_path, '/', dtable_file_name, username) else: seafile_api.post_empty_file(dst_workspace.repo_id, '/', dtable_file_name, username) except Exception as e: logger.error('copy dtable: %s.dtable file error: %s', name, e) DTables.objects.filter(id=dst_dtable.id).delete() error_msg = 'Internal Server Error' return None, api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) finally: clear_tmp_files_and_dirs(str(dst_dtable.uuid)) try: # asset dir by seafile_api.copy_file, sync-style temporary copy_asset(src_workspace.repo_id, src_dtable.uuid, dst_workspace.repo_id, dst_dtable.uuid, username) except Exception as e: logger.error('dtable: %s, copy asset dir error: %s', src_dtable.id, e) error_msg = 'Internal Server Error' DTables.objects.filter(id=dst_dtable.id).delete() if seafile_api.get_file_id_by_path(dst_workspace.repo_id, '/' + dtable_file_name): seafile_api.del_file(dst_workspace.repo_id, '/', dtable_file_name, username) return None, api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) finally: clear_tmp_files_and_dirs(str(dst_dtable.uuid)) return dst_dtable, None