kaffe 0.0.4

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: 54af1d3d0377a497f6324b9c96a84cd5026e9774
4
+ data.tar.gz: b7ca063757eaf0da2b3ac3610270bd355a507bca
5
+ SHA512:
6
+ metadata.gz: 252edcddaf865e0ac60b9298980b6105cf92ea71bed3575f6fcdb8d3f301924f5f45005ee71142ea1916f290914ef161650801559b18899ddfca96d5d9b7d57c
7
+ data.tar.gz: 9e29043f70a593e0b0595a1898c00e924ffb19d76a40628f5932900b6310ab532e653f1170ad17c63560a50628ae715d4f0c3e42261612a5a7dd2dff30012593
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,21 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ script: bundle exec rake spec
5
+ before_deploy:
6
+ - bundle exec rake build
7
+ - export GEM_FILE="$(ls -1 pkg/*.gem | tail -n1)"
8
+ deploy:
9
+ - provider: rubygems
10
+ api_key: ${RUBYGEMS_KEY}
11
+ gem: kaffe
12
+ on:
13
+ tags: true
14
+ repo: kaffepanna/kaffe
15
+ - provider: releases
16
+ api_key: ${GITHUB_TOKEN}
17
+ file: ${GEM_FILE}
18
+ file_glob: true
19
+ on:
20
+ tags: true
21
+ repo: kaffepanna/kaffe
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kaffe.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Patrik Pettersson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all 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,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ # Kaffe Framework
2
+ This is a minimalistic webframework inspired by sinatra and
3
+ rails.
4
+
5
+ ## Basic usage
6
+ The idea is to use be able to create modular applications and
7
+ forward requests between them.
8
+
9
+ class Blog < Kaffe::Base
10
+ use Rack::CommonLogger
11
+
12
+ get '/?' do
13
+ "Hello From Blog"
14
+ end
15
+ end
16
+
17
+ class Admin < Kaffe::Base
18
+ get '/login' do
19
+ ... Login logics ...
20
+ end
21
+
22
+ error 400..500 do |code, message|
23
+ .. show pretty error message ..
24
+ end
25
+ end
26
+
27
+ class MyApp < Kaffe::Base
28
+ route '/blog', Blog
29
+ route '/admin', Admin
30
+ end
31
+
32
+ run MyApp
33
+
34
+ ## API overview
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "kaffe"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,11 @@
1
+ require 'kaffe'
2
+ require 'rack'
3
+
4
+
5
+ class MyApp < Kaffe::Base
6
+ get '/?' do
7
+ "Hello World"
8
+ end
9
+ end
10
+
11
+ Rack::Handler::WEBrick.run MyApp
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'kaffe/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "kaffe"
9
+ spec.version = Kaffe::VERSION
10
+ spec.authors = ["Patrik Pettersson"]
11
+ spec.email = ["pettersson.pa@gmail.com"]
12
+
13
+ spec.summary = %q{Minimalistic webframework inspired by sinatra and rails}
14
+ spec.description = `cat README.md`
15
+ spec.homepage = 'https://github.com/kaffepanna/kaffe'
16
+ spec.license = "MIT"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
+ f.match(%r{^(test|spec|features)/})
20
+ end
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_runtime_dependency "rack", '~> 1.5'
26
+ spec.add_runtime_dependency "tilt", '~> 1.4'
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.14"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rspec", "~> 3.0"
31
+ end
@@ -0,0 +1,11 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $:.unshift(libdir) unless $:.include?(libdir)
3
+ require 'tilt'
4
+ require 'kaffe/render'
5
+ require 'kaffe/error'
6
+ require 'kaffe/routes'
7
+ require 'kaffe/actions'
8
+ require 'kaffe/static'
9
+ require 'kaffe/settings'
10
+ require 'kaffe/base'
11
+ require 'kaffe/version'
@@ -0,0 +1,73 @@
1
+ module Kaffe
2
+
3
+ module Actions
4
+ module ClassMethods
5
+ attr_accessor :actions
6
+ def actions; @actions ||= Hash.new {|hash, key| hash[key] = []} end
7
+
8
+ def call(env); instance.call(env) end
9
+ def get(path, &block); action('GET', path, &block) end
10
+ def post(path, &block); action('POST', path, &block) end
11
+
12
+ def action(method, path, &block)
13
+ id = :"#{method} #{path}"
14
+ define_method(id, &block)
15
+ expr, keys = compile!(path)
16
+ actions[method] << [expr, keys, id]
17
+ end
18
+
19
+ def compile!(path)
20
+ keys = []
21
+ if path.is_a? Regexp
22
+ keys = 'splat'
23
+ pattern = path
24
+ elsif path.is_a? String
25
+ pattern =path.gsub(/(:\w+)/) do |match|
26
+ keys << $1[1..-1]
27
+ "([^/?&#]+)"
28
+ end
29
+ end
30
+ return [/^#{pattern}$/, keys]
31
+ end
32
+ end
33
+
34
+ def dispatch_action!
35
+ routes = self.class.actions[@request.request_method]
36
+ path = @request.path_info
37
+ routes.each do |expr, keys, id|
38
+ if path.match(expr)
39
+ values = $~.captures.to_a
40
+ if keys == "splat"
41
+ hash = {'splat' => values }
42
+ else
43
+ hash = Hash[keys.zip(values)]
44
+ end
45
+ @request.params.merge! hash
46
+ m = method(id)
47
+ throw :success, if m.arity != 0
48
+ m.call(*values)
49
+ else
50
+ m.call
51
+ end
52
+ end
53
+ end
54
+ raise NoMethodError.new("Could not find matching action for #{path}")
55
+ end
56
+
57
+ def action!
58
+ begin
59
+ dispatch_action!
60
+ rescue NoMethodError => e
61
+ register_error(404, "Could Not Find Action: #{e.message}\n#{e.backtrace.join("\n")}")
62
+ rescue Exception => error
63
+ register_error(500, error.message)
64
+ ensure
65
+ # TODO: after filter!
66
+ end
67
+ end
68
+
69
+ def self.included(base)
70
+ base.extend(ClassMethods)
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,82 @@
1
+ require 'rack'
2
+ require 'tilt'
3
+
4
+ module Kaffe
5
+ class Base
6
+ include Kaffe::Error
7
+ include Kaffe::Actions
8
+ include Kaffe::Routes
9
+ include Kaffe::Settings
10
+ include Kaffe::Render
11
+
12
+ attr_reader :params, :request, :response, :env
13
+
14
+ set :environment, proc { ENV['RACK_ENV'] || :development }
15
+
16
+ def initialize(app=nil)
17
+ @app = app
18
+ @templates = {}
19
+ end
20
+
21
+ def call(env)
22
+ @env = env
23
+ @request = Rack::Request.new(env)
24
+ @response = Rack::Response.new
25
+ run! {
26
+ # handle if errors were sent from route
27
+ env['kaffe.error'] = catch(:error) {
28
+ route!
29
+ action!
30
+ }
31
+ error!
32
+ }
33
+
34
+ if @app
35
+ @app.call(@response.finish)
36
+ else
37
+ @response.finish
38
+ end
39
+ end
40
+
41
+ def run! &block
42
+ begin
43
+ res = catch(:success) { block.call }
44
+ case res
45
+ when String
46
+ @response.body = [res]
47
+ when Array
48
+ @response.status = res[0]
49
+ res[1].each {|h, v| @response.headers[h] = v }
50
+ @response.body = res[2]
51
+ else
52
+ puts "Should not be here"
53
+ @response.status = 500
54
+ end
55
+ rescue # Something gone wrong and havent been handeled.
56
+ puts "WARN: Define your error handlers!!!"
57
+ @response.status = env['kaffe.error'].first
58
+ @response.body = [env['kaffe.error'].last]
59
+ end
60
+ end
61
+
62
+
63
+ class << self
64
+ def new(*args)
65
+ builder = Rack::Builder.new
66
+ middleware.each {|m, args, block| builder.use(m,*args,&block) }
67
+ builder.run super
68
+ builder.to_app
69
+ end
70
+
71
+ def call(env); instance.call(env) end
72
+ def instance; @instance ||= new end
73
+ def middleware; @middleware ||= [] end
74
+
75
+ def use(m, *args, &block)
76
+ middleware << [m, args, block]
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+
@@ -0,0 +1,59 @@
1
+ module Kaffe
2
+ module Error
3
+ module ClassMethods
4
+
5
+ def errors; @errors ||= [] end
6
+
7
+ def error(name, &block)
8
+ id = :"ERROR #{name}"
9
+ define_method(id, &block)
10
+ case name
11
+ when Range
12
+ errors << [name, id]
13
+ when Fixnum
14
+ errors << [name, id]
15
+ else
16
+ raise ArgumentError, "error must be a fixnum or range"
17
+ end
18
+ end
19
+ end
20
+
21
+ def register_error(code, message)
22
+ env['kaffe.error'] = [code, message]
23
+ throw :error, env['kaffe.error']
24
+ end
25
+
26
+ def dispatch_error!
27
+ e = env['kaffe.error'] || [500, "Unknown Server Error"]
28
+ code = e.first
29
+ block=nil
30
+ self.class.errors.each do |name, id|
31
+ case name
32
+ when Fixnum
33
+ block = method(id) if name == code
34
+ break
35
+ when Range
36
+ block = method(id) if name.include? code
37
+ break
38
+ end
39
+ end
40
+ if(block)
41
+ @response.status = code
42
+ throw:success, if block.arity != 0
43
+ block.call(*e)
44
+ else
45
+ block.call
46
+ end
47
+ end
48
+ throw :error, e
49
+ end
50
+
51
+ def error!
52
+ dispatch_error!
53
+ end
54
+
55
+ def self.included(base)
56
+ base.extend(ClassMethods)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,41 @@
1
+ module Kaffe
2
+ module Render
3
+ include Tilt::CompileSite
4
+ def templates
5
+ @templates ||= Tilt::Cache.new
6
+ end
7
+
8
+ def render(template, options: {}, &block)
9
+ local = options.delete(:locals) || {}
10
+ views = options.delete(:views) || settings.views || "./views"
11
+ layout = options[:layout] || settings.layout || :layout
12
+
13
+ case template
14
+ when Symbol
15
+ path = nil
16
+ found = false
17
+ find_template(views, template, engine) do |file|
18
+ puts "testing #{file}"
19
+ if found = File.exists?(file)
20
+ path = file
21
+ break
22
+ end
23
+ end
24
+ raise "Could not find Template #{template}" unless found
25
+ t = templates.fetch(path) { Tilt.new path }
26
+ output = t.render(self, &block)
27
+
28
+ if layout
29
+ return render(engine, layout, layout: false) { output }
30
+ end
31
+ return output
32
+ end
33
+ end
34
+
35
+ def find_template(views, name, engine)
36
+ Tilt.mappings.each do |ext, engines|
37
+ yield ::File.join(views, "#{name}.#{ext}")
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ module Kaffe
2
+ module Routes
3
+ module ClassMethods
4
+ attr_accessor :routes
5
+ def routes; @routes ||= Array.new end
6
+
7
+ def route(path, app)
8
+ routes.push [path, app]
9
+ end
10
+ end
11
+
12
+ def route!
13
+ path = env["PATH_INFO"].to_s
14
+ self.class.routes.each do |exp, app|
15
+ if path.match exp
16
+ match = $~.to_s
17
+ throw :success, app.call(env.merge(
18
+ "PATH_INFO" => path[match.size..-1],
19
+ "SCRIPT_NAME" => match))
20
+ end
21
+ end
22
+ nil
23
+ end
24
+
25
+ def self.included(base)
26
+ base.extend(ClassMethods)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module Kaffe
2
+ module Settings
3
+
4
+ module ClassMethods
5
+ def set option, value
6
+ case value
7
+ when Proc
8
+ settings.define_singleton_method(option, value)
9
+ else
10
+ set(option, proc { value })
11
+ end
12
+ end
13
+
14
+ def settings
15
+ self
16
+ end
17
+ end
18
+
19
+ def settings
20
+ self.class.settings
21
+ end
22
+
23
+ def self.included(base)
24
+ base.extend(ClassMethods)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module Kaffe
2
+ class Static
3
+ def initialize(app=nil, path)
4
+ @app = app
5
+ @files = Rack::File.new(path)
6
+ end
7
+
8
+ def call(env)
9
+ res = @files.call(env)
10
+ if res.first == 404 && @app
11
+ res =@app.call(env)
12
+ end
13
+
14
+ res
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,3 @@
1
+ module Kaffe
2
+ VERSION = `git describe --abbrev=0 --tags 2>/dev/null`.strip
3
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kaffe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Patrik Pettersson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tilt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: "# Kaffe Framework\nThis is a minimalistic webframework inspired by sinatra
84
+ and \nrails.\n\n## Basic usage\nThe idea is to use be able to create modular applications
85
+ and\nforward requests between them.\n\n class Blog < Kaffe::Base\n use
86
+ Rack::CommonLogger\n\n get '/?' do\n \"Hello From Blog\" \n
87
+ \ end\n end\n\n class Admin < Kaffe::Base\n get '/login'
88
+ do\n ... Login logics ...\n end\n\n error 400..500
89
+ do |code, message|\n .. show pretty error message ..\n end\n
90
+ \ end\n\n class MyApp < Kaffe::Base\n route '/blog', Blog\n
91
+ \ route '/admin', Admin\n end\n\n run MyApp\n\n## API overview\n"
92
+ email:
93
+ - pettersson.pa@gmail.com
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - ".gitignore"
99
+ - ".rspec"
100
+ - ".travis.yml"
101
+ - Gemfile
102
+ - LICENSE.txt
103
+ - README.md
104
+ - Rakefile
105
+ - bin/console
106
+ - bin/setup
107
+ - examples/simple.rb
108
+ - kaffe.gemspec
109
+ - lib/kaffe.rb
110
+ - lib/kaffe/actions.rb
111
+ - lib/kaffe/base.rb
112
+ - lib/kaffe/error.rb
113
+ - lib/kaffe/render.rb
114
+ - lib/kaffe/routes.rb
115
+ - lib/kaffe/settings.rb
116
+ - lib/kaffe/static.rb
117
+ - lib/kaffe/version.rb
118
+ homepage: https://github.com/kaffepanna/kaffe
119
+ licenses:
120
+ - MIT
121
+ metadata: {}
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project:
138
+ rubygems_version: 2.5.1
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Minimalistic webframework inspired by sinatra and rails
142
+ test_files: []