mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-01 23:20:51 +00:00
Merge branch 'setLibHistory'
Conflicts: seahub/urls.py
This commit is contained in:
88
seahub/api2/endpoints/admin/library_history.py
Normal file
88
seahub/api2/endpoints/admin/library_history.py
Normal file
@@ -0,0 +1,88 @@
|
||||
import logging
|
||||
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.permissions import IsAdminUser
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from pysearpc import SearpcError
|
||||
from seaserv import seafile_api
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.api2.utils import api_error
|
||||
|
||||
from constance import config
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class AdminLibraryHistoryLimit(APIView):
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAdminUser, )
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
|
||||
def get(self, request, repo_id, format=None):
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
error_msg = 'Library %s not found.' % repo_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# no settings for virtual repo
|
||||
if repo.is_virtual:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
try:
|
||||
keep_days = seafile_api.get_repo_history_limit(repo_id)
|
||||
return Response({'keep_days': keep_days})
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
def put(self, request, repo_id, format=None):
|
||||
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
error_msg = 'Library %s not found.' % repo_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# no settings for virtual repo
|
||||
if repo.is_virtual or \
|
||||
not config.ENABLE_REPO_HISTORY_SETTING:
|
||||
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# check arg validation
|
||||
keep_days = request.data.get('keep_days', None)
|
||||
if not keep_days:
|
||||
error_msg = 'keep_days invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
try:
|
||||
keep_days = int(keep_days)
|
||||
except ValueError:
|
||||
error_msg = 'keep_days invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
try:
|
||||
# days <= -1, keep full history
|
||||
# days = 0, not keep history
|
||||
# days > 0, keep a period of days
|
||||
res = seafile_api.set_repo_history_limit(repo_id, keep_days)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
if res == 0:
|
||||
new_limit = seafile_api.get_repo_history_limit(repo_id)
|
||||
return Response({'keep_days': new_limit})
|
||||
else:
|
||||
error_msg = 'Failed to set library history limit.'
|
||||
return api_error(status.HTTP_520_OPERATION_FAILED, error_msg)
|
@@ -106,9 +106,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'js/templates.html' %}
|
||||
</div><!-- wrapper -->
|
||||
|
||||
{% include 'js/common-templates.html' %}
|
||||
{% include 'js/templates.html' %}
|
||||
<script type="text/javascript">
|
||||
var app = {
|
||||
config: {
|
||||
|
34
seahub/templates/js/common-templates.html
Normal file
34
seahub/templates/js/common-templates.html
Normal file
@@ -0,0 +1,34 @@
|
||||
{# templates in this file are used for both 'app' & 'sysadmin-app' #}
|
||||
{% load i18n %}
|
||||
<script type="text/template" id="history-settings-dialog-tmpl">
|
||||
<h3 id="dialogTitle"><%= title %></h3>
|
||||
|
||||
<p class="history-settings-notice outstanding-tip hide">{% trans "Setting library history is disabled by Admin" %}</p>
|
||||
|
||||
<form action="" method="post">
|
||||
<label class="radio-item">
|
||||
<input type="radio" name="history" value="full_history" class="vam" />
|
||||
<span class="vam">{% trans "Keep full history" %}</span>
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<label class="radio-item">
|
||||
<input type="radio" name="history" value="no_history" class="vam" />
|
||||
<span class="vam">{% trans "Don't keep history" %}</span>
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<label class="radio-item">
|
||||
<input type="radio" name="history" value="partial_history" class="vam" />
|
||||
<span calss="vam">{% trans "Only keep a period of history:" %}
|
||||
<input type="text" name="days" size="4" disabled="disabled" class="input-disabled" value="<%= default_history_limit %>" /> {% trans "days" %}
|
||||
</span>
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<p class="error hide"></p>
|
||||
</script>
|
@@ -410,9 +410,15 @@
|
||||
<td>
|
||||
<a href="#" class="sf2-icon-delete sf2-x repo-delete-btn op-icon vh" title="{% trans "Delete" %}" aria-label="{% trans "Delete" %}"></a>
|
||||
<a href="#" class="sf2-icon-move sf2-x repo-transfer-btn op-icon vh" title="{% trans "Transfer" %}" aria-label="{% trans "Transfer" %}"></a>
|
||||
<div class="sf-dropdown sf-dropdown-inline">
|
||||
<a href="#" class="sf2-icon-caret-down more-op-icon op-icon vh sf-dropdown-toggle" title="{% trans "More Operations" %}" aria-label="{% trans "More Operations" %}"></a>
|
||||
<ul class="hidden-op repo-hidden-op hide sf-dropdown-menu">
|
||||
<% if (!encrypted) { %>
|
||||
<a href="#" class="sf2-icon-share sf2-x repo-share-btn op-icon vh" title="{% trans "Share" %}" aria-label="{% trans "Share" %}"></a>
|
||||
<li><a class="op js-repo-share" href="#">{% trans "Share" %}</a></li>
|
||||
<% } %>
|
||||
<li><a class="op js-popup-history-setting" href="#">{% trans "History Setting" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
</script>
|
||||
|
||||
|
@@ -1798,39 +1798,6 @@
|
||||
<% } %>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="history-settings-dialog-tmpl">
|
||||
<h3 id="dialogTitle"><%= title %></h3>
|
||||
|
||||
<p class="history-settings-notice outstanding-tip hide">{% trans "Setting library history is disabled by Admin" %}</p>
|
||||
|
||||
<form action="" method="post">
|
||||
<label class="radio-item">
|
||||
<input type="radio" name="history" value="full_history" class="vam" />
|
||||
<span class="vam">{% trans "Keep full history" %}</span>
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<label class="radio-item">
|
||||
<input type="radio" name="history" value="no_history" class="vam" />
|
||||
<span class="vam">{% trans "Don't keep history" %}</span>
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<label class="radio-item">
|
||||
<input type="radio" name="history" value="partial_history" class="vam" />
|
||||
<span calss="vam">{% trans "Only keep a period of history:" %}
|
||||
<input type="text" name="days" size="4" disabled="disabled" class="input-disabled" value="<%= default_history_limit %>" /> {% trans "days" %}
|
||||
</span>
|
||||
</label>
|
||||
<br />
|
||||
|
||||
<input type="submit" value="{% trans "Submit" %}" class="submit" />
|
||||
</form>
|
||||
|
||||
<span class="loading-icon loading-tip"></span>
|
||||
<p class="error hide"></p>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="repo-shared-links-admin-dialog-tmpl">
|
||||
<h3 id="dialogTitle"><%= title %></h3>
|
||||
<div id="repo-shared-links" class="nav-con-tabs js-tabs">
|
||||
|
@@ -72,9 +72,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'js/sysadmin-templates.html' %}
|
||||
</div><!-- wrapper -->
|
||||
|
||||
{% include 'js/common-templates.html' %}
|
||||
{% include 'js/sysadmin-templates.html' %}
|
||||
{% include "js/lib-op-popups.html" %}
|
||||
<script type="text/javascript">
|
||||
var app = {
|
||||
@@ -98,6 +99,7 @@ app["pageOptions"] = {
|
||||
thumbnail_default_size: {{ thumbnail_default_size }},
|
||||
thumbnail_size_for_grid: {{ thumbnail_size_for_grid }},
|
||||
enable_encrypted_library: {% if enable_encrypted_library %} true {% else %} false {% endif %},
|
||||
enable_repo_history_setting: {% if enable_repo_history_setting %} true {% else %} false {% endif %},
|
||||
max_upload_file_size: {% if max_upload_file_size %} {{ max_upload_file_size }} {% else %} '' {% endif %},
|
||||
folder_perm_enabled: {% if folder_perm_enabled %} true {% else %} false {% endif %},
|
||||
is_pro: {% if is_pro %} true {% else %} false {% endif %},
|
||||
|
@@ -84,6 +84,7 @@ from seahub.api2.endpoints.admin.logo import AdminLogo
|
||||
from seahub.api2.endpoints.admin.favicon import AdminFavicon
|
||||
from seahub.api2.endpoints.admin.license import AdminLicense
|
||||
from seahub.api2.endpoints.admin.invitations import InvitationsView as AdminInvitationsView
|
||||
from seahub.api2.endpoints.admin.library_history import AdminLibraryHistoryLimit
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
#from django.contrib import admin
|
||||
@@ -281,6 +282,7 @@ urlpatterns = patterns(
|
||||
## admin::libraries
|
||||
url(r'^api/v2.1/admin/libraries/$', AdminLibraries.as_view(), name='api-v2.1-admin-libraries'),
|
||||
url(r'^api/v2.1/admin/libraries/(?P<repo_id>[-0-9a-f]{36})/$', AdminLibrary.as_view(), name='api-v2.1-admin-library'),
|
||||
url(r'^api/v2.1/admin/libraries/(?P<repo_id>[-0-9a-f]{36})/history-limit/$', AdminLibraryHistoryLimit.as_view(), name="api-v2.1-admin-library-history-limit"),
|
||||
url(r'^api/v2.1/admin/libraries/(?P<repo_id>[-0-9a-f]{36})/dirents/$', AdminLibraryDirents.as_view(), name='api-v2.1-admin-library-dirents'),
|
||||
url(r'^api/v2.1/admin/libraries/(?P<repo_id>[-0-9a-f]{36})/dirent/$', AdminLibraryDirent.as_view(), name='api-v2.1-admin-library-dirent'),
|
||||
|
||||
|
@@ -13,6 +13,7 @@ define([
|
||||
initialize: function(options) {
|
||||
this.repo_name = options.repo_name;
|
||||
this.repo_id = options.repo_id;
|
||||
this.url_name = options.url_name;
|
||||
|
||||
this.render();
|
||||
this.$('.op-target').css({'max-width':280}); // for long repo name
|
||||
@@ -48,7 +49,7 @@ define([
|
||||
|
||||
$.ajax({
|
||||
url: Common.getUrl({
|
||||
'name': 'repo_history_limit',
|
||||
'name': this.url_name,
|
||||
'repo_id': this.repo_id
|
||||
}),
|
||||
type: 'get',
|
||||
@@ -120,7 +121,7 @@ define([
|
||||
|
||||
$.ajax({
|
||||
url: Common.getUrl({
|
||||
'name': 'repo_history_limit',
|
||||
'name': this.url_name,
|
||||
'repo_id': this.repo_id
|
||||
}),
|
||||
type: 'put',
|
||||
|
@@ -291,7 +291,8 @@ define([
|
||||
popupHistorySetting: function() {
|
||||
var options = {
|
||||
'repo_name': this.model.get('name'),
|
||||
'repo_id': this.model.get('id')
|
||||
'repo_id': this.model.get('id'),
|
||||
'url_name': 'repo_history_limit'
|
||||
};
|
||||
this.togglePopup(); // close the popup
|
||||
new HistorySettingsDialog(options);
|
||||
|
@@ -180,6 +180,7 @@ define([
|
||||
case 'admin-device-errors': return siteRoot + 'api/v2.1/admin/device-errors/';
|
||||
case 'admin-libraries': return siteRoot + 'api/v2.1/admin/libraries/';
|
||||
case 'admin-library': return siteRoot + 'api/v2.1/admin/libraries/' + options.repo_id + '/';
|
||||
case 'admin-library-history-limit': return siteRoot + 'api/v2.1/admin/libraries/' + options.repo_id + '/history-limit/';
|
||||
case 'admin-library-dirents': return siteRoot + 'api/v2.1/admin/libraries/' + options.repo_id + '/dirents/';
|
||||
case 'admin-groups': return siteRoot + 'api/v2.1/admin/groups/';
|
||||
case 'admin-group': return siteRoot + 'api/v2.1/admin/groups/' + options.group_id + '/';
|
||||
|
@@ -8,9 +8,12 @@ define([
|
||||
'select2',
|
||||
'jquery.ui.tabs',
|
||||
'sysadmin-app/views/share',
|
||||
'app/views/widgets/hl-item-view'
|
||||
'app/views/dialogs/repo-history-settings',
|
||||
'app/views/widgets/hl-item-view',
|
||||
'app/views/widgets/dropdown'
|
||||
], function($, _, Backbone, Common, Moment, Simplemodal,
|
||||
Select2, Tabs, ShareView, HLItemView) {
|
||||
Select2, Tabs, ShareView, HistorySettingsDialog,
|
||||
HLItemView, DropdownView) {
|
||||
|
||||
'use strict';
|
||||
|
||||
@@ -21,7 +24,8 @@ define([
|
||||
transferTemplate: _.template($('#library-transfer-form-tmpl').html()),
|
||||
|
||||
events: {
|
||||
'click .repo-share-btn': 'share',
|
||||
'click .js-repo-share': 'share',
|
||||
'click .js-popup-history-setting': 'popupHistorySetting',
|
||||
'click .repo-delete-btn': 'deleteLibrary',
|
||||
'click .repo-transfer-btn': 'transferLibrary'
|
||||
},
|
||||
@@ -32,9 +36,25 @@ define([
|
||||
'repo_name': this.model.get('name')
|
||||
};
|
||||
new ShareView(options);
|
||||
this.togglePopup(); // close the popup
|
||||
return false;
|
||||
},
|
||||
|
||||
popupHistorySetting: function() {
|
||||
var options = {
|
||||
'repo_name': this.model.get('name'),
|
||||
'repo_id': this.model.get('id'),
|
||||
'url_name': 'admin-library-history-limit'
|
||||
};
|
||||
this.togglePopup(); // close the popup
|
||||
new HistorySettingsDialog(options);
|
||||
return false;
|
||||
},
|
||||
|
||||
togglePopup: function() {
|
||||
this.dropdown.hide();
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
HLItemView.prototype.initialize.call(this);
|
||||
this.listenTo(this.model, "change", this.render);
|
||||
@@ -146,6 +166,11 @@ define([
|
||||
|
||||
this.$el.html(this.template(data));
|
||||
|
||||
this.dropdown = new DropdownView({
|
||||
el: this.$('.sf-dropdown'),
|
||||
right: 0
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
37
tests/api/endpoints/admin/test_library_history.py
Normal file
37
tests/api/endpoints/admin/test_library_history.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import json
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from seahub.test_utils import BaseTestCase
|
||||
|
||||
class LibraryHistory(BaseTestCase):
|
||||
def setUp(self):
|
||||
self.login_as(self.admin)
|
||||
self.repo_id = self.repo.id
|
||||
self.url = reverse('api-v2.1-admin-library-history-limit', kwargs=dict(repo_id=self.repo_id))
|
||||
|
||||
def test_can_get(self):
|
||||
resp = self.client.get(self.url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
def test_can_put(self):
|
||||
data = "keep_days=-1"
|
||||
resp = self.client.put(self.url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
self.assertEqual(-1, json_resp['keep_days'])
|
||||
|
||||
data = "keep_days=0"
|
||||
resp = self.client.put(self.url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
self.assertEqual(0, json_resp['keep_days'])
|
||||
|
||||
data = "keep_days=8"
|
||||
resp = self.client.put(self.url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
self.assertEqual(8, json_resp['keep_days'])
|
||||
|
||||
data = "keep_days=q"
|
||||
resp = self.client.put(self.url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(400, resp.status_code)
|
Reference in New Issue
Block a user