1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-05-13 02:15:59 +00:00

rm synced repos at devices page ()

This commit is contained in:
lian 2016-07-14 13:54:17 +08:00 committed by Daniel Pan
parent fe236eca03
commit b5d9ece164
6 changed files with 27 additions and 96 deletions
seahub
static/scripts/app/views
tests/api

View File

@ -40,7 +40,7 @@ from .utils import get_diff_details, \
api_repo_group_folder_perm_check
from seahub.api2.base import APIView
from seahub.api2.models import TokenV2
from seahub.api2.models import TokenV2, DESKTOP_PLATFORMS
from seahub.avatar.templatetags.avatar_tags import api_avatar_url, avatar
from seahub.avatar.templatetags.group_avatar_tags import api_grp_avatar_url, \
grp_avatar
@ -65,7 +65,7 @@ from seahub.utils import gen_file_get_url, gen_token, gen_file_upload_url, \
gen_file_share_link, gen_dir_share_link, is_org_context, gen_shared_link, \
get_org_user_events, calculate_repos_last_modify, send_perm_audit_msg, \
gen_shared_upload_link, convert_cmmt_desc_link, is_org_repo_creation_allowed
from seahub.utils.devices import get_user_devices, do_unlink_device
from seahub.utils.devices import do_unlink_device
from seahub.utils.repo import get_sub_repo_abbrev_origin_path
from seahub.utils.star import star_file, unstar_file
from seahub.utils.file_types import DOCUMENT
@ -1812,15 +1812,28 @@ class OwaFileView(APIView):
class DevicesView(APIView):
"""List user devices"""
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
def get(self, request, format=None):
""" List user's devices.
Permission checking:
1. All authenticated users.
"""
username = request.user.username
user_devices = get_user_devices(username)
return Response(user_devices)
devices = TokenV2.objects.get_user_devices(username)
for device in devices:
device['is_desktop_client'] = False
if device['platform'] in DESKTOP_PLATFORMS:
device['is_desktop_client'] = True
device['last_accessed'] = datetime_to_isoformat_timestr(device['last_accessed'])
return Response(devices)
def delete(self, request, format=None):

View File

@ -1431,20 +1431,6 @@
<td><%- device_name %></td>
<td><%- last_login_ip %></td>
<td><time title='<%- time %>'><%- time_from_now %></time></td>
<td>
<% if (synced_repos.length > 0) { %>
<div class="sf-dropdown">
<a href="#" class="normal black sf-dropdown-toggle"><%- synced_repos_length %> <span class="icon-caret-down"></span></a>
<ul class="device-libs-dropdown-menu sf-dropdown-menu hide">
<% for (var i = 0, len = synced_repos_length; i < len; i++) { %>
<li><a href="#common/lib/<%- synced_repos[i].repo_id %>"><%- synced_repos[i].repo_name %></a></li>
<% } %>
</ul>
</div>
<% } else { %>
0
<% } %>
</td>
<td>
<div>
<span class="unlink-device op-icon sf2-icon-delete vh" title="{% trans "Unlink" %}"></span>

View File

@ -192,10 +192,9 @@
<thead>
<tr>
<th width="13%">{% trans "Platform" %}</th>
<th width="25%">{% trans "Device Name" %}</th>
<th width="20%">{% trans "IP" %}</th>
<th width="30%">{% trans "Device Name" %}</th>
<th width="30%">{% trans "IP" %}</th>
<th width="17%">{% trans "Last Access" %}</th>
<th width="15%">{% trans "# Libraries" %}</th>
<th width="10%"></th>
</tr>
</thead>

View File

@ -3,12 +3,10 @@ import datetime
from seaserv import seafile_api
from seahub.api2.models import TokenV2, DESKTOP_PLATFORMS
from seahub.utils.timeutils import datetime_to_isoformat_timestr
logger = logging.getLogger(__name__)
__all__ = [
'get_user_devices',
'do_unlink_device',
]
@ -16,60 +14,6 @@ def _last_sync_time(repos):
latest_sync_time = max([r['sync_time'] for r in repos])
return datetime.datetime.fromtimestamp(latest_sync_time)
def get_user_devices(username):
devices = TokenV2.objects.get_user_devices(username)
peer_repos_map = get_user_synced_repo_infos(username)
for device in devices:
device['is_desktop_client'] = False
if device['platform'] in DESKTOP_PLATFORMS:
device['is_desktop_client'] = True
peer_id = device['device_id']
repos = peer_repos_map.get(peer_id, [])
device['synced_repos'] = repos
if repos:
device['last_accessed'] = max(device['last_accessed'],
_last_sync_time(repos))
device['last_accessed'] = datetime_to_isoformat_timestr(device['last_accessed'])
return devices
def get_user_synced_repo_infos(username):
'''Return a (client_ccnet_peer_id, synced_repos_on_that_client) dict'''
tokens = []
try:
tokens = seafile_api.list_repo_tokens_by_email(username)
except:
return {}
def sort_by_sync_time_descending(a, b):
if isinstance(a, dict):
return cmp(b['sync_time'], a['sync_time'])
else:
return cmp(b.sync_time, a.sync_time)
tokens.sort(sort_by_sync_time_descending, reverse=True)
peer_repos_map = {}
for token in tokens:
peer_id = token.peer_id
repo_id = token.repo_id
if peer_id not in peer_repos_map:
peer_repos_map[peer_id] = {}
peer_repos_map[peer_id][repo_id] = {
'repo_id': token.repo_id,
'repo_name': token.repo_name,
'sync_time': token.sync_time
}
ret = {}
for peer_id, repos in peer_repos_map.iteritems():
ret[peer_id] = sorted(repos.values(), sort_by_sync_time_descending)
return ret
def do_unlink_device(username, platform, device_id, remote_wipe=False):
if platform in DESKTOP_PLATFORMS:
# For desktop client, we also remove the sync tokens

View File

@ -4,9 +4,8 @@ define([
'backbone',
'common',
'moment',
'app/views/widgets/hl-item-view',
'app/views/widgets/dropdown'
], function($, _, Backbone, Common, Moment, HLItemView, DropdownView) {
'app/views/widgets/hl-item-view'
], function($, _, Backbone, Common, Moment, HLItemView) {
'use strict';
var DeviceView = HLItemView.extend({
@ -25,27 +24,12 @@ define([
render: function() {
var data = this.model.toJSON();
if (typeof(data['synced_repos']) == 'undefined') {
data['synced_repos'] = new Array();
}
if (data['synced_repos']) {
data['synced_repos_length'] = data['synced_repos'].length;
} else {
data['synced_repos_length'] = 0;
}
var last_accessed = Moment(data['last_accessed']);
data['time'] = last_accessed.format('LLLL');
data['time_from_now'] = Common.getRelativeTimeStr(last_accessed);
this.$el.html(this.template(data));
new DropdownView({
el: this.$('.sf-dropdown'),
left: '-60px'
});
return this;
},

View File

@ -26,6 +26,11 @@ class DevicesTest(BaseTestCase, Fixtures):
assert json_resp[0]['platform'] == self.platform
assert json_resp[0]['device_id'] == self.device_id
def test_can_not_list_if_not_authenticated(self):
resp = self.client.get(reverse('api2-devices'))
self.assertEqual(403, resp.status_code)
def test_can_delete(self):
self.login_as(self.user)
data = 'platform=%s&device_id=%s' % (self.platform, self.device_id)