Пример #1
0
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
Пример #2
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)
Пример #3
0
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,
        })
Пример #4
0
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
Пример #5
0
    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
Пример #6
0
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)
Пример #7
0
    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)
Пример #8
0
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)
Пример #9
0
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)
Пример #10
0
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'))
Пример #11
0
    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()
Пример #12
0
    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()
Пример #13
0
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})
Пример #14
0
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)
Пример #15
0
 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
Пример #16
0
    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)
Пример #17
0
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'