feedly ではてブ数を表示する userscript (1行表示時にも対応)
以前、下記の記事で紹介させていただいたはてぶ数表示の userscript ですが、
feedly ではてなブックマーク数の確認(とはてブページへ) - 弘法にも筆の誤り
一覧表示の時もはてぶ数を確認したくなったので、勉強も兼ねて元スクリプトを読んでみました。
プログラマー人生のほぼ全てを静的言語で歩んできたので、正直javascriptはほとんど読めません。
試行錯誤を繰り返して何とか形になりました。
で、完成系がこんな感じ。
chrome のバージョン 27.0.1453.116 m で動作確認しています。
表示場所がなかったので、更新時間の領域に上書きしています。
# マウスオーバーすると場所が変わったり、そのままではクリック出来ないなど問題も多々。。
userscript は以下に置いています。
Feedly にはてぶ数を表示するUserscript
もっと綺麗に書けるんだろうなー。
javascript、難しい。。でも面白い!
Chrome の userscript (とConsole)で jQuery を使う方法
Chrome の userscript は @require を使えないので自前で呼ばないとダメらしい。
知らなかったのでメモメモ。
From:How can I use jQuery in Greasemonkey scripts in Google Chrome? - Stack Overflow
で、上記サイトのコードだと関数がグローバルスコープなので即時関数で囲います。
即時関数については以下のサイトが分かりやすかったです。
知ってて当然?初級者のためのJavaScriptで使う即時関数(function(){...})()の全て - 三等兵
こんな感じ。
ちなみに Chrome の Console 内で jQuery 読み込むには上記のコードから jQuery 読み込みの部分だけ抜き出して Console で以下を実行します。
追記:Chrome のスニペットでもっと楽に!
Chrome スニペット機能を使う - 弘法にも筆の誤り
javascript、楽しくなってきた:-)
JavaEE7とGlassfish4.0でJAX-RSを試してみた
タイトルの通り。
tomcat + Jersey でやってたことと同じ事ができるのか試してみました。
新規プロジェクトで「Java Web」=>「Webアプリケーション」
次へ。
次へ。
プロジェクト右クリックから「新規」「パターンからのRESTful~」
次へ。
リソースパッケージetcを埋めて終了。
生成直後はこんな構成。
ShopResource.java を以下の内容に修正。
package example.resource; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.Context; import javax.ws.rs.core.UriInfo; import javax.ws.rs.Path; import javax.ws.rs.GET; import javax.ws.rs.Produces; import javax.enterprise.context.RequestScoped; import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; /** * REST Web Service * * @author Administrator */ @Path("Shop") @RequestScoped public class ShopResource { @Context private UriInfo context; public ShopResource() { } @GET @Produces(MediaType.APPLICATION_JSON) public List<Shop> getJson() { List<Shop> shopList = new ArrayList<>(); for (int i = 0; i < 5; i++) { Shop shop = new Shop(); shop.setShopId(String.valueOf(i)); shop.setShopName("shopName" + i); shopList.add(shop); } return shopList; } @Path("{shopNo}") @GET @Produces(MediaType.APPLICATION_JSON) public Shop getJson2(@PathParam("shopNo") String shopNo) { Shop shop = new Shop(); shop.setShopId(shopNo); shop.setShopName("URIから取得したshopです"); return shop; } }
箱となるクラスを新規作成。
package example.resource; /** * * @author iwa4 */ public class Shop { private String shopId; private String shopName; public String getShopId() { return shopId; } public void setShopId(String shopId) { this.shopId = shopId; } public String getShopName() { return shopName; } public void setShopName(String shopName) { this.shopName = shopName; } }
最後に画面。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JAX-RS test</title> </head> <body> <h1>JAX-RS test</h1> <button id="button1">get json!</button> <button id="button2">get json2!</button> <div id="list"></div> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script> <script> $("#button1").click(function() { $.getJSON("webresources/Shop", function(data) { for (var i in data) { $("#list").append("<li>" + data[i].shopName + "</li>"); } }); }); $("#button2").click(function() { $.getJSON("webresources/Shop/999", function(data) { $("#list").append("<li>" + data.shopName + "</li>"); }); }); </script> </body> </html>
実行してみる。
「get json!」「get json2!」を押下すると、それぞれJSONを取得している。
動作確認するにはこのテスト・リソースURIが楽だなぁと思いました。
関係ないけど、Rictyフォントに変えてから少し幸せになりました。
テーブルをjQueryでインクリメンタルサーチ
これぐらいだったらライブラリなしで実装できますね。
コールバック関数とか使ったらもっと綺麗に書けるんだろうけど、JavaScriptの言語仕様とAPI理解が足りなひ。
show()とhide()にアニメーションつけるとチラつくし、作りが悪いんだろうなー。
feedly ではてなブックマーク数の確認(とはてブページへ)
20130702追記:feedly ではてブ数を表示する userscript (1行表示時にも対応) - 弘法にも筆の誤り
と同じ思いで、はてぶ数確認したいなーと思っていたら、ChromeのUserScriptを書いていらっしゃる方がいました。
Feedly 移行記念、Feedly をはてブ対応させるユーザースクリプト – OTCHY.NET
助かりました!
ちょっとだけ嵌ったんだけど、拡張機能タブ内にjsファイルをドロップしても、file:// で中身を開いてしまい、なんでインストール出来ないのかな、と思っていたら、UserScriptは
*.user.js
のファイル名じゃなきゃダメなんですね。
ダウンロードしたjsファイルの名前を変更してドロップすると、インストールダイアログ出てきました。
短いスクリプトなので、中身も理解しておこう。
Windows で Node.js を始める時のあれこれ
npm
プロキシ設定
package.json があるディレクトリで npm install を実行すると、依存するパッケージを npm がインストールしてくれる。
ダウンロードされたパッケージは node_modules 以下に配置される。
プロキシ環境で実行する場合は、npmコマンドでプロキシを指定する必要がある。
>npm config set proxy http://PROXY-SERVER:PROXY-PORT
ローカルとグローバル
npm コマンドは -g フラグを付けるとグローバルディレクトリに対して処理が実行される。
グローバルディレクトリの場所は
>npm bin -g C:\Users\iwa4\AppData\Roaming\npm (not in PATH env variable)
not in PATH env variable と出てるのは、システム環境変数にパスが通っていないから。
NODE_PATH 環境変数にパスを通せばいい。
# インストール時にグローバルディレクトリにユーザー環境変数のパスが通っているので、
気にしなくてもおk。
設定確認
上記の内容など、設定した内容は npm config list で見れる。
>npm config list ; cli configs registry = "https://registry.npmjs.org/" ; userconfig C:\Users\iwa4\.npmrc proxy = "http://PROXY-SERVER:PROXY-PORT/" ; builtin config undefined prefix = "C:\\Users\\iwa4\\AppData\\Roaming\\npm" ; node bin location = C:\Program Files\nodejs\\node.exe ; cwd = C:\develop\nodejs-sample ; HOME = C:\Users\iwa4 ; 'npm config ls -l' to show all defaults.
デバッグ
デバッグには node-inspector を使う。
>npm -g install node-inspector
最初、-g をつけずにインストールしたところ、
>npm WARN prefer global node-inspector@0.2.0beta4 should be installed with -g
という警告が出た。
この辺りがまだ理解出来ていないのだけど、ローカルにインストールした場合とグローバルにインストールした場合で、生成されるファイルが少し異なっている。
node-inspector.cmd ファイルが出来てなかったり、node-inspector ファイルの中身が異なっていたり。
直接コマンド叩いて起動するものはグローバルディレクトリにインストールした方が無難みたい。
で、デバッグしてみる。
デバッガ起動。
>node-inspector info - socket.io started visit http://0.0.0.0:8080/debug?port=5858 to start debugging
Node.js起動。
>node --debug example.js debugger listening on port 5858 http://127.0.0.1:8192/
これで、http://127.0.0.1:8080/debug?port=5858 にWebkit系のブラウザでアクセスすると、デバッグ用画面が表示される。
あとは、Scripts から js ファイルを選択して、ブレイクポイントを使ってデバッグ。
CSV ファイルを マルチテーブル・インサート を使ってインポートする
大量データをDBに取り込む時、Oracleではマルチテーブル・インサートという機能があります。
CSVファイルを1レコードずつ読み込んでDBにINSERT、とかよくありますよね。
現行システムがここで時間かかっていたので、対応したいと思います。
※PL/SQL or SQL*Loader の方が早いけど、今回は可能な限り修正コストを抑えたいので、コード修正だけで対応できるこの方法で。
構文はこんな感じ。
insert all
1つのSQL文で複数の表にINSERTする絶品テクニック(1/2) − @IT
into sample_table (id, name, value) values (1, 'TKISHIMO', 0)
into sample_table2 (id, name, value) values (2, 'MHAYASHI', 0)
select * from dual;
では、何件ずつ突っ込めば一番早いんだ?検証してみる。
using Oracle.DataAccess.Client; using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace MultiInsert { class Program { static void Main(string[] args) { var connStr = new OracleConnectionStringBuilder(); connStr.UserID = "UID"; connStr.Password = "PWD"; connStr.DataSource = "SID"; using (var conn = new OracleConnection(connStr.ToString())) { try { conn.Open(); //create Execute(String.Format("create table Test({0})", GetNames(true)), conn); var insert = string.Format("insert into Test({0}) values({1})", GetNames(false), GetValue()); var sqls = new List<string>(); for (int i = 0; i < 50000; i++) sqls.Add(insert); var sw = new Stopwatch(); sw.Start(); foreach (var sql in sqls) Execute(sql, conn); sw.Stop(); Console.WriteLine(" 1件ずつinsert : {0}", sw.Elapsed); sw.Reset(); sw.Start(); MultiExecute(sqls, conn, 10); sw.Stop(); Console.WriteLine(" 10件ずつinsert : {0}", sw.Elapsed); sw.Reset(); sw.Start(); MultiExecute(sqls, conn, 100); sw.Stop(); Console.WriteLine(" 100件ずつinsert : {0}", sw.Elapsed); sw.Reset(); sw.Start(); MultiExecute(sqls, conn, 500); sw.Stop(); Console.WriteLine(" 500件ずつinsert : {0}", sw.Elapsed); //delete Execute("drop table Test", conn); Console.WriteLine("Press any key..."); Console.ReadLine(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } private static void MultiExecute(List<string> sqls, OracleConnection conn, int p) { var sb = new StringBuilder(); var array = new string[p]; for (int i = 0; i < sqls.Count; i += p) { sqls.CopyTo(i, array, 0, p); sb.AppendLine("insert all"); foreach (var item in array) sb.AppendLine(item.Replace("insert ", "")); sb.AppendLine("select * from dual"); Execute(sb.ToString(), conn); sb.Clear(); } } static string GetNames(bool isCreate) { var list = new List<String>(); var type = isCreate ? "VARCHAR2(50)" : ""; for (int i = 0; i < 100; i++) list.Add(String.Format("V_{0:000} {1}", i, type)); return String.Join(",", list); } static string GetValue() { var list = new List<String>(); for (int i = 0; i < 100; i++) list.Add("'test string'"); return String.Join(",", list); } static void Execute(string sql, OracleConnection conn) { using (var cmd = new OracleCommand(sql, conn)) { cmd.ExecuteNonQuery(); } } } }
結果はこんな感じ。
1件ずつinsert : 00:01:15.7948220 10件ずつinsert : 00:00:13.7392012 100件ずつinsert : 00:00:06.7394553 500件ずつinsert : 00:01:04.8971647 Press any key...
多すぎても良くないみたい。
だが、1件ずつループでINSERTするよりも断然早い。