picombo 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,155 @@
1
+ module Picombo
2
+
3
+ # Processes the URI to route requests to proper controller
4
+ #
5
+ # == Using Routes
6
+ # Routes are defined in the +config/routes.yaml+:: config file.
7
+ #
8
+ # There should always be a 'default' route, which is the route that applies when there are no uri segments. ex: +default: controller/method+::
9
+ #
10
+ # The first kind of route is an exact match route. This will look for a URI match in the keys of the routes file. ex: +foobar/baz: controller/method+::
11
+ #
12
+ # You can also use regex routes for more powerful routing:
13
+ # * A catch-all route: .+: controller/method
14
+ # * Routing all second URI segments to the index method: foobar/(.+): foobar/index
15
+ # * ([a-z]{2}): chamber/video/\1
16
+
17
+ class Router
18
+ @@req = nil
19
+
20
+ # Data writer.
21
+ def self.routes=(routes)
22
+ @@routes = routes
23
+ end
24
+ def self.current_uri=(current_uri)
25
+ @@current_uri = current_uri
26
+ end
27
+ def self.current_uri
28
+ @@current_uri
29
+ end
30
+ def self.segments=(segments)
31
+ @@segments = segments
32
+ end
33
+ def self.segments
34
+ @@segments
35
+ end
36
+ def self.rsegments=(rsegments)
37
+ @@rsegments = rsegments
38
+ end
39
+ def self.controller=(controller)
40
+ @@controller = controller
41
+ end
42
+ def self.controller
43
+ @@controller
44
+ end
45
+ def self.method=(method)
46
+ @@method = method
47
+ end
48
+ def self.method
49
+ @@method
50
+ end
51
+
52
+ def initialize(req)
53
+ @@req = req
54
+ end
55
+
56
+ # Processes the URI
57
+ def process()
58
+ Picombo::Bench.instance.start('setup')
59
+
60
+ Picombo::Event.run('system.pre_router')
61
+ # Find the controller and method
62
+ uri = @@req.path
63
+ path = uri[0..-(File.extname(uri).length+1)]
64
+ uri = Picombo::Router.process_uri(path)
65
+
66
+ # Let events have the ability to modify the uri array
67
+ Picombo::Event.run('system.post_router', uri)
68
+ @@controller = 'Picombo::Controllers::'+uri[:controller]
69
+ @@method = uri[:method]
70
+
71
+ # Try and load the controller class
72
+ begin
73
+ controller = Picombo::Controllers::const_get(uri[:controller].capitalize!).new
74
+ rescue LoadError
75
+ return Picombo::Controllers::Error_404.new.run_error(@@req.path)
76
+ end
77
+
78
+ controller_methods = controller.methods
79
+
80
+ Picombo::Bench.instance.stop('setup')
81
+
82
+ # Execute the controller method
83
+ Picombo::Bench.instance.start('controller_execution')
84
+
85
+ Picombo::Event.run('system.pre_controller')
86
+ if controller_methods.include?(uri[:method])
87
+ begin
88
+ if uri[:params].nil? or uri[:params].empty?
89
+ controller.send(uri[:method])
90
+ else
91
+ controller.send(uri[:method], *uri[:params])
92
+ end
93
+ rescue Picombo::E404
94
+ return Picombo::Controllers::Error_404.new.run_error(@@req.path)
95
+ end
96
+ else
97
+ return Picombo::Controllers::Error_404.new.run_error(uri.inspect)
98
+ end
99
+ Picombo::Event.run('system.post_controller')
100
+
101
+ Picombo::Bench.instance.stop('controller_execution')
102
+ Picombo::Bench.instance.stop('application')
103
+
104
+ Picombo::Core.render
105
+ end
106
+
107
+ # Takes a uri path string and determines the controller, method and any get parameters
108
+ # Uses the routes config file for translation
109
+ def self.process_uri(path)
110
+ router_parts = path == '/' ? ('/'+Picombo::Config.get('routes._default')).split('/') : path.split('/')
111
+ @@current_uri = path.split('?').at(0)
112
+ @@segments = @@current_uri.split('/')[1..-1]
113
+ @@rsegments = router_parts[1..-1]
114
+ routed_uri = @@current_uri
115
+
116
+ # Load routes
117
+ routes = Picombo::Config.load('routes')
118
+
119
+ # Try and find a direct match
120
+ if routes.key?(@@current_uri)
121
+ routed_uri = routes[@@current_uri]
122
+ @@rsegments = routed_uri.split('/')
123
+ else
124
+ routes.each do |route, destination|
125
+ if route != '_default'
126
+ if Regexp.new(route).match(@@current_uri)
127
+ routed_uri.gsub!(Regexp.new(route), destination)
128
+ @@rsegments = routed_uri.split('/')[1..-1]
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ params = @@rsegments.slice(2, router_parts.length)
135
+
136
+ if ! params.nil?
137
+ params.collect! do |param|
138
+ param.split('?').at(0)
139
+ end
140
+ else
141
+ params = []
142
+ end
143
+
144
+ # Use the default route if nothing has been found
145
+ if ! @@rsegments[1].nil?
146
+ @@rsegments[1] = @@rsegments[1].split('?').at(0)
147
+ else
148
+ @@rsegments[1] = ('/'+Picombo::Config.get('routes._default')).split('/').at(2)
149
+ end
150
+
151
+ # make sure to remove the GET from any of the parameters
152
+ {:controller => @@rsegments[0].split('?').at(0), :method => @@rsegments[1], :params => params}
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,46 @@
1
+ module Picombo
2
+ # Helper class for security things like xss
3
+ class Security
4
+ # Returns the base URL for use with any internal links.
5
+ def self.xss_clean(str, driver = nil)
6
+ driver = 'default' if driver.nil? or driver == true
7
+
8
+ Security.send(driver, str)
9
+ end
10
+
11
+ #This is a blacklist method, so ensure this is what you really want
12
+ def self.bitkeeper(str)
13
+ # clean any control characters
14
+ str.gsub!(/[\x00-\x20]*/, '')
15
+ # clean null byte
16
+ str.gsub!(/[\0]/, '')
17
+
18
+ # Remove javascript: and vbscript: protocols
19
+ str.gsub!(/([a-z]*)=([`"]*)javascript:/iu, '\1=\2nojavascript....')
20
+ str.gsub!(/([a-z]*)=([`"]*)vbscript:/iu, '\1=\2novbscript....')
21
+ str.gsub!(/#([a-z]*)=(["]*)-moz-binding:/u, '\1=\2nomozbinding...')
22
+
23
+ # Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
24
+ str.gsub!(/(<[^>]+?)style=[`"]*.*?expression\([^>]*>/i, '\1>')
25
+ str.gsub!(/(<[^>]+?)style=[`"]*.*?behaviour\([^>]*>/i, '\1>')
26
+ str.gsub!(/(<[^>]+?)style=[`"]*.*?script:*[^>]*>/iu, '\1>')
27
+
28
+ # Remove namespaced elements (we do not need them)
29
+ data = str.gsub(/<\/*\w+:\w[^>]*>/i, '')
30
+
31
+ begin
32
+ old_data = data
33
+ data.gsub!(/<\/*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*>/i, '')
34
+ end until old_data == data
35
+
36
+ data
37
+ end
38
+
39
+ #default cleaner. encodes the strign to prevent xss
40
+ def self.default(str)
41
+ require 'htmlentities'
42
+
43
+ HTMLEntities.new.encode(str)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ module Picombo
2
+ class Session
3
+ include Singleton
4
+
5
+ def init(req)
6
+ @@req = req
7
+ end
8
+
9
+ def get(key = nil, default = nil)
10
+ return @@req.session if key.nil?
11
+
12
+ result = Picombo::Config.key_string(@@req.session, key)
13
+
14
+ return result.nil? ? default : result
15
+ end
16
+
17
+ def set(key, val)
18
+ @@req.session[key] = val
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Picombo
2
+ # Helper class to assist in URL generation
3
+ class Url
4
+ # Returns the base URL for use with any internal links.
5
+ def self.base(protocol = nil)
6
+ protocol = Picombo::Config.get('config.protocol') if protocol.nil?
7
+ protocol+"://"+Picombo::Config.get('config.site_domain')+'/'
8
+ end
9
+
10
+ # Creates a full URL using the base path plus the path passed to the method
11
+ def self.site(path, protocol = nil)
12
+ base(protocol)+path
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ module Picombo
2
+ module View
3
+ # == XML View
4
+ #
5
+ # The core view renders XML to the browser
6
+ #
7
+ # See the View documentation for usage specifics
8
+ class XML < Picombo::View::Core
9
+ def initialize(filename)
10
+ super(filename)
11
+
12
+ # Changes the content type to xml for the application
13
+ Picombo::Core.raw_response()['Content-Type'] = 'text/xml'
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,80 @@
1
+ module Picombo
2
+ # == View Class
3
+ #
4
+ # The Picombo::View class allows for template files to be rendered and displayed in the browser.
5
+ #
6
+ # By default, only ERB templating is currently supported.
7
+ # === Examples
8
+ #
9
+ # foobar = Picombo::View::Core.new('template')
10
+ # # Sets a view variable
11
+ # foobar.set('bar', 'baz')
12
+ # # Renders the view to the output buffer
13
+ # foobar.render
14
+ #
15
+ # You can also nest views like so:
16
+ #
17
+ # body = Picombo::View::Core.new('page/body')
18
+ # body.set('content', 'Hello World!')
19
+ # template = Picombo::View::Core.new('template')
20
+ # template.set('body', body.render(true))
21
+ # template.render
22
+ #
23
+ # This will render a body subview inside of your template view file
24
+ module View
25
+ # == Core View
26
+ #
27
+ # The core view renders HTML to the browser using ERB
28
+ #
29
+ # See the View documentation for usage specifics
30
+ class Core
31
+ @view_file = ''
32
+ @view_data = []
33
+
34
+ # Creates a new view object and sets the filename. Raises an IOError exception if the view file is not found
35
+ def initialize(filename)
36
+ @view_data = {}
37
+ view_location = Picombo::Core.find_file('views', filename, false, 'rhtml').shift
38
+
39
+ if view_location.nil?
40
+ raise IOError
41
+ end
42
+
43
+ @view_file = view_location
44
+ end
45
+
46
+ # Support templating of member data.
47
+ def get_binding
48
+ binding
49
+ end
50
+
51
+ # Sets a view variable
52
+ def set(key, val)
53
+ instance_variable_set "@#{key}", val
54
+ end
55
+
56
+ # Renders the view to the output buffer, or optionally simply returns it if echo is true
57
+ def render(echo = false)
58
+ view = ERB::new(File.read(@view_file))
59
+
60
+ if echo
61
+ view.result(get_binding())
62
+ else
63
+ Picombo::Core.response view.result(get_binding())
64
+ end
65
+ end
66
+ end
67
+
68
+ def View.const_missing(name)
69
+ filename = name.to_s
70
+
71
+ require 'classes/view/'+filename.downcase
72
+
73
+ raise name.to_s+' not found!' if ! const_defined?(name)
74
+
75
+ klass = const_get(name)
76
+ return klass if klass
77
+ raise klass+" not found!"
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,3 @@
1
+ default:
2
+ driver: file
3
+ lifetime: '86400'
@@ -0,0 +1,10 @@
1
+ directory: logs/
2
+
3
+ # Log thresholds:
4
+ # 0 - Disable logging
5
+ # 1 - Errors and exceptions
6
+ # 2 - Warnings
7
+ # 3 - Notices
8
+ # 4 - Debugging
9
+
10
+ log_threshold: 1
@@ -0,0 +1,210 @@
1
+ 323: [text/h323]
2
+ 7z: [application/x-7z-compressed]
3
+ abw: [application/x-abiword]
4
+ acx: [application/internet-property-stream]
5
+ ai: [application/postscript]
6
+ aif: [audio/x-aiff]
7
+ aifc: [audio/x-aiff]
8
+ aiff: [audio/x-aiff]
9
+ asf: [video/x-ms-asf]
10
+ asr: [video/x-ms-asf]
11
+ asx: [video/x-ms-asf]
12
+ atom: [application/atom+xml]
13
+ avi: [video/avi, video/msvideo, video/x-msvideo]
14
+ bin: [application/octet-stream, application/macbinary]
15
+ bmp: [image/bmp]
16
+ c: [text/x-csrc]
17
+ c++: [text/x-c++src]
18
+ cab: [application/x-cab]
19
+ cc: [text/x-c++src]
20
+ cda: [application/x-cdf]
21
+ class: [application/octet-stream]
22
+ cpp: [text/x-c++src]
23
+ cpt: [application/mac-compactpro]
24
+ csh: [text/x-csh]
25
+ css: [text/css]
26
+ csv: [text/x-comma-separated-values, application/vnd.ms-excel, text/comma-separated-values, text/csv]
27
+ dbk: [application/docbook+xml]
28
+ dcr: [application/x-director]
29
+ deb: [application/x-debian-package]
30
+ diff: [text/x-diff]
31
+ dir: [application/x-director]
32
+ divx: [video/divx]
33
+ dll: [application/octet-stream, application/x-msdos-program]
34
+ dmg: [application/x-apple-diskimage]
35
+ dms: [application/octet-stream]
36
+ doc: [application/msword]
37
+ dvi: [application/x-dvi]
38
+ dxr: [application/x-director]
39
+ eml: [message/rfc822]
40
+ eps: [application/postscript]
41
+ evy: [application/envoy]
42
+ exe: [application/x-msdos-program, application/octet-stream]
43
+ fla: [application/octet-stream]
44
+ flac: [application/x-flac]
45
+ flc: [video/flc]
46
+ fli: [video/fli]
47
+ flv: [video/x-flv]
48
+ gif: [image/gif]
49
+ gtar: [application/x-gtar]
50
+ gz: [application/x-gzip]
51
+ h: [text/x-chdr]
52
+ h++: [text/x-c++hdr]
53
+ hh: [text/x-c++hdr]
54
+ hpp: [text/x-c++hdr]
55
+ hqx: [application/mac-binhex40]
56
+ hs: [text/x-haskell]
57
+ htm: [text/html]
58
+ html: [text/html]
59
+ ico: [image/x-icon]
60
+ ics: [text/calendar]
61
+ iii: [application/x-iphone]
62
+ ins: [application/x-internet-signup]
63
+ iso: [application/x-iso9660-image]
64
+ isp: [application/x-internet-signup]
65
+ jar: [application/java-archive]
66
+ java: [application/x-java-applet]
67
+ jpe: [image/jpeg, image/pjpeg]
68
+ jpeg: [image/jpeg, image/pjpeg]
69
+ jpg: [image/jpeg, image/pjpeg]
70
+ js: [application/x-javascript]
71
+ json: [application/json]
72
+ latex: [application/x-latex]
73
+ lha: [application/octet-stream]
74
+ log: [text/plain, text/x-log]
75
+ lzh: [application/octet-stream]
76
+ m4a: [audio/mpeg]
77
+ m4p: [video/mp4v-es]
78
+ m4v: [video/mp4]
79
+ man: [application/x-troff-man]
80
+ mdb: [application/x-msaccess]
81
+ midi: [audio/midi]
82
+ mid: [audio/midi]
83
+ mif: [application/vnd.mif]
84
+ mka: [audio/x-matroska]
85
+ mkv: [video/x-matroska]
86
+ mov: [video/quicktime]
87
+ movie: [video/x-sgi-movie]
88
+ mp2: [audio/mpeg]
89
+ mp3: [audio/mpeg]
90
+ mp4: [application/mp4, audio/mp4, video/mp4]
91
+ mpa: [video/mpeg]
92
+ mpe: [video/mpeg]
93
+ mpeg: [video/mpeg]
94
+ mpg: [video/mpeg]
95
+ mpg4: [video/mp4]
96
+ mpga: [audio/mpeg]
97
+ mpp: [application/vnd.ms-project]
98
+ mpv: [video/x-matroska]
99
+ mpv2: [video/mpeg]
100
+ ms: [application/x-troff-ms]
101
+ msg: [application/msoutlook, application/x-msg]
102
+ msi: [application/x-msi]
103
+ nws: [message/rfc822]
104
+ oda: [application/oda]
105
+ odb: [application/vnd.oasis.opendocument.database]
106
+ odc: [application/vnd.oasis.opendocument.chart]
107
+ odf: [application/vnd.oasis.opendocument.forumla]
108
+ odg: [application/vnd.oasis.opendocument.graphics]
109
+ odi: [application/vnd.oasis.opendocument.image]
110
+ odm: [application/vnd.oasis.opendocument.text-master]
111
+ odp: [application/vnd.oasis.opendocument.presentation]
112
+ ods: [application/vnd.oasis.opendocument.spreadsheet]
113
+ odt: [application/vnd.oasis.opendocument.text]
114
+ oga: [audio/ogg]
115
+ ogg: [application/ogg]
116
+ ogv: [video/ogg]
117
+ otg: [application/vnd.oasis.opendocument.graphics-template]
118
+ oth: [application/vnd.oasis.opendocument.web]
119
+ otp: [application/vnd.oasis.opendocument.presentation-template]
120
+ ots: [application/vnd.oasis.opendocument.spreadsheet-template]
121
+ ott: [application/vnd.oasis.opendocument.template]
122
+ p: [text/x-pascal]
123
+ pas: [text/x-pascal]
124
+ patch: [text/x-diff]
125
+ pbm: [image/x-portable-bitmap]
126
+ pdf: [application/pdf, application/x-download]
127
+ php: [application/x-httpd-php]
128
+ php3: [application/x-httpd-php]
129
+ php4: [application/x-httpd-php]
130
+ php5: [application/x-httpd-php]
131
+ phps: [application/x-httpd-php-source]
132
+ phtml: [application/x-httpd-php]
133
+ pl: [text/x-perl]
134
+ pm: [text/x-perl]
135
+ png: [image/png, image/x-png]
136
+ po: [text/x-gettext-translation]
137
+ pot: [application/vnd.ms-powerpoint]
138
+ pps: [application/vnd.ms-powerpoint]
139
+ ppt: [application/powerpoint]
140
+ ps: [application/postscript]
141
+ psd: [application/x-photoshop, image/x-photoshop]
142
+ pub: [application/x-mspublisher]
143
+ py: [text/x-python]
144
+ qt: [video/quicktime]
145
+ ra: [audio/x-realaudio]
146
+ ram: [audio/x-realaudio, audio/x-pn-realaudio]
147
+ rar: [application/rar]
148
+ rgb: [image/x-rgb]
149
+ rm: [audio/x-pn-realaudio]
150
+ rpm: [audio/x-pn-realaudio-plugin, application/x-redhat-package-manager]
151
+ rss: [application/rss+xml]
152
+ rtf: [text/rtf]
153
+ rtx: [text/richtext]
154
+ rv: [video/vnd.rn-realvideo]
155
+ sea: [application/octet-stream]
156
+ sh: [text/x-sh]
157
+ shtml: [text/html]
158
+ sit: [application/x-stuffit]
159
+ smi: [application/smil]
160
+ smil: [application/smil]
161
+ so: [application/octet-stream]
162
+ src: [application/x-wais-source]
163
+ svg: [image/svg+xml]
164
+ swf: [application/x-shockwave-flash]
165
+ t: [application/x-troff]
166
+ tar: [application/x-tar]
167
+ tcl: [text/x-tcl]
168
+ tex: [application/x-tex]
169
+ text: [text/plain]
170
+ texti: [application/x-texinfo]
171
+ textinfo: [application/x-texinfo]
172
+ tgz: [application/x-tar]
173
+ tif: [image/tiff]
174
+ tiff: [image/tiff]
175
+ torrent: [application/x-bittorrent]
176
+ tr: [application/x-troff]
177
+ tsv: [text/tab-separated-values]
178
+ txt: [text/plain]
179
+ wav: [audio/x-wav]
180
+ wax: [audio/x-ms-wax]
181
+ wbxml: [application/wbxml]
182
+ wm: [video/x-ms-wm]
183
+ wma: [audio/x-ms-wma]
184
+ wmd: [application/x-ms-wmd]
185
+ wmlc: [application/wmlc]
186
+ wmv: [video/x-ms-wmv, application/octet-stream]
187
+ wmx: [video/x-ms-wmx]
188
+ wmz: [application/x-ms-wmz]
189
+ word: [application/msword, application/octet-stream]
190
+ wp5: [application/wordperfect5.1]
191
+ wpd: [application/vnd.wordperfect]
192
+ wvx: [video/x-ms-wvx]
193
+ xbm: [image/x-xbitmap]
194
+ xcf: [image/xcf]
195
+ xhtml: [application/xhtml+xml]
196
+ xht: [application/xhtml+xml]
197
+ xl: [application/excel, application/vnd.ms-excel]
198
+ xla: [application/excel, application/vnd.ms-excel]
199
+ xlc: [application/excel, application/vnd.ms-excel]
200
+ xlm: [application/excel, application/vnd.ms-excel]
201
+ xls: [application/excel, application/vnd.ms-excel]
202
+ xlt: [application/excel, application/vnd.ms-excel]
203
+ xml: [text/xml]
204
+ xof: [x-world/x-vrml]
205
+ xpm: [image/x-xpixmap]
206
+ xsl: [text/xml]
207
+ xvid: [video/x-xvid]
208
+ xwd: [image/x-xwindowdump]
209
+ z: [application/x-compress]
210
+ zip: [application/x-zip, application/zip, application/x-zip-compressed]
@@ -0,0 +1 @@
1
+ _default: test/index
@@ -0,0 +1,11 @@
1
+ module Picombo
2
+ module Controllers
3
+ class Error_404
4
+ def run_error(uri)
5
+ body = Picombo::View::Core.new('404')
6
+ body.set('uri', uri)
7
+ return [404, {'Content-Type' => 'text/html'}, body.render(true)]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module Picombo
2
+ module Controllers
3
+ # == Template Controller
4
+ #
5
+ # The template controller enables your application to take advantage of view templating and auto rendering.
6
+ #
7
+ # To use it, simply tell your controllers to extend Picombo::Controllers::Template.
8
+ # You must also explicitly call the parent initialize method in your controllers:
9
+ #
10
+ # def initialize
11
+ # super
12
+ # end
13
+ #
14
+ # The default template view is called 'template' which is located in views/template.rhtml. You can change this on a per controller basis by changing the @@template vartiable in the controller:
15
+ #
16
+ # @@template = 'foobar_template'
17
+ #
18
+ # Now, you can use @@template in your controller and it will always use the same template. The template will automatically render at the end of the controller execution, so there is no need to call @@template.render manually
19
+ class Template
20
+ @@template = 'template'
21
+ @@auto_render = true
22
+
23
+ def initialize
24
+ @@template = Picombo::View::Core.new(@@template) if @@template.is_a?(String)
25
+
26
+ Picombo::Event.add('system.post_controller', 'Picombo::Controllers::Template.render') if @@auto_render
27
+ end
28
+
29
+ def self.render
30
+ @@template.render if @@auto_render
31
+ end
32
+ end
33
+ end
34
+ end