def on_actionDelete_Feed_activated(self, b=None): """Unsubscribe from current feed""" if b is not None: return item = self.ui.feeds.currentItem() if item: fitem = item.parent() if not fitem: fitem = item feed = backend.Feed.get_by(xmlurl=fitem._id) if not feed: return # Got the current feed, now, must delete it feed.delete() # Delete all feedless posts for p in backend.Post.query.filter_by(feed=None).all(): p.delete() backend.saveData() # May need to delete feed from google if self.keepGoogleSynced: try: # Add this feed to google reader reader = self.getGoogleReader2() if reader: print "Unsubscribing at google: ", fitem._id reader.unsubscribe_feed(fitem._id) except Exception, e: # I'm not going to worry if this fails print e self.loadFeeds()
def on_actionImport_Google_Reader_activated(self, b=None): if b is not None: return reader = self.getGoogleReader() if not reader: return reader.buildSubscriptionList() feeds = reader.getFeeds() for f in feeds: f1 = backend.Feed.update_or_create(dict(name=f.title.decode("utf-8"), xmlurl=f.url), surrogate=False) backend.saveData() self.refreshFeeds()
def on_actionStar_toggled(self, b=None): """Mark the current post as unread""" # FIXME this **can** be called without the item being current # if the user calls it from the page link, so it should take an ID # as optional argument if b is None: return item = self.ui.feeds.currentItem() if not item.parent(): return # Not a post post = backend.Post.get_by(_id=item._id) if not post: return post.star = b backend.saveData() self.refreshFeeds()
def on_actionSync_Read_Items_activated(self, b=None): """Fetches the readingList from google and marks all known articles as read. Saves that list as self.googleList""" if b is not None: return progress = QtGui.QProgressDialog(self) progress.setLabelText(self.tr("Connecting to Google Reader")) progress.show() progress.setAutoClose(True) QtCore.QCoreApplication.processEvents() reader = self.getGoogleReader() userJson = reader.httpGet(reader.READING_LIST_URL, {"n": 5000}) allPosts = json.loads(userJson, strict=False)["items"] userInfo = reader.getUserInfo() readtag = u"user/%s/state/com.google/read" % userInfo["userId"] changedFeeds = set() progress.setLabelText(self.tr("Syncing")) progress.setMaximum(len(allPosts)) for i, p in enumerate(allPosts): progress.setValue(i) if i % 10 == 0: QtCore.QCoreApplication.processEvents() if progress.wasCanceled(): break if readtag in p["categories"]: # It's read p2 = backend.Post.get_by(url=p["alternate"][0]["href"]) f1 = backend.Feed.get_by(xmlurl=p["origin"]["streamId"][5:]) if p2 and f1 and p2.feed == f1 and p2.read == False: p2.read = True print "Marking post: ", p2._id if f1 not in changedFeeds: changedFeeds.add(f1) elif not p2: print "Can't find post:", p["alternate"] self.googleList = allPosts backend.saveData() progress.close() # Update all changed feeds in the UI # FIXME: this can be made smarter self.refreshFeeds()
def on_actionMark_All_As_Read_triggered(self, b=None): """Mark all visible posts in the current feed as read""" if b is not None: return print "Marking feed as Read" item = self.ui.feeds.currentItem() fitem = item.parent() if not fitem: fitem = item if fitem._id in (-1, -2): return for i in range(fitem.childCount()): _id = fitem.child(i)._id if _id: post = backend.Post.get_by(_id=_id) post.read = True if not self.showAllPosts: fitem.takeChildren() backend.saveData() self.on_feeds_itemClicked(item=fitem, column=1)
def on_feeds_itemClicked(self, item=None, column=1): if item is None: return fitem = item.parent() if fitem: # Post p = backend.Post.get_by(_id=item._id) data = pickle.loads(base64.b64decode(p.data)) # We display differently depending on current mode # The modes are: # ["Feed Decides", "Site", "Feed", "Fast Site", "Fast Feed"] # Use feed mode as feed decides for a while if self.mode == 0: self.mode = 2 if self.mode == 0: # Feed decides self.ui.html.load(QtCore.QUrl(p.url)) elif self.mode == 1: # Site mode self.ui.html.load(QtCore.QUrl(p.url)) elif self.mode == 2: # Feed mode # content = '' # if 'content' in data: # content = '<hr>'.join([c.value for c in data['content']]) # elif 'summary' in data: # content = data['summary'] # elif 'value' in data: # content = data['value'] # else: # print "Can't find content in this entry" # print data ## Rudimentary NON-html detection # if not '<' in content: # content=escape(content).replace('\n\n', '<p>') self.ui.html.setHtml( renderTemplate( "post.tmpl", post=p, data=data, content=p.content, cssdir=tmplDir, escapedposturl=cgi.escape(p.url), escapedposttitle=cgi.escape(p.title), ) ) elif self.mode == 3: # Fast site mode fname = os.path.join(backend.dbdir, "cache", "%s.jpg" % hashlib.md5(p._id).hexdigest()) if os.path.exists(fname): self.ui.html.setHtml("""<img src="file://%s" style="max-width:100%%;">""" % fname) else: self.ui.html.load(QtCore.QUrl(p.url)) elif self.mode == 4: # Fast Feed mode pass # Enclosures for enclosure in self.enclosures: enclosure.hide() enclosure.deleteLater() self.enclosures = [] resize = False for e in data.get("enclosures", []): # FIXME: add generic 'download' enclosure widget cls = None if hasattr(e, "type"): if e.type.startswith("audio"): cls = AudioPlayer elif e.type.startswith("video") or e.href.split(".")[-1] in ["ogv", "m4v", "avi", "mp4"]: cls = VideoPlayer resize = True if cls: player = cls(e.href, self.enclosureContainer) player.show() self.enclosures.append(player) self.enclosureLayout.addWidget(player) if self.enclosures: self.enclosureContainer.show() if resize: self.enclosureContainer.setGeometry(0, 0, self.width(), 200) else: self.enclosureContainer.hide() p.read = True if column == 0: print "Star clicked setting to:", not p.star p.star = not p.star if p.star: item.setIcon(0, QtGui.QIcon(":/icons/star.svg")) else: item.setIcon(0, QtGui.QIcon(":/icons/star2.svg")) backend.saveData() item.setForeground(1, QtGui.QBrush(QtGui.QColor("lightgray"))) if fitem._id != p.feed.xmlurl: # Also mark as read in the post's feed item = self.findPostItem(p) if item: item.setForeground(1, QtGui.QBrush(QtGui.QColor("lightgray"))) if p.star: item.setIcon(0, QtGui.QIcon(":/icons/star.svg")) else: item.setIcon(0, QtGui.QIcon(":/icons/star2.svg")) # Update unread count self.updateFeed(p.feed.xmlurl) else: # Feed self.enclosureContainer.hide() self.updateCurrentFeed() feed = backend.Feed.get_by(xmlurl=item._id) if feed: # Timeline data structure tdata = {} # tdata['events']=[{ # 'start': p.date.strftime(r"%b %d %Y %H:%M:00 GMT"), # 'title': p.title, # 'link': p.url, # } for p in feed.posts] data = pickle.loads(base64.b64decode(feed.data)) if "status" in data: status = data["status"] else: status = "Unknown" self.ui.html.setHtml( renderTemplate( "feed.tmpl", timelinedata=json.dumps(tdata), feed=feed, cssdir=tmplDir, status=status ) ) else: self.ui.html.setHtml("") if not item.isExpanded(): self.ui.feeds.collapseAll() item.takeChildren() item.setExpanded(True) self.showFeedPosts(item, feed)