astrotrain 0.3.1

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 (57) hide show
  1. data/.gitignore +26 -0
  2. data/LICENSE +20 -0
  3. data/README +47 -0
  4. data/Rakefile +122 -0
  5. data/VERSION +1 -0
  6. data/astrotrain.gemspec +129 -0
  7. data/config/sample.rb +12 -0
  8. data/lib/astrotrain.rb +53 -0
  9. data/lib/astrotrain/api.rb +52 -0
  10. data/lib/astrotrain/logged_mail.rb +46 -0
  11. data/lib/astrotrain/mapping.rb +157 -0
  12. data/lib/astrotrain/mapping/http_post.rb +18 -0
  13. data/lib/astrotrain/mapping/jabber.rb +28 -0
  14. data/lib/astrotrain/mapping/transport.rb +55 -0
  15. data/lib/astrotrain/message.rb +330 -0
  16. data/lib/astrotrain/tmail.rb +58 -0
  17. data/lib/astrotrain/worker.rb +65 -0
  18. data/lib/vendor/rest-client/README.rdoc +104 -0
  19. data/lib/vendor/rest-client/Rakefile +84 -0
  20. data/lib/vendor/rest-client/bin/restclient +65 -0
  21. data/lib/vendor/rest-client/foo.diff +66 -0
  22. data/lib/vendor/rest-client/lib/rest_client.rb +188 -0
  23. data/lib/vendor/rest-client/lib/rest_client/net_http_ext.rb +23 -0
  24. data/lib/vendor/rest-client/lib/rest_client/payload.rb +185 -0
  25. data/lib/vendor/rest-client/lib/rest_client/request_errors.rb +75 -0
  26. data/lib/vendor/rest-client/lib/rest_client/resource.rb +103 -0
  27. data/lib/vendor/rest-client/rest-client.gemspec +18 -0
  28. data/lib/vendor/rest-client/spec/base.rb +5 -0
  29. data/lib/vendor/rest-client/spec/master_shake.jpg +0 -0
  30. data/lib/vendor/rest-client/spec/payload_spec.rb +71 -0
  31. data/lib/vendor/rest-client/spec/request_errors_spec.rb +44 -0
  32. data/lib/vendor/rest-client/spec/resource_spec.rb +52 -0
  33. data/lib/vendor/rest-client/spec/rest_client_spec.rb +219 -0
  34. data/test/api_test.rb +28 -0
  35. data/test/fixtures/apple_multipart.txt +100 -0
  36. data/test/fixtures/bad_content_type.txt +27 -0
  37. data/test/fixtures/basic.txt +14 -0
  38. data/test/fixtures/custom.txt +15 -0
  39. data/test/fixtures/fwd.txt +0 -0
  40. data/test/fixtures/gb2312_encoding.txt +16 -0
  41. data/test/fixtures/gb2312_encoding_invalid.txt +15 -0
  42. data/test/fixtures/html.txt +16 -0
  43. data/test/fixtures/iso-8859-1.txt +13 -0
  44. data/test/fixtures/mapped.txt +13 -0
  45. data/test/fixtures/multipart.txt +213 -0
  46. data/test/fixtures/multipart2.txt +213 -0
  47. data/test/fixtures/multiple.txt +13 -0
  48. data/test/fixtures/multiple_delivered_to.txt +14 -0
  49. data/test/fixtures/multiple_with_body_recipients.txt +15 -0
  50. data/test/fixtures/reply.txt +16 -0
  51. data/test/fixtures/utf-8.txt +13 -0
  52. data/test/logged_mail_test.rb +67 -0
  53. data/test/mapping_test.rb +129 -0
  54. data/test/message_test.rb +440 -0
  55. data/test/test_helper.rb +57 -0
  56. data/test/transport_test.rb +111 -0
  57. metadata +225 -0
@@ -0,0 +1,26 @@
1
+ .DS_Store
2
+ .rake_tasks
3
+ log/*
4
+ tmp/*
5
+ TAGS
6
+ *~
7
+ .#*
8
+ pkg
9
+ schema/schema.rb
10
+ schema/*_structure.sql
11
+ schema/*.sqlite3
12
+ schema/*.sqlite
13
+ schema/*.db
14
+ *.sqlite
15
+ *.sqlite3
16
+ *.db
17
+ src/*
18
+ .hgignore
19
+ .hg/*
20
+ .svn/*
21
+ doc
22
+ config/database.yml
23
+ merb/custom.rb
24
+ test/fixtures/queue
25
+ messages
26
+ test/messages
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-* ENTP
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,47 @@
1
+ astrotrain
2
+ ==========
3
+
4
+ NOTE: Astrotrain is a full gem now. If you're looking for the old Astrotrain on merb:
5
+ http://github.com/entp/astrotrain/tree/merb
6
+ git://github.com/entp/astrotrain.git (merb branch)
7
+
8
+ Scans incoming emails for mapped recipients and sends an HTTP POST somewhere.
9
+
10
+ # setup a config file.
11
+ # Point the queue_path at a directory that your mail server dumps each raw incoming mail.
12
+ require 'astrotrain'
13
+
14
+ Astrotrain.load path do
15
+ DataMapper.setup(:default, {
16
+ :adapter => "mysql",
17
+ :database => "astrotrain",
18
+ :username => "root",
19
+ :host => "localhost"
20
+ })
21
+ end
22
+ Astrotrain::Message.queue_path = "/path/to/maildir"
23
+ Astrotrain::Mapping::Transport.processing = true
24
+
25
+ # start up IRB
26
+ irb -I /var/astrotrain/lib -r config.rb
27
+
28
+ # manage mappings
29
+ LIB=/var/astrotrain/lib CONFIG=config.rb rake at:mappings
30
+ LIB=/var/astrotrain/lib CONFIG=config.rb rake at:map EMAIL=support@foo.com DEST=http://foo.com/email
31
+ LIB=/var/astrotrain/lib CONFIG=config.rb rake at:unmap MAP=123
32
+
33
+ # start the server that runs over the queue directory
34
+ LIB=/var/astrotrain/lib CONFIG=config.rb rake at:process
35
+
36
+ # start the sinatra API
37
+ ruby -I /var/astrotrain/lib /var/astrotrain/lib/astrotrain/api.rb config.rb
38
+
39
+ A single Astrotrain process currently handles email for two production applications, processing thousands daily.
40
+ It's far from perfect, but definitely usable.
41
+
42
+ TODO
43
+ ====
44
+
45
+ Gem package - I realize the load paths could be simplified a bunch, so a gem package will come soon.
46
+ Docs
47
+ bounced emails
@@ -0,0 +1,122 @@
1
+ require 'rake'
2
+
3
+ begin
4
+ require 'jeweler'
5
+ Jeweler::Tasks.new do |gem|
6
+ gem.name = "astrotrain"
7
+ gem.summary = %Q{email => http post}
8
+ gem.email = "technoweenie@gmail.com"
9
+ gem.homepage = "http://github.com/entp/astrotrain"
10
+ gem.authors = ["technoweenie"]
11
+
12
+ dm_ver = "0.9.11"
13
+ gem.add_runtime_dependency 'addressable', '2.0.2'
14
+ gem.add_runtime_dependency "tmail", "1.2.3.1"
15
+ gem.add_runtime_dependency "dm-core", dm_ver # The datamapper ORM
16
+ gem.add_runtime_dependency "dm-aggregates", dm_ver # Provides your DM models with count, sum, avg, min, max, etc.
17
+ gem.add_runtime_dependency "dm-timestamps", dm_ver # Automatically populate created_at, created_on, etc. when those properties are present.
18
+ gem.add_runtime_dependency "dm-types", dm_ver # Provides additional types, including csv, json, yaml.
19
+ gem.add_runtime_dependency "dm-validations", dm_ver # Validation framework
20
+ gem.add_development_dependency "context"
21
+ gem.add_development_dependency "rr"
22
+ gem.add_development_dependency "sinatra"
23
+ gem.add_development_dependency "xmppr4-simple"
24
+ end
25
+
26
+ rescue LoadError
27
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
28
+ end
29
+
30
+ namespace :at do
31
+ task :init do
32
+ $LOAD_PATH.unshift File.expand_path(ENV['LIB']) if ENV['LIB']
33
+ require ENV['CONFIG'] if ENV['CONFIG']
34
+
35
+ if !Object.const_defined?(:Astrotrain)
36
+ require 'astrotrain'
37
+ Astrotrain.load
38
+ end
39
+
40
+ Astrotrain::Message.queue_path = ENV['QUEUE'] if ENV['QUEUE']
41
+ if !File.exist?(Astrotrain::Message.queue_path)
42
+ puts "No Queue: #{Astrotrain.queue_path.inspect}"
43
+ exit
44
+ end
45
+ end
46
+
47
+ desc "List Mappings"
48
+ task :mappings => :init do
49
+ Astrotrain::Mapping.all.each do |map|
50
+ puts "##{map.id}: #{map.full_email} => #{map.destination}"
51
+ puts "Separated by: #{map.separator.inspect}" if !map.separator.blank?
52
+ puts
53
+ end
54
+ end
55
+
56
+ desc "Add mapping EMAIL=ticket*@foo.com DEST=http://foo.com/email [TRANS=(http_post|jabber)] [SEP=REPLYABOVEHERE] [HEADERS=delivered_to,to,original_to]"
57
+ task :map => :init do
58
+ map = Astrotrain::Mapping.new
59
+ map.email_user, map.email_domain = ENV['EMAIL'].to_s.split('@')
60
+ map.destination = ENV['DEST']
61
+ map.transport = ENV['TRANS'] if ENV['TRANS']
62
+ map.separator = ENV['SEP'] if ENV['SEP']
63
+ if map.save
64
+ puts "Mapping created for #{map.full_email} => #{map.destination}"
65
+ Rake::Task['at:mappings'].invoke
66
+ else
67
+ puts map.inspect
68
+ puts map.errors.inspect
69
+ end
70
+ end
71
+
72
+ desc "Remove mapping MAP=123"
73
+ task :unmap => :init do
74
+ map = Astrotrain::Mapping.get(ENV["MAP"])
75
+ map.destroy if map
76
+ Rake::Task['at:mappings'].invoke
77
+ end
78
+
79
+ desc "Start astrotrain DRb server."
80
+ task :process => :init do
81
+ require 'astrotrain/worker'
82
+ Astrotrain::Worker.start
83
+ end
84
+ end
85
+
86
+ require 'rake/testtask'
87
+ Rake::TestTask.new do |t|
88
+ t.test_files = FileList['test/*_test.rb']
89
+ t.verbose = true
90
+ end
91
+
92
+ begin
93
+ require 'rcov/rcovtask'
94
+ Rcov::RcovTask.new do |test|
95
+ test.libs << 'test'
96
+ test.pattern = 'test/**/*_test.rb'
97
+ test.verbose = true
98
+ end
99
+ rescue LoadError
100
+ task :rcov do
101
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
102
+ end
103
+ end
104
+
105
+ require 'rake/rdoctask'
106
+ Rake::RDocTask.new do |rdoc|
107
+ if File.exist?('VERSION.yml')
108
+ config = YAML.load(File.read('VERSION.yml'))
109
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
110
+ else
111
+ version = ""
112
+ end
113
+
114
+ rdoc.rdoc_dir = 'rdoc'
115
+ rdoc.title = "astrotrain #{version}"
116
+ rdoc.rdoc_files.include('README*')
117
+ rdoc.rdoc_files.include('lib/**/*.rb')
118
+ end
119
+
120
+
121
+ desc 'Default: run test examples'
122
+ task :default => 'test'
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.1
@@ -0,0 +1,129 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{astrotrain}
5
+ s.version = "0.3.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["technoweenie"]
9
+ s.date = %q{2009-09-25}
10
+ s.email = %q{technoweenie@gmail.com}
11
+ s.extra_rdoc_files = [
12
+ "LICENSE",
13
+ "README"
14
+ ]
15
+ s.files = [
16
+ ".gitignore",
17
+ "LICENSE",
18
+ "README",
19
+ "Rakefile",
20
+ "VERSION",
21
+ "astrotrain.gemspec",
22
+ "config/sample.rb",
23
+ "lib/astrotrain.rb",
24
+ "lib/astrotrain/api.rb",
25
+ "lib/astrotrain/logged_mail.rb",
26
+ "lib/astrotrain/mapping.rb",
27
+ "lib/astrotrain/mapping/http_post.rb",
28
+ "lib/astrotrain/mapping/jabber.rb",
29
+ "lib/astrotrain/mapping/transport.rb",
30
+ "lib/astrotrain/message.rb",
31
+ "lib/astrotrain/tmail.rb",
32
+ "lib/astrotrain/worker.rb",
33
+ "lib/vendor/rest-client/README.rdoc",
34
+ "lib/vendor/rest-client/Rakefile",
35
+ "lib/vendor/rest-client/bin/restclient",
36
+ "lib/vendor/rest-client/foo.diff",
37
+ "lib/vendor/rest-client/lib/rest_client.rb",
38
+ "lib/vendor/rest-client/lib/rest_client/net_http_ext.rb",
39
+ "lib/vendor/rest-client/lib/rest_client/payload.rb",
40
+ "lib/vendor/rest-client/lib/rest_client/request_errors.rb",
41
+ "lib/vendor/rest-client/lib/rest_client/resource.rb",
42
+ "lib/vendor/rest-client/rest-client.gemspec",
43
+ "lib/vendor/rest-client/spec/base.rb",
44
+ "lib/vendor/rest-client/spec/master_shake.jpg",
45
+ "lib/vendor/rest-client/spec/payload_spec.rb",
46
+ "lib/vendor/rest-client/spec/request_errors_spec.rb",
47
+ "lib/vendor/rest-client/spec/resource_spec.rb",
48
+ "lib/vendor/rest-client/spec/rest_client_spec.rb",
49
+ "test/api_test.rb",
50
+ "test/fixtures/apple_multipart.txt",
51
+ "test/fixtures/bad_content_type.txt",
52
+ "test/fixtures/basic.txt",
53
+ "test/fixtures/custom.txt",
54
+ "test/fixtures/fwd.txt",
55
+ "test/fixtures/gb2312_encoding.txt",
56
+ "test/fixtures/gb2312_encoding_invalid.txt",
57
+ "test/fixtures/html.txt",
58
+ "test/fixtures/iso-8859-1.txt",
59
+ "test/fixtures/mapped.txt",
60
+ "test/fixtures/multipart.txt",
61
+ "test/fixtures/multipart2.txt",
62
+ "test/fixtures/multiple.txt",
63
+ "test/fixtures/multiple_delivered_to.txt",
64
+ "test/fixtures/multiple_with_body_recipients.txt",
65
+ "test/fixtures/reply.txt",
66
+ "test/fixtures/utf-8.txt",
67
+ "test/logged_mail_test.rb",
68
+ "test/mapping_test.rb",
69
+ "test/message_test.rb",
70
+ "test/test_helper.rb",
71
+ "test/transport_test.rb"
72
+ ]
73
+ s.homepage = %q{http://github.com/entp/astrotrain}
74
+ s.rdoc_options = ["--charset=UTF-8"]
75
+ s.require_paths = ["lib"]
76
+ s.rubygems_version = %q{1.3.4}
77
+ s.summary = %q{email => http post}
78
+ s.test_files = [
79
+ "test/api_test.rb",
80
+ "test/logged_mail_test.rb",
81
+ "test/mapping_test.rb",
82
+ "test/message_test.rb",
83
+ "test/test_helper.rb",
84
+ "test/transport_test.rb"
85
+ ]
86
+
87
+ if s.respond_to? :specification_version then
88
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
89
+ s.specification_version = 3
90
+
91
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
92
+ s.add_runtime_dependency(%q<addressable>, ["= 2.0.2"])
93
+ s.add_runtime_dependency(%q<tmail>, ["= 1.2.3.1"])
94
+ s.add_runtime_dependency(%q<dm-core>, ["= 0.9.11"])
95
+ s.add_runtime_dependency(%q<dm-aggregates>, ["= 0.9.11"])
96
+ s.add_runtime_dependency(%q<dm-timestamps>, ["= 0.9.11"])
97
+ s.add_runtime_dependency(%q<dm-types>, ["= 0.9.11"])
98
+ s.add_runtime_dependency(%q<dm-validations>, ["= 0.9.11"])
99
+ s.add_development_dependency(%q<context>, [">= 0"])
100
+ s.add_development_dependency(%q<rr>, [">= 0"])
101
+ s.add_development_dependency(%q<sinatra>, [">= 0"])
102
+ s.add_development_dependency(%q<xmppr4-simple>, [">= 0"])
103
+ else
104
+ s.add_dependency(%q<addressable>, ["= 2.0.2"])
105
+ s.add_dependency(%q<tmail>, ["= 1.2.3.1"])
106
+ s.add_dependency(%q<dm-core>, ["= 0.9.11"])
107
+ s.add_dependency(%q<dm-aggregates>, ["= 0.9.11"])
108
+ s.add_dependency(%q<dm-timestamps>, ["= 0.9.11"])
109
+ s.add_dependency(%q<dm-types>, ["= 0.9.11"])
110
+ s.add_dependency(%q<dm-validations>, ["= 0.9.11"])
111
+ s.add_dependency(%q<context>, [">= 0"])
112
+ s.add_dependency(%q<rr>, [">= 0"])
113
+ s.add_dependency(%q<sinatra>, [">= 0"])
114
+ s.add_dependency(%q<xmppr4-simple>, [">= 0"])
115
+ end
116
+ else
117
+ s.add_dependency(%q<addressable>, ["= 2.0.2"])
118
+ s.add_dependency(%q<tmail>, ["= 1.2.3.1"])
119
+ s.add_dependency(%q<dm-core>, ["= 0.9.11"])
120
+ s.add_dependency(%q<dm-aggregates>, ["= 0.9.11"])
121
+ s.add_dependency(%q<dm-timestamps>, ["= 0.9.11"])
122
+ s.add_dependency(%q<dm-types>, ["= 0.9.11"])
123
+ s.add_dependency(%q<dm-validations>, ["= 0.9.11"])
124
+ s.add_dependency(%q<context>, [">= 0"])
125
+ s.add_dependency(%q<rr>, [">= 0"])
126
+ s.add_dependency(%q<sinatra>, [">= 0"])
127
+ s.add_dependency(%q<xmppr4-simple>, [">= 0"])
128
+ end
129
+ end
@@ -0,0 +1,12 @@
1
+ path = File.join(File.dirname(__FILE__), '..')
2
+ $LOAD_PATH.unshift File.join(path, 'lib')
3
+ require 'astrotrain'
4
+
5
+ Astrotrain.load path do
6
+ DataMapper.setup(:default, {
7
+ :adapter => "mysql",
8
+ :database => "astrotrain",
9
+ :username => "root",
10
+ :host => "localhost"
11
+ })
12
+ end
@@ -0,0 +1,53 @@
1
+ module Astrotrain
2
+ CALLBACK_TYPES = [:pre_mapping, :pre_processing, :post_processing]
3
+ class << self
4
+ attr_accessor :root, :lib_root, :callbacks
5
+ end
6
+
7
+ def self.load(root = Dir.pwd)
8
+ self.root = File.expand_path(root)
9
+ self.lib_root = File.expand_path(File.dirname(__FILE__))
10
+ load_dependencies
11
+ yield if block_given?
12
+ %w(tmail message mapping logged_mail mapping/transport mapping/http_post mapping/jabber).each do |lib|
13
+ require "astrotrain/#{lib}"
14
+ end
15
+ Astrotrain::Mail::ALLOW_MULTIPLE['delivered-to'] = true
16
+ end
17
+
18
+ def self.callback(name, *args, &block)
19
+ found = callbacks[name]
20
+ if block
21
+ found << block
22
+ else
23
+ found.each { |cback| cback.call(*args) }
24
+ end
25
+ found
26
+ end
27
+
28
+ def self.clear_callbacks
29
+ self.callbacks = CALLBACK_TYPES.inject({}) { |memo, ctype| memo.update(ctype => []) }
30
+ end
31
+
32
+ clear_callbacks
33
+
34
+ private
35
+ # help me ryan tomayko, you're my only help
36
+ def self.load_dependencies
37
+ require 'rubygems'
38
+ gem 'addressable', '2.0.2'
39
+
40
+ dm_ver = "0.9.11"
41
+ gem "dm-core", dm_ver # The datamapper ORM
42
+ gem "dm-aggregates", dm_ver # Provides your DM models with count, sum, avg, min, max, etc.
43
+ gem "dm-timestamps", dm_ver # Automatically populate created_at, created_on, etc. when those properties are present.
44
+ gem "dm-types", dm_ver # Provides additional types, including csv, json, yaml.
45
+ gem "dm-validations", dm_ver # Validation framework
46
+
47
+ $LOAD_PATH.unshift File.join(lib_root, 'vendor', 'rest-client', 'lib')
48
+
49
+ %w(dm-core dm-aggregates dm-timestamps dm-types dm-validations tmail rest_client).each do |lib|
50
+ require lib
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,52 @@
1
+ require 'sinatra'
2
+
3
+ before do
4
+ response['Content-Type'] = 'text/plain'
5
+ end
6
+
7
+ get '/queue_size' do
8
+ if File.exist?(Astrotrain::Message.queue_path)
9
+ (Dir.entries(Astrotrain::Message.queue_path).size - 2).to_s
10
+ else
11
+ '0'
12
+ end
13
+ end
14
+
15
+ get '/queue/*' do
16
+ path = params[:splat].first
17
+ path.gsub! /^\/+/, ''
18
+ file = File.join(Astrotrain::Message.queue_path, path)
19
+ if File.exist?(file)
20
+ IO.read(file)
21
+ else
22
+ halt 404, "#{path.inspect} was not found."
23
+ end
24
+ end
25
+
26
+ get '/queue' do
27
+ data = []
28
+ Dir.entries(Astrotrain::Message.queue_path).each do |e|
29
+ data << e unless e =~ /^\.{1,2}$/
30
+ end
31
+ data * "\n"
32
+ end
33
+
34
+ unless $testing
35
+ configure do
36
+ # the idea being, you pass the name of the config file
37
+ #
38
+ # # loads File.join(Dir.pwd, 'config.rb')
39
+ # CONFIG=config ruby lib/astrotrain/api.rb
40
+ #
41
+ # # loads File.join(Dir.pwd, 'config.rb')
42
+ # ruby lib/astrotrain/api.rb config
43
+ #
44
+ # That file contains the Greymalkin.load block that initializes Sequel
45
+ #
46
+ path = ENV['CONFIG'] || ARGV.shift
47
+ if path[0..0] != '/'
48
+ path = File.join(Dir.pwd, path)
49
+ end
50
+ require File.expand_path(path)
51
+ end
52
+ end