appoxy_rails 0.0.18 → 0.0.19

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext'
2
+ require_relative 'utils'
2
3
  require_relative 'appoxy_ui'
3
4
  require_relative 'appoxy_api'
4
5
  require_relative 'appoxy_sessions'
@@ -1,14 +1,21 @@
1
1
  # see http://api.rubyonrails.org/classes/Rails/Railtie.html
2
2
 
3
+ # Nice write-up of hooking gems into the views/layouts/statics of Rails 3 apps:
4
+ # http://numbers.brighterplanet.com/2010/07/26/sharing-views-across-rails-3-apps/
5
+
3
6
  require 'rails'
4
7
 
5
- module SimpleWorker
6
- class Railtie < Rails::Railtie
8
+ module AppoxyRails
9
+ class Railtie < ::Rails::Railtie
7
10
 
8
11
  initializer "appoxy_rails.configure_rails_initialization" do |app|
9
12
  puts 'Initializing appoxy_rails Railtie'
10
13
 
11
14
  # routes = app.routes
15
+ # app.paths.app.views.push Appoxy::Rails::Layout.view_path
16
+
17
+ # config.app_middleware.use '::ActionDispatch::Static', Appoxy::UI.public_path
18
+ # config.app.append_asset_paths
12
19
 
13
20
  end
14
21
  end
@@ -5,7 +5,6 @@ module Appoxy
5
5
 
6
6
  def self.included(base)
7
7
  # Initialize module.
8
- puts 'ApplicationController included.'
9
8
  base.helper_method :logged_in?
10
9
  base.helper_method :current_user
11
10
  base.helper_method :base_url
@@ -53,14 +52,22 @@ module Appoxy
53
52
 
54
53
 
55
54
  def current_user
56
- @current_user ||= (login_from_session)
55
+ @current_user ||= login_from_session
57
56
  @current_user
58
57
  end
59
58
 
60
59
 
61
60
  def login_from_session
62
61
  #puts 'Login from session=' + session[:user_id].inspect
63
- ::User.find_by_id(session[:user_id]) if session[:user_id]
62
+ u = nil
63
+ if session[:user_id]
64
+ begin
65
+ u = ::User.find(session[:user_id])
66
+ rescue => ex
67
+ puts 'User not found: ' + ex.message
68
+ end
69
+ end
70
+ u
64
71
  end
65
72
 
66
73
  def current_url
@@ -78,10 +85,7 @@ module Appoxy
78
85
  end
79
86
 
80
87
  def random_string(length=10)
81
- chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
82
- password = ''
83
- length.times { password << chars[rand(chars.size)] }
84
- password
88
+ Appoxy::Utils.random_string(length)
85
89
  end
86
90
 
87
91
  def authenticate
@@ -100,9 +104,10 @@ module Appoxy
100
104
  end
101
105
  end
102
106
  redirect_to :controller=>"sessions", :action=>"new", :ac=>params[:ac]
107
+ else
108
+ after_authenticate
103
109
  end
104
110
 
105
- after_authenticate
106
111
 
107
112
  end
108
113
 
@@ -111,9 +116,9 @@ module Appoxy
111
116
  end
112
117
 
113
118
 
114
-
115
119
  def facebook_oauth_url(options={})
116
- puts 'appconfig==' + Rails.application.config.inspect
120
+ # puts 'appconfig==' + Rails.application.config.inspect
121
+ raise "Please config your facebook id and api keys." unless Rails.application.config.respond_to?(:facebook_app_id)
117
122
  raise "Scope must be specified." unless options[:scope]
118
123
  app_id = Rails.application.config.facebook_app_id
119
124
  if app_id
@@ -135,8 +135,155 @@ module Appoxy
135
135
  destroy
136
136
  end
137
137
 
138
+ def openid_start
139
+
140
+ begin
141
+ identifier = params[:openid_identifier]
142
+ if identifier.nil?
143
+ flash[:warning] = "There is no openid identifier."
144
+ redirect_to root_path
145
+ return
146
+ end
147
+ oidreq = consumer.begin(identifier)
148
+ rescue OpenID::OpenIDError => e
149
+ flash[:error] = "Discovery failed for #{identifier}: #{e}"
150
+ redirect_to root_path
151
+ return
152
+ end
153
+ if true || params[:use_ax]
154
+ sregreq = OpenID::AX::FetchRequest.new
155
+ sregreq.add(OpenID::AX::AttrInfo.new("http://schema.openid.net/contact/email", "email", true))
156
+ oidreq.add_extension(sregreq)
157
+ oidreq.return_to_args['did_ax'] = 'y'
158
+ end
159
+ if params[:use_sreg]
160
+ sregreq = OpenID::SReg::Request.new
161
+ # required fields
162
+ sregreq.request_fields(['email', 'nickname'], true)
163
+ # optional fields
164
+ sregreq.request_fields(['dob', 'fullname'], false)
165
+ oidreq.add_extension(sregreq)
166
+ oidreq.return_to_args['did_sreg'] = 'y'
167
+ end
168
+ if params[:use_pape]
169
+ papereq = OpenID::PAPE::Request.new
170
+ papereq.add_policy_uri(OpenID::PAPE::AUTH_PHISHING_RESISTANT)
171
+ papereq.max_auth_age = 2*60*60
172
+ oidreq.add_extension(papereq)
173
+ oidreq.return_to_args['did_pape'] = 'y'
174
+ end
175
+ if params[:force_post]
176
+ oidreq.return_to_args['force_post']='x'*2048
177
+ end
178
+ return_to = base_url + "/sessions/openid_complete"
179
+ realm = base_url
180
+
181
+ puts 'about to redirect'
182
+
183
+ if oidreq.send_redirect?(realm, return_to, params[:immediate])
184
+ url = oidreq.redirect_url(realm, return_to, params[:immediate])
185
+ puts 'yep, redirecting to ' + url
186
+ # response["x-test-yo"] = "fuck me"
187
+ redirect_to url
188
+ else
189
+ haml oidreq.html_markup(realm, return_to, params[:immediate], {'id' => 'openid_form'})
190
+ end
191
+ # dump_flash
192
+
193
+ end
194
+
195
+
196
+ def openid_complete
197
+
198
+ return if before_create == false
199
+
200
+ temp1 = session
201
+
202
+ current_url = base_url + "/sessions/openid_complete" # url_for(:action => 'complete', :only_path => false)
203
+ puts 'current_url=' + current_url.inspect
204
+ puts 'path_params=' + request.path_parameters.inspect
205
+ parameters = params.reject { |k, v| request.path_parameters[k.to_sym] }
206
+ puts 'PARAMETERS=' + parameters.inspect
207
+ oidresp = consumer.complete(parameters, current_url)
208
+ puts 'oidresp=' + oidresp.inspect
209
+ user_data = {}
210
+ case oidresp.status
211
+ when OpenID::Consumer::FAILURE
212
+ if oidresp.display_identifier
213
+ flash[:error] = ("Verification of #{oidresp.display_identifier} failed: #{oidresp.message}")
214
+ else
215
+ flash[:error] = "Verification failed: #{oidresp.message}"
216
+ end
217
+ when OpenID::Consumer::SUCCESS
218
+ logger.info ("Verification of #{oidresp.display_identifier} succeeded.")
219
+
220
+ user_data[:open_id] = oidresp.identity_url
221
+ if params[:did_ax]
222
+ sreg_resp = OpenID::AX::FetchResponse.from_success_response(oidresp)
223
+ sreg_message = "AX Registration data was requested"
224
+ if sreg_resp.data.empty?
225
+ sreg_message << ", but none was returned."
226
+ else
227
+ sreg_message << ". The following data were sent:"
228
+ sreg_resp.data.each { |k, v|
229
+ sreg_message << "<br/><b>#{k}</b>: #{v}"
230
+ }
231
+ user_data[:email] = sreg_resp.data["http://schema.openid.net/contact/email"][0]
232
+ end
233
+ puts sreg_message
234
+ end
235
+ if params[:did_sreg]
236
+ sreg_resp = OpenID::SReg::Response.from_success_response(oidresp)
237
+ sreg_message = "Simple Registration data was requested"
238
+ if sreg_resp.empty?
239
+ sreg_message << ", but none was returned."
240
+ else
241
+ sreg_message << ". The following data were sent:"
242
+ sreg_resp.data.each { |k, v|
243
+ sreg_message << "<br/><b>#{k}</b>: #{v}"
244
+ }
245
+
246
+ end
247
+ puts sreg_message
248
+ end
249
+ if params[:did_pape]
250
+ pape_resp = OpenID::PAPE::Response.from_success_response(oidresp)
251
+ pape_message = "A phishing resistant authentication method was requested"
252
+ if pape_resp.auth_policies.member? OpenID::PAPE::AUTH_PHISHING_RESISTANT
253
+ pape_message << ", and the server reported one."
254
+ else
255
+ pape_message << ", but the server did not report one."
256
+ end
257
+ if pape_resp.auth_time
258
+ pape_message << "<br><b>Authentication time:</b> #{pape_resp.auth_time} seconds"
259
+ end
260
+ if pape_resp.nist_auth_level
261
+ pape_message << "<br><b>NIST Auth Level:</b> #{pape_resp.nist_auth_level}"
262
+ end
263
+ puts pape_message
264
+ end
265
+ # todo: CREATE A USER FOR THIS PROJECT HERE WITH IDENITY AND EMAIL
266
+ user = create_or_update_user(user_data)
267
+ if user
268
+ flash[:success] = "Authentication successful."
269
+ end
270
+
271
+ when OpenID::Consumer::SETUP_NEEDED
272
+ flash[:warning] = "Immediate request failed - Setup Needed"
273
+ when OpenID::Consumer::CANCEL
274
+ flash[:warning] = "OpenID transaction cancelled."
275
+ else
276
+ end
277
+ # dump_flash
278
+ # return_to = session[:return_to]
279
+ # puts 'return_to=' + return_to.inspect
280
+ # redirect_to (return_to || after_login_url || root_path)
281
+
282
+
283
+ end
138
284
 
139
285
  def create_facebook
286
+ return if before_create == false
140
287
  if facebook_auth(Rails.application.config.facebook_app_id,
141
288
  Rails.application.config.facebook_secret)
142
289
  after_create
@@ -186,22 +333,40 @@ module Appoxy
186
333
  @user.save(:dirty=>true)
187
334
  end
188
335
 
189
- set_current_user @user
190
- @user
336
+ after_save_setup @user
191
337
 
192
338
  end
193
339
  end
194
340
 
195
- def twitter_auth
196
- callback_url = "#{base_url}/sessions/create_twitter"
197
- @request_token = twitter_oauth_consumer(:signin=>true).get_request_token(:oauth_callback => callback_url)
341
+ def oauth_start(key, secret, callback_url, site, request_token_path, authorize_path, access_token_path)
342
+ consumer = oauth_consumer(key, secret,
343
+ callback_url,
344
+ site,
345
+ request_token_path,
346
+ authorize_path,
347
+ access_token_path
348
+ )
349
+ @request_token = consumer.get_request_token(:oauth_callback => callback_url)
198
350
  session[:request_token] = @request_token
199
- ru = @request_token.authorize_url(:oauth_callback => callback_url)
200
- puts ru.inspect
201
- redirect_to ru
351
+ auth_url = @request_token.authorize_url(:oauth_callback => callback_url)
352
+ puts auth_url.inspect
353
+ redirect_to auth_url
354
+ end
355
+
356
+ def twitter_auth
357
+ signin = true
358
+ callback_url = "#{base_url}/sessions/#{(signin ? "create_twitter" : "create_twitter_oauth")}"
359
+ auth_path = signin ? "authenticate" : "authorize"
360
+ consumer = oauth_start(Rails.application.config.twitter_consumer_key, Rails.application.config.twitter_consumer_secret,
361
+ callback_url,
362
+ "https://api.twitter.com",
363
+ "/oauth/request_token",
364
+ "/oauth/#{auth_path}",
365
+ "/oauth/access_token"
366
+ )
202
367
  end
203
368
 
204
- # OAUTH VERSION
369
+ # OAUTH VERSION for oauthing, shouldn't be in this controller
205
370
  def create_twitter_oauth
206
371
  puts 'params=' + params.inspect
207
372
  @request_token = session[:request_token]
@@ -228,28 +393,34 @@ module Appoxy
228
393
 
229
394
  end
230
395
 
231
- def create_twitter
232
- before_create
233
- puts 'params=' + params.inspect
396
+ def get_oauth_access_token
234
397
  @request_token = session[:request_token]
235
398
  @access_token = @request_token.get_access_token(:oauth_verifier => params[:oauth_verifier])
236
399
  puts 'access_token = ' + @access_token.inspect
237
400
  p @access_token.params
401
+ @access_token
402
+ end
403
+
404
+ def create_twitter
405
+ return if before_create == false
406
+ puts 'params=' + params.inspect
407
+ get_oauth_access_token()
238
408
 
239
409
  @user = User.find_by_twitter_id(@access_token.params[:user_id])
240
410
  unless @user
241
- @user = User.new(:username =>@access_token.params[:screen_name],
242
- :twitter_screen_name=>@access_token.params[:screen_name],
243
- :twitter_id =>@access_token.params[:user_id])
244
- @user.save!
411
+ @user = User.new(# shouldn't set this, because can't say it will be unique ':username =>@access_token.params[:screen_name],
412
+ :twitter_screen_name=>@access_token.params[:screen_name],
413
+ :twitter_id =>@access_token.params[:user_id])
414
+ @user.set_remember
415
+ @user.save
245
416
  puts '@user=' + @user.inspect
246
417
  else
247
418
  @user.username = @access_token.params[:screen_name]
419
+ @user.set_remember
248
420
  @user.save(:dirty=>true)
249
-
250
421
  end
251
422
 
252
- set_current_user @user
423
+ after_save_setup @user
253
424
 
254
425
  flash[:success] = "Authorized with Twitter."
255
426
 
@@ -258,16 +429,69 @@ module Appoxy
258
429
  end
259
430
 
260
431
  private
261
- def twitter_oauth_consumer(options={})
262
- auth_path = options[:signin] ? "authenticate" : "authorize"
263
- @consumer = OAuth::Consumer.new(Rails.application.config.twitter_consumer_key,
264
- Rails.application.config.twitter_consumer_secret,
265
- :site => "https://api.twitter.com",
266
- :oauth_callback => "#{base_url}/sessions/#{(options[:signin] ? "create_twitter" : "create_twitter_oauth")}",
267
- :request_token_path => "/oauth/request_token",
268
- :authorize_path => "/oauth/#{auth_path}",
269
- :access_token_path => "/oauth/access_token")
432
+
433
+ def after_save_setup(user)
434
+ if user.errors.present?
435
+ flash[:error] = "Error saving user: #{user.errors.full_messages}"
436
+ return false
437
+ else
438
+ set_user_cookies(user)
439
+ after_create
440
+ return user
441
+ end
442
+ end
443
+
444
+ def create_or_update_user(user_data)
445
+ user = User.find_by_email(user_data[:email]) # google returns different openid all the time so using email User.find_by_openid user_data[:openid]
446
+
447
+ unless user
448
+ user = User.new(user_data)
449
+ user.set_remember
450
+ user.save
451
+ else
452
+ if user.email.nil? || user.email != user_data[:email]
453
+ user.email = user_data[:email]
454
+ end
455
+ # if user.remember_me.nil? || user.remember_me_expires.nil? || user.remember_me_expires < Time.now
456
+ # logger.debug "Remember me expired."
457
+ # user.remember_me = user_data[:remember_me]
458
+ # user.remember_me_expires = 30.days.since
459
+ # end
460
+ user.set_remember
461
+ user.save(:dirty=>true)
462
+ end
463
+
464
+ # puts 'user=' + user.inspect
465
+ return after_save_setup(user)
466
+ end
467
+
468
+ def set_user_cookies(user)
469
+ set_current_user(user)
470
+ response.set_cookie('user_id', :value => user.id, :expires => user.remember_expires)
471
+ response.set_cookie('rme', :value=>user.remember_me, :expires => user.remember_expires)
472
+ end
473
+
474
+
475
+ # todo: allow user to specify store type in options
476
+ def openid_consumer(options={})
477
+ @openid_consumer ||= OpenID::Consumer.new(session,
478
+ OpenID::Store::Filesystem.new("/mnt/tmp/openid"))
479
+ # todo: add S3Store to appoxy_sessions
480
+ # @openid_consumer ||= OpenID::Consumer.new(session,
481
+ # S3Store.new(S3BucketWrapper.new(context, main_bucket)))
482
+ end
483
+
484
+
485
+ def oauth_consumer(key, secret, callback, site, request_token_path, authorize_path, access_token_path)
486
+ @consumer = OAuth::Consumer.new(key,
487
+ secret,
488
+ :site => site,
489
+ :oauth_callback => callback,
490
+ :request_token_path => request_token_path,
491
+ :authorize_path => authorize_path,
492
+ :access_token_path => access_token_path)
270
493
  p @consumer
494
+ @consumer
271
495
  end
272
496
 
273
497
 
@@ -16,7 +16,7 @@ module Appoxy
16
16
  {:name => :password, :hashed=>true},
17
17
  :first_name,
18
18
  :last_name,
19
- :remember_me,
19
+ :remember_token,
20
20
  :activation_code,
21
21
  :status, # invited, active
22
22
  :oauth_access_key,
@@ -25,18 +25,18 @@ module Appoxy
25
25
  :lat, :lng
26
26
 
27
27
  has_dates :last_login,
28
- :remember_me_expires
28
+ :remember_expires
29
29
 
30
30
 
31
31
  def validate
32
- errors.add("email", "is not valid") unless User.email_is_valid?(email)
32
+ # errors.add("email", "is not valid") unless User.email_is_valid?(email)
33
33
 
34
34
  if status == "invited"
35
35
  # doesn't need password
36
36
  elsif open_id
37
37
  # doesn't need password
38
38
  else
39
- errors.add("password", "must be at least 6 characters long.") if password.blank?
39
+ # errors.add("password", "must be at least 6 characters long.") if password.blank?
40
40
  end
41
41
  end
42
42
 
@@ -75,6 +75,12 @@ module Appoxy
75
75
  (self.password == password) ? self : nil
76
76
  end
77
77
 
78
+ def set_remember
79
+ rme_string = random_string(50)
80
+ self.remember_token = rme_string
81
+ self.remember_expires = 30.days.since
82
+ end
83
+
78
84
 
79
85
  end
80
86
 
@@ -91,7 +91,6 @@ module Appoxy
91
91
  end
92
92
 
93
93
  def flash_messages
94
- puts 'FLASH MESSAGE!'
95
94
  if flash.size > 0
96
95
  s = "<div class=\"flash_messages_container\">"
97
96
  s2 = ""
@@ -0,0 +1,11 @@
1
+ module Appoxy
2
+ module Utils
3
+ def self.random_string(length=10)
4
+ chars = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
5
+ password = ''
6
+ length.times { password << chars[rand(chars.size)] }
7
+ password
8
+ end
9
+
10
+ end
11
+ end
metadata CHANGED
@@ -1,109 +1,90 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: appoxy_rails
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 18
9
- version: 0.0.18
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.19
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Travis Reeder
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-02-07 00:00:00 -08:00
12
+ date: 2011-02-17 00:00:00.000000000 -08:00
18
13
  default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
21
16
  name: rest-client
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &26527800 !ruby/object:Gem::Requirement
24
18
  none: false
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 0
30
- version: "0"
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
31
23
  type: :runtime
32
- version_requirements: *id001
33
- - !ruby/object:Gem::Dependency
34
- name: oauth
35
24
  prerelease: false
36
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *26527800
26
+ - !ruby/object:Gem::Dependency
27
+ name: oauth
28
+ requirement: &26527464 !ruby/object:Gem::Requirement
37
29
  none: false
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 0
43
- version: "0"
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
44
34
  type: :runtime
45
- version_requirements: *id002
46
- - !ruby/object:Gem::Dependency
47
- name: ruby-openid
48
35
  prerelease: false
49
- requirement: &id003 !ruby/object:Gem::Requirement
36
+ version_requirements: *26527464
37
+ - !ruby/object:Gem::Dependency
38
+ name: ruby-openid
39
+ requirement: &26527164 !ruby/object:Gem::Requirement
50
40
  none: false
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- segments:
55
- - 0
56
- version: "0"
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
57
45
  type: :runtime
58
- version_requirements: *id003
59
- - !ruby/object:Gem::Dependency
60
- name: appoxy_api
61
46
  prerelease: false
62
- requirement: &id004 !ruby/object:Gem::Requirement
47
+ version_requirements: *26527164
48
+ - !ruby/object:Gem::Dependency
49
+ name: appoxy_api
50
+ requirement: &26526828 !ruby/object:Gem::Requirement
63
51
  none: false
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- segments:
68
- - 0
69
- version: "0"
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
70
56
  type: :runtime
71
- version_requirements: *id004
72
- - !ruby/object:Gem::Dependency
73
- name: mini_fb
74
57
  prerelease: false
75
- requirement: &id005 !ruby/object:Gem::Requirement
58
+ version_requirements: *26526828
59
+ - !ruby/object:Gem::Dependency
60
+ name: mini_fb
61
+ requirement: &26526480 !ruby/object:Gem::Requirement
76
62
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- segments:
81
- - 0
82
- version: "0"
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
83
67
  type: :runtime
84
- version_requirements: *id005
85
- - !ruby/object:Gem::Dependency
86
- name: simple_record
87
68
  prerelease: false
88
- requirement: &id006 !ruby/object:Gem::Requirement
69
+ version_requirements: *26526480
70
+ - !ruby/object:Gem::Dependency
71
+ name: simple_record
72
+ requirement: &26526156 !ruby/object:Gem::Requirement
89
73
  none: false
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- segments:
94
- - 0
95
- version: "0"
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
96
78
  type: :runtime
97
- version_requirements: *id006
79
+ prerelease: false
80
+ version_requirements: *26526156
98
81
  description: Appoxy API Helper gem description...
99
82
  email: travis@appoxy.com
100
83
  executables: []
101
-
102
84
  extensions: []
103
-
104
- extra_rdoc_files:
85
+ extra_rdoc_files:
105
86
  - README.markdown
106
- files:
87
+ files:
107
88
  - lib/api/api_controller.rb
108
89
  - lib/api/client.rb
109
90
  - lib/api/client_helper.rb
@@ -125,38 +106,31 @@ files:
125
106
  - lib/ui/test.rb
126
107
  - lib/ui/time_zoner.rb
127
108
  - lib/ui/visualizations.rb
109
+ - lib/utils.rb
128
110
  - README.markdown
129
111
  has_rdoc: true
130
112
  homepage: http://www.appoxy.com
131
113
  licenses: []
132
-
133
114
  post_install_message:
134
115
  rdoc_options: []
135
-
136
- require_paths:
116
+ require_paths:
137
117
  - lib
138
- required_ruby_version: !ruby/object:Gem::Requirement
118
+ required_ruby_version: !ruby/object:Gem::Requirement
139
119
  none: false
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- segments:
144
- - 0
145
- version: "0"
146
- required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
125
  none: false
148
- requirements:
149
- - - ">="
150
- - !ruby/object:Gem::Version
151
- segments:
152
- - 0
153
- version: "0"
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
154
130
  requirements: []
155
-
156
131
  rubyforge_project:
157
- rubygems_version: 1.3.7
132
+ rubygems_version: 1.5.2
158
133
  signing_key:
159
134
  specification_version: 3
160
135
  summary: Appoxy Rails Helper gem
161
136
  test_files: []
162
-