[Migration] Get Podcasts / Episodes from PostgreSQL
[mygpo.git] / mygpo / web / views / __init__.py
blobdc280807032f9977ceda9751acbaf5d70775f380
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 import sys
19 from collections import defaultdict
20 from datetime import datetime, timedelta
22 try:
23 import gevent
24 except ImportError:
25 gevent = None
27 from django.core.urlresolvers import reverse
28 from django.http import HttpResponseRedirect
29 from django.contrib import messages
30 from django.utils.translation import ugettext as _
31 from django.contrib.auth.decorators import login_required
32 from django.shortcuts import render
33 from django.contrib.sites.models import RequestSite
34 from django.views.generic.base import View
35 from django.views.decorators.vary import vary_on_cookie
36 from django.views.decorators.cache import never_cache, cache_control
38 from mygpo.decorators import repeat_on_conflict
39 from mygpo.core.podcasts import PodcastSet
40 from mygpo.podcasts.models import Podcast
41 from mygpo.directory.toplist import PodcastToplist
42 from mygpo.users.models import History, HistoryEntry, DeviceDoesNotExist
43 from mygpo.users.tasks import update_suggestions
44 from mygpo.web.utils import process_lang_params
45 from mygpo.utils import parse_range
46 #from mygpo.web.views.podcast import slug_id_decorator
47 from mygpo.users.settings import FLATTR_AUTO, FLATTR_TOKEN
48 from mygpo.db.couchdb.episode import favorite_episode_ids_for_user
49 from mygpo.db.couchdb.podcast import podcast_by_id
50 from mygpo.db.couchdb.user import (suggestions_for_user,
51 blacklist_suggested_podcast)
52 from mygpo.db.couchdb.directory import tags_for_user
53 from mygpo.db.couchdb.podcastlist import podcastlists_for_user
56 @vary_on_cookie
57 @cache_control(private=True)
58 def home(request):
59 if request.user.is_authenticated():
60 return dashboard(request)
61 else:
62 return welcome(request)
65 @vary_on_cookie
66 @cache_control(private=True)
67 def welcome(request):
68 current_site = RequestSite(request)
70 lang = process_lang_params(request)
72 toplist = PodcastToplist(lang)
74 return render(request, 'home.html', {
75 'url': current_site,
76 'toplist': toplist,
80 @vary_on_cookie
81 @cache_control(private=True)
82 @login_required
83 def dashboard(request, episode_count=10):
85 subscribed_podcasts = list(request.user.get_subscribed_podcasts())
86 site = RequestSite(request)
88 checklist = []
90 if request.user.devices:
91 checklist.append('devices')
93 if subscribed_podcasts:
94 checklist.append('subscriptions')
96 if favorite_episode_ids_for_user(request.user):
97 checklist.append('favorites')
99 if not request.user.get_token('subscriptions_token'):
100 checklist.append('share')
102 if not request.user.get_token('favorite_feeds_token'):
103 checklist.append('share-favorites')
105 if not request.user.get_token('userpage_token'):
106 checklist.append('userpage')
108 if tags_for_user(request.user):
109 checklist.append('tags')
111 # TODO add podcastlist_count_for_user
112 if podcastlists_for_user(request.user._id):
113 checklist.append('lists')
115 if request.user.published_objects:
116 checklist.append('publish')
118 if request.user.get_wksetting(FLATTR_TOKEN):
119 checklist.append('flattr')
121 if request.user.get_wksetting(FLATTR_AUTO):
122 checklist.append('auto-flattr')
124 tomorrow = datetime.today() + timedelta(days=1)
126 podcasts = PodcastSet(subscribed_podcasts)
128 newest_episodes = podcasts.get_newest_episodes(tomorrow, episode_count)
130 # we only show the "install reader" link in firefox, because we don't know
131 # yet how/if this works in other browsers.
132 # hints appreciated at https://bugs.gpodder.org/show_bug.cgi?id=58
133 show_install_reader = \
134 'firefox' in request.META.get('HTTP_USER_AGENT', '').lower()
136 return render(request, 'dashboard.html', {
137 'user': request.user,
138 'subscribed_podcasts': subscribed_podcasts,
139 'newest_episodes': list(newest_episodes),
140 'random_podcast': Podcast.objects.random().first(),
141 'checklist': checklist,
142 'site': site,
143 'show_install_reader': show_install_reader,
147 @vary_on_cookie
148 @cache_control(private=True)
149 @login_required
150 def history(request, count=15, uid=None):
152 page = parse_range(request.GET.get('page', None), 0, sys.maxint, 0)
154 if uid:
155 try:
156 device = request.user.get_device_by_uid(uid, only_active=False)
157 except DeviceDoesNotExist as e:
158 messages.error(request, str(e))
160 else:
161 device = None
163 history_obj = History(request.user, device)
165 start = page*count
166 end = start+count
167 entries = history_obj[start:end]
168 HistoryEntry.fetch_data(request.user, entries)
170 return render(request, 'history.html', {
171 'history': entries,
172 'device': device,
173 'page': page,
177 @never_cache
178 @login_required
179 #@slug_id_decorator
180 def blacklist(request, blacklisted_podcast):
181 user = request.user
182 suggestion = suggestions_for_user(user)
183 blacklist_suggested_podcast(suggestion, blacklisted_podcast.get_id())
184 update_suggestions.delay(user)
185 return HttpResponseRedirect(reverse('suggestions'))
188 @never_cache
189 @login_required
190 def rate_suggestions(request):
191 rating_val = int(request.GET.get('rate', None))
193 suggestion = suggestions_for_user(request.user)
194 suggestion.rate(rating_val, request.user._id)
195 suggestion.save()
197 messages.success(request, _('Thanks for rating!'))
199 return HttpResponseRedirect(reverse('suggestions'))
202 @vary_on_cookie
203 @cache_control(private=True)
204 @login_required
205 def suggestions(request):
206 suggestion_obj = suggestions_for_user(request.user)
207 suggestions = suggestion_obj.get_podcasts()
208 current_site = RequestSite(request)
209 return render(request, 'suggestions.html', {
210 'entries': suggestions,
211 'url': current_site
215 @vary_on_cookie
216 @cache_control(private=True)
217 @login_required
218 def mytags(request):
219 tags_podcast = {}
220 tags_tag = defaultdict(list)
222 for podcast_id, taglist in tags_for_user(request.user).items():
223 podcast = podcast_by_id(podcast_id)
224 tags_podcast[podcast] = taglist
226 for tag in taglist:
227 tags_tag[ tag ].append(podcast)
229 return render(request, 'mytags.html', {
230 'tags_podcast': tags_podcast,
231 'tags_tag': dict(tags_tag.items()),
236 class GeventView(View):
237 """ View that provides parts of the context via gevent coroutines """
239 def get_context(self, context_funs):
240 """ returns a dictionary that can be used for a template context
242 context_funs is a context-key => Greenlet object mapping """
244 if gevent:
245 jobs = {}
246 for key, fun in context_funs.items():
247 jobs[key] = gevent.spawn(fun)
249 gevent.joinall(jobs.values())
251 for key, gev in jobs.items():
252 context_funs[key] = gev.get()
254 else:
255 for key, fun in context_funs.items():
256 context_funs[key] = fun()
258 return context_funs