fenix-core 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 37db55f893c24efef37be505436257dd1a09dd19
4
+ data.tar.gz: c087e6e935faa04cf9ccd80f17b3cd51e0adc5f2
5
+ SHA512:
6
+ metadata.gz: 8e05e4febe2f6f5b4a7f45bcbddc802974ef9a455bba729f48b2cd828218a1fc9bb7d639f8d885423f1a4e28cf816dbabc8f337379f0ae623e1a349e5e6cdc02
7
+ data.tar.gz: efbf2a730fe2fb49f723f62ac8c9e7af82f4532d2b368bb1090fab18ca3fa07064e4b1baabb045c38c36ff74898952f34d3dfbda3021697c162f6be1493da3e5
checksums.yaml.gz.sig ADDED
@@ -0,0 +1 @@
1
+ ep��\X� �27�z��
data.tar.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ ��:�����Z9 +A�G j�:��pX�>&_��0?���!�����#��x���È����U�v��H�N[��N83SQ�*��C.��L��� ���E2r6R~<���#���ݳpH9�n6@�#�t���vSY/�?)��88�t����>� (,H!P��^�� h�����d���Kvi�����ҢzN��|����9bFb�G4�/Y�y���L�@D='.�1�&�=^�_SO�
2
+ �%�'���
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require_relative 'core/lib/fenix/core/version'
2
+
3
+ gems = [
4
+ 'fenix',
5
+ 'fenix-assets',
6
+ 'fenix-cache',
7
+ 'fenix-cookies',
8
+ 'fenix-core',
9
+ 'fenix-forms',
10
+ 'fenix-mail'
11
+ ]
@@ -0,0 +1,33 @@
1
+ require_relative 'lib/fenix/core/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = 'fenix-core'
5
+ spec.version = Fenix.version
6
+ spec.authors = ['Benjamin Bloch']
7
+ spec.email = ['cirex@aethernet.org']
8
+ spec.homepage = 'https://github.com/fenix-novus/fenix'
9
+ spec.license = 'MIT'
10
+ spec.description = 'Lightweight web framework inspired by Sinatra'
11
+ spec.summary = spec.description
12
+
13
+ spec.files = `git ls-files`.split($/)
14
+ spec.executables = spec.files.grep(%r(/bin/)) { |file| File.basename(file) }
15
+ spec.test_files = spec.files.grep(%r(/spec/))
16
+ spec.require_paths = ['lib']
17
+
18
+ private_key = File.expand_path('~/keys/gem-private.pem')
19
+
20
+ if File.exists?(private_key)
21
+ spec.signing_key = private_key
22
+ spec.cert_chain = ['../fenix-public.pem']
23
+ end
24
+
25
+ spec.add_runtime_dependency 'rack', '~> 1.5'
26
+ spec.add_runtime_dependency 'tilt', '~> 2.0'
27
+ spec.add_runtime_dependency 'mustermann', '~> 0.2'
28
+ spec.add_runtime_dependency 'i18n', '~> 0.6'
29
+
30
+ spec.add_development_dependency 'rspec', '= 3.0.0.beta1'
31
+
32
+ spec.required_ruby_version = '>= 2.1.0'
33
+ end
data/lib/fenix/core.rb ADDED
@@ -0,0 +1,89 @@
1
+ require_relative 'core/application'
2
+ require_relative 'core/version'
3
+
4
+ require 'mustermann'
5
+ require 'rack'
6
+ require 'tilt'
7
+
8
+ RACK_ENV = ENV['RACK_ENV'] ||= 'development' unless defined?(RACK_ENV)
9
+
10
+ module Fenix
11
+ class << self
12
+ ####
13
+ # @example
14
+ # Fenix.root('Application', 'Views')
15
+ # # => '/Home/Fenix/Application/Views'
16
+ #
17
+ # Fenix.root
18
+ # # => '/Home/Fenix'
19
+ #
20
+ # @return [String]
21
+ # @since 1.0.0
22
+ # @api public
23
+ def root(*paths)
24
+ File.join(FENIX_ROOT, *paths)
25
+ end
26
+
27
+ ####
28
+ # Returns the current environmental state
29
+ ####
30
+ #
31
+ # @example
32
+ # Fenix.environment
33
+ # # => :production
34
+ #
35
+ # Fenix.environment
36
+ # # => :test
37
+ #
38
+ # @return [Symbol]
39
+ # @since 1.0.0
40
+ # @api public
41
+ def environment
42
+ @_environment ||= RACK_ENV.to_sym.downcase
43
+ end
44
+ alias_method :env, :environment
45
+
46
+ ####
47
+ # @example
48
+ # Fenix.before_load do
49
+ # # ...
50
+ # end
51
+ #
52
+ # @return [Array<Proc>]
53
+ # @since 1.0.0
54
+ # @api public
55
+ def before_load(&block)
56
+ @_before_load ||= []
57
+ @_before_load << block if block_given?
58
+ @_before_load
59
+ end
60
+
61
+ ####
62
+ # @example
63
+ # Fenix.after_load do
64
+ # # ...
65
+ # end
66
+ #
67
+ # @return [Array<Proc>]
68
+ # @since 1.0.0
69
+ # @api public
70
+ def after_load(&block)
71
+ @_after_load ||= []
72
+ @_after_load << block if block_given?
73
+ @_after_load
74
+ end
75
+
76
+ ####
77
+ # @example
78
+ # Fenix.load_paths << Dir[Fenix.root('app', 'controllers', '**')]
79
+ #
80
+ # @return [Array<String>]
81
+ # @since 1.0.0
82
+ # @api public
83
+ def load_paths
84
+ @_load_paths ||= ['app/controllers/**', 'app/models/**', 'lib/**'].map do |directory|
85
+ Dir[Fenix.root(directory)]
86
+ end.flatten
87
+ end
88
+ end # self
89
+ end # Fenix
@@ -0,0 +1,209 @@
1
+ require_relative 'exceptions'
2
+ require_relative 'rendering'
3
+ require_relative 'settings'
4
+ require_relative 'response'
5
+ require_relative 'request'
6
+
7
+ module Fenix
8
+ class Application
9
+ attr_reader :env
10
+ attr_reader :request
11
+ attr_reader :response
12
+
13
+ include Rendering
14
+
15
+ class << self
16
+ # @private
17
+ def new(*arguments, &block)
18
+ instance = super(*arguments, &block)
19
+ stack.run(instance)
20
+ stack
21
+ end
22
+
23
+ %w(GET HEAD POST PUT PATCH DELETE OPTIONS).each do |verb|
24
+ define_method(verb.downcase) do |path, **conditions, &block|
25
+ routes[verb] << compile_route(path, conditions, &block)
26
+ end
27
+ end
28
+
29
+ # @private
30
+ private def compile_route(path, conditions, &block)
31
+ {
32
+ conditions: conditions,
33
+ object: Mustermann.new(path),
34
+ block: block
35
+ }
36
+ end
37
+
38
+ ####
39
+ # @return [Hash]
40
+ # @since 1.0.0
41
+ # @api public
42
+ def routes
43
+ @_routes ||= Hash.new { |hash, key| hash[key] = [] }
44
+ end
45
+
46
+ ####
47
+ # @return [Rack::Builder]
48
+ # @see https://github.com/rack/rack/blob/master/lib/rack/builder.rb
49
+ # @since 1.0.0
50
+ # @api public
51
+ def stack
52
+ @_stack ||= Rack::Builder.new
53
+ end
54
+
55
+ ####
56
+ # @param [options] Array<Symbol>
57
+ #
58
+ # @example
59
+ # enable :cache
60
+ #
61
+ # @since 1.0.0
62
+ # @api public
63
+ def enable(*options)
64
+ options.each { |option| settings[option] = true }
65
+ end
66
+
67
+ ####
68
+ # @param [options] Array<Symbol>
69
+ #
70
+ # @example
71
+ # disable :cache
72
+ #
73
+ # @since 1.0.0
74
+ # @api public
75
+ def disable(*options)
76
+ options.each { |option| settings[option] = false }
77
+ end
78
+
79
+ ####
80
+ # @return [Array]
81
+ # @since 1.0.0
82
+ # @api public
83
+ def extensions
84
+ @_extensions ||= []
85
+ end
86
+
87
+ ###
88
+ # @param [extensions] Array
89
+ #
90
+ # @example
91
+ # register Fenix::Assets
92
+ # register Fenix::Cookies
93
+ #
94
+ # @since 1.0.0
95
+ # @api public
96
+ def register(*extensions)
97
+ self.extensions += extensions
98
+ extensions.each do |extension|
99
+ extension.registered(self) if extension.respond_to?(:registered)
100
+ extend extension
101
+ end
102
+ end
103
+
104
+ ####
105
+ # @return [Fenix::Settings]
106
+ # @see Fenix::Settings
107
+ # @since 1.0.0
108
+ # @api public
109
+ def settings
110
+ @_settings ||= Fenix::Settings.new
111
+ end
112
+ end # self
113
+
114
+ ####
115
+ # @return [Fenix::Settings]
116
+ # @see Fenix::Settings
117
+ # @since 1.0.0
118
+ # @api public
119
+ def settings
120
+ self.class.settings
121
+ end
122
+
123
+ # @return [Hash]
124
+ # @since 1.0.0
125
+ # @api public
126
+ def session
127
+ env['rack.session']
128
+ end
129
+
130
+ # @return [Symbol]
131
+ # @since 1.0.0
132
+ # @api public
133
+ def locale
134
+ I18n.locale
135
+ end
136
+
137
+ # @return [Hash]
138
+ # @since 1.0.0
139
+ # @api public
140
+ def params
141
+ request.params
142
+ end
143
+
144
+ # @return [Hash]
145
+ # @since 1.0.0
146
+ # @api public
147
+ def cookies
148
+ request.cookies
149
+ end
150
+
151
+ # @since 1.0.0
152
+ # @api public
153
+ def logger
154
+ request.logger
155
+ end
156
+
157
+ # @since 1.0.0
158
+ # @api public
159
+ def redirect(uri, **notifications)
160
+ if env['HTTP_VERSION'] == 'HTTP/1.1' and env['REQUEST_METHOD'] != 'GET'
161
+ status = 303
162
+ else
163
+ status = 302
164
+ end
165
+
166
+ response['Location'] = uri
167
+ halt(status)
168
+ end
169
+
170
+ # @since 1.0.0
171
+ # @api public
172
+ def halt(status = 500)
173
+ response.status = status
174
+ throw :halt
175
+ end
176
+
177
+ # @private
178
+ def call(env)
179
+ @env = env
180
+ @request = Fenix::Request.new(env)
181
+ @response = Fenix::Response.new
182
+
183
+ dispatch
184
+ @response.finish
185
+ end
186
+
187
+ # @private
188
+ private def dispatch
189
+ catch :halt do
190
+ if route = find_route
191
+ response.write(instance_eval(&route[:block]))
192
+ else
193
+ raise Fenix::NotFound
194
+ end
195
+ end
196
+ end
197
+
198
+ # @private
199
+ private def find_route
200
+ self.class.routes[request.request_method].detect do |route|
201
+ if match = route[:object].match(request.path_info)
202
+ match.names.each_with_index do |index, name|
203
+ request[name] = match.captures[index]
204
+ end
205
+ end
206
+ end
207
+ end
208
+ end # Application
209
+ end # Fenix
@@ -0,0 +1,7 @@
1
+ module Fenix
2
+ class NotFound < NameError
3
+ end # NotFound
4
+
5
+ class TemplateNotFound < RuntimeError
6
+ end # TemplateNotFound
7
+ end # Fenix
@@ -0,0 +1,4 @@
1
+ module Fenix
2
+ class Rendering
3
+ end # Rendering
4
+ end # Fenix
@@ -0,0 +1,18 @@
1
+ module Fenix
2
+ class Request < Rack::Request
3
+ BOT_AGENTS = [
4
+ /archive.org/i,
5
+ /baiduspider/i,
6
+ /bingbot/i,
7
+ /blexbot/i
8
+ /googlebot/i,
9
+ /msnbot/i,
10
+ /yahoo/i,
11
+ /yandexbot/i
12
+ ]
13
+
14
+ def bot?
15
+ BOT_AGENTS.any? { |bot_agent| user_agent =~ bot_agent }
16
+ end
17
+ end # Request
18
+ end # Fenix
@@ -0,0 +1,28 @@
1
+ module Fenix
2
+ class Response
3
+ attr_accessor :body
4
+ attr_accessor :headers
5
+ attr_accessor :status
6
+
7
+ def initialize(body: [], status: 200, headers: { 'Content-Type' => 'text/html; charset=utf-8' })
8
+ @body, @headers, @status = body, headers, status
9
+ end
10
+
11
+ def finish
12
+ headers['Content-Length'] ||= body.each.map(&:size).inject(0, &:+).to_s
13
+ [status, headers, body]
14
+ end
15
+
16
+ def write(string)
17
+ self.body << string
18
+ end
19
+
20
+ def [](key)
21
+ @headers[key]
22
+ end
23
+
24
+ def []=(key, value)
25
+ @headers[key] = value
26
+ end
27
+ end # Request
28
+ end # Fenix
@@ -0,0 +1,46 @@
1
+ module Fenix
2
+ class Settings
3
+ # @since 1.0.0
4
+ # @api public
5
+ def initialize(file = nil)
6
+ @settings = {}
7
+ end
8
+
9
+ ####
10
+ # Returns the provided configuration option
11
+ ####
12
+ #
13
+ # @param [Symbol] key
14
+ #
15
+ # @example
16
+ # settings[:compress_assets]
17
+ # # => true
18
+ #
19
+ # settings.compress_assets
20
+ # # => true
21
+ #
22
+ # @since 1.0.0
23
+ # @api public
24
+ def [](key)
25
+ @settings[key.to_sym]
26
+ end
27
+
28
+ ####
29
+ # Sets the provided configuration option
30
+ ####
31
+ #
32
+ # @param [Symbol] key
33
+ # @param value
34
+ #
35
+ # @example
36
+ # settings[:compress_assets] = true
37
+ # settings.compress_assets = true
38
+ #
39
+ # @return [value]
40
+ # @since 1.0.0
41
+ # @api public
42
+ def []=(key, value)
43
+ @settings[key.to_sym] = value
44
+ end
45
+ end # Settings
46
+ end # Fenix
@@ -0,0 +1,9 @@
1
+ module Fenix
2
+ VERSION = '0.0.1'
3
+
4
+ class << self
5
+ def version
6
+ VERSION
7
+ end
8
+ end # self
9
+ end # Fenix
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fenix-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Benjamin Bloch
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDfDCCAmSgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMQ4wDAYDVQQDDAVjaXJl
14
+ eDEbMBkGCgmSJomT8ixkARkWC2Zlbml4LW5vdnVzMRMwEQYKCZImiZPyLGQBGRYD
15
+ Y29tMB4XDTE0MDIxMzIwMjIzM1oXDTE1MDIxMzIwMjIzM1owQjEOMAwGA1UEAwwF
16
+ Y2lyZXgxGzAZBgoJkiaJk/IsZAEZFgtmZW5peC1ub3Z1czETMBEGCgmSJomT8ixk
17
+ ARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOH7mNE94OS2
18
+ utbVYVuKj2tDYbM2+RnIufEdb4+m5vgqt1r6MRMPGwffvNN13YyVo0qZTQLOZwkj
19
+ Bqxtp9l25S5WTMpo0zskGa7MaenITqVayrQZoXFo0rfeISZn6fuwU5rnaIlV0XWr
20
+ zEiqfnMj3QFWFOgjOj/nMHREM0diuP1zHIwXNlEc/2wlPDuEtuy6mGxt9YT+1JCp
21
+ D+12oAW/UsWUJRfMUzA8V0LzM9F0QDbzf+rdqeGWAuBuC97/5v013SpJEssBmSia
22
+ Nn9ck7aTBFv3eyg/wChPAnLyRXvVzFAAi72/6Ehs9xiUCpJDHSLbrc3VMP2VJGxK
23
+ mOn0pckZOSkCAwEAAaN9MHswCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
24
+ BBYEFIhpfbQVAq5apBAD7tmXPyG6/M9GMCAGA1UdEQQZMBeBFWNpcmV4QGZlbml4
25
+ LW5vdnVzLmNvbTAgBgNVHRIEGTAXgRVjaXJleEBmZW5peC1ub3Z1cy5jb20wDQYJ
26
+ KoZIhvcNAQEFBQADggEBABFBohle+WV4bm8+Zb1vEtyzEf2rVrgceEEXgp2kLBk8
27
+ HQj/T/7nwqUJbESPbMuk4jFg4ZVQTB7Ui7sUmVbysGMFEHrMM5ujoiTpIjJHyOxe
28
+ 3ariA+qErQyJAjZcY2FvDI65jOYK/kWEHhPMrqHDIGUQMK4zTz7rHsT4E0hxdftB
29
+ 7RlEdgZQ/0TVeZchImNepXrLOtYMXL8tjTFhqnuVTWW00gKoRrEiuXw0igtw2cG+
30
+ szIvSaoMHw6qsq2Dsa0StAFlPE59s5HlRmyKR0BZ83ulvk7nLve08La5fGA6AKkJ
31
+ RURvnKXD6fC98LPWN6uJtIHFLf4Ss9Q3YLmEkegO2WM=
32
+ -----END CERTIFICATE-----
33
+ date: 2014-02-13 00:00:00.000000000 Z
34
+ dependencies:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rack
37
+ requirement: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.5'
42
+ type: :runtime
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.5'
49
+ - !ruby/object:Gem::Dependency
50
+ name: tilt
51
+ requirement: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '2.0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: mustermann
65
+ requirement: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.2'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '0.2'
77
+ - !ruby/object:Gem::Dependency
78
+ name: i18n
79
+ requirement: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '0.6'
84
+ type: :runtime
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '0.6'
91
+ - !ruby/object:Gem::Dependency
92
+ name: rspec
93
+ requirement: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '='
96
+ - !ruby/object:Gem::Version
97
+ version: 3.0.0.beta1
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '='
103
+ - !ruby/object:Gem::Version
104
+ version: 3.0.0.beta1
105
+ description: Lightweight web framework inspired by Sinatra
106
+ email:
107
+ - cirex@aethernet.org
108
+ executables: []
109
+ extensions: []
110
+ extra_rdoc_files: []
111
+ files:
112
+ - Rakefile
113
+ - fenix-core.gemspec
114
+ - lib/fenix/core.rb
115
+ - lib/fenix/core/application.rb
116
+ - lib/fenix/core/exceptions.rb
117
+ - lib/fenix/core/rendering.rb
118
+ - lib/fenix/core/request.rb
119
+ - lib/fenix/core/response.rb
120
+ - lib/fenix/core/settings.rb
121
+ - lib/fenix/core/version.rb
122
+ homepage: https://github.com/fenix-novus/fenix
123
+ licenses:
124
+ - MIT
125
+ metadata: {}
126
+ post_install_message:
127
+ rdoc_options: []
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: 2.1.0
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 2.2.1
143
+ signing_key:
144
+ specification_version: 4
145
+ summary: Lightweight web framework inspired by Sinatra
146
+ test_files: []
147
+ has_rdoc:
metadata.gz.sig ADDED
Binary file