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 mygpo
.api
.basic_auth
import require_valid_user
19 from django
.http
import HttpResponse
, HttpResponseBadRequest
, HttpResponseForbidden
, Http404
20 from mygpo
.api
.models
import Device
, SubscriptionAction
, Podcast
, SUBSCRIBE_ACTION
, UNSUBSCRIBE_ACTION
21 from mygpo
.api
.opml
import Exporter
, Importer
22 from mygpo
.api
.httpresponse
import JsonResponse
23 from django
.core
import serializers
24 from datetime
import datetime
25 from mygpo
.api
.httpresponse
import HttpResponseNotAuthorized
27 from mygpo
.log
import log
30 import simplejson
as json
35 def subscriptions(request
, username
, device_uid
, format
):
37 if request
.user
.username
!= username
:
39 return HttpResponseNotAuthorized()
41 if request
.method
== 'GET':
42 return format_subscriptions(get_subscriptions(request
.user
, device_uid
), format
, username
)
44 elif request
.method
== 'PUT':
45 return set_subscriptions(parse_subscription(request
.raw_post_data
, format
, request
.user
, device_uid
))
47 return HttpResponseBadReqest()
50 def format_subscriptions(subscriptions
, format
, username
):
52 #return subscriptions formatted as txt
53 urls
= [p
.url
for p
in subscriptions
]
56 return HttpResponse(s
, mimetype
='text/plain')
58 elif format
== 'opml':
59 title
= username
+ '\'s subscription list'
60 exporter
= Exporter(title
)
61 opml
= exporter
.generate(subscriptions
)
62 return HttpResponse(opml
, mimetype
='text/xml')
64 elif format
== 'json':
65 urls
= [p
.url
for p
in subscriptions
]
66 return JsonResponse(urls
)
68 def get_subscriptions(user
, device_uid
):
69 #get and return subscription list from database (use backend to sync)
71 d
= Device
.objects
.get(uid
=device_uid
, user
=user
)
72 except Device
.DoesNotExist
:
73 raise Http404('Device doesn\'t exist!')
74 return [p
.podcast
for p
in d
.get_subscriptions()]
76 def parse_subscription(raw_post_data
, format
, user
, device_uid
):
78 sub
= raw_post_data
.split('\n')
82 if re
.search(p
, x
) == None:
83 log('parse_subscription (txt): invalid podcast url: %s' % x
)
87 elif format
== 'opml':
88 i
= Importer(content
=raw_post_data
)
89 urls
= [p
['url'] for p
in i
.items
]
91 elif format
== 'json':
92 urls
= json
.loads(raw_post_data
)
94 else: raise ValueError('unsupported format %s' % format
)
96 d
, created
= Device
.objects
.get_or_create(user
=user
, uid
=device_uid
,
97 defaults
= {'type': 'other', 'name': device_uid
})
99 podcasts
= [p
.podcast
for p
in d
.get_subscriptions()]
100 old
= [p
.url
for p
in podcasts
]
101 new
= [p
for p
in urls
if p
not in old
]
102 rem
= [p
for p
in old
if p
not in urls
]
106 def set_subscriptions(subscriptions
):
107 new
, rem
, d
= subscriptions
110 p
= Podcast
.objects
.get(url
=r
)
111 s
= SubscriptionAction(podcast
=p
, device
=d
, action
=UNSUBSCRIBE_ACTION
)
115 p
, created
= Podcast
.objects
.get_or_create(url
=n
,
116 defaults
={'title':n
,'description':n
,'last_update':datetime
.now()})
117 s
= SubscriptionAction(podcast
=p
, action
=SUBSCRIBE_ACTION
, device
=d
)
120 # Only an empty response is a successful response
121 return HttpResponse('', mimetype
='text/plain')