1
0
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:
zhengxie
2017-08-23 15:37:29 +08:00
12 changed files with 209 additions and 44 deletions

View 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)

View File

@@ -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: {

View 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>

View File

@@ -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>

View File

@@ -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">

View File

@@ -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 %},

View File

@@ -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'),

View File

@@ -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',

View File

@@ -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);

View File

@@ -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 + '/';

View File

@@ -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;
}

View 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)