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
.core
.json
import JSONDecodeError
24 from mygpo
.utils
import parse_request_body
25 from mygpo
.api
.basic_auth
import require_valid_user
, check_username
26 from mygpo
.api
.httpresponse
import JsonResponse
27 from mygpo
.users
.models
import DeviceDoesNotExist
, User
28 from mygpo
.users
.tasks
import sync_user
29 from mygpo
.users
.sync
import get_grouped_devices
36 @allowed_methods(['GET', 'POST'])
38 def main(request
, username
):
39 """ API Endpoint for Device Synchronisation """
41 if request
.method
== 'GET':
42 return JsonResponse(get_sync_status(request
.user
))
46 actions
= parse_request_body(request
)
47 except JSONDecodeError
as e
:
48 return HttpResponseBadRequest(str(e
))
50 synclist
= actions
.get('synchronize', [])
51 stopsync
= actions
.get('stop-synchronize', [])
54 update_sync_status(request
.user
, synclist
, stopsync
)
55 except ValueError as e
:
56 return HttpResponseBadRequest(str(e
))
57 except DeviceDoesNotExist
as e
:
58 return HttpResponseNotFound(str(e
))
60 # reload user to get current sync status
61 user
= User
.get(request
.user
._id
)
62 return JsonResponse(get_sync_status(user
))
66 def get_sync_status(user
):
67 """ Returns the current Device Sync status """
72 for group
in get_grouped_devices(user
):
73 uids
= [device
.uid
for device
in group
.devices
]
76 sync_groups
.append(uids
)
82 'synchronized': sync_groups
,
83 'not-synchronized': unsynced
88 def update_sync_status(user
, synclist
, stopsync
):
89 """ Updates the current Device Sync status
91 Synchronisation between devices can be set up and stopped. Devices are
92 identified by their UIDs. Unknown UIDs cause errors, no new devices are
95 for devlist
in synclist
:
98 raise ValueError('at least two devices are needed to sync')
100 # Setup all devices to sync with the first in the list
102 dev
= user
.get_device_by_uid(uid
)
104 for other_uid
in devlist
[1:]:
105 other
= user
.get_device_by_uid(other_uid
)
110 dev
= user
.get_device_by_uid(uid
)
114 # if all devices of a sync-group are un-synced,
115 # the last one will raise a ValueError, because it is no longer
116 # being synced -- we just ignore it
121 sync_user
.delay(user
)