sum 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +10 -12
- data/Rakefile +6 -7
- data/config/externals.yml +3 -3
- data/config/schedule.rb +0 -1
- data/features/step_definitions/when.rb +3 -3
- data/features/support/env.rb +9 -10
- data/gemspec.rb +13 -14
- data/lib/sum.rb +8 -8
- data/lib/sum/helper/cron.rb +1 -1
- data/lib/sum/model/user.rb +3 -3
- data/vendor/fetcher/MIT-LICENSE +20 -0
- data/vendor/fetcher/README.rdoc +94 -0
- data/vendor/fetcher/Rakefile +30 -0
- data/vendor/fetcher/fetcher.gemspec +27 -0
- data/vendor/fetcher/gemspec.rb +17 -0
- data/vendor/fetcher/init.rb +0 -0
- data/vendor/fetcher/lib/fetcher.rb +23 -0
- data/vendor/fetcher/lib/fetcher/base.rb +63 -0
- data/vendor/fetcher/lib/fetcher/imap.rb +79 -0
- data/vendor/fetcher/lib/fetcher/pop.rb +50 -0
- data/vendor/fetcher/lib/vendor/plain_imap.rb +21 -0
- data/vendor/fetcher/lib/vendor/secure_pop.rb +125 -0
- data/vendor/fetcher/test/fetcher_test.rb +74 -0
- metadata +40 -241
- data/sum.gemspec +0 -69
- data/vendor/webrat/History.txt +0 -358
- data/vendor/webrat/MIT-LICENSE.txt +0 -19
- data/vendor/webrat/README.rdoc +0 -85
- data/vendor/webrat/Rakefile +0 -200
- data/vendor/webrat/install.rb +0 -1
- data/vendor/webrat/lib/webrat.rb +0 -31
- data/vendor/webrat/lib/webrat/core.rb +0 -14
- data/vendor/webrat/lib/webrat/core/configuration.rb +0 -102
- data/vendor/webrat/lib/webrat/core/elements/area.rb +0 -31
- data/vendor/webrat/lib/webrat/core/elements/element.rb +0 -33
- data/vendor/webrat/lib/webrat/core/elements/field.rb +0 -409
- data/vendor/webrat/lib/webrat/core/elements/form.rb +0 -103
- data/vendor/webrat/lib/webrat/core/elements/label.rb +0 -31
- data/vendor/webrat/lib/webrat/core/elements/link.rb +0 -93
- data/vendor/webrat/lib/webrat/core/elements/select_option.rb +0 -35
- data/vendor/webrat/lib/webrat/core/locators.rb +0 -20
- data/vendor/webrat/lib/webrat/core/locators/area_locator.rb +0 -38
- data/vendor/webrat/lib/webrat/core/locators/button_locator.rb +0 -54
- data/vendor/webrat/lib/webrat/core/locators/field_by_id_locator.rb +0 -37
- data/vendor/webrat/lib/webrat/core/locators/field_labeled_locator.rb +0 -56
- data/vendor/webrat/lib/webrat/core/locators/field_locator.rb +0 -25
- data/vendor/webrat/lib/webrat/core/locators/field_named_locator.rb +0 -41
- data/vendor/webrat/lib/webrat/core/locators/form_locator.rb +0 -19
- data/vendor/webrat/lib/webrat/core/locators/label_locator.rb +0 -34
- data/vendor/webrat/lib/webrat/core/locators/link_locator.rb +0 -74
- data/vendor/webrat/lib/webrat/core/locators/locator.rb +0 -20
- data/vendor/webrat/lib/webrat/core/locators/select_option_locator.rb +0 -59
- data/vendor/webrat/lib/webrat/core/logging.rb +0 -24
- data/vendor/webrat/lib/webrat/core/matchers.rb +0 -4
- data/vendor/webrat/lib/webrat/core/matchers/have_content.rb +0 -73
- data/vendor/webrat/lib/webrat/core/matchers/have_selector.rb +0 -74
- data/vendor/webrat/lib/webrat/core/matchers/have_tag.rb +0 -21
- data/vendor/webrat/lib/webrat/core/matchers/have_xpath.rb +0 -147
- data/vendor/webrat/lib/webrat/core/methods.rb +0 -63
- data/vendor/webrat/lib/webrat/core/mime.rb +0 -29
- data/vendor/webrat/lib/webrat/core/save_and_open_page.rb +0 -48
- data/vendor/webrat/lib/webrat/core/scope.rb +0 -350
- data/vendor/webrat/lib/webrat/core/session.rb +0 -299
- data/vendor/webrat/lib/webrat/core/xml.rb +0 -115
- data/vendor/webrat/lib/webrat/core/xml/hpricot.rb +0 -19
- data/vendor/webrat/lib/webrat/core/xml/nokogiri.rb +0 -76
- data/vendor/webrat/lib/webrat/core/xml/rexml.rb +0 -24
- data/vendor/webrat/lib/webrat/core_extensions/blank.rb +0 -58
- data/vendor/webrat/lib/webrat/core_extensions/deprecate.rb +0 -8
- data/vendor/webrat/lib/webrat/core_extensions/detect_mapped.rb +0 -12
- data/vendor/webrat/lib/webrat/core_extensions/meta_class.rb +0 -6
- data/vendor/webrat/lib/webrat/core_extensions/nil_to_param.rb +0 -5
- data/vendor/webrat/lib/webrat/core_extensions/tcp_socket.rb +0 -27
- data/vendor/webrat/lib/webrat/mechanize.rb +0 -74
- data/vendor/webrat/lib/webrat/merb.rb +0 -9
- data/vendor/webrat/lib/webrat/merb_multipart_support.rb +0 -27
- data/vendor/webrat/lib/webrat/merb_session.rb +0 -82
- data/vendor/webrat/lib/webrat/rack.rb +0 -25
- data/vendor/webrat/lib/webrat/rails.rb +0 -106
- data/vendor/webrat/lib/webrat/rspec-rails.rb +0 -10
- data/vendor/webrat/lib/webrat/selenium.rb +0 -81
- data/vendor/webrat/lib/webrat/selenium/application_server_factory.rb +0 -40
- data/vendor/webrat/lib/webrat/selenium/application_servers.rb +0 -5
- data/vendor/webrat/lib/webrat/selenium/application_servers/base.rb +0 -46
- data/vendor/webrat/lib/webrat/selenium/application_servers/external.rb +0 -26
- data/vendor/webrat/lib/webrat/selenium/application_servers/merb.rb +0 -50
- data/vendor/webrat/lib/webrat/selenium/application_servers/rails.rb +0 -44
- data/vendor/webrat/lib/webrat/selenium/application_servers/sinatra.rb +0 -37
- data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/button.js +0 -19
- data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/label.js +0 -16
- data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webrat.js +0 -5
- data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratlink.js +0 -12
- data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +0 -15
- data/vendor/webrat/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +0 -5
- data/vendor/webrat/lib/webrat/selenium/matchers.rb +0 -4
- data/vendor/webrat/lib/webrat/selenium/matchers/have_content.rb +0 -66
- data/vendor/webrat/lib/webrat/selenium/matchers/have_selector.rb +0 -49
- data/vendor/webrat/lib/webrat/selenium/matchers/have_tag.rb +0 -72
- data/vendor/webrat/lib/webrat/selenium/matchers/have_xpath.rb +0 -45
- data/vendor/webrat/lib/webrat/selenium/selenium_extensions.js +0 -6
- data/vendor/webrat/lib/webrat/selenium/selenium_rc_server.rb +0 -84
- data/vendor/webrat/lib/webrat/selenium/selenium_session.rb +0 -248
- data/vendor/webrat/lib/webrat/selenium/silence_stream.rb +0 -18
- data/vendor/webrat/lib/webrat/sinatra.rb +0 -11
- data/vendor/webrat/spec/fakes/test_session.rb +0 -34
- data/vendor/webrat/spec/integration/merb/Rakefile +0 -35
- data/vendor/webrat/spec/integration/merb/app/controllers/application.rb +0 -2
- data/vendor/webrat/spec/integration/merb/app/controllers/exceptions.rb +0 -13
- data/vendor/webrat/spec/integration/merb/app/controllers/testing.rb +0 -27
- data/vendor/webrat/spec/integration/merb/app/views/exceptions/not_acceptable.html.erb +0 -63
- data/vendor/webrat/spec/integration/merb/app/views/exceptions/not_found.html.erb +0 -47
- data/vendor/webrat/spec/integration/merb/app/views/layout/application.html.erb +0 -12
- data/vendor/webrat/spec/integration/merb/app/views/testing/show_form.html.erb +0 -27
- data/vendor/webrat/spec/integration/merb/app/views/testing/upload.html.erb +0 -9
- data/vendor/webrat/spec/integration/merb/config/environments/development.rb +0 -15
- data/vendor/webrat/spec/integration/merb/config/environments/rake.rb +0 -11
- data/vendor/webrat/spec/integration/merb/config/environments/test.rb +0 -14
- data/vendor/webrat/spec/integration/merb/config/init.rb +0 -25
- data/vendor/webrat/spec/integration/merb/config/rack.rb +0 -11
- data/vendor/webrat/spec/integration/merb/config/router.rb +0 -34
- data/vendor/webrat/spec/integration/merb/spec/spec.opts +0 -1
- data/vendor/webrat/spec/integration/merb/spec/spec_helper.rb +0 -24
- data/vendor/webrat/spec/integration/merb/spec/webrat_spec.rb +0 -39
- data/vendor/webrat/spec/integration/merb/tasks/merb.thor/app_script.rb +0 -31
- data/vendor/webrat/spec/integration/merb/tasks/merb.thor/common.rb +0 -64
- data/vendor/webrat/spec/integration/merb/tasks/merb.thor/gem_ext.rb +0 -124
- data/vendor/webrat/spec/integration/merb/tasks/merb.thor/main.thor +0 -150
- data/vendor/webrat/spec/integration/merb/tasks/merb.thor/ops.rb +0 -93
- data/vendor/webrat/spec/integration/merb/tasks/merb.thor/utils.rb +0 -40
- data/vendor/webrat/spec/integration/rack/Rakefile +0 -5
- data/vendor/webrat/spec/integration/rack/app.rb +0 -73
- data/vendor/webrat/spec/integration/rack/test/helper.rb +0 -20
- data/vendor/webrat/spec/integration/rack/test/webrat_rack_test.rb +0 -62
- data/vendor/webrat/spec/integration/rails/Rakefile +0 -30
- data/vendor/webrat/spec/integration/rails/app/controllers/application.rb +0 -15
- data/vendor/webrat/spec/integration/rails/app/controllers/buttons_controller.rb +0 -7
- data/vendor/webrat/spec/integration/rails/app/controllers/fields_controller.rb +0 -4
- data/vendor/webrat/spec/integration/rails/app/controllers/links_controller.rb +0 -7
- data/vendor/webrat/spec/integration/rails/app/controllers/webrat_controller.rb +0 -43
- data/vendor/webrat/spec/integration/rails/app/helpers/buttons_helper.rb +0 -2
- data/vendor/webrat/spec/integration/rails/app/helpers/fields_helper.rb +0 -2
- data/vendor/webrat/spec/integration/rails/app/helpers/links_helper.rb +0 -2
- data/vendor/webrat/spec/integration/rails/app/views/buttons/show.html.erb +0 -11
- data/vendor/webrat/spec/integration/rails/app/views/fields/show.html.erb +0 -9
- data/vendor/webrat/spec/integration/rails/app/views/links/show.html.erb +0 -5
- data/vendor/webrat/spec/integration/rails/app/views/webrat/before_redirect_form.html.erb +0 -4
- data/vendor/webrat/spec/integration/rails/app/views/webrat/buttons.html.erb +0 -11
- data/vendor/webrat/spec/integration/rails/app/views/webrat/form.html.erb +0 -28
- data/vendor/webrat/spec/integration/rails/config/boot.rb +0 -109
- data/vendor/webrat/spec/integration/rails/config/environment.rb +0 -12
- data/vendor/webrat/spec/integration/rails/config/environments/development.rb +0 -17
- data/vendor/webrat/spec/integration/rails/config/environments/selenium.rb +0 -22
- data/vendor/webrat/spec/integration/rails/config/environments/test.rb +0 -22
- data/vendor/webrat/spec/integration/rails/config/initializers/inflections.rb +0 -10
- data/vendor/webrat/spec/integration/rails/config/initializers/mime_types.rb +0 -5
- data/vendor/webrat/spec/integration/rails/config/initializers/new_rails_defaults.rb +0 -17
- data/vendor/webrat/spec/integration/rails/config/locales/en.yml +0 -5
- data/vendor/webrat/spec/integration/rails/config/routes.rb +0 -18
- data/vendor/webrat/spec/integration/rails/public/404.html +0 -30
- data/vendor/webrat/spec/integration/rails/public/422.html +0 -30
- data/vendor/webrat/spec/integration/rails/public/500.html +0 -33
- data/vendor/webrat/spec/integration/rails/script/about +0 -4
- data/vendor/webrat/spec/integration/rails/script/console +0 -3
- data/vendor/webrat/spec/integration/rails/script/dbconsole +0 -3
- data/vendor/webrat/spec/integration/rails/script/destroy +0 -3
- data/vendor/webrat/spec/integration/rails/script/generate +0 -3
- data/vendor/webrat/spec/integration/rails/script/performance/benchmarker +0 -3
- data/vendor/webrat/spec/integration/rails/script/performance/profiler +0 -3
- data/vendor/webrat/spec/integration/rails/script/performance/request +0 -3
- data/vendor/webrat/spec/integration/rails/script/plugin +0 -3
- data/vendor/webrat/spec/integration/rails/script/process/inspector +0 -3
- data/vendor/webrat/spec/integration/rails/script/process/reaper +0 -3
- data/vendor/webrat/spec/integration/rails/script/process/spawner +0 -3
- data/vendor/webrat/spec/integration/rails/script/runner +0 -3
- data/vendor/webrat/spec/integration/rails/script/server +0 -3
- data/vendor/webrat/spec/integration/rails/test/integration/button_click_test.rb +0 -80
- data/vendor/webrat/spec/integration/rails/test/integration/fill_in_test.rb +0 -24
- data/vendor/webrat/spec/integration/rails/test/integration/link_click_test.rb +0 -27
- data/vendor/webrat/spec/integration/rails/test/integration/webrat_test.rb +0 -97
- data/vendor/webrat/spec/integration/rails/test/test_helper.rb +0 -25
- data/vendor/webrat/spec/integration/sinatra/Rakefile +0 -5
- data/vendor/webrat/spec/integration/sinatra/classic_app.rb +0 -64
- data/vendor/webrat/spec/integration/sinatra/modular_app.rb +0 -16
- data/vendor/webrat/spec/integration/sinatra/test/classic_app_test.rb +0 -37
- data/vendor/webrat/spec/integration/sinatra/test/modular_app_test.rb +0 -18
- data/vendor/webrat/spec/integration/sinatra/test/test_helper.rb +0 -16
- data/vendor/webrat/spec/private/core/configuration_spec.rb +0 -116
- data/vendor/webrat/spec/private/core/field_spec.rb +0 -85
- data/vendor/webrat/spec/private/core/link_spec.rb +0 -24
- data/vendor/webrat/spec/private/core/logging_spec.rb +0 -10
- data/vendor/webrat/spec/private/core/session_spec.rb +0 -195
- data/vendor/webrat/spec/private/mechanize/mechanize_session_spec.rb +0 -81
- data/vendor/webrat/spec/private/merb/attaches_file_spec.rb +0 -93
- data/vendor/webrat/spec/private/merb/merb_session_spec.rb +0 -61
- data/vendor/webrat/spec/private/nokogiri_spec.rb +0 -77
- data/vendor/webrat/spec/private/rails/attaches_file_spec.rb +0 -81
- data/vendor/webrat/spec/private/rails/rails_session_spec.rb +0 -112
- data/vendor/webrat/spec/private/selenium/application_servers/rails_spec.rb +0 -26
- data/vendor/webrat/spec/public/basic_auth_spec.rb +0 -24
- data/vendor/webrat/spec/public/check_spec.rb +0 -191
- data/vendor/webrat/spec/public/choose_spec.rb +0 -118
- data/vendor/webrat/spec/public/click_area_spec.rb +0 -106
- data/vendor/webrat/spec/public/click_button_spec.rb +0 -496
- data/vendor/webrat/spec/public/click_link_spec.rb +0 -511
- data/vendor/webrat/spec/public/fill_in_spec.rb +0 -209
- data/vendor/webrat/spec/public/locators/field_by_xpath_spec.rb +0 -19
- data/vendor/webrat/spec/public/locators/field_labeled_spec.rb +0 -172
- data/vendor/webrat/spec/public/locators/field_with_id_spec.rb +0 -16
- data/vendor/webrat/spec/public/matchers/contain_spec.rb +0 -114
- data/vendor/webrat/spec/public/matchers/have_selector_spec.rb +0 -142
- data/vendor/webrat/spec/public/matchers/have_tag_spec.rb +0 -39
- data/vendor/webrat/spec/public/matchers/have_xpath_spec.rb +0 -136
- data/vendor/webrat/spec/public/reload_spec.rb +0 -10
- data/vendor/webrat/spec/public/save_and_open_spec.rb +0 -70
- data/vendor/webrat/spec/public/select_date_spec.rb +0 -112
- data/vendor/webrat/spec/public/select_datetime_spec.rb +0 -137
- data/vendor/webrat/spec/public/select_spec.rb +0 -249
- data/vendor/webrat/spec/public/select_time_spec.rb +0 -100
- data/vendor/webrat/spec/public/selenium/application_server_factory_spec.rb +0 -49
- data/vendor/webrat/spec/public/selenium/application_servers/external_spec.rb +0 -12
- data/vendor/webrat/spec/public/selenium/selenium_session_spec.rb +0 -37
- data/vendor/webrat/spec/public/set_hidden_field_spec.rb +0 -5
- data/vendor/webrat/spec/public/submit_form_spec.rb +0 -5
- data/vendor/webrat/spec/public/visit_spec.rb +0 -58
- data/vendor/webrat/spec/public/within_spec.rb +0 -177
- data/vendor/webrat/spec/rcov.opts +0 -1
- data/vendor/webrat/spec/spec.opts +0 -2
- 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
|