def add(request): context = {} context['page_title'] = 'Add Podcast' id = request.GET.get('id', '').strip() if id: podcast = get_object_or_404(Podcast, id=id) if not podcast.image and podcast.image_url: podcast.download_image() if not Episode.objects.filter(podcast=podcast).exists(): download_episodes(podcast) url = reverse('podcasttime:index') + '#ids={}'.format(podcast.id) return redirect(url) search = request.GET.get('search', '').strip() context['search'] = search if search: podcasts = [] matches = itunes_search(search, attribute='titleTerm') for result in matches['results']: pod = { 'image_url': result['artworkUrl600'], 'itunes_url': result['collectionViewUrl'], 'artist_name': result['artistName'], 'tags': result['genres'], 'name': result['collectionName'], # 'feed_url': result['feedUrl'], } try: podcast = Podcast.objects.get( url=result['feedUrl'], name=result['collectionName'] ) except Podcast.DoesNotExist: podcast = Podcast.objects.create( name=result['collectionName'], url=result['feedUrl'], itunes_lookup=result, image_url=result['artworkUrl600'], ) # episodes will be created and downloaded by the cron job redownload_podcast_image.delay(podcast.id) pod['id'] = podcast.id pod['url'] = reverse( 'podcasttime:podcast_slug', args=(podcast.id, podcast.get_or_create_slug()) ) podcasts.append(pod) context['found'] = matches['resultCount'] context['podcasts'] = podcasts return render(request, 'podcasttime/add.html', context)
def podcast(request, id, slug=None): podcast = get_object_or_404(Podcast, id=id) context = {} context['podcast'] = podcast context['page_title'] = podcast.name episodes = Episode.objects.filter( podcast=podcast ).order_by('-published') if podcast.image and is_html_document(podcast.image.path): print "Found a podcast.image that wasn't an image" podcast.image = None podcast.save() redownload_podcast_image.delay(podcast.id) elif not podcast.image and podcast.image_url: redownload_podcast_image.delay(podcast.id) if podcast.itunes_lookup is None: fetch_itunes_lookup.delay(podcast.id) if not episodes.exists(): download_episodes_task.delay(podcast.id) context['episodes'] = episodes try: context['thumb'] = thumbnail(podcast.image, '300x300') except IOError: # image is so busted it can't be turned into a thumbnail podcast.image = None podcast.save() context['thumb'] = None redownload_podcast_image.delay(podcast.id) return render(request, 'podcasttime/podcast.html', context)
def podcast_data(request, id, slug=None): podcast = get_object_or_404(Podcast, id=id, slug__iexact=slug) context = {} context.update({ 'id': podcast.id, 'slug': podcast.slug, 'name': podcast.name, 'url': podcast.url, 'image_url': podcast.image_url, 'times_picked': podcast.times_picked, 'total_seconds': podcast.total_seconds, 'last_fetch': podcast.last_fetch, 'modified': podcast.modified, }) if podcast.error: context['_has_error'] = True if ( not podcast.last_fetch or podcast.last_fetch < timezone.now() - datetime.timedelta(days=7) ): cache_key = 'updating:episodes:{}'.format(podcast.id) if not cache.get(cache_key): cache.set(cache_key, True, 60) download_episodes_task.delay(podcast.id) context['_updating'] = True episodes = Episode.objects.filter( podcast=podcast ).order_by('-published') if podcast.image and is_html_document(podcast.image.path): print "Found a podcast.image that wasn't an image" podcast.image = None podcast.save() redownload_podcast_image.delay(podcast.id) elif not podcast.image and podcast.image_url: redownload_podcast_image.delay(podcast.id) if podcast.itunes_lookup is None: fetch_itunes_lookup.delay(podcast.id) if not episodes.exists(): download_episodes_task.delay(podcast.id) context['episodes_count'] = episodes.count() context['episodes'] = [] for episode in episodes: context['episodes'].append({ 'duration': episode.duration, 'published': episode.published, 'guid': episode.guid, }) try: thumb = thumbnail(podcast.image, '300x300') context['thumb'] = { 'url': thumb.url, 'width': thumb.width, 'height': thumb.height, } except IOError: # image is so busted it can't be turned into a thumbnail podcast.image = None podcast.save() context['thumb'] = None redownload_podcast_image.delay(podcast.id) return http.JsonResponse(context)
def find(request): if not (request.GET.get('ids') or request.GET.get('q')): return http.HttpResponseBadRequest('no ids or q') found = [] max_ = 5 q = None if request.GET.get('ids'): ids = [int(x) for x in request.GET['ids'].split(',')] found = Podcast.objects.filter(id__in=ids) # rearrange them in the order they were found = sorted(found, key=lambda x: ids.index(x.id)) # for podcast in found: # if not podcast.last_fetch: # download_episodes_task.delay(podcast.id) elif request.GET.get('itunes'): q = request.GET['q'] try: results = itunes_search( q, attribute='titleTerm', timeout=6, )['results'] except (ReadTimeout, ConnectTimeout): results = [] for result in results: # pod = { # 'image_url': result['artworkUrl600'], # 'itunes_url': result['collectionViewUrl'], # 'artist_name': result['artistName'], # 'tags': result['genres'], # 'name': result['collectionName'], # # 'feed_url': result['feedUrl'], # } try: podcast = Podcast.objects.get( url=result['feedUrl'], name=result['collectionName'] ) except Podcast.DoesNotExist: podcast = Podcast.objects.create( name=result['collectionName'], url=result['feedUrl'], itunes_lookup=result, image_url=result['artworkUrl600'], ) try: podcast.download_image(timeout=3) except (ReadTimeout, ConnectTimeout): redownload_podcast_image(podcast.id) download_episodes_task.delay(podcast.id) # Reload since the task functions operate on a new instance # podcast = Podcast.objects.get(id=podcast.id) found.append(podcast) else: q = request.GET['q'] items = [] # import time # time.sleep(random.randint(1,4)) base_qs = Podcast.objects.filter(error__isnull=True) podcasts = base_qs.filter(name__istartswith=q) for podcast in podcasts[:max_]: found.append(podcast) if len(q) > 2: sql = ( "to_tsvector('english', name) @@ " "plainto_tsquery('english', %s)" ) podcasts = base_qs.exclude( id__in=[x.id for x in found] ).extra( where=[sql], params=[q] )[:max_] for podcast in podcasts[:max_]: if len(found) >= max_: break found.append(podcast) if len(q) > 1: podcasts = base_qs.filter(name__icontains=q).exclude( id__in=[x.id for x in found] ) for podcast in podcasts[:max_]: if len(found) >= max_: break found.append(podcast) def episodes_meta(podcast): episodes_cache_key = 'episodes-meta%s' % podcast.id meta = cache.get(episodes_cache_key) if meta is None: episodes = Episode.objects.filter(podcast=podcast) episodes_count = episodes.count() total_hours = None if episodes_count: total_seconds = episodes.aggregate( Sum('duration') )['duration__sum'] if total_seconds: total_hours = total_seconds / 3600.0 else: download_episodes_task.delay(podcast.id) meta = { 'count': episodes_count, 'total_hours': total_hours, } if episodes_count: cache.set(episodes_cache_key, meta, 60 * 60 * 24) return meta items = [] for podcast in found: if podcast.image and is_html_document(podcast.image.path): print "Found a podcast.image that wasn't an image" podcast.image = None podcast.save() if podcast.image: if podcast.image.size < 1000: print "IMAGE LOOKS SUSPICIOUS" print podcast.image_url print repr(podcast), podcast.id print podcast.url print repr(podcast.image.read()) podcast.download_image() thumb_url = None if podcast.image: try: thumb_url = thumbnail( podcast.image, '100x100', quality=81, upscale=False ).url thumb_url = make_absolute_url(thumb_url, request) except IOError: import sys print "BAD IMAGE!" print sys.exc_info() print repr(podcast.image) print repr(podcast), podcast.url print podcast.image = None podcast.save() redownload_podcast_image.delay(podcast.id) else: redownload_podcast_image.delay(podcast.id) # Temporarily put here if podcast.itunes_lookup is None: fetch_itunes_lookup.delay(podcast.id) meta = episodes_meta(podcast) episodes_count = meta['count'] total_hours = meta['total_hours'] items.append({ 'id': podcast.id, 'name': podcast.name, 'image_url': thumb_url, 'episodes': episodes_count, 'hours': total_hours, 'last_fetch': podcast.last_fetch, 'slug': podcast.get_or_create_slug(), 'url': reverse( 'podcasttime:podcast_slug', args=(podcast.id, podcast.get_or_create_slug()) ), }) return http.JsonResponse({ 'items': items, 'q': q, })