sum 0.1.1 → 0.1.2

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 (228) hide show
  1. data/README.markdown +10 -12
  2. data/Rakefile +6 -7
  3. data/config/externals.yml +3 -3
  4. data/config/schedule.rb +0 -1
  5. data/features/step_definitions/when.rb +3 -3
  6. data/features/support/env.rb +9 -10
  7. data/gemspec.rb +13 -14
  8. data/lib/sum.rb +8 -8
  9. data/lib/sum/helper/cron.rb +1 -1
  10. data/lib/sum/model/user.rb +3 -3
  11. data/vendor/fetcher/MIT-LICENSE +20 -0
  12. data/vendor/fetcher/README.rdoc +94 -0
  13. data/vendor/fetcher/Rakefile +30 -0
  14. data/vendor/fetcher/fetcher.gemspec +27 -0
  15. data/vendor/fetcher/gemspec.rb +17 -0
  16. data/vendor/fetcher/init.rb +0 -0
  17. data/vendor/fetcher/lib/fetcher.rb +23 -0
  18. data/vendor/fetcher/lib/fetcher/base.rb +63 -0
  19. data/vendor/fetcher/lib/fetcher/imap.rb +79 -0
  20. data/vendor/fetcher/lib/fetcher/pop.rb +50 -0
  21. data/vendor/fetcher/lib/vendor/plain_imap.rb +21 -0
  22. data/vendor/fetcher/lib/vendor/secure_pop.rb +125 -0
  23. data/vendor/fetcher/test/fetcher_test.rb +74 -0
  24. metadata +40 -241
  25. data/sum.gemspec +0 -69
  26. data/vendor/webrat/History.txt +0 -358
  27. data/vendor/webrat/MIT-LICENSE.txt +0 -19
  28. data/vendor/webrat/README.rdoc +0 -85
  29. data/vendor/webrat/Rakefile +0 -200
  30. data/vendor/webrat/install.rb +0 -1
  31. data/vendor/webrat/lib/webrat.rb +0 -31
  32. data/vendor/webrat/lib/webrat/core.rb +0 -14
  33. data/vendor/webrat/lib/webrat/core/configuration.rb +0 -102
  34. data/vendor/webrat/lib/webrat/core/elements/area.rb +0 -31
  35. data/vendor/webrat/lib/webrat/core/elements/element.rb +0 -33
  36. data/vendor/webrat/lib/webrat/core/elements/field.rb +0 -409
  37. data/vendor/webrat/lib/webrat/core/elements/form.rb +0 -103
  38. data/vendor/webrat/lib/webrat/core/elements/label.rb +0 -31
  39. data/vendor/webrat/lib/webrat/core/elements/link.rb +0 -93
  40. data/vendor/webrat/lib/webrat/core/elements/select_option.rb +0 -35
  41. data/vendor/webrat/lib/webrat/core/locators.rb +0 -20
  42. data/vendor/webrat/lib/webrat/core/locators/area_locator.rb +0 -38
  43. data/vendor/webrat/lib/webrat/core/locators/button_locator.rb +0 -54
  44. data/vendor/webrat/lib/webrat/core/locators/field_by_id_locator.rb +0 -37
  45. data/vendor/webrat/lib/webrat/core/locators/field_labeled_locator.rb +0 -56
  46. data/vendor/webrat/lib/webrat/core/locators/field_locator.rb +0 -25
  47. data/vendor/webrat/lib/webrat/core/locators/field_named_locator.rb +0 -41
  48. data/vendor/webrat/lib/webrat/core/locators/form_locator.rb +0 -19
  49. data/vendor/webrat/lib/webrat/core/locators/label_locator.rb +0 -34
  50. data/vendor/webrat/lib/webrat/core/locators/link_locator.rb +0 -74
  51. data/vendor/webrat/lib/webrat/core/locators/locator.rb +0 -20
  52. data/vendor/webrat/lib/webrat/core/locators/select_option_locator.rb +0 -59
  53. data/vendor/webrat/lib/webrat/core/logging.rb +0 -24
  54. data/vendor/webrat/lib/webrat/core/matchers.rb +0 -4
  55. data/vendor/webrat/lib/webrat/core/matchers/have_content.rb +0 -73
  56. data/vendor/webrat/lib/webrat/core/matchers/have_selector.rb +0 -74
  57. data/vendor/webrat/lib/webrat/core/matchers/have_tag.rb +0 -21
  58. data/vendor/webrat/lib/webrat/core/matchers/have_xpath.rb +0 -147
  59. data/vendor/webrat/lib/webrat/core/methods.rb +0 -63
  60. data/vendor/webrat/lib/webrat/core/mime.rb +0 -29
  61. data/vendor/webrat/lib/webrat/core/save_and_open_page.rb +0 -48
  62. data/vendor/webrat/lib/webrat/core/scope.rb +0 -350
  63. data/vendor/webrat/lib/webrat/core/session.rb +0 -299
  64. data/vendor/webrat/lib/webrat/core/xml.rb +0 -115
  65. data/vendor/webrat/lib/webrat/core/xml/hpricot.rb +0 -19
  66. data/vendor/webrat/lib/webrat/core/xml/nokogiri.rb +0 -76
  67. data/vendor/webrat/lib/webrat/core/xml/rexml.rb +0 -24
  68. data/vendor/webrat/lib/webrat/core_extensions/blank.rb +0 -58
  69. data/vendor/webrat/lib/webrat/core_extensions/deprecate.rb +0 -8
  70. data/vendor/webrat/lib/webrat/core_extensions/detect_mapped.rb +0 -12
  71. data/vendor/webrat/lib/webrat/core_extensions/meta_class.rb +0 -6
  72. data/vendor/webrat/lib/webrat/core_extensions/nil_to_param.rb +0 -5
  73. data/vendor/webrat/lib/webrat/core_extensions/tcp_socket.rb +0 -27
  74. data/vendor/webrat/lib/webrat/mechanize.rb +0 -74
  75. data/vendor/webrat/lib/webrat/merb.rb +0 -9
  76. data/vendor/webrat/lib/webrat/merb_multipart_support.rb +0 -27
  77. data/vendor/webrat/lib/webrat/merb_session.rb +0 -82
  78. data/vendor/webrat/lib/webrat/rack.rb +0 -25
  79. data/vendor/webrat/lib/webrat/rails.rb +0 -106
  80. data/vendor/webrat/lib/webrat/rspec-rails.rb +0 -10
  81. data/vendor/webrat/lib/webrat/selenium.rb +0 -81
  82. data/vendor/webrat/lib/webrat/selenium/application_server_factory.rb +0 -40
  83. data/vendor/webrat/lib/webrat/selenium/application_servers.rb +0 -5
  84. data/vendor/webrat/lib/webrat/selenium/application_servers/base.rb +0 -46
  85. data/vendor/webrat/lib/webrat/selenium/application_servers/external.rb +0 -26
  86. data/vendor/webrat/lib/webrat/selenium/application_servers/merb.rb +0 -50
  87. data/vendor/webrat/lib/webrat/selenium/application_servers/rails.rb +0 -44
  88. data/vendor/webrat/lib/webrat/selenium/application_servers/sinatra.rb +0 -37
  89. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/button.js +0 -19
  90. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/label.js +0 -16
  91. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webrat.js +0 -5
  92. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratlink.js +0 -12
  93. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +0 -15
  94. data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +0 -5
  95. data/vendor/webrat/lib/webrat/selenium/matchers.rb +0 -4
  96. data/vendor/webrat/lib/webrat/selenium/matchers/have_content.rb +0 -66
  97. data/vendor/webrat/lib/webrat/selenium/matchers/have_selector.rb +0 -49
  98. data/vendor/webrat/lib/webrat/selenium/matchers/have_tag.rb +0 -72
  99. data/vendor/webrat/lib/webrat/selenium/matchers/have_xpath.rb +0 -45
  100. data/vendor/webrat/lib/webrat/selenium/selenium_extensions.js +0 -6
  101. data/vendor/webrat/lib/webrat/selenium/selenium_rc_server.rb +0 -84
  102. data/vendor/webrat/lib/webrat/selenium/selenium_session.rb +0 -248
  103. data/vendor/webrat/lib/webrat/selenium/silence_stream.rb +0 -18
  104. data/vendor/webrat/lib/webrat/sinatra.rb +0 -11
  105. data/vendor/webrat/spec/fakes/test_session.rb +0 -34
  106. data/vendor/webrat/spec/integration/merb/Rakefile +0 -35
  107. data/vendor/webrat/spec/integration/merb/app/controllers/application.rb +0 -2
  108. data/vendor/webrat/spec/integration/merb/app/controllers/exceptions.rb +0 -13
  109. data/vendor/webrat/spec/integration/merb/app/controllers/testing.rb +0 -27
  110. data/vendor/webrat/spec/integration/merb/app/views/exceptions/not_acceptable.html.erb +0 -63
  111. data/vendor/webrat/spec/integration/merb/app/views/exceptions/not_found.html.erb +0 -47
  112. data/vendor/webrat/spec/integration/merb/app/views/layout/application.html.erb +0 -12
  113. data/vendor/webrat/spec/integration/merb/app/views/testing/show_form.html.erb +0 -27
  114. data/vendor/webrat/spec/integration/merb/app/views/testing/upload.html.erb +0 -9
  115. data/vendor/webrat/spec/integration/merb/config/environments/development.rb +0 -15
  116. data/vendor/webrat/spec/integration/merb/config/environments/rake.rb +0 -11
  117. data/vendor/webrat/spec/integration/merb/config/environments/test.rb +0 -14
  118. data/vendor/webrat/spec/integration/merb/config/init.rb +0 -25
  119. data/vendor/webrat/spec/integration/merb/config/rack.rb +0 -11
  120. data/vendor/webrat/spec/integration/merb/config/router.rb +0 -34
  121. data/vendor/webrat/spec/integration/merb/spec/spec.opts +0 -1
  122. data/vendor/webrat/spec/integration/merb/spec/spec_helper.rb +0 -24
  123. data/vendor/webrat/spec/integration/merb/spec/webrat_spec.rb +0 -39
  124. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/app_script.rb +0 -31
  125. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/common.rb +0 -64
  126. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/gem_ext.rb +0 -124
  127. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/main.thor +0 -150
  128. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/ops.rb +0 -93
  129. data/vendor/webrat/spec/integration/merb/tasks/merb.thor/utils.rb +0 -40
  130. data/vendor/webrat/spec/integration/rack/Rakefile +0 -5
  131. data/vendor/webrat/spec/integration/rack/app.rb +0 -73
  132. data/vendor/webrat/spec/integration/rack/test/helper.rb +0 -20
  133. data/vendor/webrat/spec/integration/rack/test/webrat_rack_test.rb +0 -62
  134. data/vendor/webrat/spec/integration/rails/Rakefile +0 -30
  135. data/vendor/webrat/spec/integration/rails/app/controllers/application.rb +0 -15
  136. data/vendor/webrat/spec/integration/rails/app/controllers/buttons_controller.rb +0 -7
  137. data/vendor/webrat/spec/integration/rails/app/controllers/fields_controller.rb +0 -4
  138. data/vendor/webrat/spec/integration/rails/app/controllers/links_controller.rb +0 -7
  139. data/vendor/webrat/spec/integration/rails/app/controllers/webrat_controller.rb +0 -43
  140. data/vendor/webrat/spec/integration/rails/app/helpers/buttons_helper.rb +0 -2
  141. data/vendor/webrat/spec/integration/rails/app/helpers/fields_helper.rb +0 -2
  142. data/vendor/webrat/spec/integration/rails/app/helpers/links_helper.rb +0 -2
  143. data/vendor/webrat/spec/integration/rails/app/views/buttons/show.html.erb +0 -11
  144. data/vendor/webrat/spec/integration/rails/app/views/fields/show.html.erb +0 -9
  145. data/vendor/webrat/spec/integration/rails/app/views/links/show.html.erb +0 -5
  146. data/vendor/webrat/spec/integration/rails/app/views/webrat/before_redirect_form.html.erb +0 -4
  147. data/vendor/webrat/spec/integration/rails/app/views/webrat/buttons.html.erb +0 -11
  148. data/vendor/webrat/spec/integration/rails/app/views/webrat/form.html.erb +0 -28
  149. data/vendor/webrat/spec/integration/rails/config/boot.rb +0 -109
  150. data/vendor/webrat/spec/integration/rails/config/environment.rb +0 -12
  151. data/vendor/webrat/spec/integration/rails/config/environments/development.rb +0 -17
  152. data/vendor/webrat/spec/integration/rails/config/environments/selenium.rb +0 -22
  153. data/vendor/webrat/spec/integration/rails/config/environments/test.rb +0 -22
  154. data/vendor/webrat/spec/integration/rails/config/initializers/inflections.rb +0 -10
  155. data/vendor/webrat/spec/integration/rails/config/initializers/mime_types.rb +0 -5
  156. data/vendor/webrat/spec/integration/rails/config/initializers/new_rails_defaults.rb +0 -17
  157. data/vendor/webrat/spec/integration/rails/config/locales/en.yml +0 -5
  158. data/vendor/webrat/spec/integration/rails/config/routes.rb +0 -18
  159. data/vendor/webrat/spec/integration/rails/public/404.html +0 -30
  160. data/vendor/webrat/spec/integration/rails/public/422.html +0 -30
  161. data/vendor/webrat/spec/integration/rails/public/500.html +0 -33
  162. data/vendor/webrat/spec/integration/rails/script/about +0 -4
  163. data/vendor/webrat/spec/integration/rails/script/console +0 -3
  164. data/vendor/webrat/spec/integration/rails/script/dbconsole +0 -3
  165. data/vendor/webrat/spec/integration/rails/script/destroy +0 -3
  166. data/vendor/webrat/spec/integration/rails/script/generate +0 -3
  167. data/vendor/webrat/spec/integration/rails/script/performance/benchmarker +0 -3
  168. data/vendor/webrat/spec/integration/rails/script/performance/profiler +0 -3
  169. data/vendor/webrat/spec/integration/rails/script/performance/request +0 -3
  170. data/vendor/webrat/spec/integration/rails/script/plugin +0 -3
  171. data/vendor/webrat/spec/integration/rails/script/process/inspector +0 -3
  172. data/vendor/webrat/spec/integration/rails/script/process/reaper +0 -3
  173. data/vendor/webrat/spec/integration/rails/script/process/spawner +0 -3
  174. data/vendor/webrat/spec/integration/rails/script/runner +0 -3
  175. data/vendor/webrat/spec/integration/rails/script/server +0 -3
  176. data/vendor/webrat/spec/integration/rails/test/integration/button_click_test.rb +0 -80
  177. data/vendor/webrat/spec/integration/rails/test/integration/fill_in_test.rb +0 -24
  178. data/vendor/webrat/spec/integration/rails/test/integration/link_click_test.rb +0 -27
  179. data/vendor/webrat/spec/integration/rails/test/integration/webrat_test.rb +0 -97
  180. data/vendor/webrat/spec/integration/rails/test/test_helper.rb +0 -25
  181. data/vendor/webrat/spec/integration/sinatra/Rakefile +0 -5
  182. data/vendor/webrat/spec/integration/sinatra/classic_app.rb +0 -64
  183. data/vendor/webrat/spec/integration/sinatra/modular_app.rb +0 -16
  184. data/vendor/webrat/spec/integration/sinatra/test/classic_app_test.rb +0 -37
  185. data/vendor/webrat/spec/integration/sinatra/test/modular_app_test.rb +0 -18
  186. data/vendor/webrat/spec/integration/sinatra/test/test_helper.rb +0 -16
  187. data/vendor/webrat/spec/private/core/configuration_spec.rb +0 -116
  188. data/vendor/webrat/spec/private/core/field_spec.rb +0 -85
  189. data/vendor/webrat/spec/private/core/link_spec.rb +0 -24
  190. data/vendor/webrat/spec/private/core/logging_spec.rb +0 -10
  191. data/vendor/webrat/spec/private/core/session_spec.rb +0 -195
  192. data/vendor/webrat/spec/private/mechanize/mechanize_session_spec.rb +0 -81
  193. data/vendor/webrat/spec/private/merb/attaches_file_spec.rb +0 -93
  194. data/vendor/webrat/spec/private/merb/merb_session_spec.rb +0 -61
  195. data/vendor/webrat/spec/private/nokogiri_spec.rb +0 -77
  196. data/vendor/webrat/spec/private/rails/attaches_file_spec.rb +0 -81
  197. data/vendor/webrat/spec/private/rails/rails_session_spec.rb +0 -112
  198. data/vendor/webrat/spec/private/selenium/application_servers/rails_spec.rb +0 -26
  199. data/vendor/webrat/spec/public/basic_auth_spec.rb +0 -24
  200. data/vendor/webrat/spec/public/check_spec.rb +0 -191
  201. data/vendor/webrat/spec/public/choose_spec.rb +0 -118
  202. data/vendor/webrat/spec/public/click_area_spec.rb +0 -106
  203. data/vendor/webrat/spec/public/click_button_spec.rb +0 -496
  204. data/vendor/webrat/spec/public/click_link_spec.rb +0 -511
  205. data/vendor/webrat/spec/public/fill_in_spec.rb +0 -209
  206. data/vendor/webrat/spec/public/locators/field_by_xpath_spec.rb +0 -19
  207. data/vendor/webrat/spec/public/locators/field_labeled_spec.rb +0 -172
  208. data/vendor/webrat/spec/public/locators/field_with_id_spec.rb +0 -16
  209. data/vendor/webrat/spec/public/matchers/contain_spec.rb +0 -114
  210. data/vendor/webrat/spec/public/matchers/have_selector_spec.rb +0 -142
  211. data/vendor/webrat/spec/public/matchers/have_tag_spec.rb +0 -39
  212. data/vendor/webrat/spec/public/matchers/have_xpath_spec.rb +0 -136
  213. data/vendor/webrat/spec/public/reload_spec.rb +0 -10
  214. data/vendor/webrat/spec/public/save_and_open_spec.rb +0 -70
  215. data/vendor/webrat/spec/public/select_date_spec.rb +0 -112
  216. data/vendor/webrat/spec/public/select_datetime_spec.rb +0 -137
  217. data/vendor/webrat/spec/public/select_spec.rb +0 -249
  218. data/vendor/webrat/spec/public/select_time_spec.rb +0 -100
  219. data/vendor/webrat/spec/public/selenium/application_server_factory_spec.rb +0 -49
  220. data/vendor/webrat/spec/public/selenium/application_servers/external_spec.rb +0 -12
  221. data/vendor/webrat/spec/public/selenium/selenium_session_spec.rb +0 -37
  222. data/vendor/webrat/spec/public/set_hidden_field_spec.rb +0 -5
  223. data/vendor/webrat/spec/public/submit_form_spec.rb +0 -5
  224. data/vendor/webrat/spec/public/visit_spec.rb +0 -58
  225. data/vendor/webrat/spec/public/within_spec.rb +0 -177
  226. data/vendor/webrat/spec/rcov.opts +0 -1
  227. data/vendor/webrat/spec/spec.opts +0 -2
  228. data/vendor/webrat/spec/spec_helper.rb +0 -50
@@ -0,0 +1,17 @@
1
+ GEM_NAME = 'fetcher'
2
+ GEM_FILES = FileList['**/*'] - FileList['coverage', 'coverage/**/*', 'pkg', 'pkg/**/*']
3
+ GEM_SPEC = Gem::Specification.new do |s|
4
+ # == CONFIGURE ==
5
+ s.author = "Luke Francl"
6
+ s.email = "look@recursion.org"
7
+ s.homepage = "http://github.com/winton/#{GEM_NAME}"
8
+ s.summary = "download email from POP3 or IMAP and do stuff with it. gemified fork"
9
+ # == CONFIGURE ==
10
+ s.extra_rdoc_files = [ "README.rdoc" ]
11
+ s.files = GEM_FILES.to_a
12
+ s.has_rdoc = false
13
+ s.name = GEM_NAME
14
+ s.platform = Gem::Platform::RUBY
15
+ s.require_path = "lib"
16
+ s.version = "0.1.2"
17
+ end
File without changes
@@ -0,0 +1,23 @@
1
+ module Fetcher
2
+ # Use factory-style initialization or insantiate directly from a subclass
3
+ #
4
+ # Options:
5
+ # * <tt>:type</tt> - Name of class as a symbol to instantiate
6
+ #
7
+ # Other options are the same as Fetcher::Base.new
8
+ #
9
+ # Example:
10
+ #
11
+ # Fetcher.create(:type => :pop) is equivalent to
12
+ # Fetcher::Pop.new()
13
+ def self.create(options={})
14
+ options = options.dup
15
+ klass = options.delete(:type)
16
+ raise ArgumentError, 'Must supply a type' unless klass
17
+ module_eval "#{klass.to_s.capitalize}.new(options)"
18
+ end
19
+ end
20
+
21
+ require 'fetcher/base'
22
+ require 'fetcher/pop'
23
+ require 'fetcher/imap'
@@ -0,0 +1,63 @@
1
+ module Fetcher
2
+ class Base
3
+ # Options:
4
+ # * <tt>:server</tt> - Server to connect to.
5
+ # * <tt>:username</tt> - Username to use when connecting to server.
6
+ # * <tt>:password</tt> - Password to use when connecting to server.
7
+ # * <tt>:receiver</tt> - Receiver object to pass messages to. Assumes the
8
+ # receiver object has a receive method that takes a message as it's argument
9
+ #
10
+ # Additional protocol-specific options implimented by sub-classes
11
+ #
12
+ # Example:
13
+ # Fetcher::Base.new(:server => 'mail.example.com',
14
+ # :username => 'pam',
15
+ # :password => 'test',
16
+ # :receiver => IncomingMailHandler)
17
+ def initialize(options={})
18
+ %w(server username password receiver).each do |opt|
19
+ raise ArgumentError, "#{opt} is required" unless options[opt.to_sym]
20
+ # convert receiver to a Class if it isn't already.
21
+ if opt == "receiver" && options[:receiver].is_a?(String)
22
+ options[:receiver] = Kernel.const_get(options[:receiver])
23
+ end
24
+
25
+ instance_eval("@#{opt} = options[:#{opt}]")
26
+ end
27
+ end
28
+
29
+ # Run the fetching process
30
+ def fetch
31
+ establish_connection
32
+ get_messages
33
+ close_connection
34
+ end
35
+
36
+ protected
37
+
38
+ # Stub. Should be overridden by subclass.
39
+ def establish_connection #:nodoc:
40
+ raise NotImplementedError, "This method should be overridden by subclass"
41
+ end
42
+
43
+ # Stub. Should be overridden by subclass.
44
+ def get_messages #:nodoc:
45
+ raise NotImplementedError, "This method should be overridden by subclass"
46
+ end
47
+
48
+ # Stub. Should be overridden by subclass.
49
+ def close_connection #:nodoc:
50
+ raise NotImplementedError, "This method should be overridden by subclass"
51
+ end
52
+
53
+ # Send message to receiver object
54
+ def process_message(message)
55
+ @receiver.receive(message)
56
+ end
57
+
58
+ # Stub. Should be overridden by subclass.
59
+ def handle_bogus_message(message) #:nodoc:
60
+ raise NotImplementedError, "This method should be overridden by subclass"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,79 @@
1
+ require File.dirname(__FILE__) + '/../vendor/plain_imap'
2
+
3
+ module Fetcher
4
+ class Imap < Base
5
+
6
+ PORT = 143
7
+
8
+ protected
9
+
10
+ # Additional Options:
11
+ # * <tt>:authentication</tt> - authentication type to use, defaults to PLAIN
12
+ # * <tt>:port</tt> - port to use (defaults to 143)
13
+ # * <tt>:ssl</tt> - use SSL to connect
14
+ # * <tt>:use_login</tt> - use LOGIN instead of AUTHENTICATE to connect (some IMAP servers, like GMail, do not support AUTHENTICATE)
15
+ # * <tt>:processed_folder</tt> - if set to the name of a mailbox, messages will be moved to that mailbox instead of deleted after processing. The mailbox will be created if it does not exist.
16
+ # * <tt>:error_folder:</tt> - the name of a mailbox where messages that cannot be processed (i.e., your receiver throws an exception) will be moved. Defaults to "bogus". The mailbox will be created if it does not exist.
17
+ def initialize(options={})
18
+ @authentication = options.delete(:authentication) || 'PLAIN'
19
+ @port = options.delete(:port) || PORT
20
+ @ssl = options.delete(:ssl)
21
+ @use_login = options.delete(:use_login)
22
+ @processed_folder = options.delete(:processed_folder)
23
+ @error_folder = options.delete(:error_folder) || 'bogus'
24
+ super(options)
25
+ end
26
+
27
+ # Open connection and login to server
28
+ def establish_connection
29
+ @connection = Net::IMAP.new(@server, @port, @ssl)
30
+ if @use_login
31
+ @connection.login(@username, @password)
32
+ else
33
+ @connection.authenticate(@authentication, @username, @password)
34
+ end
35
+ end
36
+
37
+ # Retrieve messages from server
38
+ def get_messages
39
+ @connection.select('INBOX')
40
+ @connection.uid_search(['ALL']).each do |uid|
41
+ msg = @connection.uid_fetch(uid,'RFC822').first.attr['RFC822']
42
+ begin
43
+ process_message(msg)
44
+ add_to_processed_folder(uid) if @processed_folder
45
+ rescue
46
+ handle_bogus_message(msg)
47
+ end
48
+ # Mark message as deleted
49
+ @connection.uid_store(uid, "+FLAGS", [:Seen, :Deleted])
50
+ end
51
+ end
52
+
53
+ # Store the message for inspection if the receiver errors
54
+ def handle_bogus_message(message)
55
+ create_mailbox(@error_folder)
56
+ @connection.append(@error_folder, message)
57
+ end
58
+
59
+ # Delete messages and log out
60
+ def close_connection
61
+ @connection.expunge
62
+ @connection.logout
63
+ @connection.disconnect
64
+ rescue
65
+ end
66
+
67
+ def add_to_processed_folder(uid)
68
+ create_mailbox(@processed_folder)
69
+ @connection.uid_copy(uid, @processed_folder)
70
+ end
71
+
72
+ def create_mailbox(mailbox)
73
+ unless @connection.list("", mailbox)
74
+ @connection.create(mailbox)
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/../vendor/secure_pop'
2
+
3
+ module Fetcher
4
+ class Pop < Base
5
+
6
+ protected
7
+
8
+ # Additional Options:
9
+ # * <tt>:ssl</tt> - whether or not to use ssl encryption
10
+ # * <tt>:port</tt> - port to use (defaults to 110)
11
+ def initialize(options={})
12
+ @ssl = options.delete(:ssl)
13
+ @port = options.delete(:port) || Net::POP3.default_port
14
+ super(options)
15
+ end
16
+
17
+ # Open connection and login to server
18
+ def establish_connection
19
+ @connection = Net::POP3.new(@server, @port)
20
+ @connection.enable_ssl(OpenSSL::SSL::VERIFY_NONE) if @ssl
21
+ @connection.start(@username, @password)
22
+ end
23
+
24
+ # Retrieve messages from server
25
+ def get_messages
26
+ unless @connection.mails.empty?
27
+ @connection.each_mail do |msg|
28
+ begin
29
+ process_message(msg.pop)
30
+ rescue
31
+ handle_bogus_message(msg.pop)
32
+ end
33
+ # Delete message from server
34
+ msg.delete
35
+ end
36
+ end
37
+ end
38
+
39
+ # Store the message for inspection if the receiver errors
40
+ def handle_bogus_message(message)
41
+ # This needs a good solution
42
+ end
43
+
44
+ # Close connection to server
45
+ def close_connection
46
+ @connection.finish
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,21 @@
1
+ require 'net/imap'
2
+ # add plain as an authentication type...
3
+ # This is taken from:
4
+ # http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/net/imap.rb?revision=7657&view=markup&pathrev=10966
5
+
6
+ # Authenticator for the "PLAIN" authentication type. See
7
+ # #authenticate().
8
+ class PlainAuthenticator
9
+ def process(data)
10
+ return "\0#{@user}\0#{@password}"
11
+ end
12
+
13
+ private
14
+
15
+ def initialize(user, password)
16
+ @user = user
17
+ @password = password
18
+ end
19
+ end
20
+
21
+ Net::IMAP.add_authenticator "PLAIN", PlainAuthenticator
@@ -0,0 +1,125 @@
1
+ require 'socket'
2
+ require 'net/pop'
3
+ require 'net/protocol'
4
+ require 'openssl/ssl'
5
+
6
+ # Backport of ruby 1.9's POP3 SSL support
7
+ class Net::POP3
8
+ @@usessl = nil
9
+ @@verify = nil
10
+ @@certs = nil
11
+ PORT = 110
12
+ SSL_PORT = 995
13
+
14
+ def self.default_port
15
+ PORT
16
+ end
17
+
18
+ def self.default_ssl_port
19
+ SSL_PORT
20
+ end
21
+
22
+ # Enable SSL for all new instances.
23
+ # +verify+ is the type of verification to do on the Server Cert; Defaults
24
+ # to OpenSSL::SSL::VERIFY_PEER.
25
+ # +certs+ is a file or directory holding CA certs to use to verify the
26
+ # server cert; Defaults to nil.
27
+ def self.enable_ssl( verify = OpenSSL::SSL::VERIFY_PEER, certs = nil )
28
+ @@usessl = true
29
+ @@verify = verify
30
+ @@certs = certs
31
+ end
32
+
33
+ # Disable SSL for all new instances.
34
+ def self.disable_ssl
35
+ @@usessl = nil
36
+ @@verify = nil
37
+ @@certs = nil
38
+ end
39
+
40
+ # Creates a new POP3 object.
41
+ # +addr+ is the hostname or ip address of your POP3 server.
42
+ # The optional +port+ is the port to connect to.
43
+ # The optional +isapop+ specifies whether this connection is going
44
+ # to use APOP authentication; it defaults to +false+.
45
+ # This method does *not* open the TCP connection.
46
+ def initialize(addr, port = nil, isapop = false)
47
+ @address = addr
48
+ @usessl = @@usessl
49
+ if @usessl
50
+ @port = port || SSL_PORT
51
+ else
52
+ @port = port || PORT
53
+ end
54
+ @apop = isapop
55
+
56
+ @certs = @@certs
57
+ @verify = @@verify
58
+
59
+ @command = nil
60
+ @socket = nil
61
+ @started = false
62
+ @open_timeout = 30
63
+ @read_timeout = 60
64
+ @debug_output = nil
65
+
66
+ @mails = nil
67
+ @n_mails = nil
68
+ @n_bytes = nil
69
+ end
70
+
71
+ # does this instance use SSL?
72
+ def usessl?
73
+ @usessl
74
+ end
75
+
76
+ # Enables SSL for this instance. Must be called before the connection is
77
+ # established to have any effect.
78
+ # +verify+ is the type of verification to do on the Server Cert; Defaults
79
+ # to OpenSSL::SSL::VERIFY_PEER.
80
+ # +certs+ is a file or directory holding CA certs to use to verify the
81
+ # server cert; Defaults to nil.
82
+ # +port+ is port to establish the SSL conection on; Defaults to 995.
83
+ def enable_ssl(verify = OpenSSL::SSL::VERIFY_PEER, certs = nil,
84
+ port = SSL_PORT)
85
+ @usessl = true
86
+ @verify = verify
87
+ @certs = certs
88
+ @port = port
89
+ end
90
+
91
+ def disable_ssl
92
+ @usessl = nil
93
+ @verify = nil
94
+ @certs = nil
95
+ end
96
+
97
+ def do_start( account, password )
98
+ s = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
99
+ if @usessl
100
+ unless defined?(OpenSSL)
101
+ raise "SSL extension not installed"
102
+ end
103
+ sslctx = OpenSSL::SSL::SSLContext.new
104
+ sslctx.verify_mode = @verify
105
+ sslctx.ca_file = @certs if @certs && FileTest::file?(@certs)
106
+ sslctx.ca_path = @certs if @certs && FileTest::directory?(@certs)
107
+ s = OpenSSL::SSL::SSLSocket.new(s, sslctx)
108
+ s.sync_close = true
109
+ s.connect
110
+ end
111
+
112
+ @socket = Net::InternetMessageIO.new(s)
113
+ on_connect
114
+ @command = Net::POP3Command.new(@socket)
115
+ if apop?
116
+ @command.apop account, password
117
+ else
118
+ @command.auth account, password
119
+ end
120
+ @started = true
121
+ ensure
122
+ do_finish if not @started
123
+ end
124
+ private :do_start
125
+ end
@@ -0,0 +1,74 @@
1
+ # require File.dirname(__FILE__) + '/../../../../config/boot'
2
+ require 'rubygems'
3
+ require 'test/unit'
4
+ require 'mocha'
5
+ require 'fetcher'
6
+
7
+ class FetcherTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ @receiver = mock()
11
+ end
12
+
13
+ def test_should_set_configuration_instance_variables
14
+ create_fetcher
15
+ assert_equal 'test.host', @fetcher.instance_variable_get(:@server)
16
+ assert_equal 'name', @fetcher.instance_variable_get(:@username)
17
+ assert_equal 'password', @fetcher.instance_variable_get(:@password)
18
+ assert_equal @receiver, @fetcher.instance_variable_get(:@receiver)
19
+ end
20
+
21
+ def test_should_require_subclass
22
+ create_fetcher
23
+ assert_raise(NotImplementedError) { @fetcher.fetch }
24
+ end
25
+
26
+ def test_should_require_server
27
+ assert_raise(ArgumentError) { create_fetcher(:server => nil) }
28
+ end
29
+
30
+ def test_should_require_username
31
+ assert_raise(ArgumentError) { create_fetcher(:username => nil) }
32
+ end
33
+
34
+ def test_should_require_password
35
+ assert_raise(ArgumentError) { create_fetcher(:password => nil) }
36
+ end
37
+
38
+ def test_should_require_receiver
39
+ assert_raise(ArgumentError) { create_fetcher(:receiver => nil) }
40
+ end
41
+
42
+ def create_fetcher(options={})
43
+ @fetcher = Fetcher::Base.new({:server => 'test.host', :username => 'name', :password => 'password', :receiver => @receiver}.merge(options))
44
+ end
45
+
46
+ end
47
+
48
+ class FactoryFetcherTest < Test::Unit::TestCase
49
+
50
+ def setup
51
+ @receiver = mock()
52
+ @pop_fetcher = Fetcher.create(:type => :pop, :server => 'test.host',
53
+ :username => 'name',
54
+ :password => 'password',
55
+ :receiver => @receiver)
56
+
57
+ @imap_fetcher = Fetcher.create(:type => :imap, :server => 'test.host',
58
+ :username => 'name',
59
+ :password => 'password',
60
+ :receiver => @receiver)
61
+ end
62
+
63
+ def test_should_be_sublcass
64
+ assert_equal Fetcher::Pop, @pop_fetcher.class
65
+ assert_equal Fetcher::Imap, @imap_fetcher.class
66
+ end
67
+
68
+ def test_should_require_type
69
+ assert_raise(ArgumentError) { Fetcher.create({}) }
70
+ end
71
+
72
+ end
73
+
74
+ # Write tests for sub-classes