rubko 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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/bin/rubko-deploy +40 -0
  4. data/bin/rubko-init +6 -0
  5. data/lib/rubko/app.rb +79 -0
  6. data/lib/rubko/asset/fileStream.rb +18 -0
  7. data/lib/rubko/asset/gzipStream.rb +26 -0
  8. data/lib/rubko/asset.rb +71 -0
  9. data/lib/rubko/base.rb +123 -0
  10. data/lib/rubko/controller.rb +17 -0
  11. data/lib/rubko/model.rb +5 -0
  12. data/lib/rubko/plugin.rb +7 -0
  13. data/lib/rubko/plugins/cookie.rb +45 -0
  14. data/lib/rubko/plugins/db.rb +389 -0
  15. data/lib/rubko/plugins/facebook.rb +50 -0
  16. data/lib/rubko/plugins/log.rb +49 -0
  17. data/lib/rubko/plugins/session.rb +88 -0
  18. data/lib/rubko/plugins/storage/db.rb +6 -0
  19. data/lib/rubko/plugins/storage/disk.rb +50 -0
  20. data/lib/rubko/plugins/storage/memory.rb +60 -0
  21. data/lib/rubko/plugins/url.rb +91 -0
  22. data/lib/rubko/socket.rb +23 -0
  23. data/lib/rubko/storage.rb +27 -0
  24. data/lib/rubko.rb +32 -0
  25. data/rubko.gemspec +22 -0
  26. data/stamp/.gitignore +3 -0
  27. data/stamp/config/db.rb +8 -0
  28. data/stamp/config/facebook.rb +8 -0
  29. data/stamp/config/session.rb +7 -0
  30. data/stamp/config/url.rb +7 -0
  31. data/stamp/config.ru +38 -0
  32. data/stamp/controllers/error404.rb +19 -0
  33. data/stamp/controllers/files.rb +20 -0
  34. data/stamp/controllers/welcome.rb +6 -0
  35. data/stamp/models/user.rb +14 -0
  36. data/stamp/public/css/.private/default.sass +31 -0
  37. data/stamp/public/img/favicon.png +0 -0
  38. data/stamp/public/js/jquery/iframize.js +25 -0
  39. data/stamp/public/js/jquery/translate.js +112 -0
  40. data/stamp/public/js/merge.sh +10 -0
  41. data/stamp/tarok.yml +17 -0
  42. data/stamp/views/welcome.haml +11 -0
  43. metadata +100 -0
@@ -0,0 +1,91 @@
1
+ require 'uri'
2
+
3
+ class UrlPlugin < Rubko::Plugin
4
+ def init
5
+ @ending = '/' # the ending for documents (use .php for amusement)
6
+ @base = '/' # if project is not top level, set (or use HTML <base>)
7
+ @fileBase = 'files' # nil to import them globally
8
+ @fileTime = true # timestamp files for automatic reload
9
+ @fullPath = false # generate absolute paths
10
+ end
11
+
12
+ def path=(path)
13
+ len = path.start_with?(@base) ? @base.length : 1
14
+ @path = URI.unescape(path)[len..-1].chomp(@ending).split '/', -1
15
+ @newPath = nil
16
+
17
+ @protocol = env['rack.url_scheme'] + '://'
18
+ @host = env['HTTP_HOST']
19
+
20
+ @method = env['REQUEST_METHOD'].upcase
21
+ end
22
+
23
+ def newPath
24
+ unless @newPath
25
+ @newPath = @path * '/'
26
+ config
27
+ @newPath = @newPath.split '/', -1
28
+ end
29
+ @newPath
30
+ end
31
+
32
+ attr_accessor :ending, :base, :fileBase, :fileTime, :fullPath
33
+ attr_reader :protocol, :host, :method, :path #, :newPath
34
+
35
+ def ajax?
36
+ env["HTTP_X_REQUESTED_WITH"] == 'XMLHttpRequest'
37
+ end
38
+
39
+ def rewrite(from, to)
40
+ @newPath.sub! from, to if from === @newPath
41
+ end
42
+
43
+ def slug(str)
44
+ str.strip.downcase.gsub(/[^0-9a-z]+/i, '-').gsub(/^-+|-+$/, '')
45
+ end
46
+
47
+ def generate(*path)
48
+ path.compact!
49
+ path.map! { |seg|
50
+ seg = @path[seg] if seg.kind_of? Integer
51
+ URI.escape seg
52
+ }
53
+ (@protocol+@host if @fullPath).to_s + @base + path.join('/')
54
+ end
55
+
56
+ def link(*path)
57
+ generate(*path) + (@ending unless path.empty?).to_s
58
+ end
59
+
60
+ def linkSlug(*path)
61
+ link( *path.compact.map { |x| slug x } )
62
+ end
63
+
64
+ def file(*path)
65
+ name = 'public/' + path.join('/')
66
+ time = File.mtime(name).to_i / 3 % 1000000 if File.exists? name
67
+ generate @fileBase, (time.to_s if @fileTime), *path
68
+ end
69
+
70
+ def redirect(*path)
71
+ self.status = 302
72
+ self.headers['Location'] =
73
+ if path.size == 1 && path.first =~ %r{^(https?:)?//}
74
+ path.first
75
+ else
76
+ link(*path)
77
+ end
78
+ ''
79
+ end
80
+
81
+ def refresh
82
+ redirect(*@path)
83
+ end
84
+
85
+ def forceSSL
86
+ if @protocol != 'https://'
87
+ @protocol, @fullPath = 'https://', true
88
+ refresh
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,23 @@
1
+ require 'faye/websocket'
2
+ require 'rubko/controller'
3
+
4
+ class Rubko::Socket < Rubko::Controller
5
+ Faye::WebSocket.load_adapter 'thin'
6
+
7
+ def initialize(*)
8
+ super
9
+ if Faye::WebSocket.websocket?(env)
10
+ @ws = Faye::WebSocket.new env#, [], ping: 10*60
11
+ @ws.onclose = -> event {
12
+ p [:close, event.code, event.reason]
13
+ @ws = nil
14
+ }
15
+ end
16
+ end
17
+
18
+ def finalize
19
+ self.status, self.headers, self.body = *@ws.rack_response if @ws
20
+ end
21
+
22
+ def compressible?; false end
23
+ end
@@ -0,0 +1,27 @@
1
+ require 'rubko/plugin'
2
+
3
+ class Rubko::Storage < Rubko::Plugin
4
+ def values(*path)
5
+ Hash[ keys(*path).map { |key|
6
+ [ key, self[*(path+[key])] ]
7
+ } ]
8
+ end
9
+
10
+ def _inspect(path, depth = 0)
11
+ keys(*path).flat_map { |desc|
12
+ child = path + [desc]
13
+ curr = ' '*depth + desc.to_s
14
+ curr << " (#{self[*child]})" if self[*child]
15
+ [curr] + _inspect(child, depth+1)
16
+ }
17
+ end
18
+ private :_inspect
19
+
20
+ def inspect(*path)
21
+ _inspect path
22
+ end
23
+
24
+ def to_s(*path)
25
+ inspect(path) * "\n"
26
+ end
27
+ end
data/lib/rubko.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubko/app'
2
+
3
+ class Rubko
4
+ VERSION = '0.1'
5
+
6
+ def initialize(shared = {})
7
+ @shared = shared
8
+
9
+ Dir['./includes/**/*.rb'].each { |file|
10
+ require file
11
+ }
12
+ puts 'Server started successfully.'
13
+ end
14
+
15
+ # do not USE !
16
+ def threaded
17
+ EM.threadpool_size = 50
18
+ -> env {
19
+ EM.defer(
20
+ -> { call env },
21
+ -> r { env['async.callback'].call r }
22
+ )
23
+ throw :async
24
+ }
25
+ end
26
+
27
+ def call(env)
28
+ abort if env['rack.multithread']
29
+ app = Rubko::App.new env, @shared
30
+ app.init env['REQUEST_URI'].encode 'utf-8'
31
+ end
32
+ end
data/rubko.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ require './lib/rubko'
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = 'rubko'
5
+ gem.version = Rubko::VERSION
6
+ gem.date = Date.today.to_s
7
+ gem.license = 'GPL'
8
+
9
+ gem.summary = 'Web framework'
10
+ gem.description = 'Simple and amazingly fast ruby web framework.'
11
+
12
+ gem.authors = ['Rok Kralj']
13
+ gem.email = 'ruby@rok-kralj.net'
14
+ gem.homepage = 'https://github.com/strelec/Rubko'
15
+
16
+ files = `git ls-files`
17
+ files = `find ./*` if files.empty?
18
+ gem.files = files.split "\n"
19
+ gem.executables = ['rubko-deploy', 'rubko-init']
20
+
21
+ gem.add_dependency 'json'
22
+ end
data/stamp/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ /.dev
2
+ /.run
3
+ /public/css/*.css
@@ -0,0 +1,8 @@
1
+ class DbPlugin
2
+ def config
3
+ # :host, :port, :user, :password, :db, :pool
4
+
5
+ @db = 'db_name'
6
+ @pool = memory
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class FacebookPlugin
2
+ def config
3
+ # :id, :secret, :home
4
+
5
+ @id = '199853290083934'
6
+ @secret = '0d689e9aed9a32b645c268aa717cf2d3'
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ class SessionPlugin
2
+ def config
3
+ # :name, :path, :timeout, :purgeRate, :hashSize, :storage, :cookie
4
+
5
+ @storage = disk
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class UrlPlugin
2
+ def config
3
+ # :ending, :base, :fileBase, :fileTime, :fullPath
4
+
5
+ rewrite 'favicon.ico', 'files/img/favicon.png'
6
+ end
7
+ end
data/stamp/config.ru ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubko'
2
+
3
+ #\ -w -p 8080
4
+
5
+ Signal.trap('USR1') {
6
+ GC.start
7
+ }
8
+
9
+ #use Rack::CommonLogger
10
+ use Rack::Runtime
11
+
12
+ case ENV['RACK_ENV'].to_sym
13
+ when :development
14
+
15
+ use Rack::Reloader, 0
16
+ use Rack::ShowExceptions
17
+ use Rack::Runtime
18
+ #use Rack::Lint
19
+
20
+ require 'sass/plugin/rack'
21
+ use Sass::Plugin::Rack
22
+ Sass::Plugin.options.merge!(
23
+ style: :compressed,
24
+ cache: false,
25
+ template_location: {
26
+ './public/css/.private' => './public/css'
27
+ },
28
+ full_exception: false
29
+ )
30
+
31
+ when :production
32
+
33
+ # no, because we already do it
34
+ #use Rack::ContentLength
35
+
36
+ end
37
+
38
+ run Rubko.new
@@ -0,0 +1,19 @@
1
+ class Error404Controller < Rubko::Controller
2
+ def index
3
+ other
4
+ end
5
+
6
+ def other(name = nil, *path)
7
+ notFound # or #redirect
8
+ self.mime = 'text/plain'
9
+ "404 \n" + ([name]+path)*' / '
10
+ end
11
+
12
+ def notFound
13
+ self.status = 404
14
+ end
15
+
16
+ def redirect
17
+ url.redirect
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubko/asset'
2
+
3
+ class FilesController < Rubko::Asset
4
+
5
+ def init
6
+ self.dir = 'public'
7
+ end
8
+
9
+ def hit(*path)
10
+ # do nothing special
11
+ end
12
+
13
+ def cache(*path)
14
+ # do nothing
15
+ end
16
+
17
+ def miss(*path)
18
+ super
19
+ end
20
+ end
@@ -0,0 +1,6 @@
1
+ class WelcomeController < Rubko::Controller
2
+
3
+ def index
4
+ loadView :welcome
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ require 'digest/md5'
2
+
3
+ class UserModel < Rubko::Model
4
+
5
+ def [](id, public = false)
6
+ return unless id
7
+ if public
8
+ ret = db.row 'SELECT id, fbID, name, gender, rights, rating FROM users WHERE id=?', id
9
+ ret.merge hash: Digest::MD5.hexdigest(ret[:name])
10
+ else
11
+ db.row 'SELECT * FROM users WHERE id=?', id
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,31 @@
1
+ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td
2
+ margin: 0
3
+ padding: 0
4
+ table
5
+ border-collapse: collapse
6
+ border-spacing: 0
7
+ fieldset, img
8
+ border: 0
9
+ address, caption, cite, code, dfn, em, strong, th, var
10
+ font-style: normal
11
+ font-weight: normal
12
+ ol, ul
13
+ list-style: none
14
+ caption, th
15
+ text-align: left
16
+ h1, h2, h3, h4, h5, h6
17
+ font-size: 100%
18
+ font-weight: normal
19
+ q:before, q:after
20
+ content: ''
21
+ abbr, acronym
22
+ border: 0px
23
+
24
+ body
25
+ padding: 10px 15px
26
+ font-family: 'Open Sans', Arial
27
+
28
+ h1
29
+ font-size: 24px
30
+ font-weight: bold
31
+ margin-bottom: 5px
Binary file
@@ -0,0 +1,25 @@
1
+ $.fn.iframize = function() {
2
+ var arg = arguments;
3
+ $(this).each(function() {
4
+ var o=$(this);
5
+
6
+ function loadURL(url) {
7
+ $.get(url, {}, function(data) {
8
+ o.html(data);
9
+ });
10
+ }
11
+ if (arg[0])
12
+ loadURL(arg[0]);
13
+
14
+ o.find('a').live('click', function() {
15
+ loadURL($(this).attr('href'));
16
+ return false;
17
+ });
18
+ o.find('form').live('submit', function() {
19
+ $.post(url, $(this).find('*').serialize(), function(data) {
20
+ o.html(data);
21
+ });
22
+ });
23
+ });
24
+ return $(this);
25
+ };
@@ -0,0 +1,112 @@
1
+ //(function() {
2
+ //"use strict";
3
+
4
+ $.translate={
5
+ add: function(dict) {
6
+ if (!$.translate.dictionary[$.translate.module])
7
+ $.translate.dictionary[$.translate.module]={};
8
+ if (!$.translate.dictionary[$.translate.module][$.translate.language])
9
+ $.translate.dictionary[$.translate.module][$.translate.language]={string: {}, regex: {}};
10
+ $.each(dict, function(key, val) {
11
+ if (val instanceof RegExp) {
12
+ $.translate.dictionary[$.translate.module][$.translate.language].regex[key]=val;
13
+ } else {
14
+ $.translate.dictionary[$.translate.module][$.translate.language].string[$.translate.clear(key).toLowerCase()]=$.translate.clear(val);
15
+ }
16
+ });
17
+ },
18
+ clear: function(str) {
19
+ return str.replace(/^[\s!?.:()]*|[\s!?.:()]*$/gi, '');
20
+ },
21
+ textNodes: function(el) {
22
+ return $(el).not('iframe,script,style').contents().andSelf().filter(function() {
23
+ return (this.nodeType===3 || $(this).is('input[value][type!=radio][type!=checkbox]')) && /[a-z]/i.test($.translate.get(this));
24
+ });
25
+ },
26
+ get: function(el) {
27
+ if (el.nodeType===3)
28
+ return el.nodeValue;
29
+ return $(el).attr('value');
30
+ },
31
+ set: function(el, val) {
32
+ if (el.nodeType===3)
33
+ return el.nodeValue=val;
34
+ return $(el).attr('value', val);
35
+ },
36
+ lookup: function(str, module, language) {
37
+ module = module || $.translate.module;
38
+ language = language || $.translate.language;
39
+ var ret=false;
40
+ var value=$.translate.clear(str);
41
+ if ($.translate.dictionary[module] && $.translate.dictionary[module][language]) {
42
+ var translation=$.translate.dictionary[module][language].string[value.toLowerCase()];
43
+ if (translation) {
44
+ var temp=str.replace(value, translation);
45
+ if (value[0].toLowerCase()===value[0])
46
+ return temp[0].toLowerCase()+temp.slice(1)
47
+ return temp[0].toUpperCase()+temp.slice(1);
48
+ }
49
+ $.each($.translate.dictionary[module][language].regex, function(key, val) {
50
+ if (val.test(str)) {
51
+ ret=str.replace(val, key);
52
+ return false;
53
+ }
54
+ });
55
+ }
56
+ if (!ret)
57
+ console.log(value);
58
+ return ret;
59
+ },
60
+ text: function(str, module, language) {
61
+ var result=$.translate.lookup(str, module, language);
62
+ if (result!==false)
63
+ return result;
64
+ return str;
65
+ },
66
+ dictionary: {},
67
+ module: 'default',
68
+ language: 'xx',
69
+ original: 'en'
70
+ };
71
+
72
+ $.fn.translate = function(module, language) {
73
+ module = module || $.translate.module;
74
+ language = language || $.translate.language;
75
+ $.translate.textNodes(this).each(function() {
76
+ $(this).untranslate(true);
77
+ if ($(this).data('translateO') || $.translate.clear($.translate.get(this))) {
78
+ if (!$(this).data('translateO'))
79
+ $(this).data('translateO', $.translate.get(this));
80
+ var translation = $(this).data('translateO');
81
+ if (language === $.translate.original || (translation = $.translate.lookup($(this).data('translateO'), module, language)) ) {
82
+ $.translate.set(this, translation);
83
+ $(this).data('translateM', module).data('translateL', language);
84
+ } else $(this).untranslate(true);
85
+ }
86
+ });
87
+ return $(this);
88
+ };
89
+
90
+ $.fn.retranslate = function(module_, language_) {
91
+ $.translate.textNodes(this).each(function() {
92
+ if ($(this).data('translateO')) {
93
+ var module = module_ || $(this).data('translateM');
94
+ var language = language_ || $(this).data('translateL');
95
+ var translation = $(this).data('translateO');
96
+ if (language === $.translate.original || (translation = $.translate.lookup($(this).data('translateO'), module, language)) ) {
97
+ $.translate.set(this, translation);
98
+ $(this).data('translateM', module).data('translateL', language);
99
+ }
100
+ }
101
+ });
102
+ return $(this);
103
+ };
104
+
105
+ $.fn.untranslate = function(undo) {
106
+ $.translate.textNodes(this).each(function() {
107
+ if (undo && $(this).data('translateO'))
108
+ $.translate.set(this, $(this).data('translateO'));
109
+ $(this).removeData();
110
+ });
111
+ };
112
+ //})();
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ coffee -c .private/core.coffee
4
+
5
+ :> js.js
6
+ closure --charset utf-8 jquery/jquery.js >> js.js
7
+ closure --charset utf-8 core.js >> js.js
8
+ closure --charset utf-8 jquery/iframize.js >> js.js
9
+ closure --charset utf-8 jquery/translate.js >> js.js
10
+ closure --charset utf-8 .private/core.js >> js.js
data/stamp/tarok.yml ADDED
@@ -0,0 +1,17 @@
1
+ ---
2
+ user: http
3
+ group: http
4
+ #port: 3000
5
+ pid: .run/thin.pid
6
+ chdir: /srv/http/tarok/
7
+ tag: tarok
8
+ timeout: 600
9
+ wait: 30
10
+ log: .run/thin.log
11
+ max_conns: 1024
12
+ environment: production
13
+ max_persistent_conns: 512
14
+ servers: 1
15
+ threaded: false
16
+ daemonize: true
17
+ socket: .run/thin.sock
@@ -0,0 +1,11 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title Test page
5
+ %link{href: url.file('css', 'default.css'), media: 'screen, print', rel: 'stylesheet', type: 'text/css'}
6
+ %body
7
+ %header
8
+ %h1 Welcome to default page of Rubko framework!
9
+ #content
10
+ %p
11
+ You should edit controllers/welcome.rb and corresponding template views/welcome.haml.
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubko
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Rok Kralj
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Simple and amazingly fast ruby web framework.
28
+ email: ruby@rok-kralj.net
29
+ executables:
30
+ - rubko-deploy
31
+ - rubko-init
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - bin/rubko-deploy
37
+ - bin/rubko-init
38
+ - lib/rubko.rb
39
+ - lib/rubko/app.rb
40
+ - lib/rubko/asset.rb
41
+ - lib/rubko/asset/fileStream.rb
42
+ - lib/rubko/asset/gzipStream.rb
43
+ - lib/rubko/base.rb
44
+ - lib/rubko/controller.rb
45
+ - lib/rubko/model.rb
46
+ - lib/rubko/plugin.rb
47
+ - lib/rubko/plugins/cookie.rb
48
+ - lib/rubko/plugins/db.rb
49
+ - lib/rubko/plugins/facebook.rb
50
+ - lib/rubko/plugins/log.rb
51
+ - lib/rubko/plugins/session.rb
52
+ - lib/rubko/plugins/storage/db.rb
53
+ - lib/rubko/plugins/storage/disk.rb
54
+ - lib/rubko/plugins/storage/memory.rb
55
+ - lib/rubko/plugins/url.rb
56
+ - lib/rubko/socket.rb
57
+ - lib/rubko/storage.rb
58
+ - rubko.gemspec
59
+ - stamp/.gitignore
60
+ - stamp/config.ru
61
+ - stamp/config/db.rb
62
+ - stamp/config/facebook.rb
63
+ - stamp/config/session.rb
64
+ - stamp/config/url.rb
65
+ - stamp/controllers/error404.rb
66
+ - stamp/controllers/files.rb
67
+ - stamp/controllers/welcome.rb
68
+ - stamp/models/user.rb
69
+ - stamp/public/css/.private/default.sass
70
+ - stamp/public/img/favicon.png
71
+ - stamp/public/js/jquery/iframize.js
72
+ - stamp/public/js/jquery/translate.js
73
+ - stamp/public/js/merge.sh
74
+ - stamp/tarok.yml
75
+ - stamp/views/welcome.haml
76
+ homepage: https://github.com/strelec/Rubko
77
+ licenses:
78
+ - GPL
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.0.3
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Web framework
100
+ test_files: []