예제 #1
0
def importopml(request):
    theFile = request.FILES["opml"].read()

    count = 0
    dom = minidom.parseString(theFile)
    imported = []

    sources = dom.getElementsByTagName("outline")
    for s in sources:

        url = s.getAttribute("xmlUrl")
        if url.strip() != "":
            ns = Source.objects.filter(feed_url=url)
            if ns.count() > 0:

                # feed already exists - so there may already be a user subscription for it
                ns = ns[0]
                us = Subscription.objects.filter(source=ns).filter(
                    user=request.user)
                if us.count() == 0:
                    us = Subscription(source=ns,
                                      user=request.user,
                                      name=ns.display_name)

                    if ns.max_index > 10:  # don't flood people with all these old things
                        us.last_read = ns.max_index - 10

                    us.save()
                    count += 1

                ns.num_subs = ns.subscriptions.count()
                ns.save()

            else:
                # Feed does not already exist it must also be a new sub
                ns = Source()
                ns.due_poll = datetime.datetime.utcnow().replace(tzinfo=utc)
                ns.site_url = s.getAttribute("htmlUrl")
                ns.feed_url = url  # probably best to see that there isn't a match here :)
                ns.name = s.getAttribute("title")
                ns.save()

                us = Subscription(source=ns,
                                  user=request.user,
                                  name=ns.display_name)
                us.save()

                count += 1

            imported.append(ns)

    vals = {}
    vals["imported"] = imported
    vals["count"] = count
    return render(request, 'importopml.html', vals)
예제 #2
0
def addfeed(request):
    try:
        feed = ""
        if request.method == 'GET':
            if request.GET.__contains__("feed"):
                feed = request.GET["feed"]
            groups = Subscription.objects.filter(
                Q(user=request.user) & Q(source=None))

            return render(request, "addfeed.html", {
                "feed": feed,
                "groups": groups
            })

        else:

            if request.POST.__contains__("feed"):
                feed = request.POST["feed"]

            headers = {
                "User-Agent":
                "FeedThing/3.3 (+http://%s; Initial Feed Crawler)" %
                request.META["HTTP_HOST"],
                "Cache-Control":
                "no-cache,max-age=0",
                "Pragma":
                "no-cache"
            }  # identify ourselves and also stop our requests getting picked up by google's cache

            ret = requests.get(feed, headers=headers, verify=False, timeout=15)
            # can I be bothered to check return codes here?  I think not on balance

            isFeed = False

            content_type = "Not Set"
            if "Content-Type" in ret.headers:
                content_type = ret.headers["Content-Type"]

            feed_title = feed

            body = ret.text.strip()
            if "xml" in content_type or body[0:1] == "<":
                ff = feedparser.parse(
                    body)  # are we a feed?  # imported by django-feed-reader
                isFeed = (len(ff.entries) > 0)
                if isFeed:
                    feed_title = ff.feed.title
            if "json" in content_type or body[0:1] == "{":
                data = json.loads(body)
                isFeed = "items" in data and len(data["items"]) > 0
                if isFeed:
                    feed_title = data["title"]

            if not isFeed:

                soup = BeautifulSoup(body)
                feedcount = 0
                rethtml = ""
                for l in soup.findAll(name='link'):
                    if l.has_attr("rel") and l.has_attr("type"):
                        if l['rel'][0] == "alternate" and (
                                l['type'] == 'application/atom+xml'
                                or l['type'] == 'application/rss+xml'
                                or l['type'] == 'application/json'):
                            feedcount += 1
                            try:
                                name = l['title']
                            except Exception as ex:
                                name = "Feed %d" % feedcount
                            rethtml += '<li><form method="post" onsubmit="return false;"> <input type="hidden" name="feed" id="feed-%d" value="%s"><a href="#" onclick="addFeed(%d)" class="btn btn-xs btn-default">Subscribe</a> - %s</form></li>' % (
                                feedcount, urljoin(feed,
                                                   l['href']), feedcount, name)
                            feed = urljoin(
                                feed, l['href']
                            )  # store this in case there is only one feed and we wind up importing it
                            # TODO: need to accout for relative URLs here
                # if feedcount == 1:
                # just 1 feed found, let's import it now

                #   ret = fetch(f)
                #   isFeed = True
                if feedcount == 0:
                    return HttpResponse("No feeds found")
                else:
                    return HttpResponse(rethtml)

            if isFeed:
                parent = None
                if request.POST["group"] != "0":
                    parent = get_object_or_404(Subscription,
                                               id=int(request.POST["group"]))
                    if parent.user != request.user:
                        return HttpResponse(
                            "<div>Internal error.<!--bad group --></div>")

                s = Source.objects.filter(feed_url=feed)
                if s.count() > 0:
                    # feed already exists
                    s = s[0]
                    us = Subscription.objects.filter(
                        Q(user=request.user) & Q(source=s))
                    if us.count() > 0:
                        return HttpResponse(
                            "<div>Already subscribed to this feed </div>")
                    else:
                        us = Subscription(source=s,
                                          user=request.user,
                                          name=s.display_name,
                                          parent=parent)

                        if s.max_index > 10:  # don't flood people with all these old things
                            us.last_read = s.max_index - 10

                        us.save()

                        s.num_subs = s.subscriptions.count()
                        s.save()

                        return HttpResponse("<div>Imported feed %s</div>" %
                                            us.name)

                # need to start checking feed parser errors here
                ns = Source()
                # ns.due_poll = datetime.datetime.utcnow().replace(tzinfo=utc)

                # print request.POST["river"]
                # ns.inRiver = (request.POST["river"] == "yes")

                ns.name = feed_title
                ns.feed_url = feed

                ns.save()

                us = Subscription(source=ns,
                                  user=request.user,
                                  name=ns.display_name,
                                  parent=parent)
                us.save()

                # you see really, I could parse out the items here and insert them rather than wait for them to come back round in the refresh cycle

                return HttpResponse("<div>Imported feed %s</div>" % ns.name)
    except Exception as xx:
        return HttpResponse("<div>Error %s: %s</div>" %
                            (xx.__class__.__name__, str(xx)))