re:dashがインストールできなくなったので調査した
7/3 22:30追記
re:dash開発者の @arikfr さんがこの記事を読んでくれたらしく。setuptoolsが修正されるまではこの記事で紹介したワークアラウンドを入れることになったようです。
なので、これからインストールする方にはこの記事は不要なのですが、記事は自分の活動記録としてそのまま残しておきます。
まえがき
Ubuntu用のセットアップスクリプトでre:dashをインストールしようとしたらインストールできなくなってたので調べました。
使用した環境はVagrantで起動したUbuntu14.04で、Vagrant Boxはubuntu/trusty64 (virtualbox, 20160627.0.0)
, re:dashのバージョンは0.10.1.b1834
です。
検証に使用したVagrantfile
# -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.configure("2") do |config| config.vm.box = "ubuntu/trusty64" config.vm.network "forwarded_port", guest: 80, host: 9001 config.vm.provider "virtualbox" do |vb| vb.memory = "2048" end config.vm.provision "shell", inline: <<-SHELL sudo locale-gen ja_JP.UTF-8 SHELL end
セットアップスクリプト実行中のエラー
$ curl https://raw.githubusercontent.com/getredash/redash/master/setup/ubuntu/bootstrap.sh $ sudo bash bootstrap.sh
VMにログインし上記の様にスクリプトを実行したところ、途中は割愛しますがre:dashが依存しているモジュールを pip
でインストールするあたりでこんなエラーが出てしまいました。
Downloading/unpacking httplib2==0.9.2 (from -r requirements.txt (line 1)) Downloading httplib2-0.9.2.zip (210kB): 210kB downloaded Running setup.py (path:/tmp/pip_build_root/httplib2/setup.py) egg_info for package httplib2 Traceback (most recent call last): File "<string>", line 3, in <module> File "/usr/local/lib/python2.7/dist-packages/setuptools/__init__.py", line 14, in <module> from setuptools.extension import Extension File "/usr/local/lib/python2.7/dist-packages/setuptools/extension.py", line 11, in <module> from . import msvc File "/usr/local/lib/python2.7/dist-packages/setuptools/msvc.py", line 244, in <module> class PlatformInfo: File "/usr/local/lib/python2.7/dist-packages/setuptools/msvc.py", line 253, in PlatformInfo current_cpu = safe_env['processor_architecture'].lower() File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__ raise KeyError(key) KeyError: 'processor_architecture' Complete output from command python setup.py egg_info: Traceback (most recent call last): File "<string>", line 3, in <module> File "/usr/local/lib/python2.7/dist-packages/setuptools/__init__.py", line 14, in <module> from setuptools.extension import Extension File "/usr/local/lib/python2.7/dist-packages/setuptools/extension.py", line 11, in <module> from . import msvc File "/usr/local/lib/python2.7/dist-packages/setuptools/msvc.py", line 244, in <module> class PlatformInfo: File "/usr/local/lib/python2.7/dist-packages/setuptools/msvc.py", line 253, in PlatformInfo current_cpu = safe_env['processor_architecture'].lower() File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__ raise KeyError(key) KeyError: 'processor_architecture' ---------------------------------------- Cleaning up... Command python setup.py egg_info failed with error code 1 in /tmp/pip_build_root/httplib2 Storing debug log for failure in /root/.pip/pip.log
re:dashのセットアップスクリプトでいうと以下の辺りです。
原因を考える
ちょっと前に使った時は問題なかったのですが、なぜエラーが発生するようになってしまったのでしょうか。
いろいろ調べて回ったのですが、同様の事例や解決策を見つけられなかったのでsetuptools
のリポジトリを見てみました。
リリースを見てみると、最近リリースがあったようです(2016/7/03 10時現在では8時間前)
先ほどのエラーメッセージに/usr/local/lib/python2.7/dist-packages/setuptools/msvc.py
とあったので、該当のファイルが追加されたPull Requestをみてみます。
たぶんこのあたりでなんかあるんだろうなと思ったので、セットアップスクリプトを以下のように変えて再度実行します。
@@ -29,7 +29,7 @@ apt-get -y update apt-get -y dist-upgrade apt-get install -y python-pip python-dev nginx curl build-essential pwgen -pip install -U setuptools +pip install -U setuptools==23.1.0 # redash user # TODO: check user doesn't exist yet?
再実行
再実行時は念のためVMを破棄し、再度作成しなおしたVM上でスクリプトを実行したところインストールが問題なく完了し、 http://localhost:9001/ にアクセスすることが出来ました。
まとめ
re:dashは頻繁にアップデートされるため、たまにインストールがうまくいかないことがある印象があるのですが、今回はsetuptoolsの問題でした。
おそらくsetuptoolsもそのうち修正されるんじゃないかと思いますが、re:dashを使おうとして同じような問題にぶつかった方がこの記事を参考にしていただけたらうれしいです。
iOS9のWebView内でTwitterのシェアボタンをクリックしたらiOS標準のダイアログで投稿したい
まえがき
同僚さんがタイトルに書いてあるようなことをやりたいけどできないと言っていたのでちょっと調べてみました。
やってみた
正しいやり方かどうかは別として、こんなやり方になりました。
import UIKit import Social class ViewController: UIViewController, UIWebViewDelegate { @IBOutlet weak var webView: UIWebView! let twitterIntentUrl = "https://twitter.com/intent/tweet" let initialUrlString = "http://ariarijp.hatenablog.com" override func viewDidLoad() { super.viewDidLoad() let url = NSURL(string : initialUrlString) let urlRequest = NSURLRequest(URL: url!) webView.delegate = self; // WebViewの初期表示 webView.loadRequest(urlRequest) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool { let absUrl = request.URL?.absoluteString // リクエストされたURLがTwitterのシェアボタンっぽいものだったら、Social.frameworkでダイアログを表示する if absUrl!.containsString(twitterIntentUrl) { // アカウントの設定が済んでいれば投稿ダイアログ、設定が済んでいなかったらアラートを表示する // 参考: http://www.brianjcoleman.com/tutorial-share-facebook-twitter-swift/ if SLComposeViewController.isAvailableForServiceType(SLServiceTypeTwitter){ // URLからシェアに使うテキスト、URLを取り出す let tweetUrl = getQueryStringParameter(request.URL?.absoluteString, param: "url") let tweetText = getQueryStringParameter(request.URL?.absoluteString, param: "text") let twitterSheet:SLComposeViewController = SLComposeViewController(forServiceType: SLServiceTypeTwitter) twitterSheet.setInitialText("\(tweetText!) \(tweetUrl!)") self.presentViewController(twitterSheet, animated: true, completion: nil) } else { let alert = UIAlertController(title: "アカウントエラー", message: "Twitterにログインしてください", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "閉じる", style: UIAlertActionStyle.Default, handler: nil)) self.presentViewController(alert, animated: true, completion: nil) } return false } return true } // URLから指定したパラメータを文字列として取り出す // 参考: https://gist.github.com/gillesdemey/509bb8a1a8c576ea215a#gistcomment-1483938 func getQueryStringParameter(url: String?, param: String) -> String? { if let url = url, urlComponents = NSURLComponents(string: url), queryItems = (urlComponents.queryItems) { return queryItems.filter({ (item) in item.name == param }).first?.value! } return nil } }
StoryboardでwebViewを配置して、このViewControllerにOutletを追加してあるのが前提です。
また、はてなブログのURLで動作確認してますが、HTTPSでは無いのでATSの設定をいじったりしてます。
動作確認
動かしてみるとこんな感じです。
Twitterにログインしていない状態でアプリ内WebViewでシェアボタンをタップ
Twitterにログインした状態でアプリ内WebViewでシェアボタンをタップ
今回のような実装を入れなかった場合(デフォルトの挙動
まとめ
雑な感じで「できないことはないでしょう」と言った手前ムキになってやった感がありますが、思ったようなことはできたのでよかったです。
もっと効率が良いやりかたがあれば、Twitterなんかでぜひ教えて下さい。
会社の半期評価でもらったフィードバックを読み返す
うちの会社は1年に2回評価のタイミングがあって、今日は上期の評価フィードバックがあった。
評価制度として、よくある360度評価の仕組みを取り入れられているんだけど、今回のフィードバックは今まで以上に突き刺さるものが多かった。 本当はフィードバックをそのまま転載したいぐらいだけど、自分なりに噛み砕いて、そのいくつかについて考えてみる。
話が長くなる、しゃべるのが早い
- 話が長くてしゃべるのが早いってかなりコミュニケーションとしては致命的な感じ。これは昔からこんな感じだけど、いい加減なんとかしたい
- 話が長いっていうのは言葉を発する前の前処理の質の問題だろうか。落とし所を考えずにしゃべりはじめるというのがある気がする
- しゃべるのが早いっていうのは、「自分はこんなに考えてる」っていうのを無意識にアピールしようとしているような気もする
- 特に発言者の少ない打ち合わせでは、どうしても沈黙を埋めようとしてしまう
誰かのサポートをするのはいいけど、サポートの範囲を超えて手を動かし過ぎてる
- まったくもって仰るとおり。「自分ならできる」という快感に酔っていることがあるのだろう
- ある程度まではサポートしつつも、最後はその人にやりきってもらうみたいな感じにできるようにしたい
- サポート以上に「仕事を奪われている」感を与えてしまっているとつらいので、一歩引く意識をもうちょっと強く持たないとな。と思う。
要求を実現するだけでなく、もっと事業に対してこの方向に進んでいくべき。というような思考や議論ができるようになると良い
- 意識しているつもりだけど、外から見たらあんまりできてないということかなと思う
- これは強めにアピールしようと思えばできそうだけど、なんかそれも違う気がする
まとめ
他にもいいのがあったけど3つぐらいにしておく。
いいフィードバックをもらえてるとは思うので。改善できるところから手をつけていきたいところ。
PHPで例外が発生したらリトライするような処理をigorw/retryで簡単に書いてみる
Web APIを相手にするようなコードを書いていると、リトライ処理は必ず現れる課題です。
先日も似たようなことがあったので、ちょっとした処理を書いて対処したのですが、これはなんかライブラリがあるんじゃないかなと思って調べてみると、Packagistでよくダウンロードされていそうなライブラリがありました。
Githubのスターも結構付いているので、これを試してみます。
インストール
Packagistで公開されているので、もちろんcomposer
でインストールしますが、開発版のようなのでdev-master
を指定してcomposer require
します。
$ composer require igorw/retry dev-master
サンプルコード
使い方は簡単で、retry
関数にリトライ回数と実行したい処理を無名関数やcallable
として渡すだけです。
動作確認用に、2回目までは例外を投げて3回目に成功するメソッドを作って確認してみます。
<?php require __DIR__.'/vendor/autoload.php'; use function igorw\retry; class A { private static $retries = 0; public static function hello() { if (self::$retries < 2) { ++self::$retries; echo 'retry'.PHP_EOL; throw new \Exception(); } echo 'hello'.PHP_EOL; } } retry(2, function () { A::hello(); });
これを実行すると、以下のような結果になります。
$ php example.php retry retry hello
2回までリトライするようになっているので、初回の実行と1回目のリトライでは例外が発生していますが、2回目のリトライ(通算3回目の実行)では処理が正常に終了していますので、想定通りの動作となっています。
また、指定された回数リトライしても例外が発生するとigorw\FailingTooHardException
が発生するようになっています。
ソースを読んでみる
すごくシンプルな処理なので、ソースを追うのも楽です。
retry/retry.php at master · igorw/retry · GitHub
無限ループにして指定回数を超えたらbreakするような実装を想像していましたが、まさかのgoto
でした。こういう使い方もあるんですね。
このライブラリでできないこと
単純にリトライするだけなら、これを使えばとても簡単にリトライ処理が書けるような気がしますが、WebAPI相手だとExponential Backoffのようにリトライ時にスリープを入れたり、特定の例外だった場合のみリトライするようなことはできません。
リトライ時の処理をもっと柔軟に定義したい場合は、以下のライブラリもよさそうです。
この記事では紹介のみにとどめますが、このライブラリも試してみたいと思っています。
TrelloのCLIクライアントをGoで書いた
影響されやすい性格なので、Rebuildを聞いて形骸化しかけていたTODOリストの運用を再開しました。
最近までTodoistを使っていたのですが、ちょっと気分転換もしたかったので、以前使っていたTrelloに出戻りしました。
Todoistと違ってTrelloは公式のMac版クライアントがないようなので、主にブラウザから使っているのですが、ちょっとタスクのリストを確認したいときに億劫になってしまうので、ターミナル上で実行可能なCLIクライアントを書いてみました。
「trello cli」で検索すると、すでにいくつかTrelloのCLIクライアントが公開されています。
すでにあるものをなぜ作ったかという話ですが、GWに時間があったので書いてみたくなった。というのが主なモチベーションです。
Goで書いた理由は単純にGoを使いたかったというのもありますが、Githubに公開してしまえばgo get
で気軽にインストールできるというのが大きな要因です。
また、すでにGoのTrello APIクライアントがあったので、それを利用できたというのもあります。
実のところ、実装の大部分はこのライブラリのサンプルコードとほとんど変わりません。
使い方
インストール
go get
を使います。
$ go get github.com/ariarijp/trellocli
インストール後の設定
~/trelloclirc
に必要な設定を書きます。rcという名前付けが的確だったかについては微妙に自信がありません。
app_key = "YOUR_TRELLO_APP_KEY" token = "YOUR_TRELLO_TOKEN" username = "YOUR_TRELLO_USERNAME"
Trelloのアプリケーションキー、アクセストークンなどは、以下のページあたりから発行できると思います。
実行
設定ファイルを作ったら実行してみます
$ trellocli # ボード名 (ボードのURL) * リスト名 * カードのタイトル * カードのタイトル * カードのタイトル * カードのタイトル * カードのタイトル * リスト名 * カードのタイトル * カードのタイトル
こんな感じで、微妙にMarkdownっぽい形式でタスクリストが表示されます。
また、作業途中ではありますが、ラベルの色にあわせて表示色が変わるようにもなっています。
(実際に使っているタスクリストなので、ほぼほぼモザイクになっています。見難いですがご容赦ください
作ってみた感想
Markdownっぽい表示はQiita:teamでの日報で使い回すためだとか、ラベルにあわせて色分けするとか、自分の業務を楽にするためにだけ書いたので短いコードながら楽しく書けました。
かなり雑なコードですが、go get
したいがためにGithubにpushしたので、気になるところはご指摘いただきたかったりもします。
まだ使い始めて2日程度ですが、ターミナルから出なくてもちょっとしたタスクの確認ができるのは悪くない感じです。
まとめ
そういえばRebuildで「〇〇ってツールを便利に使うために△△しました」とか言うのってなんか恥ずかしい。。みたいなことを聞いた気がする。。と思いながらこの記事を書きました。