togo 0.6.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/togo-admin +3 -3
- data/lib/togo/admin/admin.rb +21 -2
- data/lib/togo/admin/helpers.rb +5 -17
- data/lib/togo/admin/public/css/login.css +95 -0
- data/lib/togo/admin/public/css/screen.css +13 -0
- data/lib/togo/admin/public/img/login-bg.png +0 -0
- data/lib/togo/admin/public/img/shadow.png +0 -0
- data/lib/togo/admin/public/js/login.js +30 -0
- data/lib/togo/admin/views/layout.erb +11 -5
- data/lib/togo/admin/views/login.erb +33 -0
- data/lib/togo/admin.rb +2 -1
- data/lib/togo/dispatch/dispatch.rb +37 -2
- data/lib/togo/model/model.rb +1 -5
- metadata +13 -8
data/bin/togo-admin
CHANGED
@@ -28,6 +28,9 @@ OptionParser.new{|opt|
|
|
28
28
|
end
|
29
29
|
}.parse!
|
30
30
|
|
31
|
+
require 'togo'
|
32
|
+
require 'togo/admin'
|
33
|
+
|
31
34
|
begin
|
32
35
|
files_to_require.each{|f| require f}
|
33
36
|
require 'togo-admin-config'
|
@@ -35,9 +38,6 @@ rescue LoadError => detail
|
|
35
38
|
puts "Warning: #{detail}"
|
36
39
|
end
|
37
40
|
|
38
|
-
require 'togo'
|
39
|
-
require 'togo/admin'
|
40
|
-
|
41
41
|
config.merge!({
|
42
42
|
:handler => Togo::Admin.handler,
|
43
43
|
:reloader => Togo::TogoReloader
|
data/lib/togo/admin/admin.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'helpers'
|
1
|
+
require 'togo/admin/helpers'
|
2
2
|
|
3
3
|
module Togo
|
4
4
|
class Admin < Dispatch
|
@@ -6,13 +6,32 @@ module Togo
|
|
6
6
|
include Helpers
|
7
7
|
|
8
8
|
before do
|
9
|
-
|
9
|
+
if not logged_in? and request.path != '/login'
|
10
|
+
redirect "/login"
|
11
|
+
else
|
12
|
+
@model = Togo.const_get(params[:model]) if params[:model]
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
get '/' do
|
13
17
|
redirect "/#{Togo.models.first}"
|
14
18
|
end
|
15
19
|
|
20
|
+
get '/login' do
|
21
|
+
erb :login, :layout => false
|
22
|
+
end
|
23
|
+
|
24
|
+
post '/login' do
|
25
|
+
session[:user] = config[:auth_model].authenticate(params[:username], params[:password])
|
26
|
+
flash[:error] = "Invalid Username or Password" if not logged_in?
|
27
|
+
redirect '/'
|
28
|
+
end
|
29
|
+
|
30
|
+
get '/logout' do
|
31
|
+
session[:user] = nil
|
32
|
+
redirect '/'
|
33
|
+
end
|
34
|
+
|
16
35
|
get '/:model' do
|
17
36
|
@q = params[:q] || ''
|
18
37
|
@p = (params[:p] || 1).to_i
|
data/lib/togo/admin/helpers.rb
CHANGED
@@ -1,22 +1,5 @@
|
|
1
1
|
module Helpers
|
2
2
|
|
3
|
-
class FlashHash
|
4
|
-
def initialize
|
5
|
-
@h = {}
|
6
|
-
@c = {}
|
7
|
-
end
|
8
|
-
def [](key)
|
9
|
-
return @c[key] if @c.keys.include?(key)
|
10
|
-
@c[key] = @h.delete(key) if @h.keys.include?(key)
|
11
|
-
end
|
12
|
-
def []=(key,val)
|
13
|
-
@h[key] = val
|
14
|
-
end
|
15
|
-
def sweep!
|
16
|
-
@c = {}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
3
|
def hash_to_qs(h)
|
21
4
|
return nil if h.blank?
|
22
5
|
qs = h.keys.collect{|k|
|
@@ -54,4 +37,9 @@ module Helpers
|
|
54
37
|
request.path =~ /#{name}/ ? 'active' : ''
|
55
38
|
end
|
56
39
|
|
40
|
+
def logged_in?
|
41
|
+
return true if not config[:auth_model] or not config[:sessions]
|
42
|
+
config[:auth_model] and session[:user] and session[:user].authenticated?
|
43
|
+
end
|
44
|
+
|
57
45
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
* {
|
2
|
+
outline: none;
|
3
|
+
}
|
4
|
+
.error {
|
5
|
+
background: #8A0000;
|
6
|
+
text-shadow: 0 1px 1px #710000;
|
7
|
+
border: 1px solid #a12f19;
|
8
|
+
-webkit-border-radius: 4px;
|
9
|
+
-moz-border-radius: 4px;
|
10
|
+
color: #FFF;
|
11
|
+
}
|
12
|
+
h3.error {
|
13
|
+
margin: 0 25px 10px 20px;
|
14
|
+
padding: 10px 0 10px 10px;
|
15
|
+
font-size: 14px;
|
16
|
+
}
|
17
|
+
body {
|
18
|
+
background: #efefef url(/img/login-bg.png) top left repeat-x;
|
19
|
+
font: 100% helvetica, arial, sans-serif;
|
20
|
+
margin: 0;
|
21
|
+
padding: 0;
|
22
|
+
}
|
23
|
+
#container {
|
24
|
+
background: #f5f5f5;
|
25
|
+
width: 400px;
|
26
|
+
margin: 100px auto;
|
27
|
+
border: 1px solid #d4d2d2;
|
28
|
+
-webkit-border-radius: 4px;
|
29
|
+
-moz-border-radius: 4px;
|
30
|
+
}
|
31
|
+
#container h1 {
|
32
|
+
background: #586069 url(/img/bg-header.png) repeat-x top left;
|
33
|
+
font-size: 24px;
|
34
|
+
color: #FFF;
|
35
|
+
text-shadow: 1px 1px 1px #5e6a76;
|
36
|
+
font-weight: normal;
|
37
|
+
line-height: 60px;
|
38
|
+
margin: 0 0 20px 0;
|
39
|
+
padding: 0 20px;
|
40
|
+
-webkit-border-top-right-radius: 4px;
|
41
|
+
-webkit-border-top-left-radius: 4px;
|
42
|
+
-moz-border-radius: 4px;
|
43
|
+
}
|
44
|
+
#container form {
|
45
|
+
padding: 0 20px 20px 20px;
|
46
|
+
}
|
47
|
+
#container fieldset {
|
48
|
+
border: 0;
|
49
|
+
padding: 10px 20px 10px 0;
|
50
|
+
}
|
51
|
+
#container fieldset label {
|
52
|
+
font-size: 13px;
|
53
|
+
font-weight: bold;
|
54
|
+
color: #515151;
|
55
|
+
display: block;
|
56
|
+
padding-bottom: 10px;
|
57
|
+
}
|
58
|
+
#container fieldset label.inline {
|
59
|
+
display: inline;
|
60
|
+
font-weight: normal;
|
61
|
+
}
|
62
|
+
#container fieldset input[type=password],
|
63
|
+
#container fieldset input[type=text] {
|
64
|
+
border: 1px solid #dedddd;
|
65
|
+
border-top: 2px solid #CCC;
|
66
|
+
border-left: 2px solid #CCC;
|
67
|
+
background: #f9f9f9;
|
68
|
+
padding: 7px;
|
69
|
+
width: 100%;
|
70
|
+
margin-right: 20px;
|
71
|
+
font-size: 13px;
|
72
|
+
}
|
73
|
+
#container fieldset input.placeholder {
|
74
|
+
color: #999;
|
75
|
+
}
|
76
|
+
#container form button {
|
77
|
+
border: 1px solid #549300;
|
78
|
+
background: #61a801 url(/img/button-bg-save.png) repeat-x top left;
|
79
|
+
-webkit-border-radius: 4px;
|
80
|
+
-moz-border-radius: 4px;
|
81
|
+
padding: 5px 10px;
|
82
|
+
font-size: 13px;
|
83
|
+
font-weight: bold;
|
84
|
+
text-shadow: 0 1px 1px #538A00;
|
85
|
+
color: #FFF;
|
86
|
+
}
|
87
|
+
#container form button:hover {
|
88
|
+
background: #69b802 url(/img/button-bg-save.png) repeat-x -30px left;
|
89
|
+
text-shadow: 0 1px 1px #538A00;
|
90
|
+
cursor: pointer;
|
91
|
+
}
|
92
|
+
#container fieldset.submit {
|
93
|
+
text-align: right;
|
94
|
+
padding: 0;
|
95
|
+
}
|
@@ -46,6 +46,19 @@ h3.error {
|
|
46
46
|
padding: 5px;
|
47
47
|
font-size: 11px;
|
48
48
|
}
|
49
|
+
#header #system-menu ul {
|
50
|
+
margin: 0;
|
51
|
+
padding: 0;
|
52
|
+
}
|
53
|
+
#header #system-menu ul li {
|
54
|
+
margin: 0;
|
55
|
+
padding: 0;
|
56
|
+
list-style: none;
|
57
|
+
}
|
58
|
+
#header #system-menu ul li a {
|
59
|
+
color: #FFF;
|
60
|
+
text-decoration: none;
|
61
|
+
}
|
49
62
|
#model-select {
|
50
63
|
font-size: 16px;
|
51
64
|
position: absolute;
|
Binary file
|
Binary file
|
@@ -0,0 +1,30 @@
|
|
1
|
+
var login = (function() {
|
2
|
+
|
3
|
+
var clearDefaults = function(e) {
|
4
|
+
if (this.defaultValue == this.value) {
|
5
|
+
removeClass(this, 'placeholder');
|
6
|
+
this.value = '';
|
7
|
+
if (this.getAttribute('id') == 'password') {
|
8
|
+
this.setAttribute('type','password');
|
9
|
+
}
|
10
|
+
} else if (this.value == '') {
|
11
|
+
this.value = this.defaultValue;
|
12
|
+
addClass(this, 'placeholder');
|
13
|
+
if (this.getAttribute('type') == 'password') {
|
14
|
+
this.setAttribute('type', 'text');
|
15
|
+
}
|
16
|
+
}
|
17
|
+
};
|
18
|
+
|
19
|
+
var init = function() {
|
20
|
+
listen('focus', el('username'), clearDefaults);
|
21
|
+
listen('blur', el('username'), clearDefaults);
|
22
|
+
listen('focus', el('password'), clearDefaults);
|
23
|
+
listen('blur', el('password'), clearDefaults);
|
24
|
+
};
|
25
|
+
|
26
|
+
return {
|
27
|
+
init: init
|
28
|
+
};
|
29
|
+
|
30
|
+
}());
|
@@ -2,17 +2,23 @@
|
|
2
2
|
<html>
|
3
3
|
<head>
|
4
4
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
5
|
-
<title
|
5
|
+
<title><%= config[:site_title] %></title>
|
6
6
|
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
|
7
7
|
<script type="text/javascript" src="/js/togo.js"></script>
|
8
8
|
</head>
|
9
9
|
<body id="<%= @body_id %>">
|
10
10
|
<div id="container">
|
11
11
|
<div id="header">
|
12
|
-
<h1
|
13
|
-
|
14
|
-
<
|
15
|
-
|
12
|
+
<h1><%= config[:site_title] %></h1>
|
13
|
+
<% if config[:system_menu] and config[:system_menu].is_a?(Array) %>
|
14
|
+
<div id="system-menu">
|
15
|
+
<ul>
|
16
|
+
<% config[:system_menu].each do |s| %>
|
17
|
+
<li><a href="<%= s[:url] %>"><%= s[:title] %></a></li>
|
18
|
+
<% end %>
|
19
|
+
</ul>
|
20
|
+
</div>
|
21
|
+
<% end %>
|
16
22
|
</div>
|
17
23
|
<div id="content">
|
18
24
|
<%= yield %>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
5
|
+
<title><%= config[:site_title] %> - Login</title>
|
6
|
+
<link rel="stylesheet" href="/css/login.css" type="text/css" media="screen" />
|
7
|
+
<script type="text/javascript" src="/js/togo.js"></script>
|
8
|
+
<script type="text/javascript" src="/js/login.js"></script>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<div id="container">
|
12
|
+
<h1>Welcome! Please Log In.</h1>
|
13
|
+
<% if flash[:error] %>
|
14
|
+
<h3 class="error"><%= flash[:error] %></h3>
|
15
|
+
<% end %>
|
16
|
+
<form action="/login" method="post">
|
17
|
+
<fieldset>
|
18
|
+
<input type="text" name="username" value="Username" id="username" class="placeholder" />
|
19
|
+
</fieldset>
|
20
|
+
<fieldset>
|
21
|
+
<input type="text" name="password" value="Password" id="password" class="placeholder" />
|
22
|
+
</fieldset>
|
23
|
+
<fieldset class="submit">
|
24
|
+
<button type="submit">Log In</button>
|
25
|
+
</fieldset>
|
26
|
+
</form>
|
27
|
+
<script type="text/javascript">
|
28
|
+
login.init();
|
29
|
+
</script>
|
30
|
+
</div>
|
31
|
+
<img src="/img/shadow.png" alt="" style="display: block; margin: 0 auto;" />
|
32
|
+
</body>
|
33
|
+
</html>
|
data/lib/togo/admin.rb
CHANGED
@@ -3,5 +3,6 @@ require 'togo/admin/admin'
|
|
3
3
|
|
4
4
|
Togo::Admin.configure({
|
5
5
|
:view_path => File.join($:.find{|p| p =~ /lib\/togo\/admin/},'views'),
|
6
|
-
:public_path => File.join($:.find{|p| p =~ /lib\/togo\/admin/},'public')
|
6
|
+
:public_path => File.join($:.find{|p| p =~ /lib\/togo\/admin/},'public'),
|
7
|
+
:site_title => "Togo Admin"
|
7
8
|
})
|
@@ -2,6 +2,24 @@ require 'rack'
|
|
2
2
|
require 'erubis'
|
3
3
|
|
4
4
|
module Togo
|
5
|
+
|
6
|
+
class FlashHash
|
7
|
+
def initialize
|
8
|
+
@h = {}
|
9
|
+
@c = {}
|
10
|
+
end
|
11
|
+
def [](key)
|
12
|
+
return @c[key] if @c.keys.include?(key)
|
13
|
+
@c[key] = @h.delete(key) if @h.keys.include?(key)
|
14
|
+
end
|
15
|
+
def []=(key,val)
|
16
|
+
@h[key] = val
|
17
|
+
end
|
18
|
+
def sweep!
|
19
|
+
@c = {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
5
23
|
class Dispatch
|
6
24
|
|
7
25
|
HANDLERS = %w(thin mongrel webrick)
|
@@ -45,12 +63,13 @@ module Togo
|
|
45
63
|
else
|
46
64
|
begin
|
47
65
|
__before if defined? __before
|
48
|
-
@response.write(send(method))
|
66
|
+
@response.write(send(method)) unless [301, 302].include?(@response.status)
|
49
67
|
rescue => detail
|
50
68
|
@response.status = 500
|
51
|
-
|
69
|
+
@response.write(["Error: #{detail}",$!.backtrace.join("<br />\n")].join("<br />\n"))
|
52
70
|
end
|
53
71
|
end
|
72
|
+
flash.sweep!
|
54
73
|
end
|
55
74
|
|
56
75
|
def erb(content, opts = {}, &block)
|
@@ -74,6 +93,14 @@ module Togo
|
|
74
93
|
ENV['RACK_ENV'] == name.to_sym
|
75
94
|
end
|
76
95
|
|
96
|
+
def session
|
97
|
+
@request.session
|
98
|
+
end
|
99
|
+
|
100
|
+
def flash
|
101
|
+
session[:flash] ||= FlashHash.new
|
102
|
+
end
|
103
|
+
|
77
104
|
def self.handler
|
78
105
|
HANDLERS.each do |h|
|
79
106
|
begin
|
@@ -84,6 +111,10 @@ module Togo
|
|
84
111
|
puts "Could not find any handlers to run. Please be sure your requested handler is installed."
|
85
112
|
end
|
86
113
|
|
114
|
+
def config
|
115
|
+
self.class.send(:config)
|
116
|
+
end
|
117
|
+
|
87
118
|
class << self
|
88
119
|
attr_accessor :routes, :config
|
89
120
|
|
@@ -147,6 +178,10 @@ module Togo
|
|
147
178
|
end
|
148
179
|
end
|
149
180
|
builder.use Rack::Static, :urls => opts[:static_urls], :root => opts[:public_path]
|
181
|
+
if opts[:sessions] or opts[:auth_model]
|
182
|
+
builder.use Rack::Session::Cookie
|
183
|
+
opts[:sessions] = true
|
184
|
+
end
|
150
185
|
builder.run new(opts)
|
151
186
|
if opts[:standalone]
|
152
187
|
opts[:handler].run(builder.to_app, :Port => opts[:port], :Host => opts[:host])
|
data/lib/togo/model/model.rb
CHANGED
@@ -125,16 +125,12 @@ module Togo
|
|
125
125
|
when ::DataMapper::Associations::OneToMany::Relationship
|
126
126
|
'has_n'
|
127
127
|
when ::DataMapper::Property
|
128
|
-
class_variable_get(:@@inflector).demodulize(property.type || property.
|
128
|
+
class_variable_get(:@@inflector).demodulize(property.type || property.class).downcase # type seems to be deprecated in 1.0
|
129
129
|
else
|
130
130
|
'string'
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
def is_extended_type?(property)
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
134
|
def pick_properties(selection, args)
|
139
135
|
if class_variable_get(:"@@#{selection}_properties").empty?
|
140
136
|
args = shown_properties.map{|p| p.name} if args.empty?
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: togo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 1
|
10
|
+
version: 0.6.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matt King
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-17 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -24,14 +24,14 @@ dependencies:
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- - "
|
27
|
+
- - ">"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 53
|
30
30
|
segments:
|
31
31
|
- 0
|
32
32
|
- 10
|
33
|
-
-
|
34
|
-
version: 0.10.
|
33
|
+
- 1
|
34
|
+
version: 0.10.1
|
35
35
|
type: :runtime
|
36
36
|
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
@@ -64,6 +64,7 @@ files:
|
|
64
64
|
- LICENSE
|
65
65
|
- lib/togo/admin/admin.rb
|
66
66
|
- lib/togo/admin/helpers.rb
|
67
|
+
- lib/togo/admin/public/css/login.css
|
67
68
|
- lib/togo/admin/public/css/screen.css
|
68
69
|
- lib/togo/admin/public/img/arrow-down.png
|
69
70
|
- lib/togo/admin/public/img/arrows.png
|
@@ -76,15 +77,19 @@ files:
|
|
76
77
|
- lib/togo/admin/public/img/button-bg-delete.png
|
77
78
|
- lib/togo/admin/public/img/button-bg-save.png
|
78
79
|
- lib/togo/admin/public/img/footer-bg.png
|
80
|
+
- lib/togo/admin/public/img/login-bg.png
|
81
|
+
- lib/togo/admin/public/img/shadow.png
|
79
82
|
- lib/togo/admin/public/img/subhead-bg.png
|
80
83
|
- lib/togo/admin/public/js/edit.js
|
81
84
|
- lib/togo/admin/public/js/index.js
|
85
|
+
- lib/togo/admin/public/js/login.js
|
82
86
|
- lib/togo/admin/public/js/togo.js
|
83
87
|
- lib/togo/admin/views/_paging.erb
|
84
88
|
- lib/togo/admin/views/custom_title.erb
|
85
89
|
- lib/togo/admin/views/edit.erb
|
86
90
|
- lib/togo/admin/views/index.erb
|
87
91
|
- lib/togo/admin/views/layout.erb
|
92
|
+
- lib/togo/admin/views/login.erb
|
88
93
|
- lib/togo/admin/views/new.erb
|
89
94
|
- lib/togo/admin.rb
|
90
95
|
- lib/togo/dispatch/dispatch.rb
|