1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 18:29:23 +00:00

Merge pull request #1 from haiwen/master

pull
This commit is contained in:
TMHBOFH
2017-05-22 13:17:45 +02:00
committed by GitHub
6 changed files with 165 additions and 14 deletions

View File

@@ -30,6 +30,7 @@ json_content_type = 'application/json; charset=utf-8'
def get_account_info(user): def get_account_info(user):
email = user.username email = user.username
d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email) d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email)
profile = Profile.objects.get_profile_by_user(email)
info = {} info = {}
info['email'] = email info['email'] = email
@@ -39,6 +40,7 @@ def get_account_info(user):
info['is_staff'] = user.is_staff info['is_staff'] = user.is_staff
info['is_active'] = user.is_active info['is_active'] = user.is_active
info['create_time'] = user.ctime info['create_time'] = user.ctime
info['login_id'] = profile.login_id if profile else ''
info['total'] = seafile_api.get_user_quota(email) info['total'] = seafile_api.get_user_quota(email)
info['usage'] = seafile_api.get_user_self_usage(email) info['usage'] = seafile_api.get_user_self_usage(email)
@@ -108,10 +110,18 @@ class Account(APIView):
profile = Profile.objects.get_profile_by_user(email) profile = Profile.objects.get_profile_by_user(email)
if profile is None: if profile is None:
profile = Profile(user=email) profile = Profile(user=email)
profile.nickname = name profile.nickname = name
profile.save() profile.save()
# update account loginid
loginid = request.data.get("login_id", '').strip()
if loginid != '':
profile = Profile.objects.get_profile_by_user(email)
if profile is None:
profile = Profile(user=email)
profile.login_id = loginid
profile.save()
# update account detailed profile # update account detailed profile
department = request.data.get("department", None) department = request.data.get("department", None)
if department is not None: if department is not None:
@@ -165,6 +175,18 @@ class Account(APIView):
return api_error(status.HTTP_400_BAD_REQUEST, return api_error(status.HTTP_400_BAD_REQUEST,
_(u"Name should not include '/'.")) _(u"Name should not include '/'."))
#argument check for loginid
loginid = request.data.get("login_id", None)
if loginid is not None:
loginid = loginid.strip()
if loginid == "":
return api_error(status.HTTP_400_BAD_REQUEST,
_(u"Login id can't be empty"))
usernamebyloginid = Profile.objects.get_username_by_login_id(loginid)
if usernamebyloginid is not None:
return api_error(status.HTTP_400_BAD_REQUEST,
_(u"Login id %s already exists." % loginid))
# argument check for department # argument check for department
department = request.data.get("department", None) department = request.data.get("department", None)
if department is not None: if department is not None:

View File

@@ -253,6 +253,10 @@ class User(object):
ccnet_api.remove_emailuser(source, username) ccnet_api.remove_emailuser(source, username)
Profile.objects.delete_profile_by_user(username) Profile.objects.delete_profile_by_user(username)
if settings.ENABLE_TERMS_AND_CONDITIONS:
from termsandconditions.models import UserTermsAndConditions
UserTermsAndConditions.objects.filter(username=username).delete()
def get_and_delete_messages(self): def get_and_delete_messages(self):
messages = [] messages = []
return messages return messages

View File

@@ -520,11 +520,14 @@ THUMBNAIL_EXTENSION = 'png'
THUMBNAIL_DEFAULT_SIZE = 48 THUMBNAIL_DEFAULT_SIZE = 48
THUMBNAIL_SIZE_FOR_GRID = 192 THUMBNAIL_SIZE_FOR_GRID = 192
# size(MB) limit for generate thumbnail # size(MB) limit for generate thumbnail
THUMBNAIL_IMAGE_SIZE_LIMIT = 20 THUMBNAIL_IMAGE_SIZE_LIMIT = 20
THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT = 256 THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT = 256
# video thumbnails
ENABLE_VIDEO_THUMBNAIL = False
THUMBNAIL_VIDEO_FRAME_TIME = 5 # use the frame at 5 second as thumbnail
# template for create new office file # template for create new office file
OFFICE_TEMPLATE_ROOT = os.path.join(MEDIA_ROOT, 'office-template') OFFICE_TEMPLATE_ROOT = os.path.join(MEDIA_ROOT, 'office-template')

View File

@@ -53,6 +53,18 @@
<span id="set-name" title="{% trans "Edit"%}" class="sf2-icon-edit op-icon"></span> <span id="set-name" title="{% trans "Edit"%}" class="sf2-icon-edit op-icon"></span>
</dd> </dd>
<dt>{% trans "Login ID" %}</dt>
<dd>
<span id="loginid">
{% if profile and profile.login_id %}
{{ profile.login_id }}
{% else %}
--
{% endif %}
</span>
<span id="set-loginid" title="{% trans "Edit"%}" class="sf2-icon-edit op-icon"></span>
</dd>
<dt>{% trans "Department" %}</dt> <dt>{% trans "Department" %}</dt>
<dd> <dd>
<span id="department"> <span id="department">
@@ -98,6 +110,13 @@
<input type="submit" value="{% trans "Submit" %}" class="submit" /> <input type="submit" value="{% trans "Submit" %}" class="submit" />
</form> </form>
<form id="set-loginid-form" method="post" action="" class="hide">{% csrf_token %}
<h3>{% trans "Set user Login ID" %}</h3>
<input type="text" name="loginid" class="input" value="" /><br />
<p class="error hide"></p>
<input type="submit" value="{% trans "Submit" %}" class="submit" />
</form>
<form id="set-quota-form" method="post" class="hide">{% csrf_token %} <form id="set-quota-form" method="post" class="hide">{% csrf_token %}
<h3>{% trans "Set user storage limit" %}</h3> <h3>{% trans "Set user storage limit" %}</h3>
<input type="text" name="space_quota" class="input" /> MB <input type="text" name="space_quota" class="input" /> MB
@@ -300,6 +319,10 @@ $('#set-name').click(function() {
$("#set-name-form").modal({appendTo: "#main"}); $("#set-name-form").modal({appendTo: "#main"});
$('#simplemodal-container').css({'width':'auto', 'height':'auto'}); $('#simplemodal-container').css({'width':'auto', 'height':'auto'});
}); });
$('#set-loginid').click(function () {
$("#set-loginid-form").modal({appendTo:"#main"});
$('#simplemodal-container').css({'width':'auto', 'height':'auto'});
})
$('#set-dept').click(function() { $('#set-dept').click(function() {
$("#set-dept-form").modal({appendTo: "#main"}); $("#set-dept-form").modal({appendTo: "#main"});
$('#simplemodal-container').css({'width':'auto', 'height':'auto'}); $('#simplemodal-container').css({'width':'auto', 'height':'auto'});
@@ -351,6 +374,43 @@ $('#set-name-form').submit(function() {
return false; return false;
}); });
$('#set-loginid-form').submit(function() {
var loginid = $.trim($('[name="loginid"]', $(this)).val());
var $loginid = $('#loginid');
var $error = $('.error', $(this));
var $submitBtn = $('[type="submit"]', $(this));
if (!loginid){
$error.html("{% trans "Login id can't be empty" %}").show();
return false;
}
disable($submitBtn);
$.ajax({
url: '{% url 'api2-account' email %}',
type: 'PUT',
dataType: 'json',
cache: false,
beforeSend: prepareCSRFToken,
data: {'login_id': loginid},
success: function(data) {
$loginid.html(HTMLescape(data['login_id']));
$.modal.close();
},
error: function(xhr, textStatus, errorThrown) {
var err_msg;
if (xhr.responseText) {
err_msg = $.parseJSON(xhr.responseText).error_msg;
} else {
err_msg = "{% trans "Failed. Please check the network." %}";
}
$error.html(err_msg).show();
enable($submitBtn);
}
});
return false;
});
$('#set-dept-form').submit(function() { $('#set-dept-form').submit(function() {
var department = $.trim($('[name="department"]', $(this)).val()); var department = $.trim($('[name="department"]', $(this)).val());
var $department = $('#department'); var $department = $('#department');

View File

@@ -8,24 +8,24 @@ import logging
from StringIO import StringIO from StringIO import StringIO
from PIL import Image from PIL import Image
try:
from moviepy.editor import VideoFileClip
_ENABLE_VIDEO_THUMBNAIL = True
except ImportError:
_ENABLE_VIDEO_THUMBNAIL = False
from seaserv import get_file_id_by_path, get_repo, get_file_size, \ from seaserv import get_file_id_by_path, get_repo, get_file_size, \
seafile_api seafile_api
from seahub.utils import gen_inner_file_get_url, get_file_type_and_ext from seahub.utils import gen_inner_file_get_url, get_file_type_and_ext
from seahub.utils.file_types import VIDEO from seahub.utils.file_types import VIDEO
from seahub.settings import THUMBNAIL_IMAGE_SIZE_LIMIT, \ from seahub.settings import THUMBNAIL_IMAGE_SIZE_LIMIT, \
THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, THUMBNAIL_IMAGE_ORIGINAL_SIZE_LIMIT,\
ENABLE_VIDEO_THUMBNAIL, THUMBNAIL_VIDEO_FRAME_TIME
# Get an instance of a logger # Get an instance of a logger
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if _ENABLE_VIDEO_THUMBNAIL: if ENABLE_VIDEO_THUMBNAIL:
logger.debug('Video thumbnail is enabled.') try:
from moviepy.editor import VideoFileClip
logger.debug('Video thumbnail is enabled.')
except ImportError:
logger.error("Could not find moviepy installed.")
else: else:
logger.debug('Video thumbnail is disabled.') logger.debug('Video thumbnail is disabled.')
@@ -106,7 +106,7 @@ def generate_thumbnail(request, repo_id, size, path):
if filetype == VIDEO: if filetype == VIDEO:
# video thumbnails # video thumbnails
if _ENABLE_VIDEO_THUMBNAIL: if ENABLE_VIDEO_THUMBNAIL:
return create_video_thumbnails(repo, file_id, path, size, return create_video_thumbnails(repo, file_id, path, size,
thumbnail_file, file_size) thumbnail_file, file_size)
else: else:
@@ -137,7 +137,8 @@ def create_video_thumbnails(repo, file_id, path, size, thumbnail_file, file_size
inner_path = gen_inner_file_get_url(token, os.path.basename(path)) inner_path = gen_inner_file_get_url(token, os.path.basename(path))
clip = VideoFileClip(inner_path) clip = VideoFileClip(inner_path)
tmp_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id[:8])) tmp_path = str(os.path.join(tempfile.gettempdir(), '%s.png' % file_id[:8]))
clip.save_frame(tmp_path, t=5) # save the frame in 5 second
clip.save_frame(tmp_path, t=THUMBNAIL_VIDEO_FRAME_TIME)
t2 = timeit.default_timer() t2 = timeit.default_timer()
logger.debug('Create thumbnail of [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1))) logger.debug('Create thumbnail of [%s](size: %s) takes: %s' % (path, file_size, (t2 - t1)))

View File

@@ -45,7 +45,40 @@ class AccountTest(BaseTestCase):
def _do_update(self): def _do_update(self):
return self.client.put( return self.client.put(
reverse('api2-account', args=[self.user1.username]), reverse('api2-account', args=[self.user1.username]),
'password=654321&is_staff=1&is_active=0&name=user1&storage=102400', 'password=654321&is_staff=1&is_active=0&name=user1&storage=102400&login_id=hello',
'application/x-www-form-urlencoded',
)
def _do_update_name(self):
return self.client.put(
reverse('api2-account', args=[self.user1.username]),
'name=user1',
'application/x-www-form-urlencoded',
)
def _do_update_loginid(self):
return self.client.put(
reverse('api2-account', args=[self.user1.username]),
'login_id=hello',
'application/x-www-form-urlencoded',
)
def _do_update_loginid_useemptystring(self):
return self.client.put(
reverse('api2-account', args=[self.user1.username]),
'login_id=',
'application/x-www-form-urlencoded',
)
def _do_update_loginid_sendagain(self):
self.client.put(
reverse('api2-account', args=[self.user1.username]),
'login_id=test',
'application/x-www-form-urlencoded',
)
return self.client.put(
reverse('api2-account', args=[self.user1.username]),
'login_id=test',
'application/x-www-form-urlencoded', 'application/x-www-form-urlencoded',
) )
@@ -77,7 +110,7 @@ class AccountTest(BaseTestCase):
resp = self._do_get_info() resp = self._do_get_info()
json_resp = json.loads(resp.content) json_resp = json.loads(resp.content)
assert len(json_resp) == 9 assert len(json_resp) == 10
assert json_resp['email'] == self.user1.username assert json_resp['email'] == self.user1.username
assert json_resp['is_staff'] is False assert json_resp['is_staff'] is False
assert json_resp['is_active'] is True assert json_resp['is_active'] is True
@@ -99,11 +132,39 @@ class AccountTest(BaseTestCase):
'654321')) '654321'))
self.assertTrue(User.objects.get(self.user1.username).is_staff) self.assertTrue(User.objects.get(self.user1.username).is_staff)
self.assertFalse(User.objects.get(self.user1.username).is_active) self.assertFalse(User.objects.get(self.user1.username).is_active)
self.assertEqual(Profile.objects.get_profile_by_user(
self.user1.username).login_id, 'hello')
self.assertEqual(Profile.objects.get_profile_by_user( self.assertEqual(Profile.objects.get_profile_by_user(
self.user1.username).nickname, 'user1') self.user1.username).nickname, 'user1')
self.assertEqual(seafile_api.get_user_quota( self.assertEqual(seafile_api.get_user_quota(
self.user1.username), 102400000000) self.user1.username), 102400000000)
def test_update_name(self):
"""only test name"""
self.login_as(self.admin)
resp = self._do_update_name()
self.assertEqual(Profile.objects.get_profile_by_user(
self.user1.username).nickname, 'user1')
def test_update_loginid(self):
"""only test loginid"""
self.login_as(self.admin)
resp = self._do_update_loginid()
self.assertEqual(Profile.objects.get_profile_by_user(
self.user1.username).login_id, 'hello')
def test_update_loginid_useemptystring(self):
"""test loginid, longid send the empty"""
self.login_as(self.admin)
resp = self._do_update_loginid_useemptystring()
self.assertEqual(400, resp.status_code)
def test_update_loginid_sendagain(self):
"""test loginid,sent twice"""
self.login_as(self.admin)
resp = self._do_update_loginid_sendagain()
self.assertEqual(400, resp.status_code)
def test_refresh_profile_cache_after_update(self): def test_refresh_profile_cache_after_update(self):
self.login_as(self.admin) self.login_as(self.admin)
self.assertEqual(email2nickname(self.user1.username), self.assertEqual(email2nickname(self.user1.username),