actionframework 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2dfbfdbff057caaa49f475b6181cfe8a8c65a1c
4
- data.tar.gz: a232de6f77636b5790bd31cb3f06887da70223a3
3
+ metadata.gz: 3aedef6d1f194574cd1d6d70060908e52a00d3f8
4
+ data.tar.gz: b3a016326a7c9d37233d02905ffa5f6cc40a3c74
5
5
  SHA512:
6
- metadata.gz: 60ca2cf0c2938de702fa57cebaa58bcd4fd4d6e5c5522454337a55bea0ec1f3db7ce60308f674bccc7def60214980d97fe03d6cfd5e21725c7d2c4ebf0de90d3
7
- data.tar.gz: 4167766a9254097c0b2f8aca143708a9dae10c9b3f01a109b7b955e590ed84f9a112972efc724a72bbeac3ca059cfe62babc1b35caeb41ee77e226ce72bb2b47
6
+ metadata.gz: de9f3c95ef8262b36a83823e0ff6947187810eda5506c818020aac3818b0911736524227e5759fe62297f3fe1d9a7b27190795f50a19cbe0c07a962e5f07f857
7
+ data.tar.gz: 20399cbb33d4ac43b61b40dec725e5250f5e17102b6d66403b9c88d8a6fd0954dfc02e376d1d0b56707f0c3be743c693f5d7807b15432120516afed820227b05
data/bin/action ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optitron'
3
+ require 'fileutils'
4
+ require 'actionframework'
5
+ require 'json'
6
+ require 'httparty'
7
+
8
+ class String
9
+ def black; "\033[30m#{self}\033[0m" end
10
+ def red; "\033[31m#{self}\033[0m" end
11
+ def green; "\033[32m#{self}\033[0m" end
12
+ def brown; "\033[33m#{self}\033[0m" end
13
+ def blue; "\033[34m#{self}\033[0m" end
14
+ def magenta; "\033[35m#{self}\033[0m" end
15
+ def cyan; "\033[36m#{self}\033[0m" end
16
+ def gray; "\033[37m#{self}\033[0m" end
17
+ def bg_black; "\033[40m#{self}\0330m" end
18
+ def bg_red; "\033[41m#{self}\033[0m" end
19
+ def bg_green; "\033[42m#{self}\033[0m" end
20
+ def bg_brown; "\033[43m#{self}\033[0m" end
21
+ def bg_blue; "\033[44m#{self}\033[0m" end
22
+ def bg_magenta; "\033[45m#{self}\033[0m" end
23
+ def bg_cyan; "\033[46m#{self}\033[0m" end
24
+ def bg_gray; "\033[47m#{self}\033[0m" end
25
+ def bold; "\033[1m#{self}\033[22m" end
26
+ def reverse_color; "\033[7m#{self}\033[27m" end
27
+ end
28
+
29
+ class ActionFrameworkCLI < Optitron::CLI
30
+ desc "About ActionFramework"
31
+ def about
32
+ puts "ActionFramework (previously called ActionFramework) is a web application framework that tries to be as flexible as sinatra and at the same time have the structure of rails.Enjoy!"
33
+ end
34
+ desc "Create ActionFramework project"
35
+ def new projectname
36
+ puts "Creating project directory and structure"
37
+ Dir.mkdir("#{projectname}")
38
+ Dir.mkdir("#{projectname}/controllers")
39
+ Dir.mkdir("#{projectname}/models")
40
+ Dir.mkdir("#{projectname}/views")
41
+ Dir.mkdir("#{projectname}/config")
42
+ Dir.mkdir("#{projectname}/static")
43
+ Dir.mkdir("#{projectname}/initializers")
44
+ FileUtils.touch("#{projectname}/views/layout.html.erb")
45
+ FileUtils.touch("#{projectname}/Gemfile")
46
+ File.write("#{projectname}/main.rb","# Example of basic configuration\nActionFramework = ActionFramework::Server.new\n\nnActionFramework.autoimport\nActionFramework.start")
47
+ File.write("#{projectname}/controllers/default_controller.rb","class DefaultController < ActionFramework::Controller
48
+ \n def index\n \"<h1>Welcome to ActionFramework</h1><i>Great Opensource Ruby Server</i><p>ActionFramework is loading routes from routes.json but you should write your own main.rb<br/>This is just to gettings started</p>\"\n end\nend");
49
+ File.write("#{projectname}/routes.json","{\n \"get\": [{\n \"/\": \"DefaultController#index\"\n}]\n}")
50
+ File.write("#{projectname}/config/routes.rb","ActionFramework::Server.current.routes do\n\n get \"/\" => \"DefaultController#index\"\n\nend")
51
+ File.write("#{projectname}/config/settings.rb","ActionFramework::Server.current.settings do |s|\n\nend")
52
+ File.write("#{projectname}/Gemfile","source 'https://rubygems.org'\n\ngem 'actionframework'")
53
+ File.write("#{projectname}/config.ru","require 'actionframework'\n\nrun ActionFramework::Base.new")
54
+ File.write("#{projectname}/config/plugables.rb","ActionFramework::Plugables.new do \n\nend")
55
+ system("cd #{projectname} && bundle install")
56
+ puts "Done"
57
+ puts "Run \"afw s\" to run your app"
58
+ end
59
+
60
+ desc "Start ActionFramework server"
61
+ def s
62
+ `rackup`
63
+ end
64
+
65
+ desc "Start ActionFramework console"
66
+ def c
67
+ $runningserver = ActionFramework::Server.new
68
+ puts "Starting ActionFramework IRB"
69
+ require 'irb'
70
+ ARGV.clear
71
+ IRB.start
72
+ end
73
+
74
+ desc "Install Stock plugables and add sources list"
75
+ def install_plugables
76
+ puts "Creating plugables directory".blue
77
+ puts "Downloading plugables sources list...".blue
78
+ Dir.mkdir(Dir.home+"/.actionframework/")
79
+ Dir.mkdir(Dir.home+"/.actionframework/plugables/")
80
+ Dir.mkdir(Dir.home+"/.actionframework/plugables/sources/")
81
+ Dir.mkdir(Dir.home+"/.actionframework/plugables/plugs/")
82
+
83
+ begin
84
+ plugables = HTTParty.get("https://raw.github.com/actionframework/plubables/master/sources.json").body
85
+ File.write(Dir.home+"/.actionframework/plugables/sources/list.json",plugables)
86
+ puts "Downloading stock plugables...".blue
87
+ plugables["stock"].each do |plugable|
88
+ puts "Downloading ".plugable["name"]+"..."
89
+ source = HTTParty.get("https://raw.github.com/actionframework/plugables/master/plugs/"+plugable["name"]+".rb").body
90
+ File.write(Dir.home+"/.actionframework/plugables/plugs/"+plugable["name"],source)
91
+ end
92
+ rescue Exception => e
93
+ puts "ERROR: Something went wrong".red
94
+ puts "ERROR: "+e.message.red
95
+ puts "LOG: "+e.backtrace.inspect
96
+ end
97
+ puts "Done".green
98
+ end
99
+ end
100
+
101
+ ActionFrameworkCLI.dispatch
@@ -3,9 +3,16 @@ require 'tilt'
3
3
  require 'json'
4
4
  require 'erb'
5
5
 
6
+ require 'actionframework/string'
7
+ require 'actionframework/gemextra'
8
+ require 'actionframework/gem'
6
9
  require 'actionframework/routes'
7
10
  require 'actionframework/controller'
8
11
  require 'actionframework/settings'
12
+ require 'actionframework/error_handler'
13
+ require 'actionframework/modelhelper'
14
+ require 'actionframework/realtime'
15
+ require 'actionframework/base'
9
16
 
10
17
  $runningserver = nil
11
18
 
@@ -44,6 +51,7 @@ module ActionFramework
44
51
 
45
52
  require './config/routes'
46
53
  require './config/settings'
54
+ require './config/plugables'
47
55
 
48
56
  Dir.glob("initializers/*").each do |file|
49
57
  require './'+file
@@ -55,9 +63,13 @@ module ActionFramework
55
63
  req = Rack::Request.new(env)
56
64
  res = Rack::Response.new
57
65
 
66
+ # auto-api feature (only at path /api/*)
67
+ getModelResponse req,res
68
+
58
69
  controllerinfo = @routesklass.route(req.path,req.request_method)
59
70
  if(controllerinfo == nil)
60
- res.write "<h1>404 Not found</h1>"
71
+ res.body = [ActionFramework::ErrorHandler.new(req,res,{}).send("error_404")]
72
+ res.status = 404
61
73
  return res.finish
62
74
  end
63
75
 
@@ -80,5 +92,32 @@ module ActionFramework
80
92
  def start
81
93
  Rack::Server.new({:app => self,:server => @settings.server, :Port => @settings.port}).start
82
94
  end
95
+
96
+ def getModelResponse req,res
97
+ # auto-api start
98
+ # [todo] add api security with policies
99
+ if(matcheddate = req.path.match(Regexp.new("^/api/(?<modelname>(.*))$")))
100
+ policy = @routesklass.models[matcheddata[:modelname]]
101
+ if(policy != nil)
102
+ res.headers = {"Content-type" => "application/json"}
103
+ model = Object.const_get(matcheddata[:modelname])
104
+ case req.request_method
105
+ when "POST"
106
+ ActionFramework::ModelHelper.post model,res
107
+ when "GET"
108
+ ActionFramework::ModelHelper.get model,res
109
+ when "UPDATE"
110
+ ActionFramework::ModelHelper.update model,res
111
+ when "DELETE"
112
+
113
+ else
114
+
115
+ end
116
+
117
+ end
118
+ end
119
+ # end auto-api
120
+ end
121
+
83
122
  end
84
123
  end
@@ -0,0 +1,26 @@
1
+ #######################
2
+ # Licenced under MIT ##
3
+ ### © BramVDB.com #####
4
+ #######################
5
+ module ActionFramework
6
+ # Base class (in config.ru -> run ActionFramework::Base.new)
7
+ class Base
8
+ def initialize
9
+ @app = Rack::Builder.new do
10
+ map '/static' do
11
+ run Rack::File.new("static")
12
+ end
13
+
14
+ map '/realtime' do
15
+ run ActionFramework::Realtime.new
16
+ end
17
+
18
+ run ActionFramework::Server.current
19
+ end
20
+ end
21
+
22
+ def call env
23
+ @app.call(env)
24
+ end
25
+ end
26
+ end
@@ -32,5 +32,29 @@ module ActionFramework
32
32
  output = renderer.render(self){ Tilt::ERBTemplate.new("views/"+template.to_s+".html.erb").render(self) }
33
33
  return output
34
34
  end
35
+
36
+ def erb_text erb_text
37
+ renderer = Tilt::ERBTemplate.new("views/layout.html.erb")
38
+ output = renderer.render(self){ erb_text }
39
+ return output
40
+ end
41
+
42
+ def error_erb code
43
+ if(Dir.exists? "views/errors")
44
+ renderer = Tilt::ERBTemplate.new("views/layout.html.erb")
45
+ output = renderer.render(self){ Tilt::ERBTemplate.new("views/errors/#{code}.html.erb").render(self) }
46
+ return output
47
+ else
48
+ root = ActionFramework::Gem.root
49
+ libdir = root.resources.to_s
50
+ puts ActionFramework::Gem.root.inspect
51
+ renderer = Tilt::ERBTemplate.new(libdir+"/views/errors/layout.html.erb")
52
+ output = renderer.render(self){ Tilt::ERBTemplate.new(libdir+"/views/errors/#{code}.html.erb").render(self) }
53
+ end
54
+ end
55
+
56
+ def session
57
+ @req.session
58
+ end
35
59
  end
36
60
  end
@@ -0,0 +1,17 @@
1
+ module ActionFramework
2
+
3
+ class ErrorHandler < ActionFramework::Controller
4
+ def error_404
5
+ error_erb "404"
6
+ end
7
+
8
+ def error_500
9
+ error_erb "500"
10
+ end
11
+
12
+ def error_403
13
+ error_erb "403"
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,6 @@
1
+ require 'jewel'
2
+ module ActionFramework
3
+ class Gem < Jewel::Gem
4
+ root "../.."
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ module Gem
2
+ class Specification
3
+ def self.find_lib_dir_by_name name
4
+ spec = Gem::Specification.find_by_name(name)
5
+ gem_root = spec.gem_dir
6
+ gem_lib = gem_root + "/lib"
7
+ gem_lib
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ module ActionFramework
2
+ class ModelHelper
3
+ def self.post model,res
4
+ response = model.create(JSON.parse(req.body.string)).to_json
5
+ res.write response
6
+ res.finish
7
+ end
8
+
9
+ def self.get model,res
10
+ response = model.all.to_json
11
+ res.write response
12
+ res.finish
13
+ end
14
+
15
+ def self.update model,res
16
+ doc = JSON.parse(req.body.string)
17
+ modelfind = model.where(doc[:where])
18
+ response = modelfind.update_attributes(doc[:attributes]).to_json
19
+ res.write response
20
+ res.finish
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ #######################
2
+ # Licenced under MIT ##
3
+ ### © BramVDB.com #####
4
+ #######################
5
+
6
+ module ActionFramework
7
+ class Plugables
8
+ def initialize &block
9
+ @index = JSON.parse(File.read(Gem::Specification.find_lib_dir_by_name("actionframework")+"/plugables/index.json"))
10
+ self.instance_eval &block
11
+ end
12
+
13
+ def plug name
14
+ if @index["plugs"].include? name
15
+ require Gem::Specification.find_lib_dir_by_name("actionframework")+'/plugables/'+name
16
+ end
17
+ Object.const_get(name.classify).new if(Object.const_get(name.classify).superclass.to_s == "ActionFramework::Plugable::Initializer")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ #######################
2
+ # Licenced under MIT ##
3
+ ### © BramVDB.com #####
4
+ #######################
5
+ module ActionFramework
6
+ module Plugable
7
+ class Initializer
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ #######################
2
+ # Licenced under MIT ##
3
+ ### © BramVDB.com #####
4
+ #######################
5
+ require 'rack/websocket'
6
+
7
+ module ActionFramework
8
+ class Realtime < Rack::WebSocket::Application
9
+ def on_open env
10
+
11
+ puts "Client connected"
12
+ end
13
+ end
14
+ end
@@ -6,6 +6,8 @@
6
6
  module ActionFramework
7
7
  class Routes
8
8
  attr_accessor :routes
9
+ attr_accessor :models
10
+
9
11
  def initialize
10
12
  @routes = {:get => {}, :post => {}, :update => {}, :delete => {}, :patch => {}}
11
13
  end
@@ -39,6 +41,11 @@ module ActionFramework
39
41
  @routes[:patch][build_regex(hash.keys.first.to_s)] = hash[hash.keys.first.to_s]
40
42
  end
41
43
 
44
+ def model hash
45
+ # @models[name of the class of the model] = name of class of the access policy of the model
46
+ @models[hash.keys.first_to.s] = hash[hash.keys.first.to_s]
47
+ end
48
+
42
49
  def route(path,method)
43
50
  @routes[method.downcase.to_sym].each do |regex,controller|
44
51
  puts regex
@@ -0,0 +1,13 @@
1
+ #######################
2
+ # Licenced under MIT ##
3
+ ### © BramVDB.com #####
4
+ #######################
5
+
6
+ # @author BramVDB.com
7
+ # @since 0.1.1
8
+ class String
9
+ # @return [String] Classified string
10
+ def classify
11
+ self.split('_').collect(&:capitalize).join
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 actionframework
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,4 @@
1
+ plugables
2
+ =========
3
+
4
+ ActionFramework Plugables
@@ -0,0 +1,5 @@
1
+ {
2
+ "plugs": [
3
+ "mongomapper"
4
+ ]
5
+ }
@@ -0,0 +1,5 @@
1
+ class MongoMapper < ActionFramework::Plugable:Initializer
2
+ def initialize
3
+
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ {
2
+ "stock": [
3
+ {
4
+ "name": "mongomapper"
5
+ }
6
+ ]
7
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionframework
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bram Vandenbogaerde
@@ -66,21 +66,76 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: websocket-rack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: httparty
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: jewel
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
69
111
  description: A web framework built on top of Rack, it has the simplicity of sinatra
70
112
  and the structure of rails
71
113
  email: bram.vandenbogaerde@gmail.com
72
114
  executables:
73
- - afw
115
+ - action
74
116
  extensions: []
75
117
  extra_rdoc_files: []
76
118
  files:
119
+ - lib/actionframework/base.rb
77
120
  - lib/actionframework/controller.rb
121
+ - lib/actionframework/error_handler.rb
122
+ - lib/actionframework/gem.rb
123
+ - lib/actionframework/gemextra.rb
124
+ - lib/actionframework/modelhelper.rb
125
+ - lib/actionframework/plugables.rb
126
+ - lib/actionframework/plugmod.rb
78
127
  - lib/actionframework/rackup.rb
128
+ - lib/actionframework/realtime.rb
79
129
  - lib/actionframework/routes.rb
80
130
  - lib/actionframework/settings.rb
131
+ - lib/actionframework/string.rb
81
132
  - lib/actionframework.rb
82
- - lib/actionframework_old.rb
83
- - bin/afw
133
+ - lib/plugables/index.json
134
+ - lib/plugables/LICENSE
135
+ - lib/plugables/plugs/mongomapper.rb
136
+ - lib/plugables/README.md
137
+ - lib/plugables/sources.json
138
+ - bin/action
84
139
  homepage: http://rubygems.org/gems/actionframework
85
140
  licenses:
86
141
  - MIT
@@ -106,3 +161,4 @@ signing_key:
106
161
  specification_version: 4
107
162
  summary: A web framework built on top of Rack
108
163
  test_files: []
164
+ has_rdoc:
data/bin/afw DELETED
@@ -1,51 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optitron'
3
- require 'fileutils'
4
- require 'actionframework'
5
- require 'json'
6
-
7
- class ActionFrameworkCLI < Optitron::CLI
8
- desc "About ActionFramework"
9
- def about
10
- puts "ActionFramework (previously called ActionFramework) is a web application framework that tries to be as flexible as sinatra and at the same time have the structure of rails.Enjoy!"
11
- end
12
- desc "Create ActionFramework project"
13
- def new projectname
14
- puts "Creating project directory and structure"
15
- Dir.mkdir("#{projectname}")
16
- Dir.mkdir("#{projectname}/controllers")
17
- Dir.mkdir("#{projectname}/models")
18
- Dir.mkdir("#{projectname}/views")
19
- Dir.mkdir("#{projectname}/config")
20
- Dir.mkdir("#{projectname}/initializers")
21
- FileUtils.touch("#{projectname}/views/layout.html.erb")
22
- FileUtils.touch("#{projectname}/Gemfile")
23
- File.write("#{projectname}/main.rb","# Example of basic configuration\nActionFramework = ActionFramework::Server.new\n\nnActionFramework.autoimport\nActionFramework.start")
24
- File.write("#{projectname}/controllers/default_controller.rb","class DefaultController < ActionFramework::Controller
25
- \n def index\n \"<h1>Welcome to ActionFramework</h1><i>Great Opensource Ruby Server</i><p>ActionFramework is loading routes from routes.json but you should write your own main.rb<br/>This is just to gettings started</p>\"\n end\nend");
26
- File.write("#{projectname}/routes.json","{\n \"get\": [{\n \"/\": \"DefaultController#index\"\n}]\n}")
27
- File.write("#{projectname}/config/routes.rb","ActionFramework::Server.current.routes do\n\n get \"/\" => \"DefaultController#index\"\n\nend")
28
- File.write("#{projectname}/config/settings.rb","ActionFramework::Server.current.settings do |s|\n\nend")
29
- File.write("#{projectname}/Gemfile","source 'https://rubygems.org'\n\ngem 'actionframework'")
30
- system("cd #{projectname} && bundle install")
31
- puts "Done"
32
- puts "Run \"afw s\" to run your app"
33
- end
34
-
35
- desc "Start ActionFramework server"
36
- def s
37
- $runningserver = ActionFramework::Server.new
38
- ActionFramework::Server.current.start
39
- end
40
-
41
- desc "Start ActionFramework console"
42
- def c
43
- $runningserver = ActionFramework::Server.new
44
- puts "Starting ActionFramework IRB"
45
- require 'irb'
46
- ARGV.clear
47
- IRB.start
48
- end
49
- end
50
-
51
- ActionFrameworkCLI.dispatch
@@ -1,373 +0,0 @@
1
- require 'rack.rb'
2
- require 'erb'
3
- require 'tilt'
4
- require 'json'
5
- require 'ostruct'
6
-
7
- $runningserver = nil
8
-
9
- module ActionFramework
10
- class Server
11
- def self.init
12
- require 'bundler'
13
- Bundler.require(:default)
14
- ActionFramework::Server.current = ActionFramework::Server.new
15
- ActionFramework::Server.current.autoimport
16
- end
17
- def initialize
18
- @settings = Settings.new
19
- @logger = Logger.new(@settings)
20
- @routesklass = Routes.new(@logger)
21
- end
22
-
23
- def self.current
24
- if($runningserver.nil?)
25
- ActionFramework::Server.init
26
- $runningserver
27
- else
28
- $runningserver
29
- end
30
- end
31
-
32
- def self.current=(runningserver)
33
- $runningserver = runningserver
34
- end
35
-
36
- def run
37
-
38
- end
39
-
40
- def call env
41
- if(@settings.errorhandler != nil)
42
- @errorhandler = Object.const_get(@settings.errorhandler).new
43
- else
44
- @errorhandler = ActionFramework::DefaultErrorHandler.new
45
- end
46
-
47
- routesinfo = @routesklass.routes(env["REQUEST_PATH"],env["REQUEST_METHOD"].downcase)
48
- controller = routesinfo[0]
49
- @logger.log controller.inspect
50
- matcheddata = routesinfo[1]
51
-
52
- if(controller == nil)
53
- if(@settings.server != "thin")
54
- response = ["<h1>404 Not Found</h1>"]
55
- else
56
- response = "<h1>404 Not Found</h1>"
57
- end
58
- return @errorhandler.call "404"
59
- end
60
-
61
- # Logic for models: in development
62
- if(controller.include? "ActionFramework::")
63
- ctrl = controller.split("#")
64
- params = ctrl[1].split(":")
65
-
66
- req = Rack::Request.new(env)
67
-
68
- data = Model.new(req).call(params[1])
69
- return ["200",{"Content-type" => "application/json"},[data]]
70
- end
71
-
72
- # Call the Controller
73
- request = Rack::Request.new(env)
74
- request.request.params = Rack::Utils.parse_query(env["QUERY_STRING"])
75
- Rack::Utils.parse_query(env["rack.input"].read).each do |key,value|
76
- request.request.params[key] = value
77
- end
78
-
79
- if(matcheddata != nil)
80
- request.request.params.merge! (matcheddata)
81
- end
82
- request.request.params.default = ""
83
-
84
- infoctrl = controller.split("#")
85
- ctrl = Object.const_get(infoctrl[0]).new(request)
86
-
87
- response = ctrl.send(infoctrl[1])
88
- if(@settings.server != "thin")
89
- response = [response]
90
- end
91
- [ctrl.info.response.status_code,ctrl.info.response.headers,response]
92
- end
93
-
94
- def start
95
- if(@settings.errorhandler != nil)
96
- @errorhandler = Object.const_get(@settings.errorhandler).new
97
- else
98
- @errorhandler = ActionFramework::DefaultErrorHandler.new
99
- end
100
-
101
- if(@settings.daemon)
102
- puts "Sending ActionFramework to background"
103
- system("kill `cat running.pid`")
104
- Process.daemon true
105
- File.write("running.pid",Process.pid)
106
- end
107
- @logger.log @routesklass.inspect
108
- Rack::Server.new({:app => self,:server => @settings.server, :Port => @settings.port}).start
109
- end
110
-
111
- def routes &block
112
- @routesklass.instance_eval &block
113
- end
114
-
115
- def settings
116
- yield(@settings)
117
- end
118
-
119
- def autoimport
120
- Dir.glob("controllers/*").each do |file|
121
- require './'+file
122
- end
123
-
124
- Dir.glob("models/*").each do |file|
125
- require './'+file
126
- end
127
-
128
- require './config/routes'
129
- require './config/settings'
130
-
131
- Dir.glob("initializers/*").each do |file|
132
- require './'+file
133
- end
134
-
135
- end
136
-
137
- end
138
- class Routes
139
- NAME_PATTERN = /:(\S+)/
140
-
141
- attr_accessor :routes
142
- attr_accessor :models
143
- attr_accessor :posts
144
-
145
- def initialize logger
146
- @routes = {:get => {}, :post => {},:update => {}, :delete => {},:patch => {}}
147
- @models = {}
148
- @logger = logger
149
- @routespost = {}
150
- end
151
-
152
- def get hash
153
- @routes[:get][pattern_for(hash.keys.first.to_s)] = hash[hash.keys.first.to_s]
154
- @logger.log "Adding route GET "+hash.keys.first.to_s
155
- end
156
-
157
- def post hash
158
- @routes[:post][hash.keys.first.to_s] = hash[hash.keys.first.to_s]
159
- @logger.log "Adding route POST "+hash.keys.first.to_s
160
- end
161
-
162
- def update hash
163
- @routes[:update][hash.keys.first.to_s] = hash[hash.keys.first.to_s]
164
- @logger.log "Adding route UPDATE "+hash.keys.first.to_s
165
- end
166
-
167
- def delete hash
168
- @routes[:delete][hash.keys.first.to_s] = hash[hash.keys.first.to_s]
169
- @logger.log "Adding route DELETE "+hash.keys.first.to_s
170
- end
171
-
172
- def patch hash
173
- @routes[:patch][hash.keys.first.to_s] = hash[hash.keys.first.to_s]
174
- @logger.log "Adding route PATCH "+hash.keys.first.to_s
175
- end
176
-
177
- def model hash
178
- # In development
179
- @routes["/api/"+hash.keys.first.to_s] = "ActionFramework::Model#call:"+hash[hash.keys.first.to_s];
180
- puts "Adding model with path "+hash.keys.first.to_s
181
- end
182
-
183
- def routes(path,method)
184
- hash = {}
185
- controller = nil
186
- @routes[method.to_sym].each do |route,controller|
187
- if(matched = route.match path)
188
- matched.names.each do |name|
189
- hash[name] = matched[name]
190
- end
191
-
192
- return [controller,hash]
193
- end
194
- end
195
- end
196
- # Logic from github.com/alisnic/nyny
197
- def pattern_for signature
198
- if(signature.class == Regexp)
199
- return signature
200
- end
201
- build_regex(signature.start_with?('/') ? signature : "/#{signature}")
202
- end
203
-
204
- def build_regex signature
205
- return %r(^#{signature}$) unless signature.include?(':')
206
-
207
- groups = signature.split('/').map do |part|
208
- next part if part.empty?
209
- next part unless part.start_with? ':'
210
- name = NAME_PATTERN.match(part)[1]
211
- %Q{(?<#{name}>\\S+)}
212
- end.select {|s| !s.empty? }.join('\/')
213
-
214
- %r(^\/#{groups}$)
215
- end
216
- end
217
- class Controller
218
- attr_accessor :info
219
-
220
- def initialize(context)
221
- @info = context
222
- if(self.respond_to? "before")
223
- self.before
224
- end
225
- end
226
-
227
- def erb template
228
- renderer = Tilt::ERBTemplate.new("views/layout.html.erb")
229
- output = renderer.render(self){ Tilt::ERBTemplate.new("views/"+template.to_s+".html.erb").render(self) }
230
- return output
231
- end
232
-
233
- def params
234
- @info.req.params
235
- end
236
-
237
- def request
238
- @info.req
239
- end
240
-
241
- end
242
-
243
- class Request
244
- attr_accessor :response
245
- attr_accessor :request
246
- attr_accessor :req
247
-
248
- def initialize(env)
249
- @response = OpenStruct.new ({:headers => {}, :status_code => "200"})
250
- @request = OpenStruct.new ({:ip => "",:user_agent => "",:headers => {},:params => {}})
251
- @req = Rack::Request.new(env)
252
- end
253
-
254
- def info
255
- return @info
256
- end
257
- end
258
-
259
- class Model
260
- def initialize req
261
- @req = req
262
- end
263
-
264
- def call modelname
265
- case @req.request_method
266
- when "GET"
267
- if(Object.const_get(modelname.capitalize).respond_to? "append")
268
- model = Object.const_get(modelname.capitalize).all.send(Object.const_get(modelname.capitalize).append)
269
- else
270
- model = Object.const_get(modelname.capitalize).all
271
- end
272
- model.to_json
273
- when "POST"
274
- if(Object.const_get(modelname.capitalize).respond_to? "append")
275
- model = Object.const_get(modelname.capitalize).create(JSON.parse(@req.body.string))
276
- else
277
- model = Object.const_get(modelname.capitalize).create(JSON.parse(@req.body.string))
278
- end
279
- model.to_json
280
- else
281
-
282
- end
283
- end
284
-
285
- end
286
-
287
- class Settings
288
- attr_accessor :port
289
- attr_accessor :server
290
- attr_accessor :verbose
291
- attr_accessor :daemon
292
- attr_accessor :errorhandler
293
-
294
- def initialize
295
- @port = 8080
296
- @server = "puma"
297
- @verbose = true
298
- @daemon = false
299
- @errorhandler = nil
300
- end
301
- end
302
- class Logger
303
-
304
- def initialize(settings)
305
- @settings = settings
306
- end
307
-
308
- def log msg
309
- if(@settings.daemon)
310
- return
311
- end
312
- if(@settings.verbose)
313
- puts msg
314
- end
315
- end
316
-
317
- end
318
-
319
- class ErrorHelper
320
- def call(errortype)
321
- if(self.respond_to? "error_"+errortype)
322
- puts "Yes!!!!!"
323
- [errortype, {},[self.send("error_"+errortype)]]
324
- else
325
- [errortype, {}, [ActionFramework::DefaultErrorHandler.new.send("error_"+errortype)]]
326
- end
327
- end
328
-
329
- def erb template
330
- renderer = Tilt::ERBTemplate.new("views/layout.html.erb")
331
- output = renderer.render(self){ Tilt::ERBTemplate.new("views/"+template.to_s+".html.erb").render(self) }
332
- return output
333
- end
334
-
335
- end
336
-
337
- class DefaultErrorHandler < ActionFramework::ErrorHelper
338
- def error_404
339
- "<h1>404 Not Found</h1>"
340
- end
341
- def error_500
342
- "<h1>500 Internal server error</h1>"
343
- end
344
- def error_403
345
- "<h1>403 Forbidden</h1>"
346
- end
347
- end
348
- end
349
-
350
- at_exit do
351
- puts "Exiting..."
352
- if(File.exists? "running.pid")
353
- File.delete("running.pid")
354
- end
355
- end
356
-
357
-
358
- ########## IMPORTANT LOGIC SOON TO BE INTEGRATED ######
359
- string = "/{{appname}}/{{userid}}"
360
-
361
- string = string.gsub("{{","(?<")
362
- string = string.gsub("}}",">(.*))")
363
- string.insert(0,"^")
364
- string = string+"$"
365
- puts string
366
- regex = Regexp.new (string)
367
-
368
- puts regex
369
-
370
- if(matched = regex.match "/testapp/1")
371
- puts "matched"
372
- p matched
373
- end