automatic 13.1.0 → 13.2.0

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 (43) hide show
  1. data/README.md +1 -1
  2. data/VERSION +1 -1
  3. data/assets/siteinfo/items_all.json +52139 -0
  4. data/automatic.gemspec +16 -5
  5. data/bin/automatic +2 -2
  6. data/bin/automatic-config +8 -2
  7. data/doc/ChangeLog +19 -0
  8. data/doc/PLUGINS +79 -18
  9. data/doc/PLUGINS.ja +79 -17
  10. data/doc/README +10 -15
  11. data/doc/README.ja +10 -15
  12. data/lib/automatic.rb +2 -2
  13. data/plugins/filter/full_feed.rb +76 -0
  14. data/plugins/filter/ignore.rb +4 -12
  15. data/plugins/filter/{reverse.rb → sort.rb} +12 -6
  16. data/plugins/publish/instapaper.rb +77 -0
  17. data/plugins/store/target_link.rb +6 -2
  18. data/plugins/subscription/feed.rb +6 -2
  19. data/plugins/subscription/google_reader_star.rb +63 -0
  20. data/plugins/subscription/link.rb +6 -2
  21. data/plugins/subscription/tumblr.rb +14 -10
  22. data/plugins/subscription/twitter.rb +6 -2
  23. data/spec/lib/automatic_spec.rb +2 -2
  24. data/spec/plugins/filter/full_feed_spec.rb +48 -0
  25. data/spec/plugins/filter/ignore_spec.rb +184 -15
  26. data/spec/plugins/filter/sort_spec.rb +189 -0
  27. data/spec/plugins/publish/instapaper_spec.rb +56 -0
  28. data/spec/plugins/store/target_link_spec.rb +17 -1
  29. data/spec/plugins/subscription/feed_spec.rb +28 -1
  30. data/spec/plugins/subscription/google_reader_star_spec.rb +45 -0
  31. data/spec/plugins/subscription/link_spec.rb +29 -2
  32. data/spec/plugins/subscription/tumblr_spec.rb +17 -2
  33. data/spec/plugins/subscription/twitter_spec.rb +29 -2
  34. data/test/integration/test_absoluteurl.yml +25 -0
  35. data/test/integration/test_fulltext.yml +7 -1
  36. data/test/integration/test_googlestar.yml +19 -0
  37. data/test/integration/test_image2local.yml +4 -1
  38. data/test/integration/{test_reverse.yml → test_instapaper.yml} +9 -2
  39. data/test/integration/test_link2local.yml +34 -0
  40. data/test/integration/test_sort.yml +36 -0
  41. data/test/integration/test_tumblr2local.yml +16 -4
  42. metadata +16 -5
  43. data/spec/plugins/filter/reverse_spec.rb +0 -54
@@ -2,7 +2,7 @@
2
2
  # Name:: Automatic::Plugin::Filter::Ignore
3
3
  # Author:: 774 <http://id774.net>
4
4
  # Created:: Feb 22, 2012
5
- # Updated:: Jun 14, 2012
5
+ # Updated:: Feb 13, 2013
6
6
  # Copyright:: 774 Copyright (c) 2012
7
7
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
8
 
@@ -23,14 +23,6 @@ module Automatic::Plugin
23
23
  end
24
24
  }
25
25
  end
26
- unless @config['exclude'].nil?
27
- @config['exclude'].each {|e|
28
- if items.link.include?(e.chomp)
29
- detection = true
30
- Automatic::Log.puts("info", "Excluded by link: #{items.link}")
31
- end
32
- }
33
- end
34
26
  unless @config['description'].nil?
35
27
  @config['description'].each {|e|
36
28
  if items.description.include?(e.chomp)
@@ -45,13 +37,13 @@ module Automatic::Plugin
45
37
  def run
46
38
  @return_feeds = []
47
39
  @pipeline.each {|feeds|
48
- ignore = false
40
+ new_feeds = []
49
41
  unless feeds.nil?
50
42
  feeds.items.each {|items|
51
- ignore = true if exclude(items)
43
+ new_feeds << items if exclude(items) == false
52
44
  }
53
45
  end
54
- @return_feeds << feeds unless ignore
46
+ @return_feeds << Automatic::FeedParser.create(new_feeds) if new_feeds.length > 0
55
47
  }
56
48
  @return_feeds
57
49
  end
@@ -1,13 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
- # Name:: Automatic::Plugin::Filter::Reverse
2
+ # Name:: Automatic::Plugin::Filter::Sort
3
3
  # Author:: 774 <http://id774.net>
4
4
  # Created:: Mar 23, 2012
5
- # Updated:: Mar 23, 2012
5
+ # Updated:: Jan 23, 2013
6
6
  # Copyright:: 774 Copyright (c) 2012
7
7
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
8
 
9
9
  module Automatic::Plugin
10
- class FilterReverse
10
+ class FilterSort
11
11
 
12
12
  def initialize(config, pipeline=[])
13
13
  @config = config
@@ -19,9 +19,15 @@ module Automatic::Plugin
19
19
  @pipeline.each { |feeds|
20
20
  return_feed_items = []
21
21
  unless feeds.nil?
22
- feeds.items.sort!{|a,b|
23
- a.date <=> b.date
24
- }
22
+ if @config['sort'] == "asc"
23
+ feeds.items.sort!{|a,b|
24
+ a.date <=> b.date
25
+ }
26
+ else
27
+ feeds.items.sort!{|a,b|
28
+ - (a.date <=> b.date)
29
+ }
30
+ end
25
31
  @return_feeds << feeds
26
32
  end
27
33
  }
@@ -0,0 +1,77 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Name:: Automatic::Plugin::Publish::Instapaper
3
+ # Author:: soramugi <http://soramugi.net>
4
+ # Created:: Feb 9, 2013
5
+ # Updated:: Feb 9, 2013
6
+ # Copyright:: soramugi Copyright (c) 2013
7
+ # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
+
9
+ module Automatic::Plugin
10
+ class Instapaper
11
+ # @see http://www.instapaper.com/api/simple
12
+ require "net/http"
13
+ require "openssl"
14
+
15
+ def initialize(username, password = '')
16
+ @username = username
17
+ @password = password
18
+ request(:authenticate)
19
+ end
20
+
21
+ def add(url, title = '', selection = '')
22
+ params = {
23
+ :url => url,
24
+ :title => title,
25
+ :selection => selection
26
+ }
27
+ res = request(:add, params)
28
+ if res.code == "201" then
29
+ message = "Success: #{url}"
30
+ message += " Title: #{title}" unless title.nil?
31
+ Automatic::Log.puts(:info, message)
32
+ else
33
+ Automatic::Log.puts(:error, "#{res.code} Error: #{url}")
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def request(method, params = {})
40
+ request = Net::HTTP::Post.new('/api/' + method.to_s)
41
+ request.basic_auth(@username, @password)
42
+ request.set_form_data(params)
43
+ http = Net::HTTP.new('www.instapaper.com', 443)
44
+ http.use_ssl = true
45
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
46
+ http.start { http.request(request) }
47
+ end
48
+ end
49
+
50
+ class PublishInstapaper
51
+
52
+ attr_accessor :instapaper
53
+
54
+ def initialize(config, pipeline=[])
55
+ @config = config
56
+ @pipeline = pipeline
57
+
58
+ @instapaper = Instapaper.new(
59
+ @config['email'],
60
+ @config['password']
61
+ )
62
+ end
63
+
64
+ def run
65
+ @pipeline.each {|feeds|
66
+ unless feeds.nil?
67
+ feeds.items.each {|feed|
68
+ Automatic::Log.puts("info", "add: #{feed.link}")
69
+ instapaper.add(feed.link, feed.title, feed.description)
70
+ sleep @config['interval'].to_i unless @config['interval'].nil?
71
+ }
72
+ end
73
+ }
74
+ @pipeline
75
+ end
76
+ end
77
+ end
@@ -3,7 +3,7 @@
3
3
  # Name:: Automatic::Plugin::Store::TargetLink
4
4
  # Author:: 774 <http://id774.net>
5
5
  # Created:: Feb 28, 2012
6
- # Updated:: Jan 8, 2013
6
+ # Updated:: Feb 9, 2013
7
7
  # Copyright:: 774 Copyright (c) 2012
8
8
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
9
9
 
@@ -32,11 +32,15 @@ module Automatic::Plugin
32
32
  feeds.items.each {|feed|
33
33
  unless feed.link.nil?
34
34
  Automatic::Log.puts("info", "Downloading: #{feed.link}")
35
+ retries = 0
35
36
  begin
37
+ retries += 1
36
38
  wget(feed.link)
37
39
  sleep @config['interval'].to_i unless @config['interval'].nil?
38
40
  rescue
39
- Automatic::Log.puts("error", "Error found during file download.")
41
+ Automatic::Log.puts("error", "ErrorCount: #{retries}, Fault during file download.")
42
+ sleep @config['interval'].to_i unless @config['interval'].nil?
43
+ retry if retries <= @config['retry'].to_i unless @config['retry'].nil?
40
44
  end
41
45
  end
42
46
  }
@@ -2,7 +2,7 @@
2
2
  # Name:: Automatic::Plugin::SubscriptionFeed
3
3
  # Author:: 774 <http://id774.net>
4
4
  # Created:: Feb 22, 2012
5
- # Updated:: Feb 24, 2012
5
+ # Updated:: Feb 8, 2013
6
6
  # Copyright:: 774 Copyright (c) 2012
7
7
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
8
 
@@ -15,11 +15,15 @@ module Automatic::Plugin
15
15
 
16
16
  def run
17
17
  @config['feeds'].each {|feed|
18
+ retries = 0
18
19
  begin
19
20
  rss = Automatic::FeedParser.get(feed)
20
21
  @pipeline << rss
21
22
  rescue
22
- Automatic::Log.puts("error", "Fault in parsing: #{feed}")
23
+ retries += 1
24
+ Automatic::Log.puts("error", "ErrorCount: #{retries}, Fault in parsing: #{feed}")
25
+ sleep @config['interval'].to_i unless @config['interval'].nil?
26
+ retry if retries <= @config['retry'].to_i unless @config['retry'].nil?
23
27
  end
24
28
  }
25
29
  @pipeline
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Name:: Automatic::Plugin::Subscription::GoogleReaderStar
3
+ # Author:: soramugi <http://soramugi.net>
4
+ # Created:: Feb 10, 2013
5
+ # Updated:: Feb 10, 2013
6
+ # Copyright:: soramugi Copyright (c) 2013
7
+ # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
+
9
+ module Automatic::Plugin
10
+ class SubscriptionGoogleReaderStar
11
+ require 'open-uri'
12
+ require 'nokogiri'
13
+ require 'rss'
14
+
15
+ def initialize(config, pipeline=[])
16
+ @config = config
17
+ @pipeline = pipeline
18
+ end
19
+
20
+ def run
21
+ @return_feeds = []
22
+ @config['feeds'].each {|feed|
23
+ begin
24
+ Automatic::Log.puts("info", "Parsing: #{feed}")
25
+ @return_feeds << self.parse(Automatic::FeedParser.get(feed).items)
26
+ rescue
27
+ Automatic::Log.puts("error", "Fault in parsing: #{feed}")
28
+ end
29
+ }
30
+ @return_feeds
31
+ end
32
+
33
+ def parse(feeds = [])
34
+ RSS::Maker.make("2.0") {|maker|
35
+ maker.xml_stylesheets.new_xml_stylesheet
36
+ maker.channel.title = "Automatic Ruby"
37
+ maker.channel.description = "Automatic Ruby"
38
+ maker.channel.link = "https://github.com/id774/automaticruby"
39
+ maker.items.do_sort = true
40
+
41
+ unless feeds.nil?
42
+ feeds.each {|feed|
43
+ unless feed.link.href.nil?
44
+ Automatic::Log.puts("info", "Creating: #{feed.link.href}")
45
+ item = maker.items.new_item
46
+ item.title = feed.title.content # google reader feed
47
+ item.link = feed.link.href # google reader feed
48
+ begin
49
+ item.description = feed.description
50
+ item.author = feed.author
51
+ item.comments = feed.comments
52
+ item.date = feed.pubDate || Time.now
53
+ rescue NoMethodError
54
+ Automatic::Log.puts("warn", "Undefined field detected in feed.")
55
+ end
56
+ end
57
+ }
58
+ end
59
+ }
60
+ end
61
+
62
+ end
63
+ end
@@ -2,7 +2,7 @@
2
2
  # Name:: Automatic::Plugin::Subscription::Link
3
3
  # Author:: 774 <http://id774.net>
4
4
  # Created:: Sep 18, 2012
5
- # Updated:: Jan 8, 2013
5
+ # Updated:: Feb 8, 2013
6
6
  # Copyright:: 774 Copyright (c) 2012
7
7
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
8
 
@@ -30,10 +30,14 @@ module Automatic::Plugin
30
30
  def run
31
31
  @return_feeds = []
32
32
  @config['urls'].each {|url|
33
+ retries = 0
33
34
  begin
34
35
  create_rss(url)
35
36
  rescue
36
- Automatic::Log.puts("error", "Fault in parsing: #{url}")
37
+ retries += 1
38
+ Automatic::Log.puts("error", "ErrorCount: #{retries}, Fault in parsing: #{url}")
39
+ sleep @config['interval'].to_i unless @config['interval'].nil?
40
+ retry if retries <= @config['retry'].to_i unless @config['retry'].nil?
37
41
  end
38
42
  }
39
43
  @return_feeds
@@ -2,7 +2,7 @@
2
2
  # Name:: Automatic::Plugin::Subscription::Tumblr
3
3
  # Author:: 774 <http://id774.net>
4
4
  # Created:: Oct 16, 2012
5
- # Updated:: Jan 8, 2013
5
+ # Updated:: Feb 8, 2013
6
6
  # Copyright:: 774 Copyright (c) 2012
7
7
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
8
 
@@ -28,18 +28,22 @@ module Automatic::Plugin
28
28
  def run
29
29
  @return_feeds = []
30
30
  @config['urls'].each {|url|
31
+ retries = 0
31
32
  begin
32
33
  create_rss(url)
33
- unless @config['pages'].nil?
34
- @config['pages'].times {|i|
35
- if i > 0
36
- old_url = url + "/page/" + (i+1).to_s
37
- create_rss(old_url)
38
- end
39
- }
40
- end
34
+ unless @config['pages'].nil?
35
+ @config['pages'].times {|i|
36
+ if i > 0
37
+ old_url = url + "/page/" + (i+1).to_s
38
+ create_rss(old_url)
39
+ end
40
+ }
41
+ end
41
42
  rescue
42
- Automatic::Log.puts("error", "Fault in parsing: #{url}")
43
+ retries += 1
44
+ Automatic::Log.puts("error", "ErrorCount: #{retries}, Fault in parsing: #{url}")
45
+ sleep @config['interval'].to_i unless @config['interval'].nil?
46
+ retry if retries <= @config['retry'].to_i unless @config['retry'].nil?
43
47
  end
44
48
  }
45
49
  @return_feeds
@@ -2,7 +2,7 @@
2
2
  # Name:: Automatic::Plugin::Subscription::Twitter
3
3
  # Author:: 774 <http://id774.net>
4
4
  # Created:: Sep 9, 2012
5
- # Updated:: Jan 8, 2013
5
+ # Updated:: Feb 8, 2013
6
6
  # Copyright:: 774 Copyright (c) 2012
7
7
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
8
 
@@ -50,10 +50,14 @@ module Automatic::Plugin
50
50
  def run
51
51
  @return_feeds = []
52
52
  @config['urls'].each {|url|
53
+ retries = 0
53
54
  begin
54
55
  create_rss(url)
55
56
  rescue
56
- Automatic::Log.puts("error", "Fault in parsing: #{url}")
57
+ retries += 1
58
+ Automatic::Log.puts("error", "ErrorCount: #{retries}, Fault in parsing: #{url}")
59
+ sleep @config['interval'].to_i unless @config['interval'].nil?
60
+ retry if retries <= @config['retry'].to_i unless @config['retry'].nil?
57
61
  end
58
62
  }
59
63
  @return_feeds
@@ -3,7 +3,7 @@
3
3
  # Author:: kzgs
4
4
  # 774 <http://id774.net>
5
5
  # Created:: Mar 9, 2012
6
- # Updated:: Jan 8, 2013
6
+ # Updated:: Feb 13, 2013
7
7
  # Copyright:: kzgs Copyright (c) 2012
8
8
  # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
9
9
 
@@ -26,7 +26,7 @@ describe Automatic do
26
26
 
27
27
  describe "#version" do
28
28
  specify {
29
- Automatic.const_get(:VERSION).should == "13.1.0"
29
+ Automatic.const_get(:VERSION).should == "13.2.0"
30
30
  }
31
31
  end
32
32
 
@@ -0,0 +1,48 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Name:: Automatic::Plugin::Filter::FullFeed
3
+ # Author:: 774 <http://id774.net>
4
+ # Created:: Jan 24, 2013
5
+ # Updated:: Jan 24, 2013
6
+ # Copyright:: 774 Copyright (c) 2013
7
+ # License:: Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.0.
8
+
9
+ require File.expand_path(File.dirname(__FILE__) + '../../../spec_helper')
10
+
11
+ require 'filter/full_feed'
12
+
13
+ describe Automatic::Plugin::FilterFullFeed do
14
+ context "It should be asc sorted" do
15
+ subject {
16
+ Automatic::Plugin::FilterFullFeed.new(
17
+ {
18
+ 'siteinfo' => "items_all.json"
19
+ },
20
+ AutomaticSpec.generate_pipeline {
21
+ feed {
22
+ item "http://matome.naver.jp/odai/2129948007339738701/2129948085139809603", "",
23
+ "",
24
+ "Mon, 07 Mar 2011 15:54:11 +0900"
25
+ }})}
26
+
27
+ describe "#run" do
28
+ its(:run) { should have(1).feeds }
29
+
30
+ specify {
31
+ subject.instance_variable_get(:@pipeline)[0].items[0].link.
32
+ should == "http://matome.naver.jp/odai/2129948007339738701/2129948085139809603"
33
+ subject.instance_variable_get(:@pipeline)[0].items[0].description.
34
+ should == ""
35
+
36
+ subject.run
37
+
38
+ subject.instance_variable_get(:@pipeline)[0].items[0].link.
39
+ should == "http://matome.naver.jp/odai/2129948007339738701/2129948085139809603"
40
+ subject.instance_variable_get(:@pipeline)[0].items[0].description.
41
+ should ==
42
+ "<div class=\"LyMain\" role=\"main\" data-na=\"NA:main\">\r\n\t<div class=\"ArMain02\" data-na=\"NA:comment\">\r\n\r\n\r\n<script>\r\nvar COMMENT_TARGET_ID = \"PSImipbkFp746BTYcGvB8iizlwODIqiioNZ\";\r\nvar COMMENT_TYPE_CODE = \"R\";\r\nvar COMMENT_ITEM_TOTAL = 0;\r\n</script><a name=\"comment\"></a>\r\n<div id=\"ancMTMComment\" class=\"MdMTMComment01\">\r\n\r\n\t<h2 class=\"mdMTMComment01Ttl\">このまとめへのコメント<span class=\"mdMTMComment01CounterWrap\">(<span class=\"mdMTMComment01Counter\">0</span>)</span>\n</h2>\r\n\r\n\t<div class=\"MdCommentForm01\">\r\n\t<p class=\"mdCommentForm01Input\"><textarea class=\"mdCommentForm01InputTxt\" placeholder=\"追加するコメントを入力\"></textarea></p>\r\n\t<p class=\"mdCommentForm01Btn\"><span class=\"MdBtn01Post01\"><input type=\"button\" value=\"書き込む\" class=\"mdBtn01Post01Btn\" data-na=\"NC:save\"></span></p>\r\n\t</div>\r\n\r\n\t<ul class=\"MdCommentList01\"><!-- /.MdCommentList01 --></ul>\n<div class=\"MdPagination04\" data-na=\"NA:pager\">\r\n\r\n\r\n\r\n\t\t<strong>1</strong>\r\n<!--/MdPagination04-->\n</div>\r\n\r\n<script type=\"text/javascript\">\r\n$(function() {\r\n nj.Bootloader.done(\"nj.matome.comment\", function() {\r\n var cl = $(\"ul.MdCommentList01\").mtmCommentSet({\"encryptId\" : COMMENT_TARGET_ID, \"typeCode\": COMMENT_TYPE_CODE});\r\n $(\".MdPagination04\").njPageNavi({\"item\":0,\"onClickEvent\" : function(e, n){cl.mtmCommentSet(\"setArgs\",{\"page\":n});cl.mtmCommentSet(\"getComment\");}});\r\n });\r\n});\r\n</script><!--/.MdMTMComment01-->\n</div>\r\n\t<!--/ArMain02-->\n</div>\r\n<!--/LyMain-->\n</div>"
43
+
44
+ }
45
+ end
46
+ end
47
+
48
+ end