cargobull 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8afc99ac65f76c719411449cec7fffb3117f2c80
4
+ data.tar.gz: fd4ad2a39ecd949df7233668ddd57b435f7cefe2
5
+ SHA512:
6
+ metadata.gz: 5396ab2ec3a1ce7e4966bcad1320e49f48fbef53923d033a0806b5fc5f041aa6ab23840b37410406d02eb909b7c4d7bd5af3723389f749943deefb970d3e9d6d
7
+ data.tar.gz: 0571ae1fa809f89bc63f0e9dbce8bcd520253cd628202d6e77bca0752768fa54054c58e08142729665cdf2eb75a4d7089b3f08cc5f8cf9c66a073f947cb2c895
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2014, Matthias Geier
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,11 @@
1
+ require 'cargobull/extensions/string'
2
+ require 'cargobull/env'
3
+ require 'cargobull/service'
4
+ require 'cargobull/dispatch'
5
+ require 'cargobull/rackup'
6
+
7
+ if File.exist?('./setup.rb')
8
+ require 'cargobull/initialize'
9
+ require './setup'
10
+ Cargobull::Initialize.init_all
11
+ end
@@ -0,0 +1,47 @@
1
+
2
+ module Cargobull
3
+ module Dispatch
4
+ def self.translate_method_call(method)
5
+ return case method.to_s.downcase
6
+ when "get", "post"
7
+ :read
8
+ when "put"
9
+ :create
10
+ when "patch"
11
+ :update
12
+ when "delete"
13
+ :delete
14
+ else
15
+ raise RuntimeError.new("Unsupported method: #{method}")
16
+ end
17
+ end
18
+
19
+ def self.translate_action_call(action)
20
+ klass = Service.dispatch_to(action)
21
+ if klass.nil?
22
+ raise RuntimeError.new("Unsupported action: #{action}")
23
+ end
24
+ return klass
25
+ end
26
+
27
+ def self.call(method, action, *args)
28
+ klass = self.translate_action_call(action)
29
+
30
+ blk = Cargobull.env.transform_in
31
+ args = [blk.call(*args)] if blk
32
+
33
+ obj = klass.new(*args)
34
+ method = self.translate_method_call(method)
35
+ unless obj.respond_to?(method)
36
+ raise RuntimeError.new("#{action} does not respond to #{method}")
37
+ end
38
+
39
+ return self.transform(obj.send(method))
40
+ end
41
+
42
+ def self.transform(data)
43
+ blk = Cargobull.env.transform_out
44
+ return blk ? blk.call(data) : data
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+
2
+ module Cargobull
3
+ def self.env
4
+ return Env
5
+ end
6
+
7
+ class Env
8
+ class << self
9
+ attr_reader :dispatch_url, :serve_url, :transform_out, :transform_in
10
+ attr_accessor :default_files
11
+ end
12
+
13
+ @dispatch_url = "/"
14
+ @serve_url = "/files"
15
+ @default_files = ['index.html', 'index.htm']
16
+
17
+ def self.dispatch_url=(url)
18
+ sanitized_url = (url || "").split('/').reject(&:empty?).first
19
+ @dispatch_url = sanitized_url ? "/#{sanitized_url}" : "/"
20
+ @serve_url = sanitized_url ? "/" : "/files"
21
+ end
22
+
23
+ def self.transform_out=(blk)
24
+ @transform_out = blk
25
+ end
26
+
27
+ def self.transform_in=(blk)
28
+ @transform_in = blk
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,55 @@
1
+ # = String class extension
2
+ #
3
+ # A string that is supposed to becode a Module, Class or similar can be
4
+ # transformed by using #constantize
5
+ #
6
+ # "Array".constantize
7
+ # => Array
8
+ #
9
+ # When writing file names in ruby, they are usually an underscore (snakecase)
10
+ # representation of the class name. It can be transformed with #camelize and
11
+ # in place with #camelize!
12
+ #
13
+ # "file_reader".camelize
14
+ # => "FileReader"
15
+ #
16
+ # s = "file_reader"
17
+ # s.camelize!
18
+ # s
19
+ # => "FileReader"
20
+ #
21
+ # The backwards transformation from a class name to snakecase is done with
22
+ # #underscore and in place with #underscore!
23
+ #
24
+ # "FileReader".underscore
25
+ # => "file_reader"
26
+ #
27
+ # s = "FileReader".underscore
28
+ # s.underscore!
29
+ # s
30
+ # => "file_reader"
31
+ #
32
+ #
33
+ #
34
+ class String
35
+ def constantize
36
+ return self.to_s.split('::').reduce(Module){ |m, c| m.const_get(c) }
37
+ end
38
+
39
+ def camelize
40
+ return self.to_s.split(/_/).map(&:capitalize).join
41
+ end
42
+
43
+ def camelize!
44
+ self.replace(self.to_s.camelize)
45
+ end
46
+
47
+ def underscore
48
+ return self.to_s.split(/([A-Z]?[^A-Z]*)/).reject(&:empty?).
49
+ map(&:downcase).join('_')
50
+ end
51
+
52
+ def underscore!
53
+ self.replace(self.to_s.underscore)
54
+ end
55
+ end
@@ -0,0 +1,35 @@
1
+
2
+ module Cargobull
3
+ module Initialize
4
+ @file_map = []
5
+
6
+ def self.sanitize_file_name(file_name)
7
+ return "./#{File.basename(file_name)}"
8
+ end
9
+
10
+ def self.dir(*args)
11
+ sanitized_args = args.map{ |d| sanitize_file_name(d).sub(/\/$/, '') }.
12
+ select{ |d| File.directory?(d) }
13
+
14
+ sanitized_args.each do |dir|
15
+ ruby_files = Dir["#{dir}/*.rb"]
16
+ @file_map = ruby_files.reduce(@file_map) do |acc, f|
17
+ file_name = File.basename(f).sub(/\.rb$/, '')
18
+ Object.autoload(file_name.camelize, f)
19
+ acc << f
20
+ end
21
+ end
22
+ end
23
+
24
+ def self.file(klass_str, file_name)
25
+ file_name = sanitize_file_name(file_name)
26
+ return unless File.file?(file_name)
27
+ Object.autoload(klass_str, file_name)
28
+ @file_map << file_name
29
+ end
30
+
31
+ def self.init_all
32
+ @file_map.each{ |file| require file }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+
2
+ module Cargobull
3
+ class Rackup
4
+ def file(env)
5
+ path = env["REQUEST_PATH"]
6
+ path.gsub!(/\/\.+/, '')
7
+ path.sub!(/^#{Cargobull.env.serve_url}\/?/i, '')
8
+ if path.empty?
9
+ path = Cargobull.env.default_files.detect do |f|
10
+ File.file?("./files/#{f}")
11
+ end
12
+ end
13
+ path = "./files/#{path}"
14
+ if File.file?(path)
15
+ return [200, {}, File.open(path, File::RDONLY)]
16
+ else
17
+ return [404, {}, "Not found"]
18
+ end
19
+ end
20
+
21
+ def dispatch(env)
22
+ req = Rack::Request.new(env)
23
+ action = env["REQUEST_PATH"].sub(/^#{Cargobull.env.dispatch_url}\/?/, '').
24
+ gsub(/\/[^\/]+/, '')
25
+ params = req.POST.merge(req.GET)
26
+ data = Cargobull::Dispatch.call(env["REQUEST_METHOD"], action, params)
27
+ return [200, {}, data]
28
+ rescue RuntimeError
29
+ return [404, {}, "Not found"]
30
+ end
31
+
32
+ def self.routes
33
+ routes = [
34
+ [/^#{Cargobull.env.serve_url}\/?/i, :file],
35
+ [/^#{Cargobull.env.dispatch_url}\/?/i, :dispatch]
36
+ ]
37
+ routes.reverse! if Cargobull.env.serve_url == '/'
38
+ return routes.unshift([/^\/favicon/i, :file])
39
+ end
40
+
41
+ def call(env)
42
+ path = env["REQUEST_PATH"]
43
+ _, match_method = self.class.routes.detect{ |pattern, _| path =~ pattern }
44
+ return self.send(match_method, env)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+
2
+ module Cargobull
3
+ module Service
4
+ @dispatch = []
5
+
6
+ def self.dispatch
7
+ return @dispatch
8
+ end
9
+
10
+ def self.dispatch_to(action)
11
+ return self.dispatch.detect do |klass|
12
+ next klass.name.underscore == action.to_s
13
+ end
14
+ end
15
+
16
+ def self.register(klass)
17
+ @dispatch << klass
18
+ end
19
+
20
+ def self.included(base)
21
+ self.register base
22
+ end
23
+
24
+ def initialize(*args)
25
+ @params = args.shift
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,37 @@
1
+ require 'cargobull'
2
+
3
+ module Cargobull
4
+ module TestHelper
5
+ def response
6
+ return @response || ""
7
+ end
8
+
9
+ [:get, :post, :put, :patch, :delete].each do |m|
10
+ define_method(m) do |action, *args|
11
+ @response = nil
12
+ @response = Cargobull::Dispatch.call(m, action, *args)
13
+ end
14
+ end
15
+
16
+ def assert_raise(except_klass)
17
+ begin
18
+ yield
19
+ rescue except_klass
20
+ assert true
21
+ return
22
+ end
23
+ assert false
24
+ end
25
+
26
+ def assert_nothing_raised
27
+ begin
28
+ yield
29
+ assert true
30
+ rescue
31
+ assert false
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ include Cargobull::TestHelper
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cargobull
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matthias Geier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-08-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - LICENSE.md
20
+ - lib/cargobull.rb
21
+ - lib/cargobull/dispatch.rb
22
+ - lib/cargobull/env.rb
23
+ - lib/cargobull/extensions/string.rb
24
+ - lib/cargobull/initialize.rb
25
+ - lib/cargobull/rackup.rb
26
+ - lib/cargobull/service.rb
27
+ - lib/cargobull/test_helper.rb
28
+ homepage: https://github.com/matthias-geier/cargobull
29
+ licenses:
30
+ - BSD-2
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.1.0
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.2.2
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Multipurpose dispatcher for RESTful services
52
+ test_files: []