togo 0.6.0 → 0.6.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.
- 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
|