JavaScript
chrome-extension
Vue.js
ElementUI

(続)閲覧した動画の履歴をサムネ付きで表示できるChrome拡張機能を作った

以前投稿したchrome拡張機能が更に使いやすくなった上に、chromeウェブストアからダウンロードできるようになりました。

【前回】

閲覧した動画の履歴(昨夜のおかず)をサムネ付きで表示できるChrome拡張機能を作った

https://qiita.com/gogogonkun/items/c34971ce743c54c5a240

2019/02/16

1日経過した閲覧履歴が表示されないバグを修正しました。


はじめに

こんな人向けの記事


  • 便利なChrome拡張機能を探している人

  • 昨夜見た動画を見直したくなる人

  • 男性


作ったもの

特定サイトで閲覧した動画の履歴をサムネイル付きで表示できます。昨晩の動画を改めて振り返ることができます。

スクリーンショット 2018-12-31 5.41.16.jpg

↑拡張機能のアイコンをクリックすると、右側のタブに閲覧履歴が表示されます。


経緯

昨日漁っていた動画をまた見たい!!

でもどのページで何を見ていたのかなんて覚えていないですよね。

大体の方は、終わったあとにはさっと動画を閉じるのではないでしょうか。

ブラウザの履歴から辿ろうものなら、何が何だか全く分かりません。

スクリーンショット 2018-12-25 0.19.39.jpg

たとえ気に入った動画だったとしても、忘れ去ってしまうという悲しい経験がある人は多いと思います。

そんな悲しい経験をする人を世の中から減らしたいという思いで生まれました。


導入方法

chromeウェブストアから直接追加できます。

以下のURLからchromeウェブストアに飛び、chrome拡張機能として追加するだけです。

Movie Brows History Viewer

https://chrome.google.com/webstore/detail/movie-brows-history-viewe/gbidhnbjoleffagedagblicnjlknibpd/related?hl=ja

スクリーンショット 2018-12-31 7.09.22.jpg

※「Chromeから削除します」と表示されておりますが、本来であればここから追加できます。


使い方

動画を見た後に、本拡張機能のアイコンをクリックするだけです。

スクリーンショット 2018-12-31 5.41.16.jpg

動画をクリックすると、該当ページに飛ぶこともできます。


対応サイト


実装

ここからは真面目な話です。

前回までと比べて、色々なサイトへ対応しやすくなりました。


開発環境


  • Google Chrome Ver 70.0

  • Vue.js v2.5.20

  • Element UI


ソースコード


GitHub

https://github.com/gonkunkun/MovieBrowsHistoryViewer

イケてない実装、物足りない機能がある等、改善する点はたくさんあると思うので、色々意見をいただければ幸いです・・・

まずはChrome拡張機能として確実に必要となるマニュフェストファイルです。


manifest.json

{

"manifest_version": 2,
"name": "Movie Brows History Viewer",
"version": "1.0.0.4",
"description": "動画の閲覧履歴をサムネイル付きで確認できるプラグイン",
"browser_action": {
"default_icon": "icons/AH.png",
"default_title": "History Viewer",
"default_popup": "popup.html"
},

"permissions": [
"history",
"*://*.pornhub.com/*",
"*://*.xvideos.com/*",
"*://*.avgle.com/*"
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}


htmlではdisplayItemsに格納したリストを表示しています。


popup.html

<!DOCTYPE html>

<html>
<head>
<meta charset='utf-8'>

<script src="./js/vue.js"></script>
<link rel="stylesheet" href="./css/element-ui/index.css">
<link rel="stylesheet" href="./css/index.css">
<script src="./js/element-ui/index.js"></script>
<script src="./js/element-ui/umd/locale/ja.js"></script>
<script src="./js/axios.min.js"></script>
<script src="./js/lodash.js"></script>
<title>History Viewer</title>
</head>
<body>
<div id="app">
<p><span>My Browsing History</span></p>
<el-row>
<el-col :span="35" v-for="item in displayItems" :key="item.id" >
<el-card :body-style="{ padding: '0px' }">
<a :href='item.url' target='_blank'><img :src='item.imgUrl' class="image" width=224 height=126></a>
<div class="bottom-content" style="padding: 10px;">
<a :href='item.url' target='_blank'><span class="title">{{ item.title }}</span></a>
<div class="bottom clearfix">
<time class="time">Last:{{ item.lastVisitDateTime }}</time>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<script src="./js/vueData.js"></script>
</body>
</html>


htmlで表示する閲覧履歴リストを作成しています。


vueData.js

ELEMENT.locale(ELEMENT.lang.ja)

let app = new Vue({
el: '#app',
data: {
// サイト毎のデータを保持するリスト
items: {},
// htmlに表示するためのリスト
displayItems: [],
maxResults: 20,
// 動画情報を取得するサイト名と正規表現定義リスト
urlMachingList: [
{
// サイト名
name: 'pornhub',
// chrome履歴から取得するURL名
site: 'pornhub*view_video.php?viewkey',
// 取得する画像のURLパターン
str: /\<meta property=\"og\:image\" content=\"http(s)?:\/\/.*jpg/,
delStr: "<meta property=\"og:image\" content=\"",
// 表示する履歴のURLパターン
matchUrl: /.*/
},
{
name: 'xvideos',
site: 'xvideos*/video',
str: /html5player.setThumbUrl169\(\'.*jpg/,
delStr: "html5player.setThumbUrl169\(\'",
matchUrl: /.*/
},
{
name: 'avgle',
site: 'avgle.com*/video/',
str: /content=\"http(s)?:\/\/.*jpg/,
delStr: "content=\"",
matchUrl: /.*avgle.com\/video\/.*/
}
]
},
watch: {
items: function (val, oldVal) {
this.displayItems = [];
for (let i in val) {
for (let j in val[i]) {
this.displayItems.push(val[i][j]);
}
}
this.displayItems = _.orderBy(this.displayItems, "lastVisitTime", "desc");
}
},
methods: {
unixTime2ymd: function(intTime) {
var d = new Date( intTime );
var year = d.getFullYear();
var d = new Date( intTime );
var y = new Date( intTime * 1000 );
var year = y.getFullYear();
var month = d.getMonth() + 1;
var day = d.getDate();
var hour = ( '0' + d.getHours() ).slice(-2);
var min = ( '0' + d.getMinutes() ).slice(-2);
var sec = ( '0' + d.getSeconds() ).slice(-2);

return( month + '/' + day + ' ' + hour + ':' + min + ':' + sec );
},
updateChromeHistory: function () {
document.addEventListener('DOMContentLoaded', () => {
// 定義されているサイト分ループ
for (let list of this.urlMachingList) {
let name = list.name
let delStr = list.delStr;
let str = list.str;
let site = list.site;
let matchUrl = list.matchUrl;
let query = {
text: site,
maxResults: this.maxResults
};
chrome.history.search(query, (results) => {
let res = [];
// サイトの検索結果に関する履歴を排除
for (let i of results) {
if (i.url.match(matchUrl) != null ){
res.push(i);
}
}
Vue.set(this.items, name, res);
this.updateImgUrl(this.items[name], delStr, str);
});
}
});
},
updateImgUrl: function (items, delStr, str) {
for (let i of items) {
axios
.get(i.url)
.then(function(response) {
let url = response.data.match(str);
url[0] = url[0].replace(delStr,"");
Vue.set(i, "imgUrl", url[0]);
Vue.set(i, "lastVisitDateTime", this.unixTime2ymd(i.lastVisitTime));
}.bind(this)).catch(function(e) {
// console.error(e)
})
}
}
},
created: function() {
this.updateChromeHistory();
},
mounted: function() {
}
});


ここでは対応するサイトの設定をしています。

        urlMachingList: [

{
// サイト名
name: 'pornhub',
// chrome履歴から取得するURL名
site: 'pornhub*view_video.php?viewkey',
// 取得する画像のURLパターン
str: /\<meta property=\"og\:image\" content=\"http(s)?:\/\/.*jpg/,
delStr: "<meta property=\"og:image\" content=\"",
// 表示する履歴のURLパターン
matchUrl: /.*/
},
{
name: 'xvideos',
site: 'xvideos*/video',
str: /html5player.setThumbUrl169\(\'.*jpg/,
delStr: "html5player.setThumbUrl169\(\'",
matchUrl: /.*/
},
{
name: 'avgle',
site: 'avgle.com*/video/',
str: /content=\"http(s)?:\/\/.*jpg/,
delStr: "content=\"",
matchUrl: /.*avgle.com\/video\/.*/
}
]

キー
概要

name
サイト名(オブジェクトのキーとなります)

site
履歴を取得するサイトのURL

str
サムネイルを表示するために、サイト内で使われている画像リンクのURLパターンを格納

delStr
URLパターンのうち、http://***.jpgとなるように、無駄な文字列を削除するために使います

matchUrl
履歴として表示するURLパターンを選択します(検索結果画面を除去するために使用)

ここでは画面表示用のリストを作成しています。

履歴を取得してitemsに要素が追加されるたびに発火します。

    watch: {

items: function (val, oldVal) {
this.displayItems = [];
for (let i in val) {
for (let j in val[i]) {
this.displayItems.push(val[i][j]);
}
}
this.displayItems = _.orderBy(this.displayItems, "lastVisitTime", "desc");
}
},

chrome.history.search関数でchromeから履歴を取得しています。

                    chrome.history.search(query, (results) => {

let res = [];
// サイトの検索結果に関する履歴を排除
for (let i of results) {
if (i.url.match(matchUrl) != null ){
res.push(i);
}
}
Vue.set(this.items, name, res);
this.updateImgUrl(this.items[name], delStr, str);
});

サムネイル画像を取得する処理をしています。

JavaScriptでhtmlファイルを取得して、正規表現で抜いてきてるだけです。

もっと良い実装がありそう・・・

        updateImgUrl: function (items, delStr, str) {

for (let i of items) {
axios
.get(i.url)
.then(function(response) {
let url = response.data.match(str);
url[0] = url[0].replace(delStr,"");
Vue.set(i, "imgUrl", url[0]);
Vue.set(i, "lastVisitDateTime", this.unixTime2ymd(i.lastVisitTime));
}.bind(this)).catch(function(e) {
// console.error(e)
})
}
}


おわりに

閲覧した動画をサムネイル付きで表示する拡張機能を作りました。

前回までと比べて、対応サイトが増えたり、chromeウェブストアからダウンロードできるようになったり、より使いやすくなっております。

これで、昨夜のおかずを忘れてしまっても困りません!!

世の中の男性がよりハッピーになります。

2018年の締めがこんな記事になろうとは・・・

こんなくだらない記事をここまで見てくださり、ありがとうございました。


参考ページ

Google Chromeに自作の拡張機能を Chrome ウェブストア に登録する方法

https://toolmania.info/post-11618/