rubko 0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []