Отделяем зерна от плевел в Google Reader


    GreasemonkeyНа работе я стараюсь не читать Хабр и другие тематические сайты, они слишком затягивают. Можно потратить весь день на чтение статей, а по работе так ничего и не сделать. Но пропускать что-то новое и интересное я тоже не хочу, поэтому подписываюсь на различные RSS-каналы. После работы, а чаще в выходные, я открываю Google Reader и просматриваю весь список накопившихся постов. Некоторые из них написаны на интересные для меня темы, остальные — нет. Это напоминает мне чтение электронной почты, только входящие письма и спам попадают в одну папку.

    Сначала я с этим мирился, но на этих выходных, с помощью Greasemonkey скрипта, исправил ситуацию.


    Google Reader Screenshot

    В Google Reader появилась новая кнопка: «Mark selected as read», а у каждой статьи - checkbox.

    Теперь, просматривая список постов, я сразу же отмечаю неинтересные для меня и «прочитываю» их одной кнопкой. Остаются только те, что заслуживают дальнейшего внимательного изучения.

    Если вам понравилась идея, можете установить Greasemonkey скрипт. Для его работы требуется Mozilla Firefox и расширение Greasemonkey.

    Из недостатков стоить отметить невозможность работы скрипта в Google Chrome. Причиной этому служит ошибка браузера в обработке созданных KeyboardEvent.

    На всякий случай публикую исходный код скрипта:
    // ==UserScript==
    // @name     Google Reader - Mark selected items as read
    // @namespace   twitter.com/rodiontsev
    // @description  This script adds a button "Mark selected as read" and checkbox for each item.
    // @include    htt*://www.google.tld/reader/view/*
    // ==/UserScript==

    /*
    Version history

    1.0 on 10/01/2009:
      - Initial version.
    */

    var buttonText = "Mark selected as read";
    var buttonId = "mark-selected-as-read";
    var articles = new Array();

    document.addEventListener("DOMNodeInserted", function(event){nodeInserted(event);}, true);

    function nodeInserted(event) {
      var entries = document.getElementById("entries");
      if (entries && matchClass(entries, "list")) {
        var button = document.getElementById(buttonId);
        if (!button) {
          articles = new Array();
          appendButton();
        }
        
        var element = event.target;
        if (element. className && element.className.match(/entry\s+entry-\d+/) != null) {
          articles.push(element);
          
          var checkbox = document.createElement("input");
          checkbox.type = "checkbox";
          checkbox.className = "mark-selected-as-read-checkbox-class";
          checkbox.style.marginRight = "9px";
          checkbox.style.verticalAlign = "top";
          checkbox.addEventListener("click", function(event) {event.stopPropagation();}, true);
          var entrySecondary = element.getElementsByClassName("entry-secondary")[0];
          entrySecondary.insertBefore(checkbox, entrySecondary.firstChild);
        }
      }
    }

    function appendButton() {
      var viewerTopControlsId = "viewer-top-controls";
      var markAllAsReadId = "mark-all-as-read-split-button";

      var divVewerTopControls = document.getElementById(viewerTopControlsId);
      var btnMarkAllAsRead = document.getElementById(markAllAsReadId);

      if ((divVewerTopControls != null) && (btnMarkAllAsRead != null)) {
        var button = document.createElement("div");
        button.className = "goog-button goog-button-base unselectable goog-inline-block goog-button-float-left goog-button-tight scour-disabled viewer-buttons";
        button.id = buttonId;
        button.innerHTML = "<div class=\"goog-button-base-outer-box goog-inline-block\">"
                 + "<div class=\"goog-button-base-inner-box goog-inline-block\">"
                 + "<div class=\"goog-button-base-pos\">"
                 + "<div class=\"goog-button-base-top-shadow\"> </div>"
                 + "<div class=\"goog-button-base-content\">"
                 + "<div class=\"goog-button-body\">" + buttonText + "</div>"
                 + "</div>"
                 + "</div>"
                 + "</div>"
                 + "</div>";
        button.addEventListener("click", markSelectedAsRead, false);
        divVewerTopControls.insertBefore(button, btnMarkAllAsRead);
      }
    }

    function matchClass (element, sClassName) {
      return (sClassName
         && element.className
         && element.className.length
         && element.className.match(new RegExp("(^|\\s+)(" + sClassName +")($|\\s+)")));
    }

    function simulateClick(node) {
      var event = node.ownerDocument.createEvent("MouseEvents");
      event.initMouseEvent("click", true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
      node.dispatchEvent(event);
    }

    function simulateKeypress(node, keyCode) {
      var event = node.ownerDocument.createEvent("KeyboardEvent");
      event.initKeyEvent("keypress", true, true, null, false, false, false, false, keyCode, 0);
      node.dispatchEvent(event);
    }

    function simulateRead(node) {
      simulateKeypress(node, 77); //"m" button - mark entry as read.
    }

    function simulateCollapse(node) {
      simulateKeypress(node, 79); //"o" button - expand/collapse entry.
    }

    function getArticleIcon(article) {
      var divs = article.getElementsByTagName("div");
      for (var i = 0; i < divs.length; i++) {
        var div = divs[i];
        if (matchClass(div, "entry-icons")) return div;
      }
      return null;
    }

    function markSelectedAsRead() {
      var container = document.getElementById("entries");
      container.style.display = "none";
      for (var i = 0; i < articles.length; i++) {
        var article = articles[i];
        var checkbox = article.getElementsByTagName("input")[0];
        if (checkbox.checked) {
          if (!(matchClass(article, "read"))) {
            var articleIcon = getArticleIcon(article);
            simulateClick(articleIcon);
            if (!(matchClass(article, "read"))) {
              simulateRead(articleIcon);
            }
            if (matchClass(article, "expanded")) {
              simulateCollapse(articleIcon);
            }
          }
          checkbox.checked = false;
        }
      }
      container.style.display = "block";
    }

    * This source code was highlighted with Source Code Highlighter.
    Ads
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More

    Comments 46

      +2
      Отличный скрипт, спасибо! Значительно упростил жизнь!
        +8
        слегка неудобный способ, если из 1500 фидов будет только 10 полезных Ваш механизv будет не удобным, я делаю наоборот качественный контент делаю «share» и «add star» остальное «mark all as read»
          0
          Мой подход более оптимистичный :)
          Думаю, наши два метода сообща будут хорошо работать: ваш — когда хороших статей мало; мой — когда хороших статей много.
            0
            в день к примеру на том же Хабре появляется порядка 100+ статей из них как раз 10-20 достойны внимания
              –1
              Согласно Трендам в гугль ридере
              Хабрахабр: 30.9 Items per day
                +2
                вы какой смотрите habrahabr.ru/new/ или те которые попадают на главную. как раз на главной может и 30+ но все посты в день 100+
                  0
                  Ну так как в статье идет речь про Гугл Ридер, то я имел ввиду на главной.
                    +2
                    Но ведь Google Reader умеет доставлять RSS не только c главной, но из каждого блога по отдельности. В том числе и из /new.
                +5
                Есть такая замечательная вещь как yahoo pipes, которая позволяет делать много чего интересного с RSS фидами — фильтровать, обрезать, совмещать несколько фидов в один.
            +1
            А будет ли версия «Mark all as read except selected»? =)
              +2
              Будет, если в скрипте заменить
              if (checkbox.checked) на if (!checkbox.checked)
                0
                117 строчка
              +8
              И нафига это надо — тратить время на отмечание галочками? Я вижу по заголовкам, что интересно и нужно — читаю сразу, а потом давлю на кнопку «пометить всё как прочтённое», и то что неинтересно, становится «прочтённым».
                0
                У меня сейчас непрочитаными лежат 803 статьи. Сразу я физически не успею их прочитать и осмыслить, поэтому мне этот подход удобен.
                  0
                  Хм. У меня около 200 подписок. Я не оставляю непрочитанными их, стараюсь что нужно сразу получать, а ненужное потом просматриваю, просто отматывая обратно.
                    0
                    Кстати, легче уж тогда звёздочками пользоваться.
                      +1
                      Я могу просмотреть пару тысяч в день.

                      Беглый взгляд на заголовок — на текст и фото — не заинтересовал? Жму j. Заинтересовал? Жму v.
                    –1
                    эм… а помоему такое есть в Google Labs.
                    по крайней мере у меня почему-то эти кнопки есть без вашего скрипта )
                      0
                      Неужели я дождался этого от google labs?! Сейчас мы их проверим
                        0
                        К сожалению, я не нашел ни чекбоксов, ни Labs в Google Reader. Подскажите, где вы их включили?
                          0
                          прошу прощения за дезинформацию — перепутал с почтой от гугла.
                          визуально тема там такая же и расположение кнопок тоже самое, поэтому видимо и показалось.
                        0
                        а я сделал проще:
                        1) сделал отображение в виде списка, собственно также как у вас на скриншоте
                        2) разворачиваю только тебе заголовки которые мне интересны, а после этого кликаю «mark all as read»

                        имхо, это менее времязатротно, чем тыкать сначала на неинтересные новости и отмечать их прочитанными, а потом тыкать на интересные и читать их.
                          0
                          Я уже объяснял wirklich, что у меня непрочитанными бывает большое количество статей, накопившихся за неделю-две, поэтому за один раз я не успеваю их все просматривать.
                          0
                          1) отмечаю интересные заголовки
                          2) mark all as read
                          3) читаю отмеченные
                            0
                            Ну тогда бы уже стоило добавить функцию «Mark all» и потом уже снимать чекбоксы у тех заголовков, которые интересны.
                            Хотя изобретать велосипед не стоит, я пользуюсь «звёздочкой» для отложенного чтения статей.
                            Вот штук пять разноцветных звёздочек, как «Суперметки» в Gmail (доступно через Labs) точно не помешало бы
                              0
                              Да, метки были бы к месту.

                              Если отмечать интересные записи звездочками, то в Starred items посты будут идти одним списком, независимо от RSS фида, в котором они находятся. Тяжело «переключаться», когда читаешь новости, то на русском, то на английском.
                              +1
                              По-моему быстрее кнопками J + M пробежаться, чем мышкой тыкать.
                              Когда они уже фильтр сделают? Никто ничего не слышал?
                                +4
                                Можно использовать Read It Later.

                                В Firefox это расширение интегрируется в Google Reader:


                                Помеченные галочкой элементы добавляются в закладки


                                При желании можно обойтись функционалом Google Reader. Именно для этого сделаны звезды:
                                  0
                                  Интересное расширение. Обязательно посмотрю.
                                    0
                                    Странно что вы его не заметили
                                  +2
                                  если накапливается больше сотни статей то сразу жму «mark all as read» ;)
                                    0
                                    Возьму на вооружение ;)
                                      0
                                      Аналогично, только привык Shift + A жать
                                      +1
                                      А почему вы Хабралентой 3.0 не пользуетесь?

                                      Не зря же её писали. Там есть и персональные рекомендации на основе ваших действий на Хабре (за какие топики голосуете, что добавляете в избранное, в каких блогах состоите), и возможность исключать неинтересные записи, и волшебная кнопочка «не рекомендовать», которая отсеивает все похожие посты.
                                        0
                                        Как-нибудь попробовать использовать ленту. Жаль только не на всех сайтах, фиды которых я читаю, есть подобная возможность.
                                        +1
                                        У меня и так первый проход по ленте (в развернутом виде) состоит из последовательности J-M-J-M-J-J (если еще буду читать) — М…

                                        А потом уже то, что заинтересовало, то перечитываю. И никаких чекбоксов не надо.
                                        • UFO just landed and posted this here
                                            +1
                                            Способ проще: google.com/reader/i/ — версия для айфона (для тугодумов: айфон ей *не* нужен), ничего лишнего, идеальный интерфейс (я искренне не понимаю, зачем они главной версией сделали яваскриптовую, уродскую, тяжелую и неудобную).

                                            Картинкой вставить не могу, кто может, покажите плиз, как выглядит :)
                                              0
                                              Мобильная версия (http://www.google.com/reader/m), кстати, по тому же принципу сделана. Очень удобно читать только интересующие статьи, отмечая все остальное, как прочитанное.
                                                0
                                                Google Reader on iPhone
                                                Версия Google Reader для iPhone.
                                                  0
                                                  О, а вот как она выглядит в айфоне, я не видел :)
                                                0
                                                Читаю с помощью J. Никуда не тороплюсь, бывает и до 400 записей остаётся, читаю, когда есть время. Да, при это сортировка включена на 'oldest', поэтому всегда первое буду читать самое старое.
                                                  0
                                                  Что такое J?
                                                    0
                                                    Клавиша J, или кнопка «next item».

                                                    Ваша идея хороша, наврное, только я читаю развёрнутым сразу, поэтому понять не смогу…

                                                  0
                                                  Фантастическое совпадение. Читал хабр через RSS и как раз думал, что галочек очень не хватает! И тут наткнулся на эту статью.
                                                    0
                                                    меня просто убивает то, что кнопка send to в гугл хром работает только один раз за сессию. в остальных же браузерах все просто айдил. т.е. например, я если хочу мигом запостить в свой блоггер, что-либо мне понравившееся, то я могу сделать это всего-лишь один раз не перезагружая гугл ридер.

                                                    Only users with full accounts can post comments. Log in, please.