1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-30 13:23:14 +00:00

Merge branch 'sub-repo'

This commit is contained in:
zhengxie 2013-06-21 15:41:47 +08:00
commit aa4e334a12
7 changed files with 177 additions and 15 deletions

View File

@ -213,5 +213,5 @@ class RepoSettingForm(forms.Form):
repo_id = forms.CharField(error_messages={'required': _('Repo id is required')})
repo_name = forms.CharField(error_messages={'required': _('Library name is required')})
repo_desc = forms.CharField(error_messages={'required': _('Library description is required')})
days = forms.IntegerField(error_messages={'required': _('Days can\'t be empty'),
'invalid': _('Please enter a number')})
days = forms.IntegerField(required=False,
error_messages={'invalid': _('Please enter a number')})

View File

@ -346,6 +346,8 @@ SEND_EMAIL_ON_RESETTING_USER_PASSWD = True # Whether to send email when a system
ENABLE_PUBFILE = False
ENABLE_SUB_LIBRARY = False
#####################
# External settings #
#####################

View File

@ -119,6 +119,9 @@
{% if not repo.encrypted %}
<a class="op file-share" href="#" data-name="{{ dirent.obj_name }}" data-link="{{ dirent.sharelink }}" data-token="{{ dirent.sharetoken }}" data-type="d">{% trans "Share" %}</a>
{% endif %}
{% if ENABLE_SUB_LIBRARY and not repo.is_virtual %}
<a class="op create-sub-repo" href="#" data-name="{{ dirent.obj_name }}">{% trans "Sub-library" %}</a>
{% endif %}
</div>
{% if user_perm == 'rw' %}
<img src="{{ MEDIA_URL }}img/dropdown-arrow.png" title="{% trans 'More operations'%}" alt="{% trans 'More operations'%}" class="more-op-icon" data="no-popup" />
@ -239,12 +242,14 @@
<input type="text" name="repo_name" value="{{ repo.name }}" class="long-input" /><br />
<label>{% trans "Description" %}</label></br />
<input type="text" name="repo_desc" value="{{ repo.desc }}" class="long-input" /><br />
<label>{% trans "History" %}</label><br />
<input type="hidden" name="repo_id" value="{{ repo.id }}" />
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
<label>{% trans "History" %}</label><br />
<input type="radio" name="history" value="full_history" {% if history_limit < 0 %}checked="checked"{% endif %} /> {% trans "Keep full history" %}<br />
<input type="radio" name="history" value="no_history" {% if history_limit == 0 %}checked="checked"{% endif %} /> {% trans "Don't keep history" %}<br />
<input type="radio" name="history" value="partial_history" {% if history_limit > 0 %}checked="checked"{% endif %} /> {% trans "Only keep a period of history:" %}
<input type="text" name="days" size="4" {% if history_limit <= 0 %} disabled="disabled" class="input-disabled" {% else %} value="{{history_limit}}" {% endif %} /> {% trans "days" %}<br />
{% endif %}
<p class="error hide"></p>
<input type="submit" value="{% trans "Submit" %}" class="submit" />
<button class="simplemodal-close">{% trans "Cancel" %}</button>
@ -358,6 +363,7 @@ $('#repo-setting-btn').click(function () {
$('#repo-setting-form').modal({appendTo:'#main'});
});
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
$('#repo-setting-form input[name="history"]').change(function() {
var value = $(this).attr('value');
if (value == 'full_history' || value == 'no_history') {
@ -366,8 +372,10 @@ $('#repo-setting-form input[name="history"]').change(function() {
$('#repo-setting-form input[name="days"]').attr('disabled', false).removeClass('input-disabled');
}
});
{% endif %}
$('#repo-setting-form').submit(function() {
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
var days;
var value = $(this).find('input[name="history"]:checked').val();
@ -378,6 +386,7 @@ $('#repo-setting-form').submit(function() {
} else {
days = 0;
}
{% endif %}
var submit_btn = $(this).children('input[type="submit"]');
disable(submit_btn);
@ -390,7 +399,9 @@ $('#repo-setting-form').submit(function() {
'repo_id': $('#repo-setting-form input[name="repo_id"]').val(),
'repo_name': $('#repo-setting-form input[name="repo_name"]').val(),
'repo_desc': $('#repo-setting-form input[name="repo_desc"]').val(),
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
'days': days
{% endif %}
},
success: function(data) {
if (data['success']) {
@ -919,6 +930,45 @@ $('#mv-dir-list h5').click(function() {
next.addClass('hide');
}
});
{% if ENABLE_SUB_LIBRARY and not repo.is_virtual %}
$('.create-sub-repo').click(function() {
var repo_name = $(this).data('name');
var orig_path = '{{path}}' + repo_name;
feedback('{% trans "Creating sub-library..." %}', 'info');
$.ajax({
url: '{{ SITE_ROOT }}repo/create_sub_repo/',
type: 'POST',
cache: false,
beforeSend: prepareCSRFToken,
dataType: 'json',
data: {
orig_repo_id: '{{repo.id}}',
orig_path: orig_path,
repo_name: repo_name,
repo_desc: repo_name
},
success:function(data) {
if (data['success']) {
var sub_repo_id = data['repo_id'];
feedback('{% trans "Created sub-library" %} <a href="{{SITE_ROOT}}repo/' + sub_repo_id + '">' + repo_name + '</a>', 'info');
} else {
feedback(data['error'], 'error');
}
},
error:function(xhr, textStatus, errorThrown) {
if (xhr.responseText) {
feedback(jQuery.parseJSON(xhr.responseText).error, 'error');
} else {
feedback("{% trans "Failed. Please check the network." %}", 'error');
}
}
});
});
{% endif %}
{% if path == '/' %}
{% include "snippets/list_commit_detail.html" %}
{% endif %}

View File

@ -4,6 +4,9 @@
<div class="ovhd">
<ul class="fleft" id="tabs-nav">
<li><a href="#my-own-repos">{% trans "Mine" %}</a></li>
{% if ENABLE_SUB_LIBRARY %}
<li><a href="#my-sub-repos">{% trans "Sub-libraries" %}</a></li>
{% endif %}
<li><a href="#repos-shared-to-me">{% trans "Shared" %}</a></li>
<li><a href="#starred-files">{% trans "Starred" %}</a></li>
</ul>
@ -20,6 +23,7 @@
<th width="14%">{% trans "Operations" %}</th>
</tr>
{% for repo in owned_repos %}
{% if not ENABLE_SUB_LIBRARY or not repo.is_virtual %}
<tr>
<td><img src="{{MEDIA_URL}}img/sync-folder-20.png" title="{% trans "Read-Write" %}" alt="{% trans "directory icon" %}" /></td>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.props.id }}/">{{ repo.props.name }}</a></td>
@ -35,6 +39,7 @@
<span data-url="{{ SITE_ROOT }}repo/remove/{{ repo.props.id }}/?next={{ request.path }}" data-target="{{ repo.props.name }}" class="icon-trash repo-delete-btn op-icon vh" title="{% trans "Delete" %}"></span>
</td>
</tr>
{% endif %}
{% endfor %}
</table>
{% else %}
@ -47,6 +52,53 @@
</div>
{% endif %}
</div>
{% if ENABLE_SUB_LIBRARY %}
<div id="my-sub-repos" class="hide">
{% if sub_repos %}
<table>
<tr>
<th width="4%"><!--icon--></th>
<th width="24%">{% trans "Name" %}</th>
<th width="43%">{% trans "Origin" %}</th>
<th width="15%">{% trans "Last Update" %}</th>
<th width="14%">{% trans "Operations" %}</th>
</tr>
{% for repo in sub_repos %}
<tr>
<td>
{% if repo.virtual_perm == 'rw' %}
<img src="{{MEDIA_URL}}img/sync-folder-20.png" title="{% trans "Read-Write" %}" alt="{% trans "directory icon" %}" />
{% else %}
<img src="{{MEDIA_URL}}img/folder-no-write-20.png" title="{% trans "Read-Only" %}" alt="{% trans "directory icon" %}" />
{% endif %}
</td>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.id }}/">{{ repo.name }}</a></td>
<td><a href="{{ SITE_ROOT }}repo/{{ repo.origin_repo_id}}/?p={{ repo.origin_path }}">{{ repo.abbrev_origin_path }}</a></td>
{% if repo.latest_modify %}
<td>{{ repo.latest_modify|translate_seahub_time }}</td>
{% else %}
<td>--</td>
{% endif %}
<td>
<span data="{{ repo.props.id }}" class="icon-cloud-download download-btn op-icon vh" title="{% trans "Download and Sync" %}"></span>
{% if repo.is_original_owner %}
<span data-id="{{ repo.props.id }}" data-name="{{ repo.props.name }}" class="sf-icon-share repo-share-btn op-icon vh" title="{% trans "Share" %}"></span>
{% endif %}
<span data-url="{{ SITE_ROOT }}repo/remove/{{ repo.props.id }}/?next={{ request.path }}" data-target="{{ repo.props.name }}" class="icon-trash repo-delete-btn op-icon vh" title="{% trans "Delete" %}"></span>
</td>
</tr>
{% endfor %}
</table>
{% else %}
<div class="empty-tips">
<h2 class="center-contents">{% trans "You have not created any sub-libraries" %}</h2>
<p>{% trans "You can create a sub-library from a directory inside a library. A sub-library can be independently synced and shared. Files in the sub-library will be automatically kept in sync with the directory of the origin library." %}</p>
</div>
{% endif %}
</div>
{% endif %}
<div id="repos-shared-to-me" class="hide">
{% if in_repos %}
<table>
@ -92,6 +144,7 @@
</div>
{% endif %}
</div>
<div id="starred-files" class="hide">
{% if starred_files %}
<table>

View File

@ -81,6 +81,7 @@ urlpatterns = patterns('',
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/file/edit/$', file_edit, name='file_edit'),
url(r'^repo/(?P<repo_id>[-0-9a-f]{36})/(?P<obj_id>[^/]+)/$', repo_access_file, name='repo_access_file'),
(r'^repo/save_settings$', repo_save_settings),
url(r'^repo/create_sub_repo/$', create_sub_repo, name='create_sub_repo'),
url(r'^f/(?P<token>[a-f0-9]{10})/$', view_shared_file, name='view_shared_file'),
url(r'^d/(?P<token>[a-f0-9]{10})/$', view_shared_dir, name='view_shared_dir'),

View File

@ -85,7 +85,8 @@ if HAS_OFFICE_CONVERTER:
import seahub.settings as settings
from seahub.settings import FILE_PREVIEW_MAX_SIZE, INIT_PASSWD, USE_PDFJS, FILE_ENCODING_LIST, \
FILE_ENCODING_TRY_LIST, SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD
FILE_ENCODING_TRY_LIST, SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, SEND_EMAIL_ON_RESETTING_USER_PASSWD, \
ENABLE_SUB_LIBRARY
# Get an instance of a logger
logger = logging.getLogger(__name__)
@ -347,14 +348,15 @@ def repo_save_settings(request):
status=500, content_type=content_type)
# set library history
if days != None:
res = set_repo_history_limit(repo_id, days)
if res == 0:
if res != 0:
return HttpResponse(json.dumps({'error': _(u'Failed to save settings on server')}),
status=400, content_type=content_type)
messages.success(request, _(u'Settings saved.'))
return HttpResponse(json.dumps({'success': True}),
content_type=content_type)
else:
return HttpResponse(json.dumps({'error': _(u'Failed to save settings on server')}),
status=400, content_type=content_type)
else:
return HttpResponse(json.dumps({'error': str(form.errors.values()[0])}),
status=400, content_type=content_type)
@ -787,6 +789,23 @@ def myhome(request):
# Get all personal groups I joined.
joined_groups = get_personal_groups_by_user(request.user.username)
def get_abbrev_origin_path(repo_name, path):
if len(path) > 20:
abbrev_path = path[-20:]
return repo_name + '/...' + abbrev_path
else:
return repo_name + path
# compose abbrev origin path for display
sub_repos = []
if ENABLE_SUB_LIBRARY:
sub_repos = seafile_api.get_virtual_repos_by_owner(email)
for repo in sub_repos:
repo.abbrev_origin_path = get_abbrev_origin_path(repo.origin_repo_name,
repo.origin_path)
calculate_repo_last_modify(sub_repos)
sub_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
# Personal repos that I owned.
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
calculate_repo_last_modify(owned_repos)
@ -888,6 +907,8 @@ def myhome(request):
"TRAFFIC_STATS_ENABLED": TRAFFIC_STATS_ENABLED,
"traffic_stat": traffic_stat,
"ENABLE_PAYMENT": getattr(settings, 'ENABLE_PAYMENT', False),
"ENABLE_SUB_LIBRARY": ENABLE_SUB_LIBRARY,
"sub_repos": sub_repos,
}, context_instance=RequestContext(request))
@login_required
@ -1515,6 +1536,39 @@ def repo_create(request):
return HttpResponseBadRequest(json.dumps(form.errors),
content_type=content_type)
@login_required
def create_sub_repo(request):
if not request.is_ajax() or request.method != 'POST':
return Http404
result = {}
content_type = 'application/json; charset=utf-8'
orig_repo_id = request.POST.get('orig_repo_id', '')
orig_path = request.POST.get('orig_path', '')
repo_name = request.POST.get('repo_name', '')
repo_desc = request.POST.get('repo_desc', '')
owner = request.user.username
if not orig_repo_id or not orig_path or not repo_name or not repo_desc:
return HttpResponseBadRequest("Invalid arguments", content_type=content_type)
try:
repo_id = seafile_api.create_virtual_repo(orig_repo_id, orig_path,
repo_name, repo_desc, owner)
except SearpcError, e:
result['error'] = e.msg
return HttpResponse(json.dumps(result), content_type=content_type)
result['success'] = True
result['repo_id'] = repo_id
repo_created.send(sender=None,
org_id=-1,
creator=owner,
repo_id=repo_id,
repo_name=repo_name)
return HttpResponse(json.dumps(result), content_type=content_type)
def render_file_revisions (request, repo_id):
"""List all history versions of a file."""
path = request.GET.get('p', '/')

View File

@ -20,6 +20,7 @@ from seahub.views import gen_path_link, get_user_permission, get_repo_dirents
from seahub.utils import get_ccnetapplet_root, is_file_starred, \
gen_file_upload_url, get_httpserver_root, gen_shared_link, \
EMPTY_SHA1, get_user_repos
from seahub.settings import ENABLE_SUB_LIBRARY
# Get an instance of a logger
logger = logging.getLogger(__name__)
@ -84,6 +85,7 @@ def get_unencry_rw_repos_by_user(username):
owned_repos, shared_repos, groups_repos, public_repos = get_user_repos(username)
accessible_repos = []
for r in owned_repos:
if not has_repo(accessible_repos, r) and not r.encrypted:
r.has_subdir = check_has_subdir(r)
@ -165,7 +167,6 @@ def render_repo(request, repo):
Show repo direntries based on requested path
If user does not have permission to view repo
return permission deny page
"""
username = request.user.username
user_perm = check_repo_access_permission(repo.id, username)
@ -242,6 +243,7 @@ def render_repo(request, repo):
'dir_shared_link': dir_shared_link,
'history_limit': history_limit,
'search_repo_id': search_repo_id,
'ENABLE_SUB_LIBRARY': ENABLE_SUB_LIBRARY,
}, context_instance=RequestContext(request))
@login_required