1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 18:29:23 +00:00

Added org repo share

This commit is contained in:
xiez
2012-09-03 12:03:06 +08:00
parent 20fc024f15
commit 29c9ff11df
11 changed files with 354 additions and 56 deletions

View File

@@ -32,7 +32,6 @@ from seahub.views import is_registered_user
from seahub.forms import RepoCreateForm
@login_required
@ctx_switch_required
def group_list(request):
error_msg = None
if request.method == 'POST':
@@ -472,6 +471,7 @@ def group_remove_member(request, group_id, user_name):
return HttpResponseRedirect(reverse('group_members', args=[group_id]))
@login_required
def group_share_repo(request, repo_id, group_id, from_email):
"""
Share a repo to a group.
@@ -494,15 +494,16 @@ def group_share_repo(request, repo_id, group_id, from_email):
if seafserv_threaded_rpc.group_share_repo(repo_id, group_id, from_email, 'rw') != 0:
return render_error(request, u'共享失败:内部错误')
@login_required
def group_unshare_repo(request, repo_id, group_id, from_email):
"""
unshare a repo to a group
Unshare a repo in group.
"""
# Check whether group exists
group = get_group(group_id)
if not group:
return render_error(request, u'共享失败:小组不存在')
return render_error(request, u'取消共享失败:小组不存在')
# Check whether user belong to the group
joined = False
@@ -511,7 +512,7 @@ def group_unshare_repo(request, repo_id, group_id, from_email):
if group.props.id == group_id:
joined = True
if not joined:
return render_error(request, u'共享失败:未加入该小组')
return render_error(request, u'取消共享失败:未加入该小组')
# Check whether user is group staff or the one share the repo
if not check_group_staff(group_id, from_email) and \
@@ -519,7 +520,7 @@ def group_unshare_repo(request, repo_id, group_id, from_email):
return render_permission_error(request, u'取消共享失败:只有小组管理员或共享目录发布者有权取消共享')
if seafserv_threaded_rpc.group_unshare_repo(repo_id, group_id, from_email) != 0:
return render_error(request, u'共享失败:内部错误')
return render_error(request, u'取消共享失败:内部错误')
@login_required
def group_recommend(request):

View File

@@ -62,6 +62,38 @@
{% endif %}
</table>
<h3>共享给我的同步目录</h3>
{% if in_repos %}
<table>
<tr>
<th width="25%">名字</th>
<th width="20%">共享来源</th>
<th width="25%">描述</th>
<th width="20%">更新时间</th>
<th width="10%">操作</th>
</tr>
{% for repo in in_repos %}
<tr>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}">{{ repo.props.name }}</a></td>
<td>{{ repo.props.shared_email }}</td>
<td>{{ repo.props.desc }}</td>
{% if repo.latest_modify %}
<td>{{ repo.latest_modify|translate_commit_time }}</td>
{% else %}
<td>--</td>
{% endif %}
<td>
<img src="{{ MEDIA_URL }}img/sync-20.png" data="{{ repo.props.id }}" class="download-btn vh" title="同步到本地" alt="同步" />
<img src="{{ MEDIA_URL }}img/delete-20.png" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.id }}&from={{ repo.shared_email }}&to={{ request.user }}" class="unshare-btn vh" title="取消共享" alt="取消共享" />
</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>暂无</p>
{% endif %}
{% url 'org_repo_share' org.url_prefix as repo_share_url %}
{% with post_url=repo_share_url %}
{% include "snippets/repo_share_form.html" %}

View File

@@ -0,0 +1,99 @@
{% extends "org_base.html" %}
{% load seahub_tags %}
{% block nav_shareadmin_class %}class="cur"{% endblock %}
{% block right_panel %}
{% if messages %}
{% autoescape off %}
<ul class="messages hide">
{% for message in messages %}
<li class="info">{{ message }}</li>
{% endfor %}
</ul>
{% endautoescape %}
{% endif %}
<h3>我共享的同步目录</h3>
{% if out_repos %}
<table class="repo-list">
<tr>
<th width="20%">名字</th>
<th width="25%">共享给</th>
<th width="47%">描述</th>
<th width="8%">操作</th>
</tr>
{% for repo in out_repos %}
<tr>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}">{{ repo.props.name }}</a></td>
<td>{{ repo.props.shared_email }}</td>
<td>{{ repo.props.desc }}</td>
<td>
{% if repo.gid %}
<img src="{{ MEDIA_URL }}img/delete-20.png" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.id }}&from={{ request.user }}&gid={{ repo.gid }}" class="cancel-share vh" alt="取消共享" title="取消共享" />
{% else %}
<img src="{{ MEDIA_URL }}img/delete-20.png" data="{{ SITE_ROOT }}shareadmin/removeshare/?repo_id={{ repo.props.id }}&from={{ request.user }}&to={{ repo.props.shared_email }}" class="cancel-share vh" alt="取消共享" title="取消共享" />
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% else %}
<p>暂无</p>
{% endif %}
<h3>我管理的文件外链</h3>
{% if fileshares %}
<table class="sharelink-list">
<tr>
<th width="25%">文件名</th>
<th width="35%">所属目录</th>
<th width="20%">查看次数</th>
<th width="20%">操作</th>
</tr>
{% for fs in fileshares %}
<tr>
<td><a href="{{ SITE_ROOT }}repo/{{ fs.repo.id }}/files/?p={{ fs.path|urlencode }}">{{ fs.filename }}</a></td>
<td><a href="{{ SITE_ROOT }}repo/{{ fs.repo.id }}/">{{ fs.repo.name }}</a></td>
<td>{{ fs.view_cnt }}</td>
<td><a href="#" class="op view-file-link" data="{{ fs.token }}">查看链接</a>
<a class="op" href="{{ SITE_ROOT }}sharedlink/remove/?t={{ fs.token }}">删除</a></td>
</tr>
{% endfor %}
</table>
{% else %}
<p>暂无</p>
{% endif %}
<div id="view-link" name="view-link" class="hide">
<span class="view-link-alert" style="float:left; "></span>
</div>
{% endblock %}
{% block extra_script %}
<script type="text/javascript">
$('.cancel-share').click(function() {
location.href = $(this).attr('data');
});
$("table tr:gt(0)").hover(
function() {
$(this).find('img').css('cursor', 'pointer').removeClass('vh');
},
function() {
$(this).find('img').addClass('vh');
}
);
$(".view-file-link").click(function() {
var t = $(this).attr('data');
var l = '{{ protocol }}://' + '{{ domain }}{{ SITE_ROOT }}f/' + t + '/';
$('.view-link-alert').html("该文件外链为:<p>" + l + "</p>");
$("#view-link").modal({appendTo: "#main", containerCss:{padding:18}});
return false;
});
</script>
{% endblock %}

View File

@@ -13,7 +13,11 @@ urlpatterns = patterns('',
url(r'^(?P<url_prefix>[^/]+)/groups/$', org_groups, name='org_groups'),
url(r'^([^/]+)/repo/create/$', org_repo_create, name='org_repo_create'),
url(r'^([^/]+)/repo/history/(?P<repo_id>[^/]+)/$', repo_history, name='org_repo_history'),
# repo share
url(r'^(?P<url_prefix>[^/]+)/shareadmin/$', org_shareadmin, name='org_shareadmin'),
url(r'^(?P<url_prefix>[^/]+)/repo/share/$', org_repo_share, name='org_repo_share'),
url(r'^(?P<url_prefix>[^/]+)/repo/unshare/$', org_repo_unshare, name='org_repo_unshare'),
url(r'^([^/]+)/repo/(?P<repo_id>[^/]+)/$', repo, name='repo'),

View File

@@ -1,4 +1,5 @@
# encoding: utf-8
import os
import simplejson as json
import sys
from django.core.urlresolvers import reverse
@@ -12,18 +13,19 @@ from django.template import Context, loader, RequestContext
from auth.decorators import login_required
from pysearpc import SearpcError
from seaserv import ccnet_threaded_rpc, seafserv_threaded_rpc, \
from seaserv import ccnet_threaded_rpc, seafserv_threaded_rpc, get_repo, \
get_orgs_by_user, get_org_repos, list_org_inner_pub_repos, \
get_org_by_url_prefix, create_org, get_user_current_org, add_org_user, \
remove_org_user, get_org_groups, is_valid_filename, org_user_exists, \
create_org_repo, get_org_id_by_group, get_org_groups_by_user, \
get_org_users_by_url_prefix
get_org_users_by_url_prefix, list_org_shared_repos, is_personal_repo
from decorators import org_staff_required
from forms import OrgCreateForm
from signals import org_user_added
from utils import validate_org_repo_owner
from notifications.models import UserNotification
from share.models import FileShare
from share.forms import RepoShareForm
from registration.models import RegistrationProfile
from seahub.base.accounts import User
@@ -98,17 +100,27 @@ def org_personal(request, url_prefix):
calculate_repo_last_modify(owned_repos)
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
# org groups user created
# Org repos others shared to me
in_repos = list_org_shared_repos(user,'to_email', -1, -1)
# Org groups user created
groups = get_org_groups_by_user(org.org_id, user)
# org members used in auto complete
# Org members used in auto complete
contacts = []
org_members = get_org_users_by_url_prefix(org.url_prefix, 0, MAX_INT)
for m in org_members:
if m.email == user: # shouldn' show my'email in auto complete
continue
m.contact_email = m.email
contacts.append(m)
return render_to_response('organizations/personal.html', {
'owned_repos': owned_repos,
"in_repos": in_repos,
'org': org,
'groups': groups,
'org_members': org_members,
'contacts': contacts,
}, context_instance=RequestContext(request))
@login_required
@@ -476,30 +488,97 @@ def org_repo_share(request, url_prefix):
'base_template': 'org_base.html',
})
to_email_list = string2list(email_or_group)
for to_email in to_email_list:
# if to_email is user name, the format is: 'example@mail.com';
# if to_email is group, the format is 'group_name <creator@mail.com>'
if (to_email.split(' ')[0].find('@') == -1):
pass
share_to_list = string2list(email_or_group)
for share_to in share_to_list:
# if share_to is user name, the format is: 'example@mail.com';
# if share_to is group, the format is 'group_name <creator@mail.com>'
if (share_to.split(' ')[0].find('@') == -1):
''' Share repo to group '''
# TODO: if we know group id, then we can simplly call group_share_repo
if len(share_to.split(' ')) < 2:
msg = u'共享给 %s 失败。' % share_to
messages.add_message(request, messages.ERROR, msg)
continue
group_name = share_to.split(' ')[0]
group_creator = share_to.split(' ')[1]
# get org groups the user joined
groups = get_org_groups_by_user(org.org_id, from_email)
find = False
for group in groups:
# for every group that user joined, if group name and
# group creator matchs, then has finded the group
if group.props.group_name == group_name and \
group_creator.find(group.props.creator_name) >= 0:
seafserv_threaded_rpc.add_org_group_repo(repo_id,
org.org_id,
group.id,
from_email,
'rw')
find = True
msg = u'共享到 %s 成功,请前往<a href="%s">共享管理</a>查看。' % \
(group_name, reverse('org_shareadmin', args=[org.url_prefix]))
messages.add_message(request, messages.INFO, msg)
break
if not find:
msg = u'共享到 %s 失败。' % group_name
messages.add_message(request, messages.ERROR, msg)
else:
''' Share repo to user '''
# Test whether to_email is in this org
if not org_user_exists(org.org_id, to_email):
msg = u'共享给 %s 失败:团体中不存在该用户。' % to_email
# Test whether share_to is in this org
if not org_user_exists(org.org_id, share_to):
msg = u'共享给 %s 失败:团体中不存在该用户。' % share_to
messages.add_message(request, messages.ERROR, msg)
continue
# Record share info to db.
try:
seafserv_threaded_rpc.add_share(repo_id, from_email, to_email,
seafserv_threaded_rpc.add_share(repo_id, from_email, share_to,
'rw')
msg = u'共享给 %s 成功,请前往<a href="%s">共享管理</a>查看。' % \
(to_email, reverse('share_admin'))
(share_to, reverse('org_shareadmin', args=[org.url_prefix]))
messages.add_message(request, messages.INFO, msg)
except SearpcError, e:
msg = u'共享给 %s 失败。' % to_email
msg = u'共享给 %s 失败。' % share_to
messages.add_message(request, messages.ERROR, msg)
continue
return HttpResponseRedirect(reverse(org_personal, args=[org.url_prefix]))
@login_required
def org_repo_unshare(request, url_prefix):
pass
@login_required
def org_shareadmin(request, url_prefix):
"""
List personal repos I share to others, include groups and users.
"""
username = request.user.username
org = get_user_current_org(request.user.username, url_prefix)
if not org:
return HttpResponseRedirect(reverse(myhome))
# org repos that are shared to others
out_repos = list_org_shared_repos(username, 'from_email', -1, -1)
# File shared links
fileshares = FileShare.objects.filter(username=request.user.username)
o_fileshares = [] # shared files in org repos
for fs in fileshares:
if not is_personal_repo(fs.repo_id):
# only list files in org repos
fs.filename = os.path.basename(fs.path)
fs.repo = get_repo(fs.repo_id)
o_fileshares.append(fs)
return render_to_response('organizations/share_admin.html', {
"org": org,
"out_repos": out_repos,
"fileshares": o_fileshares,
"protocol": request.is_secure() and 'https' or 'http',
"domain": RequestSite(request).domain,
}, context_instance=RequestContext(request))

View File

@@ -4,6 +4,16 @@
{% block nav_shareadmin_class %}class="cur"{% endblock %}
{% block right_panel %}
{% if messages %}
{% autoescape off %}
<ul class="messages hide">
{% for message in messages %}
<li class="info">{{ message }}</li>
{% endfor %}
</ul>
{% endautoescape %}
{% endif %}
<h3>我共享的同步目录</h3>
{% if out_repos %}
<table class="repo-list">

View File

@@ -11,7 +11,8 @@ from django.contrib import messages
from django.contrib.sites.models import Site, RequestSite
from pysearpc import SearpcError
from seaserv import seafserv_threaded_rpc, get_repo, ccnet_rpc, \
ccnet_threaded_rpc, get_personal_groups
ccnet_threaded_rpc, get_personal_groups, list_personal_shared_repos, \
is_personal_repo
from forms import RepoShareForm
from models import AnonymousShare
@@ -109,14 +110,12 @@ def share_repo(request):
@login_required
def share_admin(request):
"""
List repos I share to others, include groups and users. And also list
file shared links I generated.
List personal repos I share to others, include groups and users.
"""
username = request.user.username
# repos that are share to user
out_repos = seafserv_threaded_rpc.list_share_repos(username, 'from_email',
-1, -1)
# personal repos that are share to user
out_repos = list_personal_shared_repos(username, 'from_email', -1, -1)
# repos that are share to groups
group_repos = seafserv_threaded_rpc.get_group_my_share_repos(request.user.username)
@@ -145,14 +144,18 @@ def share_admin(request):
# File shared links
fileshares = FileShare.objects.filter(username=request.user.username)
p_fileshares = [] # personal file share
for fs in fileshares:
fs.filename = os.path.basename(fs.path)
fs.repo = get_repo(fs.repo_id)
if is_personal_repo(fs.repo_id):
# only list files in personal repos
fs.filename = os.path.basename(fs.path)
fs.repo = get_repo(fs.repo_id)
p_fileshares.append(fs)
return render_to_response('repo/share_admin.html', {
"out_repos": out_repos,
# "out_links": out_links,
"fileshares": fileshares,
"fileshares": p_fileshares,
"protocol": request.is_secure() and 'https' or 'http',
"domain": RequestSite(request).domain,
}, context_instance=RequestContext(request))
@@ -223,5 +226,11 @@ def anonymous_share_confirm(request, token=None):
def remove_anonymous_share(request, token):
AnonymousShare.objects.filter(token=token).delete()
return HttpResponseRedirect(reverse('share_admin'))
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse('share_admin')
messages.add_message(request, messages.INFO, u'删除成功')
return HttpResponseRedirect(next)

View File

@@ -13,5 +13,8 @@
<li>
<a href="{% url 'organizations.views.org_personal' org.url_prefix %}" {% block nav_org_personal_class %}{% endblock %}>个人页面</a>
</li>
<li>
<a href="{% url 'organizations.views.org_shareadmin' org.url_prefix %}" {% block nav_shareadmin_class %}{% endblock %}>共享管理</a>
</li>
</ul>
{% endblock %}

View File

@@ -10,7 +10,9 @@ from service import get_org_groups, get_personal_groups, get_group_repoids, \
get_org_group_repos, get_group_repos, get_org_groups_by_user
from service import get_repos, get_repo, get_commits, get_branches, \
get_org_repos, is_repo_owner, create_org_repo, is_inner_pub_repo, \
list_org_inner_pub_repos, get_org_id_by_repo_id
list_org_inner_pub_repos, get_org_id_by_repo_id, list_org_shared_repos, \
list_personal_shared_repos, is_personal_repo
from service import get_binding_peerids, is_valid_filename, check_permission
from service import create_org, get_orgs_by_user, get_org_by_url_prefix, \
get_user_current_org, add_org_user, remove_org_user, get_org_by_id, \

View File

@@ -336,7 +336,7 @@ def get_org_id_by_repo_id(repo_id):
try:
org_id = seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id)
except SearpcError:
org_id = ''
org_id = -1
return org_id
def list_org_repos_by_owner(org_id, user):
@@ -522,3 +522,62 @@ def get_org_id_by_repo(repo_id):
org_id = -1
return org_id
def is_personal_repo(repo_id):
"""
Check whether repo is personal repo.
"""
try:
owner = seafserv_threaded_rpc.get_repo_owner(repo_id)
except SearpcError:
owner = ''
return True if owner else False
def list_personal_shared_repos(user, user_type, start, limit):
"""
List personal repos that user share with others.
If `user_type` is 'from_email', list repos user shares to others;
If `user_type` is 'to_email', list repos others sahre to user.
"""
try:
repos = seafserv_threaded_rpc.list_share_repos(user, user_type,
start, limit)
except SearpcError:
repos = []
p_repos = []
if repos:
for r in repos:
if is_personal_repo(r.id):
try:
r.latest_modify = get_commits(r.id, 0, 1)[0].ctime
except:
r.latest_modify = None
p_repos.append(r)
p_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
return p_repos
def list_org_shared_repos(user, user_type, start, limit):
"""
List org repos that user share with others.
If `user_type` is 'from_email', list repos user shares to others;
If `user_type` is 'to_email', list repos others sahre to user.
"""
try:
repos = seafserv_threaded_rpc.list_share_repos(user, user_type,
start, limit)
except SearpcError:
repos = []
o_repos = []
if repos:
for r in repos:
if not is_personal_repo(r.id):
try:
r.latest_modify = get_commits(r.id, 0, 1)[0].ctime
except:
r.latest_modify = None
o_repos.append(r)
o_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
return o_repos

View File

@@ -32,7 +32,8 @@ from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \
get_repo, get_commits, get_branches, is_valid_filename, remove_group_user,\
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, is_inner_pub_repo, \
check_group_staff, get_personal_groups, is_repo_owner, \
get_group, get_shared_groups_by_repo, is_group_user, check_permission
get_group, get_shared_groups_by_repo, is_group_user, check_permission, \
list_personal_shared_repos
from pysearpc import SearpcError
from base.accounts import User
@@ -43,7 +44,6 @@ from seahub.contacts.signals import mail_sended
from group.models import GroupMessage, MessageAttachment
from group.signals import grpmsg_added
from seahub.notifications.models import UserNotification
from seahub.organizations.utils import access_org_repo
from forms import AddUserForm, FileLinkShareForm, RepoCreateForm, \
RepoNewDirForm, RepoNewFileForm, FileCommentForm
from utils import render_permission_error, render_error, list_to_string, \
@@ -610,16 +610,13 @@ def myhome(request):
email = request.user.username
quota_usage = seafserv_threaded_rpc.get_user_quota_usage(email)
# Repos that I own
# Personal repos that I own
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
calculate_repo_last_modify(owned_repos)
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
# Repos shared with me
in_repos = seafserv_threaded_rpc.list_share_repos(email,
'to_email', -1, -1)
calculate_repo_last_modify(in_repos)
in_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
# Personal repos others shared to me
in_repos = list_personal_shared_repos(email,'to_email', -1, -1)
# my contacts
contacts = Contact.objects.filter(user_email=email)
@@ -1260,16 +1257,13 @@ def repo_remove_share(request):
from seahub.group.views import group_unshare_repo
group_unshare_repo(request, repo_id, group_id_int, from_email)
referer = request.META.get('HTTP_REFERER', None)
if not referer:
referer = 'share_admin'
return HttpResponseRedirect(reverse(referer))
else:
return HttpResponseRedirect(referer)
messages.add_message(request, messages.INFO, '操作成功')
# @login_required
# def mypeers(request):
# cid = get_user_cid(request.user)
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse(referer)
return HttpResponseRedirect(next)
@login_required
@sys_staff_required
@@ -1962,7 +1956,13 @@ def remove_shared_link(request):
if not request.is_ajax():
FileShare.objects.filter(token=token).delete()
return HttpResponseRedirect(reverse('share_admin'))
next = request.META.get('HTTP_REFERER', None)
if not next:
next = reverse('share_admin')
messages.add_message(request, messages.INFO, u'删除成功')
return HttpResponseRedirect(next)
content_type = 'application/json; charset=utf-8'