def search_podcasts(q, limit=20, skip=0): if is_url(q): url = sanitize_url(q) podcast = Podcast.for_url(url, create=True) if not podcast.title: update_podcasts([podcast]) podcast = Podcast.for_url(url) return [podcast], 1 db = get_main_database() #FIXME current couchdbkit can't parse responses for multi-query searches q = q.replace(',', '') res = db.search('podcasts/search', wrapper=search_wrapper, include_docs=True, limit=limit, skip=skip, q=q, sort='\\subscribers<int>') #FIXME: return empty results in case of search backend error try: return list(res), res.total_rows except: return [], 0
def handle(self, *args, **options): if len(args) != 5: print 'Usage: ./manage.py group-podcasts <url1> <url2> <group-name> <name1> <name2>' return p1_url = args[0] p2_url = args[1] group_title = args[2] myname = args[3] othername = args[4] p1 = Podcast.for_url(p1_url) p2 = Podcast.for_url(p2_url) p1.group_with(p2, group_title, myname, othername)
def list_favorites(request): site = RequestSite(request) episodes = backend.get_favorites(request.user) podcast_ids = [episode.podcast for episode in episodes] podcasts = get_to_dict(Podcast, podcast_ids, Podcast.get_id) def set_podcast(episode): episode = proxy_object(episode) episode.podcast = podcasts.get(episode.podcast, None) return episode episodes = map(set_podcast, episodes) feed_url = 'http://%s/%s' % (site.domain, reverse('favorites-feed', args=[request.user.username])) podcast = Podcast.for_url(feed_url) if 'public_feed' in request.GET: request.user.favorite_feeds_token = '' request.user.save() elif 'private_feed' in request.GET: request.user.create_new_token('favorite_feeds_token', 8) request.user.save() token = request.user.favorite_feeds_token return render(request, 'favorites.html', { 'episodes': episodes, 'feed_token': token, 'site': site, 'podcast': podcast, })
def create(request, username, format): """ Creates a new podcast list and links to it in the Location header """ title = request.GET.get('title', None) if not title: return HttpResponseBadRequest('Title missing') slug = slugify(title) if not slug: return HttpResponseBadRequest('Invalid title') plist = PodcastList.for_user_slug(request.user._id, slug) if plist: return HttpResponse('List already exists', status=409) urls = parse_subscription(request.raw_post_data, format) podcasts = [Podcast.for_url(url, create=True) for url in urls] podcast_ids = map(Podcast.get_id, podcasts) plist = PodcastList() plist.title = title plist.slug = slug plist.user = request.user._id plist.podcasts = podcast_ids plist.save() response = HttpResponse(status=201) list_url = reverse('api-get-list', args=[request.user.username, slug, format]) response['Location'] = list_url return response
def _get_podcasts(self, request): podcasts = [] for n in count(): podcast_url = request.POST.get('feed%d' % n, None) if podcast_url is None: break if not podcast_url: continue podcast = Podcast.for_url(podcast_url) if not podcast: raise InvalidPodcast(podcast_url) podcasts.append(Podcast.for_url(podcast_url)) return podcasts
def podcast_info(request): url = sanitize_url(request.GET.get('url', '')) podcast = Podcast.for_url(url) if not podcast: raise Http404 domain = RequestSite(request).domain resp = podcast_data(podcast, domain) return JsonResponse(resp)
def _get_obj_fun(self, action): url, op = action podcast = self.podcasts.get(url, Podcast.for_url(url, create=True)) state = podcast.get_user_state(self.user) fun = self.operations[op] return (state, fun)
def episodes(request, username, version=1): version = int(version) now = datetime.now() now_ = get_timestamp(now) ua_string = request.META.get('HTTP_USER_AGENT', '') if request.method == 'POST': try: actions = json.loads(request.raw_post_data) except (JSONDecodeError, UnicodeDecodeError) as e: log('Advanced API: could not decode episode update POST data for user %s: %s' % (username, e)) return HttpResponseBadRequest() try: update_urls = update_episodes(request.user, actions, now, ua_string) except DeviceUIDException as e: import traceback log('could not update episodes for user %s: %s %s: %s' % (username, e, traceback.format_exc(), actions)) return HttpResponseBadRequest(str(e)) return JsonResponse({'timestamp': now_, 'update_urls': update_urls}) elif request.method == 'GET': podcast_url= request.GET.get('podcast', None) device_uid = request.GET.get('device', None) since_ = request.GET.get('since', None) aggregated = parse_bool(request.GET.get('aggregated', False)) try: since = datetime.fromtimestamp(float(since_)) if since_ else None except ValueError: return HttpResponseBadRequest('since-value is not a valid timestamp') if podcast_url: podcast = Podcast.for_url(podcast_url) if not podcast: raise Http404 else: podcast = None if device_uid: try: device = request.user.get_device_by_uid(device_uid) except DeviceDoesNotExist as e: return HttpResponseNotFound(str(e)) else: device = None changes = get_episode_changes(request.user, podcast, device, since, now, aggregated, version) return JsonResponse(changes)
def search_podcast(request): form = SearchPodcastForm(request.POST) if form.is_valid(): url = form.cleaned_data['url'] podcast = Podcast.for_url(url) if not podcast: raise Http404 url = get_podcast_link_target(podcast, 'podcast-publisher-detail') else: url = reverse('publisher') return HttpResponseRedirect(url)
def subscribe_url(request): url = request.GET.get('url', None) if not url: raise Http404('http://my.gpodder.org/subscribe?url=http://www.example.com/podcast.xml') url = sanitize_url(url) if url == '': raise Http404('Please specify a valid url') podcast = Podcast.for_url(url, create=True) return HttpResponseRedirect(get_podcast_link_target(podcast, 'subscribe'))
def handle(self, *args, **options): urls = list(map(str.strip, fileinput.input(args))) try: examples = ExamplePodcasts.get(EXAMPLES_DOCID) except ResourceNotFound: examples = ExamplePodcasts() examples._id = EXAMPLES_DOCID podcasts = filter(None, [Podcast.for_url(url) for url in urls]) examples.podcast_ids = [podcast.get_id() for podcast in podcasts] examples.updated = datetime.utcnow() examples.save()
def _get_podcasts(self, *args, **options): if options.get('toplist'): yield self.get_toplist() if options.get('new'): yield self.get_podcast_with_new_episodes() if options.get('random'): yield Podcast.random() get_podcast = lambda url: Podcast.for_url(url, create=True) yield map(get_podcast, args) if not args and not options.get('toplist') and not options.get('new') \ and not options.get('random'): yield Podcast.by_last_update()
def upload(request): try: emailaddr = request.POST['username'] password = request.POST['password'] action = request.POST['action'] protocol = request.POST['protocol'] opml = request.FILES['opml'].read() except MultiValueDictKeyError: return HttpResponse("@PROTOERROR", mimetype='text/plain') user = auth(emailaddr, password) if (not user): return HttpResponse('@AUTHFAIL', mimetype='text/plain') dev = get_device(user, LEGACY_DEVICE_UID, request.META.get('HTTP_USER_AGENT', '')) existing_urls = [x.url for x in dev.get_subscribed_podcasts()] i = Importer(opml) podcast_urls = [p['url'] for p in i.items] podcast_urls = sanitize_urls(podcast_urls) podcast_urls = filter(lambda x: x, podcast_urls) new = [u for u in podcast_urls if u not in existing_urls] rem = [u for e in existing_urls if u not in podcast_urls] #remove duplicates new = list(set(new)) rem = list(set(rem)) for n in new: try: p = Podcast.for_url(n, create=True) except IntegrityError, e: log('/upload: Error trying to get podcast object: %s (error: %s)' % (n, e)) continue try: p.subscribe(user, dev) except Exception as e: log('Legacy API: %(username)s: could not subscribe to podcast %(podcast_url)s on device %(device_id)s: %(exception)s' % {'username': user.username, 'podcast_url': p.url, 'device_id': dev.id, 'exception': e})
def update_list(request, plist, owner, format): """ Replaces the podcasts in the list and returns 204 No Content """ is_own = owner == request.uuser if not is_own: return HttpResponseForbidden() urls = parse_subscription(request.raw_post_data, format) podcasts = [Podcast.for_url(url, create=True) for url in urls] podcast_ids = map(Podcast.get_id, podcasts) @repeat_on_conflict(['podcast_ids']) def _update(plist, podcast_ids): plist.podcasts = podcast_ids plist.save() _update(plist=plist, podcast_ids=podcast_ids) return HttpResponse(status=204)
def podcast_settings(user, url): podcast = Podcast.for_url(url) if not podcast: raise Http404 obj = PodcastUserState.for_user_podcast(user, podcast) return obj, obj
for n in new: try: p = Podcast.for_url(n, create=True) except IntegrityError, e: log('/upload: Error trying to get podcast object: %s (error: %s)' % (n, e)) continue try: p.subscribe(user, dev) except Exception as e: log('Legacy API: %(username)s: could not subscribe to podcast %(podcast_url)s on device %(device_id)s: %(exception)s' % {'username': user.username, 'podcast_url': p.url, 'device_id': dev.id, 'exception': e}) for r in rem: p = Podcast.for_url(r, create=True) try: p.unsubscribe(user, dev) except Exception as e: log('Legacy API: %(username): could not unsubscribe from podcast %(podcast_url) on device %(device_id): %(exception)s' % {'username': user.username, 'podcast_url': p.url, 'device_id': dev.id, 'exception': e}) return HttpResponse('@SUCCESS', mimetype='text/plain') @never_cache @csrf_exempt def getlist(request): emailaddr = request.GET.get('username', None) password = request.GET.get('password', None) user = auth(emailaddr, password)
def update_podcasts(fetch_queue): for n, podcast in enumerate(fetch_queue): print '(%d) %s' % (n, podcast.url) try: timeout = socket.getdefaulttimeout() socket.setdefaulttimeout(60) fetcher.fetch(podcast.url) socket.setdefaulttimeout(timeout) except (feedcore.Offline, feedcore.InvalidFeed, feedcore.WifiLogin, feedcore.AuthenticationRequired, socket.error, IOError): print 'marking outdated' mark_outdated(podcast) except feedcore.NewLocation, location: print 'redirecting to', location.data new_url = sanitize_url(location.data) if new_url: p = Podcast.for_url(new_url) if not p: podcast.urls.insert(0, new_url) fetch_queue = chain([podcast], fetch_queue) else: print 'podcast with new URL found, outdating old one' podcast.new_location = new_url podcast.save() mark_outdated(podcast) except feedcore.UpdatedFeed, updated: feed = updated.data existing_episodes = list(podcast.get_episodes()) update_ep = partial(update_episode, podcast=podcast) feed_episodes = filter(None, map(update_ep, feed.entries)) outdated_episodes = set(existing_episodes) - set(feed_episodes) # set episodes to be outdated, where necessary for e in filter(lambda e: not e.outdated, outdated_episodes): e.outdated = True e.save() podcast_md = get_podcast_metadata(podcast, feed) changed = False for key, value in podcast_md.items(): if getattr(podcast, key) != value: setattr(podcast, key, value) changed = True tags = get_feed_tags(feed.feed) if podcast.tags.get('feed', None) != tags: podcast.tags['feed'] = tags changed = True if changed: print 'updating podcast' podcast.last_update = datetime.utcnow() podcast.save() else: print 'podcast not updated'