示例#1
0
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)
示例#2
0
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)
示例#3
0
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)
示例#4
0
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,
    })