appoxy_rails 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +110 -1
- data/lib/appoxy_rails.rb +11 -0
- data/lib/railtie.rb +15 -0
- data/lib/sessions/application_controller.rb +34 -3
- data/lib/sessions/sessions_controller.rb +80 -80
- data/lib/sessions/user.rb +61 -59
- data/lib/sessions/users_controller.rb +132 -95
- data/lib/ui/_geo_location_finder.html.erb +56 -0
- data/lib/ui/application_helper.rb +85 -3
- data/lib/ui/binding_hack.rb +14 -0
- data/lib/ui/test.rb +7 -0
- data/lib/ui/time_zoner.rb +28 -23
- metadata +7 -3
data/README.markdown
CHANGED
@@ -1 +1,110 @@
|
|
1
|
-
|
1
|
+
This is a bunch of tools and utilities to help developing Rails apps using
|
2
|
+
tools like SimpleRecord, jquery, OpenID, Oauth, HTML5, etc.
|
3
|
+
|
4
|
+
Everything is mix-ins and methods so you can pick and choose what you want to use.
|
5
|
+
|
6
|
+
## Features
|
7
|
+
|
8
|
+
- Super easy OpenID and Facebook logins
|
9
|
+
- User authentication
|
10
|
+
- Timezone helpers
|
11
|
+
- Sharing things in an app (Shareable mix-in)
|
12
|
+
- Ready to go models (User)
|
13
|
+
- Geolocation
|
14
|
+
- API authentication to easily create secure API's
|
15
|
+
|
16
|
+
## Installation and Configuration
|
17
|
+
|
18
|
+
Clone appoxy BASE project.
|
19
|
+
|
20
|
+
OR:
|
21
|
+
|
22
|
+
- gem 'appoxy_rails'
|
23
|
+
- Delete all prototype scripts in public/javascripts
|
24
|
+
|
25
|
+
|
26
|
+
## Includes
|
27
|
+
|
28
|
+
### User
|
29
|
+
|
30
|
+
Create a User model and extend `< Appoxy::Sessions::User`
|
31
|
+
|
32
|
+
### ApplicationController
|
33
|
+
|
34
|
+
Add `include Appoxy::Sessions::ApplicationController` to your ApplicationController.
|
35
|
+
|
36
|
+
### ApplicationHelper
|
37
|
+
|
38
|
+
Add `include Appoxy::UI::ApplicationHelper` to your ApplicationHelper.
|
39
|
+
|
40
|
+
Includes:
|
41
|
+
|
42
|
+
- Date formatting based on current user's timezone.
|
43
|
+
- flash_messages
|
44
|
+
- error_messages_for
|
45
|
+
|
46
|
+
### UsersController
|
47
|
+
|
48
|
+
Add `include Appoxy::Sessions::UsersController` to your SessionsController.
|
49
|
+
|
50
|
+
Includes:
|
51
|
+
|
52
|
+
- User creation.
|
53
|
+
- Timezone setting.
|
54
|
+
- Geo location setting.
|
55
|
+
|
56
|
+
#### Callbacks
|
57
|
+
|
58
|
+
- before_create
|
59
|
+
- after_create
|
60
|
+
|
61
|
+
### SessionsController
|
62
|
+
|
63
|
+
Add `include Appoxy::Sessions::SessionsController` to your SessionsController.
|
64
|
+
|
65
|
+
Includes:
|
66
|
+
|
67
|
+
- Authentication
|
68
|
+
- Password resetting
|
69
|
+
- Logout
|
70
|
+
|
71
|
+
#### Callbacks
|
72
|
+
|
73
|
+
- before_create
|
74
|
+
- after_create
|
75
|
+
- after_reset_password - good for sending out an email, eg: Mailer.deliver_reset_password(@user, @newpass)
|
76
|
+
|
77
|
+
### appoxy_javascripts
|
78
|
+
|
79
|
+
Includes:
|
80
|
+
|
81
|
+
- jquery
|
82
|
+
- jquery ui
|
83
|
+
|
84
|
+
### appoxy_header
|
85
|
+
|
86
|
+
Includes:
|
87
|
+
|
88
|
+
- appoxy_javascripts
|
89
|
+
|
90
|
+
### appoxy_footer
|
91
|
+
|
92
|
+
Includes:
|
93
|
+
|
94
|
+
- Some debug stuff if in development environment.
|
95
|
+
- Timezone script to get user timezone.
|
96
|
+
|
97
|
+
## Authentication
|
98
|
+
|
99
|
+
Any controllers that require authentication to view, use:
|
100
|
+
|
101
|
+
before_filter :authenticate
|
102
|
+
|
103
|
+
### OpenID
|
104
|
+
|
105
|
+
### Facebook
|
106
|
+
|
107
|
+
### Oauth
|
108
|
+
|
109
|
+
## Sharing
|
110
|
+
|
data/lib/appoxy_rails.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
|
+
require 'active_support/core_ext'
|
1
2
|
require_relative 'appoxy_ui'
|
2
3
|
require_relative 'appoxy_api'
|
3
4
|
require_relative 'appoxy_sessions'
|
4
5
|
require_relative 'ui/time_zoner'
|
5
6
|
|
7
|
+
|
8
|
+
if defined?(Rails)
|
9
|
+
# puts 'Rails=' + Rails.inspect
|
10
|
+
# puts 'vers=' + Rails::VERSION::MAJOR.inspect
|
11
|
+
if Rails::VERSION::MAJOR == 2
|
12
|
+
raise "appoxy_rails only supports Rails 3+"
|
13
|
+
else
|
14
|
+
require_relative 'railtie'
|
15
|
+
end
|
16
|
+
end
|
data/lib/railtie.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# see http://api.rubyonrails.org/classes/Rails/Railtie.html
|
2
|
+
|
3
|
+
require 'rails'
|
4
|
+
|
5
|
+
module SimpleWorker
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
|
8
|
+
initializer "appoxy_rails.configure_rails_initialization" do |app|
|
9
|
+
puts 'Initializing appoxy_rails Railtie'
|
10
|
+
|
11
|
+
# routes = app.routes
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -5,14 +5,25 @@ module Appoxy
|
|
5
5
|
|
6
6
|
def self.included(base)
|
7
7
|
# Initialize module.
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
base.helper_method :logged_in?
|
9
|
+
base.helper_method :current_user
|
10
|
+
base.helper_method :base_url
|
11
|
+
|
12
|
+
base.after_filter :close_sdb_connection
|
13
|
+
base.before_filter :clear_sdb_stats
|
11
14
|
end
|
12
15
|
|
13
16
|
|
14
17
|
protected
|
15
18
|
|
19
|
+
def clear_sdb_stats
|
20
|
+
SimpleRecord.stats.clear
|
21
|
+
end
|
22
|
+
|
23
|
+
def close_sdb_connection
|
24
|
+
SimpleRecord.close_connection
|
25
|
+
end
|
26
|
+
|
16
27
|
|
17
28
|
def logout_keeping_session!
|
18
29
|
@current_user = nil # not logged in, and don't do it for me
|
@@ -48,6 +59,10 @@ module Appoxy
|
|
48
59
|
::User.find_by_id(session[:user_id]) if session[:user_id]
|
49
60
|
end
|
50
61
|
|
62
|
+
def current_url
|
63
|
+
request.url
|
64
|
+
end
|
65
|
+
|
51
66
|
|
52
67
|
def base_url
|
53
68
|
r = "#{request.protocol}#{request.host}"
|
@@ -91,6 +106,22 @@ module Appoxy
|
|
91
106
|
|
92
107
|
end
|
93
108
|
|
109
|
+
MOBILE_USER_AGENTS = 'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
|
110
|
+
'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
|
111
|
+
'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
|
112
|
+
'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
|
113
|
+
'webos|amoi|novarra|cdm|alcatel|pocket|ipad|iphone|mobileexplorer|' +
|
114
|
+
'mobile'
|
115
|
+
|
116
|
+
# SOME MOBILE STUFF FROM MOBILE_FU
|
117
|
+
def is_mobile_device?
|
118
|
+
request.user_agent.to_s.downcase =~ Regexp.new(MOBILE_USER_AGENTS)
|
119
|
+
end
|
120
|
+
|
121
|
+
def is_device?(type)
|
122
|
+
request.user_agent.to_s.downcase.include?(type.to_s.downcase)
|
123
|
+
end
|
124
|
+
|
94
125
|
|
95
126
|
end
|
96
127
|
|
@@ -1,121 +1,121 @@
|
|
1
1
|
module Appoxy
|
2
2
|
|
3
|
-
|
3
|
+
module Sessions
|
4
4
|
|
5
|
-
|
5
|
+
module SessionsController
|
6
6
|
|
7
|
-
|
7
|
+
# Todo: have a configuration block for this so user can set things like facebook_api_key and facebook_secret
|
8
8
|
|
9
|
-
|
9
|
+
def new
|
10
10
|
|
11
|
-
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
def create
|
14
|
+
before_create
|
15
15
|
|
16
|
-
|
16
|
+
# recaptchas should be optional
|
17
17
|
# unless verify_recaptcha
|
18
18
|
# flash[:error] = "You are not human! Please try again."
|
19
19
|
# render :action=>"forgot_password"
|
20
20
|
# return
|
21
21
|
# end
|
22
22
|
|
23
|
-
|
23
|
+
logout_keeping_session!
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
@email = params[:email]
|
26
|
+
@has_password = params[:has_password]
|
27
|
+
#puts 'has_pass? ' + @has_password.inspect
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
29
|
+
if params[:has_password].blank?
|
30
|
+
flash[:error] = "Please click the radio button to let us know if you have a password or not."
|
31
|
+
render :action=>"new"
|
32
|
+
return
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
if @has_password == "true"
|
36
|
+
user = ::User.find_by_email(@email)
|
37
37
|
# user = User.authenticate(@email, params[:password])
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
end
|
49
|
-
user.last_login = Time.now
|
50
|
-
user.save(:dirty=>true)
|
51
|
-
else
|
52
|
-
flash[:info] = "Invalid email or password. Please try again."
|
53
|
-
render :action => 'new'
|
54
|
-
end
|
55
|
-
else
|
56
|
-
# new user
|
57
|
-
redirect_to (new_user_path + "?email=#{@email}")
|
58
|
-
end
|
38
|
+
if user && user.authenticate(params[:password])
|
39
|
+
self.current_user = user
|
40
|
+
flash[:info] = "Logged in successfully."
|
41
|
+
orig_url = session[:return_to]
|
42
|
+
puts 'orig_url = ' + orig_url.to_s
|
43
|
+
session[:return_to] = nil
|
44
|
+
if !orig_url.nil?
|
45
|
+
redirect_to orig_url # if entered via a different url
|
46
|
+
else
|
47
|
+
after_create
|
59
48
|
end
|
49
|
+
user.last_login = Time.now
|
50
|
+
user.save(:dirty=>true)
|
51
|
+
else
|
52
|
+
flash[:info] = "Invalid email or password. Please try again."
|
53
|
+
render :action => 'new'
|
54
|
+
end
|
55
|
+
else
|
56
|
+
# new user
|
57
|
+
redirect_to (new_user_path + "?email=#{@email}")
|
58
|
+
end
|
59
|
+
end
|
60
60
|
|
61
|
-
|
61
|
+
def before_create
|
62
62
|
|
63
|
-
|
63
|
+
end
|
64
64
|
|
65
|
-
|
65
|
+
def after_create
|
66
66
|
|
67
|
-
|
67
|
+
end
|
68
68
|
|
69
|
-
|
70
|
-
|
69
|
+
def reset_password
|
70
|
+
before_reset_password
|
71
71
|
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
73
|
+
@email = params[:email]
|
74
|
+
unless User.email_is_valid? @email
|
75
|
+
flash[:error] = "You must enter a valid email."
|
76
|
+
render :action=>"forgot_password"
|
77
|
+
return
|
78
|
+
end
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
80
|
+
@user = ::User.find_by_email(@email)
|
81
|
+
unless @user
|
82
|
+
flash[:error] = "Email not found."
|
83
|
+
render :action=>"forgot_password"
|
84
|
+
return
|
85
|
+
end
|
86
86
|
|
87
|
-
|
87
|
+
@newpass = random_string(8)
|
88
88
|
|
89
|
-
|
90
|
-
|
89
|
+
@user.password = @newpass
|
90
|
+
@user.save(:dirty=>true)
|
91
91
|
|
92
|
-
|
93
|
-
|
92
|
+
flash[:success] = "Password reset. You should receive an email shortly with a new password."
|
93
|
+
redirect_to :action=>"new"
|
94
94
|
|
95
|
-
|
96
|
-
|
95
|
+
after_reset_password
|
96
|
+
end
|
97
97
|
|
98
|
-
|
98
|
+
def before_reset_password
|
99
99
|
|
100
|
-
|
100
|
+
end
|
101
101
|
|
102
|
-
|
103
|
-
|
102
|
+
# This is a great spot to send an email with the new password (the only spot actually).
|
103
|
+
def after_reset_password
|
104
104
|
|
105
|
-
|
105
|
+
end
|
106
106
|
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
def destroy
|
108
|
+
logout
|
109
|
+
end
|
110
110
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
111
|
+
def logout
|
112
|
+
@current_user = nil
|
113
|
+
reset_session
|
114
|
+
flash[:info] = "You have been logged out."
|
115
|
+
redirect_to('/')
|
116
|
+
end
|
117
117
|
|
118
118
|
|
119
|
-
end
|
120
119
|
end
|
120
|
+
end
|
121
121
|
end
|
data/lib/sessions/user.rb
CHANGED
@@ -1,80 +1,82 @@
|
|
1
1
|
module Appoxy
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
3
|
+
module Sessions
|
4
|
+
|
5
|
+
class User < SimpleRecord::Base
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
puts self.name + " included in " + base.name
|
9
|
+
end
|
10
|
+
|
11
|
+
has_strings :email,
|
12
|
+
:open_id,
|
13
|
+
:fb_id, :fb_access_token,
|
14
|
+
{:name => :password, :hashed=>true},
|
15
|
+
:first_name,
|
16
|
+
:last_name,
|
17
|
+
:remember_me,
|
18
|
+
:activation_code,
|
19
|
+
:status, # invited, active
|
20
|
+
:oauth_access_key,
|
21
|
+
:oauth_secret_key,
|
22
|
+
:time_zone,
|
23
|
+
:lat, :lng
|
24
|
+
|
25
|
+
has_dates :last_login,
|
26
|
+
:remember_me_expires
|
27
|
+
|
28
|
+
|
29
|
+
def validate
|
30
|
+
errors.add("email", "is not valid") unless User.email_is_valid?(email)
|
31
|
+
|
32
|
+
if status == "invited"
|
33
|
+
# doesn't need password
|
34
|
+
elsif open_id
|
35
|
+
# doesn't need password
|
36
|
+
else
|
37
|
+
errors.add("password", "must be at least 6 characters long.") if password.blank?
|
38
|
+
end
|
39
|
+
end
|
39
40
|
|
40
|
-
def self.email_is_valid?(email)
|
41
|
-
return email.present? && email =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
42
|
-
end
|
43
41
|
|
42
|
+
def self.email_is_valid?(email)
|
43
|
+
return email.present? && email =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
44
|
+
end
|
44
45
|
|
45
|
-
def is_active?
|
46
|
-
status == "active"
|
47
|
-
end
|
48
46
|
|
47
|
+
def is_active?
|
48
|
+
status == "active"
|
49
|
+
end
|
49
50
|
|
50
|
-
def set_activation_code
|
51
|
-
self.activation_code=Digest::SHA1.hexdigest(email.to_s+Time.now.to_s)
|
52
|
-
end
|
53
51
|
|
52
|
+
def set_activation_code
|
53
|
+
self.activation_code=Digest::SHA1.hexdigest(email.to_s+Time.now.to_s)
|
54
|
+
end
|
54
55
|
|
55
|
-
def activate!
|
56
|
-
self.activation_code=nil
|
57
|
-
self.status = "active"
|
58
|
-
end
|
59
56
|
|
57
|
+
def activate!
|
58
|
+
self.activation_code=nil
|
59
|
+
self.status = "active"
|
60
|
+
end
|
60
61
|
|
61
|
-
def authenticate(password)
|
62
62
|
|
63
|
-
|
63
|
+
def authenticate(password)
|
64
64
|
|
65
|
-
|
66
|
-
if attributes["password"][0].length < 100
|
67
|
-
self.password = attributes["password"][0]
|
68
|
-
self.save
|
69
|
-
end
|
65
|
+
return nil if attributes["password"].blank? # if the user has no password (will this happen? maybe for invites...)
|
70
66
|
|
71
|
-
|
72
|
-
|
67
|
+
# This is a normal unencrypted password, temporary
|
68
|
+
if attributes["password"][0].length < 100
|
69
|
+
self.password = attributes["password"][0]
|
70
|
+
self.save
|
71
|
+
end
|
73
72
|
|
73
|
+
(self.password == password) ? self : nil
|
74
|
+
end
|
74
75
|
|
75
|
-
end
|
76
76
|
|
77
77
|
end
|
78
78
|
|
79
|
+
end
|
80
|
+
|
79
81
|
end
|
80
82
|
|
@@ -1,122 +1,159 @@
|
|
1
1
|
module Appoxy
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
module Sessions
|
4
|
+
module UsersController
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
puts 'UsersController included'
|
8
|
+
# Initialize module.
|
9
|
+
base.protect_from_forgery :except => [:location, :timezone]
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def new
|
14
|
+
before_new
|
15
|
+
if params[:id]
|
16
|
+
@user = ::User.find params[:id]
|
17
|
+
else
|
18
|
+
@user = ::User.new
|
19
|
+
@user.email = params[:email] if params[:email]
|
20
|
+
end
|
21
|
+
@user.activation_code = params[:ac] if params[:ac]
|
22
|
+
after_new
|
23
|
+
end
|
18
24
|
|
19
|
-
|
25
|
+
def before_new
|
20
26
|
|
21
|
-
|
27
|
+
end
|
22
28
|
|
23
|
-
|
29
|
+
def after_new
|
24
30
|
|
25
|
-
|
31
|
+
end
|
26
32
|
|
27
|
-
|
28
|
-
|
29
|
-
before_create
|
30
|
-
|
31
|
-
@user = ::User.new(params[:user])
|
32
|
-
|
33
|
-
if @user.password != params[:password_confirmation]
|
34
|
-
flash[:error] = "Confirmation password does not match. Please try again."
|
35
|
-
render :action=>"new"
|
36
|
-
return
|
37
|
-
end
|
38
|
-
|
39
|
-
if params[:user][:password].length < 6
|
40
|
-
flash[:error] = "Password can not be less than 6 characters."
|
41
|
-
render :action=>"new"
|
42
|
-
return
|
43
|
-
end
|
44
|
-
|
45
|
-
existing_user = ::User.find_by_email(@user.email)
|
46
|
-
|
47
|
-
if existing_user
|
48
|
-
if params[:ac]
|
49
|
-
|
50
|
-
end
|
51
|
-
# todo: remove activation_code on user
|
52
|
-
if @user.activation_code.present?
|
53
|
-
# hasn't logged in yet, probably invited, need to check access key
|
54
|
-
if existing_user.activation_code == @user.activation_code
|
55
|
-
existing_user.activate!
|
56
|
-
existing_user.password = @user.password
|
57
|
-
@user = existing_user
|
58
|
-
end
|
59
|
-
else
|
60
|
-
flash[:error] = "The email you entered already exists in our system. You might want to try logging in if you already have an account."
|
61
|
-
render :action=>"new"
|
62
|
-
return
|
63
|
-
end
|
64
|
-
else
|
65
|
-
@user.status = "active"
|
66
|
-
end
|
67
|
-
|
68
|
-
before_save_in_create
|
69
|
-
if @user.save
|
70
|
-
self.current_user = @user
|
71
|
-
flash[:success] = "Your account was created successfully."
|
72
|
-
after_save_in_create
|
73
|
-
after_create
|
74
|
-
else
|
75
|
-
render :action => "new"
|
76
|
-
end
|
33
|
+
def create
|
77
34
|
|
78
|
-
|
35
|
+
before_create
|
79
36
|
|
80
|
-
|
37
|
+
@user = ::User.new(params[:user])
|
81
38
|
|
82
|
-
|
39
|
+
if @user.password != params[:password_confirmation]
|
40
|
+
flash[:error] = "Confirmation password does not match. Please try again."
|
41
|
+
render :action=>"new"
|
42
|
+
return
|
43
|
+
end
|
83
44
|
|
84
|
-
|
45
|
+
if params[:user][:password].length < 6
|
46
|
+
flash[:error] = "Password can not be less than 6 characters."
|
47
|
+
render :action=>"new"
|
48
|
+
return
|
49
|
+
end
|
85
50
|
|
86
|
-
|
51
|
+
existing_user = ::User.find_by_email(@user.email)
|
87
52
|
|
88
|
-
|
53
|
+
if existing_user
|
54
|
+
if params[:ac]
|
89
55
|
|
56
|
+
end
|
57
|
+
# todo: remove activation_code on user
|
58
|
+
if @user.activation_code.present?
|
59
|
+
# hasn't logged in yet, probably invited, need to check access key
|
60
|
+
if existing_user.activation_code == @user.activation_code
|
61
|
+
existing_user.activate!
|
62
|
+
existing_user.password = @user.password
|
63
|
+
@user = existing_user
|
90
64
|
end
|
65
|
+
else
|
66
|
+
flash[:error] = "The email you entered already exists in our system. You might want to try logging in if you already have an account."
|
67
|
+
render :action=>"new"
|
68
|
+
return
|
69
|
+
end
|
70
|
+
else
|
71
|
+
@user.status = "active"
|
72
|
+
end
|
91
73
|
|
92
|
-
|
74
|
+
before_save_in_create
|
75
|
+
if @user.save
|
76
|
+
self.current_user = @user
|
77
|
+
flash[:success] = "Your account was created successfully."
|
78
|
+
after_save_in_create
|
79
|
+
after_create
|
80
|
+
else
|
81
|
+
render :action => "new"
|
82
|
+
end
|
93
83
|
|
94
|
-
|
84
|
+
end
|
95
85
|
|
86
|
+
def before_create
|
96
87
|
|
97
|
-
|
98
|
-
def activate
|
99
|
-
logout_keeping_session!
|
100
|
-
@user = ::User.find_by_activation_code(params[:ac]) unless params[:ac].blank?
|
101
|
-
case
|
102
|
-
when (!params[:ac].blank?) && @user && !@user.is_active?
|
103
|
-
flash[:info] = "Account activated. please login."
|
104
|
-
@user.activate!
|
105
|
-
redirect_to login_url
|
106
|
-
when params[:ac].blank?
|
107
|
-
flash[:error] = "The activation code was missing. Please follow the URL from your email."
|
108
|
-
redirect_to(root_url)
|
109
|
-
else
|
110
|
-
flash[:error] = "We couldn't find a user with that activation code -- check your email? Or maybe you've already activated -- try signing in."
|
111
|
-
redirect_to(root_url)
|
112
|
-
end
|
113
|
-
end
|
88
|
+
end
|
114
89
|
|
115
|
-
|
90
|
+
def before_save_in_create
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
def after_save_in_create
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
def after_create
|
99
|
+
|
100
|
+
end
|
116
101
|
|
117
102
|
|
103
|
+
# Usually a user gets here via an activation link in email.
|
104
|
+
def activate
|
105
|
+
logout_keeping_session!
|
106
|
+
@user = ::User.find_by_activation_code(params[:ac]) unless params[:ac].blank?
|
107
|
+
case
|
108
|
+
when (!params[:ac].blank?) && @user && !@user.is_active?
|
109
|
+
flash[:info] = "Account activated. please login."
|
110
|
+
@user.activate!
|
111
|
+
redirect_to login_url
|
112
|
+
when params[:ac].blank?
|
113
|
+
flash[:error] = "The activation code was missing. Please follow the URL from your email."
|
114
|
+
redirect_to(root_url)
|
115
|
+
else
|
116
|
+
flash[:error] = "We couldn't find a user with that activation code -- check your email? Or maybe you've already activated -- try signing in."
|
117
|
+
redirect_to(root_url)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# To use this, add "post 'timezone'" to a member resources :users in routes.rb
|
122
|
+
# Also, be sure you have <%= appoxy_footer in view %>
|
123
|
+
def timezone
|
124
|
+
ret = {}
|
125
|
+
if logged_in?
|
126
|
+
puts 'SET TIMEZONE ' + params.inspect
|
127
|
+
tz = ActiveSupport::TimeZone[params[:offset].to_i]
|
128
|
+
if tz
|
129
|
+
puts 'tz=' + tz.name
|
130
|
+
current_user.time_zone = tz.name
|
131
|
+
current_user.save(:dirty=>true)
|
132
|
+
ret[:timezone] = tz.name
|
133
|
+
end
|
134
|
+
end
|
135
|
+
render :json=>ret
|
136
|
+
end
|
137
|
+
|
138
|
+
def geo_location
|
139
|
+
puts 'updating users location'
|
140
|
+
ret = {}
|
141
|
+
if current_user
|
142
|
+
current_user.update_position(params[:lat], params[:lng])
|
143
|
+
ret[:status]="success"
|
144
|
+
else
|
145
|
+
logger.info("Could not update user location because no current_user")
|
146
|
+
ret[:status]="failed"
|
147
|
+
ret[:msg] = "No user"
|
148
|
+
end
|
149
|
+
render :json=>ret
|
150
|
+
end
|
151
|
+
|
118
152
|
end
|
119
153
|
|
120
154
|
|
155
|
+
end
|
156
|
+
|
157
|
+
|
121
158
|
end
|
122
159
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<script type="text/javascript">
|
2
|
+
function map_success(position) {
|
3
|
+
|
4
|
+
<% if @options[:show_map] %>
|
5
|
+
var mapcanvas = document.createElement('div');
|
6
|
+
mapcanvas.id = 'mapcanvas';
|
7
|
+
mapcanvas.style.width = '100%';
|
8
|
+
mapcanvas.style.height = '100px';
|
9
|
+
|
10
|
+
document.querySelector('<%=@options[:show_map]%>').appendChild(mapcanvas);
|
11
|
+
|
12
|
+
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
|
13
|
+
var myOptions = {
|
14
|
+
zoom: 15,
|
15
|
+
center: latlng,
|
16
|
+
mapTypeControl: false,
|
17
|
+
navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL},
|
18
|
+
mapTypeId: google.maps.MapTypeId.ROADMAP
|
19
|
+
};
|
20
|
+
var map = new google.maps.Map(document.getElementById("mapcanvas"), myOptions);
|
21
|
+
|
22
|
+
var marker = new google.maps.Marker({
|
23
|
+
position: latlng,
|
24
|
+
map: map,
|
25
|
+
title:"You are here!"
|
26
|
+
});
|
27
|
+
<% end %>
|
28
|
+
|
29
|
+
<% if @options[:current_user] %>
|
30
|
+
$.post('/users/<%=@options[:current_user].id%>/geo_location', { lat: position.coords.latitude, lng: position.coords.longitude }, function(data) {
|
31
|
+
data = jQuery.parseJSON(data);
|
32
|
+
$("#status").html("updated.");
|
33
|
+
});
|
34
|
+
<% end %>
|
35
|
+
|
36
|
+
}
|
37
|
+
|
38
|
+
function map_error(msg) {
|
39
|
+
var s = document.querySelector('#status');
|
40
|
+
s.innerHTML = typeof msg == 'string' ? msg : "failed";
|
41
|
+
s.className = 'find_fail';
|
42
|
+
|
43
|
+
// console.log(arguments);
|
44
|
+
}
|
45
|
+
|
46
|
+
$(document).ready(function() {
|
47
|
+
if (navigator.geolocation) {
|
48
|
+
navigator.geolocation.getCurrentPosition(map_success, map_error, {maximumAge:60000 * 5}); // 1 minute
|
49
|
+
} else {
|
50
|
+
// error('not supported');
|
51
|
+
}
|
52
|
+
|
53
|
+
});
|
54
|
+
|
55
|
+
</script>
|
56
|
+
|
@@ -1,23 +1,92 @@
|
|
1
|
+
require_relative 'binding_hack'
|
2
|
+
|
1
3
|
module Appoxy
|
2
4
|
|
3
5
|
module UI
|
4
6
|
|
7
|
+
# To use, include in your ApplicationHelper.
|
8
|
+
# include Appoxy::UI::ApplicationHelper
|
5
9
|
module ApplicationHelper
|
6
10
|
|
7
11
|
def self.included(base)
|
8
12
|
# puts self.class.name + " included in " + base.class.name
|
9
13
|
end
|
10
14
|
|
11
|
-
|
12
15
|
def current_url
|
13
16
|
request.url
|
14
17
|
end
|
15
18
|
|
19
|
+
def base_url
|
20
|
+
r = "#{request.protocol}#{request.host}"
|
21
|
+
if request.port != 80
|
22
|
+
r << ":#{request.port}"
|
23
|
+
end
|
24
|
+
@base_url = r
|
25
|
+
r
|
26
|
+
end
|
27
|
+
|
28
|
+
def appoxy_javascripts
|
29
|
+
' <script type="text/javascript" src="http://www.google.com/jsapi?key=ABQIAAAAhes0f80sBcwL-h5xCNkkgxQBmiBpQeSpIciQPfZ5Ss-a60KXIRQOVvqzsNpqzhmG9tjky_5rOuaeow"></script>
|
30
|
+
<script type="text/javascript">
|
31
|
+
google.load("jquery", "1");
|
32
|
+
google.load("jqueryui", "1");
|
33
|
+
|
34
|
+
</script>
|
35
|
+
'.html_safe
|
36
|
+
end
|
37
|
+
|
38
|
+
# Place in application.html.erb in head to get default Appoxy style elements and javascripts.
|
39
|
+
def appoxy_header
|
40
|
+
# stylesheets and what not could either be included in this gem or links to s3
|
41
|
+
|
42
|
+
# include google javascript for jquery and jquery-ui and perhaps jquery tools
|
43
|
+
ret = appoxy_javascripts
|
44
|
+
ret.html_safe
|
45
|
+
end
|
46
|
+
|
47
|
+
def appoxy_footer
|
48
|
+
ret = ''
|
49
|
+
|
50
|
+
if current_user # && current_user.time_zone.blank?
|
51
|
+
ret += '
|
52
|
+
<script type="text/javascript">
|
53
|
+
$(document).ready(function() {
|
54
|
+
var myDate = new Date();
|
55
|
+
var tz_offset = -(myDate.getTimezoneOffset() / 60);
|
56
|
+
// document.write(tz_offset);
|
57
|
+
$.post("/users/' + current_user.id + '/timezone", { offset: tz_offset })
|
58
|
+
});
|
59
|
+
</script>'
|
60
|
+
end
|
61
|
+
|
62
|
+
if defined?(RELEASE_INFO)
|
63
|
+
ret += '<div style="clear:both; margin-top:15px;" class="instance_info_div"><%= INSTANCE_INFO["instance_id"] %>: Revision <%= RELEASE_INFO["scm"]["revision"][0..5] %> built on <%= RELEASE_INFO["deploy_date"] %></div>'
|
64
|
+
end
|
65
|
+
if Rails.env == "development"
|
66
|
+
ret += '<div style="margin-top: 10px;">' + ERB::Util.html_escape(SimpleRecord.stats.inspect) + '</div>'
|
67
|
+
end
|
68
|
+
ret.html_safe
|
69
|
+
end
|
70
|
+
|
71
|
+
# options:
|
72
|
+
# :format=>:long, default = :long
|
73
|
+
# :user=> a User object, if not specified will use @current_user
|
74
|
+
def date_format(date, options={})
|
75
|
+
format = options[:format] || :long
|
76
|
+
# puts 'date_format on ' + date.class.name + " --- " + date.inspect
|
77
|
+
user ||= @current_user
|
78
|
+
return '' if date.nil?
|
79
|
+
date = Time.parse(date) if date.is_a?(String)
|
80
|
+
if date.is_a?(Date) && !date.is_a?(DateTime) && !date.is_a?(Time)
|
81
|
+
return date.to_formatted_s(format)
|
82
|
+
end
|
83
|
+
return date.to_local_s(user, :format=>format)
|
84
|
+
end
|
16
85
|
|
17
86
|
def flash_messages
|
18
87
|
puts 'FLASH MESSAGE!'
|
19
88
|
if flash.size > 0
|
20
|
-
s
|
89
|
+
s = "<div class=\"flash_messages_container\">"
|
21
90
|
s2 = ""
|
22
91
|
flash.each_pair do |type, msg|
|
23
92
|
if msg.is_a?(Array)
|
@@ -35,7 +104,7 @@ module Appoxy
|
|
35
104
|
end
|
36
105
|
|
37
106
|
def error_messages_for(ob)
|
38
|
-
|
107
|
+
return '' if ob.nil?
|
39
108
|
if ob.errors.size > 0
|
40
109
|
s = "<div class=\"error_message_for_container\">"
|
41
110
|
s2 = ""
|
@@ -48,6 +117,19 @@ module Appoxy
|
|
48
117
|
end
|
49
118
|
end
|
50
119
|
|
120
|
+
# Helper for getting user's geo location and storing it on User object.
|
121
|
+
# options:
|
122
|
+
# :show_map=>"#div_to_show_on" - This will display a tiny map of location
|
123
|
+
#
|
124
|
+
def appoxy_geo_finder(options={})
|
125
|
+
# ret = File.read('_geo_location_finder.html.erb')
|
126
|
+
options.merge!({:current_user=>current_user})
|
127
|
+
options = Appoxy::UI::BindingHack.new(options)
|
128
|
+
template = ERB.new(File.read(File.join(File.dirname(__FILE__), '_geo_location_finder.html.erb')))
|
129
|
+
ret = template.result(options.get_binding)
|
130
|
+
ret.html_safe
|
131
|
+
end
|
132
|
+
|
51
133
|
|
52
134
|
end
|
53
135
|
|
data/lib/ui/test.rb
ADDED
data/lib/ui/time_zoner.rb
CHANGED
@@ -1,47 +1,52 @@
|
|
1
|
-
# adds a to_pst method to Time
|
2
|
-
module TimePluginizer # ActiveSupport::CoreExtensions::Time::Conversions
|
3
1
|
|
4
|
-
|
2
|
+
module Appoxy
|
3
|
+
module TimeStuff # avoid naming conflicts. ;)
|
4
|
+
module Zones
|
5
|
+
|
6
|
+
def self.included(base) #:nodoc:
|
5
7
|
base.class_eval do
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
#puts 'TP mixing'
|
9
|
+
# If we want to_s to ALWAYS be local, uncomment the below line
|
10
|
+
#alias_method :to_s, :to_local_s #
|
9
11
|
end
|
10
|
-
|
12
|
+
end
|
11
13
|
|
12
|
-
|
14
|
+
def to_pst
|
13
15
|
return in_time_zone('Pacific Time (US & Canada)')
|
14
|
-
|
16
|
+
end
|
15
17
|
|
16
|
-
|
18
|
+
def to_user_time(user = nil)
|
17
19
|
local = nil
|
18
20
|
if user && user.time_zone
|
19
|
-
|
21
|
+
local = in_time_zone(user.time_zone)
|
20
22
|
else
|
21
|
-
|
23
|
+
local = to_pst
|
22
24
|
end
|
23
25
|
local
|
24
|
-
|
26
|
+
end
|
25
27
|
|
26
|
-
|
28
|
+
def to_local_s(user = nil, options={})
|
29
|
+
format = options[:format] || :long
|
27
30
|
#puts 'calling to_local_s on ' + self.class.name
|
28
31
|
zone = to_user_time(user)
|
29
32
|
return zone.to_formatted_s(format)
|
30
|
-
|
33
|
+
end
|
31
34
|
|
32
|
-
end
|
33
35
|
|
34
|
-
|
35
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
module StringTimezoner
|
39
|
+
def to_user_time(user)
|
36
40
|
tz = ActiveSupport::TimeZone.new(user.time_zone || 'Pacific Time (US & Canada)')
|
37
41
|
# puts 'tz=' + tz.inspect
|
38
|
-
t
|
42
|
+
t = tz.parse(self)
|
39
43
|
return t
|
44
|
+
end
|
40
45
|
end
|
46
|
+
end
|
41
47
|
end
|
42
48
|
|
43
|
-
Time.send :include,
|
44
|
-
DateTime.send :include,
|
45
|
-
|
49
|
+
Time.send :include, Appoxy::TimeStuff::Zones
|
50
|
+
DateTime.send :include, Appoxy::TimeStuff::Zones
|
51
|
+
String.send :include, Appoxy::TimeStuff::StringTimezoner
|
46
52
|
|
47
|
-
String.send :include, StringTimezoner
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 12
|
9
|
+
version: 0.0.12
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Travis Reeder
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-01-
|
17
|
+
date: 2011-01-27 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -47,12 +47,16 @@ files:
|
|
47
47
|
- lib/appoxy_rails.rb
|
48
48
|
- lib/appoxy_sessions.rb
|
49
49
|
- lib/appoxy_ui.rb
|
50
|
+
- lib/railtie.rb
|
50
51
|
- lib/sessions/application_controller.rb
|
51
52
|
- lib/sessions/sessions_controller.rb
|
52
53
|
- lib/sessions/shareable.rb
|
53
54
|
- lib/sessions/user.rb
|
54
55
|
- lib/sessions/users_controller.rb
|
56
|
+
- lib/ui/_geo_location_finder.html.erb
|
55
57
|
- lib/ui/application_helper.rb
|
58
|
+
- lib/ui/binding_hack.rb
|
59
|
+
- lib/ui/test.rb
|
56
60
|
- lib/ui/time_zoner.rb
|
57
61
|
- README.markdown
|
58
62
|
has_rdoc: true
|