Remove usage for ultrajson (ujson)
[mygpo.git] / mygpo / api / advanced / sync.py
blob0840350d655dc6b77f19e0d56a421e4c6a98041e
2 # This file is part of my.gpodder.org.
4 # my.gpodder.org is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or (at your
7 # option) any later version.
9 # my.gpodder.org is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
12 # License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with my.gpodder.org. If not, see <http://www.gnu.org/licenses/>.
18 from django.http import HttpResponseBadRequest, HttpResponseNotFound
19 from django.views.decorators.csrf import csrf_exempt
20 from django.views.decorators.cache import never_cache
22 from mygpo.decorators import allowed_methods, cors_origin
23 from mygpo.utils import parse_request_body
24 from mygpo.api.basic_auth import require_valid_user, check_username
25 from mygpo.api.httpresponse import JsonResponse
26 from mygpo.users.models import Client, UserProxy
27 from mygpo.users.tasks import sync_user
30 @csrf_exempt
31 @require_valid_user
32 @check_username
33 @never_cache
34 @allowed_methods(['GET', 'POST'])
35 @cors_origin()
36 def main(request, username):
37 """ API Endpoint for Device Synchronisation """
39 if request.method == 'GET':
40 return JsonResponse(get_sync_status(request.user))
42 else:
43 try:
44 actions = parse_request_body(request)
45 except ValueError as e:
46 return HttpResponseBadRequest(str(e))
48 synclist = actions.get('synchronize', [])
49 stopsync = actions.get('stop-synchronize', [])
51 try:
52 update_sync_status(request.user, synclist, stopsync)
53 except ValueError as e:
54 return HttpResponseBadRequest(str(e))
55 except Client.DoesNotExist as e:
56 return HttpResponseNotFound(str(e))
58 return JsonResponse(get_sync_status(user))
62 def get_sync_status(user):
63 """ Returns the current Device Sync status """
65 sync_groups = []
66 unsynced = []
68 user = UserProxy.objects.from_user(user)
69 for group in user.get_grouped_devices():
70 uids = [device.uid for device in group.devices]
72 if group.is_synced:
73 sync_groups.append(uids)
75 else:
76 unsynced = uids
78 return {
79 'synchronized': sync_groups,
80 'not-synchronized': unsynced
85 def update_sync_status(user, synclist, stopsync):
86 """ Updates the current Device Sync status
88 Synchronisation between devices can be set up and stopped. Devices are
89 identified by their UIDs. Unknown UIDs cause errors, no new devices are
90 created. """
92 for devlist in synclist:
94 if len(devlist) <= 1:
95 raise ValueError('at least two devices are needed to sync')
97 # Setup all devices to sync with the first in the list
98 uid = devlist[0]
99 dev = user.client_set.get(uid=uid)
101 for other_uid in devlist[1:]:
102 other = user.get_device_by_uid(other_uid)
103 dev.sync_with(other)
106 for uid in stopsync:
107 dev = user.get_device_by_uid(uid)
108 try:
109 dev.stop_sync()
110 except ValueError:
111 # if all devices of a sync-group are un-synced,
112 # the last one will raise a ValueError, because it is no longer
113 # being synced -- we just ignore it
114 pass
116 user.save()
118 sync_user.delay(user)