astrotrain 0.5.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +8 -0
- data/LICENSE +18 -17
- data/Rakefile +118 -103
- data/astrotrain.gemspec +87 -136
- data/lib/astrotrain.rb +47 -51
- data/lib/astrotrain/attachment.rb +55 -0
- data/lib/astrotrain/message.rb +221 -235
- data/lib/astrotrain/transports/http_post.rb +67 -0
- data/lib/astrotrain/transports/resque.rb +63 -0
- data/test/fixtures/bad_email_format.txt +15 -0
- data/test/fixtures/basic.txt +4 -1
- data/test/fixtures/iso-8859-1.txt +1 -0
- data/test/message_test.rb +146 -457
- data/test/test_helper.rb +20 -42
- data/test/transport_test.rb +98 -100
- metadata +100 -243
- data/.gitignore +0 -26
- data/README +0 -47
- data/VERSION +0 -1
- data/config/sample.rb +0 -12
- data/lib/astrotrain/api.rb +0 -52
- data/lib/astrotrain/logged_mail.rb +0 -48
- data/lib/astrotrain/mapping.rb +0 -162
- data/lib/astrotrain/mapping/http_post.rb +0 -18
- data/lib/astrotrain/mapping/jabber.rb +0 -28
- data/lib/astrotrain/mapping/transport.rb +0 -55
- data/lib/astrotrain/tmail.rb +0 -58
- data/lib/astrotrain/worker.rb +0 -65
- data/lib/vendor/rest-client/README.rdoc +0 -104
- data/lib/vendor/rest-client/Rakefile +0 -84
- data/lib/vendor/rest-client/bin/restclient +0 -65
- data/lib/vendor/rest-client/foo.diff +0 -66
- data/lib/vendor/rest-client/lib/rest_client.rb +0 -188
- data/lib/vendor/rest-client/lib/rest_client/net_http_ext.rb +0 -23
- data/lib/vendor/rest-client/lib/rest_client/payload.rb +0 -185
- data/lib/vendor/rest-client/lib/rest_client/request_errors.rb +0 -75
- data/lib/vendor/rest-client/lib/rest_client/resource.rb +0 -103
- data/lib/vendor/rest-client/rest-client.gemspec +0 -18
- data/lib/vendor/rest-client/spec/base.rb +0 -5
- data/lib/vendor/rest-client/spec/master_shake.jpg +0 -0
- data/lib/vendor/rest-client/spec/payload_spec.rb +0 -71
- data/lib/vendor/rest-client/spec/request_errors_spec.rb +0 -44
- data/lib/vendor/rest-client/spec/resource_spec.rb +0 -52
- data/lib/vendor/rest-client/spec/rest_client_spec.rb +0 -219
- data/test/api_test.rb +0 -32
- data/test/logged_mail_test.rb +0 -67
- data/test/mapping_test.rb +0 -129
data/lib/astrotrain/tmail.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
module Astrotrain
|
2
|
-
# custom subclass of TMail::Mail that fixes some bugs. The fixes were pushed upstream,
|
3
|
-
# and this class will go away once the gem is released.
|
4
|
-
class Mail < TMail::Mail
|
5
|
-
def charset( default = nil )
|
6
|
-
if h = @header['content-type']
|
7
|
-
h['charset'] || mime_version_charset || default
|
8
|
-
else
|
9
|
-
mime_version_charset || default
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# some weird emails come with the charset specified in the mime-version header:
|
14
|
-
#
|
15
|
-
# #<TMail::MimeVersionHeader "1.0\n charset=\"gb2312\"">
|
16
|
-
#
|
17
|
-
def mime_version_charset
|
18
|
-
if header['mime-version'].inspect =~ /charset=('|\\")?([^\\"']+)/
|
19
|
-
$2
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
# copied from TMail::Mail, uses #charset instead of #sub_header
|
24
|
-
def unquoted_body(to_charset = 'utf-8')
|
25
|
-
from_charset = charset
|
26
|
-
case (content_transfer_encoding || "7bit").downcase
|
27
|
-
when "quoted-printable"
|
28
|
-
# the default charset is set to iso-8859-1 instead of 'us-ascii'.
|
29
|
-
# This is needed as many mailer do not set the charset but send in ISO. This is only used if no charset is set.
|
30
|
-
if !from_charset.blank? && from_charset.downcase == 'us-ascii'
|
31
|
-
from_charset = 'iso-8859-1'
|
32
|
-
end
|
33
|
-
|
34
|
-
TMail::Unquoter.unquote_quoted_printable_and_convert_to(quoted_body,
|
35
|
-
to_charset, from_charset, true)
|
36
|
-
when "base64"
|
37
|
-
TMail::Unquoter.unquote_base64_and_convert_to(quoted_body, to_charset,
|
38
|
-
from_charset)
|
39
|
-
when "7bit", "8bit"
|
40
|
-
TMail::Unquoter.convert_to(quoted_body, to_charset, from_charset)
|
41
|
-
when "binary"
|
42
|
-
quoted_body
|
43
|
-
else
|
44
|
-
quoted_body
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
module TMail
|
51
|
-
# small tweak to provide the raw body of headers in case they're unable to
|
52
|
-
# be parsed properly
|
53
|
-
class HeaderField
|
54
|
-
def raw_body
|
55
|
-
@body
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/lib/astrotrain/worker.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'benchmark'
|
2
|
-
module Astrotrain
|
3
|
-
class Worker
|
4
|
-
attr_accessor :logger, :sleep_duration, :name
|
5
|
-
|
6
|
-
def self.start(options = {}, &block)
|
7
|
-
new(options).run(&block)
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(options = {})
|
11
|
-
@name = options[:name] || "pid:#{Process.pid}"
|
12
|
-
@pid = options[:pid] || File.join(Astrotrain.root, 'log', 'astrotrain_job.pid')
|
13
|
-
@sleep_duration = options[:sleep] || 5
|
14
|
-
@logger = options.key?(:logger) ? options[:logger] : STDOUT
|
15
|
-
end
|
16
|
-
|
17
|
-
# override this to perform other tasks in the astrotrain job loop
|
18
|
-
def run(&block)
|
19
|
-
block ||= lambda { |w| w.process_emails }
|
20
|
-
setup(&block)
|
21
|
-
end
|
22
|
-
|
23
|
-
def process_emails
|
24
|
-
files = 0
|
25
|
-
Dir.foreach(Message.queue_path) do |f|
|
26
|
-
next if f =~ /^\.{1,2}$/
|
27
|
-
files += 1
|
28
|
-
file = File.join(Message.queue_path, f)
|
29
|
-
Message.receive_file(file)
|
30
|
-
end
|
31
|
-
files
|
32
|
-
end
|
33
|
-
|
34
|
-
def say(s)
|
35
|
-
@logger << "#{s}\n" if @logger
|
36
|
-
end
|
37
|
-
|
38
|
-
def setup
|
39
|
-
say "*** Starting Astrotrain::Worker #{@name}"
|
40
|
-
FileUtils.mkdir_p File.dirname(@pid)
|
41
|
-
|
42
|
-
File.open(@pid, 'w') { |f| f << Process.pid.to_s }
|
43
|
-
|
44
|
-
trap('TERM') { puts 'Exiting...'; $exit = true }
|
45
|
-
trap('INT') { puts 'Exiting...'; $exit = true }
|
46
|
-
|
47
|
-
loop do
|
48
|
-
count = nil
|
49
|
-
realtime = Benchmark.realtime { count = yield(self) }
|
50
|
-
|
51
|
-
break if $exit
|
52
|
-
|
53
|
-
if count.zero?
|
54
|
-
sleep(@sleep_duration)
|
55
|
-
else
|
56
|
-
puts "#{count} mails processed at %.4f m/s ..." % [count / realtime]
|
57
|
-
end
|
58
|
-
|
59
|
-
break if $exit
|
60
|
-
end
|
61
|
-
ensure
|
62
|
-
FileUtils.rm(@pid) rescue nil
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
= REST Client -- simple DSL for accessing REST resources
|
2
|
-
|
3
|
-
A simple REST client for Ruby, inspired by the Sinatra's microframework style
|
4
|
-
of specifying actions: get, put, post, delete.
|
5
|
-
|
6
|
-
== Usage: Raw URL
|
7
|
-
|
8
|
-
require 'rest_client'
|
9
|
-
|
10
|
-
RestClient.get 'http://example.com/resource'
|
11
|
-
RestClient.get 'https://user:password@example.com/private/resource'
|
12
|
-
|
13
|
-
RestClient.post 'http://example.com/resource', :param1 => 'one', :nested => { :param2 => 'two' }
|
14
|
-
|
15
|
-
RestClient.delete 'http://example.com/resource'
|
16
|
-
|
17
|
-
== Multipart
|
18
|
-
|
19
|
-
Yeah, that's right! This does multipart sends for you!
|
20
|
-
|
21
|
-
RestClient.post '/data', :myfile => File.new("/path/to/image.jpg")
|
22
|
-
|
23
|
-
This does two things for you:
|
24
|
-
|
25
|
-
* Auto-detects that you have a File value sends it as multipart
|
26
|
-
* Auto-detects the mime of the file and sets it in the HEAD of the payload for each entry
|
27
|
-
|
28
|
-
If you are sending params that do not contain a File object but the payload needs to be multipart then:
|
29
|
-
|
30
|
-
RestClient.post '/data', :foo => 'bar', :multipart => true
|
31
|
-
|
32
|
-
== Streaming downloads
|
33
|
-
|
34
|
-
RestClient.get('http://some/resource/lotsofdata') do |res|
|
35
|
-
res.read_body do |chunk|
|
36
|
-
.. do something with chunk ..
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
See RestClient module docs for more details.
|
41
|
-
|
42
|
-
== Usage: ActiveResource-Style
|
43
|
-
|
44
|
-
resource = RestClient::Resource.new 'http://example.com/resource'
|
45
|
-
resource.get
|
46
|
-
|
47
|
-
private_resource = RestClient::Resource.new 'https://example.com/private/resource', 'user', 'pass'
|
48
|
-
private_resource.put File.read('pic.jpg'), :content_type => 'image/jpg'
|
49
|
-
|
50
|
-
See RestClient::Resource module docs for details.
|
51
|
-
|
52
|
-
== Usage: Resource Nesting
|
53
|
-
|
54
|
-
site = RestClient::Resource.new('http://example.com')
|
55
|
-
site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
|
56
|
-
|
57
|
-
See RestClient::Resource docs for details.
|
58
|
-
|
59
|
-
== Shell
|
60
|
-
|
61
|
-
The restclient shell command gives an IRB session with RestClient already loaded:
|
62
|
-
|
63
|
-
$ restclient
|
64
|
-
>> RestClient.get 'http://example.com'
|
65
|
-
|
66
|
-
Specify a URL argument for get/post/put/delete on that resource:
|
67
|
-
|
68
|
-
$ restclient http://example.com
|
69
|
-
>> put '/resource', 'data'
|
70
|
-
|
71
|
-
Add a user and password for authenticated resources:
|
72
|
-
|
73
|
-
$ restclient https://example.com user pass
|
74
|
-
>> delete '/private/resource'
|
75
|
-
|
76
|
-
Create ~/.restclient for named sessions:
|
77
|
-
|
78
|
-
sinatra:
|
79
|
-
url: http://localhost:4567
|
80
|
-
rack:
|
81
|
-
url: http://localhost:9292
|
82
|
-
private_site:
|
83
|
-
url: http://example.com
|
84
|
-
username: user
|
85
|
-
password: pass
|
86
|
-
|
87
|
-
Then invoke:
|
88
|
-
|
89
|
-
$ restclient private_site
|
90
|
-
|
91
|
-
== Meta
|
92
|
-
|
93
|
-
Written by Adam Wiggins (adam at heroku dot com)
|
94
|
-
|
95
|
-
Major modifications by Blake Mizerany
|
96
|
-
|
97
|
-
Patches contributed by: Chris Anderson, Greg Borenstein, Ardekantur, Pedro Belo, Rafael Souza, Rick Olson, and Aman Gupta
|
98
|
-
|
99
|
-
Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
|
100
|
-
|
101
|
-
http://rest-client.heroku.com
|
102
|
-
|
103
|
-
http://github.com/adamwiggins/rest-client
|
104
|
-
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'rake'
|
2
|
-
require 'spec/rake/spectask'
|
3
|
-
|
4
|
-
desc "Run all specs"
|
5
|
-
Spec::Rake::SpecTask.new('spec') do |t|
|
6
|
-
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
7
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
8
|
-
end
|
9
|
-
|
10
|
-
desc "Print specdocs"
|
11
|
-
Spec::Rake::SpecTask.new(:doc) do |t|
|
12
|
-
t.spec_opts = ["--format", "specdoc", "--dry-run"]
|
13
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
14
|
-
end
|
15
|
-
|
16
|
-
desc "Run all examples with RCov"
|
17
|
-
Spec::Rake::SpecTask.new('rcov') do |t|
|
18
|
-
t.spec_files = FileList['spec/*_spec.rb']
|
19
|
-
t.rcov = true
|
20
|
-
t.rcov_opts = ['--exclude', 'examples']
|
21
|
-
end
|
22
|
-
|
23
|
-
task :default => :spec
|
24
|
-
|
25
|
-
######################################################
|
26
|
-
|
27
|
-
require 'rake'
|
28
|
-
require 'rake/testtask'
|
29
|
-
require 'rake/clean'
|
30
|
-
require 'rake/gempackagetask'
|
31
|
-
require 'rake/rdoctask'
|
32
|
-
require 'fileutils'
|
33
|
-
|
34
|
-
version = "0.6.2"
|
35
|
-
name = "rest-client"
|
36
|
-
|
37
|
-
spec = Gem::Specification.new do |s|
|
38
|
-
s.name = name
|
39
|
-
s.version = version
|
40
|
-
s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
|
41
|
-
s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
|
42
|
-
s.author = "Adam Wiggins"
|
43
|
-
s.email = "adam@heroku.com"
|
44
|
-
s.homepage = "http://rest-client.heroku.com/"
|
45
|
-
s.rubyforge_project = "rest-client"
|
46
|
-
|
47
|
-
s.platform = Gem::Platform::RUBY
|
48
|
-
s.has_rdoc = true
|
49
|
-
|
50
|
-
s.files = %w(Rakefile) + Dir.glob("{lib,spec}/**/*")
|
51
|
-
s.executables = ['restclient']
|
52
|
-
|
53
|
-
s.require_path = "lib"
|
54
|
-
end
|
55
|
-
|
56
|
-
Rake::GemPackageTask.new(spec) do |p|
|
57
|
-
p.need_tar = true if RUBY_PLATFORM !~ /mswin/
|
58
|
-
end
|
59
|
-
|
60
|
-
task :install => [ :package ] do
|
61
|
-
sh %{sudo gem install pkg/#{name}-#{version}.gem}
|
62
|
-
end
|
63
|
-
|
64
|
-
task :uninstall => [ :clean ] do
|
65
|
-
sh %{sudo gem uninstall #{name}}
|
66
|
-
end
|
67
|
-
|
68
|
-
Rake::TestTask.new do |t|
|
69
|
-
t.libs << "spec"
|
70
|
-
t.test_files = FileList['spec/*_spec.rb']
|
71
|
-
t.verbose = true
|
72
|
-
end
|
73
|
-
|
74
|
-
Rake::RDocTask.new do |t|
|
75
|
-
t.rdoc_dir = 'rdoc'
|
76
|
-
t.title = "rest-client, fetch RESTful resources effortlessly"
|
77
|
-
t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
|
78
|
-
t.options << '--charset' << 'utf-8'
|
79
|
-
t.rdoc_files.include('README.rdoc')
|
80
|
-
t.rdoc_files.include('lib/*.rb')
|
81
|
-
end
|
82
|
-
|
83
|
-
CLEAN.include [ 'pkg', '*.gem', '.config' ]
|
84
|
-
|
@@ -1,65 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$:.unshift File.dirname(__FILE__) + "/../lib"
|
4
|
-
require 'rest_client'
|
5
|
-
|
6
|
-
require "yaml"
|
7
|
-
|
8
|
-
def usage(why = nil)
|
9
|
-
puts "failed for reason: #{why}" if why
|
10
|
-
puts "usage: restclient url|name [username] [password]"
|
11
|
-
exit(1)
|
12
|
-
end
|
13
|
-
|
14
|
-
@url = ARGV.shift || 'http://localhost:4567'
|
15
|
-
|
16
|
-
config = YAML.load(File.read(ENV['HOME'] + "/.restclient")) rescue {}
|
17
|
-
|
18
|
-
@url, @username, @password = if c = config[@url]
|
19
|
-
[c['url'], c['username'], c['password']]
|
20
|
-
else
|
21
|
-
[@url, *ARGV]
|
22
|
-
end
|
23
|
-
|
24
|
-
usage("invalid url '#{@url}") unless @url =~ /^https?/
|
25
|
-
usage("to few args") unless ARGV.size < 3
|
26
|
-
|
27
|
-
def r
|
28
|
-
@r ||= RestClient::Resource.new(@url, @username, @password)
|
29
|
-
end
|
30
|
-
|
31
|
-
r # force rc to load
|
32
|
-
|
33
|
-
%w(get post put delete).each do |m|
|
34
|
-
eval <<-end_eval
|
35
|
-
def #{m}(path, *args, &b)
|
36
|
-
r[path].#{m}(*args, &b)
|
37
|
-
end
|
38
|
-
end_eval
|
39
|
-
end
|
40
|
-
|
41
|
-
def method_missing(s, *args, &b)
|
42
|
-
super unless r.respond_to?(s)
|
43
|
-
begin
|
44
|
-
r.send(s, *args, &b)
|
45
|
-
rescue RestClient::RequestFailed => e
|
46
|
-
puts e.response.body
|
47
|
-
raise e
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
require 'irb'
|
52
|
-
require 'irb/completion'
|
53
|
-
|
54
|
-
if File.exists? ".irbrc"
|
55
|
-
ENV['IRBRC'] = ".irbrc"
|
56
|
-
end
|
57
|
-
|
58
|
-
if File.exists?(rcfile = "~/.restclientrc")
|
59
|
-
load(rcfile)
|
60
|
-
end
|
61
|
-
|
62
|
-
ARGV.clear
|
63
|
-
|
64
|
-
IRB.start
|
65
|
-
exit!
|
@@ -1,66 +0,0 @@
|
|
1
|
-
commit 1a1a16d6abda6b40091b49d3ad082400018e665b
|
2
|
-
Author: rick <technoweenie@gmail.com>
|
3
|
-
Date: Wed Dec 10 20:01:02 2008 -0800
|
4
|
-
|
5
|
-
fix spacing issues with multipart bodies:
|
6
|
-
* the final boundary should be on a line below the final param's content.
|
7
|
-
* the ending double dash should be on the same line as the final boundary
|
8
|
-
|
9
|
-
diff --git a/lib/rest_client/payload.rb b/lib/rest_client/payload.rb
|
10
|
-
index dfc2921..e896be0 100644
|
11
|
-
--- a/lib/rest_client/payload.rb
|
12
|
-
+++ b/lib/rest_client/payload.rb
|
13
|
-
@@ -76,9 +76,10 @@ module RestClient
|
14
|
-
else
|
15
|
-
create_regular_field(@stream, k,v)
|
16
|
-
end
|
17
|
-
- @stream.write(b + EOL)
|
18
|
-
+ @stream.write(EOL + b)
|
19
|
-
end
|
20
|
-
@stream.write('--')
|
21
|
-
+ @stream.write(EOL)
|
22
|
-
@stream.seek(0)
|
23
|
-
end
|
24
|
-
|
25
|
-
diff --git a/spec/payload_spec.rb b/spec/payload_spec.rb
|
26
|
-
index 22b5a5a..35564ee 100644
|
27
|
-
--- a/spec/payload_spec.rb
|
28
|
-
+++ b/spec/payload_spec.rb
|
29
|
-
@@ -20,29 +20,27 @@ describe RestClient::Payload do
|
30
|
-
m.headers['Content-Type'].should == 'multipart/form-data; boundary="123"'
|
31
|
-
end
|
32
|
-
|
33
|
-
- xit "should form properly seperated multipart data" do
|
34
|
-
+ it "should form properly seperated multipart data" do
|
35
|
-
m = RestClient::Payload::Multipart.new({:foo => "bar"})
|
36
|
-
- m.stub!(:boundary).and_return("123")
|
37
|
-
m.to_s.should == <<-EOS
|
38
|
-
---123\r
|
39
|
-
+--#{m.boundary}\r
|
40
|
-
Content-Disposition: multipart/form-data; name="foo"\r
|
41
|
-
\r
|
42
|
-
bar\r
|
43
|
-
---123--\r
|
44
|
-
+--#{m.boundary}--\r
|
45
|
-
EOS
|
46
|
-
end
|
47
|
-
|
48
|
-
- xit "should form properly seperated multipart data" do
|
49
|
-
+ it "should form properly seperated multipart data" do
|
50
|
-
f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
|
51
|
-
m = RestClient::Payload::Multipart.new({:foo => f})
|
52
|
-
- m.stub!(:boundary).and_return("123")
|
53
|
-
m.to_s.should == <<-EOS
|
54
|
-
---123\r
|
55
|
-
-Content-Disposition: multipart/form-data; name="foo"; filename="master_shake.jpg"\r
|
56
|
-
+--#{m.boundary}\r
|
57
|
-
+Content-Disposition: multipart/form-data; name="foo"; filename="./spec/master_shake.jpg"\r
|
58
|
-
Content-Type: image/jpeg\r
|
59
|
-
\r
|
60
|
-
-datadatadata\r
|
61
|
-
---123--\r
|
62
|
-
+#{IO.read(f.path)}\r
|
63
|
-
+--#{m.boundary}--\r
|
64
|
-
EOS
|
65
|
-
end
|
66
|
-
end
|