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
34 @allowed_methods(['GET', 'POST'])
36 def main(request
, username
):
37 """ API Endpoint for Device Synchronisation """
39 if request
.method
== 'GET':
40 return JsonResponse(get_sync_status(request
.user
))
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', [])
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 """
68 user
= UserProxy
.objects
.from_user(user
)
69 for group
in user
.get_grouped_devices():
70 uids
= [device
.uid
for device
in group
.devices
]
73 sync_groups
.append(uids
)
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
92 for devlist
in synclist
:
95 raise ValueError('at least two devices are needed to sync')
97 # Setup all devices to sync with the first in the list
99 dev
= user
.client_set
.get(uid
=uid
)
101 for other_uid
in devlist
[1:]:
102 other
= user
.get_device_by_uid(other_uid
)
107 dev
= user
.get_device_by_uid(uid
)
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
118 sync_user
.delay(user
)