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
25 from mygpo
.podcasts
.models
import Podcast
26 from mygpo
.users
.models
import User
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
.db
.couchdb
.podcast_state
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", mimetype
='text/plain')
52 user
= auth(emailaddr
, password
)
54 return HttpResponse('@AUTHFAIL', mimetype
='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
= filter(None, podcast_urls
)
67 new
= [u
for u
in podcast_urls
if u
not in existing_urls
]
68 rem
= [u
for e
in existing_urls
if u
not in podcast_urls
]
75 p
= Podcast
.objects
.get_or_create_for_url(n
)
78 subscribe(p
, user
, dev
)
79 except SubscriptionException
as e
:
80 logger
.exception('Legacy API: %(username)s: could not subscribe to podcast %(podcast_url)s on device %(device_id)s' %
81 {'username': user
.username
, 'podcast_url': p
.url
, 'device_id': dev
.id})
84 p
= Podcast
.objects
.get_or_create_for_url(r
)
86 unsubscribe(p
, user
, dev
)
87 except SubscriptionException
as e
:
88 logger
.exception('Legacy API: %(username): could not unsubscribe from podcast %(podcast_url) on device %(device_id)' %
89 {'username': user
.username
, 'podcast_url': p
.url
, 'device_id': dev
.id})
91 return HttpResponse('@SUCCESS', mimetype
='text/plain')
96 emailaddr
= request
.GET
.get('username', None)
97 password
= request
.GET
.get('password', None)
99 user
= auth(emailaddr
, password
)
101 return HttpResponse('@AUTHFAIL', mimetype
='text/plain')
103 dev
= get_device(user
, LEGACY_DEVICE_UID
,
104 request
.META
.get('HTTP_USER_AGENT', ''),
106 podcasts
= dev
.get_subscribed_podcasts()
108 title
= "{username}'s subscriptions".format(username
=user
.username
)
109 exporter
= Exporter(title
)
111 opml
= exporter
.generate(podcasts
)
113 return HttpResponse(opml
, mimetype
='text/xml')
116 def auth(emailaddr
, password
):
117 if emailaddr
is None or password
is None:
120 user
= User
.get_user_by_email(emailaddr
)
124 if not user
.check_password(password
):
127 if not user
.is_active
: