diff --git a/organizations/middleware.py b/organizations/middleware.py index abaeef2d77..da3df3febb 100644 --- a/organizations/middleware.py +++ b/organizations/middleware.py @@ -12,8 +12,6 @@ class OrganizationMiddleware(object): """ def process_request(self, request): - """ - """ # Get current org context org = cache.get(ORG_CACHE_PREFIX + request.user.username) request.user.org = org diff --git a/organizations/signals.py b/organizations/signals.py index 92896da493..a19bc636e1 100644 --- a/organizations/signals.py +++ b/organizations/signals.py @@ -1,4 +1,3 @@ import django.dispatch org_user_added = django.dispatch.Signal(providing_args=["org_id", "from_email", "to_email"]) - diff --git a/organizations/templates/organizations/change_account.html b/organizations/templates/organizations/change_account.html deleted file mode 100644 index 597838ea1a..0000000000 --- a/organizations/templates/organizations/change_account.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends base_template %} -{% load avatar_tags %} - -{% block left_panel %} - -

操作

- - -{% endblock %} - -{% block right_panel %} -
-

切换帐号

- - - - - - - - - -{% for org in orgs %} - - - - -{% endfor %} -
名称操作
{{ request.user}}
{{ org.org_name }}
-
- -
-
-
- -{% endblock %} - -{% block extra_script %} - -{% endblock %} - diff --git a/organizations/templates/organizations/create_org.html b/organizations/templates/organizations/create_org.html index 1d3456dae2..fdc34f112e 100644 --- a/organizations/templates/organizations/create_org.html +++ b/organizations/templates/organizations/create_org.html @@ -1,9 +1,9 @@ {% extends base_template %} {% block main_panel %}
-

创建企业帐号

+

创建团体帐号

- + {{ form.org_name}} 域名前缀: {{ form.url_prefix }} diff --git a/organizations/templates/organizations/org_info.html b/organizations/templates/organizations/org_info.html index abb8ec6908..d4ba6b6365 100644 --- a/organizations/templates/organizations/org_info.html +++ b/organizations/templates/organizations/org_info.html @@ -41,7 +41,7 @@ {% if repos %} {% for repo in repos %} - {{ repo.props.name }} + {{ repo.props.name }} {{ repo.props.desc }} {% if repo.latest_modify %} {{ repo.latest_modify|translate_commit_time }} @@ -50,33 +50,22 @@ {% endif %} 同步 - + 共享 删除 {% endfor %} {% endif %} -
+ +{% include "snippets/repo_share_form.html" %} +{% include "snippets/repo_create_form.html" %} + {% endblock %} {% block extra_script %} {% endblock %} diff --git a/organizations/urls.py b/organizations/urls.py index 0915da394c..2683e56796 100644 --- a/organizations/urls.py +++ b/organizations/urls.py @@ -6,14 +6,12 @@ from seahub.views import repo, repo_history, org_seafadmin, \ urlpatterns = patterns('', url(r'^create/$', create_org, name='create_org'), - (r'^change_account/$', change_account), url(r'^messages/$', org_msg, name='org_msg'), - url(r'^(?P[^/]+)/$', org_info, name='org_info'), url(r'^(?P[^/]+)/groups/$', org_groups, name='org_groups'), - url(r'^([^/]+)/repo/(?P[^/]+)/$', repo, name='repo'), url(r'^([^/]+)/repo/history/(?P[^/]+)/$', repo_history, name='org_repo_history'), + url(r'^([^/]+)/repo/create/$', org_repo_create, name='org_repo_create'), ### Org admin ### url(r'^([^/]+)/seafadmin/$', org_seafadmin, name='org_seafadmin'), diff --git a/organizations/views.py b/organizations/views.py index 4fdf4c5a7b..1ae4a755da 100644 --- a/organizations/views.py +++ b/organizations/views.py @@ -12,7 +12,7 @@ from auth.decorators import login_required from pysearpc import SearpcError from seaserv import ccnet_threaded_rpc, get_orgs_by_user, get_org_repos, \ get_org_by_url_prefix, create_org, get_user_current_org, add_org_user, \ - get_ccnetuser, remove_org_user, get_org_groups + get_ccnetuser, remove_org_user, get_org_groups, is_valid_filename from forms import OrgCreateForm from signals import org_user_added @@ -25,11 +25,10 @@ from seahub.utils import go_error, go_permission_error, validate_group_name, \ emails2list, gen_token from seahub.views import myhome - @login_required def create_org(request): """ - + Create org account. """ if request.method == 'POST': form = OrgCreateForm(request.POST) @@ -53,20 +52,10 @@ def create_org(request): 'form': form, }, context_instance=RequestContext(request)) -@login_required -def change_account(request): - """ - - """ - orgs = get_orgs_by_user(request.user.username) - - return render_to_response('organizations/change_account.html', { - 'orgs': orgs, - }, context_instance=RequestContext(request)) - @login_required def org_info(request, url_prefix): """ + Show org info page. """ org = get_user_current_org(request.user.username, url_prefix) if not org: @@ -77,16 +66,19 @@ def org_info(request, url_prefix): org_members = ccnet_threaded_rpc.get_org_emailusers(url_prefix, 0, sys.maxint) repos = get_org_repos(org.org_id, 0, sys.maxint) + + url = 'organizations/%s/repo/create/' % org.url_prefix return render_to_response('organizations/org_info.html', { 'org': org, 'org_users': org_members, 'repos': repos, + 'url': seahub_settings.SITE_ROOT + url, }, context_instance=RequestContext(request)) @login_required def org_groups(request, url_prefix): """ - + List org groups and add org group. """ org = get_user_current_org(request.user.username, url_prefix) if not org: @@ -232,8 +224,64 @@ def org_msg(request): # remove new org msg notification UserNotification.objects.filter(to_user=request.user.username, msg_type='org_msg').delete() - print orgmsg_list + return render_to_response('organizations/new_msg.html', { 'orgmsg_list': orgmsg_list, }, context_instance=RequestContext(request)) + +@login_required +def org_repo_create(request): + ''' + Handle ajax post to create org repo. + ''' + if request.method != 'POST': + return Http404 + repo_name = request.POST.get("repo_name") + repo_desc = request.POST.get("repo_desc") + encrypted = int(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 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 == 1: + 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) + + try: + user = request.user.username + org_id = request.user.org['org_id'] + repo_id = create_org_repo(repo_name, repo_desc, user, passwd, org_id) + result['success'] = True + except: + result['error'] = u"创建目录失败" + else: + if not repo_id: + result['error'] = u"创建目录失败" + + return HttpResponse(json.dumps(result), content_type=content_type) diff --git a/templates/myhome.html b/templates/myhome.html index 07b75584f4..a29146bf2f 100644 --- a/templates/myhome.html +++ b/templates/myhome.html @@ -152,165 +152,13 @@

暂无

{% endif %} - -
- - -

可以是非网站注册用户,我们会以邮件通知对方。

-

(如未收到,请检查垃圾邮件)

-

输入不能为空。

- - - -
-

新建同步目录

-
-
-
- -
-
- (3到15个字符)
-
-
- -
-

- -
+{% include "snippets/repo_share_form.html" %} +{% include "snippets/repo_create_form.html" %} {% endblock %} {% block extra_script %} {% endblock %} diff --git a/templates/myhome_extra_script.html b/templates/myhome_extra_script.html new file mode 100644 index 0000000000..11aab2f879 --- /dev/null +++ b/templates/myhome_extra_script.html @@ -0,0 +1,129 @@ +$(function() { + //repo-share-form share-list autocomplete + var share_list = []; + {% for contact in contacts %} + share_list.push('{{ contact.contact_email }}'); + {% endfor %} + + {% for group in groups %} + share_list.push('{{ group.props.group_name }} <{{ group.props.creator_name }}>'); + {% endfor %} + + $(".repo-share-btn").click(function() { + $("#repo_id").val($(this).attr("data")); + $("#repo-share-form").modal({appendTo: "#main"}); + addAutocomplete('#email_or_group', '#repo-share-form', share_list); + }); + + //check before post + $('#share-submit-btn').click(function() { + if (!$.trim($('#email_or_group').attr('value'))) { + $('#repo-share-form .error').removeClass('hide'); + $('#simplemodal-container').css('height', $('#repo-share-form').height()); + return false; + } + }); + + addConfirmTo($('.repo-delete-btn')); + + addConfirmTo($('.unshare-btn'), '确定要取消共享?'); + + $(".download-btn").click(function() { + window.open('{{ SITE_ROOT }}seafile_access_check/?repo_id=' + $(this).attr('data')); + }); + +//show op images when mouse hover on + $("table tr:gt(0)").hover( + function() { + $(this).find('img').css('cursor', 'pointer').removeClass('vh'); + }, + function() { + $(this).find('img').addClass('vh'); + } + ); +}); + +//repo-create-form +$('#repo-create').hover( + function() { + $(this).css({'background-color': '#fff', 'cursor': 'pointer'}); + }, + function() { + $(this).css('background-color', '#f5f5f5'); + } +); +$('#repo-create').click(function() { + $('#repo-create-form').modal({appendTo: '#main', autoResize: true}); +}); +$('#encrypt-switch').click(function () { + if ($(this).attr('checked')) { + $('#repo-create-form input[type="password"]').attr('disabled', false).removeClass('input-disabled'); + } else { + $('#repo-create-form input[type="password"]').attr('disabled', true).addClass('input-disabled'); + } +}); +function showError(err) { + $('#repo-create-form .error').html(err).attr('class','error'); + $('#simplemodal-container').css('height', $('#repo-create-form').height()); +} +$('#repo-create-submit').click(function() { + var passwd = $('#repo-create-form input[name="passwd"]'), + passwd_again = $('#repo-create-form input[name="passwd_again"]'); + + if (!$('#repo-name').val()) { + showError('目录名不能为空。'); + return false; + } + if (!$('#repo-desc').val()) { + showError('描述不能为空。'); + return false; + } + + if ($('#encrypt-switch').attr('checked')) { + if (!passwd.val()) { + showError('密码不能为空。'); + return false; + } + if (!passwd_again.val()) { + showError('请确认密码。'); + return false; + } + if (passwd.val().length < 3) { + showError('密码太短。'); + return false; + } + if (passwd.val().length > 15) { + showError('密码太长。'); + return false; + } + if (passwd.val() != passwd_again.val()) { + showError('两次输入的密码不一致。'); + return false; + } + } + + $.ajax({ + url: '{{ url }}', + type: 'POST', + dataType: 'json', + cache: 'false', + contentType: 'application/json; charset=utf-8', + beforeSend: prepareCSRFToken, + data: { + 'repo_name': $('#repo-name').val(), + 'repo_desc': $('#repo-desc').val(), + 'encryption': $('#encrypt-switch').attr('checked') ? 1 : 0, + 'passwd': passwd.val(), + 'passwd_again': passwd_again.val() + }, + success: function(data) { + if (data['success']) { + location.reload(true); + } else { + showError(data['error']); + } + } + }); + + return false; +}); \ No newline at end of file diff --git a/templates/snippets/myhome_extra_script.html b/templates/snippets/myhome_extra_script.html new file mode 100644 index 0000000000..f586af9284 --- /dev/null +++ b/templates/snippets/myhome_extra_script.html @@ -0,0 +1,130 @@ +$(function() { + //repo-share-form share-list autocomplete + var share_list = []; + {% for contact in contacts %} + share_list.push('{{ contact.contact_email }}'); + {% endfor %} + + {% for group in groups %} + share_list.push('{{ group.props.group_name }} <{{ group.props.creator_name }}>'); + {% endfor %} + + $(".repo-share-btn").click(function() { + $("#repo_id").val($(this).attr("data")); + $("#repo-share-form").modal({appendTo: "#main"}); + addAutocomplete('#email_or_group', '#repo-share-form', share_list); + }); + + //check before post + $('#share-submit-btn').click(function() { + if (!$.trim($('#email_or_group').attr('value'))) { + $('#repo-share-form .error').removeClass('hide'); + $('#simplemodal-container').css('height', $('#repo-share-form').height()); + return false; + } + }); + + addConfirmTo($('.repo-delete-btn')); + + addConfirmTo($('.unshare-btn'), '确定要取消共享?'); + + $(".download-btn").click(function() { + window.open('{{ SITE_ROOT }}seafile_access_check/?repo_id=' + $(this).attr('data')); + }); + +//show op images when mouse hover on + $("table tr:gt(0)").hover( + function() { + $(this).find('img').css('cursor', 'pointer').removeClass('vh'); + }, + function() { + $(this).find('img').addClass('vh'); + } + ); +}); + +//repo-create-form +$('#repo-create').hover( + function() { + $(this).css({'background-color': '#fff', 'cursor': 'pointer'}); + }, + function() { + $(this).css('background-color', '#f5f5f5'); + } +); +$('#repo-create').click(function() { + $('#repo-create-form').modal({appendTo: '#main', autoResize: true}); +}); +$('#encrypt-switch').click(function () { + if ($(this).attr('checked')) { + $('#repo-create-form input[type="password"]').attr('disabled', false).removeClass('input-disabled'); + } else { + $('#repo-create-form input[type="password"]').attr('disabled', true).addClass('input-disabled'); + } +}); +function showError(err) { + $('#repo-create-form .error').html(err).attr('class','error'); + $('#simplemodal-container').css('height', $('#repo-create-form').height()); +} +$('#repo-create-submit').click(function() { + var passwd = $('#repo-create-form input[name="passwd"]'), + passwd_again = $('#repo-create-form input[name="passwd_again"]'); + + if (!$('#repo-name').val()) { + showError('目录名不能为空。'); + return false; + } + if (!$('#repo-desc').val()) { + showError('描述不能为空。'); + return false; + } + + if ($('#encrypt-switch').attr('checked')) { + if (!passwd.val()) { + showError('密码不能为空。'); + return false; + } + if (!passwd_again.val()) { + showError('请确认密码。'); + return false; + } + if (passwd.val().length < 3) { + showError('密码太短。'); + return false; + } + if (passwd.val().length > 15) { + showError('密码太长。'); + return false; + } + if (passwd.val() != passwd_again.val()) { + showError('两次输入的密码不一致。'); + return false; + } + } + + $.ajax({ + url: '{{ url }}', + type: 'POST', + dataType: 'json', + cache: 'false', + contentType: 'application/json; charset=utf-8', + beforeSend: prepareCSRFToken, + data: { + 'repo_name': $('#repo-name').val(), + 'repo_desc': $('#repo-desc').val(), + 'encryption': $('#encrypt-switch').attr('checked') ? 1 : 0, + 'passwd': passwd.val(), + 'passwd_again': passwd_again.val() + }, + success: function(data) { + alert(data); + if (data['success']) { + location.reload(true); + } else { + showError(data['error']); + } + } + }); + + return false; +}); \ No newline at end of file diff --git a/templates/snippets/repo_create_form.html b/templates/snippets/repo_create_form.html new file mode 100644 index 0000000000..fa4adbfe5a --- /dev/null +++ b/templates/snippets/repo_create_form.html @@ -0,0 +1,16 @@ +
+

新建同步目录

+
+
+
+ +
+
+ (3到15个字符)
+
+
+ +
+

+ +
diff --git a/templates/snippets/repo_share_form.html b/templates/snippets/repo_share_form.html new file mode 100644 index 0000000000..9cf7999100 --- /dev/null +++ b/templates/snippets/repo_share_form.html @@ -0,0 +1,9 @@ +
+
+ + +

可以是非网站注册用户,我们会以邮件通知对方。

+

(如未收到,请检查垃圾邮件)

+

输入不能为空。

+ +
diff --git a/thirdpart/seaserv/__init__.py b/thirdpart/seaserv/__init__.py index a17520a5b0..1bf41765d1 100644 --- a/thirdpart/seaserv/__init__.py +++ b/thirdpart/seaserv/__init__.py @@ -9,7 +9,8 @@ from service import get_binding_peerids from service import get_ccnetuser, get_emailusers from service import get_group_repoids, check_group_staff 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 + get_user_current_org, add_org_user, remove_org_user, get_org_by_id, \ + is_valid_filename from service import CCNET_CONF_PATH diff --git a/thirdpart/seaserv/service.py b/thirdpart/seaserv/service.py index 6fff9f5a96..afe16eed0b 100644 --- a/thirdpart/seaserv/service.py +++ b/thirdpart/seaserv/service.py @@ -115,6 +115,14 @@ def get_emailusers(start, limit): # group.maintainers = group.props.maintainers.split(" ") # return group +def check_group_staff(group_id_int, user_or_username): + """Check where user is group staff""" + from seahub.base.accounts import CcnetUser + if isinstance(user_or_username, CcnetUser): + user_or_username = user_or_username.username + + return ccnet_threaded_rpc.check_group_staff(group_id_int, user_or_username) + def get_org_groups(org_id, start, limit): try: groups = ccnet_threaded_rpc.get_org_groups(org_id, 0, sys.maxint) @@ -198,6 +206,18 @@ def get_repos(): """ return seafserv_threaded_rpc.get_repo_list("", 100) +def create_org_repo(repo_name, repo_desc, user, passwd, org_id): + """ + Create org repo, return valid repo id if success. + """ + try: + repo_id = seafserv_threaded_rpc.create_org_repo(repo_name, repo_desc, + user, passwd, org_id) + except SearpcError: + repo_id = None + + return repo_id + def get_org_repos(org_id, start, limit): """ """ @@ -253,11 +273,13 @@ def get_group_repoids(group_id=None): repoid_list.append(repo_id) return repoid_list -def check_group_staff(group_id_int, user_or_username): - """Check where user is group staff""" - from seahub.base.accounts import CcnetUser - if isinstance(user_or_username, CcnetUser): - user_or_username = user_or_username.username - - return ccnet_threaded_rpc.check_group_staff(group_id_int, user_or_username) +def is_valid_filename(file_or_dir): + """ + Check whether file name or directory name is valid. + """ + try: + ret = seafserv_threaded_rpc.is_valid_filename('', file_or_dir) + except SearpcError: + ret = 0 + return ret diff --git a/views.py b/views.py index d830279670..d14a1f846f 100644 --- a/views.py +++ b/views.py @@ -28,7 +28,7 @@ from auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, \ from auth.tokens import default_token_generator from share.models import FileShare from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, get_emailusers, \ - get_repo, get_commits, get_branches, \ + get_repo, get_commits, get_branches, is_valid_filename, \ seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \ get_group_repoids, check_group_staff, get_personal_groups from pysearpc import SearpcError @@ -744,6 +744,7 @@ def myhome(request): "orgmsg_list": orgmsg_list, "groups_manage": groups_manage, "groups_join": groups_join, + "url": settings.SITE_ROOT + 'repo/create/', }, context_instance=RequestContext(request)) @login_required @@ -1596,7 +1597,7 @@ def repo_new_dir(request): return go_error (request, error_msg) try: - if not seafserv_threaded_rpc.is_valid_filename(repo_id, new_dir_name): + if not is_valid_filename(new_dir_name): error_msg = (u"您输入的目录名称 %s 包含非法字符" % new_dir_name) return go_error (request, error_msg) except SearpcError,e: @@ -1651,7 +1652,7 @@ def validate_filename(request): result = {'ret':'yes'} try: - ret = seafserv_threaded_rpc.is_valid_filename (repo_id, filename); + ret = is_valid_filename(filename); except SearpcError: result['ret'] = 'error' else: @@ -1681,7 +1682,7 @@ def repo_create(request): error_msg = u"目录名不能为空" elif len(repo_name) > 50: error_msg = u"目录名太长" - elif not seafserv_threaded_rpc.is_valid_filename('', repo_name): + elif not is_valid_filename(repo_name): error_msg = (u"您输入的目录名 %s 包含非法字符" % repo_name) elif not repo_desc: error_msg = u"描述不能为空"