appoxy_rails 0.0.11 → 0.0.12
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/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
|