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.
Files changed (172) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +635 -83
  3. data/VERSION +1 -1
  4. data/automatic.gemspec +109 -248
  5. data/bin/automatic +20 -139
  6. data/config/feed2console.yml +10 -4
  7. data/config/feed2markdown.yml +41 -0
  8. data/doc/AI_TUTORIAL.md +518 -0
  9. data/doc/BASIC_DESIGN.md +516 -0
  10. data/doc/COPYING.LESSER +165 -0
  11. data/doc/DEPLOYMENT.md +824 -0
  12. data/doc/LICENSE.md +14 -0
  13. data/doc/PLUGINS.md +1875 -0
  14. data/doc/PLUGIN_DEVELOPMENT.md +86 -0
  15. data/doc/POLICY.md +857 -0
  16. data/doc/QUICKSTART.md +256 -0
  17. data/doc/RELEASING.md +381 -0
  18. data/doc/REQUIREMENTS.md +526 -0
  19. data/doc/VERSIONS +208 -0
  20. data/lib/automatic/cli.rb +248 -0
  21. data/lib/automatic/environment.rb +31 -5
  22. data/lib/automatic/feed_maker.rb +10 -9
  23. data/lib/automatic/feed_parser.rb +51 -35
  24. data/lib/automatic/http.rb +107 -0
  25. data/lib/automatic/log.rb +49 -18
  26. data/lib/automatic/opml.rb +3 -1
  27. data/lib/automatic/pipeline.rb +63 -32
  28. data/lib/automatic/recipe.rb +56 -17
  29. data/lib/automatic/version.rb +14 -1
  30. data/lib/automatic.rb +78 -20
  31. data/plugins/custom_feed/svn_log.rb +73 -32
  32. data/plugins/custom_feed/web.rb +348 -0
  33. data/plugins/filter/absolute_uri.rb +43 -27
  34. data/plugins/filter/accept.rb +38 -45
  35. data/plugins/filter/claude.rb +217 -0
  36. data/plugins/filter/clear.rb +12 -8
  37. data/plugins/filter/description_link.rb +49 -51
  38. data/plugins/filter/full_feed.rb +158 -52
  39. data/plugins/filter/gemini.rb +216 -0
  40. data/plugins/filter/github_feed.rb +38 -26
  41. data/plugins/filter/ignore.rb +33 -44
  42. data/plugins/filter/image.rb +36 -25
  43. data/plugins/filter/image_source.rb +58 -52
  44. data/plugins/filter/join.rb +107 -0
  45. data/plugins/filter/one.rb +19 -26
  46. data/plugins/filter/open_ai.rb +198 -0
  47. data/plugins/filter/rand.rb +16 -17
  48. data/plugins/filter/sakura_ai.rb +205 -0
  49. data/plugins/filter/sanitize.rb +29 -34
  50. data/plugins/filter/sort.rb +20 -27
  51. data/plugins/filter/tumblr_resize.rb +31 -23
  52. data/plugins/notify/ikachan.rb +86 -48
  53. data/plugins/provide/fluentd.rb +43 -24
  54. data/plugins/publish/amazon_s3.rb +73 -40
  55. data/plugins/publish/console.rb +19 -16
  56. data/plugins/publish/console_link.rb +20 -17
  57. data/plugins/publish/eject.rb +48 -26
  58. data/plugins/publish/fluentd.rb +50 -30
  59. data/plugins/publish/hatena_bookmark.rb +88 -71
  60. data/plugins/publish/instapaper.rb +69 -59
  61. data/plugins/publish/markdown.rb +278 -0
  62. data/plugins/publish/memcached.rb +35 -29
  63. data/plugins/store/database.rb +50 -48
  64. data/plugins/store/digest.rb +212 -0
  65. data/plugins/store/file.rb +99 -68
  66. data/plugins/store/full_text.rb +32 -25
  67. data/plugins/store/permalink.rb +18 -22
  68. data/plugins/subscription/feed.rb +34 -21
  69. data/plugins/subscription/link.rb +31 -32
  70. data/plugins/subscription/text.rb +32 -46
  71. data/plugins/subscription/tumblr.rb +55 -44
  72. data/plugins/subscription/xml.rb +40 -36
  73. metadata +108 -321
  74. data/Gemfile +0 -38
  75. data/Rakefile +0 -59
  76. data/doc/ChangeLog +0 -303
  77. data/doc/PLUGINS +0 -750
  78. data/doc/PLUGINS.ja +0 -753
  79. data/doc/README +0 -511
  80. data/doc/README.ja +0 -519
  81. data/plugins/filter/google_news.rb +0 -50
  82. data/plugins/publish/google_calendar.rb +0 -84
  83. data/plugins/publish/hipchat.rb +0 -46
  84. data/plugins/publish/pocket.rb +0 -45
  85. data/plugins/publish/twitter.rb +0 -58
  86. data/plugins/subscription/chan_toru.rb +0 -57
  87. data/plugins/subscription/g_guide.rb +0 -57
  88. data/plugins/subscription/pocket.rb +0 -51
  89. data/plugins/subscription/twitter.rb +0 -69
  90. data/plugins/subscription/twitter_search.rb +0 -50
  91. data/plugins/subscription/weather.rb +0 -33
  92. data/script/build +0 -84
  93. data/spec/fixtures/sampleFeeds.tsv +0 -1
  94. data/spec/fixtures/sampleFeeds2.tsv +0 -2
  95. data/spec/fixtures/sampleRecipe.yml +0 -24
  96. data/spec/lib/automatic/log_spec.rb +0 -32
  97. data/spec/lib/automatic/pipeline_spec.rb +0 -68
  98. data/spec/lib/automatic/recipe_spec.rb +0 -40
  99. data/spec/lib/automatic_spec.rb +0 -99
  100. data/spec/plugins/custom_feed/svn_log_spec.rb +0 -31
  101. data/spec/plugins/filter/absolute_uri_spec.rb +0 -61
  102. data/spec/plugins/filter/accept_spec.rb +0 -331
  103. data/spec/plugins/filter/clear_spec.rb +0 -49
  104. data/spec/plugins/filter/description_link_spec.rb +0 -138
  105. data/spec/plugins/filter/full_feed_spec.rb +0 -129
  106. data/spec/plugins/filter/github_feed_spec.rb +0 -55
  107. data/spec/plugins/filter/google_news_spec.rb +0 -69
  108. data/spec/plugins/filter/ignore_spec.rb +0 -328
  109. data/spec/plugins/filter/image_source_spec.rb +0 -89
  110. data/spec/plugins/filter/image_spec.rb +0 -65
  111. data/spec/plugins/filter/one_spec.rb +0 -71
  112. data/spec/plugins/filter/rand_spec.rb +0 -52
  113. data/spec/plugins/filter/sanitize_spec.rb +0 -153
  114. data/spec/plugins/filter/sort_spec.rb +0 -189
  115. data/spec/plugins/filter/tumblr_resize_spec.rb +0 -109
  116. data/spec/plugins/notify/ikachan_spec.rb +0 -58
  117. data/spec/plugins/provide/fluentd_spec.rb +0 -49
  118. data/spec/plugins/publish/amazon_s3_spec.rb +0 -40
  119. data/spec/plugins/publish/console_spec.rb +0 -30
  120. data/spec/plugins/publish/eject_spec.rb +0 -40
  121. data/spec/plugins/publish/fluentd_spec.rb +0 -40
  122. data/spec/plugins/publish/google_calendar_spec.rb +0 -83
  123. data/spec/plugins/publish/hatena_bookmark_spec.rb +0 -134
  124. data/spec/plugins/publish/hipchat_spec.rb +0 -69
  125. data/spec/plugins/publish/instapaper_spec.rb +0 -82
  126. data/spec/plugins/publish/memcached_spec.rb +0 -63
  127. data/spec/plugins/publish/pocket_spec.rb +0 -51
  128. data/spec/plugins/publish/twitter_spec.rb +0 -73
  129. data/spec/plugins/store/file_spec.rb +0 -58
  130. data/spec/plugins/store/full_text_spec.rb +0 -152
  131. data/spec/plugins/store/permalink_spec.rb +0 -206
  132. data/spec/plugins/subscription/chan_toru_spec.rb +0 -56
  133. data/spec/plugins/subscription/feed_spec.rb +0 -71
  134. data/spec/plugins/subscription/g_guide_spec.rb +0 -82
  135. data/spec/plugins/subscription/link_spec.rb +0 -72
  136. data/spec/plugins/subscription/pocket_spec.rb +0 -57
  137. data/spec/plugins/subscription/text_spec.rb +0 -84
  138. data/spec/plugins/subscription/tumblr_spec.rb +0 -74
  139. data/spec/plugins/subscription/twitter_search_spec.rb +0 -57
  140. data/spec/plugins/subscription/twitter_spec.rb +0 -73
  141. data/spec/plugins/subscription/weather_spec.rb +0 -44
  142. data/spec/plugins/subscription/xml_spec.rb +0 -84
  143. data/spec/spec_helper.rb +0 -106
  144. data/spec/user_dir/plugins/store/mock.rb +0 -16
  145. data/test/fixtures/sampleOPML.xml +0 -11
  146. data/test/integration/test_absoluteurl.yml +0 -25
  147. data/test/integration/test_activerecord.yml +0 -24
  148. data/test/integration/test_add_pocket.yml +0 -26
  149. data/test/integration/test_chan_toru.yml +0 -21
  150. data/test/integration/test_descriptionlink.yml +0 -21
  151. data/test/integration/test_fluentd.yml +0 -22
  152. data/test/integration/test_fulltext.yml +0 -30
  153. data/test/integration/test_google_news.yml +0 -21
  154. data/test/integration/test_googlealert.yml +0 -21
  155. data/test/integration/test_hatenabookmark.yml +0 -30
  156. data/test/integration/test_ignore.yml +0 -25
  157. data/test/integration/test_ignore2.yml +0 -22
  158. data/test/integration/test_image2local.yml +0 -33
  159. data/test/integration/test_instapaper.yml +0 -26
  160. data/test/integration/test_link2local.yml +0 -34
  161. data/test/integration/test_one.yml +0 -23
  162. data/test/integration/test_pocket.yml +0 -22
  163. data/test/integration/test_rand.yml +0 -21
  164. data/test/integration/test_sanitize.yml +0 -23
  165. data/test/integration/test_sort.yml +0 -36
  166. data/test/integration/test_svnlog.yml +0 -15
  167. data/test/integration/test_text2feed.yml +0 -36
  168. data/test/integration/test_tumblr2local.yml +0 -43
  169. data/test/integration/test_twitter_search.yml +0 -22
  170. data/test/integration/test_weather.yml +0 -19
  171. data/test/integration/test_xml2fluentd.yml +0 -21
  172. data/vendor/.gitkeep +0 -0
@@ -0,0 +1,86 @@
1
+ # Plugin Development
2
+
3
+ A plugin is a small Ruby class with `initialize` and `run`. It needs no registry,
4
+ framework edit or dependency-injection container.
5
+
6
+ To add or change a plugin in this repository, first follow the
7
+ [source checkout setup](../README.md#from-a-checkout), including `bundle
8
+ install` and the default test suite. User plugins under `~/.automatic` do not
9
+ require a framework checkout.
10
+
11
+ ## Naming and location
12
+
13
+ The class name combines a category and a name. The file path separates them:
14
+
15
+ ```text
16
+ FilterTitlePrefix -> filter/title_prefix.rb
17
+ ```
18
+
19
+ Shipped plugins live under `plugins/`. A user plugin lives under
20
+ `~/.automatic/plugins/` and is found before a shipped plugin with the same name.
21
+
22
+ ## A complete plugin
23
+
24
+ Create `~/.automatic/plugins/filter/title_prefix.rb`:
25
+
26
+ ```ruby
27
+ module Automatic::Plugin
28
+ class FilterTitlePrefix
29
+ def initialize(config, pipeline = [])
30
+ @config = config || {}
31
+ @pipeline = pipeline
32
+ end
33
+
34
+ def run
35
+ prefix = @config['prefix'].to_s
36
+ @pipeline.each do |feed|
37
+ next if feed.nil?
38
+
39
+ feed.items.each do |item|
40
+ item.title = "#{prefix}#{item.title}"
41
+ end
42
+ end
43
+ @pipeline
44
+ end
45
+ end
46
+ end
47
+ ```
48
+
49
+ Use it in any Recipe:
50
+
51
+ ```yaml
52
+ - module: FilterTitlePrefix
53
+ config:
54
+ prefix: "[News] "
55
+ ```
56
+
57
+ No framework source or registry is changed. The loader derives the file path
58
+ from `FilterTitlePrefix` and loads it from the user plugin directory.
59
+
60
+ ## The contract
61
+
62
+ - Put the class in `Automatic::Plugin`.
63
+ - Choose one existing category: `Subscription`, `CustomFeed`, `Filter`, `Store`,
64
+ `Provide`, `Notify` or `Publish`.
65
+ - Accept `(config, pipeline)` in `initialize`; tolerate a missing config.
66
+ - Read config by string key, because it comes from YAML.
67
+ - Implement `run` and return the shared pipeline value.
68
+ - Use `Automatic::Log.puts('info', 'message')` for useful operational events.
69
+ Never log credentials or one noisy line per routine transformation.
70
+ - Require an external gem at the top of the plugin file. A dependency used by
71
+ one optional plugin does not belong in the framework gemspec.
72
+
73
+ A source plugin creates feed objects. A Filter or Store changes or narrows them.
74
+ A Publish plugin serializes or sends them, then still returns the pipeline.
75
+
76
+ ## Test it without a network
77
+
78
+ Construct a pipeline with `Automatic::FeedMaker`, run the class directly and
79
+ assert on its returned items. Use fixed input and temporary directories. The
80
+ default suite must not contact a real host, use a credential or depend on the
81
+ clock. Put an explicitly tagged integration check outside the default suite if
82
+ the plugin must also be exercised against a live service.
83
+
84
+ The repository's loader specs demonstrate that a plugin placed under the user
85
+ directory is discoverable. The plugin catalogue and complete contract are in
86
+ [`PLUGINS.md`](PLUGINS.md).