chrome拡張で自分だけのリンク集を作成してみた

注意:この投稿はGWが暇だったため、なんとなく作ってみたものです。 ほとんど調べたりしていません。 ウンコードな部分も多いと思いますが、せっかく作ったのでブログに投稿しようと思っただけです。


f:id:okumuraa1:20180501151709p:plain

chrome拡張の右上の小窓で、こんな感じのリンク集とリンク先の最終更新日が開いてくれたら、すごく自分には便利だったため、作りました。


作成方法

$ git clone git@github.com:okumurakengo/reactvuelink.git
$ cd reactvuelink

chrome://extensions/

f:id:okumuraa1:20180501152201p:plain

パッケージ化されていない拡張機能を読み込む

cloneしてきたフォルダを指定

chromeの右上にアイコンができる

最終更新日をパソコン起動時にスクレイピングで取得

$ npm i
  • macからscraping.jsを自動実行する

f:id:okumuraa1:20180501153459p:plain

Automatorを起動し、「アプリケーション」を選択

f:id:okumuraa1:20180501153712p:plain

シェルスクリプトを実行」をダブルクリックすると、シェルを書くエディターが出てくる

以下のように設定し、保存する。

cd /Users/<cloneしたディレクトリ>/reactvuelink
/Users/<nodeをインストールしたディレクトリ>/node scraping.js

「システム環境設定」>「ユーザーとグループ」 「ログイン項目」を選び、今保存したシェルを実行するだけのアプリを登録しておく f:id:okumuraa1:20180501154525p:plain

パソコンを再起動するか、Automatorで作成したアプリをダブルクリックするたびに、 リンク先の最終更新日時を取得したlink_update.jsonができる。

link_update.jsonをpopup.htmlで読み込んでリンク集に最終更新日、最新投稿タイトルをつけてくれる f:id:okumuraa1:20180501155936p:plain


  • 工夫してみた点

たくさんリンクがあったほうが自分も便利なので、リンク先を増やしたい時にやりやすくは考えてみた

  1. link.jsonの中にリンク先を増やす
[
    {
        "no":101,
        "type":"vue",
        "name":"Vue.js News",
        "url":"https://news.vuejs.org/",
        "rss":"https://vuenews.fireside.fm/rss"
    },
    {
        "no":102,
        "type":"react",
        "name":"reactjs.org",
        "url":"https://reactjs.org/blog/"
    },
+  {
+    "no":103,
+    "type":"react",
+    "name":"Hatena::Bookmark react",
+    "url":"http://b.hatena.ne.jp/search/text?safe=on&q=react&users=3"
+  }
]
  1. scraping.jsで取得したいタグを指定
const fs = require('fs')
     ,client = require('cheerio-httpcli');
let   link_update = JSON.parse(fs.readFileSync('./link.json','utf8'))
     ,link_option = []
     ,url,title,date;

Promise.resolve().then(()=>{
    return new Promise((resolve, reject)=>{
        (function loop(i=0){
            // rssがある場合はrssを取得
            url=link_update[i].rss ? link_update[i].rss : link_update[i].url;

            client.fetch(url,{},(err,$,res)=>{
                if(err) { console.log(err); return; }

                switch(link_update[i].no){
                    case 102:
                        // reactjs.org
                        title = $('h1').text().trim();
                        date = $('h1').parent().next().text().replace(/by.*$/,'');
                        break;
+                  case 103:
+                      // Hatena::Bookmark
+                      title = $('.search-result:nth-of-type(1) h3').text().trim();
+                      date = $('.search-result:nth-of-type(1) .created').text();
+                      naiyou = $('.search-result:nth-of-type(1) blockquote').text();
+                      break;
                    default:
                        // rss
                        title = $('item:nth-of-type(1)').find('title').text();
                        date = $('item:nth-of-type(1)').find('pubDate').text();
                        break;
                }

                link_option.push({title,date});

                if(link_update[i+1]){
                    loop(i+1);
                    return;
                }
                resolve();
            });
        })();
    });
}).then(()=>{
    link_update = link_update.map((obj,index)=>{
        obj.title=link_option[index].title;
        obj.date=link_option[index].date;
        return obj;
    });
    
    fs.writeFile('./link_update.json',JSON.stringify(link_update,undefined,1),err=>{
        if (err) { console.log(err); return; }
    });
});

f:id:okumuraa1:20180501162529p:plain

f:id:okumuraa1:20180501162539p:plain

はてなブックマークの「react」で検索した一番上の情報が取れた!