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)
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)))