# <google>googleのサービス使ってブログもどき作ってみた
な〜んとなく、作ってみたよ
見切り発車で書いてるからまとまるか微妙だよ
いつものことですね
は〜い
目次
- 使ったもの
- 書いたコード
- できたもの
- その他
1.使ったもの
今回はgoogleのサービスだけを使ってブログっぽいものをどこまで作れるかをやろうということで、googleのサービスです
- google form (入力系)
- google spreadsheet(保存系)
- google apps script(表示系)
- bootsrap 4(見た目系)
レイアウトの調整にbootstrapをちょっと使いました。
2.書いたコード
まずはgoogle formを用意します。
今回は暫定的に以下を聞きます。
- ブログタイトル(必須)
- ブログコンテンツ(必須)
- 関連リンク(任意)
で、その結果をスプレに吐き出します。
オエ〜って感じですね(違う)
そうすることでスプレに吐き出されるのは聞いたこと+タイムスタンプになります
そのデータを基にしてブログぽい表示をしていきます
HTML
index.html
表示の基になるものです。特に何も書いてません
<!DOCTYPE html> <html> <head> <base target="_top"> <?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?> </head> <body> <h1>blog</h1> <?!= getcontent(); ?> </body> </html>
さて、ここの
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
これはcssを読み出す用のやつです。 そして、
<?!= getcontent(); ?>
でコードを読みだします
css.html
google apps scriptを使うとcssもhtmlの中に書かなきゃいけません、難しいですね。
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <style> .date{ font-size:10px; font-weight:200; } .card{ margin-bottom:30px; width:400px; } </style>
特殊なことはないですね、bootsrap をCDNで引いてるくらいです
google apps script
htmlの表示
単純なhtmlの表示にもスクリプトが必要です。
function doGet() { return HtmlService.createTemplateFromFile("index").evaluate(); }
これはコピペのようなものです。
sheetの情報からブログっぽく表示する
html内から呼び出したコードです
function getcontent() { //変数spreadsheetに指定のスプレッドシートオブジェクトを取得します var url ="ここにシートのリンク"; var spreadsheet = SpreadsheetApp.openByUrl(url); //spreadsheetのシートを全て読み出す var sheets = spreadsheet.getSheets(); //結果の格納されたシートを読み出す var sheet = sheets[0]; //シートの最終行番号、最終列番号を取得 var startrow = 1; var startcol = 1; var lastrow = sheet.getLastRow(); var lastcol = sheet.getLastColumn(); //シートのデータを取得 var sheetdata = sheet.getSheetValues(startrow, startcol, lastrow, lastcol); //シートをhtmlコードに反映していく var content=""; for(var i=lastrow-1;i>=1;i--){ content+="<div class=\"card\">"; content+="<div class=\"card-header\"><p class=\"card-subtitle date\">"+sheetdata[i][0]+"</p>"; content+="<h2 class=\"card-title\">"+sheetdata[i][1]+"</h2></div>"; content+="<p>"+sheetdata[i][2]+"</p>"; //link適応 if(sheetdata[i][3]!=""){ if(sheetdata[i][3].indexOf(",")!=-1){ var links=sheetdata[i][3].split(","); for(var j=0;j<links.length;j++){ content+="<a href=\""+links[j]+"\">"+links[j]+"</a>"; } }else{ content+="<a href=\""+sheetdata[i][3]+"\">"+sheetdata[i][3]+"</a>"; } } content+="</div>" } return content }
こんな感じです
シートの回答を読みだして、新しい順に表示するようにしてます。
逆順表示にして、最新の回答から順にカード表示してます。
リンク情報を別で取ってるのはリンクタグ適応のためです。
これでカード表示でいい感じのができます
3.できたもの
こんな感じのができます
改造タイム入ったのでリンクは死んでます
PCからぱらっとみるぶんには問題ないとこまできました。
どうしてもトップにgoogle公認のものではないことを示すあれが出るので、ガチブログとして運用するには向かないかも?
4.その他
参考サイト
上記ページ以外にもgas全般で参考にしてます
# <chrome extension>次の動画を通知してくれる拡張作った
思いつきから作りました はい。
目次
- 作ったもの
- 実際のコード
- 動作確認の方法
- 公開、リリースまでの流れ
1.作ったもの
今回はchromeでyoutubeを自動再生中に次の動画タイトルを通知してくれる拡張を作りました。
ターゲットとしてはyoutubeをバックグラウンドで再生して作業する人ですかね。
2.実際のコード
そもそもchrome extensionって何使って作るだって感じあるじゃないですか、少なくとも僕にはありました。
調べたじゃないですか
なんと、なぁんとですねぇ、
- HTML
- CSS
- JavaScript
- JSON
の4つなんですねぇ、なんかびっくりです
というかJSONがキモでそれに関連して機能に応じてhtml,CSS,JSを使うって感じです。
なんかいけそうな気がしませんか。
僕はあんまりそんな気がしなかったのでサンプルを改造して目的のものを完成させました。
今回参考にしたサンプル
Water Popup
これをベースにしてググりながらごりごりやりました
今回やりたいことを踏まえて必要なコードはJSON,JS,HTMLでした
2.1 JSON
今回のキモのJSONからです。
この、拡張機能を機能させるときに必ず必要になるのがmanifest.jsonというものです。
どういう拡張機能かを表すファイルですね。
拡張機能の名称とかを書いていきます。
以下のような感じです。
{ "name": "Next Movie is...", "description": "バックグラウンドで再生してるそのyoutube、次に流れる映像を通知します!", "version": "1.0.1", "manifest_version": 2, "permissions": ["tabs","https://www.youtube.com/*", "notifications"], "background": { "presitent": true, "page":"popup.html" }, "icons": { "16": "icons/icon_16.png", "32": "icons/icon_32.png", "48": "icons/icon_48.png", "128": "icons/icon_128.png" } }
詳しい記法は書きませんがざっくりした説明
name | value |
---|---|
name | 拡張機能名 |
description | 拡張機能の説明 |
manifest_version | 書式のバージョン(基本的に2) |
permissions | 拡張機能がアクセスすることのできる権限 |
background | 拡張機能がバックグラウンドで動くのを許可するやつ(くらいに思ってる) |
icons | 拡張機能のアイコン |
2.2HTML
すごいよ、びっくりするよ、見ちゃう??見ちゃう?????
<script src="background.js"></script>
だけ、やば、終わり
2.3JavaScript
今後修正が多少入りそうなので公開されてる状態というよりは最低限こんな感じで動くよってコードを載せときます。
まずはトリガーまわり
//tabが読み込まれた(更新された時のトリガー) chrome.tabs.onUpdated.addListener(function(tabId, props,tab) { //読み込み状態の判別 if (props.status != "complete"){ //タブのタイトル、urlを取得 var ttl=tab.title; var url=tab.url; //動画再生画面の時に通知を発生 if(url.match(/watch/)!=null){ //動画名称の部分を抜き出し ttl=ttl.slice(0,-10); //通知を出す関数にタイトルを渡す send_notification(ttl); } } });
読み込み状態の判別については何度か試したのですが、==にして実行すると前に再生していた動画が出てきてたので今回はこれでいきます。
からの通知生成
function send_notification(ttl) { chrome.notifications.create({ //通知のタイプ type: 'basic', //通知につけるアイコン iconUrl: 'icons/icon_32.png', //通知のタイトル title: 'Next Movie is', //通知の内容(動画タイトル) message: ttl, priority: 0 }); }
こんな感じのコードを実装すると目的の機能ができました。
3.動作確認の方法
まずはchromeを起動して
more tools->extensionsを開きます
開いたらdeveloper ModeをONにします。
そうすると"Load unpacked","pack extension","update"が出てきます。
その中で、"load unpacked" を開いて、マニフェストファイルのあるフォルダを選択します。
そうすると拡張機能が読み込まれます。
これにエラーやらなんやらが全部出ます。
これは個人的になのですが"update"を使っても変わらないことがあったのでコード変えたらdelete->"Load unpacked"がいいと思います。
4.公開、リリースまでの流れ
今回はなんとなく、webストアにリリースしてみました。
そこまでの流れをまとめます。
まずは登録します。
webストアにアクセスしてデベロッパーダッシュボードを開きます。
で登録をぽちぽちします。
で5$って言われるので
ぽちぽち支払います。
そして、新しいアイテムを追加を押して追加します。
ここで追加できるのは、作成したコードが格納されたフォルダをZIPしたものです。
アップロードしたら、ストアの情報を追加していきます。
ここで色々画像が必要になります。
必要な画像のざっくりした一覧です。
画像の種類 | サイズ |
---|---|
アイコン | 128x128 |
タイル(小) | 440x280 |
タイル(大) | 920x680 |
マーキー | 1400x560 |
それをアップロードして、関連したフォームを埋めていくとプレビュー機能を使ってストア画面に表示した感じをみれるようになります。
そんな感じでぽちぽちして公開を押すと公開されます。
時間はちょっとかかります。我慢です。
我慢し続けると、ページができます。
ちなみに今回リリースした拡張機能は以下リンクから
今後更新されたらまた書きます。
2019/07/10 リポジトリ公開しました
<ruby> grep ぽいことするやつ作った
新しいMac買ってしまった
お金やばいのも多少あるけどそれ以上にサクサク動いて快適
grepぽいことするやつ作った
grepってコマンドあるじゃないですか。
ファイルの中身とか検索するあれ
あれってwindowsで使えないじゃないですか
互換はあるけど使い方で見れば別物なのでなんともっていう
そこで同じように使うとなったらプログラム書くしかなくねとなり書きました。
目次
- 今回の目的
- 作ったもの
2.1 ファイルの取得
2.2 取得したファイルの検索
2.3 検索結果の出力
3.できたもの
1.今回の目的
目的はほぼ最初のところに書いてしまっている。
なのでさらに詳細まで書きます。
今回の最終的な目的としてはドラッグ&ドロップで対象ファイル選んでキーワード、条件に一致するやつを検索するようなものを完成させるのが目的になっています。
最初っから一気に完成形を目指せる自信は皆無なのでまずはコマンドで使えるようになればいいかなということで作成します。
今回のゴールとしては
grep-test poolbooyer$ grep -n index data/* data/sample1.txt:3:index data/sample1.txt:4:index data/sample1.txt:5:index data/sample1.txt:6:/index.htm data/sample1.txt:7:index data/sample1.txt:9:/index.html data/sample1.txt:10:/index.htm data/sample2.txt:3:/assets/js/index.js ...
的なものを作ります。
ただ、このままだと微妙に見づらさがあるので、出力形式を以下のようにします。
file名 行数:ヒットした文字列 行数:ヒットした文字列 file名 行数:ヒットした文字列 ...
なんかいい感じに同じファイル単位でまとめて表示するようにします。
2.作ったもの
ということで実装していきました。
今回の流れとしては
ファイル一覧取得->ファイル内容取得->ファイル内部検索->結果出力
でいきます。
この時検索する語句と対象はコマンドライン引数で引っ張ってきます。
ruby serch-eg.rb フォルダ名 検索語句
最初二つはDirで取得して、fileopenなので今回は
ちゃんと書きます
2.1 ファイルの取得
まずはファイルの情報を取得します。
検索対象のフォルダの中身を確認します。
その後、検索対象の中身を取得します。
今回はファイル名とファイルの中身を1つの配列で返すようにしました。
まずはフォルダの中身の確認と取得するところを呼び出すところまで
# 引数のフォルダの中身を確認する fi=Dir::entries(ARGV[0]) # 結果を取扱う配列 data=[] # フォルダ中身全てに対して for i in 0..(fi.length-1) do if fi[i].length>2 then # ファイルの中身を呼び出して配列に追加 data.push(read_file(ARGV[0]+fi[i])) end end
read_fileに渡しているARGV[0]+fi[i]はファイルへのパスです
その上で読み出すプログラム
def read_file(path) r_data=[] r_data[0]=path File.open(path,"r") do |f| r_data[1]=f.read end # 読み込んだデータとファイルのパスを返す return r_data end
的な感じです
2.2 ファイルの検索
読み込んだ情報をもとにしてその中身を検索します。
targetには読み込んだデータ、queryには検索する文字列が入っています。
def search_infile(target,query) # 検索結果 res=[] for i in 0..(target.length-1) do # 文字列を含むか検索 if target[i].include?(query) then res[i]=true else res[i]=false end end # 検索結果を返す return res end
2.3 結果の出力
検索と出力が1つのプログラムにまとめてます。
ここは分割する予定です。
検索するプログラムにコマンドライン引数で受け取った検索文字列と読み込んだファイルのデータを渡すところから
query=ARGV[1] search_each(data,query)
そして、2.2のプログラムを呼び出します
def search_each(data,query) data.each do |line| # line[1]にあるファイルの中身を改行単位で配列に分割 target=line[1].split("\n") # 検索結果を取得 res=search_infile(target,query) # 検索結果をカウント count=0 # ファイル名称を出力 puts line[0] # 検索結果を参照 for i in 0..(res.length-1) do # 一致していたら出力 if res[i]==true then puts "L#{i+1}: #{target[i]}" else count+=1 end end # 1つも一致しなかったら"Not found"と出力 if count==(res.length) then puts "Not found" end # ファイルの結果の間に一行あける puts "" end end
3.できたもの
ということでこれを実行するとこんな感じになります
grep-test poolbooyer$ ruby ./searcher/search-eg.rb data/ inde data/sample4.txt L1: index L2: /index.htm L3: index L7: index L8: /assets/js/index.js L9: index L10: /index.html data/sample5.txt L1: inde ... grep-test poolbooyer$ ruby ./searcher/search-eg.rb data/ fuga data/sample4.txt Not found data/sample5.txt Not found data/sample1.txt ...
これで期待する結果の出方になりましたー!
ちなみに今回のコードは以下にあります
github.com
(search/に入ってます、検索対象にするデータはscript/generator.rbを使って生成してます)
まだ直しが入る予定なので今回はここまで