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 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
@@ -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
- @model = Togo.const_get(params[:model]) if params[:model]
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
@@ -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;
@@ -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>Togo Admin</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>Togo Admin</h1>
13
- <div id="system-menu">
14
- <span>System Menu</span>
15
- </div>
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
- @response.write(["Error: #{detail}",$!.backtrace.join("<br />\n")].join("<br />\n"))
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])
@@ -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.primitive || property.class).downcase # type seems to be deprecated in 1.0
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: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 6
9
- - 0
10
- version: 0.6.0
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-15 00:00:00 -08:00
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: 51
29
+ hash: 53
30
30
  segments:
31
31
  - 0
32
32
  - 10
33
- - 2
34
- version: 0.10.2
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