def get(self, request, repo_id, format=None): repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') # check whether user is repo owner if validate_owner(request, repo_id): owner = "self" else: owner = "share" last_commit = get_commits(repo.id, 0, 1)[0] repo.latest_modify = last_commit.ctime if last_commit else None # query repo infomation repo.size = seafserv_threaded_rpc.server_repo_size(repo_id) current_commit = get_commits(repo_id, 0, 1)[0] root_id = current_commit.root_id if current_commit else None repo_json = { "type": "repo", "id": repo.id, "owner": owner, "name": repo.name, "desc": repo.desc, "mtime": repo.latest_modify, "size": repo.size, "encrypted": repo.encrypted, "root": root_id, } return Response(repo_json)
def render_file_revisions(request, repo_id): """List all history versions of a file.""" days_str = request.GET.get('days', '') try: days = int(days_str) except ValueError: days = 7 path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) if not path: return render_error(request) repo = get_repo(repo_id) if not repo: error_msg = _(u"Library does not exist") return render_error(request, error_msg) filetype = get_file_type_and_ext(u_filename)[0].lower() if filetype == 'text' or filetype == 'markdown': can_compare = True else: can_compare = False try: commits = seafile_api.get_file_revisions(repo_id, path, -1, -1, days) except SearpcError, e: logger.error(e.msg) return render_error(request, e.msg)
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 get(self, request, repo_id, format=None): repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') # generate download url for client ccnet_applet_root = get_ccnetapplet_root() relay_id = get_session_info().id addr, port = get_ccnet_server_addr_port() email = request.user.username token = seafserv_threaded_rpc.generate_repo_token( repo_id, request.user.username) repo_name = repo.name enc = 1 if repo.encrypted else '' magic = repo.magic if repo.encrypted else '' info_json = { 'relay_id': relay_id, 'relay_addr': addr, 'relay_port': port, 'email': email, 'token': token, 'repo_id': repo_id, 'repo_name': repo_name, 'encrypted': enc, 'magic': magic, } return Response(info_json)
def GET(self): inputs = web.webapi.input(repo='') sync_status = {} repo = get_repo(inputs.repo) if not repo or not repo.props.worktree or not repo.props.head_branch: return json.dumps(sync_status) relay = get_relay_of_repo(repo) if relay: if relay.props.net_state != NET_STATE_CONNECTED: sync_status['state'] = 'relay not connected' return json.dumps(sync_status) t = seafile_rpc.get_repo_sync_task(inputs.repo) if t: if t.props.state == 'error' and t.props.error == 'relay not connected': # Hide the 'relay not connected' error from daemon when relay # is actually connected, but the check sync pulse has not come yet sync_status['state'] = 'waiting for sync' return json.dumps(sync_status) elif t.props.state == 'canceled' or t.props.state == 'cancel pending': sync_status['state'] = 'waiting for sync' else: sync_status['state'] = t.props.state sync_status['is_sync_lan'] = t.props.is_sync_lan sync_status['error'] = t.props.error else: # No sync task yet: seafile maybe have just been started sync_status['state'] = 'waiting for sync' if sync_status['state'] == 'waiting for sync' and not repo.props.auto_sync: sync_status['state'] = 'auto sync is turned off' return json.dumps(sync_status)
def repo_online_gc(request, repo_id): if request.method != 'POST': raise Http404 repo = get_repo(repo_id) if not repo: raise Http404 referer = request.META.get('HTTP_REFERER', None) next = settings.SITE_ROOT if referer is None else referer username = request.user.username if is_org_context(request): repo_owner = seafile_api.get_org_repo_owner(repo.id) else: repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not is_repo_owner: messages.error(request, _('Permission denied')) return HttpResponseRedirect(next) day = int(request.POST.get('day')) try: seafile_api.clean_up_repo_history(repo.id, day) except SearpcError as e: logger.error(e) messages.error(request, _('Internal server error')) return HttpResponseRedirect(next) return HttpResponseRedirect(next)
def repo_history(request, repo_id): """ List library modification histories. """ user_perm = check_folder_permission(request, repo_id, '/') if not user_perm: return render_permission_error( request, _(u'Unable to view library modification')) repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False password_set = False if repo.props.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)): try: ret = seafserv_rpc.is_passwd_set(repo_id, username) if ret == 1: password_set = True except SearpcError, e: return render_error(request, e.msg) if not password_set: return HttpResponseRedirect( reverse("view_common_lib_dir", args=[repo_id, '']))
def _decorated(request, *args, **kwargs): repo_id = kwargs.get('repo_id', None) if not repo_id: raise Exception, 'Repo id is not found in url.' repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username if repo.encrypted: if (repo.enc_version == 1 or (repo.enc_version == 2 and SERVER_CRYPTO)) \ and not is_passwd_set(repo_id, username): # Redirect uesr to decrypt repo page. return render_to_response( 'decrypt_repo_form.html', { 'repo': repo, 'next': request.get_full_path(), }, context_instance=RequestContext(request)) if repo.enc_version == 2 and not SERVER_CRYPTO: return render_error( request, _(u'Files in this library can not be viewed online.')) return func(request, *args, **kwargs)
def download_file(request, repo_id, obj_id): """Download file. Arguments: - `request`: - `repo_id`: - `obj_id`: """ username = request.user.username repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted and not seafile_api.is_password_set(repo_id, username): return HttpResponseRedirect(reverse('repo', args=[repo_id])) # If vistor's file shared token in url params matches the token in db, # then we know the vistor is from file shared link. share_token = request.GET.get('t', '') fileshare = FileShare.objects.get( token=share_token) if share_token else None shared_by = None if fileshare: from_shared_link = True shared_by = fileshare.username else: from_shared_link = False if from_shared_link: # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): messages.error( request, _(u'Unable to access file: share link traffic is used up.')) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) return HttpResponseRedirect(next) # Permission check and generate download link path = request.GET.get('p', '') if check_repo_access_permission(repo_id, request.user) or \ get_file_access_permission(repo_id, path, username) or from_shared_link: # Get a token to access file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, 'download', username) else: messages.error(request, _(u'Unable to download file')) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) return HttpResponseRedirect(next) # send stats message if from_shared_link: try: file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) send_message( 'seahub.stats', 'file-download\t%s\t%s\t%s\t%s' % (repo.id, shared_by, obj_id, file_size)) except Exception, e: logger.error('Error when sending file-download message: %s' % str(e))
def view_raw_file(request, repo_id, file_path): """Returns raw content of a file. Arguments: - `request`: - `repo_id`: """ repo = get_repo(repo_id) if not repo: raise Http404 file_path = file_path.rstrip('/') if file_path[0] != '/': file_path = '/' + file_path obj_id = get_file_id_by_path(repo_id, file_path) if not obj_id: raise Http404 raw_path, inner_path, user_perm = get_file_view_path_and_perm( request, repo.id, obj_id, file_path) if user_perm is None: raise Http404 return HttpResponseRedirect(raw_path)
def post(self, request, repo_id, format=None): repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') resp = check_repo_access_permission(request, repo) if resp: return resp parent_dir = request.GET.get('p', '/') file_names = request.POST.get("file_names") if not parent_dir or not file_names: return api_error(status.HTTP_404_NOT_FOUND, 'File or directory not found.') names = file_names.split(':') names = map(lambda x: unquote(x).decode('utf-8'), names) for file_name in names: try: seafserv_threaded_rpc.del_file(repo_id, parent_dir, file_name, request.user.username) except SearpcError,e: return api_error(HTTP_520_OPERATION_FAILED, "Failed to delete file.")
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 _decorated(request, *args, **kwargs): repo_id = kwargs.get('repo_id', None) if not repo_id: raise Exception, 'Repo id is not found in url.' repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response( 'options/set_user_options.html', {}, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_passwd_set(repo_id, username): return render_to_response( 'decrypt_repo_form.html', { 'repo': repo, 'next': request.get_full_path(), }, context_instance=RequestContext(request)) if repo.enc_version == 2 and not server_crypto: return render_error( request, _(u'Files in this library can not be viewed online.')) return func(request, *args, **kwargs)
def render_file_revisions (request, repo_id): """List all history versions of a file.""" days_str = request.GET.get('days', '') try: days = int(days_str) except ValueError: days = 7 path = request.GET.get('p', '/') if path[-1] == '/': path = path[:-1] u_filename = os.path.basename(path) if not path: return render_error(request) repo = get_repo(repo_id) if not repo: error_msg = _(u"Library does not exist") return render_error(request, error_msg) filetype = get_file_type_and_ext(u_filename)[0].lower() if filetype == 'text' or filetype == 'markdown': can_compare = True else: can_compare = False try: commits = seafile_api.get_file_revisions(repo_id, path, -1, -1, days) except SearpcError, e: logger.error(e.msg) return render_error(request, e.msg)
def share_link_latest_entry(request, token, size, path): fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare: return None repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: return None if fileshare.path == '/': image_path = path else: image_path = posixpath.join(fileshare.path, path.lstrip('/')) obj_id = get_file_id_by_path(repo_id, image_path) if obj_id: try: thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id) last_modified_time = os.path.getmtime(thumbnail_file) # convert float to datatime obj return datetime.datetime.fromtimestamp(last_modified_time) except Exception as e: logger.error(e) # no thumbnail file exists return None else: return None
def get(self, request, format=None): username = request.user.username shared_repos = [] shared_repos += seafile_api.get_share_in_repo_list(username, -1, -1) joined_groups = get_personal_groups_by_user(username) for grp in joined_groups: # Get group repos, and for each group repos... for r_id in get_group_repoids(grp.id): # No need to list my own repo if seafile_api.is_repo_owner(username, r_id): continue # Convert repo properties due to the different collumns in Repo # and SharedRepo r = get_repo(r_id) if not r: continue r.repo_id = r.id r.repo_name = r.name r.repo_desc = r.desc cmmts = get_commits(r_id, 0, 1) last_commit = cmmts[0] if cmmts else None r.last_modified = last_commit.ctime if last_commit else 0 r.share_type = 'group' r.user = seafile_api.get_repo_owner(r_id) r.user_perm = check_permission(r_id, username) shared_repos.append(r) if not CLOUD_MODE: shared_repos += list_inner_pub_repos(username) return HttpResponse(json.dumps(shared_repos, cls=SearpcObjEncoder), status=200, content_type=json_content_type)
def delete(self, request, repo_id, format=None): # delete file repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') resp = check_repo_access_permission(request, repo) if resp: return resp path = request.GET.get('p', None) if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.') parent_dir = os.path.dirname(path) parent_dir_utf8 = os.path.dirname(path).encode('utf-8') file_name_utf8 = os.path.basename(path).encode('utf-8') try: seafserv_threaded_rpc.del_file(repo_id, parent_dir_utf8, file_name_utf8, request.user.username) except SearpcError, e: return api_error(HTTP_520_OPERATION_FAILED, "Failed to delete file.")
def get(self, request, repo_id, format=None): repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') # generate download url for client ccnet_applet_root = get_ccnetapplet_root() relay_id = get_session_info().id addr, port = get_ccnet_server_addr_port () email = request.user.username token = seafserv_threaded_rpc.generate_repo_token(repo_id, request.user.username) repo_name = repo.name enc = 1 if repo.encrypted else '' magic = repo.magic if repo.encrypted else '' info_json = { 'relay_id': relay_id, 'relay_addr': addr, 'relay_port': port, 'email': email, 'token': token, 'repo_id': repo_id, 'repo_name': repo_name, 'encrypted': enc, 'magic': magic, } return Response(info_json)
def delete(self, request, repo_id, format=None): # delete dir or file repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') resp = check_repo_access_permission(request, repo) if resp: return resp path = request.GET.get('p', None) if not path: return api_error(status.HTTP_400_BAD_REQUEST, 'Path is missing.') if path == '/': # Can not delete root path. return api_error(status.HTTP_400_BAD_REQUEST, 'Path is invalid.') if path[-1] == '/': # Cut out last '/' if possible. path = path[:-1] parent_dir = os.path.dirname(path) parent_dir_utf8 = os.path.dirname(path).encode('utf-8') file_name_utf8 = os.path.basename(path).encode('utf-8') try: seafserv_threaded_rpc.del_file(repo_id, parent_dir_utf8, file_name_utf8, request.user.username) except SearpcError, e: return api_error(HTTP_520_OPERATION_FAILED, "Failed to delete file.")
def get(self, request, repo_id, format=None): repo = get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Repo not found.') # check whether user is repo owner if validate_owner(request, repo_id): owner = "self" else: owner = "share" last_commit = get_commits(repo.id, 0, 1)[0] repo.latest_modify = last_commit.ctime if last_commit else None # query repo infomation repo.size = seafserv_threaded_rpc.server_repo_size(repo_id) current_commit = get_commits(repo_id, 0, 1)[0] root_id = current_commit.root_id if current_commit else None repo_json = { "type":"repo", "id":repo.id, "owner":owner, "name":repo.name, "desc":repo.desc, "mtime":repo.latest_modify, "size":repo.size, "encrypted":repo.encrypted, "root":root_id, } return Response(repo_json)
def _get_events_inner(ev_session, username, start, limit): '''Read events from seafevents database, and remove events that are no longer valid Return 'limit' events or less than 'limit' events if no more events remain ''' valid_events = [] next_start = start while True: events = seafevents.get_user_events(ev_session, username, next_start, limit) if not events: break for ev in events: if ev.etype == 'repo-update': repo = get_repo(ev.repo_id) if not repo: # delete the update event for repo which has been deleted seafevents.delete_event(ev_session, ev.uuid) continue if repo.encrypted: repo.password_set = seafserv_rpc.is_passwd_set(repo.id, username) ev.repo = repo ev.commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, ev.commit_id) valid_events.append(ev) if len(valid_events) == limit: break if len(valid_events) == limit: break next_start = next_start + len(valid_events) return valid_events
def get(self, request, repo_id, dir_id): repo = get_repo(repo_id) resp = check_repo_access_permission(request, repo) if resp: return resp return get_dir_entrys_by_id(request, dir_id)
def share_link_thumbnail_get(request, token, size, path): """ handle thumbnail src from dir download link page return thumbnail file to web """ fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare: return HttpResponse() repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: return HttpResponse() if fileshare.path == '/': image_path = path else: image_path = posixpath.join(fileshare.path, path.lstrip('/')) obj_id = get_file_id_by_path(repo_id, image_path) thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id) if not os.path.exists(thumbnail_file) and \ allow_generate_thumbnail(request, repo_id, image_path): generate_thumbnail(request, repo_id, size, image_path) try: with open(thumbnail_file, 'rb') as f: thumbnail = f.read() return HttpResponse(content=thumbnail, mimetype='image/' + THUMBNAIL_EXTENSION) except IOError as e: logger.error(e) return HttpResponse()
def share_link_thumbnail_get(request, token, size, path): """ handle thumbnail src from dir download link page return thumbnail file to web """ fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare: return HttpResponse() repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: return HttpResponse() if fileshare.path == '/': image_path = path else: image_path = posixpath.join(fileshare.path, path.lstrip('/')) obj_id = get_file_id_by_path(repo_id, image_path) thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id) if not os.path.exists(thumbnail_file) and \ allow_generate_thumbnail(request, repo_id, image_path): generate_thumbnail(request, repo_id, size, image_path) try: with open(thumbnail_file, 'rb') as f: thumbnail = f.read() return HttpResponse(content=thumbnail, mimetype='image/'+THUMBNAIL_EXTENSION) except IOError as e: logger.error(e) return HttpResponse()
def share_link_latest_entry(request, token, size, path): fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare: return None repo_id = fileshare.repo_id repo = get_repo(repo_id) if not repo: return None image_path = get_real_path_by_fs_and_req_path(fileshare, path) obj_id = get_file_id_by_path(repo_id, image_path) if obj_id: try: thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id) last_modified_time = os.path.getmtime(thumbnail_file) # convert float to datatime obj return datetime.datetime.fromtimestamp(last_modified_time) except Exception as e: logger.error(e) # no thumbnail file exists return None else: return None
def post(self, request, repo_id): repo = get_repo(repo_id) resp = check_repo_access_permission(request, repo) if resp: return resp path = request.GET.get('p', None) if not path: return api_error(request, '413', 'Path needed') op = request.GET.get('op', 'sendsharelink') if op == 'sendsharelink': emails = request.POST.get('email', None) if not emails: return api_error(request, '400', "Email required") return send_share_link(request, path, emails) elif op == 'star': org_id = int(request.GET.get('org', '-1')) star_file(request.user.username, repo_id, path, False, org_id=org_id) return HttpResponse(json.dumps('success'), status=200, content_type=json_content_type) elif op == 'unstar': unstar_file(request.user.username, repo_id, path) return HttpResponse(json.dumps('success'), status=200, content_type=json_content_type) return api_error(request, '415')
def post(self, request, repo_id): resp = check_repo_access_permission(request, get_repo(repo_id)) if resp: return resp path = request.GET.get('p') newname = request.POST.get("newname") if not path or path[0] != '/' or not newname: return api_error(request, '400') newname = unquote(newname).decode('utf-8') if len(newname) > settings.MAX_UPLOAD_FILE_NAME_LEN: return api_error(request, '420', 'New name too long') parent_dir = os.path.dirname(path) oldname = os.path.basename(path) if oldname == newname: return api_error(request, '420', 'The new name is the same to the old') newname = check_filename_with_rename(repo_id, parent_dir, newname) try: seafserv_threaded_rpc.rename_file (repo_id, parent_dir, oldname, newname, request.user.username) except SearpcError,e: return api_error(request, '420', "SearpcError:" + e.msg)
def _get_events_inner(ev_session, username, start, limit): '''Read events from seafevents database, and remove events that are no longer valid Return 'limit' events or less than 'limit' events if no more events remain ''' valid_events = [] next_start = start while True: events = seafevents.get_user_events(ev_session, username, next_start, limit) if not events: break for ev in events: if ev.etype == 'repo-update': repo = get_repo(ev.repo_id) if not repo: # delete the update event for repo which has been deleted seafevents.delete_event(ev_session, ev.uuid) continue if repo.encrypted: repo.password_set = seafserv_rpc.is_passwd_set(repo.id, username) ev.repo = repo ev.commit = seafserv_threaded_rpc.get_commit(ev.commit_id) valid_events.append(ev) if len(valid_events) == limit: break if len(valid_events) == limit: break next_start = next_start + len(valid_events) return valid_events
def _decorated(request, *args, **kwargs): repo_id = kwargs.get('repo_id', None) if not repo_id: raise Exception, 'Repo id is not found in url.' repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response('options/set_user_options.html', { }, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_passwd_set(repo_id, username): return render_to_response('decrypt_repo_form.html', { 'repo': repo, 'next': request.get_full_path(), }, context_instance=RequestContext(request)) if repo.enc_version == 2 and not server_crypto: return render_error(request, _(u'Files in this library can not be viewed online.')) return func(request, *args, **kwargs)
def _get_events_inner(ev_session, username, start, org_id=None): '''Read 11 events from seafevents database, and remove events that are no longer valid ''' if org_id == None: events = seafevents.get_user_events(ev_session, username, start, start + 11) else: events = seafevents.get_org_user_events(ev_session, \ org_id, username, start, start + 11) total = len(events) valid_events = [] for ev in events: if ev.etype == 'repo-update': repo = get_repo(ev.repo_id) if not repo: # delete the update event for repo which has been deleted seafevents.delete_event(ev_session, ev.uuid) continue if repo.encrypted: repo.password_set = seafserv_rpc.is_passwd_set(repo.id, username) ev.repo = repo ev.commit = seafserv_threaded_rpc.get_commit(ev.commit_id) valid_events.append(ev) return total, valid_events
def repo_revert_history(request, repo_id): next_page = request.META.get('HTTP_REFERER', None) if not next_page: next_page = settings.SITE_ROOT repo = get_repo(repo_id) if not repo: messages.error(request, _("Library does not exist")) return HttpResponseRedirect(next_page) # perm check perm = check_folder_permission(request, repo_id, '/') username = request.user.username repo_owner = seafile_api.get_repo_owner(repo.id) if perm is None or repo_owner != username: messages.error(request, _("Permission denied")) return HttpResponseRedirect(next_page) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False password_set = False if repo.props.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)): try: ret = seafile_api.is_password_set(repo_id, username) if ret == 1: password_set = True except SearpcError as e: return render_error(request, e.msg) if not password_set: reverse_url = reverse('lib_view', args=[repo_id, repo.name, '']) return HttpResponseRedirect(reverse_url) commit_id = request.GET.get('commit_id', '') if not commit_id: return render_error(request, _('Please specify history ID')) try: seafserv_threaded_rpc.revert_on_server(repo_id, commit_id, request.user.username) messages.success(request, _('Successfully restored the library.')) except SearpcError as e: if e.msg == 'Bad arguments': return render_error(request, _('Invalid arguments.')) elif e.msg == 'No such repo': return render_error(request, _('Library does not exist')) elif e.msg == "Commit doesn't exist": return render_error(request, _('History you specified does not exist')) else: return render_error(request, _('Unknown error')) return HttpResponseRedirect(next_page)
def _decorated(request, *args, **kwargs): repo_id = kwargs.get("repo_id", None) if not repo_id: raise Exception, "Repo id is not found in url." repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username if repo.encrypted: try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: return render_to_response("options/set_user_options.html", {}, context_instance=RequestContext(request)) if (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) and not is_passwd_set( repo_id, username ): return render_to_response( "decrypt_repo_form.html", {"repo": repo, "next": request.get_full_path(), "force_server_crypto": FORCE_SERVER_CRYPTO}, context_instance=RequestContext(request), ) if repo.enc_version == 2 and not server_crypto: return render_error(request, _(u"Files in this library can not be viewed online.")) return func(request, *args, **kwargs)
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 repo_history(request, repo_id): """ List library modification histories. """ user_perm = check_folder_permission(request, repo_id, '/') if not user_perm: return render_permission_error(request, _(u'Unable to view library modification')) repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False password_set = False if repo.props.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)): try: ret = seafserv_rpc.is_passwd_set(repo_id, username) if ret == 1: password_set = True except SearpcError, e: return render_error(request, e.msg) if not password_set: return HttpResponseRedirect(reverse("view_common_lib_dir", args=[repo_id, '']))
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_shared_upload_link(request): """ Handle ajax request to generate dir upload link. """ content_type = 'application/json; charset=utf-8' repo_id = request.GET.get('repo_id', '') path = request.GET.get('p', '') use_passwd = True if int(request.POST.get('use_passwd', '0')) == 1 else False passwd = request.POST.get('passwd') if use_passwd else None if not (repo_id and path): err = _('Invalid arguments') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) if path == '/': # can not share root dir err = _('You cannot share the library in this way.') data = json.dumps({'error': err}) return HttpResponse(data, status=400, content_type=content_type) else: if path[-1] != '/': # append '/' at end of path path += '/' repo = seaserv.get_repo(repo_id) if not repo: messages.error(request, _(u'Library does not exist')) return HttpResponse(status=400, content_type=content_type) user_perm = check_folder_permission(repo.id, path, request.user.username) if user_perm == 'r': messages.error(request, _(u'Permission denied')) return HttpResponse(status=403, content_type=content_type) elif user_perm == 'rw': l = UploadLinkShare.objects.filter(repo_id=repo_id).filter( username=request.user.username).filter(path=path) if len(l) > 0: upload_link = l[0] token = upload_link.token else: username = request.user.username uls = UploadLinkShare.objects.create_upload_link_share( username, repo_id, path, passwd) token = uls.token shared_upload_link = gen_shared_upload_link(token) data = json.dumps({ 'token': token, 'shared_upload_link': shared_upload_link }) return HttpResponse(data, status=200, content_type=content_type) else: messages.error(request, _(u'Operation failed')) return HttpResponse(json.dumps(), status=500, content_type=content_type)
def share_link_thumbnail_get(request, token, size, path): """ handle thumbnail src from dir download link page return thumbnail file to web """ try: size = int(size) except ValueError as e: logger.error(e) return HttpResponse() fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare: return HttpResponse() password_check_passed, err_msg = check_share_link_common( request, fileshare) if not password_check_passed: d = { 'token': token, 'view_name': 'view_shared_dir', 'err_msg': err_msg } return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) image_path = get_real_path_by_fs_and_req_path(fileshare, path) repo_id = fileshare.repo_id repo = get_repo(repo_id) obj_id = get_file_id_by_path(repo_id, image_path) # check if file exist if not repo or not obj_id: return HttpResponse() # check if is allowed if repo.encrypted or not ENABLE_THUMBNAIL: return HttpResponse() success = True thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id) if not os.path.exists(thumbnail_file): success, status_code = generate_thumbnail(request, repo_id, size, image_path) if success: try: with open(thumbnail_file, 'rb') as f: thumbnail = f.read() return HttpResponse(content=thumbnail, content_type='image/' + THUMBNAIL_EXTENSION) except IOError as e: logger.error(e) return HttpResponse() else: return HttpResponse()
def thumbnail_create(request, repo_id): content_type = 'application/json; charset=utf-8' result = {} path = request.GET.get('path') size = request.GET.get('size', THUMBNAIL_DEFAULT_SIZE) obj_id = get_file_id_by_path(repo_id, path) raw_path, inner_path, user_perm = get_file_view_path_and_perm( request, repo_id, obj_id, path) if user_perm is None: err_msg = _(u"Permission denied.") return HttpResponse(json.dumps({"err_msg": err_msg}), status=403, content_type=content_type) repo = get_repo(repo_id) 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) 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) open_file = urllib2.urlopen(raw_path) file_size = int(open_file.info()['Content-Length']) if file_size > THUMBNAIL_IMAGE_SIZE_LIMIT * 1024**2: # if file is bigger than 30MB 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) image.thumbnail((int(size), int(size)), Image.ANTIALIAS) image.save(thumbnail_file, THUMBNAIL_EXTENSION) except Exception as e: logger.error(e) return HttpResponse(json.dumps({'success': False}), 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 text_diff(request, repo_id): commit_id = request.GET.get('commit', '') path = request.GET.get('p', '') u_filename = os.path.basename(path) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' if not (commit_id and path): return render_error(request, 'bad params') repo = get_repo(repo_id) if not repo: return render_error(request, 'bad repo') current_commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, commit_id) if not current_commit: return render_error(request, 'bad commit id') prev_commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, current_commit.parent_id) if not prev_commit: return render_error('bad commit id') path = path.encode('utf-8') current_content, err = get_file_content_by_commit_and_path(request, \ repo_id, current_commit.id, path, file_enc) if err: return render_error(request, err) prev_content, err = get_file_content_by_commit_and_path(request, \ repo_id, prev_commit.id, path, file_enc) if err: return render_error(request, err) is_new_file = False diff_result_table = '' if prev_content == '' and current_content == '': is_new_file = True else: diff = HtmlDiff() diff_result_table = diff.make_table(prev_content.splitlines(), current_content.splitlines(), True) zipped = gen_path_link(path, repo.name) return render_to_response('text_diff.html', { 'u_filename': u_filename, 'repo': repo, 'path': path, 'zipped': zipped, 'current_commit': current_commit, 'prev_commit': prev_commit, 'diff_result_table': diff_result_table, 'is_new_file': is_new_file, }, context_instance=RequestContext(request))
def get(self, request, repo_id, file_id): repo = get_repo(repo_id) resp = check_repo_access_permission(request, repo) if resp: return resp file_name = request.GET.get('file_name', file_id) return get_repo_file (request, repo_id, file_id, file_name, 'download')
def msg_reply_new(request): username = request.user.username grpmsg_reply_list = [ x for x in UserNotification.objects.get_group_msg_reply_notices(username) ] msg_ids = [] for e in grpmsg_reply_list: try: msg_id = e.grpmsg_reply_detail_to_dict().get('msg_id') except UserNotification.InvalidDetailError: continue msg_ids.append(msg_id) group_msgs = [] for msg_id in msg_ids: try: m = GroupMessage.objects.get(id=msg_id) except GroupMessage.DoesNotExist: continue else: if m in group_msgs: continue # get group name group = get_group(m.group_id) if not group: continue m.group_name = group.group_name # get attachements attachments = m.messageattachment_set.all() for attachment in attachments: path = attachment.path if path == '/': repo = get_repo(attachment.repo_id) if not repo: continue attachment.name = repo.name else: attachment.name = os.path.basename(path) m.attachments = attachments # get message replies reply_list = MessageReply.objects.filter(reply_to=m) m.reply_cnt = reply_list.count() if m.reply_cnt > 3: m.replies = reply_list[m.reply_cnt - 3:] else: m.replies = reply_list group_msgs.append(m) # remove new group msg reply notification UserNotification.objects.seen_group_msg_reply_notice(username) return render_to_response("group/new_msg_reply.html", { 'group_msgs': group_msgs, }, context_instance=RequestContext(request))
def msg_reply_new(request): username = request.user.username grpmsg_reply_list = [x for x in UserNotification.objects.get_group_msg_reply_notices(username)] msg_ids = [] for e in grpmsg_reply_list: try: msg_id = e.grpmsg_reply_detail_to_dict().get("msg_id") except UserNotification.InvalidDetailError: continue msg_ids.append(msg_id) group_msgs = [] for msg_id in msg_ids: try: m = GroupMessage.objects.get(id=msg_id) except GroupMessage.DoesNotExist: continue else: if m in group_msgs: continue # get group name group = get_group(m.group_id) if not group: continue m.group_name = group.group_name # get attachements attachments = m.messageattachment_set.all() for attachment in attachments: path = attachment.path if path == "/": repo = get_repo(attachment.repo_id) if not repo: continue attachment.name = repo.name else: attachment.name = os.path.basename(path) m.attachments = attachments # get message replies reply_list = MessageReply.objects.filter(reply_to=m) m.reply_cnt = reply_list.count() if m.reply_cnt > 3: m.replies = reply_list[m.reply_cnt - 3 :] else: m.replies = reply_list group_msgs.append(m) # remove new group msg reply notification UserNotification.objects.seen_group_msg_reply_notice(username) return render_to_response( "group/new_msg_reply.html", {"group_msgs": group_msgs}, context_instance=RequestContext(request) )
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 text_diff(request, repo_id): commit_id = request.GET.get("commit", "") path = request.GET.get("p", "") u_filename = os.path.basename(path) file_enc = request.GET.get("file_enc", "auto") if not file_enc in FILE_ENCODING_LIST: file_enc = "auto" if not (commit_id and path): return render_error(request, "bad params") repo = get_repo(repo_id) if not repo: return render_error(request, "bad repo") current_commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, commit_id) if not current_commit: return render_error(request, "bad commit id") prev_commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, current_commit.parent_id) if not prev_commit: return render_error("bad commit id") path = path.encode("utf-8") current_content, err = get_file_content_by_commit_and_path(request, repo_id, current_commit.id, path, file_enc) if err: return render_error(request, err) prev_content, err = get_file_content_by_commit_and_path(request, repo_id, prev_commit.id, path, file_enc) if err: return render_error(request, err) is_new_file = False diff_result_table = "" if prev_content == "" and current_content == "": is_new_file = True else: diff = HtmlDiff() diff_result_table = diff.make_table(prev_content.splitlines(), current_content.splitlines(), True) zipped = gen_path_link(path, repo.name) return render_to_response( "text_diff.html", { "u_filename": u_filename, "repo": repo, "path": path, "zipped": zipped, "current_commit": current_commit, "prev_commit": prev_commit, "diff_result_table": diff_result_table, "is_new_file": is_new_file, }, context_instance=RequestContext(request), )
def get_repo_root_dir(repo_id): """ Get repo root dir from object storage """ repo = get_repo(repo_id) commits = seafile_api.get_commit_list(repo.id, 0, 1) commit = commit_mgr.load_commit(repo.id, repo.version, commits[0].id) dir = fs_mgr.load_seafdir(repo.id, repo.version, commit.root_id) return dir
def post(self, request, repo_id, format=None): resp = check_repo_access_permission(request, get_repo(repo_id)) if resp: return resp op = request.GET.get('op', 'setpassword') if op == 'setpassword': return Response("success") return Response("unsupported operation")
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 get_personal_wiki_repo(username): try: wiki = PersonalWiki.objects.get(username=username) except PersonalWiki.DoesNotExist: raise WikiDoesNotExist repo = seaserv.get_repo(wiki.repo_id) if not repo: raise WikiDoesNotExist return repo
def repo_revert_file(request, repo_id): repo = get_repo(repo_id) if not repo: raise Http404 commit_id = request.GET.get('commit') path = request.GET.get('p') if not (commit_id and path): return render_error(request, _(u"Invalid arguments")) referer = request.META.get('HTTP_REFERER', None) next = settings.SITE_ROOT if referer is None else referer username = request.user.username # perm check if check_folder_permission(request, repo.id, path) != 'rw': messages.error(request, _("Permission denied")) return HttpResponseRedirect(next) is_locked, locked_by_me = check_file_lock(repo_id, path, username) if (is_locked, locked_by_me) == (None, None): messages.error(request, _("Check file lock error")) return HttpResponseRedirect(next) if is_locked and not locked_by_me: messages.error(request, _("File is locked")) return HttpResponseRedirect(next) try: ret = seafile_api.revert_file(repo_id, commit_id, path, username) except Exception as e: logger.error(e) messages.error(request, _('Failed to restore, please try again later.')) return HttpResponseRedirect(next) if ret == 1: root_url = reverse('view_common_lib_dir', args=[repo_id, '']) msg = _( u'Successfully revert %(path)s to <a href="%(root)s">root directory.</a>' ) % { "path": escape(path.lstrip('/')), "root": root_url } messages.success(request, msg, extra_tags='safe') else: file_view_url = reverse('view_lib_file', args=[repo_id, path.encode('utf-8')]) msg = _(u'Successfully revert <a href="%(url)s">%(path)s</a>') % { "url": file_view_url, "path": escape(path.lstrip('/')) } messages.success(request, msg, extra_tags='safe') return HttpResponseRedirect(next)
def org_log_file_update(request): """ """ if not EVENTS_ENABLED: raise Http404 # Make sure page request is an int. If not, deliver first page. try: current_page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: current_page = 1 per_page = 100 user_selected = request.GET.get('email', None) repo_selected = request.GET.get('repo_id', None) start = per_page * (current_page - 1) limit = per_page org_id = request.user.org.org_id events = get_file_update_events(user_selected, org_id, repo_selected, start, limit) if events: for ev in events: ev.repo = get_repo(ev.repo_id) ev.local_time = utc_to_local(ev.timestamp) ev.time = int(ev.local_time.strftime('%s')) if org_user_exists(org_id, ev.user): ev.is_org_user = True page_next = True if len(events) == per_page else False else: page_next = False extra_href = '' if user_selected: extra_href += "&email=%s" % user_selected if repo_selected: extra_href += "&repo_id=%s" % repo_selected return render( request, 'organizations/org_file_update.html', { 'events': events, 'user_selected': user_selected, 'repo_selected': repo_selected, 'extra_href': extra_href, 'current_page': current_page, 'prev_page': current_page - 1, 'next_page': current_page + 1, 'per_page': per_page, 'page_next': page_next, })
def text_diff(request, repo_id): commit_id = request.GET.get('commit', '') path = request.GET.get('p', '') u_filename = os.path.basename(path) file_enc = request.GET.get('file_enc', 'auto') if not file_enc in FILE_ENCODING_LIST: file_enc = 'auto' if not (commit_id and path): return render_error(request, 'bad params') repo = get_repo(repo_id) if not repo: return render_error(request, 'bad repo') current_commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, commit_id) if not current_commit: return render_error(request, 'bad commit id') prev_commit = seafserv_threaded_rpc.get_commit(repo.id, repo.version, current_commit.parent_id) if not prev_commit: return render_error('bad commit id') path = path.encode('utf-8') current_content, err = get_file_content_by_commit_and_path(request, \ repo_id, current_commit.id, path, file_enc) if err: return render_error(request, err) prev_content, err = get_file_content_by_commit_and_path(request, \ repo_id, prev_commit.id, path, file_enc) if err: return render_error(request, err) is_new_file = False diff_result_table = '' if prev_content == '' and current_content == '': is_new_file = True else: diff = HtmlDiff() diff_result_table = diff.make_table(prev_content.splitlines(), current_content.splitlines(), True) zipped = gen_path_link(path, repo.name) return render_to_response('text_diff.html', { 'u_filename':u_filename, 'repo': repo, 'path': path, 'zipped': zipped, 'current_commit': current_commit, 'prev_commit': prev_commit, 'diff_result_table': diff_result_table, 'is_new_file': is_new_file, }, context_instance=RequestContext(request))
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')) 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) # 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, raw_path, ret_dict) elif filetype == DOCUMENT: handle_document(raw_path, obj_id, fileext, ret_dict) elif filetype == PDF: handle_pdf(raw_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 Exception, e: logger.error('Error when sending file-view message: %s' % str(e))
def share_link_thumbnail_get(request, token, size, path): """ handle thumbnail src from dir download link page return thumbnail file to web """ try: size = int(size) except ValueError as e: logger.error(e) return HttpResponse() fileshare = FileShare.objects.get_valid_file_link_by_token(token) if not fileshare: return HttpResponse() password_check_passed, err_msg = check_share_link_common(request, fileshare) if not password_check_passed: d = {'token': token, 'view_name': 'view_shared_dir', 'err_msg': err_msg} return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) if fileshare.path == '/': image_path = path else: image_path = posixpath.join(fileshare.path, path.lstrip('/')) repo_id = fileshare.repo_id repo = get_repo(repo_id) obj_id = get_file_id_by_path(repo_id, image_path) # check if file exist if not repo or not obj_id: return HttpResponse() # check if is allowed if repo.encrypted or not ENABLE_THUMBNAIL: return HttpResponse() success = True thumbnail_file = os.path.join(THUMBNAIL_ROOT, str(size), obj_id) if not os.path.exists(thumbnail_file): success, status_code = generate_thumbnail(request, repo_id, size, image_path) if success: try: with open(thumbnail_file, 'rb') as f: thumbnail = f.read() return HttpResponse(content=thumbnail, content_type='image/' + THUMBNAIL_EXTENSION) except IOError as e: logger.error(e) return HttpResponse() else: return HttpResponse()
def unsetinnerpub(request, repo_id): """Unshare repos in organization or in share admin page. Only system admin, organization admin or repo owner can perform this op. """ repo = get_repo(repo_id) perm = request.GET.get('permission', None) if perm is None: return render_error(request, _(u'Argument is not valid')) if not repo: messages.error( request, _('Failed to unshare the library, as it does not exist.')) return HttpResponseRedirect(reverse('share_admin')) # permission check username = request.user.username if is_org_context(request): org_id = request.user.org.org_id repo_owner = seafile_api.get_org_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.org.is_staff or is_repo_owner): raise Http404 else: repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.is_staff or is_repo_owner): raise Http404 try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo( org_id, repo.id) else: seaserv.unset_inner_pub_repo(repo.id) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' send_perm_audit_msg('delete-repo-perm', username, 'all', perm_repo_id, perm_path, perm) messages.success(request, _('Unshare "%s" successfully.') % repo.name) except SearpcError: messages.error(request, _('Failed to unshare "%s".') % repo.name) referer = request.META.get('HTTP_REFERER', None) next = settings.SITE_ROOT if referer is None else referer return HttpResponseRedirect(next)
def download_file(request, repo_id, obj_id): """Download file. Arguments: - `request`: - `repo_id`: - `obj_id`: """ username = request.user.username repo = get_repo(repo_id) if not repo: raise Http404 if repo.encrypted and not seafile_api.is_password_set(repo_id, username): return HttpResponseRedirect(reverse("repo", args=[repo_id])) # If vistor's file shared token in url params matches the token in db, # then we know the vistor is from file shared link. share_token = request.GET.get("t", "") fileshare = FileShare.objects.get(token=share_token) if share_token else None shared_by = None if fileshare: from_shared_link = True shared_by = fileshare.username else: from_shared_link = False if from_shared_link: # check whether owner's traffic over the limit if user_traffic_over_limit(fileshare.username): messages.error(request, _(u"Unable to access file: share link traffic is used up.")) next = request.META.get("HTTP_REFERER", settings.SITE_ROOT) return HttpResponseRedirect(next) # Permission check and generate download link path = request.GET.get("p", "") if ( check_repo_access_permission(repo_id, request.user) or get_file_access_permission(repo_id, path, username) or from_shared_link ): # Get a token to access file token = seafserv_rpc.web_get_access_token(repo_id, obj_id, "download", username) else: messages.error(request, _(u"Unable to download file")) next = request.META.get("HTTP_REFERER", settings.SITE_ROOT) return HttpResponseRedirect(next) # send stats message if from_shared_link: try: file_size = seafile_api.get_file_size(repo.store_id, repo.version, obj_id) send_message("seahub.stats", "file-download\t%s\t%s\t%s\t%s" % (repo.id, shared_by, obj_id, file_size)) except Exception, e: logger.error("Error when sending file-download message: %s" % str(e))
def post(self, request, repo_id): resp = check_repo_access_permission(request, get_repo(repo_id)) if resp: return resp op = request.GET.get('op', 'setpassword') if op == 'setpassword': return HttpResponse(json.dumps("success"), status=200, content_type=json_content_type) return HttpResponse(json.dumps("unsupported operation"), status=200, content_type=json_content_type)