2013-07-27 17:07:44 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
|
|
import stat
|
|
|
|
import logging
|
|
|
|
import simplejson as json
|
|
|
|
|
|
|
|
from django.core.urlresolvers import reverse
|
2014-05-07 17:25:22 +08:00
|
|
|
from django.http import HttpResponse, Http404, HttpResponseBadRequest
|
2013-07-27 17:07:44 +08:00
|
|
|
from django.template import RequestContext
|
|
|
|
from django.template.loader import render_to_string
|
|
|
|
from django.utils.http import urlquote
|
|
|
|
from django.utils.translation import ugettext as _
|
|
|
|
|
|
|
|
import seaserv
|
2014-05-07 17:25:22 +08:00
|
|
|
from seaserv import seafile_api, seafserv_rpc, is_passwd_set, \
|
2013-11-21 11:23:43 +08:00
|
|
|
get_related_users_by_repo, get_related_users_by_org_repo, \
|
2014-03-05 14:10:05 +08:00
|
|
|
CALC_SHARE_USAGE, seafserv_threaded_rpc, \
|
2014-03-12 13:51:32 +08:00
|
|
|
get_user_quota_usage, get_user_share_usage
|
2013-07-27 17:07:44 +08:00
|
|
|
from pysearpc import SearpcError
|
|
|
|
|
|
|
|
from seahub.auth.decorators import login_required
|
2013-07-30 11:10:45 +08:00
|
|
|
from seahub.contacts.models import Contact
|
2014-04-28 17:18:41 +08:00
|
|
|
from seahub.forms import RepoNewDirentForm, RepoRenameDirentForm, \
|
|
|
|
RepoCreateForm, SharedRepoCreateForm
|
2013-11-05 15:17:21 +08:00
|
|
|
from seahub.options.models import UserOptions, CryptoOptionNotSetError
|
2013-11-19 16:35:31 +08:00
|
|
|
from seahub.notifications.models import UserNotification
|
2014-04-28 17:18:41 +08:00
|
|
|
from seahub.signals import upload_file_successful, repo_created, repo_deleted
|
2013-12-17 12:14:58 +08:00
|
|
|
from seahub.views import get_repo_dirents, validate_owner, \
|
2014-01-21 16:30:07 +08:00
|
|
|
check_repo_access_permission, get_unencry_rw_repos_by_user, \
|
2014-05-29 15:26:57 +08:00
|
|
|
get_system_default_repo_id, access_to_repo, get_diff, group_events_data, \
|
|
|
|
get_owned_repo_list
|
|
|
|
|
2013-11-13 10:29:52 +08:00
|
|
|
from seahub.views.repo import get_nav_path, get_fileshare, get_dir_share_link, \
|
2014-03-05 14:10:05 +08:00
|
|
|
get_uploadlink, get_dir_shared_upload_link
|
2013-07-27 17:07:44 +08:00
|
|
|
import seahub.settings as settings
|
2014-03-05 14:10:05 +08:00
|
|
|
from seahub.utils import check_filename_with_rename, EMPTY_SHA1, \
|
|
|
|
gen_block_get_url, TRAFFIC_STATS_ENABLED, get_user_traffic_stat,\
|
2014-03-03 13:39:25 +08:00
|
|
|
new_merge_with_no_conflict, get_commit_before_new_merge, \
|
2014-05-07 17:52:34 +08:00
|
|
|
get_repo_last_modify, gen_file_upload_url, is_org_context, \
|
|
|
|
get_org_user_events, get_user_events
|
2013-08-30 15:15:18 +08:00
|
|
|
from seahub.utils.star import star_file, unstar_file
|
2014-06-03 10:14:53 +08:00
|
|
|
from seahub.avatar.util import get_default_avatar_url
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
# Get an instance of a logger
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
########## Seafile API Wrapper
|
|
|
|
def get_repo(repo_id):
|
|
|
|
return seafile_api.get_repo(repo_id)
|
|
|
|
|
2014-03-11 19:59:08 +08:00
|
|
|
def get_commit(repo_id, repo_version, commit_id):
|
|
|
|
return seaserv.get_commit(repo_id, repo_version, commit_id)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
2013-07-30 11:10:45 +08:00
|
|
|
def get_group(gid):
|
|
|
|
return seaserv.get_group(gid)
|
|
|
|
|
|
|
|
def is_group_user(gid, username):
|
|
|
|
return seaserv.is_group_user(gid, username)
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
########## repo related
|
|
|
|
@login_required
|
|
|
|
def get_dirents(request, repo_id):
|
|
|
|
"""
|
|
|
|
Get dirents in a dir for file tree
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
# permission checking
|
2013-12-17 12:14:58 +08:00
|
|
|
user_perm = check_repo_access_permission(repo_id, request.user)
|
2013-07-27 17:07:44 +08:00
|
|
|
if user_perm is None:
|
|
|
|
err_msg = _(u"You don't have permission to access the library.")
|
|
|
|
return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
path = request.GET.get('path', '')
|
|
|
|
dir_only = request.GET.get('dir_only', False)
|
2013-10-30 21:18:58 +08:00
|
|
|
all_dir = request.GET.get('all_dir', False)
|
2013-07-27 17:07:44 +08:00
|
|
|
if not path:
|
|
|
|
err_msg = _(u"No path.")
|
|
|
|
return HttpResponse(json.dumps({"err_msg": err_msg}), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
2013-10-30 21:18:58 +08:00
|
|
|
# get dirents for every path element
|
|
|
|
if all_dir:
|
|
|
|
all_dirents = []
|
|
|
|
path_eles = path.split('/')[:-1]
|
|
|
|
for i, x in enumerate(path_eles):
|
|
|
|
ele_path = '/'.join(path_eles[:i+1]) + '/'
|
|
|
|
try:
|
|
|
|
ele_path_dirents = seafile_api.list_dir_by_path(repo_id, ele_path.encode('utf-8'))
|
|
|
|
except SearpcError, e:
|
|
|
|
ele_path_dirents = []
|
|
|
|
ds = []
|
|
|
|
for d in ele_path_dirents:
|
|
|
|
if stat.S_ISDIR(d.mode):
|
|
|
|
ds.append(d.obj_name)
|
2014-04-02 21:10:50 +08:00
|
|
|
ds.sort(lambda x, y : cmp(x.lower(), y.lower()))
|
2013-10-30 21:18:58 +08:00
|
|
|
all_dirents.append(ds)
|
|
|
|
return HttpResponse(json.dumps(all_dirents), content_type=content_type)
|
|
|
|
|
|
|
|
# get dirents in path
|
2013-07-27 17:07:44 +08:00
|
|
|
try:
|
|
|
|
dirents = seafile_api.list_dir_by_path(repo_id, path.encode('utf-8'))
|
|
|
|
except SearpcError, e:
|
|
|
|
return HttpResponse(json.dumps({"err_msg": e.msg}), status=500,
|
|
|
|
content_type=content_type)
|
2014-04-02 21:10:50 +08:00
|
|
|
|
|
|
|
d_list = []
|
|
|
|
f_list = []
|
2013-07-27 17:07:44 +08:00
|
|
|
for dirent in dirents:
|
|
|
|
if stat.S_ISDIR(dirent.mode):
|
|
|
|
dirent.has_subdir = False
|
|
|
|
|
|
|
|
if dir_only:
|
|
|
|
dirent_path = os.path.join(path, dirent.obj_name)
|
|
|
|
try:
|
|
|
|
dirent_dirents = seafile_api.list_dir_by_path(repo_id, dirent_path.encode('utf-8'))
|
|
|
|
except SearpcError, e:
|
|
|
|
dirent_dirents = []
|
|
|
|
for dirent_dirent in dirent_dirents:
|
|
|
|
if stat.S_ISDIR(dirent_dirent.props.mode):
|
|
|
|
dirent.has_subdir = True
|
|
|
|
break
|
|
|
|
|
|
|
|
subdir = {
|
|
|
|
'name': dirent.obj_name,
|
|
|
|
'id': dirent.obj_id,
|
|
|
|
'type': 'dir',
|
|
|
|
'has_subdir': dirent.has_subdir, # to decide node 'state' ('closed' or not) in jstree
|
|
|
|
}
|
2014-04-02 21:10:50 +08:00
|
|
|
d_list.append(subdir)
|
2013-07-27 17:07:44 +08:00
|
|
|
else:
|
|
|
|
if not dir_only:
|
|
|
|
f = {
|
|
|
|
'id': dirent.obj_id,
|
|
|
|
'name': dirent.obj_name,
|
|
|
|
'type': 'file',
|
|
|
|
}
|
2014-04-02 21:10:50 +08:00
|
|
|
f_list.append(f)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
2014-04-02 21:10:50 +08:00
|
|
|
d_list.sort(lambda x, y : cmp(x['name'].lower(), y['name'].lower()))
|
|
|
|
f_list.sort(lambda x, y : cmp(x['name'].lower(), y['name'].lower()))
|
|
|
|
return HttpResponse(json.dumps(d_list + f_list), content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
@login_required
|
2014-03-14 13:32:00 +08:00
|
|
|
def get_unenc_group_repos(request, group_id):
|
|
|
|
'''
|
|
|
|
Get unenc repos in a group.
|
|
|
|
'''
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
group_id_int = int(group_id)
|
|
|
|
group = get_group(group_id_int)
|
|
|
|
if not group:
|
|
|
|
err_msg = _(u"The group doesn't exist")
|
2013-07-30 11:10:45 +08:00
|
|
|
return HttpResponse(json.dumps({"err_msg": err_msg}), status=400,
|
|
|
|
content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
joined = is_group_user(group_id_int, request.user.username)
|
|
|
|
if not joined and not request.user.is_staff:
|
|
|
|
err_msg = _(u"Permission denied")
|
2013-07-30 11:10:45 +08:00
|
|
|
return HttpResponse(json.dumps({"err_msg": err_msg}), status=403,
|
|
|
|
content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
repos = seafile_api.get_group_repo_list(group_id_int)
|
|
|
|
repo_list = []
|
|
|
|
for repo in repos:
|
2014-03-14 13:32:00 +08:00
|
|
|
if not repo.encrypted:
|
|
|
|
repo_list.append({"name": repo.props.name, "id": repo.props.id})
|
2014-04-09 18:44:52 +08:00
|
|
|
|
|
|
|
repo_list.sort(lambda x, y : cmp(x['name'].lower(), y['name'].lower()))
|
2013-07-27 17:07:44 +08:00
|
|
|
return HttpResponse(json.dumps(repo_list), content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
2013-08-14 10:16:19 +08:00
|
|
|
def get_my_unenc_repos(request):
|
|
|
|
"""Get my owned and unencrypted repos.
|
|
|
|
"""
|
2013-07-27 17:07:44 +08:00
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
2014-05-29 15:26:57 +08:00
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
2014-05-29 15:26:57 +08:00
|
|
|
repos = get_owned_repo_list(request)
|
2013-07-27 17:07:44 +08:00
|
|
|
repo_list = []
|
|
|
|
for repo in repos:
|
2014-04-11 16:12:48 +08:00
|
|
|
if repo.encrypted or repo.is_virtual:
|
2013-08-14 10:16:19 +08:00
|
|
|
continue
|
|
|
|
repo_list.append({"name": repo.name, "id": repo.id})
|
2014-05-29 15:26:57 +08:00
|
|
|
|
|
|
|
repo_list.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
|
2013-07-27 17:07:44 +08:00
|
|
|
return HttpResponse(json.dumps(repo_list), content_type=content_type)
|
|
|
|
|
2013-12-21 12:07:50 +08:00
|
|
|
@login_required
|
|
|
|
def unenc_rw_repos(request):
|
|
|
|
"""Get a user's unencrypt repos that he/she can read-write.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
2014-05-29 15:26:57 +08:00
|
|
|
|
2013-12-21 12:07:50 +08:00
|
|
|
content_type = 'application/json; charset=utf-8'
|
2014-05-29 15:26:57 +08:00
|
|
|
acc_repos = get_unencry_rw_repos_by_user(request)
|
2013-12-21 12:07:50 +08:00
|
|
|
|
|
|
|
repo_list = []
|
|
|
|
for repo in acc_repos:
|
|
|
|
repo_list.append({"name": repo.name, "id": repo.id})
|
2014-04-10 10:37:08 +08:00
|
|
|
|
2014-05-29 15:26:57 +08:00
|
|
|
repo_list.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
|
2013-12-21 12:07:50 +08:00
|
|
|
return HttpResponse(json.dumps(repo_list), content_type=content_type)
|
2014-05-29 15:26:57 +08:00
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
@login_required
|
|
|
|
def list_dir(request, repo_id):
|
|
|
|
"""
|
|
|
|
List directory entries in AJAX.
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
2013-07-30 11:10:45 +08:00
|
|
|
content_type = 'application/json; charset=utf-8'
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
err_msg = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
user_perm = check_repo_access_permission(repo.id, request.user)
|
2013-07-27 17:07:44 +08:00
|
|
|
if user_perm is None:
|
|
|
|
err_msg = _(u'Permission denied.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
2013-11-18 17:41:39 +08:00
|
|
|
sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
|
|
|
|
|
2013-11-05 15:17:21 +08:00
|
|
|
try:
|
|
|
|
server_crypto = UserOptions.objects.is_server_crypto(username)
|
|
|
|
except CryptoOptionNotSetError:
|
|
|
|
# Assume server_crypto is ``False`` if this option is not set.
|
2014-03-24 17:41:08 +08:00
|
|
|
server_crypto = False
|
|
|
|
|
2013-10-14 19:42:04 +08:00
|
|
|
if repo.encrypted and \
|
2013-11-05 15:17:21 +08:00
|
|
|
(repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
|
2013-10-14 19:42:04 +08:00
|
|
|
and not seafile_api.is_password_set(repo.id, username):
|
2013-07-27 17:07:44 +08:00
|
|
|
err_msg = _(u'Library is encrypted.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
2014-03-11 19:59:08 +08:00
|
|
|
head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
|
2013-07-27 17:07:44 +08:00
|
|
|
if not head_commit:
|
|
|
|
err_msg = _(u'Error: no head commit id')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=500, content_type=content_type)
|
|
|
|
|
2014-03-24 17:41:08 +08:00
|
|
|
if new_merge_with_no_conflict(head_commit):
|
|
|
|
info_commit = get_commit_before_new_merge(head_commit)
|
|
|
|
else:
|
|
|
|
info_commit = head_commit
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
path = request.GET.get('p', '/')
|
|
|
|
if path[-1] != '/':
|
2014-03-24 17:41:08 +08:00
|
|
|
path = path + '/'
|
2013-07-27 17:07:44 +08:00
|
|
|
|
2013-08-20 18:30:17 +08:00
|
|
|
more_start = None
|
2014-03-11 19:59:08 +08:00
|
|
|
file_list, dir_list, dirent_more = get_repo_dirents(request, repo, head_commit, path, offset=0, limit=100)
|
2013-08-20 18:30:17 +08:00
|
|
|
if dirent_more:
|
|
|
|
more_start = 100
|
2013-07-27 17:07:44 +08:00
|
|
|
zipped = get_nav_path(path, repo.name)
|
|
|
|
fileshare = get_fileshare(repo.id, username, path)
|
|
|
|
dir_shared_link = get_dir_share_link(fileshare)
|
2013-11-13 10:29:52 +08:00
|
|
|
uploadlink = get_uploadlink(repo.id, username, path)
|
|
|
|
dir_shared_upload_link = get_dir_shared_upload_link(uploadlink)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
ctx = {
|
|
|
|
'repo': repo,
|
|
|
|
'zipped': zipped,
|
|
|
|
'user_perm': user_perm,
|
|
|
|
'path': path,
|
2013-11-07 15:56:42 +08:00
|
|
|
'server_crypto': server_crypto,
|
2013-07-27 17:07:44 +08:00
|
|
|
'fileshare': fileshare,
|
|
|
|
'dir_shared_link': dir_shared_link,
|
2013-11-13 10:29:52 +08:00
|
|
|
'uploadlink': uploadlink,
|
|
|
|
'dir_shared_upload_link': dir_shared_upload_link,
|
2013-07-27 17:07:44 +08:00
|
|
|
'dir_list': dir_list,
|
|
|
|
'file_list': file_list,
|
2013-08-20 18:30:17 +08:00
|
|
|
'dirent_more': dirent_more,
|
|
|
|
'more_start': more_start,
|
2013-07-27 17:07:44 +08:00
|
|
|
'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
|
2013-11-18 17:41:39 +08:00
|
|
|
"sub_lib_enabled": sub_lib_enabled,
|
2014-02-21 16:47:34 +08:00
|
|
|
'current_commit': head_commit,
|
2014-03-24 17:41:08 +08:00
|
|
|
'info_commit': info_commit,
|
2013-07-27 17:07:44 +08:00
|
|
|
}
|
|
|
|
html = render_to_string('snippets/repo_dir_data.html', ctx,
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
return HttpResponse(json.dumps({'html': html, 'path': path}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
2013-08-20 18:30:17 +08:00
|
|
|
@login_required
|
|
|
|
def list_dir_more(request, repo_id):
|
|
|
|
"""
|
|
|
|
List 'more' entries in a directory with AJAX.
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
err_msg = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
user_perm = check_repo_access_permission(repo.id, request.user)
|
2013-08-20 18:30:17 +08:00
|
|
|
if user_perm is None:
|
|
|
|
err_msg = _(u'Permission denied.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
2013-11-18 17:41:39 +08:00
|
|
|
sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
|
|
|
|
|
2013-11-05 15:17:21 +08:00
|
|
|
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
|
|
|
|
|
2013-10-14 19:42:04 +08:00
|
|
|
if repo.encrypted and \
|
2013-11-05 15:17:21 +08:00
|
|
|
(repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
|
2013-10-14 19:42:04 +08:00
|
|
|
and not seafile_api.is_password_set(repo.id, username):
|
2013-08-20 18:30:17 +08:00
|
|
|
err_msg = _(u'Library is encrypted.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
2014-03-11 19:59:08 +08:00
|
|
|
head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
|
2013-08-20 18:30:17 +08:00
|
|
|
if not head_commit:
|
|
|
|
err_msg = _(u'Error: no head commit id')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=500, content_type=content_type)
|
|
|
|
|
|
|
|
path = request.GET.get('p', '/')
|
|
|
|
if path[-1] != '/':
|
|
|
|
path = path + '/'
|
|
|
|
|
|
|
|
offset = int(request.GET.get('start'))
|
|
|
|
if not offset:
|
|
|
|
err_msg = _(u'Argument missing')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
more_start = None
|
2014-03-11 19:59:08 +08:00
|
|
|
file_list, dir_list, dirent_more = get_repo_dirents(request, repo, head_commit, path, offset, limit=100)
|
2013-08-20 18:30:17 +08:00
|
|
|
if dirent_more:
|
|
|
|
more_start = offset + 100
|
|
|
|
|
|
|
|
ctx = {
|
|
|
|
'repo': repo,
|
|
|
|
'user_perm': user_perm,
|
|
|
|
'path': path,
|
2013-11-07 15:56:42 +08:00
|
|
|
'server_crypto': server_crypto,
|
2013-08-20 18:30:17 +08:00
|
|
|
'dir_list': dir_list,
|
|
|
|
'file_list': file_list,
|
|
|
|
'ENABLE_SUB_LIBRARY': settings.ENABLE_SUB_LIBRARY,
|
2013-11-18 17:41:39 +08:00
|
|
|
"sub_lib_enabled": sub_lib_enabled,
|
2013-08-20 18:30:17 +08:00
|
|
|
}
|
|
|
|
html = render_to_string('snippets/repo_dirents.html', ctx,
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
return HttpResponse(json.dumps({'html': html, 'dirent_more': dirent_more, 'more_start': more_start}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
def new_dirent_common(func):
|
|
|
|
"""Decorator for common logic in creating directory and file.
|
|
|
|
"""
|
|
|
|
def _decorated(request, repo_id, *args, **kwargs):
|
|
|
|
if request.method != 'POST' or not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
result['error'] = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# permission checking
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
2013-07-27 17:07:44 +08:00
|
|
|
result['error'] = _('Permission denied')
|
|
|
|
return HttpResponse(json.dumps(result), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# form validation
|
|
|
|
form = RepoNewDirentForm(request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
dirent_name = form.cleaned_data["dirent_name"]
|
|
|
|
else:
|
|
|
|
result['error'] = str(form.errors.values()[0])
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# arguments checking
|
|
|
|
parent_dir = request.GET.get('parent_dir', None)
|
|
|
|
if not parent_dir:
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# rename duplicate name
|
|
|
|
dirent_name = check_filename_with_rename(repo.id, parent_dir,
|
|
|
|
dirent_name)
|
|
|
|
return func(repo.id, parent_dir, dirent_name, username)
|
|
|
|
return _decorated
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
@new_dirent_common
|
|
|
|
def new_dir(repo_id, parent_dir, dirent_name, username):
|
|
|
|
"""
|
|
|
|
Create a new dir with ajax.
|
|
|
|
"""
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
# create new dirent
|
|
|
|
try:
|
|
|
|
seafile_api.post_dir(repo_id, parent_dir, dirent_name, username)
|
|
|
|
except SearpcError, e:
|
|
|
|
result['error'] = str(e)
|
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success': True, 'name': dirent_name}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
@new_dirent_common
|
|
|
|
def new_file(repo_id, parent_dir, dirent_name, username):
|
|
|
|
"""
|
|
|
|
Create a new file with ajax.
|
|
|
|
"""
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
# create new dirent
|
|
|
|
try:
|
|
|
|
seafile_api.post_empty_file(repo_id, parent_dir, dirent_name, username)
|
|
|
|
except SearpcError, e:
|
|
|
|
result['error'] = str(e)
|
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success': True, 'name': dirent_name}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def rename_dirent(request, repo_id):
|
|
|
|
"""
|
|
|
|
Rename a file/dir in a repo, with ajax
|
|
|
|
"""
|
|
|
|
if request.method != 'POST' or not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
username = request.user.username
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
result['error'] = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# permission checking
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
2013-07-27 17:07:44 +08:00
|
|
|
result['error'] = _('Permission denied')
|
|
|
|
return HttpResponse(json.dumps(result), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# form validation
|
|
|
|
form = RepoRenameDirentForm(request.POST)
|
|
|
|
if form.is_valid():
|
|
|
|
oldname = form.cleaned_data["oldname"]
|
|
|
|
newname = form.cleaned_data["newname"]
|
|
|
|
else:
|
|
|
|
result['error'] = str(form.errors.values()[0])
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
if newname == oldname:
|
|
|
|
return HttpResponse(json.dumps({'success': True}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# argument checking
|
|
|
|
parent_dir = request.GET.get('parent_dir', None)
|
|
|
|
if not parent_dir:
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# rename duplicate name
|
|
|
|
newname = check_filename_with_rename(repo_id, parent_dir, newname)
|
|
|
|
|
|
|
|
# rename file/dir
|
|
|
|
try:
|
|
|
|
seafile_api.rename_file(repo_id, parent_dir, oldname, newname, username)
|
|
|
|
except SearpcError, e:
|
|
|
|
result['error'] = str(e)
|
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success': True}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def delete_dirent(request, repo_id):
|
|
|
|
"""
|
|
|
|
Delete a file/dir with ajax.
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
err_msg = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
# permission checking
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
2013-07-27 17:07:44 +08:00
|
|
|
err_msg = _(u'Permission denied.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
|
|
|
# argument checking
|
|
|
|
parent_dir = request.GET.get("parent_dir", None)
|
|
|
|
dirent_name = request.GET.get("name", None)
|
|
|
|
if not (parent_dir and dirent_name):
|
|
|
|
err_msg = _(u'Argument missing.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
# delete file/dir
|
|
|
|
try:
|
|
|
|
seafile_api.del_file(repo_id, parent_dir, dirent_name, username)
|
|
|
|
return HttpResponse(json.dumps({'success': True}),
|
|
|
|
content_type=content_type)
|
|
|
|
except SearpcError, e:
|
|
|
|
logger.error(e)
|
|
|
|
err_msg = _(u'Internal error. Failed to delete %s.') % dirent_name
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=500, content_type=content_type)
|
|
|
|
|
2013-08-30 13:46:56 +08:00
|
|
|
@login_required
|
|
|
|
def delete_dirents(request, repo_id):
|
|
|
|
"""
|
|
|
|
Delete multi files/dirs with ajax.
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
err_msg = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
# permission checking
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
2013-08-30 13:46:56 +08:00
|
|
|
err_msg = _(u'Permission denied.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
|
|
|
# argument checking
|
|
|
|
parent_dir = request.GET.get("parent_dir")
|
|
|
|
dirents_names = request.POST.getlist('dirents_names')
|
|
|
|
if not (parent_dir and dirents_names):
|
|
|
|
err_msg = _(u'Argument missing.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
deleted = []
|
|
|
|
undeleted = []
|
|
|
|
for dirent_name in dirents_names:
|
|
|
|
try:
|
|
|
|
seafile_api.del_file(repo_id, parent_dir, dirent_name, username)
|
|
|
|
deleted.append(dirent_name)
|
|
|
|
except SearpcError, e:
|
|
|
|
logger.error(e)
|
|
|
|
undeleted.append(dirent_name)
|
|
|
|
|
2013-11-07 17:14:16 +08:00
|
|
|
return HttpResponse(json.dumps({'deleted': deleted, 'undeleted': undeleted}),
|
|
|
|
content_type=content_type)
|
2013-08-30 13:46:56 +08:00
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
def copy_move_common(func):
|
|
|
|
"""Decorator for common logic in copying/moving dir/file.
|
|
|
|
"""
|
|
|
|
def _decorated(request, repo_id, *args, **kwargs):
|
|
|
|
if request.method != 'POST' or not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
result['error'] = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# permission checking
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
2013-07-27 17:07:44 +08:00
|
|
|
result['error'] = _('Permission denied')
|
|
|
|
return HttpResponse(json.dumps(result), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
|
|
|
|
# arguments validation
|
|
|
|
path = request.GET.get('path')
|
|
|
|
obj_name = request.GET.get('obj_name')
|
|
|
|
dst_repo_id = request.POST.get('dst_repo')
|
|
|
|
dst_path = request.POST.get('dst_path')
|
|
|
|
|
|
|
|
if not (path and obj_name and dst_repo_id and dst_path):
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# check file path
|
|
|
|
if len(dst_path+obj_name) > settings.MAX_PATH:
|
|
|
|
result['error'] = _('Destination path is too long.')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# check whether user has write permission to dest repo
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(dst_repo_id, request.user) != 'rw':
|
2013-07-27 17:07:44 +08:00
|
|
|
result['error'] = _('Permission denied')
|
|
|
|
return HttpResponse(json.dumps(result), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# do nothing when dst is the same as src
|
|
|
|
if repo_id == dst_repo_id and path == dst_path:
|
2013-08-30 13:46:56 +08:00
|
|
|
result['error'] = _('Invalid destination path')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
return func(repo_id, path, dst_repo_id, dst_path, obj_name, username)
|
|
|
|
return _decorated
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
@copy_move_common
|
|
|
|
def mv_file(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
|
|
|
|
try:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = seafile_api.move_file(src_repo_id, src_path, obj_name,
|
|
|
|
dst_repo_id, dst_path, new_obj_name, username, need_progress=1)
|
2013-07-27 17:07:44 +08:00
|
|
|
except SearpcError, e:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = None
|
|
|
|
|
|
|
|
# res can be None or an object
|
|
|
|
if not res:
|
|
|
|
result['error'] = _(u'Internal server error')
|
2013-07-27 17:07:44 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
2014-04-08 17:57:09 +08:00
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
result['success'] = True
|
|
|
|
msg_url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
|
|
|
|
msg = _(u'Successfully moved %(name)s <a href="%(url)s">view</a>') % \
|
|
|
|
{"name":obj_name, "url":msg_url}
|
|
|
|
result['msg'] = msg
|
|
|
|
if res.background:
|
|
|
|
result['task_id'] = res.task_id
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
@copy_move_common
|
|
|
|
def cp_file(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
|
|
|
|
try:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = seafile_api.copy_file(src_repo_id, src_path, obj_name,
|
|
|
|
dst_repo_id, dst_path, new_obj_name, username, need_progress=1)
|
2013-07-27 17:07:44 +08:00
|
|
|
except SearpcError, e:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = None
|
|
|
|
|
|
|
|
if not res:
|
|
|
|
result['error'] = _(u'Internal server error')
|
2013-07-27 17:07:44 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
2014-04-08 17:57:09 +08:00
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
result['success'] = True
|
|
|
|
msg_url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
|
|
|
|
msg = _(u'Successfully copied %(name)s <a href="%(url)s">view</a>') % \
|
|
|
|
{"name":obj_name, "url":msg_url}
|
|
|
|
result['msg'] = msg
|
|
|
|
|
|
|
|
if res.background:
|
|
|
|
result['task_id'] = res.task_id
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
@copy_move_common
|
|
|
|
def mv_dir(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
2013-07-30 11:10:45 +08:00
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
src_dir = os.path.join(src_path, obj_name)
|
|
|
|
if dst_path.startswith(src_dir):
|
|
|
|
error_msg = _(u'Can not move directory %(src)s to its subdirectory %(des)s') \
|
|
|
|
% {'src': src_dir, 'des': dst_path}
|
|
|
|
result['error'] = error_msg
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
|
|
|
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
|
|
|
|
try:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = seafile_api.move_file(src_repo_id, src_path, obj_name,
|
|
|
|
dst_repo_id, dst_path, new_obj_name, username, need_progress=1)
|
2013-07-27 17:07:44 +08:00
|
|
|
except SearpcError, e:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = None
|
|
|
|
|
|
|
|
# res can be None or an object
|
|
|
|
if not res:
|
|
|
|
result['error'] = _(u'Internal server error')
|
2013-07-27 17:07:44 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
2014-04-08 17:57:09 +08:00
|
|
|
content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
2014-04-08 17:57:09 +08:00
|
|
|
result['success'] = True
|
|
|
|
msg_url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
|
|
|
|
msg = _(u'Successfully moved %(name)s <a href="%(url)s">view</a>') % \
|
|
|
|
{"name":obj_name, "url":msg_url}
|
|
|
|
result['msg'] = msg
|
|
|
|
if res.background:
|
|
|
|
result['task_id'] = res.task_id
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
@login_required
|
|
|
|
@copy_move_common
|
|
|
|
def cp_dir(src_repo_id, src_path, dst_repo_id, dst_path, obj_name, username):
|
2013-07-30 11:10:45 +08:00
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
src_dir = os.path.join(src_path, obj_name)
|
|
|
|
if dst_path.startswith(src_dir):
|
|
|
|
error_msg = _(u'Can not copy directory %(src)s to its subdirectory %(des)s') \
|
|
|
|
% {'src': src_dir, 'des': dst_path}
|
|
|
|
result['error'] = error_msg
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
|
|
|
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
|
|
|
|
try:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = seafile_api.copy_file(src_repo_id, src_path, obj_name,
|
|
|
|
dst_repo_id, dst_path, new_obj_name, username, need_progress=1)
|
2013-07-27 17:07:44 +08:00
|
|
|
except SearpcError, e:
|
2014-04-08 17:57:09 +08:00
|
|
|
res = None
|
|
|
|
|
|
|
|
# res can be None or an object
|
|
|
|
if not res:
|
|
|
|
result['error'] = _(u'Internal server error')
|
2013-07-27 17:07:44 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
2014-04-08 17:57:09 +08:00
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
result['success'] = True
|
|
|
|
msg_url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
|
|
|
|
msg = _(u'Successfully copied %(name)s <a href="%(url)s">view</a>') % \
|
|
|
|
{"name":obj_name, "url":msg_url}
|
|
|
|
result['msg'] = msg
|
|
|
|
if res.background:
|
|
|
|
result['task_id'] = res.task_id
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
2013-08-30 13:46:56 +08:00
|
|
|
|
|
|
|
def dirents_copy_move_common(func):
|
|
|
|
"""
|
|
|
|
Decorator for common logic in copying/moving dirs/files.
|
|
|
|
"""
|
|
|
|
def _decorated(request, repo_id, *args, **kwargs):
|
|
|
|
|
|
|
|
if request.method != 'POST' or not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
result['error'] = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# permission checking
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(repo.id, request.user) != 'rw':
|
2013-08-30 13:46:56 +08:00
|
|
|
result['error'] = _('Permission denied')
|
|
|
|
return HttpResponse(json.dumps(result), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# arguments validation
|
|
|
|
parent_dir = request.GET.get('parent_dir')
|
|
|
|
obj_file_names = request.POST.getlist('file_names')
|
|
|
|
obj_dir_names = request.POST.getlist('dir_names')
|
|
|
|
dst_repo_id = request.POST.get('dst_repo')
|
|
|
|
dst_path = request.POST.get('dst_path')
|
|
|
|
|
|
|
|
if not (parent_dir and dst_repo_id and dst_path) and not (obj_file_names or obj_dir_names):
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# check file path
|
|
|
|
for obj_name in obj_file_names + obj_dir_names:
|
|
|
|
if len(dst_path+obj_name) > settings.MAX_PATH:
|
|
|
|
result['error'] = _('Destination path is too long for %s.') % obj_name
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# check whether user has write permission to dest repo
|
2013-12-17 12:14:58 +08:00
|
|
|
if check_repo_access_permission(dst_repo_id, request.user) != 'rw':
|
2013-08-30 13:46:56 +08:00
|
|
|
result['error'] = _('Permission denied')
|
|
|
|
return HttpResponse(json.dumps(result), status=403,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
# when dst is the same as src
|
|
|
|
if repo_id == dst_repo_id and parent_dir == dst_path:
|
|
|
|
result['error'] = _('Invalid destination path')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
|
|
|
|
|
|
|
return func(repo_id, parent_dir, dst_repo_id, dst_path, obj_file_names, obj_dir_names, username)
|
|
|
|
return _decorated
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
@dirents_copy_move_common
|
|
|
|
def mv_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj_dir_names, username):
|
2013-11-07 17:14:16 +08:00
|
|
|
result = {}
|
2013-08-30 13:46:56 +08:00
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
for obj_name in obj_dir_names:
|
|
|
|
src_dir = os.path.join(src_path, obj_name)
|
|
|
|
if dst_path.startswith(src_dir):
|
|
|
|
error_msg = _(u'Can not move directory %(src)s to its subdirectory %(des)s') \
|
|
|
|
% {'src': src_dir, 'des': dst_path}
|
|
|
|
result['error'] = error_msg
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
|
|
|
|
|
|
|
success = []
|
|
|
|
failed = []
|
|
|
|
url = None
|
2014-04-09 16:33:18 +08:00
|
|
|
task_ids = []
|
2013-08-30 13:46:56 +08:00
|
|
|
for obj_name in obj_file_names + obj_dir_names:
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
try:
|
2014-04-09 16:33:18 +08:00
|
|
|
res = seafile_api.move_file(src_repo_id, src_path, obj_name,
|
2014-04-08 17:57:09 +08:00
|
|
|
dst_repo_id, dst_path, new_obj_name, username, need_progress=1)
|
2013-08-30 13:46:56 +08:00
|
|
|
except SearpcError, e:
|
2014-04-09 16:33:18 +08:00
|
|
|
res = None
|
|
|
|
|
|
|
|
if not res:
|
2013-08-30 13:46:56 +08:00
|
|
|
failed.append(obj_name)
|
2014-04-09 16:33:18 +08:00
|
|
|
else:
|
|
|
|
success.append(obj_name)
|
|
|
|
if res.background:
|
|
|
|
task_ids.append(res.task_id)
|
2013-08-30 13:46:56 +08:00
|
|
|
|
|
|
|
if len(success) > 0:
|
|
|
|
url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
|
2014-04-09 16:33:18 +08:00
|
|
|
|
|
|
|
result = {'success': success, 'failed': failed, 'url': url, 'task_ids': task_ids}
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-08-30 13:46:56 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
@dirents_copy_move_common
|
|
|
|
def cp_dirents(src_repo_id, src_path, dst_repo_id, dst_path, obj_file_names, obj_dir_names, username):
|
2013-11-07 17:14:16 +08:00
|
|
|
result = {}
|
2013-08-30 13:46:56 +08:00
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
for obj_name in obj_dir_names:
|
|
|
|
src_dir = os.path.join(src_path, obj_name)
|
|
|
|
if dst_path.startswith(src_dir):
|
|
|
|
error_msg = _(u'Can not copy directory %(src)s to its subdirectory %(des)s') \
|
|
|
|
% {'src': src_dir, 'des': dst_path}
|
|
|
|
result['error'] = error_msg
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
|
|
|
|
|
|
|
success = []
|
|
|
|
failed = []
|
|
|
|
url = None
|
2014-04-09 16:33:18 +08:00
|
|
|
task_ids = []
|
2013-08-30 13:46:56 +08:00
|
|
|
for obj_name in obj_file_names + obj_dir_names:
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
try:
|
2014-04-09 16:33:18 +08:00
|
|
|
res = seafile_api.copy_file(src_repo_id, src_path, obj_name,
|
2014-04-08 17:57:09 +08:00
|
|
|
dst_repo_id, dst_path, new_obj_name, username, need_progress=1)
|
2013-08-30 13:46:56 +08:00
|
|
|
except SearpcError, e:
|
2014-04-09 16:33:18 +08:00
|
|
|
res = None
|
|
|
|
|
|
|
|
if not res:
|
2013-08-30 13:46:56 +08:00
|
|
|
failed.append(obj_name)
|
2014-04-09 16:33:18 +08:00
|
|
|
else:
|
|
|
|
success.append(obj_name)
|
|
|
|
if res.background:
|
|
|
|
task_ids.append(res.task_id)
|
2013-08-30 13:46:56 +08:00
|
|
|
|
|
|
|
if len(success) > 0:
|
|
|
|
url = reverse('repo', args=[dst_repo_id]) + '?p=' + urlquote(dst_path)
|
2014-04-09 16:33:18 +08:00
|
|
|
|
|
|
|
result = {'success': success, 'failed': failed, 'url': url, 'task_ids': task_ids}
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-08-30 13:46:56 +08:00
|
|
|
|
2014-04-08 17:57:09 +08:00
|
|
|
@login_required
|
|
|
|
def get_cp_progress(request):
|
|
|
|
'''
|
|
|
|
Fetch progress of file/dir mv/cp.
|
|
|
|
'''
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
task_id = request.GET.get('task_id')
|
|
|
|
if not task_id:
|
|
|
|
result['error'] = _(u'Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
res = seafile_api.get_copy_task(task_id)
|
|
|
|
|
|
|
|
# res can be None
|
|
|
|
if not res:
|
|
|
|
result['error'] = _(u'Error')
|
|
|
|
return HttpResponse(json.dumps(result), status=500, content_type=content_type)
|
|
|
|
|
|
|
|
result['done'] = res.done
|
|
|
|
result['total'] = res.total
|
|
|
|
result['canceled'] = res.canceled
|
|
|
|
result['failed'] = res.failed
|
|
|
|
result['successful'] = res.successful
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
2014-04-09 16:33:18 +08:00
|
|
|
@login_required
|
|
|
|
def get_multi_cp_progress(request):
|
|
|
|
'''
|
|
|
|
Fetch progress of multi files/dirs mv/cp.
|
|
|
|
'''
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
task_ids = request.GET.getlist('task_ids')
|
|
|
|
if not task_ids:
|
|
|
|
result['error'] = _(u'Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
success = 0
|
|
|
|
fail = 0
|
|
|
|
for task_id in task_ids:
|
|
|
|
res = seafile_api.get_copy_task(task_id)
|
|
|
|
if not res:
|
|
|
|
fail += 1
|
|
|
|
else:
|
|
|
|
if res.failed:
|
|
|
|
fail += 1
|
|
|
|
elif res.successful:
|
|
|
|
success += 1
|
|
|
|
|
|
|
|
result['success'] = success
|
|
|
|
result['fail'] = fail
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
2014-04-08 17:57:09 +08:00
|
|
|
@login_required
|
|
|
|
def cancel_cp(request):
|
|
|
|
'''
|
|
|
|
cancel file/dir mv/cp.
|
|
|
|
'''
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
task_id = request.GET.get('task_id')
|
|
|
|
if not task_id:
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
res = seafile_api.cancel_copy_task(task_id) # returns 0 or -1
|
|
|
|
|
|
|
|
if res == 0:
|
|
|
|
result['success'] = True
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
else:
|
|
|
|
result['error'] = _('Failed')
|
|
|
|
return HttpResponse(json.dumps(result), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
2013-07-27 17:07:44 +08:00
|
|
|
@login_required
|
|
|
|
def repo_star_file(request, repo_id):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
path = request.GET.get('file', '')
|
|
|
|
if not path:
|
|
|
|
return HttpResponse(json.dumps({'error': _(u'Invalid arguments')}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
is_dir = False
|
|
|
|
star_file(request.user.username, repo_id, path, is_dir)
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success':True}), content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def repo_unstar_file(request, repo_id):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
path = request.GET.get('file', '')
|
|
|
|
if not path:
|
|
|
|
return HttpResponse(json.dumps({'error': _(u'Invalid arguments')}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
unstar_file(request.user.username, repo_id, path)
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success':True}), content_type=content_type)
|
|
|
|
|
|
|
|
########## contacts related
|
|
|
|
@login_required
|
2014-03-12 13:51:32 +08:00
|
|
|
def get_contacts(request):
|
2013-07-27 17:07:44 +08:00
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
username = request.user.username
|
|
|
|
contacts = Contact.objects.get_contacts_by_user(username)
|
|
|
|
contact_list = []
|
|
|
|
from seahub.avatar.templatetags.avatar_tags import avatar
|
|
|
|
for c in contacts:
|
|
|
|
contact_list.append({"email": c.contact_email, "avatar": avatar(c.contact_email, 16)})
|
|
|
|
|
2014-03-12 13:51:32 +08:00
|
|
|
return HttpResponse(json.dumps({"contacts":contact_list}), content_type=content_type)
|
2013-07-27 17:07:44 +08:00
|
|
|
|
2013-08-01 11:38:28 +08:00
|
|
|
@login_required
|
|
|
|
def get_current_commit(request, repo_id):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
err_msg = _(u'Library does not exist.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=400, content_type=content_type)
|
|
|
|
|
|
|
|
username = request.user.username
|
2013-12-17 12:14:58 +08:00
|
|
|
user_perm = check_repo_access_permission(repo.id, request.user)
|
2013-08-01 11:38:28 +08:00
|
|
|
if user_perm is None:
|
|
|
|
err_msg = _(u'Permission denied.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
2013-11-05 15:17:21 +08:00
|
|
|
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
|
|
|
|
|
2013-10-14 19:42:04 +08:00
|
|
|
if repo.encrypted and \
|
2013-11-05 15:17:21 +08:00
|
|
|
(repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
|
2013-10-14 19:42:04 +08:00
|
|
|
and not seafile_api.is_password_set(repo.id, username):
|
2013-08-01 11:38:28 +08:00
|
|
|
err_msg = _(u'Library is encrypted.')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=403, content_type=content_type)
|
|
|
|
|
2014-03-11 19:59:08 +08:00
|
|
|
head_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id)
|
2013-08-01 11:38:28 +08:00
|
|
|
if not head_commit:
|
|
|
|
err_msg = _(u'Error: no head commit id')
|
|
|
|
return HttpResponse(json.dumps({'error': err_msg}),
|
|
|
|
status=500, content_type=content_type)
|
2014-03-24 17:41:08 +08:00
|
|
|
|
2014-02-17 16:10:46 +08:00
|
|
|
if new_merge_with_no_conflict(head_commit):
|
2014-03-24 17:41:08 +08:00
|
|
|
info_commit = get_commit_before_new_merge(head_commit)
|
|
|
|
else:
|
|
|
|
info_commit = head_commit
|
2013-08-01 11:38:28 +08:00
|
|
|
|
|
|
|
ctx = {
|
|
|
|
'repo': repo,
|
2014-03-24 17:41:08 +08:00
|
|
|
'info_commit': info_commit
|
2013-08-01 11:38:28 +08:00
|
|
|
}
|
|
|
|
html = render_to_string('snippets/current_commit.html', ctx,
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
return HttpResponse(json.dumps({'html': html}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
2013-08-12 15:28:55 +08:00
|
|
|
@login_required
|
2013-09-16 14:12:15 +08:00
|
|
|
def sub_repo(request, repo_id):
|
2013-08-12 15:28:55 +08:00
|
|
|
'''
|
|
|
|
check if a dir has a corresponding sub_repo
|
2013-09-13 17:57:39 +08:00
|
|
|
if it does not have, create one
|
2013-08-12 15:28:55 +08:00
|
|
|
'''
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
path = request.GET.get('p')
|
2014-04-11 16:12:48 +08:00
|
|
|
if not path:
|
2013-08-12 15:28:55 +08:00
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=content_type)
|
2014-04-11 16:12:48 +08:00
|
|
|
name = os.path.basename(path)
|
2013-08-12 15:28:55 +08:00
|
|
|
|
2013-09-16 14:12:15 +08:00
|
|
|
username = request.user.username
|
2013-09-13 17:57:39 +08:00
|
|
|
|
|
|
|
# check if the sub-lib exist
|
2013-08-12 15:28:55 +08:00
|
|
|
try:
|
2014-05-28 16:05:15 +08:00
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
sub_repo = seaserv.seafserv_threaded_rpc.get_org_virtual_repo(
|
|
|
|
org_id, repo_id, path, username)
|
|
|
|
else:
|
|
|
|
sub_repo = seafile_api.get_virtual_repo(repo_id, path, username)
|
|
|
|
except SearpcError as e:
|
2013-08-12 15:28:55 +08:00
|
|
|
result['error'] = e.msg
|
2013-09-13 17:57:39 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=500, content_type=content_type)
|
2013-08-12 15:28:55 +08:00
|
|
|
|
|
|
|
if sub_repo:
|
|
|
|
result['sub_repo_id'] = sub_repo.id
|
|
|
|
else:
|
2013-09-13 17:57:39 +08:00
|
|
|
# create a sub-lib
|
|
|
|
try:
|
|
|
|
# use name as 'repo_name' & 'repo_desc' for sub_repo
|
2014-05-28 16:05:15 +08:00
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
sub_repo_id = seaserv.seafserv_threaded_rpc.create_org_virtual_repo(
|
|
|
|
org_id, repo_id, path, name, name, username)
|
|
|
|
else:
|
|
|
|
sub_repo_id = seafile_api.create_virtual_repo(repo_id, path,
|
|
|
|
name, name,
|
|
|
|
username)
|
2013-09-13 17:57:39 +08:00
|
|
|
result['sub_repo_id'] = sub_repo_id
|
|
|
|
except SearpcError, e:
|
|
|
|
result['error'] = e.msg
|
|
|
|
return HttpResponse(json.dumps(result), status=500, content_type=content_type)
|
2013-08-12 15:28:55 +08:00
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-10-14 19:42:04 +08:00
|
|
|
|
|
|
|
def download_enc_file(request, repo_id, file_id):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
op = 'downloadblks'
|
|
|
|
blklist = []
|
|
|
|
|
|
|
|
if file_id == EMPTY_SHA1:
|
|
|
|
result = { 'blklist':blklist, 'url':None, }
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
|
|
|
try:
|
2014-03-11 19:59:08 +08:00
|
|
|
blks = seafile_api.list_file_by_file_id(repo_id, file_id)
|
2013-10-14 19:42:04 +08:00
|
|
|
except SearpcError, e:
|
|
|
|
result['error'] = _(u'Failed to get file block list')
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
|
|
|
blklist = blks.split('\n')
|
|
|
|
blklist = [i for i in blklist if len(i) == 40]
|
|
|
|
token = seafserv_rpc.web_get_access_token(repo_id, file_id,
|
|
|
|
op, request.user.username)
|
|
|
|
url = gen_block_get_url(token, None)
|
|
|
|
result = {
|
|
|
|
'blklist':blklist,
|
|
|
|
'url':url,
|
|
|
|
}
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2013-11-18 10:56:10 +08:00
|
|
|
|
|
|
|
def upload_file_done(request):
|
|
|
|
"""Send a message when a file is uploaded.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
ct = 'application/json; charset=utf-8'
|
|
|
|
result = {}
|
|
|
|
|
|
|
|
filename = request.GET.get('fn', '')
|
|
|
|
if not filename:
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=ct)
|
|
|
|
repo_id = request.GET.get('repo_id', '')
|
|
|
|
if not repo_id:
|
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=ct)
|
|
|
|
path = request.GET.get('p', '')
|
2014-05-30 17:55:03 +08:00
|
|
|
if not path:
|
2013-11-18 10:56:10 +08:00
|
|
|
result['error'] = _('Argument missing')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=ct)
|
|
|
|
|
|
|
|
# a few checkings
|
|
|
|
if not seafile_api.get_repo(repo_id):
|
|
|
|
result['error'] = _('Wrong repo id')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=ct)
|
|
|
|
|
|
|
|
owner = seafile_api.get_repo_owner(repo_id)
|
2014-05-30 17:55:03 +08:00
|
|
|
if not owner: # this is an org repo, get org repo owner
|
|
|
|
owner = seafile_api.get_org_repo_owner(repo_id)
|
2013-11-18 10:56:10 +08:00
|
|
|
|
|
|
|
file_path = path.rstrip('/') + '/' + filename
|
|
|
|
if seafile_api.get_file_id_by_path(repo_id, file_path) is None:
|
|
|
|
result['error'] = _('File does not exist')
|
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=ct)
|
|
|
|
|
|
|
|
# send singal
|
|
|
|
upload_file_successful.send(sender=None,
|
|
|
|
repo_id=repo_id,
|
|
|
|
file_path=file_path,
|
|
|
|
owner=owner)
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success': True}), content_type=ct)
|
2013-11-19 16:35:31 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
def unseen_notices_count(request):
|
|
|
|
"""Count user's unseen notices.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
username = request.user.username
|
|
|
|
|
|
|
|
count = UserNotification.objects.count_unseen_user_notifications(username)
|
|
|
|
result = {}
|
|
|
|
result['count'] = count
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2014-03-05 14:10:05 +08:00
|
|
|
|
2014-06-03 10:14:53 +08:00
|
|
|
@login_required
|
|
|
|
def get_popup_notices(request):
|
|
|
|
"""Get user's unseen notices:
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
username = request.user.username
|
|
|
|
|
|
|
|
count = UserNotification.objects.count_unseen_user_notifications(username)
|
|
|
|
result_notices = []
|
|
|
|
unseen_notices = []
|
|
|
|
seen_notices = []
|
|
|
|
list_num = 5
|
|
|
|
|
|
|
|
if count == 0:
|
|
|
|
seen_notices = UserNotification.objects.filter(to_user = username)[:list_num]
|
|
|
|
elif count > list_num:
|
|
|
|
unseen_notices = UserNotification.objects.filter(to_user = username, seen = False)
|
|
|
|
else:
|
|
|
|
unseen_notices = UserNotification.objects.filter(to_user = username, seen = False)
|
|
|
|
seen_notices = UserNotification.objects.filter(
|
|
|
|
to_user = username,
|
|
|
|
seen = True)[:list_num-count]
|
|
|
|
|
|
|
|
result_notices += unseen_notices
|
|
|
|
result_notices += seen_notices
|
|
|
|
|
|
|
|
for notice in result_notices:
|
|
|
|
if notice.is_user_message():
|
|
|
|
d = notice.user_message_detail_to_dict()
|
|
|
|
notice.msg_from = d.get('msg_from')
|
|
|
|
continue
|
|
|
|
|
|
|
|
elif notice.is_group_msg():
|
|
|
|
d = json.loads(notice.detail)
|
|
|
|
notice.msg_from = d['msg_from']
|
|
|
|
continue
|
|
|
|
|
|
|
|
elif notice.is_grpmsg_reply():
|
|
|
|
d = json.loads(notice.detail)
|
|
|
|
notice.msg_from = d['reply_from']
|
|
|
|
continue
|
|
|
|
|
|
|
|
elif notice.is_file_uploaded_msg():
|
|
|
|
d = json.loads(notice.detail)
|
|
|
|
notice.default_avatar_url = get_default_avatar_url()
|
|
|
|
continue
|
|
|
|
|
|
|
|
elif notice.is_repo_share_msg():
|
|
|
|
d = json.loads(notice.detail)
|
|
|
|
notice.msg_from = d['share_from']
|
|
|
|
continue
|
|
|
|
|
|
|
|
elif notice.is_priv_file_share_msg():
|
|
|
|
d = json.loads(notice.detail)
|
|
|
|
notice.msg_from = d['share_from']
|
|
|
|
continue
|
|
|
|
|
|
|
|
elif notice.is_group_join_request():
|
|
|
|
d = json.loads(notice.detail)
|
|
|
|
notice.msg_from = d['username']
|
|
|
|
continue
|
|
|
|
|
|
|
|
else:
|
|
|
|
pass
|
|
|
|
|
|
|
|
ctx_notices = {"notices": result_notices}
|
|
|
|
|
|
|
|
notifications_popup_html = render_to_string(
|
|
|
|
'snippets/notifications_popup.html', ctx_notices,
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({"notifications_popup_html": notifications_popup_html}),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def set_notices_seen(request):
|
|
|
|
"""Set user's notices seen:
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
username = request.user.username
|
|
|
|
|
|
|
|
unseen_notices = UserNotification.objects.filter(to_user = username, seen = False)
|
|
|
|
for notice in unseen_notices:
|
|
|
|
notice.seen = True
|
|
|
|
notice.save()
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success': True}), content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def set_notice_seen_by_id(request):
|
|
|
|
"""
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
notice_id = request.GET.get('notice_id')
|
|
|
|
|
|
|
|
notice = UserNotification.objects.get(id=notice_id)
|
|
|
|
if notice.seen == False:
|
|
|
|
notice.seen = True
|
|
|
|
notice.save()
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({'success': True}), content_type=content_type)
|
|
|
|
|
2013-11-21 11:23:43 +08:00
|
|
|
@login_required
|
|
|
|
def repo_remove(request, repo_id):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
2014-03-05 14:10:05 +08:00
|
|
|
ct = 'application/json; charset=utf-8'
|
2013-11-21 11:23:43 +08:00
|
|
|
result = {}
|
|
|
|
|
2014-01-21 16:30:07 +08:00
|
|
|
if get_system_default_repo_id() == repo_id:
|
|
|
|
result['error'] = _(u'System library can not be deleted.')
|
2014-05-07 17:52:34 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=403, content_type=ct)
|
2014-01-21 16:30:07 +08:00
|
|
|
|
2013-11-21 11:23:43 +08:00
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
result['error'] = _(u'Library does not exist')
|
2014-03-05 14:10:05 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=400, content_type=ct)
|
2013-11-21 11:23:43 +08:00
|
|
|
|
2014-03-05 14:10:05 +08:00
|
|
|
username = request.user.username
|
|
|
|
if is_org_context(request):
|
2013-11-21 11:23:43 +08:00
|
|
|
# Remove repo in org context, only repo owner or org staff can
|
|
|
|
# perform this operation.
|
2014-03-05 14:10:05 +08:00
|
|
|
org_id = request.user.org.org_id
|
|
|
|
is_org_staff = request.user.org.is_staff
|
|
|
|
org_repo_owner = seafile_api.get_org_repo_owner(repo_id)
|
|
|
|
if request.user.is_staff or is_org_staff or org_repo_owner == username:
|
2013-11-21 11:23:43 +08:00
|
|
|
# Must get related useres before remove the repo
|
2014-03-05 14:10:05 +08:00
|
|
|
usernames = get_related_users_by_org_repo(org_id, repo_id)
|
2013-11-21 11:23:43 +08:00
|
|
|
seafile_api.remove_repo(repo_id)
|
|
|
|
repo_deleted.send(sender=None,
|
2014-03-05 14:10:05 +08:00
|
|
|
org_id=org_id,
|
2013-11-21 11:23:43 +08:00
|
|
|
usernames=usernames,
|
2014-03-05 14:10:05 +08:00
|
|
|
repo_owner=username,
|
2013-11-21 11:23:43 +08:00
|
|
|
repo_id=repo_id,
|
|
|
|
repo_name=repo.name,
|
2014-03-05 14:10:05 +08:00
|
|
|
)
|
2013-11-21 11:23:43 +08:00
|
|
|
result['success'] = True
|
2014-03-05 14:10:05 +08:00
|
|
|
return HttpResponse(json.dumps(result), content_type=ct)
|
2013-11-21 11:23:43 +08:00
|
|
|
else:
|
|
|
|
result['error'] = _(u'Permission denied.')
|
2014-03-05 14:10:05 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=403, content_type=ct)
|
2013-11-21 11:23:43 +08:00
|
|
|
else:
|
|
|
|
# Remove repo in personal context, only repo owner or site staff can
|
|
|
|
# perform this operation.
|
|
|
|
if validate_owner(request, repo_id) or request.user.is_staff:
|
|
|
|
usernames = get_related_users_by_repo(repo_id)
|
|
|
|
seafile_api.remove_repo(repo_id)
|
|
|
|
repo_deleted.send(sender=None,
|
|
|
|
org_id=-1,
|
|
|
|
usernames=usernames,
|
2014-03-05 14:10:05 +08:00
|
|
|
repo_owner=username,
|
2013-11-21 11:23:43 +08:00
|
|
|
repo_id=repo_id,
|
|
|
|
repo_name=repo.name,
|
|
|
|
)
|
|
|
|
result['success'] = True
|
2014-03-05 14:10:05 +08:00
|
|
|
return HttpResponse(json.dumps(result), content_type=ct)
|
2013-11-21 11:23:43 +08:00
|
|
|
else:
|
|
|
|
result['error'] = _(u'Permission denied.')
|
2014-03-05 14:10:05 +08:00
|
|
|
return HttpResponse(json.dumps(result), status=403, content_type=ct)
|
2013-12-10 12:14:12 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
def space_and_traffic(request):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
username = request.user.username
|
|
|
|
|
|
|
|
quota = seafserv_threaded_rpc.get_user_quota(username)
|
|
|
|
quota_usage = 0
|
|
|
|
share_usage = 0
|
|
|
|
my_usage = get_user_quota_usage(username)
|
|
|
|
rates = {}
|
|
|
|
if CALC_SHARE_USAGE:
|
|
|
|
share_usage = get_user_share_usage(username)
|
|
|
|
quota_usage = my_usage + share_usage
|
|
|
|
if quota > 0:
|
|
|
|
rates['my_usage'] = str(float(my_usage)/quota * 100) + '%'
|
|
|
|
rates['share_usage'] = str(float(share_usage)/quota * 100) + '%'
|
|
|
|
else:
|
|
|
|
quota_usage = my_usage
|
|
|
|
if quota > 0:
|
|
|
|
rates['quota_usage'] = str(float(my_usage)/quota * 100) + '%'
|
|
|
|
|
|
|
|
traffic_stat = 0
|
|
|
|
if TRAFFIC_STATS_ENABLED:
|
|
|
|
# User's network traffic stat in this month
|
|
|
|
try:
|
|
|
|
stat = get_user_traffic_stat(username)
|
|
|
|
except Exception as e:
|
|
|
|
logger.error(e)
|
|
|
|
stat = None
|
|
|
|
|
|
|
|
if stat:
|
|
|
|
traffic_stat = stat['file_view'] + stat['file_download'] + stat['dir_download']
|
|
|
|
|
2014-03-07 14:35:25 +08:00
|
|
|
payment_url = ''
|
|
|
|
ENABLE_PAYMENT = getattr(settings, 'ENABLE_PAYMENT', False)
|
|
|
|
if ENABLE_PAYMENT:
|
|
|
|
if is_org_context(request):
|
|
|
|
if request.user.org and bool(request.user.org.is_staff) is True:
|
|
|
|
# payment for org admin
|
|
|
|
payment_url = reverse('org_plan')
|
|
|
|
else:
|
|
|
|
# no payment for org members
|
|
|
|
ENABLE_PAYMENT = False
|
|
|
|
else:
|
|
|
|
# payment for personal account
|
|
|
|
payment_url = reverse('plan')
|
|
|
|
|
2013-12-10 12:14:12 +08:00
|
|
|
ctx = {
|
|
|
|
"CALC_SHARE_USAGE": CALC_SHARE_USAGE,
|
|
|
|
"quota": quota,
|
|
|
|
"quota_usage": quota_usage,
|
|
|
|
"share_usage": share_usage,
|
|
|
|
"my_usage": my_usage,
|
|
|
|
"rates": rates,
|
|
|
|
"TRAFFIC_STATS_ENABLED": TRAFFIC_STATS_ENABLED,
|
|
|
|
"traffic_stat": traffic_stat,
|
2014-03-07 14:35:25 +08:00
|
|
|
"ENABLE_PAYMENT": ENABLE_PAYMENT,
|
|
|
|
"payment_url": payment_url,
|
2013-12-10 12:14:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
html = render_to_string('snippets/space_and_traffic.html', ctx,
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
return HttpResponse(json.dumps({"html": html}), content_type=content_type)
|
2014-03-03 13:39:25 +08:00
|
|
|
|
2014-05-28 16:05:15 +08:00
|
|
|
def get_share_in_repo_list(request, start, limit):
|
|
|
|
"""List share in repos.
|
|
|
|
"""
|
|
|
|
username = request.user.username
|
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
repo_list = seafile_api.get_org_share_in_repo_list(org_id, username,
|
|
|
|
-1, -1)
|
|
|
|
else:
|
|
|
|
repo_list = seafile_api.get_share_in_repo_list(username, -1, -1)
|
|
|
|
|
|
|
|
for repo in repo_list:
|
|
|
|
repo.user_perm = seafile_api.check_repo_access_permission(repo.repo_id,
|
|
|
|
username)
|
|
|
|
return repo_list
|
|
|
|
|
|
|
|
def get_groups_by_user(request):
|
|
|
|
"""List user groups.
|
|
|
|
"""
|
|
|
|
username = request.user.username
|
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
return seaserv.get_org_groups_by_user(org_id, username)
|
|
|
|
else:
|
|
|
|
return seaserv.get_personal_groups_by_user(username)
|
|
|
|
|
|
|
|
def get_group_repos(request, groups):
|
|
|
|
"""Get repos shared to groups.
|
|
|
|
"""
|
|
|
|
username = request.user.username
|
|
|
|
group_repos = []
|
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
# For each group I joined...
|
|
|
|
for grp in groups:
|
|
|
|
# Get group repos, and for each group repos...
|
|
|
|
for r_id in seafile_api.get_org_group_repoids(org_id, grp.id):
|
|
|
|
# No need to list my own repo
|
|
|
|
repo_owner = seafile_api.get_org_repo_owner(r_id)
|
|
|
|
if repo_owner == username:
|
|
|
|
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
|
|
|
|
r.last_modified = get_repo_last_modify(r)
|
|
|
|
r.share_type = 'group'
|
|
|
|
r.user = repo_owner
|
|
|
|
r.user_perm = seafile_api.check_repo_access_permission(
|
|
|
|
r_id, username)
|
|
|
|
r.group = grp
|
|
|
|
group_repos.append(r)
|
|
|
|
else:
|
|
|
|
# For each group I joined...
|
|
|
|
for grp in groups:
|
|
|
|
# Get group repos, and for each group repos...
|
|
|
|
for r_id in seafile_api.get_group_repoids(grp.id):
|
|
|
|
# No need to list my own repo
|
|
|
|
repo_owner = seafile_api.get_repo_owner(r_id)
|
|
|
|
if repo_owner == username:
|
|
|
|
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
|
|
|
|
r.last_modified = get_repo_last_modify(r)
|
|
|
|
r.share_type = 'group'
|
|
|
|
r.user = repo_owner
|
|
|
|
r.user_perm = seafile_api.check_repo_access_permission(
|
|
|
|
r_id, username)
|
|
|
|
r.group = grp
|
|
|
|
group_repos.append(r)
|
|
|
|
return group_repos
|
|
|
|
|
2014-03-03 13:39:25 +08:00
|
|
|
@login_required
|
2014-03-10 12:16:21 +08:00
|
|
|
def my_shared_and_group_repos(request):
|
|
|
|
"""Return html snippet of repos that shared to user and group repos.
|
2014-05-28 16:05:15 +08:00
|
|
|
|
2014-03-03 13:39:25 +08:00
|
|
|
Arguments:
|
|
|
|
- `request`:
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
2014-03-10 12:16:21 +08:00
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
2014-05-28 16:05:15 +08:00
|
|
|
# shared
|
|
|
|
shared_repos = get_share_in_repo_list(request, -1, -1)
|
2014-03-03 13:39:25 +08:00
|
|
|
shared_repos.sort(lambda x, y: cmp(y.last_modified, x.last_modified))
|
2014-03-03 13:39:25 +08:00
|
|
|
|
2014-05-28 16:05:15 +08:00
|
|
|
# group repos
|
|
|
|
joined_groups = get_groups_by_user(request)
|
|
|
|
group_repos = get_group_repos(request, joined_groups)
|
2014-03-03 13:39:25 +08:00
|
|
|
group_repos.sort(key=lambda x: x.group.group_name)
|
|
|
|
for i, repo in enumerate(group_repos):
|
|
|
|
if i == 0:
|
|
|
|
repo.show_group_name = True
|
|
|
|
else:
|
|
|
|
if repo.group.group_name != group_repos[i-1].group.group_name:
|
|
|
|
repo.show_group_name = True
|
|
|
|
|
2014-06-10 15:55:43 +08:00
|
|
|
ctx_shared = {"shared_repos": shared_repos}
|
|
|
|
ctx_group = {"group_repos": group_repos}
|
|
|
|
shared_repos_html = render_to_string(
|
|
|
|
'snippets/my_shared_repos.html', ctx_shared,
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
group_repos_html = render_to_string(
|
|
|
|
'snippets/my_group_repos.html', ctx_group,
|
|
|
|
context_instance=RequestContext(request))
|
2014-05-12 11:59:49 +08:00
|
|
|
|
|
|
|
return_shared_repos = True if shared_repos else False
|
|
|
|
|
|
|
|
ret = {
|
|
|
|
"shared": {
|
|
|
|
"html": shared_repos_html,
|
|
|
|
"return_shared_repos": return_shared_repos
|
|
|
|
},
|
|
|
|
"group": group_repos_html
|
|
|
|
}
|
|
|
|
return HttpResponse(json.dumps(ret), content_type=content_type)
|
2014-03-19 14:42:18 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
def get_file_op_url(request, repo_id):
|
|
|
|
"""Get file upload/update url for AJAX.
|
|
|
|
"""
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
op_type = request.GET.get('op_type') # value can be 'upload', 'update', 'upload-blks', 'update-blks'
|
|
|
|
if not op_type:
|
|
|
|
err_msg = _(u'Argument missing')
|
|
|
|
return HttpResponse(json.dumps({"error": err_msg}), status=400,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
username = request.user.username
|
|
|
|
url = ''
|
|
|
|
if check_repo_access_permission(repo_id, request.user) == 'rw':
|
|
|
|
token = seafile_api.get_httpserver_access_token(repo_id, 'dummy',
|
|
|
|
op_type, username)
|
|
|
|
url = gen_file_upload_url(token, op_type + '-aj')
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps({"url": url}), content_type=content_type)
|
2014-04-28 17:18:41 +08:00
|
|
|
|
|
|
|
@login_required
|
|
|
|
def repo_history_changes(request, repo_id):
|
|
|
|
if not request.is_ajax():
|
|
|
|
return Http404
|
|
|
|
|
|
|
|
changes = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
if not access_to_repo(request, repo_id, ''):
|
|
|
|
return HttpResponse(json.dumps(changes), content_type=content_type)
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
if not repo:
|
|
|
|
return HttpResponse(json.dumps(changes), content_type=content_type)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
if repo.encrypted and \
|
|
|
|
(repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \
|
|
|
|
and not is_passwd_set(repo_id, username):
|
|
|
|
return HttpResponse(json.dumps(changes), content_type=content_type)
|
|
|
|
|
|
|
|
commit_id = request.GET.get('commit_id', '')
|
|
|
|
if not commit_id:
|
|
|
|
return HttpResponse(json.dumps(changes), content_type=content_type)
|
|
|
|
|
|
|
|
changes = get_diff(repo_id, '', commit_id)
|
|
|
|
|
|
|
|
c = get_commit(repo.id, repo.version, commit_id)
|
|
|
|
if c.parent_id is None:
|
|
|
|
# A commit is a first commit only if it's parent id is None.
|
|
|
|
changes['cmt_desc'] = repo.desc
|
|
|
|
elif c.second_parent_id is None:
|
|
|
|
# Normal commit only has one parent.
|
|
|
|
if c.desc.startswith('Changed library'):
|
|
|
|
changes['cmt_desc'] = _('Changed library name or description')
|
|
|
|
else:
|
|
|
|
# A commit is a merge only if it has two parents.
|
|
|
|
changes['cmt_desc'] = _('No conflict in the merge.')
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(changes), content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def repo_create(request):
|
|
|
|
'''
|
|
|
|
Handle ajax post to create a library.
|
|
|
|
|
|
|
|
'''
|
|
|
|
if not request.is_ajax() or request.method != 'POST':
|
|
|
|
return Http404
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
form = RepoCreateForm(request.POST)
|
|
|
|
if not form.is_valid():
|
|
|
|
result['error'] = str(form.errors.values()[0])
|
|
|
|
return HttpResponseBadRequest(json.dumps(result),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
repo_name = form.cleaned_data['repo_name']
|
|
|
|
repo_desc = form.cleaned_data['repo_desc']
|
|
|
|
encryption = int(form.cleaned_data['encryption'])
|
|
|
|
|
|
|
|
uuid = form.cleaned_data['uuid']
|
|
|
|
magic_str = form.cleaned_data['magic_str']
|
|
|
|
encrypted_file_key = form.cleaned_data['encrypted_file_key']
|
|
|
|
|
|
|
|
username = request.user.username
|
2014-05-21 12:07:03 +08:00
|
|
|
org_id = -1
|
|
|
|
try:
|
2014-04-28 17:18:41 +08:00
|
|
|
if not encryption:
|
2014-05-21 12:07:03 +08:00
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
repo_id = seafile_api.create_org_repo(repo_name, repo_desc,
|
|
|
|
username, None, org_id)
|
|
|
|
else:
|
|
|
|
repo_id = seafile_api.create_repo(repo_name, repo_desc,
|
|
|
|
username, None)
|
2014-04-28 17:18:41 +08:00
|
|
|
else:
|
2014-05-21 12:07:03 +08:00
|
|
|
if is_org_context(request):
|
|
|
|
org_id = request.user.org.org_id
|
|
|
|
repo_id = seafile_api.create_org_enc_repo(
|
|
|
|
uuid, repo_name, repo_desc, username, magic_str,
|
|
|
|
encrypted_file_key, enc_version=2, org_id=org_id)
|
|
|
|
else:
|
|
|
|
repo_id = seafile_api.create_enc_repo(
|
|
|
|
uuid, repo_name, repo_desc, username,
|
|
|
|
magic_str, encrypted_file_key, enc_version=2)
|
|
|
|
except SearpcError as e:
|
|
|
|
logger.error(e)
|
2014-04-28 17:18:41 +08:00
|
|
|
repo_id = None
|
|
|
|
|
|
|
|
if not repo_id:
|
|
|
|
result['error'] = _(u"Internal Server Error")
|
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
|
|
|
content_type=content_type)
|
2014-05-07 17:25:22 +08:00
|
|
|
|
2014-04-28 17:18:41 +08:00
|
|
|
try:
|
|
|
|
default_lib = (int(request.GET.get('default_lib', 0)) == 1)
|
|
|
|
except ValueError:
|
|
|
|
default_lib = False
|
|
|
|
if default_lib:
|
|
|
|
UserOptions.objects.set_default_repo(username, repo_id)
|
|
|
|
|
|
|
|
result = {
|
|
|
|
'repo_id': repo_id,
|
|
|
|
'repo_name': repo_name,
|
|
|
|
'repo_desc': repo_desc,
|
|
|
|
'repo_enc': encryption,
|
|
|
|
}
|
|
|
|
repo_created.send(sender=None,
|
2014-05-21 12:07:03 +08:00
|
|
|
org_id=org_id,
|
2014-04-28 17:18:41 +08:00
|
|
|
creator=username,
|
|
|
|
repo_id=repo_id,
|
|
|
|
repo_name=repo_name)
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def public_repo_create(request):
|
|
|
|
'''
|
|
|
|
Handle ajax post to create public repo.
|
|
|
|
|
|
|
|
'''
|
|
|
|
if not request.is_ajax() or request.method != 'POST':
|
|
|
|
return Http404
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
form = SharedRepoCreateForm(request.POST)
|
|
|
|
if not form.is_valid():
|
|
|
|
result['error'] = str(form.errors.values()[0])
|
|
|
|
return HttpResponseBadRequest(json.dumps(result),
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
repo_name = form.cleaned_data['repo_name']
|
|
|
|
repo_desc = form.cleaned_data['repo_desc']
|
|
|
|
permission = form.cleaned_data['permission']
|
|
|
|
encryption = int(form.cleaned_data['encryption'])
|
|
|
|
|
|
|
|
uuid = form.cleaned_data['uuid']
|
|
|
|
magic_str = form.cleaned_data['magic_str']
|
|
|
|
encrypted_file_key = form.cleaned_data['encrypted_file_key']
|
|
|
|
|
|
|
|
user = request.user.username
|
|
|
|
|
|
|
|
try:
|
|
|
|
if not encryption:
|
|
|
|
repo_id = seafile_api.create_repo(repo_name, repo_desc, user, None)
|
|
|
|
else:
|
|
|
|
repo_id = seafile_api.create_enc_repo(uuid, repo_name, repo_desc, user, magic_str, encrypted_file_key, enc_version=2)
|
|
|
|
|
|
|
|
# set this repo as inner pub
|
|
|
|
seafile_api.add_inner_pub_repo(repo_id, permission)
|
|
|
|
#seafserv_threaded_rpc.set_inner_pub_repo(repo_id, permission)
|
|
|
|
except SearpcError as e:
|
|
|
|
repo_id = None
|
|
|
|
logger.error(e)
|
|
|
|
|
|
|
|
if not repo_id:
|
|
|
|
result['error'] = _(u'Internal Server Error')
|
|
|
|
return HttpResponse(json.dumps(result), status=500,
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
result['success'] = True
|
|
|
|
repo_created.send(sender=None,
|
|
|
|
org_id=-1,
|
|
|
|
creator=user,
|
|
|
|
repo_id=repo_id,
|
|
|
|
repo_name=repo_name)
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
def events(request):
|
|
|
|
if not request.is_ajax():
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
events_count = 15
|
|
|
|
username = request.user.username
|
|
|
|
start = int(request.GET.get('start'))
|
|
|
|
|
2014-05-07 17:52:34 +08:00
|
|
|
# if request.cloud_mode:
|
|
|
|
# org_id = request.GET.get('org_id')
|
|
|
|
# events, start = get_org_user_events(org_id, username, start, events_count)
|
|
|
|
# else:
|
|
|
|
# events, start = get_user_events(username, start, events_count)
|
|
|
|
events, start = get_user_events(username, start, events_count)
|
2014-04-28 17:18:41 +08:00
|
|
|
events_more = True if len(events) == events_count else False
|
|
|
|
|
|
|
|
event_groups = group_events_data(events)
|
|
|
|
ctx = {'event_groups': event_groups}
|
|
|
|
html = render_to_string("snippets/events_body.html", ctx)
|
|
|
|
|
2014-05-07 17:25:22 +08:00
|
|
|
return HttpResponse(json.dumps({'html': html,
|
|
|
|
'events_more': events_more,
|
2014-04-28 17:18:41 +08:00
|
|
|
'new_start': start}),
|
2014-05-07 17:25:22 +08:00
|
|
|
content_type='application/json; charset=utf-8')
|