Safari + JXA その 2

この間 の続きです。

いや、書いていてですね、ちょっとかったるかったんですよ、doJavaScript。

理由はいくつかあって、要するに文字列にしないといけないので、syntax highlighting が使えないとか。
それ以前の問題として、JavaScript って here document ってないですよね、多分。
複数行にまたがるような長いものは書きづらいと。

なもんで、ゴリゴリやってもいいんだけど、あまりに汚らしいので、ちょっとは綺麗に書こうかしらと。

今回の参考記事。

というわけで、半分くらいうまくいったようですが、変数の受け渡しは、当然に NG でした。

これは、JSON.stringify() を使えばなんとかなるんじゃないかと思います。

say についても、Application.currentApplication() に対して呼べばうまく行きました。
ただ、日本語を喋れません。

Terminal の say コマンドだと -v で Kyoko を指定すればいいんですが、まあ、別に無理して日本語を喋らせる必要はないので、英語のままでいい気もしています。

そういえば、JXA で doShellScript すればいいという話かもしれません。

Safari + JXA

STORES やなんかもそうなんですが、意外とかゆいところに手が届きません。

Yahoo! Auctions なども、API で出品できるようにするといっていたのですが、問い合わせたら、できなくなりました、ということなので、ブラウザの側をスクリプトで制御して、決まった動作を(半)自動化しているのですが、今までは AppleScript で行っていたので、AppleScript と JavaScript、更に shell とのちゃんぽんだったわけです。

別に動いているものを特に書き換えるつもりもないのですが、最近覚えるよりも忘れるほうが早いので、なるべく単一の言語でやりたい、というのがありまして、重い腰を上げて JXA なるものを初めてみました。

というわけで、かなりの人にどうでもいいネタだと思いますが、備忘録として。

Imperia Online という村ゲーをしているのですが、これの特定の村を表示するスクリプトを書いてみました。
いや、ブックマークが 20 件までしか登録できないので、不便なので。

参考にしたのは、この辺り。

動作的には、Safari のすべてのウインドウを取得して、ウインドウの中にぶら下がっているすべてのタブを巡回し、URL をマッチして目的のタブを調べる、という部分、あとは、そこで取得したタブに対して、JavaScript を実行する、という部分で成り立っています。

例えば、Yahoo! Auctions で発送作業をしようと思った時など、発送情報が開かれているタブと、クリックポストの発送入力画面が開かれているタブと、その両方を取得して、それぞれで doJavaScript をすれば、通常できないクロスサイト・スクリプティングが簡単に可能になり、スクリプトメニューにそういうよく使うスクリプトは登録しておくこともでき、また、所詮はスクリプトですから、サイト側のデザイン変更などにも容易、かつ、迅速に対応ができるわけです。

ところで、今のところのハマっている部分。

いちいちエラー画面を出すのがイヤなので、通常は、say を使って喋らせているんですが、うまくいかないんですよね。
多分、Accessibility の権限設定が間違えているんだと思うんだけど。

こちらで参考にしたのは、openspc。
一体何年お世話になりっぱなしなんだろう。

STORES の管理画面がリニューアルされた件

雑貨屋 Hearth & Home 暖炉家(暖炉屋) は STORES という個人のお店用のサービスを使って営業しています。

こういうサイトを一から作るのはそれなりに手間隙がかかるわけで、売れるかどうかもわからない状態で、コストを掛けることはできないし、拙速に行こうということで、サービスが始まった当初に登録して、1 年くらいは開店休業状態だったんですが、2 年ほど前から、本格的に活動を始めたわけです。

ヤフオクも手数料が跳ね上がったので、今までどおりの価格では出品できなくなったのと、簡単取引の仕組みが導入されたたため、すべての出品を一度終了していたのですが、自動出品機能も STORES のほうが変更になったので機能しなくなっていたので、雨で外の仕事ができないので、ごそごそとプログラムを書き直しました。

ほとんど備忘録ですが、JavaScript で変数の汚染の問題があったんですが、とりあえず、無名関数を使って対処するようにしました。

それはそうと、いろいろ調べ物をしていて、今頃知ったんですが、JXA といって、Mac の操作が JavaScript からできるようになっているようです。

Illustrator とかも、JavaScript で自動化できるようですし、Safari 自体も、コンテンツを JavaScript で外部から云々すれば、クロスサイトでの処理も、上の join のようなブサイクなことをしなくても済むので、かなりコーディングが楽になりそうです。

勉強してみようと思いますが、その前に、Raspberry Pi、届いているんですが、micro SD のアダプタがないこと、HDMI で繋がるディスプレイがないこと、この 2 点でテンションが下がって、放置プレイ中です。

忘れるほうが早い年代になってきましたので、忘れないうちにこっちにも時間を割いていこうと思います。

AngularJS 事始め

かれこれ 10 年近く開発の現場からは遠ざかっていたので、その間に世間はすっかり様変わりしているようなんですが、STORES.jp があまりに痒いところに手が届かなさすぎて、痒くて仕方ないので、AngularJS を勉強しようと思った次第です。

まあ、その労力を、ヤフーなり、楽天なり、売れるプラットフォームに引っ越す、ということに費やしたらどうか、と言われそうなのですが、袖振り合うも多生の縁といいますし、もう少し踏ん張ってみうというか、前向きに何かできることをしてみよう、と思ったりしたわけです。

とはいえ、あまりに久しぶりなので、習うより慣れろじゃあないですが、とにかく動かしてみて、理解を深めていこうと思います。

出典 http://www.oreilly.co.jp

出典 http://www.oreilly.co.jp

もう、ハコフグ本 も買ったので、後には引き返せません。

昔の感覚が今でも通用するかはわかりませんが、それでいえば、Oreilly から本が出て、そして、邦訳されている時点で、AngularJS は腐っている、旬は過ぎていると思われますので、今更感が強いんですよね。

そういう意味では、Aurelia.JS あたりで始めたほうがいいようにも思うんですが、STORES.jpAngularJS なんで、それは一旦忘れておこうと思います。

なんせ、税別 2,400 円もしたのですから、多少は元を取りたいと思います。

とりあえず、最初の最初のサンプルをトライしてみたんですが。。。全く動きませんでした。

仕方がないので、次のコードで動きましたけど、いきなり、最初のサンプルで動かない状態なので、先が思いやられます。

とりあえず、ボチボチ頑張って勉強しようと思います。

今更ながら JavaScript で半角 → 全角

まあ、半角・全角という表現がアレなのはおいておいてください。

最近、郵送にクリックポストという手段を使うのですが、ヤマトのメール便に似た感じのサービスで、A4 サイズ、3cm までの厚みのものが安価に送れます。

ウェブで送り先などを入力して、ラベルを作成するんですが、ある程度の数になると、それが結構面倒臭いんですよね。

需要があるのか、さっぱりわかりませんが、重松は住所録ソフトは筆まめを使っているんですが、その筆まめの住所データーをいちいち Windows と Mac とを切り替えながらコピペするのも面倒くさいので、自動化しました。

その時、住所は半角があってはいけないので、変換する必要があるんですが、以前は、Script Managaer を使って変換していたんですけど、もう OSAX がどっかに行ってしまっているし、JavaScript でやることにしました。

以下のページを参考にしました。

ブログ村へのリンク

このブログは WordPress で運用しているのですが、記事にいちいち「ブログ村に参加しています」と書くのは面倒なので、Adman というプラグインで差し込んでいます。ところが、いつの間にか、動かなくなってるんですよね。

なんでかずっとわからなかったんですが、ようやく原因がわかりました。
記事の投稿の際に、画面下の方にある Adman の設定の、Disable ads on this page/post: にチェックが入っていただけのことでした。

で、原因もわかったことだし、重い腰を上げて懸案を片付けることにしました。
続きを読む

STORES.jp の倉庫サービスを使ってみて

出店したと少し前のエントリーで書いた STORES.jp ですが、BASE と同じく、CtoC のサービスとしてとても注目されていて、両者とも急成長しているのは皆さんご存知の通りだと思います。

スピード感があって、次々と新サービスが打ち出されてくるものの、まだまだ発展途上のサービスであり、使い心地としては、箱庭の中に収まっている間はシンプルで心地いいんですが、BtoC、あるいは、BtoB と規模が大きくなり、顧客のニーズが多様化するに連れ、非常に使いづらいか、あるいは、使いものにならなくなっていく、というのが率直な感です。基本的にビギナーが簡単に参入できることにフォーカスしすぎているため、極端にシンプルにしすぎているためでしょう。

STORES.jp を利用する最大のメリット(BASE は使ってないのですが、多分同じだと思います)は、やはり倉庫サービスと言えます。オンラインストアのトラブルの大部分は、品物の発送に起因するものだそうですが、倉庫サービスを利用すると、在庫の管理・発送という業務から開放され、本来注力すべき仕入れや販売に専念できるからです。

しかしながら、メリットであると同時に、まだ立ち上がったばかりで、問題点も多く抱えているように感じます。
その中でも、クリティカルな問題点について、整理をしてみたいと思います。

その問題点とは、ズバリ「預け入れの手順がシンプル過ぎて、その後が大変」ということです。

そもそも論として、STORES.jp には、Amazon でいうところの asin (Amazon Standard Item Number) のような仕組みがありませんし、各テナントストアは完全に独立しています。
なので、横断的に商品そのものを一意に管理するための仕組みそのものが存在しません。
じゃあどうなっているのかというと、あくまでも推測ですが、アイテムを登録した際に、24 文字の一意な id が発行されるようで、便宜上これを item number と呼ぶことにしますが、これでストアの側では受注などを管理をします。
しかし、item number を少なくとも利用者(ストアのオーナー)が意識し、利用することはできません。

次に、じゃあ倉庫どうやって在庫を管理しているのかというと、預け入れた際に、20 文字の id ができるようなのです。
これは便宜上 storage number と呼ぶことにしましょう。
ただ、そのままだと item number と storage number は全く無関係なので、意味がわからなくなりますよね?
どうやって判定するのか、というと、倉庫でアイテムの写真を取って、それで識別してね、というアナログな仕組みなんです。
実際の画面をお見せしましょう。
商品の低解像度の写真と、在庫数だけしか表示されません。
ちなみに、左上から、預け入れが古い順となっていて(ただし、バグがあり位置が時々入れ替わる)、それにより先入れ先出しを担保します。

Screen Shot 2014-08-22 at 1.51.30 PM

非常にシンプルで設計思想自体はとてもいいと思うのですが、でも、ちょっとこれはシンプルすぎる。

まず、在庫の管理ができません。
なぜか、といえば、storage number と item number とが紐付いていないので、item number が同じ商品がいくつ存在するのか、それを調べることができないからです。(無論、人間が数えれば済みますけど)
仮に紐付けたとしても、アイテムを削除して、登録しなおせば、storage number に紐付いた item number がなくなることもありえます。

一応、商品の名称も登録されているようなので、発送を申請した時に送られてくるメールなどに表示されるようになっているのですが、発送の申請時、並びに申請後のウェブサイトでは確認することができません。
しかも、この名称も、倉庫で登録作業をする人が手作業で入力しているようで、時々間違えて登録されているので、更に混乱に拍車がかかる状態が生じるわけです。

よって、この問題を解決するもっとも手っ取り早い方法というのは、倉庫に預け入れてある商品について、item number と storage number を紐付けてあげることです。

ただし、これには注意点があります。

ひとつは、バリエーションの有る商品、例えば、サイズ違い、色違い、これらの扱いをどうするのか、という問題点。別々のアイテムとして登録すれば問題はないのですが、画像はアイテムごとにしか登録できないので、画像で識別する方法だと問題が生じる予感がします。(現状、深くは調査していません)

それと、もうひとつは、同じ商品であるにもかかわらず、複数アイテム登録せざるを得ない現状がある、それに起因して生じている問題です。具体的にいえば、STORES.jp はシンプル過ぎて融通がきかないので、まとめ買いすると割引、というような機能がなく、セット商品を別のアイテムとして登録せざるを得ないわけです。セット商品といっても、ただ単にまとめ売りでしかないので、倉庫から出す数が違うだけで、アイテム的には同じものなんですが、item number が複数ある、そして在庫状況によっては、複数の strage number の商品をパッキングしないといけない、という状態が発生しうるわけです。

よって、下手に作りこまれない事自体が、今回は不幸中の幸いとなっているわけです。

以上のように、悪戦苦闘しているわけですが、STORES.jp の事務局から、数日前に、新倉庫サービスの案内を頂いたのですが、すぐに始まるサービスではないようだし、当面は、Chrome Extension を制作することにより、この件に関する負荷を軽減していこうと思います。

で、振りが長かったですが、ここからが本題です。

STORES.jp ですが、Web Inspector でみると、よくわからないタグがあり、明らかに何らかの Framework で動的にページが生成されていることに気づきます。
なんだろうかと思ったら、AngularJS という Google による Framework を採用しているようです。

ブラ三以来ですから、かれこれ 5 年くらいは JavaScript は触ってこなくて忘れているところですが、当時は、Firefox + GreaseMonkey で、Chrome はでたばっかりくらいでしたが、今は Chrome に絞って、AngularJS を使った Extension を書いたほうがいいように思います。

とはいえ、リハビリが必要ですから、まずは、スクリーンショットの画面で、storage number をキーにメモを取れるように(localStrage を使い永続させる)する Chrome Extension を作成し、これは、GraseMonkey と共用とし、その後、AngularJS を学習して、より作りこんでいく、という方向で行きたいと思います。
ちょっと 課題 もあるようなので。

STORES.jp のサービス自体のスピードが早いので、拙速にいかないと、完成した頃には、動かなくなっていそうですから。

というわけで、貼り。
やっつけ仕事ですから、動かなかったら、ごめんなさい。予め謝っておきます。

やはり動的に生成しているページのため、普通に GreaseMonkey Script を実行すると、その時点では在庫一覧が取得されていないため、textarea が表示されませんでした。ちょっと不細工ですが、setInterval を使って対処しました。

とりあえず、動作が不安定なので、AngularJS が動的に element を生成して DOM に追加されたタイミングで event listener で hook するようにしないと安定して動作しなさそうです。jQuery の live() で img の click を仕込んでみたんですが、ちょっと気持ち悪い動きになったのと、jQuery 自体の使い方をすっかり忘れているので、今日はもう寝ます。w

市外局番の正規表現

はこBOONという宅配便サービスは、ウェブで送り先を登録して番号を発行、その番号をファミポートで打ち込んで発送する、という仕組みです。
が、このウェブサービスのUIが使いにくく困りつつも、今までは我慢してきたんですが、そろそろ我慢も限界なので、自動化することにしました。
続きを読む

HTML5 Web SQL の正体

なんか、正体などと書くと、いかがわしいもののようですが、結論を書けば、Chrome の Web SQL は SQLite でした、ということです。

データベースファイル自体の所在は、[cci]~/Library/Application\ Support/Google/Chrome/Default/databases/[/cci] 以下に、URL っぽいフォルダがあって、その中に収まっています。

うちの Mac (Mac OS X 10.6.8) に最初からはいっている SQLite (sqlite3) は、version 3.6.12 でしたが、これで問題なく、閲覧などはできました。

今までは、いちいち AppleScript を併用して、[cci]do shell script[/cci] していたのですが、Chrome なら、直接 SQLite のデータベースファイルができるので、その方がスマートそうです。

筆まめのデータをSQLiteに取り込む

かれこれ、放置してしまいましたが、以前の続編です。
今回は、前回の失敗をふまえて作戦を変更しました。

まず、ContactXML に書き出すまでは、これ以外に選択肢がないので、変更はありません。

次に XML を PHP で parse するのをやめて、Safari を使うことにします。
そして、Safari を AppleScript で制御して、JavaScript によりデータを SQL 文に変換、それを AppleScript から SQLite に書き出す、という方法で変換することにしました。

続きを読む