mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-30 04:25:47 +00:00
Merge branch 'sub-repo'
This commit is contained in:
commit
aa4e334a12
@ -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')})
|
||||
|
@ -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 #
|
||||
#####################
|
||||
|
@ -116,9 +116,12 @@
|
||||
<div class="repo-file-op vh">
|
||||
<div class="displayed-op">
|
||||
<a class="op" href="{% url 'repo_download_dir' repo.id %}?p={{ path|urlencode }}{{ dirent.obj_name|urlencode }}">{% trans 'Download' %}</a>
|
||||
{% if not repo.encrypted %}
|
||||
{% 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 %}
|
||||
{% 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 %}
|
||||
|
@ -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>
|
||||
|
@ -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'),
|
||||
|
@ -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
|
||||
res = set_repo_history_limit(repo_id, days)
|
||||
if res == 0:
|
||||
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)
|
||||
if days != None:
|
||||
res = set_repo_history_limit(repo_id, days)
|
||||
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': 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', '/')
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user