2012-04-27 05:43:17 +00:00
|
|
|
|
# encoding: utf-8
|
2012-05-20 12:32:21 +00:00
|
|
|
|
import settings
|
2012-07-02 02:21:17 +00:00
|
|
|
|
import os
|
2012-05-20 12:32:21 +00:00
|
|
|
|
import stat
|
2012-05-30 06:11:33 +00:00
|
|
|
|
import simplejson as json
|
2012-07-02 14:45:21 +00:00
|
|
|
|
import re
|
2012-06-20 11:39:21 +00:00
|
|
|
|
import sys
|
2012-07-02 14:45:21 +00:00
|
|
|
|
import urllib2
|
2012-05-20 12:32:21 +00:00
|
|
|
|
from urllib import quote
|
|
|
|
|
from django.core.urlresolvers import reverse
|
2012-06-20 11:39:21 +00:00
|
|
|
|
from django.core.mail import send_mail
|
2012-06-12 02:13:14 +00:00
|
|
|
|
from django.contrib import messages
|
2012-06-20 11:39:21 +00:00
|
|
|
|
from django.contrib.sites.models import Site, RequestSite
|
2012-05-20 12:32:21 +00:00
|
|
|
|
from django.db import IntegrityError
|
2012-07-13 03:22:20 +00:00
|
|
|
|
from django.db.models import F
|
2012-04-11 11:48:20 +00:00
|
|
|
|
from django.http import HttpResponse, HttpResponseRedirect, Http404
|
2012-04-20 05:34:52 +00:00
|
|
|
|
from django.shortcuts import render_to_response, redirect
|
2012-06-20 11:39:21 +00:00
|
|
|
|
from django.template import Context, loader, RequestContext
|
2012-04-01 13:55:33 +00:00
|
|
|
|
from django.views.decorators.csrf import csrf_protect
|
2012-05-20 12:32:21 +00:00
|
|
|
|
|
2012-07-02 02:21:17 +00:00
|
|
|
|
from django.core.cache import cache
|
|
|
|
|
from django.http import HttpResponse, HttpResponseServerError
|
|
|
|
|
|
2012-05-20 12:32:21 +00:00
|
|
|
|
from auth.decorators import login_required
|
2012-05-15 02:59:16 +00:00
|
|
|
|
from auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, \
|
|
|
|
|
PasswordChangeForm
|
2012-04-20 05:34:52 +00:00
|
|
|
|
from auth.tokens import default_token_generator
|
2012-07-11 14:39:36 +00:00
|
|
|
|
from share.models import FileShare
|
2012-06-25 12:42:19 +00:00
|
|
|
|
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_groups, get_users, get_repos, \
|
2012-01-29 05:05:35 +00:00
|
|
|
|
get_repo, get_commits, get_branches, \
|
2012-05-15 02:59:16 +00:00
|
|
|
|
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \
|
2012-05-26 07:31:35 +00:00
|
|
|
|
get_group_repoids, check_group_staff
|
2012-05-20 12:32:21 +00:00
|
|
|
|
from pysearpc import SearpcError
|
2011-09-10 12:07:46 +00:00
|
|
|
|
|
2012-04-11 11:48:20 +00:00
|
|
|
|
from seahub.base.accounts import CcnetUser
|
2012-05-07 08:33:36 +00:00
|
|
|
|
from seahub.contacts.models import Contact
|
2012-06-25 13:40:18 +00:00
|
|
|
|
from seahub.notifications.models import UserNotification
|
2012-07-11 14:39:36 +00:00
|
|
|
|
from forms import AddUserForm, FileLinkShareForm
|
2012-05-20 12:32:21 +00:00
|
|
|
|
from utils import go_permission_error, go_error, list_to_string, \
|
2012-06-28 08:58:09 +00:00
|
|
|
|
get_httpserver_root, get_ccnetapplet_root, gen_token, \
|
2012-07-02 14:45:21 +00:00
|
|
|
|
calculate_repo_last_modify, valid_previewed_file, \
|
2012-07-13 09:19:44 +00:00
|
|
|
|
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1, \
|
|
|
|
|
get_file_revision_id_size
|
2012-06-20 06:18:23 +00:00
|
|
|
|
from seahub.profile.models import Profile
|
2012-07-02 14:45:21 +00:00
|
|
|
|
from settings import FILE_PREVIEW_MAX_SIZE
|
2012-07-02 02:21:17 +00:00
|
|
|
|
|
2012-01-31 16:07:10 +00:00
|
|
|
|
@login_required
|
2011-03-19 05:15:02 +00:00
|
|
|
|
def root(request):
|
2012-01-31 16:07:10 +00:00
|
|
|
|
return HttpResponseRedirect(reverse(myhome))
|
2011-04-30 05:18:32 +00:00
|
|
|
|
|
2011-03-19 14:06:58 +00:00
|
|
|
|
def peers(request):
|
|
|
|
|
peer_type = request.REQUEST.get('type', 'all')
|
|
|
|
|
peer_ids = ccnet_rpc.list_peers()
|
|
|
|
|
peers = []
|
|
|
|
|
for peer_id in peer_ids.split("\n"):
|
|
|
|
|
# too handle the ending '\n'
|
|
|
|
|
if peer_id == '':
|
|
|
|
|
continue
|
|
|
|
|
peer = ccnet_rpc.get_peer(peer_id)
|
|
|
|
|
if peer_type == 'all':
|
|
|
|
|
peers.append(peer)
|
|
|
|
|
if peer_type == 'mypeer':
|
|
|
|
|
if peer.props.role_list.find('MyPeer') != -1:
|
|
|
|
|
peers.append(peer)
|
|
|
|
|
|
2011-04-11 15:06:05 +00:00
|
|
|
|
users = get_users()
|
2011-03-19 14:06:58 +00:00
|
|
|
|
return render_to_response('peers.html', {
|
|
|
|
|
'peers': peers,
|
2011-04-11 15:06:05 +00:00
|
|
|
|
'users': users,
|
2011-03-19 14:06:58 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
2011-03-20 13:47:28 +00:00
|
|
|
|
|
2012-04-02 15:56:41 +00:00
|
|
|
|
def validate_owner(request, repo_id):
|
2012-06-12 02:13:14 +00:00
|
|
|
|
"""
|
|
|
|
|
Check whether email in the request own the repo
|
|
|
|
|
|
|
|
|
|
"""
|
2012-07-09 02:37:42 +00:00
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_threaded_rpc.is_repo_owner(request.user.username,
|
|
|
|
|
repo_id)
|
|
|
|
|
except:
|
|
|
|
|
ret = 0
|
|
|
|
|
|
2012-07-09 06:23:46 +00:00
|
|
|
|
if ret == 0 or ret is None:
|
2012-07-09 02:37:42 +00:00
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
2012-05-02 12:58:06 +00:00
|
|
|
|
|
2012-06-12 02:13:14 +00:00
|
|
|
|
def validate_emailuser(emailuser):
|
|
|
|
|
"""
|
|
|
|
|
check whether emailuser is in the database
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
try:
|
2012-06-25 12:42:19 +00:00
|
|
|
|
user = ccnet_threaded_rpc.get_emailuser(emailuser)
|
2012-06-12 02:13:14 +00:00
|
|
|
|
except:
|
|
|
|
|
user = None
|
|
|
|
|
|
|
|
|
|
if user:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
2012-04-25 12:48:56 +00:00
|
|
|
|
def check_shared_repo(request, repo_id):
|
2012-05-15 02:59:16 +00:00
|
|
|
|
"""
|
2012-06-12 02:13:14 +00:00
|
|
|
|
Check whether user has been shared this repo or
|
|
|
|
|
the repo share to the groups user join or
|
|
|
|
|
got token if user is not logged in
|
2012-04-25 12:48:56 +00:00
|
|
|
|
|
2012-05-15 02:59:16 +00:00
|
|
|
|
"""
|
2012-07-09 02:37:42 +00:00
|
|
|
|
# Not logged-in user
|
2012-06-12 02:13:14 +00:00
|
|
|
|
if not request.user.is_authenticated():
|
|
|
|
|
token = request.COOKIES.get('anontoken', None)
|
|
|
|
|
if token:
|
|
|
|
|
return True
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
|
2012-07-09 02:37:42 +00:00
|
|
|
|
# Logged-in user
|
2012-05-15 02:59:16 +00:00
|
|
|
|
repos = seafserv_threaded_rpc.list_share_repos(request.user.username, 'to_email', -1, -1)
|
2012-04-25 12:48:56 +00:00
|
|
|
|
for repo in repos:
|
2012-05-15 02:59:16 +00:00
|
|
|
|
if repo.props.id == repo_id:
|
|
|
|
|
return True
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
groups = ccnet_threaded_rpc.get_groups(request.user.username)
|
2012-05-15 02:59:16 +00:00
|
|
|
|
# for every group that user joined...
|
|
|
|
|
for group in groups:
|
|
|
|
|
# ...get repo ids in that group, and check whether repo ids contains that repo id
|
|
|
|
|
repo_ids = get_group_repoids(group.props.id)
|
2012-06-12 02:13:14 +00:00
|
|
|
|
if repo_id in repo_ids:
|
2012-04-25 12:48:56 +00:00
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
|
2012-05-22 07:28:24 +00:00
|
|
|
|
def access_to_repo(request, repo_id, repo_ap):
|
|
|
|
|
"""
|
|
|
|
|
Check whether user in the request can access to repo, which means user can
|
2012-07-09 02:37:42 +00:00
|
|
|
|
view directory entries on repo page. Only repo owner or person who is shared
|
|
|
|
|
can access to repo.
|
2012-05-22 07:28:24 +00:00
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
if repo_ap == 'own' and not validate_owner(request, repo_id) \
|
2012-07-09 02:37:42 +00:00
|
|
|
|
and not check_shared_repo(request, repo_id):
|
2012-05-22 07:28:24 +00:00
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def gen_path_link(path, repo_name):
|
|
|
|
|
"""
|
2012-07-03 13:48:33 +00:00
|
|
|
|
Generate navigate paths and links in repo page.
|
2012-05-22 07:28:24 +00:00
|
|
|
|
|
|
|
|
|
"""
|
2012-07-11 14:39:36 +00:00
|
|
|
|
if path and path[-1] != '/':
|
2012-07-11 09:47:08 +00:00
|
|
|
|
path += '/'
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
2012-05-22 07:28:24 +00:00
|
|
|
|
paths = []
|
|
|
|
|
links = []
|
|
|
|
|
if path and path != '/':
|
|
|
|
|
paths = path[1:-1].split('/')
|
|
|
|
|
i=1
|
|
|
|
|
for name in paths:
|
|
|
|
|
link = '/' + '/'.join(paths[:i])
|
|
|
|
|
i = i + 1
|
|
|
|
|
links.append(link)
|
|
|
|
|
paths.insert(0, repo_name)
|
|
|
|
|
links.insert(0, '/')
|
|
|
|
|
|
|
|
|
|
zipped = zip(paths, links)
|
|
|
|
|
|
|
|
|
|
return zipped
|
|
|
|
|
|
2012-05-24 09:43:26 +00:00
|
|
|
|
def render_repo(request, repo_id, error=''):
|
2012-05-05 11:52:36 +00:00
|
|
|
|
# get repo web access property, if no repo access property in db, then
|
|
|
|
|
# assume repo ap is 'own'
|
2012-07-09 02:37:42 +00:00
|
|
|
|
# repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
|
|
|
|
# if not repo_ap:
|
|
|
|
|
# repo_ap = 'own'
|
2012-04-25 12:48:56 +00:00
|
|
|
|
|
2012-07-09 02:37:42 +00:00
|
|
|
|
# Since repo web access property is removed since 0.9.4, we assume all repo
|
|
|
|
|
# is 'own' for compatibility
|
|
|
|
|
repo_ap = 'own'
|
|
|
|
|
|
|
|
|
|
# Check whether user can view repo page
|
|
|
|
|
can_access = access_to_repo(request, repo_id, repo_ap)
|
|
|
|
|
if not can_access:
|
|
|
|
|
return go_permission_error(request, '无法访问该同步目录')
|
2012-06-12 02:13:14 +00:00
|
|
|
|
|
2012-07-09 02:37:42 +00:00
|
|
|
|
# Check whether use is repo owner
|
2012-06-12 02:13:14 +00:00
|
|
|
|
if validate_owner(request, repo_id):
|
|
|
|
|
is_owner = True
|
|
|
|
|
else:
|
|
|
|
|
is_owner = False
|
|
|
|
|
|
2011-09-07 02:57:47 +00:00
|
|
|
|
repo = get_repo(repo_id)
|
2012-05-22 07:28:24 +00:00
|
|
|
|
if not repo:
|
2012-05-30 14:42:21 +00:00
|
|
|
|
return go_error(request, u'该同步目录不存在')
|
2012-04-24 08:15:29 +00:00
|
|
|
|
|
2012-06-12 02:13:14 +00:00
|
|
|
|
# query whether set password if repo is encrypted
|
2012-05-24 09:43:26 +00:00
|
|
|
|
password_set = False
|
|
|
|
|
if repo.props.encrypted:
|
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
|
|
|
|
|
if ret == 1:
|
|
|
|
|
password_set = True
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
|
2012-07-03 13:48:33 +00:00
|
|
|
|
# view newest worktree or history worktree
|
2012-07-05 11:29:56 +00:00
|
|
|
|
commit_id = request.GET.get('commit_id', '')
|
|
|
|
|
view_history = True if commit_id else False
|
2012-07-13 09:19:44 +00:00
|
|
|
|
current_commit = seafserv_threaded_rpc.get_commit(commit_id)
|
2012-07-03 13:48:33 +00:00
|
|
|
|
if not current_commit:
|
|
|
|
|
current_commit = get_commits(repo_id, 0, 1)[0]
|
|
|
|
|
|
2012-06-12 02:13:14 +00:00
|
|
|
|
# query repo infomation
|
2012-05-05 11:52:36 +00:00
|
|
|
|
repo_size = seafserv_threaded_rpc.server_repo_size(repo_id)
|
2012-04-24 08:15:29 +00:00
|
|
|
|
|
2012-06-12 02:13:14 +00:00
|
|
|
|
# get repo dirents
|
2012-05-04 13:36:36 +00:00
|
|
|
|
dirs = []
|
2012-05-17 14:43:47 +00:00
|
|
|
|
path = ''
|
|
|
|
|
zipped = []
|
2012-05-19 13:01:21 +00:00
|
|
|
|
dir_list = []
|
|
|
|
|
file_list = []
|
2012-05-24 09:43:26 +00:00
|
|
|
|
if not repo.props.encrypted or password_set:
|
2012-05-18 03:40:39 +00:00
|
|
|
|
path = request.GET.get('p', '/')
|
|
|
|
|
if path[-1] != '/':
|
|
|
|
|
path = path + '/'
|
2012-05-17 14:43:47 +00:00
|
|
|
|
|
2012-07-03 13:48:33 +00:00
|
|
|
|
if current_commit.root_id == EMPTY_SHA1:
|
2012-05-30 14:42:21 +00:00
|
|
|
|
dirs = []
|
|
|
|
|
else:
|
|
|
|
|
try:
|
2012-07-13 09:19:44 +00:00
|
|
|
|
dirs = seafserv_threaded_rpc.list_dir_by_path(current_commit.id,
|
2012-05-30 14:42:21 +00:00
|
|
|
|
path.encode('utf-8'))
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
for dirent in dirs:
|
|
|
|
|
if stat.S_ISDIR(dirent.props.mode):
|
|
|
|
|
dir_list.append(dirent)
|
|
|
|
|
else:
|
|
|
|
|
file_list.append(dirent)
|
|
|
|
|
try:
|
2012-07-13 09:19:44 +00:00
|
|
|
|
dirent.file_size = seafserv_threaded_rpc.get_file_size(dirent.obj_id)
|
2012-05-30 14:42:21 +00:00
|
|
|
|
except:
|
|
|
|
|
dirent.file_size = 0
|
|
|
|
|
dir_list.sort(lambda x, y : cmp(x.obj_name.lower(),
|
|
|
|
|
y.obj_name.lower()))
|
|
|
|
|
file_list.sort(lambda x, y : cmp(x.obj_name.lower(),
|
|
|
|
|
y.obj_name.lower()))
|
|
|
|
|
|
2012-07-05 06:39:28 +00:00
|
|
|
|
if request.user.is_authenticated() and not view_history:
|
|
|
|
|
try:
|
|
|
|
|
accessible_repos = get_accessible_repos(request, repo)
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
error_msg = e.msg
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
else:
|
|
|
|
|
accessible_repos = []
|
2012-07-02 02:21:17 +00:00
|
|
|
|
|
2012-05-30 14:42:21 +00:00
|
|
|
|
# generate path and link
|
|
|
|
|
zipped = gen_path_link(path, repo.name)
|
|
|
|
|
|
2012-04-24 08:15:29 +00:00
|
|
|
|
return render_to_response('repo.html', {
|
|
|
|
|
"repo": repo,
|
2012-06-12 02:13:14 +00:00
|
|
|
|
"can_access": can_access,
|
2012-07-03 13:48:33 +00:00
|
|
|
|
"current_commit": current_commit,
|
|
|
|
|
"view_history": view_history,
|
2012-04-24 08:15:29 +00:00
|
|
|
|
"is_owner": is_owner,
|
2012-05-24 09:43:26 +00:00
|
|
|
|
"password_set": password_set,
|
2012-04-24 08:15:29 +00:00
|
|
|
|
"repo_ap": repo_ap,
|
2012-04-28 11:47:38 +00:00
|
|
|
|
"repo_size": repo_size,
|
2012-05-19 13:01:21 +00:00
|
|
|
|
"dir_list": dir_list,
|
|
|
|
|
"file_list": file_list,
|
2012-05-17 14:43:47 +00:00
|
|
|
|
"path" : path,
|
2012-05-18 03:40:39 +00:00
|
|
|
|
"zipped" : zipped,
|
2012-05-24 09:43:26 +00:00
|
|
|
|
"error" : error,
|
2012-07-02 02:21:17 +00:00
|
|
|
|
"accessible_repos" : accessible_repos,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def repo_upload_file(request, repo_id):
|
|
|
|
|
repo = get_repo(repo_id)
|
2012-07-09 03:05:04 +00:00
|
|
|
|
total_space = settings.USER_TOTAL_SPACE
|
2012-07-02 02:21:17 +00:00
|
|
|
|
used_space = seafserv_threaded_rpc.get_user_quota_usage(request.user.username)
|
|
|
|
|
############ GET ############
|
|
|
|
|
if request.method == 'GET':
|
2012-07-11 09:47:08 +00:00
|
|
|
|
parent_dir = request.GET.get('p', '/')
|
2012-07-02 02:21:17 +00:00
|
|
|
|
zipped = gen_path_link (parent_dir, repo.name)
|
2012-07-11 09:47:08 +00:00
|
|
|
|
# TODO: per user quota, org user quota
|
2012-07-02 02:21:17 +00:00
|
|
|
|
return render_to_response ('repo_upload_file.html', {
|
|
|
|
|
"repo": repo,
|
|
|
|
|
"parent_dir": parent_dir,
|
|
|
|
|
"used_space": used_space,
|
|
|
|
|
"total_space": total_space,
|
|
|
|
|
"zipped": zipped,
|
2012-07-05 05:34:54 +00:00
|
|
|
|
"max_upload_file_size": settings.MAX_UPLOAD_FILE_SIZE,
|
2012-07-02 02:21:17 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
############ POST ############
|
|
|
|
|
parent_dir = request.POST.get('parent_dir', '/')
|
|
|
|
|
def render_upload_error(error_msg):
|
|
|
|
|
zipped = gen_path_link (parent_dir, repo.name)
|
|
|
|
|
return render_to_response ('repo_upload_file.html', {
|
|
|
|
|
"error_msg": error_msg,
|
|
|
|
|
"repo": repo,
|
|
|
|
|
"used_space": used_space,
|
|
|
|
|
"total_space": total_space,
|
|
|
|
|
"zipped": zipped,
|
|
|
|
|
"parent_dir": parent_dir,
|
2012-07-05 05:34:54 +00:00
|
|
|
|
"max_upload_file_size": settings.MAX_UPLOAD_FILE_SIZE,
|
2012-04-24 08:15:29 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
2012-07-02 02:21:17 +00:00
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
tmp_file = request.FILES['file']
|
|
|
|
|
except:
|
|
|
|
|
error_msg = u'请选择一个文件'
|
|
|
|
|
return render_upload_error(error_msg)
|
|
|
|
|
|
|
|
|
|
tmp_file_path = tmp_file.temporary_file_path()
|
|
|
|
|
if not os.access(tmp_file_path, os.F_OK):
|
|
|
|
|
error_msg = u'上传文件失败'
|
|
|
|
|
return render_upload_error(error_msg)
|
2012-04-24 08:15:29 +00:00
|
|
|
|
|
2012-07-05 05:34:54 +00:00
|
|
|
|
def remove_tmp_file():
|
|
|
|
|
try:
|
|
|
|
|
os.remove(tmp_file.temporary_file_path())
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
2012-07-02 02:21:17 +00:00
|
|
|
|
# rename the file if there is name conflicts
|
|
|
|
|
filename = check_filename_with_rename(repo_id, parent_dir, tmp_file.name)
|
|
|
|
|
if len(filename) > settings.MAX_UPLOAD_FILE_NAME_LEN:
|
2012-07-05 05:34:54 +00:00
|
|
|
|
remove_tmp_file()
|
2012-07-02 02:21:17 +00:00
|
|
|
|
error_msg = u"您上传的文件名称太长"
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
if tmp_file.size > settings.MAX_UPLOAD_FILE_SIZE:
|
|
|
|
|
error_msg = u"您上传的文件太大"
|
2012-07-05 05:34:54 +00:00
|
|
|
|
remove_tmp_file()
|
2012-07-02 02:21:17 +00:00
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
try:
|
2012-07-11 09:47:08 +00:00
|
|
|
|
seafserv_threaded_rpc.post_file (repo_id, tmp_file_path, parent_dir,
|
|
|
|
|
filename, request.user.username);
|
2012-07-02 02:21:17 +00:00
|
|
|
|
except SearpcError, e:
|
2012-07-05 05:34:54 +00:00
|
|
|
|
remove_tmp_file()
|
2012-07-02 02:21:17 +00:00
|
|
|
|
error_msg = e.msg
|
|
|
|
|
return render_upload_error(error_msg)
|
2012-07-05 05:34:54 +00:00
|
|
|
|
else:
|
|
|
|
|
remove_tmp_file()
|
|
|
|
|
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
|
|
|
|
|
return HttpResponseRedirect(url)
|
2012-07-11 09:47:08 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def repo_update_file(request, repo_id):
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
|
total_space = settings.USER_TOTAL_SPACE
|
|
|
|
|
used_space = seafserv_threaded_rpc.get_user_quota_usage(request.user.username)
|
|
|
|
|
############ GET ############
|
|
|
|
|
if request.method == 'GET':
|
|
|
|
|
target_file = request.GET.get('p')
|
|
|
|
|
if not target_file:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
zipped = gen_path_link (target_file, repo.name)
|
|
|
|
|
# TODO: per user quota, org user quota
|
|
|
|
|
return render_to_response ('repo_update_file.html', {
|
|
|
|
|
"repo": repo,
|
|
|
|
|
"target_file": target_file,
|
|
|
|
|
"used_space": used_space,
|
|
|
|
|
"total_space": total_space,
|
|
|
|
|
"zipped": zipped,
|
|
|
|
|
"max_upload_file_size": settings.MAX_UPLOAD_FILE_SIZE,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
############ POST ############
|
|
|
|
|
target_file = request.POST.get('target_file')
|
|
|
|
|
if not target_file:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
def render_update_file_error(error_msg):
|
|
|
|
|
zipped = gen_path_link (target_file, repo.name)
|
|
|
|
|
return render_to_response ('repo_update.html', {
|
|
|
|
|
"error_msg": error_msg,
|
|
|
|
|
"repo": repo,
|
|
|
|
|
"used_space": used_space,
|
|
|
|
|
"total_space": total_space,
|
|
|
|
|
"zipped": zipped,
|
|
|
|
|
"target_file": target_file,
|
|
|
|
|
"max_upload_file_size": settings.MAX_UPLOAD_FILE_SIZE,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
tmp_file = request.FILES['file']
|
|
|
|
|
except:
|
|
|
|
|
error_msg = u'请选择一个文件'
|
|
|
|
|
return render_update_file_error(error_msg)
|
|
|
|
|
|
|
|
|
|
tmp_file_path = tmp_file.temporary_file_path()
|
|
|
|
|
if not os.access(tmp_file_path, os.F_OK):
|
|
|
|
|
error_msg = u'上传文件失败'
|
|
|
|
|
return render_update_file_error(error_msg)
|
|
|
|
|
|
|
|
|
|
def remove_tmp_file():
|
|
|
|
|
try:
|
|
|
|
|
os.remove(tmp_file.temporary_file_path())
|
|
|
|
|
except:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
if tmp_file.size > settings.MAX_UPLOAD_FILE_SIZE:
|
|
|
|
|
error_msg = u"您上传的文件太大"
|
|
|
|
|
remove_tmp_file()
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
parent_dir = os.path.dirname(target_file)
|
|
|
|
|
filename = os.path.basename(target_file)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
seafserv_threaded_rpc.put_file (repo_id, tmp_file_path, parent_dir,
|
|
|
|
|
filename, request.user.username);
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
remove_tmp_file()
|
|
|
|
|
error_msg = e.msg
|
|
|
|
|
return render_update_file_error(error_msg)
|
|
|
|
|
else:
|
|
|
|
|
remove_tmp_file()
|
|
|
|
|
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
|
|
|
|
|
return HttpResponseRedirect(url)
|
2012-07-02 02:21:17 +00:00
|
|
|
|
|
|
|
|
|
def get_subdir(request):
|
|
|
|
|
repo_id = request.GET.get('repo_id', '')
|
|
|
|
|
path = request.GET.get('path', '')
|
|
|
|
|
|
|
|
|
|
if not (repo_id and path):
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
latest_commit = get_commits(repo_id, 0, 1)[0]
|
|
|
|
|
try:
|
2012-07-13 09:19:44 +00:00
|
|
|
|
dirents = seafserv_threaded_rpc.list_dir_by_path(latest_commit.id, path.encode('utf-8'))
|
2012-07-02 02:21:17 +00:00
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
|
|
|
|
|
subdirs = []
|
|
|
|
|
for dirent in dirents:
|
|
|
|
|
if not stat.S_ISDIR(dirent.props.mode):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
dirent.has_subdir = False
|
|
|
|
|
path_ = os.path.join (path, dirent.obj_name)
|
|
|
|
|
try:
|
2012-07-13 09:19:44 +00:00
|
|
|
|
dirs_ = seafserv_threaded_rpc.list_dir_by_path(latest_commit.id, path_.encode('utf-8'))
|
2012-07-02 02:21:17 +00:00
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
|
|
|
|
|
for dirent_ in dirs_:
|
|
|
|
|
if stat.S_ISDIR(dirent_.props.mode):
|
|
|
|
|
dirent.has_subdir = True
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
if dirent.has_subdir:
|
|
|
|
|
subdir = {
|
|
|
|
|
'data': dirent.obj_name,
|
|
|
|
|
'attr': {'repo_id': repo_id },
|
|
|
|
|
'state': 'closed'
|
|
|
|
|
}
|
|
|
|
|
subdirs.append(subdir)
|
|
|
|
|
else:
|
|
|
|
|
subdirs.append(dirent.obj_name)
|
|
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
return HttpResponse(json.dumps(subdirs),
|
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
2012-05-24 09:43:26 +00:00
|
|
|
|
def repo(request, repo_id):
|
|
|
|
|
if request.method == 'GET':
|
|
|
|
|
return render_repo(request, repo_id)
|
|
|
|
|
elif request.method == 'POST':
|
|
|
|
|
password = request.POST.get('password', '')
|
|
|
|
|
if not password:
|
|
|
|
|
return render_repo(request, repo_id, u'密码不能为空')
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
seafserv_threaded_rpc.set_passwd(repo_id, request.user.username, password)
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
if e.msg == 'Bad arguments':
|
|
|
|
|
return go_error(request, u'url 格式不正确')
|
|
|
|
|
elif e.msg == 'Repo is not encrypted':
|
|
|
|
|
return render_repo(request, repo_id)
|
|
|
|
|
elif e.msg == 'Incorrect password':
|
|
|
|
|
return render_repo(request, repo_id, u'密码不正确,请重新输入')
|
|
|
|
|
elif e.msg == 'Internal server error':
|
|
|
|
|
return go_error(request, u'服务器内部故障')
|
|
|
|
|
else:
|
|
|
|
|
return go_error(request, u'未知错误')
|
|
|
|
|
|
|
|
|
|
return render_repo(request, repo_id)
|
2012-04-24 08:15:29 +00:00
|
|
|
|
|
2012-06-20 13:38:07 +00:00
|
|
|
|
@login_required
|
2012-04-24 08:15:29 +00:00
|
|
|
|
def repo_history(request, repo_id):
|
2012-05-28 14:35:45 +00:00
|
|
|
|
"""
|
2012-06-20 13:38:07 +00:00
|
|
|
|
View repo history
|
2012-05-28 14:35:45 +00:00
|
|
|
|
"""
|
|
|
|
|
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
|
|
|
|
if not repo_ap:
|
|
|
|
|
repo_ap = 'own'
|
|
|
|
|
|
|
|
|
|
if not access_to_repo(request, repo_id, repo_ap):
|
|
|
|
|
return go_permission_error(request, u'无法浏览该同步目录修改历史')
|
|
|
|
|
|
2012-04-24 08:15:29 +00:00
|
|
|
|
repo = get_repo(repo_id)
|
2012-05-24 09:43:26 +00:00
|
|
|
|
|
|
|
|
|
password_set = False
|
|
|
|
|
if repo.props.encrypted:
|
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
|
|
|
|
|
if ret == 1:
|
|
|
|
|
password_set = True
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
|
|
|
|
|
if repo.props.encrypted and not password_set:
|
2012-05-28 14:35:45 +00:00
|
|
|
|
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
|
2012-05-24 09:43:26 +00:00
|
|
|
|
|
2012-03-30 05:49:32 +00:00
|
|
|
|
try:
|
|
|
|
|
current_page = int(request.GET.get('page', '1'))
|
|
|
|
|
per_page= int(request.GET.get('per_page', '25'))
|
|
|
|
|
except ValueError:
|
2012-04-09 08:48:14 +00:00
|
|
|
|
current_page = 1
|
2012-03-30 05:49:32 +00:00
|
|
|
|
per_page = 25
|
|
|
|
|
|
2012-05-28 14:35:45 +00:00
|
|
|
|
commits_all = get_commits(repo_id, per_page * (current_page -1),
|
|
|
|
|
per_page + 1)
|
2012-03-30 05:49:32 +00:00
|
|
|
|
commits = commits_all[:per_page]
|
|
|
|
|
|
|
|
|
|
if len(commits_all) == per_page + 1:
|
|
|
|
|
page_next = True
|
|
|
|
|
else:
|
|
|
|
|
page_next = False
|
|
|
|
|
|
2012-05-29 03:04:03 +00:00
|
|
|
|
is_owner = False
|
|
|
|
|
if request.user.is_authenticated():
|
|
|
|
|
if validate_owner(request, repo_id):
|
|
|
|
|
is_owner = True
|
2012-03-30 05:49:32 +00:00
|
|
|
|
|
2012-04-24 08:15:29 +00:00
|
|
|
|
return render_to_response('repo_history.html', {
|
2011-09-07 02:57:47 +00:00
|
|
|
|
"repo": repo,
|
|
|
|
|
"commits": commits,
|
2012-03-30 05:49:32 +00:00
|
|
|
|
'current_page': current_page,
|
|
|
|
|
'prev_page': current_page-1,
|
|
|
|
|
'next_page': current_page+1,
|
|
|
|
|
'per_page': per_page,
|
|
|
|
|
'page_next': page_next,
|
2012-05-29 03:04:03 +00:00
|
|
|
|
'is_owner': is_owner,
|
2011-09-07 02:57:47 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
2012-05-25 09:07:08 +00:00
|
|
|
|
def repo_history_revert(request, repo_id):
|
2012-05-28 14:35:45 +00:00
|
|
|
|
"""
|
|
|
|
|
Only repo owner can revert repo.
|
|
|
|
|
"""
|
|
|
|
|
if not validate_owner(request, repo_id):
|
|
|
|
|
return go_permission_error(request, u'只有同步目录拥有者有权还原目录')
|
|
|
|
|
|
2012-05-25 09:07:08 +00:00
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
|
if not repo:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
password_set = False
|
|
|
|
|
if repo.props.encrypted:
|
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
|
|
|
|
|
if ret == 1:
|
|
|
|
|
password_set = True
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
|
|
|
|
|
if repo.props.encrypted and not password_set:
|
2012-05-28 14:35:45 +00:00
|
|
|
|
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
|
2012-05-25 09:07:08 +00:00
|
|
|
|
|
|
|
|
|
commit_id = request.GET.get('commit_id', '')
|
|
|
|
|
if not commit_id:
|
|
|
|
|
return go_error(request, u'请指定历史记录 ID')
|
|
|
|
|
|
|
|
|
|
res = request.user.username.split('@')
|
|
|
|
|
user_name = res[0]
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
seafserv_threaded_rpc.revert_on_server(repo_id, commit_id, user_name)
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
if e.msg == 'Bad arguments':
|
|
|
|
|
return go_error(request, u'非法参数')
|
|
|
|
|
elif e.msg == 'No such repo':
|
|
|
|
|
return go_error(request, u'同步目录不存在')
|
|
|
|
|
elif e.msg == "Commit doesn't exist":
|
|
|
|
|
return go_error(request, u'指定的历史记录不存在')
|
|
|
|
|
else:
|
|
|
|
|
return go_error(request, u'未知错误')
|
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(reverse(repo_history, args=[repo_id]))
|
2012-05-30 06:11:33 +00:00
|
|
|
|
|
|
|
|
|
def get_diff(repo_id, arg1, arg2):
|
2012-07-05 11:56:39 +00:00
|
|
|
|
lists = {'new' : [], 'removed' : [], 'renamed' : [], 'modified' : [], \
|
|
|
|
|
'newdir' : [], 'deldir' : []}
|
2012-05-30 06:11:33 +00:00
|
|
|
|
|
|
|
|
|
diff_result = seafserv_threaded_rpc.get_diff(repo_id, arg1, arg2)
|
2012-06-13 11:56:41 +00:00
|
|
|
|
if not diff_result:
|
|
|
|
|
return lists
|
|
|
|
|
|
|
|
|
|
for d in diff_result:
|
|
|
|
|
if d.status == "add":
|
|
|
|
|
lists['new'].append(d.name)
|
|
|
|
|
elif d.status == "del":
|
|
|
|
|
lists['removed'].append(d.name)
|
|
|
|
|
elif d.status == "mov":
|
|
|
|
|
lists['renamed'].append(d.name + " ==> " + d.new_name)
|
|
|
|
|
elif d.status == "mod":
|
|
|
|
|
lists['modified'].append(d.name)
|
2012-07-05 11:56:39 +00:00
|
|
|
|
elif d.status == "newdir":
|
|
|
|
|
lists['newdir'].append(d.name)
|
|
|
|
|
elif d.status == "deldir":
|
|
|
|
|
lists['deldir'].append(d.name)
|
2012-05-30 06:11:33 +00:00
|
|
|
|
|
|
|
|
|
return lists
|
|
|
|
|
|
|
|
|
|
def repo_history_changes(request, repo_id):
|
|
|
|
|
changes = {}
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
|
|
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
|
|
|
|
if repo_ap == None:
|
|
|
|
|
repo_ap = 'own'
|
|
|
|
|
|
|
|
|
|
if not access_to_repo(request, repo_id, repo_ap):
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
password_set = False
|
|
|
|
|
if repo.props.encrypted:
|
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
|
|
|
|
|
if ret == 1:
|
|
|
|
|
password_set = True
|
|
|
|
|
except:
|
|
|
|
|
return HttpResponse(json.dumps(changes),
|
|
|
|
|
content_type=content_type)
|
|
|
|
|
|
|
|
|
|
if repo.props.encrypted and not password_set:
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(changes),
|
|
|
|
|
content_type=content_type)
|
2012-05-22 07:28:24 +00:00
|
|
|
|
|
2011-10-18 07:41:48 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def modify_token(request, repo_id):
|
2012-04-02 15:56:41 +00:00
|
|
|
|
if not validate_owner(request, repo_id):
|
2012-05-28 14:35:45 +00:00
|
|
|
|
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
|
2011-10-18 07:41:48 +00:00
|
|
|
|
|
|
|
|
|
token = request.POST.get('token', '')
|
|
|
|
|
if token:
|
2012-02-27 07:24:27 +00:00
|
|
|
|
seafserv_threaded_rpc.set_repo_token(repo_id, token)
|
2011-10-18 07:41:48 +00:00
|
|
|
|
|
2012-05-28 14:35:45 +00:00
|
|
|
|
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
|
2011-11-01 14:21:01 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def remove_repo(request, repo_id):
|
2012-04-02 15:56:41 +00:00
|
|
|
|
if not validate_owner(request, repo_id) and not request.user.is_staff:
|
2012-05-28 14:35:45 +00:00
|
|
|
|
return go_permission_error(request, u'删除同步目录失败')
|
2012-05-15 02:59:16 +00:00
|
|
|
|
|
2012-02-27 07:24:27 +00:00
|
|
|
|
seafserv_threaded_rpc.remove_repo(repo_id)
|
2012-06-05 11:38:28 +00:00
|
|
|
|
next = request.GET.get('next', '/')
|
|
|
|
|
return HttpResponseRedirect(next)
|
2011-09-07 02:57:47 +00:00
|
|
|
|
|
2012-06-05 11:38:28 +00:00
|
|
|
|
#@login_required
|
|
|
|
|
#def remove_fetched_repo(request, user_id, repo_id):
|
|
|
|
|
# if user_id and repo_id:
|
|
|
|
|
# seafserv_threaded_rpc.remove_fetched_repo (user_id, repo_id)
|
|
|
|
|
#
|
|
|
|
|
# return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
2011-09-07 02:57:47 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def myhome(request):
|
2011-10-12 16:17:48 +00:00
|
|
|
|
owned_repos = []
|
2011-11-01 14:21:01 +00:00
|
|
|
|
quota_usage = 0
|
2012-04-27 05:43:17 +00:00
|
|
|
|
output_msg = {}
|
2012-04-02 15:56:41 +00:00
|
|
|
|
|
2012-05-02 12:58:06 +00:00
|
|
|
|
email = request.user.username
|
|
|
|
|
quota_usage = seafserv_threaded_rpc.get_user_quota_usage(email)
|
2012-06-28 08:58:09 +00:00
|
|
|
|
|
|
|
|
|
# Repos that I own
|
2012-05-02 12:58:06 +00:00
|
|
|
|
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
|
2012-06-28 08:58:09 +00:00
|
|
|
|
calculate_repo_last_modify(owned_repos)
|
2012-06-28 12:02:17 +00:00
|
|
|
|
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
|
2012-05-02 12:58:06 +00:00
|
|
|
|
|
2012-04-26 14:15:07 +00:00
|
|
|
|
# Repos that are share to me
|
2012-07-02 02:21:17 +00:00
|
|
|
|
in_repos = seafserv_threaded_rpc.list_share_repos(email,
|
2012-05-26 06:47:57 +00:00
|
|
|
|
'to_email', -1, -1)
|
2012-06-28 08:58:09 +00:00
|
|
|
|
calculate_repo_last_modify(in_repos)
|
2012-06-28 12:02:17 +00:00
|
|
|
|
in_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
|
2012-05-15 02:59:16 +00:00
|
|
|
|
|
|
|
|
|
# my contacts
|
2012-05-07 08:33:36 +00:00
|
|
|
|
contacts = Contact.objects.filter(user_email=email)
|
2012-06-25 13:40:18 +00:00
|
|
|
|
|
|
|
|
|
# user notifications
|
2012-06-27 08:39:49 +00:00
|
|
|
|
grpmsg_list = []
|
2012-06-28 11:24:27 +00:00
|
|
|
|
grpmsg_reply_list = []
|
2012-06-26 06:20:37 +00:00
|
|
|
|
notes = UserNotification.objects.filter(to_user=request.user.username)
|
2012-06-25 13:40:18 +00:00
|
|
|
|
for n in notes:
|
2012-06-26 06:20:37 +00:00
|
|
|
|
if n.msg_type == 'group_msg':
|
2012-06-27 08:39:49 +00:00
|
|
|
|
grpmsg_list.append(n.detail)
|
|
|
|
|
elif n.msg_type == 'grpmsg_reply':
|
2012-06-28 11:24:27 +00:00
|
|
|
|
grpmsg_reply_list.append(n.detail)
|
2012-06-25 13:40:18 +00:00
|
|
|
|
|
2012-05-16 13:33:35 +00:00
|
|
|
|
# my groups
|
2012-06-25 12:42:19 +00:00
|
|
|
|
groups = ccnet_threaded_rpc.get_groups(email)
|
2012-05-16 13:33:35 +00:00
|
|
|
|
groups_manage = []
|
|
|
|
|
groups_join = []
|
2012-05-15 03:23:28 +00:00
|
|
|
|
for group in groups:
|
2012-06-27 08:39:49 +00:00
|
|
|
|
if str(group.id) in grpmsg_list:
|
2012-06-25 13:40:18 +00:00
|
|
|
|
group.new_msg = True
|
|
|
|
|
else:
|
|
|
|
|
group.new_msg = False
|
2012-05-15 03:23:28 +00:00
|
|
|
|
if group.props.creator_name == request.user.username:
|
2012-05-16 13:33:35 +00:00
|
|
|
|
groups_manage.append(group)
|
2012-05-15 03:23:28 +00:00
|
|
|
|
else:
|
2012-05-16 13:33:35 +00:00
|
|
|
|
groups_join.append(group)
|
2012-06-20 06:18:23 +00:00
|
|
|
|
|
2012-06-21 12:53:13 +00:00
|
|
|
|
# get nickname
|
2012-06-20 06:18:23 +00:00
|
|
|
|
if not Profile.objects.filter(user=request.user.username):
|
2012-06-21 07:26:03 +00:00
|
|
|
|
nickname = ''
|
2012-06-20 06:18:23 +00:00
|
|
|
|
else:
|
|
|
|
|
profile = Profile.objects.filter(user=request.user.username)[0]
|
|
|
|
|
nickname = profile.nickname
|
2012-06-25 13:40:18 +00:00
|
|
|
|
|
2011-09-07 02:57:47 +00:00
|
|
|
|
return render_to_response('myhome.html', {
|
2012-06-20 06:18:23 +00:00
|
|
|
|
"myname": email,
|
|
|
|
|
"nickname": nickname,
|
2011-10-12 16:17:48 +00:00
|
|
|
|
"owned_repos": owned_repos,
|
2011-11-01 14:21:01 +00:00
|
|
|
|
"quota_usage": quota_usage,
|
2012-04-26 14:15:07 +00:00
|
|
|
|
"in_repos": in_repos,
|
2012-05-07 08:33:36 +00:00
|
|
|
|
"contacts": contacts,
|
2012-05-15 02:59:16 +00:00
|
|
|
|
"groups": groups,
|
2012-06-28 11:24:27 +00:00
|
|
|
|
"grpmsg_reply_list": grpmsg_reply_list,
|
2012-05-16 13:33:35 +00:00
|
|
|
|
"groups_manage": groups_manage,
|
|
|
|
|
"groups_join": groups_join,
|
2011-09-07 02:57:47 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
2012-03-20 06:06:35 +00:00
|
|
|
|
@login_required
|
2012-04-02 15:56:41 +00:00
|
|
|
|
def ownerhome(request, owner_name):
|
2012-03-20 06:06:35 +00:00
|
|
|
|
owned_repos = []
|
|
|
|
|
quota_usage = 0
|
|
|
|
|
|
2012-05-03 02:52:43 +00:00
|
|
|
|
owned_repos = seafserv_threaded_rpc.list_owned_repos(owner_name)
|
|
|
|
|
quota_usage = seafserv_threaded_rpc.get_user_quota_usage(owner_name)
|
2012-03-20 06:06:35 +00:00
|
|
|
|
|
2012-05-03 02:52:43 +00:00
|
|
|
|
user_dict = user_info(request, owner_name)
|
|
|
|
|
|
2012-03-23 03:25:13 +00:00
|
|
|
|
return render_to_response('ownerhome.html', {
|
2012-03-20 06:06:35 +00:00
|
|
|
|
"owned_repos": owned_repos,
|
|
|
|
|
"quota_usage": quota_usage,
|
2012-04-02 15:56:41 +00:00
|
|
|
|
"owner": owner_name,
|
2012-05-03 02:52:43 +00:00
|
|
|
|
"user_dict": user_dict,
|
2012-03-20 06:06:35 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
2012-03-29 07:36:15 +00:00
|
|
|
|
@login_required
|
2012-04-26 02:57:36 +00:00
|
|
|
|
def repo_set_access_property(request, repo_id):
|
2012-06-05 11:38:28 +00:00
|
|
|
|
ap = request.GET.get('ap', '')
|
|
|
|
|
seafserv_threaded_rpc.repo_set_access_property(repo_id, ap)
|
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
|
2012-04-20 05:34:52 +00:00
|
|
|
|
|
2012-07-02 02:21:17 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def repo_del_file(request, repo_id):
|
|
|
|
|
parent_dir = request.GET.get("p", "/")
|
|
|
|
|
file_name = request.GET.get("file_name")
|
|
|
|
|
user = request.user.username
|
|
|
|
|
try:
|
|
|
|
|
seafserv_threaded_rpc.del_file(repo_id, parent_dir,file_name, user)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
def repo_view_file(request, repo_id):
|
|
|
|
|
"""
|
|
|
|
|
Preview file on web, including files in current worktree and history.
|
|
|
|
|
"""
|
2012-07-02 14:45:21 +00:00
|
|
|
|
http_server_root = get_httpserver_root()
|
2012-07-11 14:39:36 +00:00
|
|
|
|
path = request.GET.get('p', '/')
|
2012-07-12 12:35:13 +00:00
|
|
|
|
if path[-1] == '/':
|
|
|
|
|
path = path[:-1]
|
2012-07-13 09:26:33 +00:00
|
|
|
|
u_filename = os.path.basename(path)
|
|
|
|
|
filename = urllib2.quote(u_filename.encode('utf-8'))
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
2012-07-05 11:29:56 +00:00
|
|
|
|
commit_id = request.GET.get('commit_id', '')
|
|
|
|
|
view_history = True if commit_id else False
|
2012-07-13 09:19:44 +00:00
|
|
|
|
current_commit = seafserv_threaded_rpc.get_commit(commit_id)
|
2012-07-05 11:29:56 +00:00
|
|
|
|
if not current_commit:
|
|
|
|
|
current_commit = get_commits(repo_id, 0, 1)[0]
|
2012-07-02 14:45:21 +00:00
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
if view_history:
|
|
|
|
|
obj_id = request.GET.get('obj_id', '')
|
|
|
|
|
else:
|
2012-07-02 14:45:21 +00:00
|
|
|
|
try:
|
2012-07-14 13:18:59 +00:00
|
|
|
|
obj_id = seafserv_threaded_rpc.get_file_by_path(repo_id, path)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
except:
|
|
|
|
|
obj_id = None
|
|
|
|
|
|
|
|
|
|
if not obj_id:
|
|
|
|
|
return go_error(request, '文件不存在')
|
2012-07-02 14:45:21 +00:00
|
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
|
if not repo:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
# if a repo is shared to me, then I can view and download file no mater whether
|
|
|
|
|
# repo's access property is 'own' or 'public'
|
|
|
|
|
if check_shared_repo(request, repo_id):
|
|
|
|
|
share_to_me = True
|
|
|
|
|
else:
|
|
|
|
|
share_to_me = False
|
|
|
|
|
|
|
|
|
|
token = ''
|
2012-07-11 14:39:36 +00:00
|
|
|
|
# people who is owner or this repo is shared to him, can visit the repo;
|
|
|
|
|
# others, just go to 404 page
|
|
|
|
|
if validate_owner(request, repo_id) or share_to_me:
|
|
|
|
|
# owner should get a token to visit repo
|
|
|
|
|
token = gen_token()
|
|
|
|
|
# put token into memory in seaf-server
|
|
|
|
|
seafserv_rpc.web_save_access_token(token, obj_id)
|
|
|
|
|
else:
|
|
|
|
|
raise Http404
|
2012-07-02 14:45:21 +00:00
|
|
|
|
|
|
|
|
|
# generate path and link
|
|
|
|
|
zipped = gen_path_link(path, repo.name)
|
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
# determin whether file can preview on web
|
2012-07-02 14:45:21 +00:00
|
|
|
|
can_preview, filetype = valid_previewed_file(filename)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
2012-07-02 14:45:21 +00:00
|
|
|
|
# raw path
|
|
|
|
|
tmp_str = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s'
|
|
|
|
|
raw_path = tmp_str % (http_server_root,
|
|
|
|
|
repo_id, obj_id,
|
|
|
|
|
filename, 'view',
|
|
|
|
|
token,
|
|
|
|
|
request.user.username)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
|
|
|
|
# file share link
|
2012-07-12 12:35:13 +00:00
|
|
|
|
l = FileShare.objects.filter(repo_id=repo_id).filter(\
|
|
|
|
|
username=request.user.username).filter(path=path)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
fileshare = l[0] if len(l) > 0 else None
|
|
|
|
|
|
|
|
|
|
http_or_https = request.is_secure() and 'https' or 'http'
|
|
|
|
|
domain = RequestSite(request).domain
|
|
|
|
|
if fileshare:
|
|
|
|
|
file_shared_link = '%s://%s%sf/%s/' % (http_or_https, domain,
|
|
|
|
|
settings.SITE_ROOT,
|
|
|
|
|
fileshare.token)
|
|
|
|
|
else:
|
|
|
|
|
file_shared_link = ''
|
|
|
|
|
|
2012-07-02 14:45:21 +00:00
|
|
|
|
return render_to_response('repo_view_file.html', {
|
|
|
|
|
'repo': repo,
|
2012-07-13 09:19:44 +00:00
|
|
|
|
'path': path,
|
2012-07-02 14:45:21 +00:00
|
|
|
|
'obj_id': obj_id,
|
2012-07-13 09:26:33 +00:00
|
|
|
|
'u_filename': u_filename,
|
2012-07-02 14:45:21 +00:00
|
|
|
|
'file_name': filename,
|
2012-07-11 14:39:36 +00:00
|
|
|
|
'path': path,
|
2012-07-02 14:45:21 +00:00
|
|
|
|
'zipped': zipped,
|
2012-07-03 13:48:33 +00:00
|
|
|
|
'view_history': view_history,
|
|
|
|
|
'current_commit': current_commit,
|
2012-07-02 14:45:21 +00:00
|
|
|
|
'token': token,
|
|
|
|
|
'can_preview': can_preview,
|
|
|
|
|
'filetype': filetype,
|
|
|
|
|
'raw_path': raw_path,
|
2012-07-11 14:39:36 +00:00
|
|
|
|
'fileshare': fileshare,
|
|
|
|
|
'protocol': http_or_https,
|
|
|
|
|
'domain': domain,
|
|
|
|
|
'file_shared_link': file_shared_link,
|
2012-07-02 14:45:21 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
|
|
|
|
def repo_file_get(request, repo_id):
|
|
|
|
|
"""
|
|
|
|
|
Handle ajax request to get file content from httpserver.
|
|
|
|
|
If get current worktree file, need access_token, path and username from
|
|
|
|
|
url params.
|
|
|
|
|
If get history file, need access_token, path username and obj_id from
|
|
|
|
|
url params.
|
|
|
|
|
"""
|
|
|
|
|
if not request.is_ajax():
|
|
|
|
|
return Http404
|
|
|
|
|
|
|
|
|
|
http_server_root = get_httpserver_root()
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
access_token = request.GET.get('t')
|
|
|
|
|
path = request.GET.get('p', '/')
|
|
|
|
|
if path[-1] == '/':
|
|
|
|
|
path = path[:-1]
|
|
|
|
|
|
|
|
|
|
filename = urllib2.quote(os.path.basename(path).encode('utf-8'))
|
|
|
|
|
obj_id = request.GET.get('obj_id', '')
|
|
|
|
|
if not obj_id:
|
|
|
|
|
try:
|
2012-07-14 13:18:59 +00:00
|
|
|
|
obj_id = seafserv_threaded_rpc.get_file_by_path(repo_id, path)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
except:
|
|
|
|
|
obj_id = None
|
|
|
|
|
if not obj_id:
|
|
|
|
|
data = json.dumps([{'error': '获取文件数据失败'}])
|
|
|
|
|
return HttpResponse(data, status=400, content_type=content_type)
|
|
|
|
|
|
|
|
|
|
username = request.GET.get('u', '')
|
|
|
|
|
tmp_str = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s'
|
|
|
|
|
redirect_url = tmp_str % (http_server_root,
|
|
|
|
|
repo_id, obj_id,
|
|
|
|
|
filename, 'view',
|
|
|
|
|
access_token,
|
|
|
|
|
username)
|
|
|
|
|
try:
|
|
|
|
|
proxied_request = urllib2.urlopen(redirect_url)
|
|
|
|
|
if long(proxied_request.headers['Content-Length']) > FILE_PREVIEW_MAX_SIZE:
|
|
|
|
|
data = json.dumps([{'error': '文件超过10M,无法在线查看。'}])
|
|
|
|
|
return HttpResponse(data, status=400, content_type=content_type)
|
|
|
|
|
else:
|
|
|
|
|
content = proxied_request.read()
|
|
|
|
|
except urllib2.HTTPError, e:
|
|
|
|
|
err = 'HTTPError: 无法在线打开该文件'
|
|
|
|
|
data = json.dumps([{'error': err}])
|
|
|
|
|
return HttpResponse(data, status=400, content_type=content_type)
|
|
|
|
|
except urllib2.URLError as e:
|
|
|
|
|
err = 'URLError: 无法在线打开该文件'
|
|
|
|
|
data = json.dumps([{'error': err}])
|
|
|
|
|
return HttpResponse(data, status=400, content_type=content_type)
|
|
|
|
|
else:
|
|
|
|
|
l, d = [], {}
|
|
|
|
|
try:
|
|
|
|
|
# XXX: file in windows is encoded in gbk
|
2012-07-12 12:35:13 +00:00
|
|
|
|
u_content = content.decode('gbk')
|
2012-07-11 14:39:36 +00:00
|
|
|
|
except:
|
|
|
|
|
u_content = content.decode('utf-8')
|
|
|
|
|
from django.utils.html import escape
|
|
|
|
|
d['content'] = re.sub("\r\n|\n", "<br />", escape(u_content))
|
|
|
|
|
l.append(d)
|
|
|
|
|
data = json.dumps(l)
|
|
|
|
|
return HttpResponse(data, status=200, content_type=content_type)
|
|
|
|
|
|
2012-05-19 03:50:05 +00:00
|
|
|
|
def repo_access_file(request, repo_id, obj_id):
|
2012-07-12 08:14:21 +00:00
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
|
if not repo:
|
|
|
|
|
raise Http404
|
2012-05-24 09:43:26 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
password_set = False
|
|
|
|
|
if repo.props.encrypted:
|
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
|
|
|
|
|
if ret == 1:
|
|
|
|
|
password_set = True
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
2012-05-24 09:43:26 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
if repo.props.encrypted and not password_set:
|
|
|
|
|
return HttpResponseRedirect(reverse('repo', args=[repo_id]))
|
2012-05-24 09:43:26 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
op = request.GET.get('op', 'view')
|
|
|
|
|
file_name = request.GET.get('file_name', '')
|
2012-07-02 02:21:17 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
if op == 'del':
|
|
|
|
|
return repo_del_file(request, repo_id)
|
2012-07-02 02:21:17 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
# if a repo doesn't have access property in db, then assume it's 'own'
|
|
|
|
|
# repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
|
|
|
|
|
# if not repo_ap:
|
|
|
|
|
# repo_ap = 'own'
|
|
|
|
|
repo_ap = 'own'
|
2012-04-20 05:34:52 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
# if a repo is shared to me, then I can view and download file no mater whether
|
|
|
|
|
# repo's access property is 'own' or 'public'
|
|
|
|
|
if check_shared_repo(request, repo_id):
|
|
|
|
|
share_to_me = True
|
|
|
|
|
else:
|
|
|
|
|
share_to_me = False
|
|
|
|
|
|
|
|
|
|
# If vistor's file shared token in url params matches the token in db,
|
|
|
|
|
# then we know the vistor is from file shared link.
|
|
|
|
|
share_token = request.GET.get('t', '')
|
|
|
|
|
path = '/' + file_name
|
|
|
|
|
if FileShare.objects.filter(token=share_token).filter(path=path) > 0:
|
|
|
|
|
from_shared_link = True
|
|
|
|
|
else:
|
|
|
|
|
from_shared_link = False
|
|
|
|
|
|
|
|
|
|
token = ''
|
|
|
|
|
if repo_ap == 'own':
|
|
|
|
|
# people who is owner or this repo is shared to him, can visit the repo;
|
|
|
|
|
# others, just go to 404 page
|
|
|
|
|
if validate_owner(request, repo_id) or share_to_me or from_shared_link:
|
|
|
|
|
# owner should get a token to visit repo
|
|
|
|
|
token = gen_token()
|
|
|
|
|
# put token into memory in seaf-server
|
|
|
|
|
seafserv_rpc.web_save_access_token(token, obj_id)
|
2012-05-07 02:59:19 +00:00
|
|
|
|
else:
|
2012-07-12 08:14:21 +00:00
|
|
|
|
raise Http404
|
2012-04-20 05:34:52 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
http_server_root = get_httpserver_root()
|
2012-05-19 03:50:05 +00:00
|
|
|
|
|
2012-07-12 08:14:21 +00:00
|
|
|
|
tmp_str = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s'
|
|
|
|
|
redirect_url = tmp_str % (http_server_root,
|
|
|
|
|
repo_id, obj_id,
|
|
|
|
|
file_name, op,
|
|
|
|
|
token,
|
|
|
|
|
request.user.username)
|
|
|
|
|
return HttpResponseRedirect(redirect_url)
|
2012-07-02 14:45:21 +00:00
|
|
|
|
|
2012-04-24 14:31:24 +00:00
|
|
|
|
@login_required
|
2012-04-26 02:57:36 +00:00
|
|
|
|
def repo_download(request):
|
|
|
|
|
repo_id = request.GET.get('repo_id', '')
|
|
|
|
|
|
|
|
|
|
repo = seafserv_threaded_rpc.get_repo(repo_id)
|
2012-04-25 11:23:13 +00:00
|
|
|
|
repo_name = repo.props.name
|
2012-05-16 14:44:24 +00:00
|
|
|
|
quote_repo_name = quote(repo_name.encode('utf-8'))
|
2012-04-25 11:23:13 +00:00
|
|
|
|
encrypted = repo.props.encrypted
|
|
|
|
|
if encrypted:
|
|
|
|
|
enc = '1'
|
|
|
|
|
else:
|
2012-04-25 06:34:42 +00:00
|
|
|
|
enc = ''
|
2012-05-16 13:31:28 +00:00
|
|
|
|
relay_id = ccnet_rpc.get_session_info().id
|
2012-05-12 13:29:51 +00:00
|
|
|
|
if not relay_id:
|
|
|
|
|
return render_to_response('error.html', {
|
|
|
|
|
"error_msg": u"下载失败:无法取得中继"
|
|
|
|
|
}, context_instance=RequestContext(request))
|
2012-04-25 11:56:53 +00:00
|
|
|
|
|
2012-04-25 03:18:49 +00:00
|
|
|
|
ccnet_applet_root = get_ccnetapplet_root()
|
2012-04-25 06:34:42 +00:00
|
|
|
|
redirect_url = "%s/repo/download/?repo_id=%s&relay_id=%s&repo_name=%s&encrypted=%s" % (
|
|
|
|
|
ccnet_applet_root, repo_id, relay_id, quote_repo_name, enc)
|
2012-04-25 11:23:13 +00:00
|
|
|
|
|
2012-04-24 14:31:24 +00:00
|
|
|
|
return HttpResponseRedirect(redirect_url)
|
2012-05-14 13:51:55 +00:00
|
|
|
|
|
2012-07-02 02:21:17 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def file_move(request):
|
|
|
|
|
src_repo_id = request.POST.get('src_repo')
|
|
|
|
|
src_path = request.POST.get('src_path')
|
|
|
|
|
dst_repo_id = request.POST.get('dst_repo')
|
|
|
|
|
dst_path = request.POST.get('dst_path')
|
|
|
|
|
obj_name = request.POST.get('obj_name')
|
|
|
|
|
obj_type = request.POST.get('obj_type') # dir or file
|
|
|
|
|
op = request.POST.get('operation')
|
|
|
|
|
|
|
|
|
|
if not (src_repo_id and src_path and dst_repo_id \
|
|
|
|
|
and dst_path and obj_name and obj_type and op):
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
# do nothing when dst is the same as src
|
|
|
|
|
if src_repo_id == dst_repo_id and src_path == dst_path:
|
|
|
|
|
url = reverse('repo', args=[src_repo_id]) + ('?p=%s' % src_path)
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|
|
|
|
# Error when moving/copying a dir to its subdir
|
|
|
|
|
if obj_type == 'dir':
|
|
|
|
|
src_dir = os.path.join(src_path, obj_name)
|
|
|
|
|
if dst_path.startswith(src_dir):
|
|
|
|
|
error_msg = u"不能把目录 %s %s到它的子目录 %s" \
|
|
|
|
|
% (src_dir, u"复制" if op == 'cp' else u"移动", dst_path)
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
new_obj_name = check_filename_with_rename(dst_repo_id, dst_path, obj_name)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if op == 'cp':
|
|
|
|
|
seafserv_threaded_rpc.copy_file (src_repo_id, src_path, obj_name,
|
|
|
|
|
dst_repo_id, dst_path, new_obj_name,
|
|
|
|
|
request.user.username)
|
|
|
|
|
elif op == 'mv':
|
|
|
|
|
seafserv_threaded_rpc.move_file (src_repo_id, src_path, obj_name,
|
|
|
|
|
dst_repo_id, dst_path, new_obj_name,
|
|
|
|
|
request.user.username)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
return go_error(request, str(e))
|
|
|
|
|
|
|
|
|
|
url = reverse('repo', args=[src_repo_id]) + ('?p=%s' % src_path)
|
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-05-14 13:51:55 +00:00
|
|
|
|
def seafile_access_check(request):
|
|
|
|
|
repo_id = request.GET.get('repo_id', '')
|
2012-06-23 02:26:37 +00:00
|
|
|
|
applet_root = get_ccnetapplet_root()
|
|
|
|
|
|
2012-05-14 13:51:55 +00:00
|
|
|
|
return render_to_response(
|
|
|
|
|
'seafile_access_check.html', {
|
|
|
|
|
'repo_id': repo_id,
|
2012-06-23 02:26:37 +00:00
|
|
|
|
'applet_root': applet_root,
|
2012-05-14 13:51:55 +00:00
|
|
|
|
},
|
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
|
|
2012-04-24 06:21:52 +00:00
|
|
|
|
@login_required
|
2012-04-26 02:57:36 +00:00
|
|
|
|
def repo_remove_share(request):
|
2012-05-26 06:47:57 +00:00
|
|
|
|
"""
|
|
|
|
|
If repo is shared from one person to another person, only these two peson
|
|
|
|
|
can remove share.
|
|
|
|
|
If repo is shared from one person to a group, then only the one share the
|
|
|
|
|
repo and group staff can remove share.
|
|
|
|
|
"""
|
2012-04-26 02:57:36 +00:00
|
|
|
|
repo_id = request.GET.get('repo_id', '')
|
2012-05-15 02:59:16 +00:00
|
|
|
|
group_id = request.GET.get('gid')
|
2012-05-26 06:47:57 +00:00
|
|
|
|
from_email = request.GET.get('from', '')
|
2012-05-15 06:29:37 +00:00
|
|
|
|
|
2012-05-15 02:59:16 +00:00
|
|
|
|
# if request params don't have 'gid', then remove repos that share to
|
|
|
|
|
# to other person; else, remove repos that share to groups
|
|
|
|
|
if not group_id:
|
2012-05-26 06:47:57 +00:00
|
|
|
|
to_email = request.GET.get('to', '')
|
|
|
|
|
if request.user.username != from_email and \
|
|
|
|
|
request.user.username != to_email:
|
|
|
|
|
return go_permission_error(request, u'取消共享失败')
|
2012-05-15 02:59:16 +00:00
|
|
|
|
seafserv_threaded_rpc.remove_share(repo_id, from_email, to_email)
|
|
|
|
|
else:
|
|
|
|
|
try:
|
|
|
|
|
group_id_int = int(group_id)
|
|
|
|
|
except:
|
2012-05-15 06:29:37 +00:00
|
|
|
|
return go_error(request, u'group id 不是有效参数')
|
2012-05-26 07:31:35 +00:00
|
|
|
|
|
|
|
|
|
if not check_group_staff(group_id_int, request.user) \
|
|
|
|
|
and request.user.username != from_email:
|
|
|
|
|
return go_permission_error(request, u'取消共享失败')
|
2012-05-15 06:29:37 +00:00
|
|
|
|
from seahub.group.views import group_unshare_repo
|
2012-05-15 02:59:16 +00:00
|
|
|
|
group_unshare_repo(request, repo_id, group_id_int, from_email)
|
2012-06-05 11:38:28 +00:00
|
|
|
|
|
|
|
|
|
referer = request.META.get('HTTP_REFERER', None)
|
|
|
|
|
if not referer:
|
2012-06-12 02:13:14 +00:00
|
|
|
|
referer = 'share_admin'
|
2012-06-05 11:38:28 +00:00
|
|
|
|
return HttpResponseRedirect(reverse(referer))
|
|
|
|
|
else:
|
|
|
|
|
return HttpResponseRedirect(referer)
|
2012-04-24 06:21:52 +00:00
|
|
|
|
|
2011-09-07 02:57:47 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def mypeers(request):
|
|
|
|
|
cid = get_user_cid(request.user)
|
|
|
|
|
|
2012-01-29 05:05:35 +00:00
|
|
|
|
@login_required
|
2012-06-20 11:39:21 +00:00
|
|
|
|
def sys_seafadmin(request):
|
2012-01-29 05:05:35 +00:00
|
|
|
|
if not request.user.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-03-20 03:35:56 +00:00
|
|
|
|
# Make sure page request is an int. If not, deliver first page.
|
|
|
|
|
try:
|
|
|
|
|
current_page = int(request.GET.get('page', '1'))
|
|
|
|
|
per_page= int(request.GET.get('per_page', '25'))
|
|
|
|
|
except ValueError:
|
2012-04-09 08:48:14 +00:00
|
|
|
|
current_page = 1
|
2012-03-20 03:35:56 +00:00
|
|
|
|
per_page = 25
|
|
|
|
|
|
2012-05-26 12:52:53 +00:00
|
|
|
|
repos_all = seafserv_threaded_rpc.get_repo_list(per_page *
|
|
|
|
|
(current_page -1),
|
|
|
|
|
per_page + 1)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
|
|
|
|
repos = repos_all[:per_page]
|
|
|
|
|
|
|
|
|
|
if len(repos_all) == per_page + 1:
|
|
|
|
|
page_next = True
|
|
|
|
|
else:
|
|
|
|
|
page_next = False
|
|
|
|
|
|
|
|
|
|
for repo in repos:
|
|
|
|
|
try:
|
|
|
|
|
repo.owner = seafserv_threaded_rpc.get_repo_owner(repo.props.id)
|
|
|
|
|
except:
|
|
|
|
|
repo.owner = None
|
|
|
|
|
|
|
|
|
|
return render_to_response(
|
|
|
|
|
'sys_seafadmin.html', {
|
|
|
|
|
'repos': repos,
|
|
|
|
|
'current_page': current_page,
|
|
|
|
|
'prev_page': current_page-1,
|
|
|
|
|
'next_page': current_page+1,
|
|
|
|
|
'per_page': per_page,
|
|
|
|
|
'page_next': page_next,
|
|
|
|
|
},
|
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def org_seafadmin(request):
|
|
|
|
|
if not request.user.org:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
# Make sure page request is an int. If not, deliver first page.
|
|
|
|
|
try:
|
|
|
|
|
current_page = int(request.GET.get('page', '1'))
|
|
|
|
|
per_page= int(request.GET.get('per_page', '25'))
|
|
|
|
|
except ValueError:
|
|
|
|
|
current_page = 1
|
|
|
|
|
per_page = 25
|
|
|
|
|
|
|
|
|
|
repos_all = seafserv_threaded_rpc.get_org_repo_list(request.user.org.org_id,
|
|
|
|
|
per_page * (current_page -1),
|
|
|
|
|
per_page + 1)
|
|
|
|
|
|
2012-03-20 03:35:56 +00:00
|
|
|
|
repos = repos_all[:per_page]
|
|
|
|
|
|
|
|
|
|
if len(repos_all) == per_page + 1:
|
|
|
|
|
page_next = True
|
|
|
|
|
else:
|
|
|
|
|
page_next = False
|
|
|
|
|
|
2012-03-19 06:47:34 +00:00
|
|
|
|
for repo in repos:
|
2012-03-19 08:48:51 +00:00
|
|
|
|
try:
|
2012-05-02 12:58:06 +00:00
|
|
|
|
repo.owner = seafserv_threaded_rpc.get_repo_owner(repo.props.id)
|
2012-03-19 08:48:51 +00:00
|
|
|
|
except:
|
|
|
|
|
repo.owner = None
|
|
|
|
|
|
2012-01-29 05:05:35 +00:00
|
|
|
|
return render_to_response(
|
2012-06-20 11:39:21 +00:00
|
|
|
|
'org_seafadmin.html', {
|
2012-01-29 05:05:35 +00:00
|
|
|
|
'repos': repos,
|
2012-03-20 03:35:56 +00:00
|
|
|
|
'current_page': current_page,
|
|
|
|
|
'prev_page': current_page-1,
|
|
|
|
|
'next_page': current_page+1,
|
|
|
|
|
'per_page': per_page,
|
|
|
|
|
'page_next': page_next,
|
2012-01-29 05:05:35 +00:00
|
|
|
|
},
|
|
|
|
|
context_instance=RequestContext(request))
|
2012-02-21 09:11:58 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
2012-06-20 11:39:21 +00:00
|
|
|
|
def sys_useradmin(request):
|
2012-02-21 09:11:58 +00:00
|
|
|
|
if not request.user.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
users = ccnet_threaded_rpc.get_emailusers(-1,-1)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
2012-02-21 09:11:58 +00:00
|
|
|
|
for user in users:
|
2012-04-21 03:05:59 +00:00
|
|
|
|
if user.props.id == request.user.id:
|
|
|
|
|
user.is_self = True
|
2012-06-20 11:39:21 +00:00
|
|
|
|
# TODO: may add new is_org_user rpc
|
2012-06-25 12:42:19 +00:00
|
|
|
|
user.is_org_user = True if ccnet_threaded_rpc.get_org_by_user(user.email) else False
|
2012-04-21 03:05:59 +00:00
|
|
|
|
|
2012-02-21 09:11:58 +00:00
|
|
|
|
return render_to_response(
|
2012-06-20 11:39:21 +00:00
|
|
|
|
'sys_useradmin.html', {
|
|
|
|
|
'users': users,
|
|
|
|
|
},
|
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def org_useradmin(request):
|
|
|
|
|
if not request.user.org.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
users = ccnet_threaded_rpc.get_org_emailusers(request.user.org.url_prefix,
|
2012-06-20 11:39:21 +00:00
|
|
|
|
0, sys.maxint)
|
|
|
|
|
|
|
|
|
|
for user in users:
|
|
|
|
|
if user.props.id == request.user.id:
|
|
|
|
|
user.is_self = True
|
|
|
|
|
user.is_org_user = True
|
|
|
|
|
|
|
|
|
|
return render_to_response(
|
|
|
|
|
'org_useradmin.html', {
|
2012-02-21 09:11:58 +00:00
|
|
|
|
'users': users,
|
|
|
|
|
},
|
|
|
|
|
context_instance=RequestContext(request))
|
|
|
|
|
|
2012-04-13 05:21:48 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def user_info(request, email):
|
2012-05-15 02:59:16 +00:00
|
|
|
|
if request.user.username == email:
|
|
|
|
|
return HttpResponseRedirect(reverse(myhome))
|
|
|
|
|
|
2012-07-09 06:23:46 +00:00
|
|
|
|
if not request.user.is_staff:
|
2012-05-15 02:59:16 +00:00
|
|
|
|
return go_permission_error(request, u'权限不足:无法查看该用户信息')
|
2012-04-13 05:21:48 +00:00
|
|
|
|
|
2012-07-09 06:23:46 +00:00
|
|
|
|
# if request.user.org and not request.user.org.is_staff:
|
|
|
|
|
# return go_permission_error(request, u'权限不足:无法查看该用户信息')
|
|
|
|
|
|
2012-07-05 03:52:12 +00:00
|
|
|
|
# user_dict = {}
|
2012-05-03 02:52:43 +00:00
|
|
|
|
owned_repos = []
|
|
|
|
|
quota_usage = 0
|
|
|
|
|
|
|
|
|
|
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
|
|
|
|
|
quota_usage = seafserv_threaded_rpc.get_user_quota_usage(email)
|
2012-04-15 15:33:22 +00:00
|
|
|
|
|
2012-07-05 03:52:12 +00:00
|
|
|
|
# try:
|
|
|
|
|
# peers = ccnet_threaded_rpc.get_peers_by_email(email)
|
|
|
|
|
# for peer in peers:
|
|
|
|
|
# if not peer:
|
|
|
|
|
# continue
|
|
|
|
|
# peername = peer.props.name
|
|
|
|
|
# roles = peer.props.role_list
|
|
|
|
|
# user_dict[peername] = roles
|
|
|
|
|
# except:
|
|
|
|
|
# pass
|
2012-05-03 02:52:43 +00:00
|
|
|
|
|
|
|
|
|
# Repos that are share to user
|
|
|
|
|
in_repos = seafserv_threaded_rpc.list_share_repos(email, 'to_email', -1, -1)
|
|
|
|
|
|
2012-04-13 05:21:48 +00:00
|
|
|
|
return render_to_response(
|
|
|
|
|
'userinfo.html', {
|
2012-05-03 02:52:43 +00:00
|
|
|
|
'owned_repos': owned_repos,
|
|
|
|
|
'quota_usage': quota_usage,
|
|
|
|
|
"in_repos": in_repos,
|
2012-07-05 03:52:12 +00:00
|
|
|
|
# 'user_dict': user_dict,
|
2012-04-15 15:33:22 +00:00
|
|
|
|
'email': email
|
2012-04-13 05:21:48 +00:00
|
|
|
|
},
|
|
|
|
|
context_instance=RequestContext(request))
|
2012-02-21 09:11:58 +00:00
|
|
|
|
|
2012-06-05 11:38:28 +00:00
|
|
|
|
#@login_required
|
|
|
|
|
#def role_add(request, user_id):
|
|
|
|
|
# if not request.user.is_staff:
|
|
|
|
|
# raise Http404
|
|
|
|
|
#
|
|
|
|
|
# if request.method == 'POST':
|
|
|
|
|
# role = request.POST.get('role', '')
|
|
|
|
|
# if role and len(role) <= 16:
|
|
|
|
|
# ccnet_rpc.add_role(user_id, role)
|
|
|
|
|
#
|
|
|
|
|
# return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
|
|
|
|
|
|
|
|
|
#@login_required
|
|
|
|
|
#def role_remove(request, user_id):
|
|
|
|
|
# if not request.user.is_staff:
|
|
|
|
|
# raise Http404
|
|
|
|
|
#
|
|
|
|
|
# role = request.REQUEST.get('role', '')
|
|
|
|
|
# if role and len(role) <= 16:
|
|
|
|
|
# ccnet_rpc.remove_role(user_id, role)
|
|
|
|
|
#
|
|
|
|
|
# return HttpResponseRedirect(request.META['HTTP_REFERER'])
|
2012-02-24 03:23:54 +00:00
|
|
|
|
|
2012-03-17 06:05:21 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def user_remove(request, user_id):
|
2012-05-02 12:58:06 +00:00
|
|
|
|
"""The user id is emailuser id."""
|
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
if not request.user.is_staff and not request.user.org.is_staff:
|
2012-03-17 06:05:21 +00:00
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-04-11 11:48:20 +00:00
|
|
|
|
ccnetuser = get_ccnetuser(userid=int(user_id))
|
2012-06-20 11:39:21 +00:00
|
|
|
|
if ccnetuser.org:
|
2012-06-25 12:42:19 +00:00
|
|
|
|
ccnet_threaded_rpc.remove_org_user(ccnetuser.org.org_id, ccnetuser.username)
|
2012-04-11 11:48:20 +00:00
|
|
|
|
ccnetuser.delete()
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
|
|
|
|
if request.user.is_staff:
|
|
|
|
|
return HttpResponseRedirect(reverse('sys_useradmin'))
|
|
|
|
|
else:
|
|
|
|
|
return HttpResponseRedirect(reverse('org_useradmin'))
|
2012-02-24 03:23:54 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def activate_user(request, user_id):
|
2012-04-11 11:48:20 +00:00
|
|
|
|
"""The user id is emailuser id."""
|
2012-02-24 03:23:54 +00:00
|
|
|
|
|
|
|
|
|
if not request.user.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-04-11 11:48:20 +00:00
|
|
|
|
ccnetuser = get_ccnetuser(userid=int(user_id))
|
|
|
|
|
ccnetuser.is_active = True
|
|
|
|
|
ccnetuser.save()
|
2012-06-05 11:38:28 +00:00
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(reverse('useradmin'))
|
2012-02-24 03:23:54 +00:00
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
def send_user_add_mail(request, email, password):
|
|
|
|
|
""" Send email when add new user """
|
|
|
|
|
|
|
|
|
|
use_https = request.is_secure()
|
|
|
|
|
domain = RequestSite(request).domain
|
|
|
|
|
|
|
|
|
|
t = loader.get_template('user_add_email.html')
|
|
|
|
|
c = {
|
|
|
|
|
'user': request.user.username,
|
|
|
|
|
'org': request.user.org,
|
|
|
|
|
'email': email,
|
|
|
|
|
'password': password,
|
|
|
|
|
'domain': domain,
|
|
|
|
|
'protocol': use_https and 'https' or 'http',
|
|
|
|
|
}
|
|
|
|
|
try:
|
|
|
|
|
send_mail(u'SeaCloud注册信息', t.render(Context(c)),
|
|
|
|
|
None, [email], fail_silently=False)
|
|
|
|
|
messages.add_message(request, messages.INFO, email)
|
|
|
|
|
except:
|
|
|
|
|
messages.add_message(request, messages.ERROR, email)
|
|
|
|
|
|
2012-03-09 02:31:35 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def user_add(request):
|
|
|
|
|
"""Add a user"""
|
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
if not request.user.is_staff and not request.user.org.is_staff:
|
2012-03-09 02:31:35 +00:00
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
base_template = 'org_admin_base.html' if request.user.org else 'admin_base.html'
|
|
|
|
|
|
2012-03-09 02:31:35 +00:00
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
form = AddUserForm(request.POST)
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
email = form.cleaned_data['email']
|
|
|
|
|
password = form.cleaned_data['password1']
|
2012-04-11 11:48:20 +00:00
|
|
|
|
|
|
|
|
|
ccnetuser = CcnetUser(username=email, raw_password=password)
|
|
|
|
|
ccnetuser.is_active = True
|
|
|
|
|
ccnetuser.save()
|
2012-04-01 13:55:33 +00:00
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
if request.user.org:
|
|
|
|
|
org_id = request.user.org.org_id
|
2012-06-25 12:42:19 +00:00
|
|
|
|
ccnet_threaded_rpc.add_org_user(org_id, email, 0)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
if hasattr(settings, 'EMAIL_HOST'):
|
|
|
|
|
send_user_add_mail(request, email, password)
|
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(reverse('org_useradmin'))
|
|
|
|
|
else:
|
|
|
|
|
if hasattr(settings, 'EMAIL_HOST'):
|
|
|
|
|
send_user_add_mail(request, email, password)
|
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(reverse('sys_useradmin', args=[]))
|
2012-03-09 02:31:35 +00:00
|
|
|
|
else:
|
|
|
|
|
form = AddUserForm()
|
|
|
|
|
|
|
|
|
|
return render_to_response("add_user_form.html", {
|
2012-06-20 11:39:21 +00:00
|
|
|
|
'form': form,
|
|
|
|
|
'base_template': base_template,
|
2012-03-09 02:31:35 +00:00
|
|
|
|
}, context_instance=RequestContext(request))
|
2012-04-26 02:19:57 +00:00
|
|
|
|
|
|
|
|
|
def back_local(request):
|
|
|
|
|
ccnet_applt_root = get_ccnetapplet_root()
|
|
|
|
|
|
|
|
|
|
redirect_url = '%s/home/' % ccnet_applt_root
|
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(redirect_url)
|
2012-05-15 06:29:37 +00:00
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
def sys_group_admin(request):
|
2012-05-26 12:52:53 +00:00
|
|
|
|
if not request.user.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
# Make sure page request is an int. If not, deliver first page.
|
|
|
|
|
try:
|
|
|
|
|
current_page = int(request.GET.get('page', '1'))
|
|
|
|
|
per_page= int(request.GET.get('per_page', '25'))
|
|
|
|
|
except ValueError:
|
|
|
|
|
current_page = 1
|
|
|
|
|
per_page = 25
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
groups_plus_one = ccnet_threaded_rpc.get_all_groups(per_page * (current_page -1),
|
2012-05-26 12:52:53 +00:00
|
|
|
|
per_page +1)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
2012-05-26 12:52:53 +00:00
|
|
|
|
groups = groups_plus_one[:per_page]
|
|
|
|
|
|
|
|
|
|
if len(groups_plus_one) == per_page + 1:
|
|
|
|
|
page_next = True
|
|
|
|
|
else:
|
|
|
|
|
page_next = False
|
|
|
|
|
|
2012-06-20 11:39:21 +00:00
|
|
|
|
return render_to_response('sys_group_admin.html', {
|
|
|
|
|
'groups': groups,
|
|
|
|
|
'current_page': current_page,
|
|
|
|
|
'prev_page': current_page-1,
|
|
|
|
|
'next_page': current_page+1,
|
|
|
|
|
'per_page': per_page,
|
|
|
|
|
'page_next': page_next,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
def sys_org_admin(request):
|
|
|
|
|
if not request.user.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
2012-07-09 02:37:42 +00:00
|
|
|
|
try:
|
|
|
|
|
orgs = ccnet_threaded_rpc.get_all_orgs(0, sys.maxint)
|
|
|
|
|
except:
|
|
|
|
|
orgs = []
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
|
|
|
|
return render_to_response('sys_org_admin.html', {
|
|
|
|
|
'orgs': orgs,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
def org_group_admin(request):
|
|
|
|
|
if not request.user.is_staff and not request.user.org.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
# Make sure page request is an int. If not, deliver first page.
|
|
|
|
|
try:
|
|
|
|
|
current_page = int(request.GET.get('page', '1'))
|
|
|
|
|
per_page= int(request.GET.get('per_page', '25'))
|
|
|
|
|
except ValueError:
|
|
|
|
|
current_page = 1
|
|
|
|
|
per_page = 25
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
groups_plus_one = ccnet_threaded_rpc.get_org_groups (request.user.org.org_id,
|
2012-06-20 11:39:21 +00:00
|
|
|
|
per_page * (current_page -1),
|
|
|
|
|
per_page +1)
|
|
|
|
|
|
|
|
|
|
groups = groups_plus_one[:per_page]
|
|
|
|
|
|
|
|
|
|
if len(groups_plus_one) == per_page + 1:
|
|
|
|
|
page_next = True
|
|
|
|
|
else:
|
|
|
|
|
page_next = False
|
|
|
|
|
|
|
|
|
|
return render_to_response('org_group_admin.html', {
|
|
|
|
|
'groups': groups,
|
2012-05-26 12:52:53 +00:00
|
|
|
|
'current_page': current_page,
|
|
|
|
|
'prev_page': current_page-1,
|
|
|
|
|
'next_page': current_page+1,
|
|
|
|
|
'per_page': per_page,
|
|
|
|
|
'page_next': page_next,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
|
|
|
|
def org_remove(request, org_id):
|
|
|
|
|
if not request.user.is_staff:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
org_id_int = int(org_id)
|
|
|
|
|
except ValueError:
|
|
|
|
|
return HttpResponseRedirect(reverse('sys_org_admin'))
|
|
|
|
|
|
|
|
|
|
# Remove repos in that org
|
|
|
|
|
seafserv_threaded_rpc.remove_org_repo_by_org_id(org_id_int)
|
|
|
|
|
|
|
|
|
|
# TODO: Remove repos in org's groups
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
ccnet_threaded_rpc.remove_org(org_id_int)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
|
|
|
|
return HttpResponseRedirect(reverse('sys_org_admin'))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def org_info(request):
|
|
|
|
|
if not request.user.org:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
org = request.user.org
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
org_members = ccnet_threaded_rpc.get_org_emailusers(org.url_prefix, 0, sys.maxint)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
for member in org_members:
|
|
|
|
|
member.short_username = member.email.split('@')[0]
|
|
|
|
|
|
2012-06-25 12:42:19 +00:00
|
|
|
|
groups = ccnet_threaded_rpc.get_org_groups(org.org_id, 0, sys.maxint)
|
2012-06-20 11:39:21 +00:00
|
|
|
|
|
|
|
|
|
return render_to_response('org_info.html', {
|
|
|
|
|
'org': org,
|
|
|
|
|
'org_users': org_members,
|
|
|
|
|
'groups': groups,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
2012-06-28 08:58:09 +00:00
|
|
|
|
|
2012-07-02 02:21:17 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def file_upload_progress(request):
|
|
|
|
|
"""
|
|
|
|
|
Return JSON object with information about the progress of an upload.
|
|
|
|
|
"""
|
|
|
|
|
progress_id = None
|
|
|
|
|
if 'X-Progress-ID' in request.GET:
|
|
|
|
|
progress_id = request.GET['X-Progress-ID']
|
|
|
|
|
elif 'X-Progress-ID' in request.META:
|
|
|
|
|
progress_id = request.META['X-Progress-ID']
|
|
|
|
|
|
|
|
|
|
if progress_id:
|
|
|
|
|
cache_key = "%s_%s" % (request.user.username, progress_id)
|
|
|
|
|
data = cache.get(cache_key)
|
|
|
|
|
return HttpResponse(json.dumps(data))
|
|
|
|
|
else:
|
|
|
|
|
return HttpResponseServerError('Server Error: You must provide X-Progress-ID header or query param.')
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def file_upload_progress_page(request):
|
|
|
|
|
'''
|
|
|
|
|
As iframe in repo_upload_file.html, for solving problem in chrome.
|
|
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
uuid = request.GET.get('uuid', '')
|
|
|
|
|
|
|
|
|
|
return render_to_response('file_upload_progress_page.html', {
|
|
|
|
|
'uuid': uuid,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def repo_new_dir(request):
|
|
|
|
|
repo_id = request.POST.get("repo_id")
|
|
|
|
|
parent_dir = request.POST.get("parent_dir")
|
|
|
|
|
new_dir_name = request.POST.get("new_dir_name")
|
|
|
|
|
user = request.user.username
|
|
|
|
|
|
|
|
|
|
if not new_dir_name:
|
|
|
|
|
error_msg = u"请输入新目录名"
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
if not (repo_id and parent_dir and user):
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
if len(new_dir_name) > settings.MAX_UPLOAD_FILE_NAME_LEN:
|
|
|
|
|
error_msg = u"您输入的目录名称过长"
|
|
|
|
|
return go_error (request, error_msg)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
if not seafserv_threaded_rpc.is_valid_filename(repo_id, new_dir_name):
|
|
|
|
|
error_msg = (u"您输入的目录名称 %s 包含非法字符" % new_dir_name)
|
|
|
|
|
return go_error (request, error_msg)
|
|
|
|
|
except SearpcError,e:
|
|
|
|
|
return go_error (request, e.msg)
|
|
|
|
|
|
|
|
|
|
new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name)
|
|
|
|
|
|
|
|
|
|
try:
|
2012-07-11 09:47:08 +00:00
|
|
|
|
seafserv_threaded_rpc.post_dir(repo_id, parent_dir, new_dir_name, user)
|
2012-07-02 02:21:17 +00:00
|
|
|
|
except Exception, e:
|
|
|
|
|
return go_error(request, str(e))
|
|
|
|
|
|
|
|
|
|
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def repo_rename_file(request):
|
|
|
|
|
repo_id = request.POST.get("repo_id")
|
|
|
|
|
parent_dir = request.POST.get("parent_dir")
|
|
|
|
|
oldname = request.POST.get("oldname")
|
|
|
|
|
newname = request.POST.get("newname")
|
|
|
|
|
user = request.user.username
|
|
|
|
|
|
|
|
|
|
if not newname:
|
|
|
|
|
error_msg = u"新文件名不能为空"
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
if len(newname) > settings.MAX_UPLOAD_FILE_NAME_LEN:
|
|
|
|
|
error_msg = u"新文件名太长"
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
if not (repo_id and parent_dir and oldname):
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
seafserv_threaded_rpc.rename_file (repo_id, parent_dir,
|
|
|
|
|
oldname, newname, user)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
return go_error(request, str(e))
|
|
|
|
|
|
|
|
|
|
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def validate_filename(request):
|
|
|
|
|
repo_id = request.GET.get('repo_id')
|
|
|
|
|
filename = request.GET.get('filename')
|
|
|
|
|
|
|
|
|
|
if not (repo_id and filename):
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
result = {'ret':'yes'}
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
ret = seafserv_threaded_rpc.is_valid_filename (repo_id, filename);
|
|
|
|
|
except SearpcError:
|
|
|
|
|
result['ret'] = 'error'
|
|
|
|
|
else:
|
|
|
|
|
result['ret'] = 'yes' if ret == 1 else 'no'
|
|
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2012-07-09 12:56:21 +00:00
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def repo_create(request):
|
2012-07-16 08:36:46 +00:00
|
|
|
|
'''
|
|
|
|
|
Handle ajax post.
|
2012-07-09 12:56:21 +00:00
|
|
|
|
|
2012-07-16 08:36:46 +00:00
|
|
|
|
'''
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
repo_name = request.POST.get("repo_name")
|
|
|
|
|
repo_desc = request.POST.get("repo_desc")
|
|
|
|
|
encrypted = request.POST.get("encryption")
|
|
|
|
|
passwd = request.POST.get("passwd")
|
|
|
|
|
passwd_again = request.POST.get("passwd_again")
|
|
|
|
|
|
|
|
|
|
result = {}
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
|
|
error_msg = ""
|
|
|
|
|
if not repo_name:
|
|
|
|
|
error_msg = u"目录名不能为空"
|
|
|
|
|
elif len(repo_name) > 50:
|
|
|
|
|
error_msg = u"目录名太长"
|
|
|
|
|
elif not seafserv_threaded_rpc.is_valid_filename('', repo_name):
|
|
|
|
|
error_msg = (u"您输入的目录名 %s 包含非法字符" % repo_name)
|
|
|
|
|
elif not repo_desc:
|
|
|
|
|
error_msg = u"描述不能为空"
|
|
|
|
|
elif len(repo_desc) > 100:
|
|
|
|
|
error_msg = u"描述太长"
|
|
|
|
|
elif encrypted == 'on':
|
|
|
|
|
if not passwd:
|
|
|
|
|
error_msg = u"密码不能为空"
|
|
|
|
|
elif not passwd_again:
|
|
|
|
|
error_msg = u"确认密码不能为空"
|
|
|
|
|
elif len(passwd) < 3:
|
|
|
|
|
error_msg = u"密码太短"
|
|
|
|
|
elif len(passwd) > 15:
|
|
|
|
|
error_msg = u"密码太长"
|
|
|
|
|
elif passwd != passwd_again:
|
|
|
|
|
error_msg = u"两次输入的密码不相同"
|
|
|
|
|
|
|
|
|
|
if error_msg:
|
|
|
|
|
result['error'] = error_msg
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2012-07-09 12:56:21 +00:00
|
|
|
|
|
2012-07-16 08:36:46 +00:00
|
|
|
|
try:
|
|
|
|
|
repo_id = seafserv_threaded_rpc.create_repo(repo_name, repo_desc, request.user.username, passwd)
|
|
|
|
|
result['success'] = True
|
2012-07-09 12:56:21 +00:00
|
|
|
|
|
2012-07-16 08:36:46 +00:00
|
|
|
|
except:
|
|
|
|
|
result['error'] = u"创建目录失败"
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
if not repo_id:
|
|
|
|
|
result['error'] = u"创建目录失败"
|
|
|
|
|
|
|
|
|
|
return HttpResponse(json.dumps(result), content_type=content_type)
|
2012-07-13 09:19:44 +00:00
|
|
|
|
|
|
|
|
|
def render_file_revisions (request, repo_id):
|
|
|
|
|
"""List all history versions of a file."""
|
|
|
|
|
target_file = request.GET.get('p')
|
|
|
|
|
if not target_file:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
|
if not repo:
|
|
|
|
|
error_msg = u"同步目录不存在"
|
|
|
|
|
return go_error(request, error_msg)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
commits = seafserv_threaded_rpc.list_file_revisions(repo_id, target_file)
|
|
|
|
|
except SearpcError, e:
|
|
|
|
|
return go_error(request, e.msg)
|
|
|
|
|
|
|
|
|
|
if not commits:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
# Check whether use is repo owner
|
|
|
|
|
if validate_owner(request, repo_id):
|
|
|
|
|
is_owner = True
|
|
|
|
|
else:
|
|
|
|
|
is_owner = False
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
current_commit = get_commits(repo_id, 0, 1)[0]
|
|
|
|
|
current_file_id = get_file_revision_id_size (current_commit.id, target_file)[0]
|
|
|
|
|
for commit in commits:
|
|
|
|
|
file_id, file_size = get_file_revision_id_size (commit.id, target_file)
|
|
|
|
|
if not file_id or not file_size:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
commit.revision_file_size = file_size
|
|
|
|
|
if file_id == current_file_id:
|
|
|
|
|
commit.is_current_version = True
|
|
|
|
|
else:
|
|
|
|
|
commit.is_current_version = False
|
|
|
|
|
except Exception, e:
|
|
|
|
|
return go_error(request, str(e))
|
|
|
|
|
|
|
|
|
|
return render_to_response('file_revisions.html', {
|
|
|
|
|
'repo': repo,
|
|
|
|
|
'path': target_file,
|
|
|
|
|
'commits': commits,
|
|
|
|
|
'is_owner': is_owner,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def file_revisions(request, repo_id):
|
|
|
|
|
if request.method != 'GET':
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
op = request.GET.get('op')
|
|
|
|
|
if not op:
|
|
|
|
|
return render_file_revisions(request, repo_id)
|
|
|
|
|
elif op != 'revert' and op != 'download' and op != 'view':
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
commit_id = request.GET.get('commit')
|
|
|
|
|
path = request.GET.get('p')
|
|
|
|
|
|
|
|
|
|
if not (commit_id and path):
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
if op == 'revert':
|
|
|
|
|
try:
|
|
|
|
|
seafserv_threaded_rpc.revert_file (repo_id, commit_id,
|
|
|
|
|
path, request.user.username)
|
|
|
|
|
except Exception, e:
|
|
|
|
|
return go_error(request, str(e))
|
|
|
|
|
else:
|
|
|
|
|
parent_dir = os.path.dirname(path)
|
|
|
|
|
url = reverse('repo', args=[repo_id]) + ('?p=%s' % parent_dir)
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|
|
|
|
elif op == 'download':
|
|
|
|
|
def handle_download():
|
|
|
|
|
parent_dir = os.path.dirname(path)
|
|
|
|
|
file_name = os.path.basename(path)
|
|
|
|
|
seafdir = seafserv_threaded_rpc.list_dir_by_path (commit_id, \
|
|
|
|
|
parent_dir.encode('utf-8'))
|
|
|
|
|
if not seafdir:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
# for ... else ...
|
|
|
|
|
for dirent in seafdir:
|
|
|
|
|
if dirent.obj_name == file_name:
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
|
|
|
|
|
url = reverse('repo_access_file', args=[repo_id, dirent.obj_id])
|
|
|
|
|
url += '?file_name=%s&op=download' % file_name
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
return handle_download()
|
|
|
|
|
except Exception, e:
|
|
|
|
|
return go_error(request, str(e))
|
|
|
|
|
elif op == 'view':
|
|
|
|
|
seafile_id = get_file_revision_id_size (commit_id, path)[0]
|
|
|
|
|
if not seafile_id:
|
|
|
|
|
return go_error(request)
|
|
|
|
|
file_name = os.path.basename(path)
|
|
|
|
|
url = reverse(repo_view_file, args=[repo_id, seafile_id])
|
|
|
|
|
url += u'?commit_id=%s&file_name=%s&p=%s' \
|
|
|
|
|
% (commit_id, file_name, path)
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
@login_required
|
|
|
|
|
def get_shared_link(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle ajax request to generate file shared link.
|
|
|
|
|
"""
|
|
|
|
|
if not request.is_ajax():
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
|
|
repo_id = request.GET.get('repo_id')
|
|
|
|
|
obj_id = request.GET.get('obj_id')
|
|
|
|
|
path = request.GET.get('p', '/')
|
|
|
|
|
if path[-1] == '/':
|
|
|
|
|
path = path[:-1]
|
|
|
|
|
|
2012-07-12 12:35:13 +00:00
|
|
|
|
l = FileShare.objects.filter(repo_id=repo_id).filter(\
|
|
|
|
|
username=request.user.username).filter(path=path)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
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:
|
|
|
|
|
err = '获取分享链接失败,请重新获取'
|
|
|
|
|
data = json.dumps([{'error': err}])
|
|
|
|
|
return HttpResponse(data, status=500, content_type=content_type)
|
|
|
|
|
|
|
|
|
|
data = json.dumps([{'token': token}])
|
|
|
|
|
return HttpResponse(data, status=200, content_type=content_type)
|
|
|
|
|
|
|
|
|
|
def view_shared_file(request, token):
|
|
|
|
|
"""
|
|
|
|
|
Preview file via shared link.
|
|
|
|
|
"""
|
|
|
|
|
assert token is not None # Checked by URLconf
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
fileshare = FileShare.objects.get(token=token)
|
|
|
|
|
except FileShare.DoesNotExist:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
username = fileshare.username
|
|
|
|
|
repo_id = fileshare.repo_id
|
|
|
|
|
path = fileshare.path
|
|
|
|
|
|
|
|
|
|
http_server_root = get_httpserver_root()
|
|
|
|
|
if path[-1] == '/':
|
|
|
|
|
path = path[:-1]
|
|
|
|
|
filename = os.path.basename(path)
|
|
|
|
|
quote_filename = urllib2.quote(filename.encode('utf-8'))
|
|
|
|
|
|
|
|
|
|
try:
|
2012-07-14 14:41:32 +00:00
|
|
|
|
obj_id = seafserv_threaded_rpc.get_file_by_path(repo_id, path)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
except:
|
|
|
|
|
obj_id = None
|
|
|
|
|
|
|
|
|
|
if not obj_id:
|
|
|
|
|
return go_error(request, '文件不存在')
|
|
|
|
|
|
|
|
|
|
repo = get_repo(repo_id)
|
|
|
|
|
if not repo:
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
access_token = gen_token()
|
|
|
|
|
seafserv_rpc.web_save_access_token(access_token, obj_id)
|
|
|
|
|
|
|
|
|
|
can_preview, filetype = valid_previewed_file(filename)
|
|
|
|
|
|
2012-07-13 03:22:20 +00:00
|
|
|
|
# Raw path
|
2012-07-11 14:39:36 +00:00
|
|
|
|
tmp_str = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s'
|
|
|
|
|
raw_path = tmp_str % (http_server_root,
|
|
|
|
|
repo_id, obj_id,
|
|
|
|
|
quote_filename, 'view',
|
|
|
|
|
access_token,
|
|
|
|
|
username)
|
|
|
|
|
|
2012-07-13 03:22:20 +00:00
|
|
|
|
# Increase file shared link view_cnt, this operation should be atomic
|
|
|
|
|
fileshare = FileShare.objects.get(token=token)
|
|
|
|
|
fileshare.view_cnt = F('view_cnt') + 1
|
|
|
|
|
fileshare.save()
|
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
return render_to_response('view_shared_file.html', {
|
|
|
|
|
'repo': repo,
|
|
|
|
|
'obj_id': obj_id,
|
|
|
|
|
'path': path,
|
|
|
|
|
'file_name': filename,
|
2012-07-12 08:14:21 +00:00
|
|
|
|
'shared_token': token,
|
2012-07-11 14:39:36 +00:00
|
|
|
|
'access_token': access_token,
|
|
|
|
|
'can_preview': can_preview,
|
|
|
|
|
'filetype': filetype,
|
|
|
|
|
'raw_path': raw_path,
|
|
|
|
|
'username': username,
|
|
|
|
|
}, context_instance=RequestContext(request))
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def remove_shared_link(request):
|
|
|
|
|
"""
|
2012-07-13 03:22:20 +00:00
|
|
|
|
Handle request to remove file shared link.
|
2012-07-11 14:39:36 +00:00
|
|
|
|
"""
|
2012-07-13 03:22:20 +00:00
|
|
|
|
token = request.GET.get('t', '')
|
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
if not request.is_ajax():
|
2012-07-13 03:22:20 +00:00
|
|
|
|
FileShare.objects.filter(token=token).delete()
|
|
|
|
|
return HttpResponseRedirect(reverse('share_admin'))
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
|
|
FileShare.objects.filter(token=token).delete()
|
|
|
|
|
|
|
|
|
|
msg = '删除成功'
|
|
|
|
|
data = json.dumps([{'msg': msg}])
|
|
|
|
|
return HttpResponse(data, status=200, content_type=content_type)
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def send_shared_link(request):
|
|
|
|
|
"""
|
|
|
|
|
Handle ajax post request to share file shared link.
|
|
|
|
|
"""
|
|
|
|
|
if not request.is_ajax() and not request.method == 'POST':
|
|
|
|
|
raise Http404
|
|
|
|
|
|
|
|
|
|
content_type = 'application/json; charset=utf-8'
|
|
|
|
|
|
|
|
|
|
form = FileLinkShareForm(request.POST)
|
|
|
|
|
if not form.is_valid():
|
|
|
|
|
err = '发送失败'
|
|
|
|
|
data = json.dumps([{'error':err}])
|
|
|
|
|
return HttpResponse(data, status=400, content_type=content_type)
|
|
|
|
|
|
|
|
|
|
email = form.cleaned_data['email']
|
|
|
|
|
file_shared_link = form.cleaned_data['file_shared_link']
|
|
|
|
|
|
|
|
|
|
# Handle the diffent separator
|
|
|
|
|
to_email_str = email.replace(';',',')
|
|
|
|
|
to_email_str = to_email_str.replace('\n',',')
|
|
|
|
|
to_email_str = to_email_str.replace('\r',',')
|
|
|
|
|
to_email_list = to_email_str.split(',')
|
|
|
|
|
|
|
|
|
|
t = loader.get_template('shared_link_email.html')
|
2012-07-12 08:14:21 +00:00
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
for to_email in to_email_list:
|
2012-07-12 08:14:21 +00:00
|
|
|
|
to_email = to_email.strip(' ')
|
|
|
|
|
if not to_email:
|
|
|
|
|
continue
|
|
|
|
|
|
2012-07-11 14:39:36 +00:00
|
|
|
|
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:
|
|
|
|
|
err = '发送失败'
|
|
|
|
|
data = json.dumps([{'error':err}])
|
2012-07-12 08:14:21 +00:00
|
|
|
|
return HttpResponse(data, status=500, content_type=content_type)
|
2012-07-11 14:39:36 +00:00
|
|
|
|
|
|
|
|
|
msg = '发送成功。'
|
|
|
|
|
data = json.dumps([{'msg': msg}])
|
|
|
|
|
return HttpResponse(data, status=200, content_type=content_type)
|