def __init__(self, buffer_id, url, arguments, fit_to_view,
                 background_color):
        Buffer.__init__(self, buffer_id, url, arguments, fit_to_view,
                        background_color)

        self.add_widget(BrowserView())

        self.buffer_widget.loadStarted.connect(self.start_progress)
        self.buffer_widget.loadProgress.connect(self.update_progress)
        self.buffer_widget.loadFinished.connect(self.stop_progress)

        self.buffer_widget.web_page.windowCloseRequested.connect(
            self.request_close_buffer)

        self.search_term = ""

        with open(
                os.path.join(os.path.dirname(__file__), "js",
                             "get_markers.js"), "r") as f:
            self.get_markers_js = f.read()

        with open(
                os.path.join(os.path.dirname(__file__), "js",
                             "goto_marker.js"), "r") as f:
            self.goto_marker_raw = f.read()
Пример #2
0
    def __init__(self, buffer_id, url, arguments, fit_to_view, background_color):
        Buffer.__init__(self, buffer_id, url, arguments, fit_to_view, background_color)

        self.add_widget(BrowserView())

        self.buffer_widget.loadStarted.connect(self.start_progress)
        self.buffer_widget.loadProgress.connect(self.update_progress)
        self.buffer_widget.loadFinished.connect(self.stop_progress)

        self.buffer_widget.web_page.windowCloseRequested.connect(self.request_close_buffer)
Пример #3
0
    def __init__(self, config_dir):
        super(RSSReaderWidget, self).__init__()

        self.feed_file_path = os.path.join(config_dir, "rss-reader", "feeds.json")

        self.feed_area = QWidget()
        self.feed_list = QListWidget()
        self.feed_list.setStyleSheet( """QListView {background: #4D5250; show-decoration-selected: 1; selection-background-color: #464646;}""")
        panel_layout = QVBoxLayout()
        panel_layout.setSpacing(0)
        panel_layout.setContentsMargins(0, 0, 0, 0)
        panel_layout.addWidget(self.feed_list)
        self.feed_area.setLayout(panel_layout)

        self.article_area = QWidget()
        self.article_list = QListWidget()
        self.article_list.setStyleSheet( """QListView {background: #FFF; show-decoration-selected: 1; selection-background-color: #EEE;}""")
        self.article_list.verticalScrollBar().setStyleSheet("QScrollBar {width:0px;}");
        article_layout = QVBoxLayout()
        article_layout.setSpacing(0)
        article_layout.setContentsMargins(0, 0, 0, 0)

        self.browser = BrowserView(config_dir)

        article_layout.addWidget(self.article_list)
        article_layout.addWidget(self.browser)

        article_layout.setStretchFactor(self.article_list, 1)
        article_layout.setStretchFactor(self.browser, 3)

        self.article_area.setLayout(article_layout)

        self.welcome_page = QWidget()
        self.welcome_page_box = QVBoxLayout()
        self.welcome_page_box.setSpacing(10)
        self.welcome_page_box.setContentsMargins(0, 0, 0, 0)

        welcome_title_label = QLabel("Welcome to EAF RSS Reader!")
        welcome_title_label.setFont(QFont('Arial', 24))
        welcome_title_label.setStyleSheet("QLabel {color: #333; font-weight: bold; margin: 20px;}")
        welcome_title_label.setAlignment(Qt.AlignHCenter)

        add_subscription_label = QLabel("Press 'a' to subscribe to a feed!")
        add_subscription_label.setFont(QFont('Arial', 20))
        add_subscription_label.setStyleSheet("QLabel {color: #grey;}")
        add_subscription_label.setAlignment(Qt.AlignHCenter)

        self.welcome_page_box.addStretch(1)
        self.welcome_page_box.addWidget(welcome_title_label)
        self.welcome_page_box.addWidget(add_subscription_label)
        self.welcome_page_box.addStretch(1)

        self.welcome_page.setLayout(self.welcome_page_box)

        self.right_area = QStackedWidget()
        self.right_area.addWidget(self.welcome_page)
        self.right_area.addWidget(self.article_area)

        if self.has_feed():
            self.right_area.setCurrentIndex(1)
        else:
            self.right_area.setCurrentIndex(0)

        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.setContentsMargins(0, 0, 0, 0)

        hbox.addWidget(self.feed_area)
        hbox.addWidget(self.right_area)

        hbox.setStretchFactor(self.feed_area, 1)
        hbox.setStretchFactor(self.right_area, 3)

        self.setLayout(hbox)

        self.feed_list.itemActivated.connect(self.handle_feed)
        self.article_list.itemActivated.connect(self.handle_article)

        self.feed_object_dict = {}

        self.init_select_line = False

        self.fetch_feeds()
Пример #4
0
class RSSReaderWidget(QWidget):

    def __init__(self, config_dir):
        super(RSSReaderWidget, self).__init__()

        self.feed_file_path = os.path.join(config_dir, "rss-reader", "feeds.json")

        self.feed_area = QWidget()
        self.feed_list = QListWidget()
        self.feed_list.setStyleSheet( """QListView {background: #4D5250; show-decoration-selected: 1; selection-background-color: #464646;}""")
        panel_layout = QVBoxLayout()
        panel_layout.setSpacing(0)
        panel_layout.setContentsMargins(0, 0, 0, 0)
        panel_layout.addWidget(self.feed_list)
        self.feed_area.setLayout(panel_layout)

        self.article_area = QWidget()
        self.article_list = QListWidget()
        self.article_list.setStyleSheet( """QListView {background: #FFF; show-decoration-selected: 1; selection-background-color: #EEE;}""")
        self.article_list.verticalScrollBar().setStyleSheet("QScrollBar {width:0px;}");
        article_layout = QVBoxLayout()
        article_layout.setSpacing(0)
        article_layout.setContentsMargins(0, 0, 0, 0)

        self.browser = BrowserView(config_dir)

        article_layout.addWidget(self.article_list)
        article_layout.addWidget(self.browser)

        article_layout.setStretchFactor(self.article_list, 1)
        article_layout.setStretchFactor(self.browser, 3)

        self.article_area.setLayout(article_layout)

        self.welcome_page = QWidget()
        self.welcome_page_box = QVBoxLayout()
        self.welcome_page_box.setSpacing(10)
        self.welcome_page_box.setContentsMargins(0, 0, 0, 0)

        welcome_title_label = QLabel("Welcome to EAF RSS Reader!")
        welcome_title_label.setFont(QFont('Arial', 24))
        welcome_title_label.setStyleSheet("QLabel {color: #333; font-weight: bold; margin: 20px;}")
        welcome_title_label.setAlignment(Qt.AlignHCenter)

        add_subscription_label = QLabel("Press 'a' to subscribe to a feed!")
        add_subscription_label.setFont(QFont('Arial', 20))
        add_subscription_label.setStyleSheet("QLabel {color: #grey;}")
        add_subscription_label.setAlignment(Qt.AlignHCenter)

        self.welcome_page_box.addStretch(1)
        self.welcome_page_box.addWidget(welcome_title_label)
        self.welcome_page_box.addWidget(add_subscription_label)
        self.welcome_page_box.addStretch(1)

        self.welcome_page.setLayout(self.welcome_page_box)

        self.right_area = QStackedWidget()
        self.right_area.addWidget(self.welcome_page)
        self.right_area.addWidget(self.article_area)

        if self.has_feed():
            self.right_area.setCurrentIndex(1)
        else:
            self.right_area.setCurrentIndex(0)

        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.setContentsMargins(0, 0, 0, 0)

        hbox.addWidget(self.feed_area)
        hbox.addWidget(self.right_area)

        hbox.setStretchFactor(self.feed_area, 1)
        hbox.setStretchFactor(self.right_area, 3)

        self.setLayout(hbox)

        self.feed_list.itemActivated.connect(self.handle_feed)
        self.article_list.itemActivated.connect(self.handle_article)

        self.feed_object_dict = {}

        self.init_select_line = False

        self.fetch_feeds()

    def has_feed(self):
        if os.path.exists(self.feed_file_path):
            try:
                with open(self.feed_file_path, "r") as feed_file:
                    feed_dict = json.loads(feed_file.read())
                    return len(feed_dict.keys()) > 0
            except Exception:
                return False

        return False

    def fetch_feeds(self):
        if os.path.exists(self.feed_file_path):
            try:
                with open(self.feed_file_path, "r") as feed_file:
                    feed_dict = json.loads(feed_file.read())
                    for index, feed_link in enumerate(feed_dict):
                        self.fetch_feed(feed_link, index == 0)
            except Exception:
                pass

    def handle_feed(self, feed_item):
        if feed_item.feed_link in self.feed_object_dict:
            self.init_article_area(self.feed_object_dict[feed_item.feed_link])

    def handle_article(self, article_item):
        article_item.mark_as_read()

        self.browser.setUrl(QUrl(article_item.post_link))

    def fetch_feed(self, feed_link, refresh_ui):
        fetchThread = FetchRSSThread(feed_link)
        fetchThread.fetch_rss.connect(lambda f_object, f_link, f_title: self.handle_rss(f_object, f_link, f_title, refresh_ui))
        fetchThread.invalid_rss.connect(self.handle_invalid_rss)

        object_name = "feed_thread_" + feed_link
        setattr(self, object_name, fetchThread)
        getattr(self, object_name).start()

    def add_subscription(self, feed_link):
        if not self.feed_exists(feed_link):
            self.fetch_feed(feed_link, True)
        else:
            self.buffer.message_to_emacs.emit("Feed already exists: " + feed_link)

    def delete_subscription(self):
        feed_count = self.feed_list.count()
        current_row = self.feed_list.currentRow()
        feed_link = self.feed_list.currentItem().feed_link
        feed_title = self.feed_list.currentItem().feed_title

        self.feed_list.takeItem(current_row)

        with open(self.feed_file_path, "r") as feed_file:
            feed_dict = json.loads(feed_file.read())
            if feed_link in feed_dict:
                del feed_dict[feed_link]

                with open(self.feed_file_path, "w") as f:
                    f.write(json.dumps(feed_dict))

        if feed_count <= 1:
            self.feed_list.clear()
            self.article_list.clear()
            self.browser.setUrl(QUrl(""))
            self.right_area.setCurrentIndex(0)
        else:
            if current_row < feed_count - 1:
                self.feed_list.setCurrentRow(current_row)
            else:
                self.feed_list.setCurrentRow(feed_count - 2)
            self.handle_feed(self.feed_list.currentItem())
            self.buffer.message_to_emacs.emit("Removed feed: " + feed_title)

    def feed_exists(self, feed_link):
        if not os.path.exists(self.feed_file_path):
            return False

        try:
            with open(self.feed_file_path, "r") as feed_file:
                feed_dict = json.loads(feed_file.read())
                return feed_link in feed_dict
        except Exception:
            import traceback
            traceback.print_exc()

            return False

    def save_feed(self, feed_object, feed_link, feed_title):
        touch(self.feed_file_path)

        article_ids = list(map(lambda post: post.id if hasattr(post, 'id')  else post.link, feed_object.entries))

        try:
            with open(self.feed_file_path, "r") as feed_file:
                feed_dict = json.loads(feed_file.read())
                if feed_link not in feed_dict:
                    feed_dict[feed_link] = {
                        "title": feed_title,
                        "unread_articles": article_ids
                    }

                    self.save_feed_dict(feed_dict)
                    self.buffer.message_to_emacs.emit("Add feed: " + feed_link)
        except Exception:
            import traceback
            traceback.print_exc()

            self.save_feed_dict({feed_link : {
                "title": feed_title,
                "unread_articles": article_ids
            }})
            self.buffer.message_to_emacs.emit("Add feed: " + feed_link)

    def save_feed_dict(self, feed_dict):
        with open(self.feed_file_path, "w") as f:
            f.write(json.dumps(feed_dict))

    def handle_rss(self, feed_object, feed_link, feed_title, refresh_ui):
        feed_object.feed_link = feed_link
        self.feed_object_dict[feed_link] = feed_object

        self.save_feed(feed_object, feed_link, feed_title)

        self.right_area.setCurrentIndex(1)

        feed_item = QListWidgetItem(self.feed_list)
        feed_item.feed_link = feed_link
        feed_item.feed_title = feed_title
        feed_item_widget = RSSFeedItem(feed_object, len(feed_object.entries))
        feed_item.update_article_num = feed_item_widget.update_article_num
        feed_item.setSizeHint(feed_item_widget.sizeHint())
        self.feed_list.addItem(feed_item)
        self.feed_list.setItemWidget(feed_item, feed_item_widget)

        unread_articles = []
        with open(self.feed_file_path, "r") as feed_file:
            feed_dict = json.loads(feed_file.read())
            if feed_object.feed_link in feed_dict:
                if "unread_articles" in feed_dict[feed_object.feed_link]:
                    unread_articles = ["unread_articles"]

                for index in range(self.feed_list.count()):
                    feed_item = self.feed_list.item(index)
                    if feed_item.feed_link == feed_object.feed_link:
                        feed_item.update_article_num(len(unread_articles))
                        break

        if refresh_ui:
            self.init_article_area(feed_object)

    def init_article_area(self, feed_object):
        self.browser.setUrl(QUrl(feed_object.entries[0].link))

        self.article_list.clear()

        unread_articles = []
        with open(self.feed_file_path, "r") as feed_file:
            feed_dict = json.loads(feed_file.read())
            if feed_object.feed_link in feed_dict and "unread_articles" in feed_dict[feed_object.feed_link]:
                unread_articles = feed_dict[feed_object.feed_link]["unread_articles"]

        for index, post in enumerate(feed_object.entries):
            item_widget = RSSArticleItemWidget(feed_object, post, unread_articles)
            item = QListWidgetItem(self.article_list)
            item.mark_as_read = item_widget.mark_as_read
            item.post_link = item_widget.post_link
            item.setSizeHint(item_widget.sizeHint())
            item_widget.mark_article_read.connect(self.mark_article_read)
            self.article_list.addItem(item)
            self.article_list.setItemWidget(item, item_widget)

            if index == 0:
                item.mark_as_read()

        self.article_list.setCurrentRow(0)

        if not self.init_select_line:
            self.init_select_line = True
            self.feed_list.setCurrentRow(0)

    def handle_invalid_rss(self, feed_link):
        self.buffer.message_to_emacs.emit("Invalid feed link: " + feed_link)

    def mark_article_read(self, feed_link, post_link):
        if os.path.exists(self.feed_file_path):
            try:
                with open(self.feed_file_path, "r") as feed_file:
                    feed_dict = json.loads(feed_file.read())
                    if feed_link in feed_dict:
                        unread_articles = feed_dict[feed_link]["unread_articles"]

                        if post_link in unread_articles:
                            unread_articles.remove(post_link)
                            feed_dict[feed_link]["unread_articles"] = unread_articles

                            with open(self.feed_file_path, "w") as f:
                                f.write(json.dumps(feed_dict))

                        for index in range(self.feed_list.count()):
                            feed_item = self.feed_list.item(index)
                            if feed_item.feed_link == feed_link:
                                feed_item.update_article_num(len(unread_articles))
                                break
            except Exception:
                pass

    def next_subscription(self):
        feed_count = self.feed_list.count()
        current_row = self.feed_list.currentRow()

        if current_row < feed_count - 1:
            self.feed_list.setCurrentRow(current_row + 1)
            self.feed_list.scrollToItem(self.feed_list.currentItem())
            self.handle_feed(self.feed_list.currentItem())
        else:
            self.buffer.message_to_emacs.emit("End of subscribed feeds")

    def prev_subscription(self):
        current_row = self.feed_list.currentRow()

        if current_row > 0:
            self.feed_list.setCurrentRow(current_row - 1)
            self.feed_list.scrollToItem(self.feed_list.currentItem())
            self.handle_feed(self.feed_list.currentItem())
        else:
            self.buffer.message_to_emacs.emit("Beginning of subscribed feeds")

    def first_subscription(self):
        self.feed_list.setCurrentRow(0)
        self.feed_list.scrollToItem(self.feed_list.currentItem())
        self.handle_feed(self.feed_list.currentItem())

    def last_subscription(self):
        feed_count = self.feed_list.count()

        self.feed_list.setCurrentRow(feed_count - 1)
        self.feed_list.scrollToItem(self.feed_list.currentItem())
        self.handle_feed(self.feed_list.currentItem())

    def next_article(self):
        article_count = self.article_list.count()
        current_row = self.article_list.currentRow()

        if current_row < article_count - 1:
            self.article_list.setCurrentRow(current_row + 1)
            self.article_list.scrollToItem(self.article_list.currentItem())
            self.handle_article(self.article_list.currentItem())
        else:
            self.buffer.message_to_emacs.emit("End of articles")

    def prev_article(self):
        current_row = self.article_list.currentRow()

        if current_row > 0:
            self.article_list.setCurrentRow(current_row - 1)
            self.article_list.scrollToItem(self.article_list.currentItem())
            self.handle_article(self.article_list.currentItem())
        else:
            self.buffer.message_to_emacs.emit("Beginning of articles")

    def first_article(self):
        self.article_list.setCurrentRow(0)
        self.article_list.scrollToItem(self.article_list.currentItem())
        self.handle_article(self.article_list.currentItem())

    def last_article(self):
        article_count = self.article_list.count()

        self.article_list.setCurrentRow(article_count - 1)
        self.article_list.scrollToItem(self.article_list.currentItem())
        self.handle_article(self.article_list.currentItem())
    def __init__(self):
        super(RSSReaderWidget, self).__init__()

        self.feed_file_path = os.path.expanduser(
            "~/.emacs.d/eaf/rss-reader/feeds.json")

        self.feed_area = QWidget()
        self.feed_list = QListWidget()
        self.feed_list.setStyleSheet("""QListWidget{background: #4D5250;}""")
        panel_layout = QVBoxLayout()
        panel_layout.setSpacing(0)
        panel_layout.setContentsMargins(0, 0, 0, 0)
        panel_layout.addWidget(self.feed_list)
        self.feed_area.setLayout(panel_layout)

        self.article_area = QWidget()
        self.article_list = QListWidget()
        self.article_list.verticalScrollBar().setStyleSheet(
            "QScrollBar {width:0px;}")
        article_layout = QVBoxLayout()
        article_layout.setSpacing(0)
        article_layout.setContentsMargins(0, 0, 0, 0)

        self.browser = BrowserView()

        article_layout.addWidget(self.article_list)
        article_layout.addWidget(self.browser)

        article_layout.setStretchFactor(self.article_list, 1)
        article_layout.setStretchFactor(self.browser, 3)

        self.article_area.setLayout(article_layout)

        self.welcome_page = QWidget()
        self.welcome_page_box = QVBoxLayout()
        self.welcome_page_box.setSpacing(10)
        self.welcome_page_box.setContentsMargins(0, 0, 0, 0)

        welcome_title_label = QLabel("Welcome to EAF RSS Reader!")
        welcome_title_label.setFont(QFont('Arial', 24))
        welcome_title_label.setStyleSheet(
            "QLabel {color: black; font-weight: bold; margin: 20px;}")
        welcome_title_label.setAlignment(Qt.AlignHCenter)

        add_subscription_label = QLabel("Press key 'a' to add subscription")
        add_subscription_label.setFont(QFont('Arial', 20))
        add_subscription_label.setStyleSheet("QLabel {color: #333;}")
        add_subscription_label.setAlignment(Qt.AlignHCenter)

        self.welcome_page_box.addStretch(1)
        self.welcome_page_box.addWidget(welcome_title_label)
        self.welcome_page_box.addWidget(add_subscription_label)
        self.welcome_page_box.addStretch(1)

        self.welcome_page.setLayout(self.welcome_page_box)

        self.right_area = QStackedWidget()
        self.right_area.addWidget(self.welcome_page)
        self.right_area.addWidget(self.article_area)

        self.right_area.setCurrentIndex(0)

        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.setContentsMargins(0, 0, 0, 0)

        hbox.addWidget(self.feed_area)
        hbox.addWidget(self.right_area)

        hbox.setStretchFactor(self.feed_area, 1)
        hbox.setStretchFactor(self.right_area, 3)

        self.setLayout(hbox)

        self.feed_list.itemActivated.connect(self.handle_feed)
        self.article_list.itemActivated.connect(self.handle_article)

        self.feed_object_dict = {}

        self.fetch_feeds()
class RSSReaderWidget(QWidget):
    def __init__(self):
        super(RSSReaderWidget, self).__init__()

        self.feed_file_path = os.path.expanduser(
            "~/.emacs.d/eaf/rss-reader/feeds.json")

        self.feed_area = QWidget()
        self.feed_list = QListWidget()
        self.feed_list.setStyleSheet("""QListWidget{background: #4D5250;}""")
        panel_layout = QVBoxLayout()
        panel_layout.setSpacing(0)
        panel_layout.setContentsMargins(0, 0, 0, 0)
        panel_layout.addWidget(self.feed_list)
        self.feed_area.setLayout(panel_layout)

        self.article_area = QWidget()
        self.article_list = QListWidget()
        self.article_list.verticalScrollBar().setStyleSheet(
            "QScrollBar {width:0px;}")
        article_layout = QVBoxLayout()
        article_layout.setSpacing(0)
        article_layout.setContentsMargins(0, 0, 0, 0)

        self.browser = BrowserView()

        article_layout.addWidget(self.article_list)
        article_layout.addWidget(self.browser)

        article_layout.setStretchFactor(self.article_list, 1)
        article_layout.setStretchFactor(self.browser, 3)

        self.article_area.setLayout(article_layout)

        self.welcome_page = QWidget()
        self.welcome_page_box = QVBoxLayout()
        self.welcome_page_box.setSpacing(10)
        self.welcome_page_box.setContentsMargins(0, 0, 0, 0)

        welcome_title_label = QLabel("Welcome to EAF RSS Reader!")
        welcome_title_label.setFont(QFont('Arial', 24))
        welcome_title_label.setStyleSheet(
            "QLabel {color: black; font-weight: bold; margin: 20px;}")
        welcome_title_label.setAlignment(Qt.AlignHCenter)

        add_subscription_label = QLabel("Press key 'a' to add subscription")
        add_subscription_label.setFont(QFont('Arial', 20))
        add_subscription_label.setStyleSheet("QLabel {color: #333;}")
        add_subscription_label.setAlignment(Qt.AlignHCenter)

        self.welcome_page_box.addStretch(1)
        self.welcome_page_box.addWidget(welcome_title_label)
        self.welcome_page_box.addWidget(add_subscription_label)
        self.welcome_page_box.addStretch(1)

        self.welcome_page.setLayout(self.welcome_page_box)

        self.right_area = QStackedWidget()
        self.right_area.addWidget(self.welcome_page)
        self.right_area.addWidget(self.article_area)

        self.right_area.setCurrentIndex(0)

        hbox = QHBoxLayout()
        hbox.setSpacing(0)
        hbox.setContentsMargins(0, 0, 0, 0)

        hbox.addWidget(self.feed_area)
        hbox.addWidget(self.right_area)

        hbox.setStretchFactor(self.feed_area, 1)
        hbox.setStretchFactor(self.right_area, 3)

        self.setLayout(hbox)

        self.feed_list.itemActivated.connect(self.handle_feed)
        self.article_list.itemActivated.connect(self.handle_article)

        self.feed_object_dict = {}

        self.fetch_feeds()

    def fetch_feeds(self):
        if os.path.exists(self.feed_file_path):
            try:
                with open(self.feed_file_path, "r") as feed_file:
                    feed_dict = json.loads(feed_file.read())
                    for index, feed_link in enumerate(feed_dict):
                        self.fetch_feed(feed_link, index == 0)
            except Exception:
                pass

    def handle_feed(self, feed_item):
        if feed_item.feed_link in self.feed_object_dict:
            self.update_article_area(
                self.feed_object_dict[feed_item.feed_link])

    def handle_article(self, article_item):
        self.browser.setUrl(QUrl(article_item.post_link))

    def fetch_feed(self, feed_link, refresh_ui):
        fetchThread = FetchRSSThread(feed_link)
        fetchThread.fetch_rss.connect(
            lambda f_object, f_link, f_title: self.handle_rss(
                f_object, f_link, f_title, refresh_ui))
        fetchThread.invalid_rss.connect(self.handle_invalid_rss)

        object_name = "feed_thread_" + feed_link
        setattr(self, object_name, fetchThread)
        getattr(self, object_name).start()

    def add_subscription(self, feed_link):
        if not self.feed_is_exits(feed_link):
            self.fetch_feed(feed_link, True)
        else:
            self.message_to_emacs.emit("Feed has exists: " + feed_link)

    def feed_is_exits(self, feed_link):
        if not os.path.exists(self.feed_file_path):
            return False

        try:
            with open(self.feed_file_path, "r") as feed_file:
                feed_dict = json.loads(feed_file.read())
                return feed_link in feed_dict
        except Exception:
            import traceback
            traceback.print_exc()

            return False

    def save_feed(self, feed_link, feed_title):
        if not os.path.exists(self.feed_file_path):
            basedir = os.path.dirname(self.feed_file_path)
            if not os.path.exists(basedir):
                os.makedirs(basedir)

            with open(self.feed_file_path, "a"):
                os.utime(self.feed_file_path, None)

        try:
            with open(self.feed_file_path, "r") as feed_file:
                feed_dict = json.loads(feed_file.read())
                if feed_link not in feed_dict:
                    feed_dict[feed_link] = {"title": feed_title}

                    with open(self.feed_file_path, "w") as f:
                        f.write(json.dumps(feed_dict))

                    self.message_to_emacs.emit("Add feed: " + feed_link)
        except Exception:
            import traceback
            traceback.print_exc()

            with open(self.feed_file_path, "w") as f:
                f.write(json.dumps({feed_link: {"title": feed_title}}))

            self.message_to_emacs.emit("Add feed: " + feed_link)

    def handle_rss(self, feed_object, feed_link, feed_title, refresh_ui):
        self.feed_object_dict[feed_link] = feed_object

        self.save_feed(feed_link, feed_title)

        self.right_area.setCurrentIndex(1)

        feed_item = QListWidgetItem(self.feed_list)
        feed_item.feed_link = feed_link
        feed_item_widget = RSSFeedItem(feed_object, len(feed_object.entries))
        feed_item.setSizeHint(feed_item_widget.sizeHint())
        self.feed_list.addItem(feed_item)
        self.feed_list.setItemWidget(feed_item, feed_item_widget)

        if refresh_ui:
            self.update_article_area(feed_object)

    def update_article_area(self, feed_object):
        self.browser.setUrl(QUrl(feed_object.entries[0].link))

        self.article_list.clear()
        for post in feed_object.entries:
            item_widget = RSSArticleItem(post)
            item = QListWidgetItem(self.article_list)
            item.post_link = item_widget.post_link
            item.setSizeHint(item_widget.sizeHint())
            self.article_list.addItem(item)
            self.article_list.setItemWidget(item, item_widget)

    def handle_invalid_rss(self, feed_link):
        self.message_to_emacs.emit("Invalid feed link: " + feed_link)
    def __init__(self, buffer_id, url, fit_to_view, background_color):
        Buffer.__init__(self, buffer_id, url, fit_to_view, background_color)

        self.add_widget(BrowserView())