automatic 14.12.2 → 26.08
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +635 -83
- data/VERSION +1 -1
- data/automatic.gemspec +109 -248
- data/bin/automatic +20 -139
- data/config/feed2console.yml +10 -4
- data/config/feed2markdown.yml +41 -0
- data/doc/AI_TUTORIAL.md +518 -0
- data/doc/BASIC_DESIGN.md +516 -0
- data/doc/COPYING.LESSER +165 -0
- data/doc/DEPLOYMENT.md +824 -0
- data/doc/LICENSE.md +14 -0
- data/doc/PLUGINS.md +1875 -0
- data/doc/PLUGIN_DEVELOPMENT.md +86 -0
- data/doc/POLICY.md +857 -0
- data/doc/QUICKSTART.md +256 -0
- data/doc/RELEASING.md +381 -0
- data/doc/REQUIREMENTS.md +526 -0
- data/doc/VERSIONS +208 -0
- data/lib/automatic/cli.rb +248 -0
- data/lib/automatic/environment.rb +31 -5
- data/lib/automatic/feed_maker.rb +10 -9
- data/lib/automatic/feed_parser.rb +51 -35
- data/lib/automatic/http.rb +107 -0
- data/lib/automatic/log.rb +49 -18
- data/lib/automatic/opml.rb +3 -1
- data/lib/automatic/pipeline.rb +63 -32
- data/lib/automatic/recipe.rb +56 -17
- data/lib/automatic/version.rb +14 -1
- data/lib/automatic.rb +78 -20
- data/plugins/custom_feed/svn_log.rb +73 -32
- data/plugins/custom_feed/web.rb +348 -0
- data/plugins/filter/absolute_uri.rb +43 -27
- data/plugins/filter/accept.rb +38 -45
- data/plugins/filter/claude.rb +217 -0
- data/plugins/filter/clear.rb +12 -8
- data/plugins/filter/description_link.rb +49 -51
- data/plugins/filter/full_feed.rb +158 -52
- data/plugins/filter/gemini.rb +216 -0
- data/plugins/filter/github_feed.rb +38 -26
- data/plugins/filter/ignore.rb +33 -44
- data/plugins/filter/image.rb +36 -25
- data/plugins/filter/image_source.rb +58 -52
- data/plugins/filter/join.rb +107 -0
- data/plugins/filter/one.rb +19 -26
- data/plugins/filter/open_ai.rb +198 -0
- data/plugins/filter/rand.rb +16 -17
- data/plugins/filter/sakura_ai.rb +205 -0
- data/plugins/filter/sanitize.rb +29 -34
- data/plugins/filter/sort.rb +20 -27
- data/plugins/filter/tumblr_resize.rb +31 -23
- data/plugins/notify/ikachan.rb +86 -48
- data/plugins/provide/fluentd.rb +43 -24
- data/plugins/publish/amazon_s3.rb +73 -40
- data/plugins/publish/console.rb +19 -16
- data/plugins/publish/console_link.rb +20 -17
- data/plugins/publish/eject.rb +48 -26
- data/plugins/publish/fluentd.rb +50 -30
- data/plugins/publish/hatena_bookmark.rb +88 -71
- data/plugins/publish/instapaper.rb +69 -59
- data/plugins/publish/markdown.rb +278 -0
- data/plugins/publish/memcached.rb +35 -29
- data/plugins/store/database.rb +50 -48
- data/plugins/store/digest.rb +212 -0
- data/plugins/store/file.rb +99 -68
- data/plugins/store/full_text.rb +32 -25
- data/plugins/store/permalink.rb +18 -22
- data/plugins/subscription/feed.rb +34 -21
- data/plugins/subscription/link.rb +31 -32
- data/plugins/subscription/text.rb +32 -46
- data/plugins/subscription/tumblr.rb +55 -44
- data/plugins/subscription/xml.rb +40 -36
- metadata +108 -321
- data/Gemfile +0 -38
- data/Rakefile +0 -59
- data/doc/ChangeLog +0 -303
- data/doc/PLUGINS +0 -750
- data/doc/PLUGINS.ja +0 -753
- data/doc/README +0 -511
- data/doc/README.ja +0 -519
- data/plugins/filter/google_news.rb +0 -50
- data/plugins/publish/google_calendar.rb +0 -84
- data/plugins/publish/hipchat.rb +0 -46
- data/plugins/publish/pocket.rb +0 -45
- data/plugins/publish/twitter.rb +0 -58
- data/plugins/subscription/chan_toru.rb +0 -57
- data/plugins/subscription/g_guide.rb +0 -57
- data/plugins/subscription/pocket.rb +0 -51
- data/plugins/subscription/twitter.rb +0 -69
- data/plugins/subscription/twitter_search.rb +0 -50
- data/plugins/subscription/weather.rb +0 -33
- data/script/build +0 -84
- data/spec/fixtures/sampleFeeds.tsv +0 -1
- data/spec/fixtures/sampleFeeds2.tsv +0 -2
- data/spec/fixtures/sampleRecipe.yml +0 -24
- data/spec/lib/automatic/log_spec.rb +0 -32
- data/spec/lib/automatic/pipeline_spec.rb +0 -68
- data/spec/lib/automatic/recipe_spec.rb +0 -40
- data/spec/lib/automatic_spec.rb +0 -99
- data/spec/plugins/custom_feed/svn_log_spec.rb +0 -31
- data/spec/plugins/filter/absolute_uri_spec.rb +0 -61
- data/spec/plugins/filter/accept_spec.rb +0 -331
- data/spec/plugins/filter/clear_spec.rb +0 -49
- data/spec/plugins/filter/description_link_spec.rb +0 -138
- data/spec/plugins/filter/full_feed_spec.rb +0 -129
- data/spec/plugins/filter/github_feed_spec.rb +0 -55
- data/spec/plugins/filter/google_news_spec.rb +0 -69
- data/spec/plugins/filter/ignore_spec.rb +0 -328
- data/spec/plugins/filter/image_source_spec.rb +0 -89
- data/spec/plugins/filter/image_spec.rb +0 -65
- data/spec/plugins/filter/one_spec.rb +0 -71
- data/spec/plugins/filter/rand_spec.rb +0 -52
- data/spec/plugins/filter/sanitize_spec.rb +0 -153
- data/spec/plugins/filter/sort_spec.rb +0 -189
- data/spec/plugins/filter/tumblr_resize_spec.rb +0 -109
- data/spec/plugins/notify/ikachan_spec.rb +0 -58
- data/spec/plugins/provide/fluentd_spec.rb +0 -49
- data/spec/plugins/publish/amazon_s3_spec.rb +0 -40
- data/spec/plugins/publish/console_spec.rb +0 -30
- data/spec/plugins/publish/eject_spec.rb +0 -40
- data/spec/plugins/publish/fluentd_spec.rb +0 -40
- data/spec/plugins/publish/google_calendar_spec.rb +0 -83
- data/spec/plugins/publish/hatena_bookmark_spec.rb +0 -134
- data/spec/plugins/publish/hipchat_spec.rb +0 -69
- data/spec/plugins/publish/instapaper_spec.rb +0 -82
- data/spec/plugins/publish/memcached_spec.rb +0 -63
- data/spec/plugins/publish/pocket_spec.rb +0 -51
- data/spec/plugins/publish/twitter_spec.rb +0 -73
- data/spec/plugins/store/file_spec.rb +0 -58
- data/spec/plugins/store/full_text_spec.rb +0 -152
- data/spec/plugins/store/permalink_spec.rb +0 -206
- data/spec/plugins/subscription/chan_toru_spec.rb +0 -56
- data/spec/plugins/subscription/feed_spec.rb +0 -71
- data/spec/plugins/subscription/g_guide_spec.rb +0 -82
- data/spec/plugins/subscription/link_spec.rb +0 -72
- data/spec/plugins/subscription/pocket_spec.rb +0 -57
- data/spec/plugins/subscription/text_spec.rb +0 -84
- data/spec/plugins/subscription/tumblr_spec.rb +0 -74
- data/spec/plugins/subscription/twitter_search_spec.rb +0 -57
- data/spec/plugins/subscription/twitter_spec.rb +0 -73
- data/spec/plugins/subscription/weather_spec.rb +0 -44
- data/spec/plugins/subscription/xml_spec.rb +0 -84
- data/spec/spec_helper.rb +0 -106
- data/spec/user_dir/plugins/store/mock.rb +0 -16
- data/test/fixtures/sampleOPML.xml +0 -11
- data/test/integration/test_absoluteurl.yml +0 -25
- data/test/integration/test_activerecord.yml +0 -24
- data/test/integration/test_add_pocket.yml +0 -26
- data/test/integration/test_chan_toru.yml +0 -21
- data/test/integration/test_descriptionlink.yml +0 -21
- data/test/integration/test_fluentd.yml +0 -22
- data/test/integration/test_fulltext.yml +0 -30
- data/test/integration/test_google_news.yml +0 -21
- data/test/integration/test_googlealert.yml +0 -21
- data/test/integration/test_hatenabookmark.yml +0 -30
- data/test/integration/test_ignore.yml +0 -25
- data/test/integration/test_ignore2.yml +0 -22
- data/test/integration/test_image2local.yml +0 -33
- data/test/integration/test_instapaper.yml +0 -26
- data/test/integration/test_link2local.yml +0 -34
- data/test/integration/test_one.yml +0 -23
- data/test/integration/test_pocket.yml +0 -22
- data/test/integration/test_rand.yml +0 -21
- data/test/integration/test_sanitize.yml +0 -23
- data/test/integration/test_sort.yml +0 -36
- data/test/integration/test_svnlog.yml +0 -15
- data/test/integration/test_text2feed.yml +0 -36
- data/test/integration/test_tumblr2local.yml +0 -43
- data/test/integration/test_twitter_search.yml +0 -22
- data/test/integration/test_weather.yml +0 -19
- data/test/integration/test_xml2fluentd.yml +0 -21
- data/vendor/.gitkeep +0 -0
data/doc/README.ja
DELETED
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
automaticruby
|
|
2
|
-
|
|
3
|
-
名前
|
|
4
|
-
automaticruby - Ruby による汎用的な自動処理フレームワーク
|
|
5
|
-
|
|
6
|
-
書式
|
|
7
|
-
$ automatic
|
|
8
|
-
|
|
9
|
-
任意のレシピを指定して起動する
|
|
10
|
-
$ automatic -c <recipe>
|
|
11
|
-
|
|
12
|
-
バージョン番号を表示する
|
|
13
|
-
$ automatic -v
|
|
14
|
-
|
|
15
|
-
説明
|
|
16
|
-
このソフトウェアは、プラガブルに機能を拡張可能な Ruby
|
|
17
|
-
による汎用自動処理フレームワークである。
|
|
18
|
-
プラグインによってさまざまな情報を収集加工し、任意の
|
|
19
|
-
形で出力することができる。
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
============
|
|
23
|
-
インストール
|
|
24
|
-
============
|
|
25
|
-
|
|
26
|
-
[安定版]
|
|
27
|
-
$ gem install automatic
|
|
28
|
-
$ automatic scaffold
|
|
29
|
-
(ホームディレクトリに ~/.automatic を生成する)
|
|
30
|
-
$ automatic -c ~/.automatic/config/example/feed2console.yml
|
|
31
|
-
(ブログのフィードを入力しターミナルに出力する)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
[開発版]
|
|
35
|
-
$ git clone git://github.com/automaticruby/automaticruby.git
|
|
36
|
-
$ cd automaticruby
|
|
37
|
-
$ bundle install --path vendor/gems
|
|
38
|
-
$ bin/automatic scaffold
|
|
39
|
-
$ bin/automatic -c ~/.automatic/config/example/feed2console.yml
|
|
40
|
-
(上記に同じ)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
============
|
|
44
|
-
実行してみる
|
|
45
|
-
============
|
|
46
|
-
|
|
47
|
-
任意のレシピ (後述) を作成する。
|
|
48
|
-
$ automatic -c your_recipe.yml
|
|
49
|
-
|
|
50
|
-
-c オプション付きで手動実行し、問題がなければ
|
|
51
|
-
cron に登録するなどして自動化する。
|
|
52
|
-
|
|
53
|
-
単純なファイル名を -c の引数に指定した場合 ~/.automatic/config
|
|
54
|
-
にある同名のファイルがあれば優先的に読み込まれる。無い場合は指定通りの
|
|
55
|
-
パスにあるファイルが読み込まれる。
|
|
56
|
-
|
|
57
|
-
~/.automatic/db が存在する場合、データベースを生成するタイプの
|
|
58
|
-
プラグインはこのディレクトリにファイルを保存する。
|
|
59
|
-
|
|
60
|
-
~/.automatic/plugins が存在する場合、本体付属のプラグインと
|
|
61
|
-
同様にそれらも読み込まれる。
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
試しに実行するなら以下を実行すると良い。
|
|
65
|
-
$ automatic -c ~/.automatic/config/example/feed2console.yml
|
|
66
|
-
|
|
67
|
-
これは、ブログのフィードを単純にコンソール出力するだけの
|
|
68
|
-
簡単なレシピである。
|
|
69
|
-
本ソフトウェアの動作確認に使うことができる。
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
==========
|
|
74
|
-
レシピとは
|
|
75
|
-
==========
|
|
76
|
-
|
|
77
|
-
Automatic Ruby では YAML 形式で書かれた設定ファイル
|
|
78
|
-
を解析し、呼び出すプラグインの情報とそれに伴う様々な
|
|
79
|
-
情報を読み込む。
|
|
80
|
-
|
|
81
|
-
この YAML ファイルをレシピと呼ぶ。
|
|
82
|
-
|
|
83
|
-
automatic.rb 起動時に -c オプションの引数にレシピの
|
|
84
|
-
ファイル名を指定することができる。
|
|
85
|
-
|
|
86
|
-
[起動例]
|
|
87
|
-
$ automatic -c your_recipe.yml
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
================
|
|
91
|
-
レシピの記述方法
|
|
92
|
-
================
|
|
93
|
-
|
|
94
|
-
レシピには暗黙的な命名規則がある。
|
|
95
|
-
|
|
96
|
-
[書式]
|
|
97
|
-
|
|
98
|
-
plugins:
|
|
99
|
-
- module: プラグイン名
|
|
100
|
-
config:
|
|
101
|
-
変数
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
以下はレシピのサンプルとなる YAML ファイルである。
|
|
105
|
-
|
|
106
|
-
plugins:
|
|
107
|
-
- module: SubscriptionFeed
|
|
108
|
-
config:
|
|
109
|
-
feeds:
|
|
110
|
-
- http://reretlet.tumblr.com/rss
|
|
111
|
-
|
|
112
|
-
- module: StorePermalink
|
|
113
|
-
config:
|
|
114
|
-
db: tumblr.db
|
|
115
|
-
|
|
116
|
-
- module: FilterImage
|
|
117
|
-
|
|
118
|
-
- module: FilterTumblrResize
|
|
119
|
-
|
|
120
|
-
- module: StoreFile
|
|
121
|
-
config:
|
|
122
|
-
path: /Users/yourname/Desktop/
|
|
123
|
-
interval: 1
|
|
124
|
-
|
|
125
|
-
このサンプルレシピの例では
|
|
126
|
-
1. Subscription Feed で Tumblr のフィードを購読し
|
|
127
|
-
2. StorePermalink でパーマリンクをデータベースに保存し
|
|
128
|
-
3 FilterImage と FilterTumblrResize で画像の URL を指定して
|
|
129
|
-
4. StoreFile で Tumblr の画像をダウンロードする
|
|
130
|
-
という一連の処理をプラグインの組み合わせで実現している。
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
以下に別の例を示す。
|
|
134
|
-
|
|
135
|
-
plugins:
|
|
136
|
-
- module: SubscriptionFeed
|
|
137
|
-
config:
|
|
138
|
-
feeds:
|
|
139
|
-
- http://example.com/rss2
|
|
140
|
-
- http://hogefuga.com/feed
|
|
141
|
-
|
|
142
|
-
- module: FilterIgnore
|
|
143
|
-
config:
|
|
144
|
-
link:
|
|
145
|
-
- hoge
|
|
146
|
-
- fuga
|
|
147
|
-
|
|
148
|
-
- module: StorePermalink
|
|
149
|
-
config:
|
|
150
|
-
db: permalink.db
|
|
151
|
-
|
|
152
|
-
- module: PublishHatenaBookmark
|
|
153
|
-
config:
|
|
154
|
-
username: your_hatena_id
|
|
155
|
-
password: your_password
|
|
156
|
-
interval: 5
|
|
157
|
-
|
|
158
|
-
このサンプルレシピの例では
|
|
159
|
-
1. Subscription Feed でフィードを購読し
|
|
160
|
-
2. FilterIgnore で無視キーワードを含む URL を除外し
|
|
161
|
-
3. StorePermalink でパーマリンクをデータベースに保存し
|
|
162
|
-
4. PublishHatenaBookmark ではてなブックマークをする
|
|
163
|
-
という一連の処理をプラグインの組み合わせで実現している。
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
このように、プラグインと設定情報をレシピに記述するだけで
|
|
167
|
-
複数のプラグインの組み合わせ次第で無限の可能性を実現する
|
|
168
|
-
ことができる。
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
==========================
|
|
173
|
-
ディレクトリとファイル構成
|
|
174
|
-
==========================
|
|
175
|
-
.
|
|
176
|
-
|
|
|
177
|
-
+- bin
|
|
178
|
-
| |
|
|
179
|
-
| +- automatic
|
|
180
|
-
| 実行ファイル本体
|
|
181
|
-
|
|
|
182
|
-
+- config
|
|
183
|
-
| YAML 形式でプラグインの情報を記述する
|
|
184
|
-
| automatic.rb の -c オプションの引数で
|
|
185
|
-
| 任意のファイル名をレシピとして指定できる
|
|
186
|
-
|
|
|
187
|
-
| 新しくレシピを書いた場合は config ディレクトリに置く
|
|
188
|
-
|
|
|
189
|
-
|
|
|
190
|
-
+- plugins
|
|
191
|
-
| |
|
|
192
|
-
| +- subscription
|
|
193
|
-
| | フィードを購読するプラグイン
|
|
194
|
-
| |
|
|
195
|
-
| +- customfeed
|
|
196
|
-
| | カスタムフィードを生成するプラグイン
|
|
197
|
-
| |
|
|
198
|
-
| +- filter
|
|
199
|
-
| | 情報をフィルタリングするプラグイン
|
|
200
|
-
| |
|
|
201
|
-
| +- store
|
|
202
|
-
| | 情報を内部に保存するプラグイン
|
|
203
|
-
| |
|
|
204
|
-
| +- notify
|
|
205
|
-
| | 情報を通知するプラグイン
|
|
206
|
-
| |
|
|
207
|
-
| +- publish
|
|
208
|
-
| 外部に情報を送信するプラグイン
|
|
209
|
-
|
|
|
210
|
-
| プラグインを開発した場合は plugins ディレクトリに置く
|
|
211
|
-
|
|
|
212
|
-
|
|
|
213
|
-
+- lib
|
|
214
|
-
| |
|
|
215
|
-
| +- automatic.rb
|
|
216
|
-
| | Automatic モジュールの定義をする
|
|
217
|
-
| |
|
|
218
|
-
| +- automatic
|
|
219
|
-
| |
|
|
220
|
-
| +- environment.rb
|
|
221
|
-
| | 環境情報を読み込む
|
|
222
|
-
| |
|
|
223
|
-
| +- pipeline.rb
|
|
224
|
-
| | パイプラインと呼ばれるオブジェクトを利用し
|
|
225
|
-
| | レシピに書かれたプラグインに処理を順次受け渡す
|
|
226
|
-
| |
|
|
227
|
-
| +- feed_parser.rb
|
|
228
|
-
| | フィードを解析する
|
|
229
|
-
| |
|
|
230
|
-
| +- log.rb
|
|
231
|
-
| | ログを出力する
|
|
232
|
-
| |
|
|
233
|
-
| +- recipe.rb
|
|
234
|
-
| レシピを読み込む
|
|
235
|
-
|
|
|
236
|
-
+- db
|
|
237
|
-
| ~/.automatic/db が無い場合、ここにデータベースが
|
|
238
|
-
| 保存される
|
|
239
|
-
|
|
|
240
|
-
+- assets
|
|
241
|
-
| json ファイルなどプラグインの中で適宜必要とされる
|
|
242
|
-
| ファイルが格納される
|
|
243
|
-
| ~/.automatic/assets がある場合はそちらが優先される
|
|
244
|
-
|
|
|
245
|
-
+- script
|
|
246
|
-
| |
|
|
247
|
-
| +- build
|
|
248
|
-
| CI で実施する結合試験をおこなう
|
|
249
|
-
|
|
|
250
|
-
+- spec
|
|
251
|
-
| ユニットテスト用ディレクトリ
|
|
252
|
-
|
|
|
253
|
-
+- test
|
|
254
|
-
| |
|
|
255
|
-
| +- fixtures
|
|
256
|
-
| | テストでロードされるフィクスチャ
|
|
257
|
-
| |
|
|
258
|
-
| +- integration
|
|
259
|
-
| インテグレーションテスト用ディレクトリ
|
|
260
|
-
|
|
|
261
|
-
+- vendor
|
|
262
|
-
| |
|
|
263
|
-
| +- gems
|
|
264
|
-
| bundle install された gem パッケージ
|
|
265
|
-
|
|
|
266
|
-
+- doc
|
|
267
|
-
|
|
|
268
|
-
+- COPYING
|
|
269
|
-
| 本ソフトウェアのライセンス
|
|
270
|
-
|
|
|
271
|
-
+- ChangeLog
|
|
272
|
-
| 更新履歴
|
|
273
|
-
|
|
|
274
|
-
+- PLUGINS.ja
|
|
275
|
-
| プラグインについてのドキュメント
|
|
276
|
-
|
|
|
277
|
-
+- README.ja
|
|
278
|
-
本ドキュメント
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
==============
|
|
283
|
-
開発に参加する
|
|
284
|
-
==============
|
|
285
|
-
|
|
286
|
-
リポジトリ
|
|
287
|
-
https://github.com/automaticruby/automaticruby
|
|
288
|
-
|
|
289
|
-
課題
|
|
290
|
-
https://github.com/automaticruby/automaticruby/issues
|
|
291
|
-
|
|
292
|
-
RubyForge
|
|
293
|
-
http://rubyforge.org/projects/automatic/
|
|
294
|
-
|
|
295
|
-
RubyGems.org
|
|
296
|
-
https://rubygems.org/gems/automatic
|
|
297
|
-
|
|
298
|
-
CI
|
|
299
|
-
http://jenkins.id774.net/jenkins/
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
プラグインを新しく作ったり、あるいはフレームワークを
|
|
303
|
-
改善してくれるなら、以下の手順で開発に参加できる。
|
|
304
|
-
|
|
305
|
-
1. GitHub でリポジトリをフォークする。
|
|
306
|
-
2. プラグインを新しく作ったりする。
|
|
307
|
-
3. Pull Request を送信する。
|
|
308
|
-
|
|
309
|
-
なんらかの貢献があった場合、少しの修正を迅速におこなうために
|
|
310
|
-
コミット権を配布する。
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
================
|
|
314
|
-
コーディング規約
|
|
315
|
-
================
|
|
316
|
-
|
|
317
|
-
コーディング規約は 1 ファイルの中で完結するべきである
|
|
318
|
-
末尾のスペースは除去
|
|
319
|
-
{} は do end より推奨される
|
|
320
|
-
RDoc ヘッダはファイルの作者によって書かれる
|
|
321
|
-
RSPec でテストを書く
|
|
322
|
-
カバレッジ 100% を目指す
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
==================
|
|
326
|
-
プラグインの作り方
|
|
327
|
-
==================
|
|
328
|
-
|
|
329
|
-
たとえば自動処理した何らかの情報を Twitter に投稿したい。
|
|
330
|
-
|
|
331
|
-
このようなときは Publish::Twitter プラグインを作れば良い。
|
|
332
|
-
|
|
333
|
-
実装方法については後述するが、基本的には Twitter の API に
|
|
334
|
-
投稿するだけの簡単な Ruby スクリプトを作るだけである。
|
|
335
|
-
|
|
336
|
-
レシピはこのようになるだろう。
|
|
337
|
-
|
|
338
|
-
- module: PublishTwitter
|
|
339
|
-
config:
|
|
340
|
-
username: your_mail_address
|
|
341
|
-
password: your_password
|
|
342
|
-
|
|
343
|
-
この場合、ファイルを plugins/publish 配下に置き、クラス名
|
|
344
|
-
はレシピで指定した PublishTwitter とする。あとは後述する
|
|
345
|
-
Automatic::Pipeline の機能により自動的に処理される。
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
========================
|
|
349
|
-
Automatic::Pipeline とは
|
|
350
|
-
========================
|
|
351
|
-
|
|
352
|
-
本フレームワークはレシピを YAML で解析し、プラグインを
|
|
353
|
-
順次読み込む。このとき pipeline がインスタンス生成時の
|
|
354
|
-
引数として渡され、戻り値は pipeline に戻る。
|
|
355
|
-
|
|
356
|
-
コードは以下の通りである。
|
|
357
|
-
|
|
358
|
-
pipeline = []
|
|
359
|
-
recipe.each_plugin {|plugin|
|
|
360
|
-
mod = plugin.module
|
|
361
|
-
load_plugin(mod)
|
|
362
|
-
klass = Automatic::Plugin.const_get(mod)
|
|
363
|
-
pipeline = klass.new(plugin.config, pipeline).run
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
プラグイン間での連続した pipeline の受け渡しにより
|
|
367
|
-
処理要素を直列に連結し、あるプラグインの出力が次の
|
|
368
|
-
プラグインの入力となるパイプライン処理を実現する。
|
|
369
|
-
|
|
370
|
-
この機構を本フレームワークでは Automatic::Pipeline と呼ぶ。
|
|
371
|
-
|
|
372
|
-
pipeline の中身はフィードの配列である。
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
====================
|
|
376
|
-
プラグインの実装規約
|
|
377
|
-
====================
|
|
378
|
-
|
|
379
|
-
プラグインのコンストラクタは YAML.load によってロード
|
|
380
|
-
されたハッシュの配列、及びパイプラインと呼ばれる
|
|
381
|
-
インスタンス変数のオブジェクトを引数に取る。
|
|
382
|
-
|
|
383
|
-
推奨されるコンストラクタの実装例は以下の通りである。
|
|
384
|
-
|
|
385
|
-
def initialize(config, pipeline=[])
|
|
386
|
-
@config = config
|
|
387
|
-
@pipeline = pipeline
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
インスタンスメソッド run が自動的に呼ばれる。
|
|
391
|
-
戻り値はインスタンス変数 @pipeline に渡り、レシピで
|
|
392
|
-
定義された次のプラグインに引き渡される。
|
|
393
|
-
|
|
394
|
-
複数のプラグインを組み合わせるとき @pipeline の
|
|
395
|
-
データフォーマットが一致している必要がある。
|
|
396
|
-
たとえば先行するプラグインが RSS フィードを返す場合は
|
|
397
|
-
RSS フィードを処理する。 HTML を返す場合は HTML を処理
|
|
398
|
-
するコードを記述する必要がある。
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
==============
|
|
402
|
-
ユニットテスト
|
|
403
|
-
==============
|
|
404
|
-
|
|
405
|
-
ユニットテストは RSpec でおこなう。
|
|
406
|
-
|
|
407
|
-
プラグインのテストは、引数となるパイプラインを渡し
|
|
408
|
-
戻り値を検査する。
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
========
|
|
412
|
-
結合試験
|
|
413
|
-
========
|
|
414
|
-
|
|
415
|
-
test/integration 配下に複数のプラグインを結合して
|
|
416
|
-
テストをおこなうためのレシピを置く。
|
|
417
|
-
|
|
418
|
-
リポジトリにチェックインする前に必ず ruby 1.9 で
|
|
419
|
-
以下のコマンドを実施し、テストビルドを実施する。
|
|
420
|
-
|
|
421
|
-
$ script/build
|
|
422
|
-
|
|
423
|
-
これによりすべての RSpec によるテスト、及び
|
|
424
|
-
結合試験が実施される。途中で失敗することなくすべて
|
|
425
|
-
のテストが成功したことを確認した上でリポジトリに
|
|
426
|
-
チェックインする。さもなくば CI が失敗するだろう。
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
========================
|
|
430
|
-
継続的インテグレーション
|
|
431
|
-
========================
|
|
432
|
-
|
|
433
|
-
CI は Jenkins でおこなう。
|
|
434
|
-
http://jenkins.id774.net/jenkins/
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
================
|
|
438
|
-
プラグインの説明
|
|
439
|
-
================
|
|
440
|
-
|
|
441
|
-
doc/PLUGINS.ja を参照
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
============
|
|
446
|
-
サブコマンド
|
|
447
|
-
============
|
|
448
|
-
|
|
449
|
-
automatic コマンドから補助的なツールをサブコマンド経由で実行できる。
|
|
450
|
-
|
|
451
|
-
[書式]
|
|
452
|
-
$ automatic
|
|
453
|
-
ヘルプ及びサブコマンドの一覧を表示する
|
|
454
|
-
|
|
455
|
-
$ automatic scaffold
|
|
456
|
-
ホームディレクトリに ~/.automatic ディレクトリを生成する。
|
|
457
|
-
この操作により ~/.automatic の下に plugins, db, config, assets
|
|
458
|
-
ディレクトリが生成される。
|
|
459
|
-
これらは本体のそれぞれのディレクトリよりも優先される。
|
|
460
|
-
|
|
461
|
-
$ automatic unscaffold
|
|
462
|
-
ホームディレクトリの ~/.automatic ディレクトリを削除する。
|
|
463
|
-
|
|
464
|
-
$ automatic autodiscovery <url>
|
|
465
|
-
対象の URL をオートディスカバリで探知しフィードの URL を返す。
|
|
466
|
-
(例)
|
|
467
|
-
$ automatic autodiscovery http://blog.id774.net/post
|
|
468
|
-
["http://blog.id774.net/post/feed/", "http://blog.id774.net/post/comments/feed/"]
|
|
469
|
-
|
|
470
|
-
$ automatic opmlparser <opml path>
|
|
471
|
-
OPML ファイルを解析し URL を出力する。
|
|
472
|
-
(例)
|
|
473
|
-
$ automatic opmlparser opml.xml > feeds.txt
|
|
474
|
-
|
|
475
|
-
$ automatic feedparser <url>
|
|
476
|
-
フィードを解析して内容を返す。
|
|
477
|
-
|
|
478
|
-
$ automatic inspect <url>
|
|
479
|
-
対象の URL をオートディスカバリで探知する。
|
|
480
|
-
さらに最初のフィードの URL を解析して内容を返す。
|
|
481
|
-
目的のサイトのフィードを購読可能かどうか検証するのに使う。
|
|
482
|
-
|
|
483
|
-
$ automatic log <level> <message>
|
|
484
|
-
Automatic Ruby のログ形式でメッセージを出力する。
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
========
|
|
489
|
-
更新履歴
|
|
490
|
-
========
|
|
491
|
-
|
|
492
|
-
doc/ChangeLog を参照
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
====
|
|
496
|
-
TODO
|
|
497
|
-
====
|
|
498
|
-
|
|
499
|
-
GitHub の issues を参照
|
|
500
|
-
https://github.com/automaticruby/automaticruby/issues
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
========
|
|
504
|
-
動作環境
|
|
505
|
-
========
|
|
506
|
-
|
|
507
|
-
Ruby 1.9 以降
|
|
508
|
-
|
|
509
|
-
Gemfile に記述された gem パッケージに依存
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
========
|
|
513
|
-
注意事項
|
|
514
|
-
========
|
|
515
|
-
|
|
516
|
-
過剰なスクレイピング等を避け、常識の範囲の利用に留める。
|
|
517
|
-
本ソフトウェアは GPLv3 ライセンスである。
|
|
518
|
-
|
|
519
|
-
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# Name:: Automatic::Plugin::Filter::GoogleNews
|
|
3
|
-
# Author:: 774 <http://id774.net>
|
|
4
|
-
# Created:: Oct 12, 2014
|
|
5
|
-
# Updated:: Oct 14, 2014
|
|
6
|
-
# Copyright:: Copyright (c) 2014 Automatic Ruby Developers.
|
|
7
|
-
# License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
|
|
8
|
-
|
|
9
|
-
module Automatic::Plugin
|
|
10
|
-
class FilterGoogleNews
|
|
11
|
-
require 'uri'
|
|
12
|
-
require 'nkf'
|
|
13
|
-
|
|
14
|
-
def initialize(config, pipeline=[])
|
|
15
|
-
@config = config
|
|
16
|
-
@pipeline = pipeline
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def run
|
|
20
|
-
@return_feeds = []
|
|
21
|
-
@pipeline.each {|feeds|
|
|
22
|
-
new_feeds = []
|
|
23
|
-
unless feeds.nil?
|
|
24
|
-
feeds.items.each {|feed|
|
|
25
|
-
new_feeds << rewrite_link(feed) unless feed.link.nil?
|
|
26
|
-
}
|
|
27
|
-
end
|
|
28
|
-
@return_feeds << Automatic::FeedMaker.create_pipeline(new_feeds)
|
|
29
|
-
}
|
|
30
|
-
@return_feeds
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def rewrite_link(feed)
|
|
36
|
-
if feed.link.class == String
|
|
37
|
-
if feed.link.index("http://news.google.com")
|
|
38
|
-
matched = feed.link.match(/(&url=)/)
|
|
39
|
-
unless matched.nil?
|
|
40
|
-
new_link = matched.post_match
|
|
41
|
-
feed.link = new_link unless new_link.nil?
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
feed
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# Name:: Automatic::Plugin::Publish::Googlecalendar
|
|
3
|
-
# Author:: 774 <http://id774.net>
|
|
4
|
-
# Created:: Feb 24, 2012
|
|
5
|
-
# Updated:: Jan 15, 2014
|
|
6
|
-
# Copyright:: Copyright (c) 2012-2014 Automatic Ruby Developers.
|
|
7
|
-
# License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
|
|
8
|
-
|
|
9
|
-
module Automatic::Plugin
|
|
10
|
-
class Googlecalendar
|
|
11
|
-
attr_accessor :user, :feed
|
|
12
|
-
|
|
13
|
-
def initialize
|
|
14
|
-
@user = {
|
|
15
|
-
"username" => "",
|
|
16
|
-
"password" => ""
|
|
17
|
-
}
|
|
18
|
-
@feed = 'http://www.google.com/calendar/feeds/default/private/full'
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def add(arg)
|
|
22
|
-
date = nil
|
|
23
|
-
time_st = nil
|
|
24
|
-
time_en = nil
|
|
25
|
-
text = ''
|
|
26
|
-
|
|
27
|
-
# Parse Date
|
|
28
|
-
require 'date'
|
|
29
|
-
if /^([0-9]+\/[0-9]+\/[0-9]+)\s*/ =~ arg
|
|
30
|
-
# yyyy/mm/dd
|
|
31
|
-
datestr = $1
|
|
32
|
-
text = $'
|
|
33
|
-
begin
|
|
34
|
-
date = Date.parse(datestr)
|
|
35
|
-
rescue ArgumentError
|
|
36
|
-
raise "不正な日付形式-1: [#{datestr}]"
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
Automatic::Log.puts("info", "Date : #{date}")
|
|
41
|
-
Automatic::Log.puts("info", "Title : #{text}")
|
|
42
|
-
|
|
43
|
-
# Register to calendar
|
|
44
|
-
require 'rubygems'
|
|
45
|
-
require 'gcalapi'
|
|
46
|
-
|
|
47
|
-
cal = GoogleCalendar::Calendar.new(GoogleCalendar::Service.new(
|
|
48
|
-
@user["username"], @user["password"]), @feed)
|
|
49
|
-
event = cal.create_event
|
|
50
|
-
event.title = text
|
|
51
|
-
event.st = Time.mktime(date.year, date.month, date.day)
|
|
52
|
-
event.en = event.st
|
|
53
|
-
event.allday = true
|
|
54
|
-
event.save!
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
class PublishGoogleCalendar
|
|
59
|
-
attr_accessor :hb
|
|
60
|
-
|
|
61
|
-
def initialize(config, pipeline=[])
|
|
62
|
-
@config = config
|
|
63
|
-
@pipeline = pipeline
|
|
64
|
-
|
|
65
|
-
@gc = Googlecalendar.new
|
|
66
|
-
@gc.user = {
|
|
67
|
-
"hatena_id" => @config['username'],
|
|
68
|
-
"password" => @config['password']
|
|
69
|
-
}
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def run
|
|
73
|
-
@pipeline.each {|feeds|
|
|
74
|
-
unless feeds.nil?
|
|
75
|
-
feeds.items.each {|feed|
|
|
76
|
-
@gc.add('今日 ' + feed.title)
|
|
77
|
-
sleep ||= @config['interval'].to_i
|
|
78
|
-
}
|
|
79
|
-
end
|
|
80
|
-
}
|
|
81
|
-
@pipeline
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
data/plugins/publish/hipchat.rb
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# Name:: Automatic::Plugin::Publish::Hipchat
|
|
3
|
-
# Author:: Kohei Hasegawa <http://github.com/banyan>
|
|
4
|
-
# Created:: Jun 6, 2013
|
|
5
|
-
# Updated:: Jan 15, 2014
|
|
6
|
-
# Copyright:: Copyright (c) 2012-2014 Automatic Ruby Developers.
|
|
7
|
-
# License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
|
|
8
|
-
|
|
9
|
-
module Automatic::Plugin
|
|
10
|
-
require 'hipchat'
|
|
11
|
-
|
|
12
|
-
class PublishHipchat
|
|
13
|
-
def initialize(config, pipeline=[])
|
|
14
|
-
@config = config
|
|
15
|
-
@pipeline = pipeline
|
|
16
|
-
@options = {
|
|
17
|
-
'color' => 'yellow',
|
|
18
|
-
'notify' => false
|
|
19
|
-
}
|
|
20
|
-
@options.merge!(@config.select { |k, v| @options.include?(k) })
|
|
21
|
-
@client = HipChat::Client.new(@config['api_token'])[@config['room_id']]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def run
|
|
25
|
-
@pipeline.each {|feeds|
|
|
26
|
-
unless feeds.nil?
|
|
27
|
-
feeds.items.each {|feed|
|
|
28
|
-
retries = 0
|
|
29
|
-
retry_max = @config['retry'].to_i || 0
|
|
30
|
-
begin
|
|
31
|
-
@client.send(@config['username'], feed.description, @options)
|
|
32
|
-
Automatic::Log.puts("info", "Hipchat post: #{feed.description.gsub(/[\r\n]/,'')[0..50]}...") rescue nil
|
|
33
|
-
rescue => e
|
|
34
|
-
retries += 1
|
|
35
|
-
Automatic::Log.puts("error", "ErrorCount: #{retries}, #{e.message}")
|
|
36
|
-
sleep ||= @config['interval'].to_i
|
|
37
|
-
retry if retries <= retry_max
|
|
38
|
-
end
|
|
39
|
-
sleep ||= @config['interval'].to_i
|
|
40
|
-
}
|
|
41
|
-
end
|
|
42
|
-
}
|
|
43
|
-
@pipeline
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|