1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-05 11:17:36 +00:00
seahub/api/views.py

823 lines
27 KiB
Python
Raw Normal View History

# encoding: utf-8
2012-07-14 02:47:59 +00:00
import re
import sys
import os
import stat
import simplejson as json
import settings
2012-09-08 06:36:19 +00:00
from urllib2 import unquote, quote
2012-09-01 05:35:21 +00:00
from django.http import HttpResponse
from django.contrib.sites.models import RequestSite
from django.core.urlresolvers import reverse
from django.template import loader
2012-10-04 15:15:09 +00:00
from django.core.mail import send_mail
from djangorestframework.renderers import JSONRenderer
from djangorestframework.compat import View
from djangorestframework.mixins import ResponseMixin
from djangorestframework.response import Response
2012-07-14 02:47:59 +00:00
2012-09-01 05:35:21 +00:00
try:
from functools import update_wrapper, wraps
except ImportError:
from django.utils.functional import update_wrapper, wraps # Python 2.4 fallback.
from django.utils.decorators import available_attrs
2012-08-21 12:18:06 +00:00
from auth.forms import AuthenticationForm
from auth import login as auth_login
2012-07-14 02:47:59 +00:00
from pysearpc import SearpcError
2012-07-27 03:39:55 +00:00
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, \
2012-07-14 02:47:59 +00:00
get_repo, get_commits, get_branches, \
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, \
2012-09-22 09:46:56 +00:00
check_group_staff, check_permission, get_personal_groups_by_user, get_group_repos
2012-07-14 02:47:59 +00:00
from seahub.utils import list_to_string, \
get_httpserver_root, gen_token, \
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \
2012-11-04 09:06:17 +00:00
gen_file_get_url, string2list, gen_file_upload_url, \
get_starred_files, star_file, unstar_file
2012-07-14 02:47:59 +00:00
from seahub.views import access_to_repo, validate_owner
from seahub.contacts.signals import mail_sended
from share.models import FileShare
2012-07-14 12:26:41 +00:00
2012-09-01 05:35:21 +00:00
from mime import get_file_mime
2012-07-14 02:47:59 +00:00
json_content_type = 'application/json; charset=utf-8'
2012-09-01 05:35:21 +00:00
HTTP_ERRORS = {
'400':'Bad arguments',
2012-09-15 03:31:02 +00:00
'401':'Login required',
2012-11-04 09:06:17 +00:00
'402':'Incorrect repo password',
2012-09-01 05:35:21 +00:00
'403':'Can not access repo',
'404':'Repo not found',
'405':'Query password set error',
2012-09-15 03:31:02 +00:00
'406':'Repo is not encrypted',
2012-09-01 05:35:21 +00:00
'407':'Method not supported',
'408':'Login failed',
2012-09-19 16:14:40 +00:00
'409':'Repo password required',
2012-09-01 05:35:21 +00:00
'410':'Path does not exist',
'411':'Failed to get dirid by path',
'412':'Failed to get fileid by path',
2012-10-13 09:35:21 +00:00
'413':'Above quota',
2012-09-01 05:35:21 +00:00
'415':'Operation not supported',
'416':'Failed to list dir',
'417':'Set password error',
'418':'Failed to delete',
'419':'Failed to move',
2012-09-05 14:52:49 +00:00
'420':'Failed to rename',
'421':'Failed to mkdir',
2012-09-01 05:35:21 +00:00
'499':'Unknow Error',
'500':'Internal server error',
'501':'Failed to get shared link',
'502':'Failed to send shared link',
}
def api_error(request, code='499', msg=None):
err_resp = { 'error_msg': msg if msg is not None else HTTP_ERRORS[code] }
return HttpResponse(json.dumps(err_resp), status=code,
content_type=json_content_type)
def api_user_passes_test(test_func):
"""
Decorator for views that checks that the user passes the given test,
redirecting to the log-in page if necessary. The test should be a callable
that takes the user object and returns True if the user passes.
"""
def decorator(view_func):
def _wrapped_view(obj, request, *args, **kwargs):
if test_func(request.user):
return view_func(obj, request, *args, **kwargs)
2012-09-15 03:31:02 +00:00
return api_error (request, '401')
2012-09-01 05:35:21 +00:00
return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view)
return decorator
def api_login_required(function=None):
"""
Decorator for views that checks that the user is logged in, redirecting
to the log-in page if necessary.
"""
actual_decorator = api_user_passes_test(
lambda u: u.is_authenticated()
)
if function:
return actual_decorator(function)
return actual_decorator
2012-07-25 02:40:14 +00:00
2012-07-24 14:10:26 +00:00
def calculate_repo_info(repo_list, username):
"""
Get some info for repo.
"""
for repo in repo_list:
try:
commit = get_commits(repo.id, 0, 1)[0]
repo.latest_modify = commit.ctime
repo.root = commit.root_id
2012-07-25 18:17:32 +00:00
repo.size = seafserv_threaded_rpc.server_repo_size(repo.id)
if not repo.size :
repo.size = 0;
2012-08-29 15:57:51 +00:00
2012-07-24 14:10:26 +00:00
password_need = False
if repo.encrypted:
2012-07-24 14:10:26 +00:00
try:
ret = seafserv_rpc.is_passwd_set(repo.id, username)
if ret != 1:
password_need = True
except SearpcErroe, e:
pass
repo.password_need = password_need
2012-08-29 15:57:51 +00:00
except Exception,e:
repo.latest_modify = 0
2012-07-24 14:10:26 +00:00
repo.commit = None
repo.size = -1
repo.password_need = None
2012-07-14 02:47:59 +00:00
def can_access_repo(request, repo_id):
if not check_permission(repo_id, request.user.username):
2012-09-01 06:39:49 +00:00
return False
return True
2012-07-14 02:47:59 +00:00
2012-07-25 18:17:32 +00:00
def get_file_size (id):
size = seafserv_threaded_rpc.get_file_size(id)
2012-07-25 18:17:32 +00:00
if size:
return size
else:
return 0
def get_dir_entrys_by_id(request, dir_id):
2012-07-14 02:47:59 +00:00
dentrys = []
try:
2012-07-14 12:26:41 +00:00
dirs = seafserv_threaded_rpc.list_dir(dir_id)
2012-07-14 02:47:59 +00:00
except SearpcError, e:
2012-09-01 05:35:21 +00:00
return api_error(request, "416")
2012-07-14 02:47:59 +00:00
for dirent in dirs:
2012-07-24 14:10:26 +00:00
dtype = "file"
2012-07-14 02:47:59 +00:00
entry={}
if stat.S_ISDIR(dirent.mode):
2012-07-24 14:10:26 +00:00
dtype = "dir"
2012-07-14 02:47:59 +00:00
else:
2012-07-25 02:40:14 +00:00
mime = get_file_mime (dirent.obj_name)
if mime:
entry["mime"] = mime
2012-07-14 02:47:59 +00:00
try:
2012-07-25 18:17:32 +00:00
entry["size"] = get_file_size(dirent.obj_id)
2012-07-24 14:10:26 +00:00
except Exception, e:
2012-07-14 02:47:59 +00:00
entry["size"]=0
2012-07-24 14:10:26 +00:00
entry["type"]=dtype
2012-07-14 02:47:59 +00:00
entry["name"]=dirent.obj_name
entry["id"]=dirent.obj_id
dentrys.append(entry)
response = HttpResponse(json.dumps(dentrys), status=200,
content_type=json_content_type)
response["oid"] = dir_id
return response
2012-08-26 13:03:58 +00:00
def set_repo_password(request, repo, password):
2012-09-19 16:14:40 +00:00
assert password, 'password must not be none'
2012-08-26 12:44:47 +00:00
try:
2012-08-26 13:03:58 +00:00
seafserv_threaded_rpc.set_passwd(repo.id, request.user.username, password)
2012-08-26 12:44:47 +00:00
except SearpcError, e:
if e.msg == 'Bad arguments':
2012-09-01 05:35:21 +00:00
return api_error(request, '400')
2012-08-26 12:44:47 +00:00
elif e.msg == 'Repo is not encrypted':
2012-09-15 03:31:02 +00:00
return api_error(request, '406')
2012-08-26 12:44:47 +00:00
elif e.msg == 'Incorrect password':
2012-09-01 05:35:21 +00:00
return api_error(request, '402')
2012-08-26 12:44:47 +00:00
elif e.msg == 'Internal server error':
2012-09-01 05:35:21 +00:00
return api_error(request, '500')
2012-08-26 12:44:47 +00:00
else:
return api_error(request, '417', "SearpcError:" + e.msg)
def check_repo_access_permission(request, repo):
if not repo:
2012-09-01 05:35:21 +00:00
return api_error(request, '404')
if not can_access_repo(request, repo.id):
2012-09-01 05:35:21 +00:00
return api_error(request, '403')
password_set = False
if repo.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo.id, request.user.username)
if ret == 1:
password_set = True
except SearpcError, e:
return api_error(request, '405', "SearpcError:" + e.msg)
2012-08-26 12:44:47 +00:00
if not password_set:
2012-10-21 05:52:30 +00:00
password = request.REQUEST.get('password', default=None)
2012-08-26 12:44:47 +00:00
if not password:
2012-09-19 16:14:40 +00:00
return api_error(request, '409')
2012-08-26 12:44:47 +00:00
2012-08-26 13:03:58 +00:00
return set_repo_password(request, repo, password)
2012-07-14 02:47:59 +00:00
2012-07-21 17:16:43 +00:00
def api_login(request):
if request.method == "POST" :
form = AuthenticationForm(data=request.POST)
else:
2012-09-01 05:35:21 +00:00
return api_error(request, '407')
2012-07-21 17:16:43 +00:00
if form.is_valid():
auth_login(request, form.get_user())
info = {}
email = request.user.username
info['email'] = email
info['feedback'] = settings.DEFAULT_FROM_EMAIL
info['sessionid'] = request.session.session_key
info['usage'] = seafserv_threaded_rpc.get_user_quota_usage(email)
info['total'] = seafserv_threaded_rpc.get_user_quota(email)
return HttpResponse(json.dumps([info]), status=200, content_type=json_content_type)
2012-07-21 17:16:43 +00:00
else:
2012-09-01 05:35:21 +00:00
return api_error(request, '408')
2012-07-21 17:16:43 +00:00
class Ping(ResponseMixin, View):
def get(self, request):
response = HttpResponse(json.dumps("pong"), status=200, content_type=json_content_type)
if request.user.is_authenticated():
response["logined"] = True
else:
response["logined"] = False
return response
2012-07-21 17:16:43 +00:00
2012-10-04 15:15:09 +00:00
class Account(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request):
info = {}
email = request.user.username
info['email'] = email
info['usage'] = seafserv_threaded_rpc.get_user_quota_usage(email)
2012-11-04 13:59:17 +00:00
info['total'] = seafserv_threaded_rpc.get_user_quota(email)
2012-10-04 15:15:09 +00:00
info['feedback'] = settings.DEFAULT_FROM_EMAIL
response = Response(200, [info])
return self.render(response)
2012-07-14 12:26:41 +00:00
class ReposView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request):
email = request.user.username
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
2012-07-24 14:10:26 +00:00
calculate_repo_info (owned_repos, email)
2012-07-14 12:26:41 +00:00
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
n_repos = seafserv_threaded_rpc.list_share_repos(email,
'to_email', -1, -1)
2012-07-24 14:10:26 +00:00
calculate_repo_info (n_repos, email)
2012-07-14 12:26:41 +00:00
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
repos_json = []
for r in owned_repos:
repo = {
2012-07-24 14:10:26 +00:00
"type":"repo",
"id":r.id,
2012-07-24 14:10:26 +00:00
"owner":email,
"name":r.name,
"desc":r.desc,
2012-08-29 15:57:51 +00:00
"mtime":r.latest_modify,
"root":r.root,
2012-07-24 14:10:26 +00:00
"size":r.size,
"encrypted":r.encrypted,
2012-07-24 14:10:26 +00:00
"password_need":r.password_need,
2012-07-14 12:26:41 +00:00
}
repos_json.append(repo)
for r in n_repos:
repo = {
2012-09-01 07:41:55 +00:00
"type":"srepo",
"id":r.id,
"owner":r.shared_email,
"name":r.name,
"desc":r.desc,
2012-08-29 15:57:51 +00:00
"mtime":r.latest_modify,
"root":r.root,
2012-07-24 14:10:26 +00:00
"size":r.size,
"encrypted":r.encrypted,
2012-07-24 14:10:26 +00:00
"password_need":r.password_need,
2012-07-14 12:26:41 +00:00
}
repos_json.append(repo)
2012-09-22 09:46:56 +00:00
groups = get_personal_groups_by_user(email)
2012-09-01 07:41:55 +00:00
for group in groups:
g_repos = get_group_repos(group.id, email)
calculate_repo_info (g_repos, email)
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
for r in g_repos:
repo = {
"type":"grepo",
"id":r.id,
"owner":group.group_name,
"name":r.name,
"desc":r.desc,
"mtime":r.latest_modify,
"root":r.root,
"size":r.size,
"encrypted":r.encrypted,
2012-09-01 07:41:55 +00:00
"password_need":r.password_need,
}
repos_json.append(repo)
2012-07-14 12:26:41 +00:00
response = Response(200, repos_json)
return self.render(response)
2012-07-21 17:16:43 +00:00
2012-07-14 12:26:41 +00:00
class RepoView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get_repo_info(request, repo_id):
# check whether user can view repo
repo = get_repo(repo_id)
2012-08-26 12:44:47 +00:00
if not repo:
2012-09-01 05:35:21 +00:00
return api_error(request, '404')
2012-08-26 12:44:47 +00:00
if not can_access_repo(request, repo.id):
2012-09-01 05:35:21 +00:00
return api_error(request, '403')
2012-07-14 12:26:41 +00:00
# check whether use is repo owner
if validate_owner(request, repo_id):
owner = "self"
else:
owner = "share"
2012-07-14 02:47:59 +00:00
try:
2012-07-14 12:26:41 +00:00
repo.latest_modify = get_commits(repo.id, 0, 1)[0].ctime
except:
repo.latest_modify = None
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
# query repo infomation
2012-08-26 12:44:47 +00:00
repo.size = seafserv_threaded_rpc.server_repo_size(repo_id)
2012-07-14 12:26:41 +00:00
current_commit = get_commits(repo_id, 0, 1)[0]
repo_json = {
2012-07-24 14:10:26 +00:00
"type":"repo",
"id":repo.id,
2012-07-14 02:47:59 +00:00
"owner":owner,
"name":repo.name,
"desc":repo.desc,
2012-07-14 02:47:59 +00:00
"mtime":repo.lastest_modify,
2012-08-26 12:44:47 +00:00
"size":repo.size,
"encrypted":r.encrypted,
"root":current_commit.root_id,
"password_need":repo.password_need,
2012-07-14 02:47:59 +00:00
}
2012-07-14 12:26:41 +00:00
response = Response(200, repo_json)
return self.render(response)
2012-07-14 02:47:59 +00:00
2012-08-26 12:44:47 +00:00
@api_login_required
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)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
class RepoDirPathView(ResponseMixin, View):
renderers = (JSONRenderer,)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
@api_login_required
def get(self, request, repo_id):
repo = get_repo(repo_id)
resp = check_repo_access_permission(request, repo)
if resp:
return resp
2012-07-14 02:47:59 +00:00
current_commit = get_commits(repo_id, 0, 1)[0]
path = request.GET.get('p', '/')
if path[-1] != '/':
path = path + '/'
2012-07-14 02:47:59 +00:00
dir_id = None
try:
dir_id = seafserv_threaded_rpc.get_dirid_by_path(current_commit.id,
path.encode('utf-8'))
except SearpcError, e:
return api_error(request, "411", "SearpcError:" + e.msg)
2012-09-01 05:35:21 +00:00
if not dir_id:
return api_error(request, '410')
2012-07-14 02:47:59 +00:00
old_oid = request.GET.get('oid', None)
if old_oid and old_oid == dir_id :
2012-08-22 17:03:55 +00:00
response = HttpResponse(json.dumps("uptodate"), status=200,
content_type=json_content_type)
2012-08-21 13:08:10 +00:00
response["oid"] = dir_id
2012-08-22 17:03:55 +00:00
return response
else:
return get_dir_entrys_by_id(request, dir_id)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
class RepoDirIdView(ResponseMixin, View):
renderers = (JSONRenderer,)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
@api_login_required
def get(self, request, repo_id, dir_id):
repo = get_repo(repo_id)
resp = check_repo_access_permission(request, repo)
if resp:
return resp
2012-07-14 12:26:41 +00:00
return get_dir_entrys_by_id(request, dir_id)
def get_shared_link(request, repo_id, path):
l = FileShare.objects.filter(repo_id=repo_id).filter(\
username=request.user.username).filter(path=path)
token = None
if len(l) > 0:
fileshare = l[0]
token = fileshare.token
else:
token = gen_token(max_length=10)
2012-07-14 12:26:41 +00:00
fs = FileShare()
fs.username = request.user.username
fs.repo_id = repo_id
fs.path = path
fs.token = token
try:
fs.save()
except IntegrityError, e:
2012-09-01 05:35:21 +00:00
return api_err(request, '501')
domain = RequestSite(request).domain
file_shared_link = 'http://%s%sf/%s/' % (domain,
settings.SITE_ROOT, token)
return HttpResponse(json.dumps(file_shared_link), status=200, content_type=json_content_type)
def get_repo_file(request, repo_id, file_id, file_name, op):
if op == 'download':
token = seafserv_rpc.web_get_access_token(repo_id, file_id,
op, request.user.username)
redirect_url = gen_file_get_url(token, file_name)
response = HttpResponse(json.dumps(redirect_url), status=200,
content_type=json_content_type)
response["oid"] = file_id
return response
if op == 'sharelink':
path = request.GET.get('p', None)
assert path, 'path must be passed in the url'
return get_shared_link(request, repo_id, path)
def send_share_link(request, repo_id, path, emails):
l = FileShare.objects.filter(repo_id=repo_id).filter(\
username=request.user.username).filter(path=path)
if len(l) > 0:
fileshare = l[0]
token = fileshare.token
else:
token = gen_token(max_length=10)
fs = FileShare()
fs.username = request.user.username
fs.repo_id = repo_id
fs.path = path
fs.token = token
try:
fs.save()
except IntegrityError, e:
2012-09-01 05:35:21 +00:00
return api_err(request, '501')
domain = RequestSite(request).domain
file_shared_link = 'http://%s%sf/%s/' % (domain,
settings.SITE_ROOT, token)
t = loader.get_template('shared_link_email.html')
to_email_list = string2list(emails)
for to_email in to_email_list:
mail_sended.send(sender=None, user=request.user.username,
email=to_email)
c = {
'email': request.user.username,
'to_email': to_email,
'file_shared_link': file_shared_link,
}
try:
send_mail('您的好友通过SeaCloud分享了一个文件给您',
t.render(Context(c)), None, [to_email],
fail_silently=False)
except:
2012-09-01 05:35:21 +00:00
return api_error(request, '502')
return HttpResponse(json.dumps(file_shared_link), status=200, content_type=json_content_type)
class RepoFileIdView(ResponseMixin, View):
2012-07-14 12:26:41 +00:00
renderers = (JSONRenderer,)
@api_login_required
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')
2012-11-04 09:06:17 +00:00
class RepoFilePathView(ResponseMixin, View):
@api_login_required
def get(self, request, repo_id):
2012-07-14 12:26:41 +00:00
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:
2012-09-01 05:35:21 +00:00
return api_error(request, '413')
2012-07-14 12:26:41 +00:00
file_id = None
try:
file_id = seafserv_threaded_rpc.get_file_by_path(repo_id,
path.encode('utf-8'))
except SearpcError, e:
return api_error(request, '412', "SearpcError:" + e.msg)
if not file_id:
2012-09-01 05:35:21 +00:00
return api_error(request, '410')
file_name = request.GET.get('file_name', file_id)
op = request.GET.get('op', 'download')
return get_repo_file(request, repo_id, file_id, file_name, op)
2012-07-14 12:26:41 +00:00
@api_login_required
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)
2012-11-04 09:06:17 +00:00
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)
2012-09-01 05:35:21 +00:00
return api_error(request, '415')
2012-09-08 06:36:19 +00:00
def reloaddir_if_neccessary (request, repo_id, parent_dir):
reloaddir = False
s = request.GET.get('reloaddir', None)
if s and s.lower() == 'true':
reloaddir = True
if not reloaddir:
return HttpResponse(json.dumps('success'), status='200',
content_type=json_content_type)
current_commit = get_commits(repo_id, 0, 1)[0]
try:
dir_id = seafserv_threaded_rpc.get_dirid_by_path(current_commit.id,
parent_dir.encode('utf-8'))
except SearpcError, e:
return api_error(request, "411", "SearpcError:" + e.msg)
if not dir_id:
return api_error(request, '410')
return get_dir_entrys_by_id(request, dir_id)
class OpDeleteView(ResponseMixin, View):
@api_login_required
def get(self, request, repo_id):
return api_error(request, '407')
@api_login_required
def post(self, request, repo_id):
resp = check_repo_access_permission(request, get_repo(repo_id))
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(request, '400')
names = file_names.split(':')
2012-09-08 06:36:19 +00:00
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(request, '418', 'SearpcError:' + e.msg)
return reloaddir_if_neccessary (request, repo_id, parent_dir)
2012-09-05 14:52:49 +00:00
class OpMkdirView(ResponseMixin, View):
@api_login_required
def get(self, request, repo_id):
return api_error(request, '407')
@api_login_required
def post(self, request, repo_id):
resp = check_repo_access_permission(request, get_repo(repo_id))
if resp:
return resp
2012-09-05 14:52:49 +00:00
path = request.GET.get('p')
if not path or path[0] != '/':
return api_error(request, '400')
parent_dir = os.path.dirname(path)
new_dir_name = os.path.basename(path)
new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name)
try:
seafserv_threaded_rpc.post_dir(repo_id, parent_dir, new_dir_name,
request.user.username)
2012-09-05 14:52:49 +00:00
except SearpcError, e:
return api_error(request, '421', e.msg)
return reloaddir_if_neccessary (request, repo_id, parent_dir)
2012-09-05 14:52:49 +00:00
class OpRenameView(ResponseMixin, View):
@api_login_required
def get(self, request, repo_id):
return api_error(request, '407')
@api_login_required
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')
2012-09-08 06:36:19 +00:00
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)
2012-09-05 14:52:49 +00:00
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)
return reloaddir_if_neccessary (request, repo_id, parent_dir)
class OpMoveView(ResponseMixin, View):
@api_login_required
def get(self, request):
return api_error(request, '407')
@api_login_required
def post(self, request):
src_repo_id = request.POST.get('src_repo')
2012-09-08 06:36:19 +00:00
src_dir = unquote(request.POST.get('src_dir')).decode('utf-8')
dst_repo_id = request.POST.get('dst_repo')
2012-09-08 06:36:19 +00:00
dst_dir = unquote(request.POST.get('dst_dir')).decode('utf-8')
op = request.POST.get('operation')
obj_names = request.POST.get('obj_names')
if not (src_repo_id and src_dir and dst_repo_id \
and dst_dir and op and obj_names):
return api_error(request, '400')
if src_repo_id == dst_repo_id and src_dir == dst_dir:
return api_error(request, '419', 'The src_dir is same to dst_dir')
names = obj_names.split(':')
2012-09-08 06:36:19 +00:00
names = map(lambda x: unquote(x).decode('utf-8'), names)
if dst_dir.startswith(src_dir):
for obj_name in names:
if dst_dir.startswith('/'.join([src_dir, obj_name])):
return api_error(request, '419', 'Can not move a dirctory to its subdir')
for obj_name in names:
new_obj_name = check_filename_with_rename(dst_repo_id, dst_dir, obj_name)
try:
if op == 'cp':
seafserv_threaded_rpc.copy_file (src_repo_id, src_dir, obj_name,
dst_repo_id, dst_dir, new_obj_name,
request.user.username)
elif op == 'mv':
seafserv_threaded_rpc.move_file (src_repo_id, src_dir, obj_name,
dst_repo_id, dst_dir, new_obj_name,
request.user.username)
except SearpcError, e:
return api_error(request, '419', "SearpcError:" + e.msg)
return reloaddir_if_neccessary (request, dst_repo_id, dst_dir)
2012-10-13 09:35:21 +00:00
class OpUploadView(ResponseMixin, View):
@api_login_required
def post(self, request):
return api_error(request, '407')
@api_login_required
def get(self, request, repo_id):
repo = get_repo(repo_id)
if check_permission(repo_id, request.user.username) == 'rw':
token = seafserv_rpc.web_get_access_token(repo_id,
'dummy',
'upload',
request.user.username)
else:
return api_error(request, '403')
if request.cloud_mode and seafserv_threaded_rpc.check_quota(repo_id) < 0:
return api_error(request, '413')
upload_url = gen_file_upload_url(token, 'upload')
return HttpResponse(json.dumps(upload_url), status=200,
content_type=json_content_type)
2012-11-04 09:06:17 +00:00
def append_starred_files(array, files):
for f in files:
sfile = {'org' : f.org_id,
'repo' : f.repo.id,
'path' : f.path,
'mtime' : f.last_modified,
'dir' : f.is_dir,
2012-11-04 13:59:17 +00:00
'size' : f.size
2012-11-04 09:06:17 +00:00
}
array.append(sfile)
def api_starred_files(request):
starred_files = []
personal_files = get_starred_files(request.user.username, -1)
append_starred_files (starred_files, personal_files)
return HttpResponse(json.dumps(starred_files), status=200,
content_type=json_content_type)
class StarredFileView(ResponseMixin, View):
@api_login_required
def get(self, request):
return api_starred_files(request)