プロジェクト

全般

プロフィール

機能 #866

URIを渡すと適切な方法で開く機能

toshi_a 初音約1年前に追加. 12ヶ月前に更新.

ステータス:
終了
優先度:
通常
担当者:
対象バージョン:
開始日:
2016-08-29
期日:
進捗率:

0%

プラグイン名:

説明

ModelやURIをいい感じに開くイベントを提供して、Modelの種類を呼び出し側が考えずに開くことができるようにする

動機

今は似たような機能をGtk::Timelineが担当していて(!?)、URLを開くときに、特定の画像サービスの正規表現にURLがマッチしたらそれで開くという挙動を実現している。

今Gtkプラグインに実装されている方法だと、開く手段が複数ある場合に対応できていない。 #862 カスタムEntity、 #834 マルチサービスといったものが実装されると、パーマリンク、URIがリソースを特定するために広く使われるようになるため、あるURLを開く手段が複数提供されるようなケースが出てくると思う。

さらに、開く方法も Gtk::Timeline.openurl という俺も全然覚えてなかったヤバいメソッドを直接叩くようになっているので、URI投げたらざっくり開いてくれるイベントを提供する。

handle

Retriever::Model.handle(Regexp condition)

そのModelが扱えるURIを登録しておく。実際には===を呼び出すようにしておいて、Procとかもいけるみたいにしておくといいっぽい

Intent

Plugin#intent(Symbol intent_slug, String label, Class model){|IntentToken token| }

class Intent
  Symbol slug
  String label
  Class supporting_model_class

各Modelを開くためのルーチン(intent)はプラグインが提供する。
開く手段が複数あって決定できないときにユーザにintentを選択させることができるように、表示用のlabelをつけておく。

intent自身が特定のURIの書式をサポートするのではなく、対応するModelのクラスのみを宣言することで、たまにパーマリンクを変えてくるサービスがあっても(そんなサービスあるわけないったーw)、Model側だけの変更で済む。

パーマリンクを開くときにIntentが利用されたら、IntentTokenを引数にブロックが呼ばれる。

IntentToken

class IntentToken
  URI uri
  Retriever::Model model
  Intent intent
  IntentToken parent

Intentで開くときのブロックに渡すパラメータ用のクラス。Structとかでよさそう

「別のやつで開く」みたいなのを実装するために連結リストになっていて、今までどんなIntentで開かれてきたかをあとから辿れるようにしておく。「別のIntentで開く」みたいな抽象的なこをやりたい。

例) あるURIに対するIntentの候補が3つあって、それぞれが「別のIntentで開く」機能を提供している場合、今まで利用したIntentがわからないと、Intent A→Intent B→Intent A...みたいにたらいまわしにされる。

Event

Plugin.call(:open_uri, URI uri)
Plugin.call(:open_uri, String uri)
Plugin.call(:open_model, Retriever::Model model)
Plugin.call(:open_intent, IntentToken intent_token)

handleを全て走査して、利用できるintentを決定し、それで開くイベント。Web Modelみたいなのを作っておいて、WebサイトのURLを投げたらブラウザで表示してくれるような感じにする。そのURLが偶然Twitterのパーマリンクだったりすると、Userのhandlerが反応して、プロフィールを開く。

URIのほかにModelも受け入れ可能にしておく。Modelのクラスが決定していれば、どのIntentで開くべきかを決定するのに役立ちそう。
(TwitterユーザのパーマリンクはWebModelとUserどちらともとれるが、Userが渡されていれば一つに決定できる)

また、IntentTokenの節に書いたような問題にも対応できるように、IntentTokenも受け入れ可能にする。

値の種類ごとにイベントを分けずに、openイベントみたいな高級な名前にしてしまって、なんでも受け入れるようにするかもしれない


関連するチケット

関連している 機能 #900: PhotoModel 終了 2016-09-27
ブロック先 機能 #870: Entityを開く手段を、Retriever::ModelやURIを渡す形式に変更する 終了 2016-09-03
ブロック先 機能 #876: Activityの詳細画面 新規 2016-09-03
ブロック先 バグ #879: 実績メッセージのmikutter_botのアイコンをクリックするとmikutterが落ちる 終了 2016-09-04
ブロック先 機能 #905: 次回以降似たようなURIをどうやって開くか設定する機能 終了 2016-10-06
ブロック先 機能 #906: 次のintentで開く 終了 2016-10-06

関係しているリビジョン

リビジョン a4c8a984 (差分)
toshi_a 初音12ヶ月前に追加

Retriever::Model.handle を実装 refs #866

リビジョン 6afa8504 (差分)
toshi_a 初音12ヶ月前に追加

Intentプラグイン追加 refs #866

Modelを開くためのopenイベント
Modelを開く方法を宣言するintentメソッド

リビジョン 19049a2f (差分)
toshi_a 初音12ヶ月前に追加

Model: フィールドタイプuriを追加 refs #866

リビジョン ce7aecc1 (差分)
toshi_a 初音12ヶ月前に追加

IntentにModel slugフィールドを追加 refs #866

リビジョン 8e67ab4a (差分)
toshi_a 初音12ヶ月前に追加

openイベントにURIを渡した時、URIからModelを取得する refs #866

リビジョン 7990f5cc (差分)
toshi_a 初音12ヶ月前に追加

Web Modelを追加し、openイベントにURLを渡すと外部ブラウザで開く refs #866

リビジョン b7fd96bb (差分)
toshi_a 初音12ヶ月前に追加

Retriever::Model.handleに正規表現を渡してもマッチしない refs #866

右辺がURIなので。条件がRegexpだったら右辺をto_sで文字列にすることにした

リビジョン 8e327116 (差分)
toshi_a 初音12ヶ月前に追加

URIを開く方法が一つに決定できない場合、Gtk::Dialogを出してユーザに決定させる refs #866

リビジョン 6c75b178 (差分)
toshi_a 初音12ヶ月前に追加

URIからModelを生成するメソッドの定義方法を変更 refs #866

リビジョン 538da0c3 (差分)
toshi_a 初音12ヶ月前に追加

MessageのpermalinkからMessageを作成する手段 refs #866

リビジョン 9d39aaf1 (差分)
toshi_a 初音12ヶ月前に追加

UserのpermalinkからUserを作成する手段 refs #866

リビジョン 67106654 (差分)
toshi_a 初音12ヶ月前に追加

Web上のリソースを扱うためのwebプラグイン追加 refs #866

リビジョン 64bdaac3 (差分)
toshi_a 初音12ヶ月前に追加

Gtk.openurlを、openイベントを発生させるメソッドに変更 refs #866

Gtk.openurlの内容は、webプラグインに移植した

リビジョン 52cd1303 (差分)
toshi_a 初音12ヶ月前に追加

URLを開く方法>デフォルトブラウザを使う がレニウムされていた refs #866

履歴

#1 toshi_a 初音約1年前に更新

  • ブロック先 機能 #870: Entityを開く手段を、Retriever::ModelやURIを渡す形式に変更する を追加

#2 toshi_a 初音約1年前に更新

  • ブロック先 機能 #876: Activityの詳細画面 を追加

#3 toshi_a 初音約1年前に更新

  • ブロック先 バグ #879: 実績メッセージのmikutter_botのアイコンをクリックするとmikutterが落ちる を追加

#4 toshi_a 初音約1年前に更新

  • ステータス新規 から 進行中 に変更

#5 toshi_a 初音12ヶ月前に更新

#6 toshi_a 初音12ヶ月前に更新

  • ブロック先 機能 #905: 次回以降似たようなURIをどうやって開くか設定する機能 を追加

#7 toshi_a 初音12ヶ月前に更新

  • ブロック先 機能 #906: 次のintentで開く を追加

#8 toshi_a 初音12ヶ月前に更新

  • ステータス進行中 から 終了 に変更

すごいぞ

#9 rhen ium12ヶ月前に更新

commit 64bdaac3ae3d:
url_open_command が変数とメソッド名でかぶってるので、URL を開く方法を「デフォルトブラウザを使う」にしている場合にうまく動きません

diff --git a/core/plugin/web/web.rb b/core/plugin/web/web.rb
index 7273c99..a22da33 100644
--- a/core/plugin/web/web.rb
+++ b/core/plugin/web/web.rb
@@ -14,6 +14,7 @@ Plugin.create(:web) do
       shellExecuteA = Win32API.new('shell32.dll','ShellExecuteA',%w(p p p p p i),'i')
       shellExecuteA.call(0, 'open', url, 0, 0, 1)
     else
+      url_open_command = find_url_open_command
       if url_open_command
         bg_system(url_open_command, url)
       else
@@ -30,7 +31,7 @@ Plugin.create(:web) do
   end

   # URLを開くことができるコマンドを返す。
-  memoize def url_open_command
+  memoize def find_url_open_command
     openable_commands = %w{xdg-open open /etc/alternatives/x-www-browser}
     wellknown_browsers = %w{firefox chromium opera}
     command = nil

#10 toshi_a 初音12ヶ月前に更新

ありがとう、修正します

#11 toshi_a 初音12ヶ月前に更新

なんだこのコード…俺は何を考えてこんなことを…

他の形式にエクスポート: Atom PDF