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 datetime
import datetime
20 from django
.http
import HttpResponse
21 from django
.utils
.datastructures
import MultiValueDictKeyError
22 from django
.views
.decorators
.csrf
import csrf_exempt
23 from django
.views
.decorators
.cache
import never_cache
24 from django
.contrib
.auth
import get_user_model
26 from mygpo
.podcasts
.models
import Podcast
27 from mygpo
.api
.opml
import Importer
, Exporter
28 from mygpo
.users
.models
import SubscriptionException
29 from mygpo
.api
.backend
import get_device
30 from mygpo
.utils
import normalize_feed_url
31 from mygpo
.subscriptions
import subscribe
, unsubscribe
34 logger
= logging
.getLogger(__name__
)
37 LEGACY_DEVICE_NAME
= 'Legacy Device'
38 LEGACY_DEVICE_UID
= 'legacy'
44 emailaddr
= request
.POST
['username']
45 password
= request
.POST
['password']
46 action
= request
.POST
['action']
47 protocol
= request
.POST
['protocol']
48 opml
= request
.FILES
['opml'].read()
49 except MultiValueDictKeyError
:
50 return HttpResponse("@PROTOERROR", content_type
='text/plain')
52 user
= auth(emailaddr
, password
)
54 return HttpResponse('@AUTHFAIL', content_type
='text/plain')
56 dev
= get_device(user
, LEGACY_DEVICE_UID
,
57 request
.META
.get('HTTP_USER_AGENT', ''))
59 existing_urls
= [x
.url
for x
in dev
.get_subscribed_podcasts()]
63 podcast_urls
= [p
['url'] for p
in i
.items
]
64 podcast_urls
= map(normalize_feed_url
, podcast_urls
)
65 podcast_urls
= list(filter(None, podcast_urls
))
67 new
= [u
for u
in podcast_urls
if u
not in existing_urls
]
68 rem
= [u
for u
in existing_urls
if u
not in podcast_urls
]
75 p
= Podcast
.objects
.get_or_create_for_url(n
)
76 subscribe(p
, user
, dev
)
79 p
= Podcast
.objects
.get_or_create_for_url(r
)
80 unsubscribe(p
, user
, dev
)
82 return HttpResponse('@SUCCESS', content_type
='text/plain')
87 emailaddr
= request
.GET
.get('username', None)
88 password
= request
.GET
.get('password', None)
90 user
= auth(emailaddr
, password
)
92 return HttpResponse('@AUTHFAIL', content_type
='text/plain')
94 dev
= get_device(user
, LEGACY_DEVICE_UID
,
95 request
.META
.get('HTTP_USER_AGENT', ''),
97 podcasts
= dev
.get_subscribed_podcasts()
99 title
= "{username}'s subscriptions".format(username
=user
.username
)
100 exporter
= Exporter(title
)
102 opml
= exporter
.generate(podcasts
)
104 return HttpResponse(opml
, content_type
='text/xml')
107 def auth(emailaddr
, password
):
108 if emailaddr
is None or password
is None:
111 User
= get_user_model()
113 user
= User
.objects
.get(email
=emailaddr
)
114 except User
.DoesNotExist
:
117 if not user
.check_password(password
):
120 if not user
.is_active
: