Merge pull request #1 from zyphlar/master
Getting the HSL copy up to date
This commit is contained in:
commit
d807aad668
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -9,13 +9,17 @@
|
|||
|
||||
# Ignore the default SQLite database.
|
||||
/db/*.sqlite3
|
||||
/db/*.sqlite3.*
|
||||
|
||||
# Ignore all logfiles and tempfiles.
|
||||
/log/*.log
|
||||
/tmp
|
||||
tmp/
|
||||
|
||||
# Ignore compiled assets
|
||||
/public/assets
|
||||
|
||||
# Ignore config file
|
||||
# Ignore config and database files (passwords)
|
||||
/config/config.yml
|
||||
/config/database.yml
|
||||
/config/initializers/secret_token.rb
|
||||
|
|
35
.rvmrc
Normal file
35
.rvmrc
Normal file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# This is an RVM Project .rvmrc file, used to automatically load the ruby
|
||||
# development environment upon cd'ing into the directory
|
||||
|
||||
# First we specify our desired <ruby>[@<gemset>], the @gemset name is optional,
|
||||
# Only full ruby name is supported here, for short names use:
|
||||
# echo "rvm use 1.8.7" > .rvmrc
|
||||
environment_id="ruby-1.9.3-p385@members-hsl"
|
||||
|
||||
# Uncomment the following lines if you want to verify rvm version per project
|
||||
# rvmrc_rvm_version="1.18.8 (stable)" # 1.10.1 seams as a safe start
|
||||
# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || {
|
||||
# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading."
|
||||
# return 1
|
||||
# }
|
||||
|
||||
# First we attempt to load the desired environment directly from the environment
|
||||
# file. This is very fast and efficient compared to running through the entire
|
||||
# CLI and selector. If you want feedback on which environment was used then
|
||||
# insert the word 'use' after --create as this triggers verbose mode.
|
||||
if [[ -d "${rvm_path:-$HOME/.rvm}/environments"
|
||||
&& -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
|
||||
then
|
||||
\. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
|
||||
[[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] &&
|
||||
\. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true
|
||||
else
|
||||
# If the environment file has not yet been created, use the RVM CLI to select.
|
||||
rvm --create "$environment_id" || {
|
||||
echo "Failed to create RVM environment '${environment_id}'."
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
12
Gemfile
12
Gemfile
|
@ -1,11 +1,15 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'rails', '3.2.3'
|
||||
ruby '1.9.3'
|
||||
|
||||
gem 'rails', '3.2.8'
|
||||
|
||||
# Bundle edge Rails instead:
|
||||
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
||||
|
||||
gem 'sqlite3'
|
||||
gem 'pg'
|
||||
gem 'taps'
|
||||
|
||||
gem 'json'
|
||||
|
||||
|
@ -40,7 +44,11 @@ gem 'bcrypt-ruby', '~> 3.0.0'
|
|||
# gem 'capistrano'
|
||||
|
||||
# To use debugger
|
||||
# gem 'ruby-debug'
|
||||
#gem 'debugger'
|
||||
|
||||
#gem "paperclip", "~> 3.0"
|
||||
gem 'gravtastic'
|
||||
|
||||
gem 'passenger'
|
||||
|
||||
gem "rails-settings-cached", "0.2.4"
|
||||
|
|
145
Gemfile.lock
145
Gemfile.lock
|
@ -1,116 +1,135 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
actionmailer (3.2.8)
|
||||
actionpack (= 3.2.8)
|
||||
mail (~> 2.4.4)
|
||||
actionpack (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
actionpack (3.2.8)
|
||||
activemodel (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.1)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.0)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.1.2)
|
||||
activemodel (3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
sprockets (~> 2.1.3)
|
||||
activemodel (3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
activerecord (3.2.8)
|
||||
activemodel (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.3)
|
||||
activemodel (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
activesupport (3.2.3)
|
||||
activeresource (3.2.8)
|
||||
activemodel (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
activesupport (3.2.8)
|
||||
i18n (~> 0.6)
|
||||
multi_json (~> 1.0)
|
||||
arel (3.0.2)
|
||||
bcrypt-ruby (3.0.1)
|
||||
builder (3.0.0)
|
||||
cancan (1.6.8)
|
||||
builder (3.0.4)
|
||||
cancan (1.6.10)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
coffee-script (2.2.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.3.3)
|
||||
devise (2.1.1)
|
||||
coffee-script-source (1.6.3)
|
||||
daemon_controller (1.1.5)
|
||||
devise (2.2.7)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.2.1)
|
||||
erubis (2.7.0)
|
||||
execjs (1.4.0)
|
||||
multi_json (~> 1.0)
|
||||
execjs (2.0.2)
|
||||
gravtastic (3.2.6)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.0)
|
||||
hike (1.2.3)
|
||||
i18n (0.6.5)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.1.1)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.7.5)
|
||||
libv8 (3.3.10.4)
|
||||
jquery-rails (3.0.4)
|
||||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.1)
|
||||
libv8 (3.16.14.3)
|
||||
mail (2.4.4)
|
||||
i18n (>= 0.4.0)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
mime-types (1.19)
|
||||
multi_json (1.3.6)
|
||||
orm_adapter (0.1.0)
|
||||
mime-types (1.25)
|
||||
multi_json (1.8.2)
|
||||
orm_adapter (0.4.0)
|
||||
passenger (4.0.19)
|
||||
daemon_controller (>= 1.1.0)
|
||||
rack
|
||||
rake (>= 0.8.1)
|
||||
pg (0.17.0)
|
||||
polyglot (0.3.3)
|
||||
rack (1.4.1)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-ssl (1.3.2)
|
||||
rack-ssl (1.3.3)
|
||||
rack
|
||||
rack-test (0.6.1)
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.3)
|
||||
actionmailer (= 3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
activerecord (= 3.2.3)
|
||||
activeresource (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
rails (3.2.8)
|
||||
actionmailer (= 3.2.8)
|
||||
actionpack (= 3.2.8)
|
||||
activerecord (= 3.2.8)
|
||||
activeresource (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.3)
|
||||
railties (3.2.3)
|
||||
actionpack (= 3.2.3)
|
||||
activesupport (= 3.2.3)
|
||||
railties (= 3.2.8)
|
||||
rails-settings-cached (0.2.4)
|
||||
rails (>= 3.0.0)
|
||||
railties (3.2.8)
|
||||
actionpack (= 3.2.8)
|
||||
activesupport (= 3.2.8)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (~> 0.14.6)
|
||||
rake (0.9.2.2)
|
||||
rdoc (3.12)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (10.1.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
sass (3.2.1)
|
||||
sass-rails (3.2.5)
|
||||
ref (1.0.5)
|
||||
rest-client (1.6.7)
|
||||
mime-types (>= 1.16)
|
||||
sass (3.2.11)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
sequel (3.20.0)
|
||||
sinatra (1.0)
|
||||
rack (>= 1.0)
|
||||
sprockets (2.1.3)
|
||||
hike (~> 1.2)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
sqlite3 (1.3.6)
|
||||
therubyracer (0.10.1)
|
||||
libv8 (~> 3.3.10)
|
||||
thor (0.14.6)
|
||||
tilt (1.3.3)
|
||||
treetop (1.4.10)
|
||||
sqlite3 (1.3.8)
|
||||
taps (0.3.24)
|
||||
rack (>= 1.0.1)
|
||||
rest-client (>= 1.4.0, < 1.7.0)
|
||||
sequel (~> 3.20.0)
|
||||
sinatra (~> 1.0.0)
|
||||
therubyracer (0.12.0)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.18.1)
|
||||
tilt (1.4.1)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.33)
|
||||
uglifier (1.2.7)
|
||||
tzinfo (0.3.38)
|
||||
uglifier (2.2.1)
|
||||
execjs (>= 0.3.0)
|
||||
multi_json (~> 1.3)
|
||||
warden (1.2.1)
|
||||
multi_json (~> 1.0, >= 1.0.2)
|
||||
warden (1.2.3)
|
||||
rack (>= 1.0)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -124,8 +143,12 @@ DEPENDENCIES
|
|||
gravtastic
|
||||
jquery-rails
|
||||
json
|
||||
rails (= 3.2.3)
|
||||
passenger
|
||||
pg
|
||||
rails (= 3.2.8)
|
||||
rails-settings-cached (= 0.2.4)
|
||||
sass-rails (~> 3.2.3)
|
||||
sqlite3
|
||||
taps
|
||||
therubyracer
|
||||
uglifier (>= 1.0.3)
|
||||
|
|
10
README.rdoc
10
README.rdoc
|
@ -10,6 +10,12 @@ Distributed under a Creative Commons Attribution 3.0 license http://creativecomm
|
|||
|
||||
To use:
|
||||
* Load into a Rails 3 environment
|
||||
* Rename config/config.yml.example to config/config.yml and edit appropriately
|
||||
* Use the Rails console to create a new User and set user.admin = true
|
||||
* Copy config/config.yml.example to config/config.yml and edit appropriately
|
||||
* Copy config/database.yml.example to config/database.yml and edit appropriately
|
||||
* Copy config/initializers/secret_token.rb.example to config/config/initializers/secret_token.rb and edit appropriately
|
||||
* Run bundle install, rake db:migrate, etc.
|
||||
* Use the Rails console to create a new User with admin rights
|
||||
* user = User.new
|
||||
* user.password = "foobar"
|
||||
* user.admin = true
|
||||
* user.save
|
||||
|
|
3
app/assets/javascripts/ipn.js.coffee
Normal file
3
app/assets/javascripts/ipn.js.coffee
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
|
@ -12,3 +12,46 @@
|
|||
*= require_tree .
|
||||
*/
|
||||
.caption { display: inline-block; background-color: #eee; border: 1px solid #333; border-radius: 5px; margin-bottom: 1em; }
|
||||
.btn {
|
||||
display: inline-block;
|
||||
padding: 4px 10px 4px;
|
||||
margin-bottom: 0;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 1px rgba(255,255,255,.75);
|
||||
vertical-align: middle;
|
||||
background-color: #f5f5f5;
|
||||
background-image: -moz-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: -ms-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: -webkit-gradient(linear,0 0,0 100%,from( #fff),to( #e6e6e6));
|
||||
background-image: -webkit-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: -o-linear-gradient(top, #fff, #e6e6e6);
|
||||
background-image: linear-gradient(top, #fff, #e6e6e6);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
|
||||
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
|
||||
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
border: 1px solid #ccc;
|
||||
border-bottom-color: #bbb;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
|
||||
cursor: pointer;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||
}
|
||||
.member-status-symbol, .social-icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
a.social-link:hover {
|
||||
background: transparent;
|
||||
}
|
||||
.lined-table td {
|
||||
border-bottom: 1px dashed black;
|
||||
}
|
||||
|
|
3
app/assets/stylesheets/ipn.css.scss
Normal file
3
app/assets/stylesheets/ipn.css.scss
Normal file
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the Ipn controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -6,8 +6,16 @@
|
|||
.hoverinfo { cursor: progress; }
|
||||
|
||||
.payment_links { background-color: #ddd; padding: 1em; border-radius: 1em;
|
||||
display: inline-block; float: right; }
|
||||
display: inline-block; float: right; max-width: 30%; min-width: 10em;}
|
||||
|
||||
.payment-highlighted {
|
||||
background-color: orange !important;
|
||||
}
|
||||
|
||||
.avatar { height: 2em; width: 2em; }
|
||||
|
||||
.avatar-large {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
textarea { height: 10em; }
|
||||
|
|
|
@ -7,9 +7,18 @@ class ApplicationController < ActionController::Base
|
|||
else
|
||||
flash[:alert] = "Nothing to see here!"
|
||||
end
|
||||
Rails.logger.warn "----------\r\nWARNING: AccessDenied Exception: #{exception.inspect} User: #{current_user.inspect}\r\n----------"
|
||||
redirect_to root_url
|
||||
end
|
||||
|
||||
@payment_methods = [[nil],["PayPal"],["Dwolla"],["Bill Pay"],["Check"],["Cash"],["Other"]]
|
||||
@payment_instructions = {nil => nil, :paypal => "Set up a monthly recurring payment to hslfinances@gmail.com", :dwolla => "Set up a monthly recurring payment to hslfinances@gmail.com", :billpay => "Have your bank send a monthly check to HeatSync Labs Treasurer, 140 W Main St, Mesa AZ 85201", :check => "Mail to HeatSync Labs Treasurer, 140 W Main St, Mesa AZ 85201 OR put in the drop safe at the Lab with a deposit slip firmly attached each month.", :cash => "Put in the drop safe at the Lab with a deposit slip firmly attached each month.", :other => "Hmm... talk to a Treasurer!"}
|
||||
end
|
||||
|
||||
# Add a "fit" function to sanitize inputs for mac history
|
||||
class Fixnum
|
||||
def fit(range)
|
||||
self > range.max ? range.max : (self < range.min ? range.min : self)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,15 +11,16 @@ class CardsController < ApplicationController
|
|||
|
||||
if can? :read, DoorLog then
|
||||
most_active_count = 0
|
||||
runner_up_count = 0
|
||||
@most_active_card = nil
|
||||
@runner_up_card = nil
|
||||
@cards.each do |card|
|
||||
card_num_R = card.card_number.to_i(16)%32767
|
||||
card[:accesses_this_week] = DoorLog.where('key = "R" AND data =? AND created_at > ?', card_num_R, DateTime.now - 7.days).order("created_at DESC").count
|
||||
if(card[:accesses_this_week] > most_active_count) then
|
||||
most_active_count = card[:accesses_this_week]
|
||||
@most_active_card = card
|
||||
end
|
||||
card[:accesses_this_week] = DoorLog.where("key = ? AND data = ? AND created_at > ?", 'G', card_num_R, DateTime.now - 1.month).order("created_at DESC").group_by { |d| d.created_at.beginning_of_day }.count
|
||||
end
|
||||
@most_active_cards = @cards.sort{|a,b| b[:accesses_this_week] <=> a[:accesses_this_week]}
|
||||
@most_active_card = @most_active_cards[0]
|
||||
@runner_up_card = @most_active_cards[1]
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
|
@ -33,7 +34,7 @@ class CardsController < ApplicationController
|
|||
def show
|
||||
if can? :read, DoorLog then
|
||||
card_num_R = @card.card_number.to_i(16)%32767
|
||||
@door_logs = DoorLog.where('key = "R" AND data =?', card_num_R).order("created_at DESC")
|
||||
@door_logs = DoorLog.where('key = ? AND data = ?', "G", card_num_R).order("created_at DESC")
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class CertificationsController < ApplicationController
|
||||
load_and_authorize_resource :certification
|
||||
load_and_authorize_resource :user, :through => :certification
|
||||
#load_and_authorize_resource :user, :through => :certification
|
||||
before_filter :authenticate_user!
|
||||
|
||||
# GET /certifications
|
||||
|
|
|
@ -26,6 +26,7 @@ class DoorLogsController < ApplicationController
|
|||
# GET /door_logs/auto_download
|
||||
def auto_download
|
||||
@results = DoorLog.download_from_door
|
||||
@status = DoorLog.download_status # for space_api
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
|
|
|
@ -5,14 +5,22 @@ def index
|
|||
@recent_certs = UserCertification.where("created_at > ?", DateTime.now - 7.days).count
|
||||
@num_users = User.count
|
||||
@recent_users = User.where("created_at > ?", DateTime.now - 7.days).count
|
||||
# Payments: member levels are multipled by 10 to indicate current payment; 25 x 10 = 250
|
||||
@num_paid_users = User.all.select{|u| u.member_status >= 250 }.count
|
||||
@num_plus_users = User.all.select{|u| u.member_status == 1000 }.count
|
||||
@num_basic_users = User.all.select{|u| u.member_status == 500 }.count
|
||||
@num_associate_users = User.all.select{|u| u.member_status == 250 }.count
|
||||
@num_delinquent_users = User.all.select{|u| !u.payment_status }.count
|
||||
if can? :read, User then
|
||||
@recent_user_names = User.where("member_level > 10").accessible_by(current_ability).order('created_at desc').limit(5)
|
||||
end
|
||||
@num_door_opens = DoorLog.where("key = 'G'").count
|
||||
@today_door_opens = DoorLog.where("key = 'G' AND created_at > ?", DateTime.now - 1.day).count
|
||||
@recent_door_opens = DoorLog.where("key = 'G' AND created_at > ?", DateTime.now - 7.days).count
|
||||
@num_door_denieds = DoorLog.where("key = 'f'").count
|
||||
@recent_door_denieds = DoorLog.where("key = 'f' AND created_at > ?", DateTime.now - 7.days).count
|
||||
@num_door_denieds = DoorLog.where("key = 'D'").count
|
||||
@recent_door_denieds = DoorLog.where("key = 'D' AND created_at > ?", DateTime.now - 1.month).count
|
||||
@num_logins = User.sum('sign_in_count')
|
||||
@recent_logins = User.where('current_sign_in_at > ?',Date.today - 7.days).count
|
||||
@num_macs = Mac.count
|
||||
@recent_macs = Mac.where("since > ?", DateTime.now - 1.day).count
|
||||
|
||||
|
@ -21,4 +29,10 @@ def index
|
|||
end
|
||||
end
|
||||
|
||||
def more_info
|
||||
respond_to do |format|
|
||||
format.html # more_info.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
54
app/controllers/ipns_controller.rb
Normal file
54
app/controllers/ipns_controller.rb
Normal file
|
@ -0,0 +1,54 @@
|
|||
class IpnsController < ApplicationController
|
||||
load_and_authorize_resource :ipn, :except => [:new, :create]
|
||||
before_filter :authenticate_user!, :except => [:new, :create]
|
||||
|
||||
protect_from_forgery :except => [:create]
|
||||
|
||||
def index
|
||||
@ipns = Ipn.all
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
@ipn = Ipn.new_from_dynamic_params(params)
|
||||
@ipn.data = params.to_json
|
||||
@ipn.save
|
||||
render :nothing => true
|
||||
#unless @ipn.validate!
|
||||
# Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
|
||||
#end
|
||||
end
|
||||
|
||||
def import
|
||||
@ipn = Ipn.new_from_dynamic_params(params)
|
||||
@ipn.data = params.to_json
|
||||
@ipn.save
|
||||
redirect_to ipn_path(@ipn)
|
||||
#unless @ipn.validate!
|
||||
# Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
|
||||
#end
|
||||
end
|
||||
|
||||
def validate
|
||||
if @ipn.validate!
|
||||
redirect_to ipns_url, :notice => 'Valid!'
|
||||
else
|
||||
redirect_to ipns_url, :notice => 'INVALID'
|
||||
end
|
||||
end
|
||||
|
||||
def link
|
||||
result = @ipn.link_payment
|
||||
if result.first
|
||||
redirect_to ipns_url, :notice => 'Payment was successfully linked.'
|
||||
else
|
||||
redirect_to ipns_url, :notice => result.last
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,12 +1,66 @@
|
|||
class MacsController < ApplicationController
|
||||
load_and_authorize_resource :mac, :except => [:index, :scan, :import]
|
||||
load_and_authorize_resource :user, :through => :mac, :except => [:index, :show, :scan, :import]
|
||||
load_and_authorize_resource :mac, :except => [:create, :history]
|
||||
#load_and_authorize_resource :user, :through => :mac, :except => [:index, :show, :scan, :import]
|
||||
|
||||
before_filter :arp_lookup, :only => :new
|
||||
|
||||
#require "active_record"
|
||||
require "optparse"
|
||||
#require "rubygems"
|
||||
|
||||
def index
|
||||
recent_mac_logs_ungrouped = MacLog.last(1000)
|
||||
if recent_mac_logs_ungrouped.present?
|
||||
@mac_time_start_date = recent_mac_logs_ungrouped.first.created_at
|
||||
recent_mac_logs = recent_mac_logs_ungrouped.group_by(&:mac)
|
||||
@mac_times = {}
|
||||
# Go thru each mac
|
||||
recent_mac_logs.each do |mac_log|
|
||||
last_active = nil
|
||||
# And the entries for each mac (mac_log.first is the string, mac_log.last is the array)
|
||||
mac_log.last.each do |entry|
|
||||
# Find an activate followed immediately by a deactivate
|
||||
if entry.action == "activate"
|
||||
last_active = entry
|
||||
else
|
||||
if last_active && entry.action == "deactivate"
|
||||
# Calculate the time difference between the two and append to this mac's total time
|
||||
this_entry = @mac_times[entry.mac]
|
||||
if this_entry
|
||||
this_time = this_entry[:time]
|
||||
else
|
||||
this_time = 0
|
||||
end
|
||||
@mac_times[entry.mac] = {:mac => entry, :time => (entry.created_at - last_active.created_at) + this_time}
|
||||
else
|
||||
# No pair found; discard.
|
||||
last_active = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@mac_times_sorted = @mac_times.sort{|a,b| b.last[:time] <=> a.last[:time] }
|
||||
@most_active_mac = nil
|
||||
@runner_up_mac = nil
|
||||
@mac_times_sorted.each do |mac_time|
|
||||
unless @most_active_mac
|
||||
this_mac = Mac.find_by_mac(mac_time.first)
|
||||
unless this_mac.hidden
|
||||
@most_active_mac = this_mac
|
||||
@most_active = mac_time
|
||||
end
|
||||
else
|
||||
unless @runner_up_mac
|
||||
this_mac = Mac.find_by_mac(mac_time.first)
|
||||
unless this_mac.hidden
|
||||
@runner_up_mac = this_mac
|
||||
@runner_up = mac_time
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#@active_macs = Mac.where(:active => true, :hidden => false)
|
||||
#@active_macs += Mac.where(:active => true, :hidden => nil)
|
||||
|
||||
|
@ -16,7 +70,7 @@ def index
|
|||
elsif user_signed_in? then
|
||||
@active_macs = Mac.where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).includes(:user).order("users.name ASC").group("users.name")
|
||||
else
|
||||
@active_macs = Mac.select("mac, note, user_id").where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).joins(:user).order("users.name ASC").group("users.name")
|
||||
@active_macs = Mac.select("mac, note, user_id").where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).joins(:user).order("users.name ASC").group("users.name, mac, note, user_id")
|
||||
end
|
||||
|
||||
@hidden_macs = Mac.where("macs.active = ? AND macs.hidden = ?", true, true).order("note ASC")
|
||||
|
@ -32,10 +86,52 @@ def index
|
|||
end
|
||||
end
|
||||
|
||||
def history
|
||||
authorize! :read_details, Mac
|
||||
begin
|
||||
@start_date = DateTime.parse(params[:start])
|
||||
@end_date = DateTime.parse(params[:end])
|
||||
rescue
|
||||
@start_date = DateTime.now - 2.weeks
|
||||
@end_date = DateTime.now
|
||||
end
|
||||
|
||||
@mac_logs_by_hour = MacLog.where("created_at > ? AND created_at < ?", @start_date, @end_date).group_by{|m| m.created_at.beginning_of_hour}
|
||||
@mac_log_graph = []
|
||||
mac_running_balance = 0
|
||||
lowest_balance = 0
|
||||
@mac_logs_by_hour.each do |time, mac_log|
|
||||
mac_log.each do |entry|
|
||||
# Add one computer for activate, subtract one for deactivate
|
||||
if entry.action == "activate"
|
||||
mac_running_balance += 1
|
||||
elsif entry.action == "deactivate"
|
||||
mac_running_balance -= 1
|
||||
end
|
||||
# Keep track of the lowest number in the graph
|
||||
if mac_running_balance < lowest_balance
|
||||
lowest_balance = mac_running_balance
|
||||
end
|
||||
end
|
||||
@mac_log_graph << [time.to_time.to_i*1000,mac_running_balance]
|
||||
end
|
||||
|
||||
if lowest_balance != 0
|
||||
# Subtract a negative balance to raise everything
|
||||
@mac_log_graph = @mac_log_graph.map{ |time,balance| [time, balance - lowest_balance] }
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render :json => @mac_log_graph }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /macs/1
|
||||
# GET /macs/1.json
|
||||
def show
|
||||
@mac = Mac.find(params[:id])
|
||||
@mac_logs = MacLog.where(:mac => @mac.mac)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
|
@ -70,26 +166,34 @@ end
|
|||
end
|
||||
|
||||
# POST /macs
|
||||
# POST /user
|
||||
def create
|
||||
@mac = Mac.new(params[:mac])
|
||||
authorize! :update, @mac
|
||||
|
||||
if can? :manage, Mac then
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
else
|
||||
@users = [current_user]
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
if @mac.save
|
||||
format.html { redirect_to macs_path, :notice => 'Mac was successfully created.' }
|
||||
format.json { render :json => @mac, :status => :created, :location => @mac }
|
||||
@existing_mac = Mac.find_by_mac(@mac.mac)
|
||||
if can? :manage, Mac then
|
||||
@users = User.accessible_by(current_ability).sort_by(&:name)
|
||||
else
|
||||
@users = [current_user]
|
||||
end
|
||||
|
||||
if @existing_mac.present?
|
||||
if @existing_mac.user_id.nil?
|
||||
redirect_to edit_mac_path(@existing_mac), :notice => 'This MAC already exists, edit it here:'
|
||||
else
|
||||
@mac.errors.add(:user,"for this MAC is already set to #{@existing_mac.user.name} -- please contact them or an admin if this is incorrect.")
|
||||
render :action => "new"
|
||||
end
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.json { render :json => @mac.errors, :status => :unprocessable_entity }
|
||||
|
||||
respond_to do |format|
|
||||
if @mac.save
|
||||
format.html { redirect_to macs_path, :notice => 'MAC was successfully created.' }
|
||||
format.json { render :json => @mac, :status => :created, :location => @mac }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.json { render :json => @mac.errors, :status => :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /macs/1
|
||||
|
@ -109,7 +213,7 @@ end
|
|||
|
||||
respond_to do |format|
|
||||
if @mac.save
|
||||
format.html { redirect_to macs_path, :notice => 'Mac was successfully updated.' }
|
||||
format.html { redirect_to macs_path, :notice => 'MAC was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
|
@ -118,115 +222,118 @@ end
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
def arp_lookup
|
||||
@ip = request.env['REMOTE_ADDR']
|
||||
@arp = %x(/usr/sbin/arp -a | grep #{@ip})
|
||||
end
|
||||
|
||||
def scan
|
||||
Rails.logger.info "starting scan..."
|
||||
# Command line arguments
|
||||
options = {};
|
||||
OptionParser.new { |opts|
|
||||
opts.banner = "Usage: pamela-scanner.rb --interface=en0"
|
||||
# Command line arguments
|
||||
options = {};
|
||||
OptionParser.new { |opts|
|
||||
opts.banner = "Usage: pamela-scanner.rb --interface=en0"
|
||||
|
||||
options[:verbose] = true
|
||||
opts.on("v", "--verbose", "Run verbosely") { |verbose|
|
||||
options[:verbose] = verbose
|
||||
}
|
||||
options[:verbose] = true
|
||||
opts.on("v", "--verbose", "Run verbosely") { |verbose|
|
||||
options[:verbose] = verbose
|
||||
}
|
||||
|
||||
options[:interface] = "eth0"
|
||||
opts.on("i", "--interface=interface", "Network Interface") { |interface|
|
||||
options[:interface] = interface
|
||||
}
|
||||
options[:interface] = "eth0"
|
||||
opts.on("i", "--interface=interface", "Network Interface") { |interface|
|
||||
options[:interface] = interface
|
||||
}
|
||||
|
||||
options[:max_age] = 20
|
||||
opts.on("a", "--max-age=minutes", "Minutes to keep expired macs active") { |max_age|
|
||||
options[:max_age] = max_age.to_i
|
||||
}
|
||||
options[:max_age] = 20
|
||||
opts.on("a", "--max-age=minutes", "Minutes to keep expired macs active") { |max_age|
|
||||
options[:max_age] = max_age.to_i
|
||||
}
|
||||
|
||||
options[:db_host] = "configure_me"
|
||||
opts.on("r", "--db-host=host", "Database Host") { |host|
|
||||
options[:db_host] = host
|
||||
}
|
||||
options[:db_host] = "configure_me"
|
||||
opts.on("r", "--db-host=host", "Database Host") { |host|
|
||||
options[:db_host] = host
|
||||
}
|
||||
|
||||
options[:db_name] = "configure_me"
|
||||
opts.on("n", "--db-name=name", "Database Name") { |name|
|
||||
options[:db_name] = name
|
||||
}
|
||||
options[:db_name] = "configure_me"
|
||||
opts.on("n", "--db-name=name", "Database Name") { |name|
|
||||
options[:db_name] = name
|
||||
}
|
||||
|
||||
options[:db_user] = "configure_me"
|
||||
opts.on("u", "--db-user=user", "Database User") { |user|
|
||||
options[:db_user] = user
|
||||
}
|
||||
options[:db_user] = "configure_me"
|
||||
opts.on("u", "--db-user=user", "Database User") { |user|
|
||||
options[:db_user] = user
|
||||
}
|
||||
|
||||
options[:db_password] = "configure_me"
|
||||
opts.on("p", "--db-password=password", "Database Password") { |password|
|
||||
options[:db_password] = password
|
||||
}
|
||||
options[:db_password] = "configure_me"
|
||||
opts.on("p", "--db-password=password", "Database Password") { |password|
|
||||
options[:db_password] = password
|
||||
}
|
||||
|
||||
}.parse!
|
||||
}.parse!
|
||||
|
||||
# Open the database
|
||||
#ActiveRecord::Base::establish_connection(
|
||||
# :adapter => "mysql2",
|
||||
# :host => options[:db_host],
|
||||
# :database => options[:db_name],
|
||||
# :username => options[:db_user],
|
||||
# :password => options[:db_password])
|
||||
# Open the database
|
||||
#ActiveRecord::Base::establish_connection(
|
||||
# :adapter => "mysql2",
|
||||
# :host => options[:db_host],
|
||||
# :database => options[:db_name],
|
||||
# :username => options[:db_user],
|
||||
# :password => options[:db_password])
|
||||
|
||||
#class Mac < ActiveRecord::Base
|
||||
#end
|
||||
#class Mac < ActiveRecord::Base
|
||||
#end
|
||||
|
||||
#class MacLog < ActiveRecord::Base
|
||||
#end
|
||||
#class MacLog < ActiveRecord::Base
|
||||
#end
|
||||
|
||||
# Scan the network for mac addresses
|
||||
macs = {};
|
||||
command = sprintf("arp-scan -R --interface=%s --localnet", options[:interface])
|
||||
if options[:verbose]
|
||||
Rails.logger.info "Running [#{command}]"
|
||||
end
|
||||
IO.popen(command) { |stdin|
|
||||
Rails.logger.info "Reading stdin: "+stdin.inspect
|
||||
stdin.each { |line|
|
||||
next if line !~ /^([\d\.]+)\s+([[:xdigit:]:]+)\s/;
|
||||
macs[$2] = $1;
|
||||
}
|
||||
}
|
||||
# Scan the network for mac addresses
|
||||
macs = {};
|
||||
command = sprintf("arp-scan -R --interface=%s --localnet", options[:interface])
|
||||
if options[:verbose]
|
||||
Rails.logger.info "Running [#{command}]"
|
||||
end
|
||||
IO.popen(command) { |stdin|
|
||||
Rails.logger.info "Reading stdin: "+stdin.inspect
|
||||
stdin.each { |line|
|
||||
next if line !~ /^([\d\.]+)\s+([[:xdigit:]:]+)\s/;
|
||||
macs[($2).downcase] = ($1).downcase;
|
||||
}
|
||||
}
|
||||
|
||||
# Scan the existing macs and update each record as necessary
|
||||
Mac.find(:all).each { |entry|
|
||||
mac = entry.mac.downcase
|
||||
ip = entry.ip
|
||||
if macs.has_key?(mac)
|
||||
if ! entry.active || ! entry.since
|
||||
Rails.logger.info "Activating #{mac} at #{ip}" if options[:verbose]
|
||||
entry.since = Time.now
|
||||
MacLog.new(:mac => mac, :ip => ip, :action => "activate").save
|
||||
end
|
||||
entry.active = 1
|
||||
entry.ip = ip
|
||||
entry.refreshed = Time.now
|
||||
entry.save
|
||||
macs.delete(mac)
|
||||
next
|
||||
end
|
||||
# Scan the existing macs and update each record as necessary
|
||||
Mac.find(:all).each { |entry|
|
||||
mac = entry.mac.downcase
|
||||
ip = entry.ip
|
||||
if macs.has_key?(mac)
|
||||
if ! entry.active || ! entry.since
|
||||
Rails.logger.info "Activating #{mac} at #{ip}" if options[:verbose]
|
||||
entry.since = Time.now
|
||||
MacLog.new(:mac => mac, :ip => ip, :action => "activate").save
|
||||
end
|
||||
entry.active = 1
|
||||
entry.ip = ip
|
||||
entry.refreshed = Time.now
|
||||
entry.save
|
||||
macs.delete(mac)
|
||||
next
|
||||
end
|
||||
|
||||
# Entry is no longer current
|
||||
if entry.active
|
||||
ageMinutes = ((Time.now - entry.refreshed)/60).to_i
|
||||
next if ageMinutes < options[:max_age]
|
||||
Rails.logger.info "Deactivating #{mac}, #{ageMinutes} minutes old" if options[:verbose]
|
||||
entry.active = 0
|
||||
entry.save
|
||||
MacLog.new(:mac => mac, :ip => ip, :action => "deactivate").save
|
||||
end
|
||||
}
|
||||
# Entry is no longer current
|
||||
if entry.active
|
||||
ageMinutes = ((Time.now - entry.refreshed)/60).to_i
|
||||
next if ageMinutes < options[:max_age]
|
||||
Rails.logger.info "Deactivating #{mac}, #{ageMinutes} minutes old" if options[:verbose]
|
||||
entry.active = 0
|
||||
entry.save
|
||||
MacLog.new(:mac => mac, :ip => ip, :action => "deactivate").save
|
||||
end
|
||||
}
|
||||
|
||||
# Add entries for any macs not already in the db
|
||||
macs.each { |mac, ip|
|
||||
Rails.logger.info "Activating new entry #{mac} at #{ip}" if options[:verbose]
|
||||
Mac.new(:mac => mac, :ip => ip, :active => 1, :since => Time.now, :refreshed => Time.now).save
|
||||
Rails.logger.info MacLog.new(:mac => mac, :ip => ip, :action => "activate").save
|
||||
}
|
||||
# Add entries for any macs not already in the db
|
||||
macs.each { |mac, ip|
|
||||
Rails.logger.info "Activating new entry #{mac} at #{ip}" if options[:verbose]
|
||||
Mac.new(:mac => mac, :ip => ip, :active => 1, :since => Time.now, :refreshed => Time.now).save
|
||||
Rails.logger.info MacLog.new(:mac => mac, :ip => ip, :action => "activate").save
|
||||
}
|
||||
|
||||
@log = MacLog.all
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class PaymentsController < ApplicationController
|
||||
load_and_authorize_resource :payment
|
||||
load_and_authorize_resource :user, :through => :payment
|
||||
#load_and_authorize_resource :user, :through => :payment
|
||||
before_filter :authenticate_user!
|
||||
|
||||
# Load users and certs based on current ability
|
||||
|
@ -16,6 +16,10 @@ class PaymentsController < ApplicationController
|
|||
# GET /payments.json
|
||||
def index
|
||||
@payments = @payments.order("date DESC")
|
||||
@graph = { :members => chart("members"),
|
||||
:total => chart("total"),
|
||||
:basic => chart("basic"),
|
||||
:associate => chart("associate")}
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
|
@ -23,6 +27,60 @@ class PaymentsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Private method for index charts
|
||||
def chart name
|
||||
chart_name = name || "total"
|
||||
if chart_name == "total"
|
||||
chart_type = [25, 50, 100]
|
||||
elsif chart_name == "members"
|
||||
chart_type = [25, 50, 100]
|
||||
elsif chart_name == "basic"
|
||||
chart_type = [50]
|
||||
elsif chart_name == "associate"
|
||||
chart_type = [25]
|
||||
else
|
||||
chart_type = []
|
||||
end
|
||||
|
||||
payment_months = @payments.sort_by(&:date).group_by{ |p| p.date.beginning_of_month }
|
||||
@payments_by_month = []
|
||||
payment_months.each do |month|
|
||||
# Only grab the last year from today
|
||||
if month.first > (Date.today - 1.year) && month.first < Date.today
|
||||
# Calculate sum of amounts for each month and store at end of month array
|
||||
@payments_by_month << [month.first.to_time.to_i*1000, month.last.sum{|p|
|
||||
amount = amount_or_level(p)
|
||||
if chart_type.include?(amount)
|
||||
if chart_name == "members"
|
||||
1 # Output 1 to count members
|
||||
else
|
||||
amount # Output dollars to count amount
|
||||
end
|
||||
else
|
||||
0
|
||||
end
|
||||
}]
|
||||
end
|
||||
end
|
||||
|
||||
return @payments_by_month
|
||||
end
|
||||
|
||||
def amount_or_level p
|
||||
if p.amount
|
||||
return p.amount.to_i
|
||||
else
|
||||
if p.user
|
||||
Rails.logger.info p.user.member_level
|
||||
return p.user.member_level.to_i
|
||||
else
|
||||
Rails.logger.info p.inspect
|
||||
Rails.logger.info p.user.inspect
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# GET /payments/1
|
||||
# GET /payments/1.json
|
||||
def show
|
||||
|
|
28
app/controllers/paypal_csvs_controller.rb
Normal file
28
app/controllers/paypal_csvs_controller.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
class PaypalCsvsController < ApplicationController
|
||||
load_and_authorize_resource :paypal_csv
|
||||
before_filter :authenticate_user!
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
PaypalCsv.batch_import_from_csv(params[:file].path)
|
||||
redirect_to paypal_csvs_path, :notice => 'Paypal CSV batch was successfully loaded.'
|
||||
end
|
||||
|
||||
def link
|
||||
result = @paypal_csv.link_payment
|
||||
if result.first
|
||||
redirect_to paypal_csvs_url, :notice => 'Payment was successfully linked.'
|
||||
else
|
||||
redirect_to paypal_csvs_url, :notice => result.last
|
||||
end
|
||||
end
|
||||
|
||||
end
|
32
app/controllers/settings_controller.rb
Normal file
32
app/controllers/settings_controller.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
class SettingsController < ApplicationController
|
||||
authorize_resource
|
||||
|
||||
def index
|
||||
@settings = Setting.all
|
||||
@@default_settings.each do |key, value|
|
||||
if @settings[key].blank?
|
||||
@settings[key] = value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
value = Setting[params[:id].to_sym]
|
||||
if value.present?
|
||||
@setting = {}
|
||||
@setting[:var] = params[:id]
|
||||
@setting[:value] = value
|
||||
elsif @@default_settings[params[:id].to_sym].present?
|
||||
@setting = {}
|
||||
@setting[:var] = params[:id]
|
||||
@setting[:value] = @@default_settings[params[:id].to_sym]
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
Setting[params[:id]] = params[:value]
|
||||
|
||||
redirect_to settings_path
|
||||
end
|
||||
|
||||
end
|
96
app/controllers/space_api_controller.rb
Normal file
96
app/controllers/space_api_controller.rb
Normal file
|
@ -0,0 +1,96 @@
|
|||
class SpaceApiController < ApplicationController
|
||||
# Individually remove authorizing stuff since there is no SpaceApi model
|
||||
authorize_resource :except => [:index, :access, :access_post]
|
||||
# User auth here happens via params, instead of form.
|
||||
before_filter :authenticate_user!, :except => [:index, :access, :access_post]
|
||||
|
||||
def index
|
||||
@json = JSON.parse(Setting.space_api_json_template)
|
||||
door_status = DoorLog.show_status # Expect {:unlocked => boolean, :door_1_locked => boolean, :door_2_locked => boolean}
|
||||
|
||||
@json["open"] = door_status[:unlocked]
|
||||
|
||||
if( door_status[:unlocked] )
|
||||
@json["status"] = "doors_open=both"
|
||||
elsif( !door_status[:door_1_locked] )
|
||||
@json["status"] = "doors_open=door1"
|
||||
elsif( !door_status[:door_2_locked] )
|
||||
@json["status"] = "doors_open=door2"
|
||||
else
|
||||
@json["status"] = "doors_open=none"
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json {
|
||||
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
|
||||
render :json => @json
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def access
|
||||
@status = DoorLog.show_status
|
||||
|
||||
# Nothing, just render form
|
||||
unless user_signed_in?
|
||||
@output = "Invalid email or password. Please login with your Members DB email and password below."
|
||||
else
|
||||
unless can? :access_doors_remotely, :door_access
|
||||
@output = "Sorry, your account isn't able to control doors remotely."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def access_post
|
||||
@output = ""
|
||||
|
||||
#if params['cmd'] == "check-login" then
|
||||
# if users[params['user']] && users[params['user']]['pass'].to_s == (Digest::SHA2.new(bitlen=512) << params['pass']).to_s then
|
||||
# @output += '{ "login": "okay" }'
|
||||
# else
|
||||
# @output += '{ "login": "fail" }'
|
||||
# end
|
||||
#
|
||||
# exit
|
||||
#end
|
||||
|
||||
# Stop unless signed in already, OR if the supplied user/pass params are good.
|
||||
unless current_user || check_auth(params['user'],params['pass'])
|
||||
@output += "Invalid email or password."
|
||||
else
|
||||
# Stop unless the user can access the door system
|
||||
unless can? :access_doors_remotely, :door_access
|
||||
@output += "Sorry, your account isn't able to control doors remotely. Ask an admin if this is incorrect."
|
||||
Rails.logger.warn "----------\r\nWARNING: DOOR ACCESS ATTEMPT DENIED. USER #{current_user.inspect}\r\n----------"
|
||||
else
|
||||
# Stop unless we've got a command to run
|
||||
unless params['cmd']
|
||||
@output += "No command specified."
|
||||
else
|
||||
# Log the access
|
||||
Rails.logger.info "Door access: user #{current_user.inspect}"
|
||||
DoorLog.create!({:key => "rem_"+DoorLog.parse_command(params['cmd'])[:url_param], :data => current_user.id})
|
||||
|
||||
# Execute the access
|
||||
@output += DoorLog.execute_command(params['cmd'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Render the form again
|
||||
render :access
|
||||
end
|
||||
|
||||
def check_auth(email,password)
|
||||
resource = User.find_by_email(email)
|
||||
if resource && resource.valid_password?(password)
|
||||
resource.remember_me = true
|
||||
sign_in :user, resource
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
68
app/controllers/statistics_controller.rb
Normal file
68
app/controllers/statistics_controller.rb
Normal file
|
@ -0,0 +1,68 @@
|
|||
class StatisticsController < ApplicationController
|
||||
before_filter :load_and_authorize_user
|
||||
|
||||
def index
|
||||
end
|
||||
|
||||
def door_log
|
||||
# Get own user's door data
|
||||
cards = @user.cards
|
||||
card_hash = {}
|
||||
cards.each{|c| card_hash[c.card_number.to_i(16)%32767] = c.card_number}
|
||||
card_num_Rs = cards.map{|c| c.card_number.to_i(16)%32767}
|
||||
@door_logs = DoorLog.where("data = ?", card_num_Rs).order("created_at ASC")
|
||||
@door_logs.map{|l|
|
||||
l.data = card_hash[l.data.to_i].to_i(16)
|
||||
l.key = DoorLog.key_legend[l.key]
|
||||
}
|
||||
|
||||
@door_log_graph = []
|
||||
@door_logs.where("key = 'G'").group_by{|l| l.created_at.beginning_of_day}.each{|l| @door_log_graph << [l.first.to_time.to_i*1000,l.last.size]}
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render :json => @door_logs }
|
||||
end
|
||||
end
|
||||
|
||||
def mac_log
|
||||
macs = @user.macs.where(:hidden => false).map{|m| m.mac}
|
||||
@mac_logs = MacLog.where(:mac => macs)
|
||||
@mac_log_graph = {}
|
||||
macs.each do |mac|
|
||||
mac_log = MacLog.where(:mac => mac)
|
||||
|
||||
mac_times = []
|
||||
last_active = nil
|
||||
mac_log.each do |entry|
|
||||
# Find an activate followed immediately by a deactivate
|
||||
if entry.action == "activate"
|
||||
last_active = entry
|
||||
else
|
||||
if last_active && entry.action == "deactivate"
|
||||
# Calculate the time difference between the two and append to this mac's total time
|
||||
mac_times << [entry.created_at, ((entry.created_at - last_active.created_at)/60/60)]
|
||||
else
|
||||
# No pair found; discard.
|
||||
last_active = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
mac_log_graph = []
|
||||
mac_times.group_by{|m| m.first.beginning_of_day}.each{|m| mac_log_graph << [m.first.to_time.to_i*1000,m.last.map{|n| n.last}.sum.round(2)]}
|
||||
# Store each mac in the hash with its graph
|
||||
@mac_log_graph[mac] = mac_log_graph
|
||||
end
|
||||
#@mac_log_graph = mac_log_grouped.map{|g| [g.first.to_time.to_i*1000, g.last.size] }
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render :json => @mac_logs }
|
||||
end
|
||||
end
|
||||
|
||||
def load_and_authorize_user
|
||||
@user = current_user
|
||||
authorize! :read, @user
|
||||
end
|
||||
end
|
|
@ -1,12 +1,12 @@
|
|||
class UserCertificationsController < ApplicationController
|
||||
load_and_authorize_resource :user_certification
|
||||
load_and_authorize_resource :user, :through => :user_certification
|
||||
load_and_authorize_resource :certification, :through => :user_certification
|
||||
#load_and_authorize_resource :user, :through => :user_certification
|
||||
#load_and_authorize_resource :certification, :through => :user_certification
|
||||
before_filter :authenticate_user!
|
||||
|
||||
# Load users and certs based on current ability
|
||||
before_filter :only => [:new, :edit, :create, :update] do
|
||||
@users = User.where(:hidden => false).accessible_by(current_ability).sort_by(&:name)
|
||||
@users = User.where(:hidden => [false,nil]).accessible_by(current_ability).sort_by(&:name)
|
||||
@certifications = Certification.accessible_by(current_ability).sort_by(&:name)
|
||||
end
|
||||
|
||||
|
|
|
@ -2,14 +2,24 @@ class UsersController < ApplicationController
|
|||
load_and_authorize_resource
|
||||
before_filter :authenticate_user!
|
||||
|
||||
def sort_by_cert(certs,id)
|
||||
result = 0
|
||||
certs.each do |c|
|
||||
if c.id == id
|
||||
result = 1
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
# GET /users
|
||||
# GET /users.json
|
||||
def index
|
||||
case params[:sort]
|
||||
when "name"
|
||||
@users = @users.sort_by(&:name)
|
||||
when "certifications"
|
||||
@users = @users.sort_by{ |u| [-u.certifications.count,u.name] }
|
||||
when "cert"
|
||||
@users = @users.sort_by{ |u| [-sort_by_cert(u.certifications,params[:cert].to_i),u.name] }
|
||||
when "orientation"
|
||||
@users = @users.sort_by{ |u| [-u.orientation.to_i,u.name] }
|
||||
when "waiver"
|
||||
|
@ -33,6 +43,24 @@ class UsersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# 'Active' users who haven't paid recently
|
||||
def inactive
|
||||
@users = @users.all.select{|u| u if u.payment_status == false }.sort_by{ |u| -u.delinquency }
|
||||
end
|
||||
|
||||
# Recent user activity
|
||||
def activity
|
||||
@zombie_members = User.where('sign_in_count = 0').where('member_level > 1')
|
||||
@user_logins = User.where(:current_sign_in_at => 2.months.ago..Time.now).where('sign_in_count > 1')
|
||||
@new_users = User.where(:created_at => 3.months.ago..Date.today)
|
||||
@cardless_users = User.includes('cards').where(['users.member_level >= ?','50']).where('cards.id IS NULL')
|
||||
end
|
||||
|
||||
# New members (for emailing out)
|
||||
def new_member_report
|
||||
@new_users = User.where(:created_at => 3.months.ago..Date.today).where(:hidden => false).where(['member_level >= ?','1'])
|
||||
end
|
||||
|
||||
# GET /users/1
|
||||
# GET /users/1.json
|
||||
def show
|
||||
|
@ -43,6 +71,32 @@ class UsersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def compose_email
|
||||
@user = User.find(params[:user_id])
|
||||
authorize! :read, @user
|
||||
end
|
||||
|
||||
def send_email
|
||||
@user = User.find(params[:user_id])
|
||||
authorize! :read, @user
|
||||
@subject = params[:subject]
|
||||
@body = params[:body]
|
||||
if @user.send_email(current_user,@subject,@body)
|
||||
redirect_to user_path(@user), :notice => "Email sent successfully."
|
||||
else
|
||||
flash[:alert] = "Error sending email."
|
||||
render :compose_email
|
||||
end
|
||||
end
|
||||
|
||||
# GET /user_summary/1
|
||||
def user_summary
|
||||
respond_to do |format|
|
||||
format.html { render :partial => "user_summary" } # show.html.erb
|
||||
format.json { render :json => @user }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /users/new
|
||||
# GET /users/new.json
|
||||
def new
|
||||
|
@ -61,7 +115,7 @@ class UsersController < ApplicationController
|
|||
def create
|
||||
respond_to do |format|
|
||||
if @user.save
|
||||
format.html { redirect_to users_url, :notice => 'User was successfully created.' }
|
||||
format.html { redirect_to @user, :notice => 'User was successfully created.' }
|
||||
format.json { render :json => @user, :status => :created, :location => @user }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
|
@ -75,7 +129,7 @@ class UsersController < ApplicationController
|
|||
def update
|
||||
respond_to do |format|
|
||||
if @user.update_attributes(params[:user])
|
||||
format.html { redirect_to users_url, :notice => 'User was successfully updated.' }
|
||||
format.html { redirect_to @user, :notice => 'User was successfully updated.' }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
|
@ -84,6 +138,37 @@ class UsersController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# GET /users/merge
|
||||
def merge_view
|
||||
@users = @users.sort_by(&:name)
|
||||
|
||||
respond_to do |format|
|
||||
format.html # merge_view.html.erb
|
||||
end
|
||||
end
|
||||
|
||||
# POST /users/merge
|
||||
def merge_action
|
||||
@user_to_keep = User.find(params[:user][:to_keep])
|
||||
Rails.logger.info "USER TO KEEP:"
|
||||
Rails.logger.info @user_to_keep.inspect
|
||||
@user_to_merge = User.find(params[:user][:to_merge])
|
||||
Rails.logger.info "USER TO MERGE:"
|
||||
Rails.logger.info @user_to_merge.inspect
|
||||
|
||||
@user_to_keep.absorb_user(@user_to_merge)
|
||||
|
||||
Rails.logger.info "RESULT:"
|
||||
Rails.logger.info @user_to_keep.inspect
|
||||
Rails.logger.info @user_to_keep.cards.inspect
|
||||
Rails.logger.info @user_to_keep.user_certifications.inspect
|
||||
Rails.logger.info @user_to_keep.payments.inspect
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to @user_to_keep, :notice => 'Users successfully merged.' }
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /users/1
|
||||
# DELETE /users/1.json
|
||||
def destroy
|
||||
|
|
2
app/helpers/ipn_helper.rb
Normal file
2
app/helpers/ipn_helper.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
module IpnHelper
|
||||
end
|
|
@ -1,13 +1,20 @@
|
|||
class UserMailer < ActionMailer::Base
|
||||
default :from => "wiki@heatsynclabs.org"
|
||||
default :from => "no-reply@heatsynclabs.org"
|
||||
|
||||
def new_user_email(user)
|
||||
@user = user
|
||||
@url = "http://members.heatsynclabs.org"
|
||||
|
||||
#@admins = User.where(:name => "Will Bradley")
|
||||
#@admins.each do |admin|
|
||||
mail(:to => 'info@heatsynclabs.org', :subject => "New HSL Member: "+user.name)
|
||||
#end
|
||||
mail(:to => 'member-notifications@heatsynclabs.org',
|
||||
:subject => "New HSL Member: "+user.name)
|
||||
end
|
||||
|
||||
def email(to_user,from_user,subject,body)
|
||||
@url = "http://members.heatsynclabs.org"
|
||||
@body = body
|
||||
@from_user = from_user
|
||||
|
||||
mail(:to => to_user.email,
|
||||
:subject => "HSL Message: "+subject)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,8 +2,8 @@ class Ability
|
|||
include CanCan::Ability
|
||||
|
||||
def initialize(user)
|
||||
# Anonymous can read mac
|
||||
can :read, Mac
|
||||
can :read, Mac # Anonymous can read mac
|
||||
can :scan, Mac # Need anonymous so CRON can scan
|
||||
|
||||
if !user.nil?
|
||||
|
||||
|
@ -13,9 +13,14 @@ class Ability
|
|||
can :read_details, Mac
|
||||
can [:update], Mac, :user_id => nil
|
||||
can [:create,:update], Mac, :user_id => user.id
|
||||
can :read, User, :id => user.id #TODO: why can users update themselves?
|
||||
can :read, Payment, :user_id => user.id
|
||||
can [:read,:new_member_report], User, :id => user.id #TODO: why can users update themselves? Maybe because Devise doesn't check users/edit?
|
||||
can :read, UserCertification, :user_id => user.id
|
||||
|
||||
if user.card_access_enabled
|
||||
can :access_doors_remotely, :door_access
|
||||
end
|
||||
|
||||
# Instructors can manage certs and see users
|
||||
if user.instructor?
|
||||
can :manage, Certification
|
||||
|
@ -29,9 +34,11 @@ class Ability
|
|||
can :read, UserCertification
|
||||
end
|
||||
|
||||
# Accountants can manage all
|
||||
# Accountants can manage payments
|
||||
if user.accountant?
|
||||
can :manage, Payment
|
||||
can :manage, Ipn
|
||||
can :manage, PaypalCsv
|
||||
end
|
||||
|
||||
# Admins can manage all
|
||||
|
@ -40,8 +47,8 @@ class Ability
|
|||
end
|
||||
|
||||
# Prevent all destruction for now
|
||||
cannot :destroy, User
|
||||
cannot :destroy, Card
|
||||
#cannot :destroy, User
|
||||
#cannot :destroy, Card
|
||||
cannot :destroy, Certification
|
||||
cannot :destroy, Mac
|
||||
cannot :destroy, MacLog
|
||||
|
|
|
@ -2,7 +2,8 @@ class Card < ActiveRecord::Base
|
|||
require 'open-uri'
|
||||
|
||||
attr_accessible :id, :user_id, :name, :card_number, :card_permissions
|
||||
validates_uniqueness_of :id,:card_number
|
||||
validates_presence_of :user_id, :card_number, :card_permissions
|
||||
validates_uniqueness_of :id, :card_number
|
||||
belongs_to :user
|
||||
|
||||
def upload_to_door
|
||||
|
|
|
@ -2,6 +2,126 @@ class DoorLog < ActiveRecord::Base
|
|||
attr_accessible :data, :key
|
||||
require 'open-uri'
|
||||
|
||||
def self.execute_command(command)
|
||||
output = ""
|
||||
# load config values
|
||||
door_access_url = APP_CONFIG['door_access_url']
|
||||
door_access_password = APP_CONFIG['door_access_password']
|
||||
|
||||
#login
|
||||
source = open("#{door_access_url}?e=#{door_access_password}").read
|
||||
results = source.scan(/ok/)
|
||||
|
||||
#only continue if we've got an OK login
|
||||
if(results.size > 0) then
|
||||
# Parse the command and result
|
||||
parsing = parse_command(command)
|
||||
output += parsing[:output]
|
||||
url_param = parsing[:url_param]
|
||||
|
||||
# Execute the command
|
||||
open("#{door_access_url}?#{url_param}")
|
||||
|
||||
self.download_status # Update the status cache
|
||||
else
|
||||
output += 'Failed to connect to door system.'
|
||||
end
|
||||
|
||||
#logout
|
||||
open("#{door_access_url}?e=0000")
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
def self.parse_command(command)
|
||||
output = ""
|
||||
url_param = ""
|
||||
# @commands = [
|
||||
# ["Unlock all doors","unlock"],
|
||||
# ["Unlock Front door","unlock-front"],
|
||||
# ["Unlock Rear door","unlock-rear"],
|
||||
# ["Lock all doors","lock"],
|
||||
# ["Lock Front door","lock-front"],
|
||||
# ["Lock Rear door","lock-rear"],
|
||||
# ["Open Front door","open-front"],
|
||||
# ["Open Rear door","open-rear"],
|
||||
# ["Arm alarm","arm"],
|
||||
# ["Disarm alarm","disarm"]
|
||||
# ]
|
||||
case command
|
||||
when "open-front"
|
||||
output += "Front door opened."
|
||||
url_param = "o1"
|
||||
when "open-rear"
|
||||
output += "Rear door opened."
|
||||
url_param = "o2"
|
||||
when "u", "unlock"
|
||||
output += "Doors unlocked, remember to re-lock them."
|
||||
url_param = "u"
|
||||
when "u1", "unlock-front"
|
||||
output += "Front Door unlocked, remember to re-lock it."
|
||||
url_param = "u=1"
|
||||
when "u2", "unlock-rear"
|
||||
output += "Rear Door unlocked, remember to re-lock it."
|
||||
url_param = "u=2"
|
||||
when "lock", "l"
|
||||
output += "Doors locked."
|
||||
url_param = "l"
|
||||
when "lock-front", "l1"
|
||||
output += "Front Door locked."
|
||||
url_param = "l=1"
|
||||
when "lock-rear", "l2"
|
||||
output += "Rear Door locked."
|
||||
url_param = "l=2"
|
||||
when "arm"
|
||||
output += "Armed."
|
||||
url_param = "2"
|
||||
when "disarm"
|
||||
output += "Disarmed."
|
||||
url_param = "1"
|
||||
else
|
||||
output += "Fail. Don't be a naughty user!"
|
||||
url_param = "9" # Using 9 because it's just status, no harm done
|
||||
end
|
||||
return {:output => output, :url_param => url_param}
|
||||
end
|
||||
|
||||
def self.show_status
|
||||
door_logs = DoorLog.where(key: ["door_1_locked","door_2_locked"]).order('created_at DESC').take(2)
|
||||
door_1_locked = parse_locked_status(door_logs, "door_1_locked")
|
||||
door_2_locked = parse_locked_status(door_logs, "door_2_locked")
|
||||
|
||||
# Doors are unlocked if 1 AND 2 are NOT locked
|
||||
status = {:unlocked => (!door_1_locked && !door_2_locked), :door_1_locked => door_1_locked, :door_2_locked => door_2_locked }
|
||||
end
|
||||
|
||||
def self.parse_locked_status(door_logs, door_key)
|
||||
door_logs_selected = door_logs.select{|s| s.key == door_key }
|
||||
if door_logs_selected.present?
|
||||
door_data = door_logs_selected.first.data
|
||||
if door_data == 0 # 0 = unlocked
|
||||
return false
|
||||
else
|
||||
return true # 1 = locked
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.download_status
|
||||
# load config values
|
||||
door_access_url = APP_CONFIG['door_access_url']
|
||||
door_access_password = APP_CONFIG['door_access_password']
|
||||
|
||||
# query for status
|
||||
source = open("#{door_access_url}?9").read
|
||||
# expect {"armed"=>255, "activated"=>255, "alarm_3"=>1, "alarm_2"=>1, "door_1_locked"=>1, "door_2_locked"=>1}
|
||||
# See https://github.com/heatsynclabs/Open_Access_Control_Ethernet for more info
|
||||
@status = JSON.parse(source)
|
||||
@status.each do |key,value|
|
||||
DoorLog.create!({:key => key, :data => value})
|
||||
end
|
||||
end
|
||||
|
||||
def self.download_from_door
|
||||
# load config values
|
||||
door_access_url = APP_CONFIG['door_access_url']
|
||||
|
@ -41,4 +161,8 @@ class DoorLog < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.key_legend
|
||||
{'G' => "Granted", "R" => "Read", "D" => "Denied",
|
||||
'g' => "granted", "r" => "read", "d" => "denied"}
|
||||
end
|
||||
end
|
||||
|
|
95
app/models/ipn.rb
Normal file
95
app/models/ipn.rb
Normal file
|
@ -0,0 +1,95 @@
|
|||
require 'net/http'
|
||||
class Ipn < ActiveRecord::Base
|
||||
attr_accessible :data
|
||||
belongs_to :payment
|
||||
|
||||
after_create :create_payment
|
||||
|
||||
def date_parsed
|
||||
begin
|
||||
Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z")
|
||||
rescue
|
||||
Date.new
|
||||
end
|
||||
end
|
||||
|
||||
def self.new_from_dynamic_params(params)
|
||||
ipn = Ipn.new()
|
||||
|
||||
ipn.attributes.each do |c|
|
||||
unless params[c.first.to_sym].nil?
|
||||
ipn[c.first.to_sym] = params[c.first.to_sym]
|
||||
end
|
||||
end
|
||||
|
||||
return ipn
|
||||
end
|
||||
|
||||
# Post back to Paypal to make sure it's valid
|
||||
def validate!
|
||||
uri = URI.parse('https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate')
|
||||
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
http.open_timeout = 60
|
||||
http.read_timeout = 60
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
http.use_ssl = true
|
||||
response = http.post(uri.request_uri, self.data,
|
||||
'Content-Length' => "#{self.data.size}",
|
||||
'User-Agent' => "Ruby on Rails"
|
||||
).body
|
||||
|
||||
unless ["VERIFIED", "INVALID"].include?(response)
|
||||
Rails.logger.error "Faulty paypal result: #{response}"
|
||||
return false
|
||||
end
|
||||
unless response == "VERIFIED"
|
||||
Rails.logger.error "Invalid IPN: #{response}"
|
||||
Rails.logger.error "Data: #{self.data}"
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def link_payment
|
||||
create_payment
|
||||
end
|
||||
|
||||
private
|
||||
def create_payment
|
||||
# find user by email, then by payee
|
||||
user = User.where("lower(email) = ?", self._from_email_address.downcase).first
|
||||
user = User.where("lower(payee) = ?", self._from_email_address.downcase).first if user.nil? && self._from_email_address.present?
|
||||
|
||||
# Only create payments if the IPN matches a member
|
||||
if user.present?
|
||||
# And is a payment (not a cancellation, etc)
|
||||
payment_types = ["subscr_payment","send_money"]
|
||||
if payment_types.include?(self.txn_type)
|
||||
# And a member level
|
||||
if User.member_levels[self.payment_gross.to_i].present?
|
||||
payment = Payment.new
|
||||
payment.date = Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z")
|
||||
payment.user_id = user.id
|
||||
payment.amount = self.payment_gross
|
||||
if payment.save
|
||||
self.payment_id = payment.id
|
||||
self.save!
|
||||
else
|
||||
return [false, "Unable to link payment. Payment error: #{payment.errors.full_messages.first}"]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Couldn't find membership level '#{self.payment_gross.to_i}'."]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Transaction is a '#{self.txn_type}' instead of '#{payment_types.inspect}'."]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Couldn't find user/payee '#{self.payer_email}'."]
|
||||
end
|
||||
|
||||
return [true]
|
||||
end
|
||||
|
||||
end
|
|
@ -1,8 +1,10 @@
|
|||
class Payment < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
attr_accessible :date, :user_id, :created_by
|
||||
has_one :ipn
|
||||
has_one :paypal_csv
|
||||
attr_accessible :date, :user_id, :created_by, :amount
|
||||
|
||||
validates_presence_of :user_id, :date, :created_by
|
||||
validates_presence_of :user_id, :date, :amount # not created_by
|
||||
validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.'
|
||||
|
||||
def human_date
|
||||
|
|
73
app/models/paypal_csv.rb
Normal file
73
app/models/paypal_csv.rb
Normal file
|
@ -0,0 +1,73 @@
|
|||
require 'csv'
|
||||
class PaypalCsv < ActiveRecord::Base
|
||||
attr_accessible :data, :_address_status, :_counterparty_status, :_currency, :_fee, :_from_email_address, :_gross, :_item_id, :_item_title, :_name, :_net, :_status, :_time, :_time_zone, :_to_email_address, :_transaction_id, :_type, :date, :string
|
||||
belongs_to :payment
|
||||
|
||||
after_create :create_payment
|
||||
|
||||
def date_parsed
|
||||
begin
|
||||
Date.strptime(self._date, "%m/%d/%Y")
|
||||
rescue
|
||||
Date.new
|
||||
end
|
||||
end
|
||||
|
||||
def self.batch_import_from_csv(filename)
|
||||
csv = CSV.table(filename)
|
||||
csv.each do |row|
|
||||
paypal_csv = PaypalCsv.new()
|
||||
|
||||
paypal_csv.attributes.each do |c|
|
||||
unless row[c.first.to_sym].nil?
|
||||
paypal_csv[c.first.to_sym] = row[c.first.to_sym]
|
||||
end
|
||||
end
|
||||
|
||||
paypal_csv.data = row.to_json
|
||||
paypal_csv.save
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
def link_payment
|
||||
create_payment
|
||||
end
|
||||
|
||||
private
|
||||
def create_payment
|
||||
# find user by email, then by payee
|
||||
user = User.where("lower(email) = ?", self._from_email_address.downcase).first
|
||||
user = User.where("lower(payee) = ?", self._from_email_address.downcase).first if user.nil? && self._from_email_address.present?
|
||||
|
||||
# Only create payments if the CSV matches a member
|
||||
if user.present?
|
||||
# And is a payment (not a cancellation, etc)
|
||||
payment_types = ["Recurring Payment Received","Payment Received"]
|
||||
if payment_types.include?(self._type)
|
||||
# And a member level
|
||||
if User.member_levels[self._gross.to_i].present?
|
||||
payment = Payment.new
|
||||
payment.date = Date.strptime(self._date, "%m/%d/%Y") #7/6/2013 for Jul 06
|
||||
payment.user_id = user.id
|
||||
payment.amount = self._gross
|
||||
if payment.save
|
||||
self.payment_id = payment.id
|
||||
self.save!
|
||||
else
|
||||
return [false, "Unable to link payment. Payment error: #{payment.errors.full_messages.first}"]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Couldn't find membership level '#{self._gross.to_i}'."]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Transaction is a '#{self._type}' instead of '#{payment_types.inspect}'."]
|
||||
end
|
||||
else
|
||||
return [false, "Unable to link payment. Couldn't find user/payee '#{self._from_email_address}'."]
|
||||
end
|
||||
|
||||
return [true]
|
||||
end
|
||||
end
|
3
app/models/setting.rb
Normal file
3
app/models/setting.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class Setting < RailsSettings::CachedSettings
|
||||
attr_accessible :var
|
||||
end
|
|
@ -9,15 +9,66 @@ class User < ActiveRecord::Base
|
|||
:recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
# Setup accessible (or protected) attributes for your model
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :admin, :instructor, :member, :emergency_name, :emergency_phone, :current_skills, :desired_skills, :waiver, :emergency_email, :phone, :payment_method, :orientation, :member_level, :certifications, :hidden, :marketing_source, :payee, :accountant #TODO: make admin/instructor/member/etc not accessible
|
||||
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :admin, :instructor, :member, :emergency_name, :emergency_phone, :current_skills, :desired_skills, :waiver, :emergency_email, :phone, :payment_method, :orientation, :member_level, :certifications, :hidden, :marketing_source, :payee, :accountant, :exit_reason, :twitter_url, :facebook_url, :github_url, :website_url, :email_visible, :phone_visible #TODO: make admin/instructor/member/etc not accessible
|
||||
|
||||
has_many :cards
|
||||
has_many :user_certifications
|
||||
has_many :certifications, :through => :user_certifications
|
||||
has_many :payments
|
||||
has_many :macs
|
||||
|
||||
validates_format_of [:twitter_url, :facebook_url, :github_url, :website_url], :with => URI::regexp(%w(http https)), :allow_blank => true
|
||||
|
||||
after_create :send_new_user_email
|
||||
|
||||
def absorb_user(user_to_absorb)
|
||||
# copy all attributes except email, password, name, and anything that isn't blank on the destination
|
||||
user_to_absorb.attributes.each_pair {|k,v|
|
||||
unless (v.nil? || k == :id || k == :email || k == :password || k == :name || k == :password_confirmation || k == :hidden || k == 'hidden' || k == :encrypted_password || !self.attributes[k].blank? )
|
||||
Rails.logger.info "Updating "+k.to_s+" from "+self[k].to_s
|
||||
self[k] = v
|
||||
Rails.logger.info "Updated "+k.to_s+" to "+self[k].to_s
|
||||
end
|
||||
}
|
||||
|
||||
self.save!
|
||||
|
||||
user_to_absorb.cards.each {|card|
|
||||
Rails.logger.info "CARD BEFORE: "+card.inspect
|
||||
card.user_id = self.id
|
||||
card.save!
|
||||
Rails.logger.info "CARD AFTER: "+card.inspect
|
||||
}
|
||||
user_to_absorb.user_certifications.each {|user_cert|
|
||||
Rails.logger.info "CERT BEFORE: "+user_cert.inspect
|
||||
user_cert.user_id = self.id
|
||||
user_cert.save!
|
||||
Rails.logger.info "CERT AFTER: "+user_cert.inspect
|
||||
}
|
||||
user_to_absorb.payments.each {|payment|
|
||||
Rails.logger.info "PAYMENT BEFORE: "+payment.inspect
|
||||
payment.user_id = self.id
|
||||
payment.amount = 0 if payment.amount.nil? # Bypass validation on amount
|
||||
payment.save!
|
||||
Rails.logger.info "PAYMENT AFTER: "+payment.inspect
|
||||
}
|
||||
|
||||
user_to_absorb.destroy
|
||||
end
|
||||
|
||||
def card_access_enabled
|
||||
# If the user has at least one card with permission level 1, they have access
|
||||
self.cards.where(:card_permissions => 1).count > 0
|
||||
end
|
||||
|
||||
def name_with_email_and_visibility
|
||||
if hidden then
|
||||
"#{name} (#{email}) HIDDEN"
|
||||
else
|
||||
"#{name} (#{email})"
|
||||
end
|
||||
end
|
||||
|
||||
def name_with_payee_and_member_level
|
||||
if payee.blank? then
|
||||
"#{name} - #{member_level_string}"
|
||||
|
@ -43,74 +94,117 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def self.member_levels
|
||||
{25 => "Associate", 50 => "Basic", 75 => "Basic", 100 => "Plus"}
|
||||
end
|
||||
|
||||
def payment_status
|
||||
results = payment_status_calculation
|
||||
return results[:paid]
|
||||
end
|
||||
|
||||
def member_status
|
||||
case self.member_level.to_i
|
||||
when 0
|
||||
if self.payments.count > 0 then
|
||||
2
|
||||
else
|
||||
-1
|
||||
end
|
||||
when 1
|
||||
1
|
||||
when 10..24
|
||||
10
|
||||
when 25..999
|
||||
if self.payments.count > 0 then
|
||||
if self.payments.last.date < (DateTime.now - 45.days)
|
||||
3
|
||||
else
|
||||
case self.member_level.to_i
|
||||
when 25..49
|
||||
25
|
||||
when 50..99
|
||||
50
|
||||
when 100..999
|
||||
100
|
||||
end
|
||||
end
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
results = member_status_calculation
|
||||
return results[:rank]
|
||||
end
|
||||
|
||||
def member_status_symbol
|
||||
case self.member_level.to_i
|
||||
when 0
|
||||
if self.payments.count > 0 then
|
||||
"<span class='hoverinfo' title='Former Member (#{(DateTime.now - self.payments.last.date).to_i} days ago)'>:(</span>"
|
||||
else
|
||||
"<!-- Not a member -->"
|
||||
end
|
||||
when 1
|
||||
"Unable"
|
||||
when 10..24
|
||||
"<span class='hoverinfo' title='Volunteer'>◔</span>"
|
||||
when 25..999
|
||||
if self.payments.count > 0 then
|
||||
if self.payments.last.date < (DateTime.now - 45.days)
|
||||
"<span class='hoverinfo' title='Recently Lapsed (#{(DateTime.now - self.payments.last.date).to_i} days ago)'>◌</span>"
|
||||
else
|
||||
case self.member_level.to_i
|
||||
when 25..49
|
||||
"<span class='hoverinfo' title='#{member_level_string}'>◑</span>"
|
||||
when 50..99
|
||||
"<span class='hoverinfo' title='#{member_level_string}'>◕</span>"
|
||||
when 100..999
|
||||
"<span class='hoverinfo' title='#{member_level_string}'>●</span>"
|
||||
end
|
||||
end
|
||||
else
|
||||
"<span class='hoverinfo' title='No Payments'>?</span>"
|
||||
end
|
||||
results = member_status_calculation
|
||||
return "<img src='/#{results[:icon]}#{results[:flair]}-coin.png' title='#{results[:message]}' class='member-status-symbol' />"
|
||||
end
|
||||
|
||||
def last_payment_date
|
||||
self.payments.maximum(:date)
|
||||
end
|
||||
|
||||
def delinquency
|
||||
if self.payments.count > 0
|
||||
paydate = self.payments.maximum(:date)
|
||||
(Date.today - paydate).to_i
|
||||
else
|
||||
(Date.today - self.created_at.to_date).to_i
|
||||
end
|
||||
end
|
||||
|
||||
def send_email(from_user,subject,body)
|
||||
Rails.logger.info UserMailer.email(self,from_user,subject,body).deliver
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def send_new_user_email
|
||||
Rails.logger.info UserMailer.new_user_email(self).deliver
|
||||
end
|
||||
|
||||
def member_status_calculation
|
||||
# Begin output buffer
|
||||
message = ""
|
||||
icon = ""
|
||||
flair = ""
|
||||
rank = 0
|
||||
|
||||
# First status item is level
|
||||
case self.member_level.to_i
|
||||
when 0..9
|
||||
if self.payments.count > 0 then
|
||||
message = "Former Member (#{(DateTime.now - self.payments.maximum(:date)).to_i/30} months ago)"
|
||||
icon = :timeout
|
||||
rank = 1
|
||||
else
|
||||
message = "Not a Member"
|
||||
icon = :no
|
||||
rank = 0
|
||||
end
|
||||
when 10..24
|
||||
message = "Volunteer"
|
||||
icon = :heart
|
||||
rank = 101
|
||||
when 25..49
|
||||
message = member_level_string
|
||||
icon = :copper
|
||||
rank = 250
|
||||
when 50..99
|
||||
message = member_level_string
|
||||
icon = :silver
|
||||
rank = 500
|
||||
when 100..999
|
||||
message = member_level_string
|
||||
icon = :gold
|
||||
rank = 1000
|
||||
end
|
||||
|
||||
payment_results = payment_status_calculation
|
||||
flair = payment_results[:flair]
|
||||
rank = rank/10 unless payment_results[:paid]
|
||||
message = payment_results[:message] unless payment_results[:message].blank?
|
||||
|
||||
return {:message => message, :icon => icon, :flair => flair, :rank => rank}
|
||||
end
|
||||
|
||||
def payment_status_calculation
|
||||
flair = ""
|
||||
message = ""
|
||||
paid = true
|
||||
|
||||
# Second status item is payment status
|
||||
case self.member_level.to_i
|
||||
when 25..999
|
||||
# There are payments
|
||||
if self.payments.count > 0 then
|
||||
# They're on time
|
||||
if self.payments.maximum(:date) > (DateTime.now - 60.days)
|
||||
flair = "-paid"
|
||||
paid = true
|
||||
else
|
||||
message = "Last Payment #{(DateTime.now - self.payments.maximum(:date)).to_i/30} months ago"
|
||||
paid = false
|
||||
end
|
||||
else
|
||||
message = "No Payments Recorded"
|
||||
paid = false
|
||||
end
|
||||
end
|
||||
return {:message => message, :paid => paid, :flair => flair}
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,8 +1,17 @@
|
|||
class UserCertification < ActiveRecord::Base
|
||||
attr_accessible :certification_id, :user_id
|
||||
|
||||
validates_presence_of :certification_id, :user_id
|
||||
validates_uniqueness_of :certification_id, :scope => :user_id, :message => 'already exists for this user.' # Makes sure users don't get certified twice
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :certification
|
||||
|
||||
def user_name
|
||||
if user.blank?
|
||||
return "n/a (user ##{user_id} missing)"
|
||||
else
|
||||
return self.user.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<% @card.user_id = params[:user] if params[:user].present? %>
|
||||
<div class="field">
|
||||
<%= f.label :user %><br />
|
||||
<%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name) %>
|
||||
<%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :name, "Card Note" %><br />
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
<h1>Access Cards</h1>
|
||||
|
||||
<%= link_to 'New Card', new_card_path if can? :create, Card %>
|
||||
<%= link_to 'Upload all cards', upload_all_path if can? :upload_all, Card %>
|
||||
<%= link_to 'Door Logs', door_logs_path if can? :read, DoorLog %>
|
||||
<%= link_to 'New Card', new_card_path, :class => "btn" if can? :create, Card %>
|
||||
<%= link_to 'Upload all cards', upload_all_path, :class => "btn" if can? :upload_all, Card %>
|
||||
<%= link_to 'Door Logs', door_logs_path, :class => "btn" if can? :read, DoorLog %>
|
||||
<%= link_to 'Space API', space_api_path, :class => "btn" %>
|
||||
<%= link_to 'Remote Door Access', space_api_access_path, :class => "btn" if can? :access_doors_remotely, :door_access %>
|
||||
<p>
|
||||
<b>Most Active Card Last 7 Days:</b> <%= @most_active_card.name unless @most_active_card.blank? %> (<%= @most_active_card.accesses_this_week unless @most_active_card.blank? %> times)
|
||||
<b>Most Active Card Last Month:</b> <%= @most_active_card.name unless @most_active_card.blank? %> (<%= @most_active_card.accesses_this_week unless @most_active_card.blank? %> days)
|
||||
</p>
|
||||
<p>
|
||||
<% unless @runner_up_card.blank? %>
|
||||
<b>Runner Up:</b> <%= @runner_up_card.name %> (<%= @runner_up_card.accesses_this_week %> days)
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<table class="lined-table">
|
||||
<col />
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
|
@ -19,7 +26,7 @@
|
|||
<th>DB ID</th>
|
||||
<th>Card #</th>
|
||||
<th>Access?</th>
|
||||
<th>Accesses Last 7 Days</th>
|
||||
<th>Days Accessed Last Month</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
|
@ -28,7 +35,14 @@
|
|||
<% if !@cards.blank? %>
|
||||
<% @cards.each do |card| %>
|
||||
<tr>
|
||||
<td><%= link_to card.user.name, card %></td>
|
||||
<td>
|
||||
<% if card.user.nil? %>
|
||||
n/a
|
||||
<% else %>
|
||||
<%= raw(card.user.member_status_symbol) %>
|
||||
<%= link_to card.user.name , card %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= card.name %></td>
|
||||
<td><%= card.id %></td>
|
||||
<td><%= card.card_number %></td>
|
||||
|
|
|
@ -8,13 +8,10 @@
|
|||
<%= simple_format @certification.description %>
|
||||
</p>
|
||||
|
||||
<b>Certified Users:</b>
|
||||
<ul>
|
||||
<% @certification_users.each do |user| %>
|
||||
<li><%= link_to user.name, user %></li>
|
||||
<% end %>
|
||||
<% if @certification_users.blank? then %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
<p>
|
||||
<b>Certified Users:</b>
|
||||
<%= link_to "Click Here", user_certifications_path %>
|
||||
</p>
|
||||
|
||||
<% if can? :update, @certification %><%= link_to 'Edit', edit_certification_path(@certification) %> |<% end %>
|
||||
<%= link_to 'Back', certifications_path %>
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
<% if params[:flash] == "welcome_msg" then %>
|
||||
<p class="notice"><strong>Thank for you choosing to become a HeatSync Labs member!</strong> As we foster this community of learning, science, and the arts every member is important. <br/><br/>
|
||||
You can get your payments started by following the instructions on this page. <strong>Please note electronic recurring payments are -highly- encouraged</strong>-- we do not have staff. If you must pay via cash/check, please consider prepaying for 3, 6 or 12 months up front.<br/><br/>
|
||||
<strong>To claim member benefits</strong> such as storage, grab a volunteer during your next stop into HeatSync or schedule a time to meet up in advance. Someone should also be contacting you shortly via the email address you provided.<br/><br/>
|
||||
You can get your payments started by clicking the payment button on this page or contacting a HeatSync member. <strong>Please note electronic recurring payments are -highly- encouraged</strong>-- we do not have paid staff. If you must pay via cash/check, please consider prepaying for 3, 6 or 12 months up front to reduce volunteer workload.<br/><br/>
|
||||
<strong>To claim member benefits</strong> such as storage, grab a volunteer during your next stop into HeatSync or schedule a time to meet up in advance. Someone should also be contacting you shortly via the email address you provided to schedule a New Member Orientation as well. After the orientation, you'll be equipped to be an awesome member of our community, and this website will get a lot more useful.<br/><br/>
|
||||
Please also note that certain privileges like 24/7 card access require community approval.<br/><br/>
|
||||
Thanks again, and happy hacking!</p>
|
||||
<% end %>
|
||||
|
||||
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => html) do |f| %>
|
||||
<div class="field">
|
||||
<%= f.label :member_level, "Membership Level" %><br />
|
||||
<%= f.select :member_level, [[nil],["None",0],["Unable",1],["Volunteer",10],["Associate ($25)",25],["Basic ($50)",50],["Plus ($100)",100]] %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= render :partial => "/users/payment_methods", :locals => { :g => f } %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :name, "Full Name" %><br />
|
||||
<%= f.text_field :name %>
|
||||
|
@ -15,12 +24,28 @@ Thanks again, and happy hacking!</p>
|
|||
<div class="field">
|
||||
<%= f.label :email %><br />
|
||||
<%= f.email_field :email %>
|
||||
<%= f.check_box :email_visible %>
|
||||
<%= f.label :email_visible, "Show Email to All Members?" %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :phone %><br />
|
||||
<%= f.text_field :phone %>
|
||||
<%= f.check_box :phone_visible %>
|
||||
<%= f.label :phone_visible, "Show Phone to All Members?" %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :twitter_url %>
|
||||
<%= f.text_field :twitter_url, :placeholder => "https://twitter.com/heatsynclabs" %><br/>
|
||||
<%= f.label :facebook_url %>
|
||||
<%= f.text_field :facebook_url, :placeholder => "https://www.facebook.com/HeatSyncLabs" %><br/>
|
||||
<%= f.label :github_url %>
|
||||
<%= f.text_field :github_url, :placeholder => "https://github.com/heatsynclabs" %><br/>
|
||||
<%= f.label :website_url %>
|
||||
<%= f.text_field :website_url, :placeholder => "http://www.heatsynclabs.org" %>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= f.label :emergency_name, "Emergency Contact Name" %><br />
|
||||
<%= f.text_field :emergency_name %>
|
||||
|
@ -33,13 +58,6 @@ Thanks again, and happy hacking!</p>
|
|||
<%= f.label :emergency_email %><br />
|
||||
<%= f.text_field :emergency_email %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :member_level, "Membership Level" %><br />
|
||||
<%= f.select :member_level, [[nil],["None",0],["Unable",1],["Volunteer",10],["Associate ($25)",25],["Basic ($50)",50],["Plus ($100)",100]] %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= render :partial => "/users/payment_methods", :locals => { :g => f } %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :current_skills, "What skills, knowledge and experience do you bring to the community?" %><br />
|
||||
<%= f.text_area :current_skills %>
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
<%= devise_error_messages! %>
|
||||
|
||||
<div class="payment_links">
|
||||
<div class="payment_links <%= "payment-highlighted" if params[:flash] == "welcome_msg" %>">
|
||||
|
||||
<% if can? :read, resource.payments then %>
|
||||
<%= render '/statistics/index' %>
|
||||
<% if can? :read, resource.payments.first then %>
|
||||
<h3>Recorded Payments:</h3>
|
||||
<ul>
|
||||
<% resource.payments.each do |payment| %>
|
||||
<% resource.payments.sort_by(&:date).reverse!.each do |payment| %>
|
||||
<li><%= payment.date %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
@ -16,22 +17,22 @@
|
|||
|
||||
<% if resource.payment_method == "Dwolla" %>
|
||||
<h3>Dwolla Payment Link</h3>
|
||||
<% if resource.member_level == "25" %>
|
||||
<% if resource.member_level == 25 %>
|
||||
<strong>Associate Membership ($25/mo):</strong>
|
||||
<a href="http://members.heatsynclabs.org/users/edit" class="dwolla_button" data-name="Associate Membership" data-desc="$25/month membership" data-amount="25" data-shipping="0" data-tax="0" data-key="8nMi2WmI7F8uXVlSNNDmX2o2Cgh9Af8dfJGIrd7ZrgyjNfLIxj">Subscribe</a>
|
||||
<% elsif resource.member_level == "50" %>
|
||||
<a href="http://members.heatsynclabs.org/users/edit" class="dwolla_button" data-name="Associate Membership" data-desc="$25/month membership" data-amount=25 data-shipping="0" data-tax="0" data-key="8nMi2WmI7F8uXVlSNNDmX2o2Cgh9Af8dfJGIrd7ZrgyjNfLIxj">Subscribe</a>
|
||||
<% elsif resource.member_level == 50 %>
|
||||
<strong>Basic Membership ($50/mo):</strong>
|
||||
<a href="http://members.heatsynclabs.org/users/edit" class="dwolla_button" data-name="Basic Membership" data-desc="$50/month membership" data-amount="50" data-shipping="0" data-tax="0" data-key="8nMi2WmI7F8uXVlSNNDmX2o2Cgh9Af8dfJGIrd7ZrgyjNfLIxj">Subscribe</a>
|
||||
<% elsif resource.member_level == "100" %>
|
||||
<a href="http://members.heatsynclabs.org/users/edit" class="dwolla_button" data-name="Basic Membership" data-desc="$50/month membership" data-amount=50 data-shipping="0" data-tax="0" data-key="8nMi2WmI7F8uXVlSNNDmX2o2Cgh9Af8dfJGIrd7ZrgyjNfLIxj">Subscribe</a>
|
||||
<% elsif resource.member_level == 100 %>
|
||||
<strong>Plus Membership ($100/mo):</strong>
|
||||
<a href="http://members.heatsynclabs.org/users/edit" class="dwolla_button" data-name="Plus Membership" data-desc="$100/month membership" data-amount="100" data-shipping="0" data-tax="0" data-key="8nMi2WmI7F8uXVlSNNDmX2o2Cgh9Af8dfJGIrd7ZrgyjNfLIxj">Subscribe</a>
|
||||
<a href="http://members.heatsynclabs.org/users/edit" class="dwolla_button" data-name="Plus Membership" data-desc="$100/month membership" data-amount=100 data-shipping="0" data-tax="0" data-key="8nMi2WmI7F8uXVlSNNDmX2o2Cgh9Af8dfJGIrd7ZrgyjNfLIxj">Subscribe</a>
|
||||
<% else %>
|
||||
Hmm, your membership level doesn't appear to be at $25/50/100...
|
||||
<% end %>
|
||||
<script type="text/javascript" src="https://www.dwolla.com/scripts/button.min.js"> </script>
|
||||
<% elsif resource.payment_method == "PayPal" %>
|
||||
<h3>PayPal Payment Link</h3>
|
||||
<% if resource.member_level == "25" %>
|
||||
<% if resource.member_level == 25 %>
|
||||
<strong>Associate Membership ($25/mo):</strong>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick">
|
||||
|
@ -39,7 +40,7 @@
|
|||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
|
||||
</form>
|
||||
<% elsif resource.member_level == "50" %>
|
||||
<% elsif resource.member_level == 50 %>
|
||||
<strong>Basic Membership ($50/mo):</strong>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick">
|
||||
|
@ -47,7 +48,7 @@
|
|||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
|
||||
</form>
|
||||
<% elsif resource.member_level == "100" %>
|
||||
<% elsif resource.member_level == 100 %>
|
||||
<strong>Plus Membership ($100/mo):</strong>
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<input type="hidden" name="cmd" value="_s-xclick">
|
||||
|
|
|
@ -4,3 +4,8 @@
|
|||
<%= !@results.nil? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Door status:</b>
|
||||
<%= @status %>
|
||||
</p>
|
||||
|
||||
|
|
|
@ -8,6 +8,17 @@ Guide to Card Number storage:
|
|||
cardnum = (R+(r*32767)), convert to hex
|
||||
|
||||
Guide to log keys and data:
|
||||
|
||||
Commands:
|
||||
* rem_ = remote command issues via web UI (#=user id)
|
||||
Statuses:
|
||||
* armed = current status of alarm arming
|
||||
* activated = current status of alarm ringing
|
||||
* alarm_2 = current status of alarm sensor 2
|
||||
* alarm_3 = current status of alarm sensor 3
|
||||
* door_1_locked = status of door 1
|
||||
* door_2_locked = status of door 2
|
||||
Log Entries:
|
||||
* A=alarm armed (# level)
|
||||
* a=added user (# usernum)
|
||||
* C=keypad command (# command)
|
||||
|
@ -72,7 +83,7 @@ Guide to log keys and data:
|
|||
end %>
|
||||
<% @cardnum = (door_log.data.to_i+(@divided_tmp*32767)).to_s(16) %>
|
||||
<%= "Card: "+@cardnum %>
|
||||
<% @card = Card.find(:first,:conditions=>['card_number LIKE ?', @cardnum]) %>
|
||||
<% @card = Card.find(:first,:conditions=>['lower(card_number) = ?', @cardnum.downcase]) %>
|
||||
<%= "("+@card.user.name+")" unless @card.nil? %>
|
||||
</td>
|
||||
<% else
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
<h1>Welcome to the HeatSync Labs Members App.</h1>
|
||||
<h1><%= Setting.welcome_title %></h1>
|
||||
<% if !user_signed_in? then %>
|
||||
<p>You can sign up to become a member here!</p>
|
||||
<%= simple_format Setting.welcome_body %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% if user_signed_in? && current_user.orientation.blank? then %>
|
||||
<p class="alert">There's a lot more to see here, but our records show you haven't completed the new member orientation yet. If that's incorrect, please contact a volunteer.</p>
|
||||
<% end %>
|
||||
<% if user_signed_in? && current_user.member.to_i < current_user.member_level.to_i then %>
|
||||
<% if user_signed_in? && current_user.member_status.between?(2,100) then %>
|
||||
<%= current_user.member.inspect %>
|
||||
<%= current_user.member_level.inspect %>
|
||||
<p class="alert">Looks like we haven't acknowledged a recent payment for you yet. This could be because we're slow, or this app just got started, but if in doubt please see your profile for payment instructions, or consider updating your membership level to something accurate.<br/>Thanks for supporting HeatSync!</p>
|
||||
<% end %>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<% if ((can? :read, @recent_user_names) && (@recent_user_names.count > 1)) then %>
|
||||
<% if ((can? :read, User) && (@recent_user_names.count > 1)) then %>
|
||||
<h2>New People: <em>(say hi!)</em></h2>
|
||||
<ul>
|
||||
<% @recent_user_names.each do |user| %>
|
||||
<li><%= link_to user.name, user %> <%= raw(user.member_status_symbol) %> <em>(Signed up <%= user.created_at.strftime("%b %d") %>)</em></li>
|
||||
<% if can? :read, user %>
|
||||
<li><%= link_to user.name, user %> <%= raw(user.member_status_symbol) %> <em>(Signed up <%= user.created_at.strftime("%b %d") %>)</em></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
@ -27,10 +31,14 @@
|
|||
<dd><%= @num_users %> (<%= @recent_users %> new in the last 7 days)</dd>
|
||||
<dt># of People Certified:</dt>
|
||||
<dd><%= @num_certs %> (<%= @recent_certs %> new in the last 7 days)</dd>
|
||||
<dt># of Current Paying Members:</dt>
|
||||
<dd><%= @num_paid_users %> (<%= @num_plus_users %> plus, <%= @num_basic_users %> basic, <%= @num_associate_users %> associate. <%= @num_delinquent_users %> not-current)</dd>
|
||||
<dt># of Door Accesses Granted:</dt>
|
||||
<dd><%= @num_door_opens %> (<%= @today_door_opens %> today, <%= @recent_door_opens %> in the last 7 days)</dd>
|
||||
<dt># of Door Accesses Denied:</dt>
|
||||
<dd><%= @num_door_denieds %> (<%= @recent_door_denieds %> in the last 7 days)</dd>
|
||||
<dd><%= @num_door_denieds %> (<%= @recent_door_denieds %> in the last month)</dd>
|
||||
<dt># of Members DB Logins:</dt>
|
||||
<dd><%= @num_logins %> (<%= @recent_logins %> users last 7 days)</dd>
|
||||
<dt># of Computers in this DB:</dt>
|
||||
<dd><%= @num_macs %> (<%= @recent_macs %> seen today)</dd>
|
||||
</dl>
|
||||
|
@ -39,27 +47,10 @@
|
|||
<td>
|
||||
|
||||
<h2>Member Resources</h2>
|
||||
<ul>
|
||||
<li><%= link_to "Wiki", "http://wiki.heatsynclabs.org" %></li>
|
||||
<li><%= link_to "Discussion Group", "http://groups.google.com/group/heatsynclabs" %></li>
|
||||
<li><%= link_to "IRC", "irc://irc.freenode.net#heatsynclabs" %></li>
|
||||
<li><%= link_to "Live Webcams", "http://live.heatsynclabs.org/" %></li>
|
||||
<li>Lab Phone: (480) 751-1929</li>
|
||||
<li>
|
||||
<style type="text/css">
|
||||
form input {font-family: 'Lucida Console', Monaco, monospace; }
|
||||
</style>
|
||||
|
||||
<b>Send a Message!</b>
|
||||
<form method="post" action="http://tweet.zyphon.com/signage.php">
|
||||
<em>Type here and your message will show up on the LED sign in the front window!</em><br/>
|
||||
<em>(Please be nice!)</em><br/>
|
||||
<input type="text" name="msg" id="msg" value=" Hello" size="9" /> (max 9 chars per line)<br/>
|
||||
<input type="text" name="msg2" id="msg2" value=" World" size="9" /><br/>
|
||||
<input type="submit" name="submitbutton" id="submitbutton" value="Go!" />
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
<% if can? :access_doors_remotely, :door_access %>
|
||||
<ul><li><%= link_to "Remote Door Access", space_api_access_path %></li></ul>
|
||||
<% end %>
|
||||
<%= simple_format Setting.member_resources_inset %>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
|
2
app/views/home/more_info.html.erb
Normal file
2
app/views/home/more_info.html.erb
Normal file
|
@ -0,0 +1,2 @@
|
|||
<h1>More Information</h1>
|
||||
<%= simple_format Setting.more_info_page %>
|
35
app/views/ipns/index.html.erb
Normal file
35
app/views/ipns/index.html.erb
Normal file
|
@ -0,0 +1,35 @@
|
|||
<h2>PayPal IPN Records</h2>
|
||||
<p>
|
||||
<em>Automatically loaded from PayPal's servers</em>
|
||||
</p>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Name</th>
|
||||
<th>Item</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
<% @ipns.sort_by(&:date_parsed).reverse!.each do |ipn| %>
|
||||
<tr>
|
||||
<td><%= ipn.payment_date %></td>
|
||||
<td><%= ipn.first_name %> <%= ipn.last_name %></td>
|
||||
<td><%= ipn.item_name %></td>
|
||||
<td>
|
||||
<% if ipn.payment_gross.blank? %>
|
||||
<%= ipn.txn_type %>
|
||||
<% else %>
|
||||
<%= ipn.payment_gross %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if ipn.payment.present? %>
|
||||
<%= link_to "Linked Payment", ipn.payment %>
|
||||
<% else %>
|
||||
<%= link_to "Try to link email '#{ipn.payer_email}' at membership level '#{ipn.payment_gross.to_i}'", link_ipn_path(ipn) %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= link_to "Details", ipn %></td>
|
||||
<td><%= link_to "Validate", validate_ipn_path(ipn) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
123
app/views/ipns/new.html.erb
Normal file
123
app/views/ipns/new.html.erb
Normal file
|
@ -0,0 +1,123 @@
|
|||
<%= form_tag('/ipns') do |f| %>
|
||||
|
||||
<style type="text/css">
|
||||
label {
|
||||
width: 10em;
|
||||
display: inline-block;}
|
||||
</style>
|
||||
|
||||
<div class="actions">
|
||||
<%= submit_tag %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :first_name %>
|
||||
<%= text_field_tag :first_name, "John" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :last_name %>
|
||||
<%= text_field_tag :last_name, "Smith" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payer_email %>
|
||||
<%= text_field_tag :payer_email, "jsmith@example.com" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :item_name %>
|
||||
<%= text_field_tag :item_name, "Associate Membership" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_gross %>
|
||||
<%= text_field_tag :payment_gross, "25.00" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :transaction_subject %>
|
||||
<%= text_field_tag :transaction_subject, "" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_date %>
|
||||
<%= text_field_tag :payment_date, "20:46:54 Jun 20, 2013 PDT" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :txn_type %>
|
||||
<%= text_field_tag :txn_type, "subscr_payment" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :subscr_id %>
|
||||
<%= text_field_tag :subscr_id, "I-1234567890" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :residence_country %>
|
||||
<%= text_field_tag :residence_country, "US" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :mc_currency %>
|
||||
<%= text_field_tag :mc_currency, "USD" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :business %>
|
||||
<%= text_field_tag :business, "hslfinances@gmail.com" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_type %>
|
||||
<%= text_field_tag :payment_type, "instant" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :protection_eligibility %>
|
||||
<%= text_field_tag :protection_eligibility, "Ineligible" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :verify_sign %>
|
||||
<%= text_field_tag :verify_sign, "12ru9021j9f21j90fj1290fj2910fj0219fj0" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payer_status %>
|
||||
<%= text_field_tag :payer_status, "verified" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :txn_id %>
|
||||
<%= text_field_tag :txn_id, "1234567890" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :receiver_email %>
|
||||
<%= text_field_tag :receiver_email, "hslfinances@gmail.com" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payer_id %>
|
||||
<%= text_field_tag :payer_id, "V812314914" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :receiver_id %>
|
||||
<%= text_field_tag :receiver_id, "V90R1280182" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_status %>
|
||||
<%= text_field_tag :payment_status, "Completed" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :payment_fee %>
|
||||
<%= text_field_tag :payment_fee, "0.85" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :mc_fee %>
|
||||
<%= text_field_tag :mc_fee, "0.85" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :mc_gross %>
|
||||
<%= text_field_tag :mc_gross, "25.00" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :charset %>
|
||||
<%= text_field_tag :charset, "windows-1252" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :notify_version %>
|
||||
<%= text_field_tag :notify_version, "3.7" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :ipn_track_id %>
|
||||
<%= text_field_tag :ipn_track_id, "9d3d032d9070" %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= submit_tag %>
|
||||
</div>
|
||||
<% end %>
|
18
app/views/ipns/show.html.erb
Normal file
18
app/views/ipns/show.html.erb
Normal file
|
@ -0,0 +1,18 @@
|
|||
<h2>IPN Details</h2>
|
||||
|
||||
<% @ipn.attributes.except("data","payment_id").each do |attr| %>
|
||||
<p>
|
||||
<b><%= attr.first.to_s %>:</b>
|
||||
<%= @ipn.attributes[attr.first] %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<% if @ipn.payment.present? %>
|
||||
<%= link_to "Linked Payment", @ipn.payment %>
|
||||
<% else %>
|
||||
<span class="alert">Couldn't link automatically. Please create payment manually or adjust the user account and try again to <%= link_to "link email '#{@ipn.payer_email}' at membership level '#{@ipn.payment_gross.to_i}'", link_ipn_path(@ipn) %>.</span>
|
||||
<% end %>
|
||||
|
||||
</p>
|
||||
|
||||
<%= link_to "Back", ipns_path %>
|
|
@ -8,17 +8,18 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<a href="/" title="Home"><img src="/assets/logo.png" id="logo" /></a>
|
||||
<a id="home_nav_link" href="/" title="Home"><img src="/assets/logo.png" id="logo" /></a>
|
||||
<%= link_to 'People', users_path if can? :read, User %>
|
||||
<%= link_to 'Access Cards', cards_path if can? :manage, Card %>
|
||||
<% if can? :manage, UserCertification %>
|
||||
<% if can? :create, UserCertification %>
|
||||
<%= link_to 'Cert Classes', certifications_path if can? :read, Certification %>
|
||||
<%= link_to 'User Certs', user_certifications_path if can? :create, UserCertification %>
|
||||
<% else %>
|
||||
<%= link_to 'Certifications', certifications_path if can? :read, Certification %>
|
||||
<% end %>
|
||||
<%= link_to 'Payments', payments_path if can? :read, Payment %>
|
||||
<%= link_to 'Computers', macs_path if user_signed_in? && (can? :read, Mac) %>
|
||||
<%= link_to 'Computers', macs_path if user_signed_in? || (can? :read, Mac) %>
|
||||
<%= link_to 'Settings', settings_path if can? :read, Setting %>
|
||||
<% if user_signed_in? then %><%= link_to 'Profile', edit_user_registration_path %><% end %>
|
||||
<%= link_to 'Logout', destroy_user_session_path, :method => :delete if user_signed_in? %>
|
||||
<%= link_to 'Login', new_user_session_path unless user_signed_in? %>
|
||||
|
@ -29,5 +30,6 @@
|
|||
<p class="alert"><%= raw(alert) %></p>
|
||||
<%= yield %>
|
||||
</div>
|
||||
<%= raw Setting.analytics_code if Setting.present? %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<%= form_for(@mac) do |f| %>
|
||||
<% if @mac.errors.any? %>
|
||||
<div id="error_explanation">
|
||||
<h2><%= pluralize(@mac.errors.count, "error") %> prohibited this Mac from being saved:</h2>
|
||||
<h2><%= pluralize(@mac.errors.count, "error") %> prohibited this MAC from being saved:</h2>
|
||||
|
||||
<ul>
|
||||
<% @mac.errors.full_messages.each do |msg| %>
|
||||
|
@ -17,7 +17,8 @@
|
|||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :mac %><br />
|
||||
<%= f.text_field :mac %>
|
||||
<%= f.text_field :mac, :value => (@mac.mac || @arp || nil) %>
|
||||
<% if @arp.present? %><br/><em>Autodetected from your IP of <%= @ip %></em><% end %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :note %><br />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h1>Editing Mac</h1>
|
||||
<h1>Editing MAC</h1>
|
||||
|
||||
<%= render 'form' %>
|
||||
|
||||
|
|
112
app/views/macs/history.html.erb
Normal file
112
app/views/macs/history.html.erb
Normal file
|
@ -0,0 +1,112 @@
|
|||
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="http://code.highcharts.com/highcharts.js"></script>
|
||||
<script type="text/javascript">
|
||||
graph_data = <%= raw @mac_log_graph.to_json %>;
|
||||
plot_band_start_hour = 16;
|
||||
plot_band_end_hour = 22;
|
||||
|
||||
$(function() {
|
||||
|
||||
$('#graph').highcharts({
|
||||
chart: {
|
||||
type: 'column',
|
||||
zoomType : 'x'
|
||||
},
|
||||
colors: [
|
||||
'#2980B9'
|
||||
],
|
||||
title: {
|
||||
style : { fontSize: '10px' },
|
||||
text: "Click and Drag to Zoom."
|
||||
},
|
||||
xAxis: {
|
||||
title : { text : "Days" },
|
||||
type : 'datetime',
|
||||
plotBands: generatePlotBands(graph_data[0][0], graph_data[graph_data.length-1][0]),
|
||||
labels : { align : "left" }
|
||||
},
|
||||
yAxis : {
|
||||
title : {
|
||||
text : "# of Computers"
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "Computers",
|
||||
data: graph_data
|
||||
},
|
||||
],
|
||||
plotOptions: {
|
||||
spline: {
|
||||
lineWidth: 4,
|
||||
marker: {
|
||||
enabled: false
|
||||
},
|
||||
pointInterval: 3600000, // one hour
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Highcharts.setOptions({
|
||||
global : {
|
||||
useUTC : false
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function generatePlotBands(start,end){
|
||||
plotBands = new Array();
|
||||
for (var d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) {
|
||||
// weekends
|
||||
if(d.getDay()%6==0){
|
||||
// highlight the whole day
|
||||
plotBands.push({
|
||||
color: '#eee',
|
||||
from: d.setHours(0),
|
||||
to: d.setHours(23)
|
||||
});
|
||||
// weekend hours
|
||||
plotBands.push({
|
||||
color: '#94C9EC',
|
||||
from: d.setHours(12),
|
||||
to: d.setHours(18)
|
||||
});
|
||||
}
|
||||
else if(d.getDay()==3){
|
||||
// special wednesday hours
|
||||
plotBands.push({
|
||||
color: '#94C9EC',
|
||||
from: d.setHours(12),
|
||||
to: d.setHours(plot_band_end_hour)
|
||||
});
|
||||
}
|
||||
else {
|
||||
// open hours
|
||||
plotBands.push({
|
||||
color: '#82DAC9',
|
||||
from: d.setHours(plot_band_start_hour),
|
||||
to: d.setHours(plot_band_end_hour)
|
||||
});
|
||||
}
|
||||
}
|
||||
return plotBands;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<h2>Daily Computer Graph</h2>
|
||||
<p><em>Note: these numbers are not absolute. They are calculated and adjusted on-the-fly and thus may vary depending on the query parameters.</em></p>
|
||||
<%= link_to 'Back to Computers', macs_path, :class => 'btn' %>
|
||||
<%= link_to 'Download JSON', macs_history_path+".json", :class => 'btn' %>
|
||||
<div id="graph" title="MAC Presence by Day" style="height: 400px; width: 100%;"></div>
|
||||
|
||||
<%= form_tag(nil, :method => :get) do %>
|
||||
<label>Start Date
|
||||
<input id="start" name="start" type="date" value="<%= @start_date.to_date.to_s %>" />
|
||||
</label>
|
||||
<label>End Date
|
||||
<input id="end" name="end" type="date" value="<%= @end_date.to_date.to_s %>" />
|
||||
</label>
|
||||
<%= submit_tag("Change Date", :name => nil, :class => 'btn') %>
|
||||
<% end %>
|
|
@ -1,5 +1,24 @@
|
|||
<% if can? :read_details, Mac %>
|
||||
<% if @mac_time_start_date.present? %>
|
||||
<b>Most Active Machine Last <%= distance_of_time_in_words DateTime.now, @mac_time_start_date %>:</b>
|
||||
<span title="<%= @most_active_mac.mac %><%= " - "+@most_active_mac.ip.to_s if can? :read_details, @most_active_mac %>">
|
||||
<%= @most_active_mac.user.name unless @most_active_mac.user.blank? %>
|
||||
<%= "("+@most_active_mac.note+")" unless @most_active_mac.note.blank? %>
|
||||
- <%= (@most_active.last[:time] / 1.hour).round %> hrs
|
||||
</span>
|
||||
<br/>
|
||||
<b>Runner Up:</b>
|
||||
<span title="<%= @runner_up_mac.mac %><%= " - "+@runner_up_mac.ip.to_s if can? :read_details, @runner_up_mac %>">
|
||||
<%= @runner_up_mac.user.name unless @runner_up_mac.user.blank? %>
|
||||
<%= "("+@runner_up_mac.note+")" unless @runner_up_mac.note.blank? %>
|
||||
- <%= (@runner_up.last[:time] / 1.hour).round %> hrs
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<h2>What machines are on our network?</h2>
|
||||
<%= link_to "New MAC registration", new_mac_path if can? :create, Mac %>
|
||||
<%= link_to "New MAC registration", new_mac_path, :class => 'btn' if can? :create, Mac %>
|
||||
<%= link_to 'Activity Graph', macs_history_path, :class => 'btn' if can? :read_details, Mac %>
|
||||
|
||||
<ul class="mac_list">
|
||||
<%
|
||||
|
@ -15,6 +34,10 @@ Rails.logger.info mac.inspect %>
|
|||
<% end %>
|
||||
</ul>
|
||||
|
||||
<% unless can? :read_details, Mac %>
|
||||
<p>To see more or register your own, login!</p>
|
||||
<% end %>
|
||||
|
||||
<% if can? :read_details, Mac %>
|
||||
<ul class="mac_list hidden">
|
||||
<% @hidden_macs.each do |mac| %>
|
||||
|
@ -29,7 +52,7 @@ Rails.logger.info mac.inspect %>
|
|||
<% end %>
|
||||
|
||||
<% if can? :manage, Mac %>
|
||||
<h3>All Macs</h3>
|
||||
<h3>All MACs</h3>
|
||||
<table>
|
||||
<% @all_macs.each do |mac| %>
|
||||
<tr <%= raw('class="hidden"') if mac.hidden? %>>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h1>New Mac</h1>
|
||||
<h1>New MAC</h1>
|
||||
|
||||
<%= render 'form' %>
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
Scanning...
|
||||
<% @log.each do |log| %>
|
||||
<% if can? :read_details, Mac
|
||||
@log.each do |log| %>
|
||||
<%= log.mac %> =
|
||||
<%= log.ip %><br/>
|
||||
<% end %>
|
||||
<% end
|
||||
end %>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b>Mac:</b>
|
||||
<b>MAC:</b>
|
||||
<%= @mac.mac %>
|
||||
</p>
|
||||
|
||||
|
@ -23,5 +23,16 @@
|
|||
<%= @mac.ip %>
|
||||
</p>
|
||||
|
||||
<% if can? :read, MacLog %>
|
||||
<p>
|
||||
<b>Recent Log Entries:</b>
|
||||
<ul>
|
||||
<% @mac_logs.each do |log| %>
|
||||
<li><%= log.created_at %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Edit', edit_mac_path(@mac) %> |
|
||||
<%= link_to 'Back', macs_path %>
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
<%= f.label :date, "Paid for month beginning" %><br />
|
||||
<%= f.date_select :date, :default => (DateTime.now - 1.month) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :amount %><br />
|
||||
<%= f.number_field :amount %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= f.submit %>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,121 @@
|
|||
<h1>Listing payments</h1>
|
||||
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="http://code.highcharts.com/highcharts.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
$( "#graph" ).dialog({
|
||||
autoOpen: false,
|
||||
height: 325,
|
||||
width: 525,
|
||||
modal: true,
|
||||
});
|
||||
$( "#graph-button" ).click(function() {
|
||||
$( "#graph" ).dialog( "open" );
|
||||
});
|
||||
|
||||
$('#graph').highcharts({
|
||||
chart: {
|
||||
type: 'area'
|
||||
},
|
||||
title: {
|
||||
style : { fontSize: '10px' },
|
||||
text: "Numbers for Most Recent Month Greater Than They Appear"
|
||||
},
|
||||
xAxis: {
|
||||
type: 'datetime'
|
||||
},
|
||||
yAxis : [{ // Primary yAxis
|
||||
title : {
|
||||
text: "Income"
|
||||
},
|
||||
labels: {
|
||||
format: '${value}'
|
||||
}
|
||||
}, { // Secondary yAxis
|
||||
title : {
|
||||
text: "Members",
|
||||
style: { color: '#8bbc21' }
|
||||
},
|
||||
labels: {
|
||||
format: '{value}',
|
||||
style: { color: '#8bbc21' }
|
||||
},
|
||||
opposite: true
|
||||
}],
|
||||
tooltip: {
|
||||
shared: true,
|
||||
xDateFormat: '%B %Y',
|
||||
formatter: function() {
|
||||
console.log(this);
|
||||
output = '<b>'+ Highcharts.dateFormat(this.points[0].series.tooltipOptions.xDateFormat,this.x) +'</b><br/>';
|
||||
total = 0;
|
||||
this.points.forEach(function(e,i,a){
|
||||
console.log(e);
|
||||
output += '<span style="color:'+e.series.color+'">'+e.series.name +'</span>: '+ (e.series.tooltipOptions.valuePrefix||"") + Highcharts.numberFormat(e.y,0,".",",") +'<br/>';
|
||||
if(i < 2){
|
||||
total += e.y;
|
||||
}
|
||||
});
|
||||
output += '<b>Total:</b> '+(this.points[0].series.tooltipOptions.valuePrefix||"")+ Highcharts.numberFormat(total,0,".",",");
|
||||
return output;
|
||||
}
|
||||
},
|
||||
plotOptions: {
|
||||
area: {
|
||||
stacking: 'normal',
|
||||
lineColor: '#666666',
|
||||
lineWidth: 1,
|
||||
marker: {
|
||||
lineWidth: 1,
|
||||
lineColor: '#666666'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: 'Basic',
|
||||
data: <%= @graph[:basic].to_json %>,
|
||||
tooltip: {
|
||||
valuePrefix: '$'
|
||||
}
|
||||
}, {
|
||||
name: 'Associate',
|
||||
data: <%= @graph[:associate].to_json %>,
|
||||
tooltip: {
|
||||
valuePrefix: '$'
|
||||
}
|
||||
}, {
|
||||
yAxis: 1,
|
||||
type: 'spline',
|
||||
name: 'Members',
|
||||
data: <%= @graph[:members].to_json %>
|
||||
}]
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="graph" title="Payments by Month" style="height: 250px; width: 500px; float: right;"></div>
|
||||
|
||||
|
||||
<h1>Listing payments <button id="graph-button" class="btn">View Graph</button></h1>
|
||||
|
||||
<p>
|
||||
<b>Create Payments:</b>
|
||||
<%= link_to 'Manually', new_payment_path %> |
|
||||
<%= link_to 'Batched CSV', paypal_csvs_path %> |
|
||||
<%= link_to 'IPN', ipns_path %>
|
||||
</p>
|
||||
|
||||
|
||||
<%= link_to 'New Payment', new_payment_path %>
|
||||
<br />
|
||||
<table>
|
||||
<tr>
|
||||
<th>Payee</th>
|
||||
<th>User</th>
|
||||
<th>Paid for month <br/>beginning</th>
|
||||
<th>Member level</th>
|
||||
<th>Last Payment</th>
|
||||
<th>Amount</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
|
@ -13,8 +123,11 @@
|
|||
|
||||
<% @payments.each do |payment| %>
|
||||
<tr>
|
||||
<td><%= link_to payment.user.name_with_payee_and_member_level, payment.user unless payment.user.blank? %></td>
|
||||
<td><%= payment.human_date %></td>
|
||||
<td><%= payment.user.payee unless payment.user.blank? %></td>
|
||||
<td><%= link_to payment.user.name, payment.user unless payment.user.blank? %></td>
|
||||
<td><%= payment.user.member_level_string unless payment.user.blank? %></td>
|
||||
<td><%= payment.date %></td>
|
||||
<td><%= payment.amount %></td>
|
||||
<td><%= link_to 'Details', payment %></td>
|
||||
<td><%= link_to 'Edit', edit_payment_path(payment) %></td>
|
||||
</tr>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<p>
|
||||
<b>User:</b>
|
||||
<%= @payment.user.name_with_payee_and_member_level unless @payment.user.blank? %>
|
||||
<%= link_to @payment.user.name_with_payee_and_member_level, @payment.user unless @payment.user.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -8,9 +8,19 @@
|
|||
<%= @payment.date %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Amount:</b>
|
||||
<%= @payment.amount %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Last Modified by:</b>
|
||||
<%= user = @users.find{|u| u.id == @payment.created_by}; link_to user.name, user unless user.blank? %>
|
||||
<% user = @users.find{|u| u.id == @payment.created_by} %>
|
||||
<% if user.blank? %>
|
||||
n/a
|
||||
<% else %>
|
||||
<%= link_to user.name, user %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -23,6 +33,18 @@
|
|||
<%= @payment.updated_at %>
|
||||
</p>
|
||||
|
||||
<% if @payment.ipn.present? %>
|
||||
<p>
|
||||
<%= link_to "Paid via PayPal (IPN)", @payment.ipn %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if @payment.paypal_csv.present? %>
|
||||
<p>
|
||||
<%= link_to "Paid via PayPal (CSV)", @payment.paypal_csv %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
<%= link_to 'Edit', edit_payment_path(@payment) %> |
|
||||
<%= link_to 'Destroy', @payment, :confirm => 'Are you sure you want to destroy this payment?', :method => :delete if can? :destroy, @payment %> |
|
||||
|
|
35
app/views/paypal_csvs/index.html.erb
Normal file
35
app/views/paypal_csvs/index.html.erb
Normal file
|
@ -0,0 +1,35 @@
|
|||
<h2>PayPal CSV Records</h2>
|
||||
<p>
|
||||
<%= link_to "Upload CSV", new_paypal_csv_path %>
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Name</th>
|
||||
<th>Item</th>
|
||||
<th>Amount</th>
|
||||
</tr>
|
||||
<% @paypal_csvs.sort_by(&:date_parsed).reverse!.each do |paypal_csv| %>
|
||||
<tr>
|
||||
<td><%= paypal_csv.date %></td>
|
||||
<td><%= paypal_csv._name %></td>
|
||||
<td><%= paypal_csv._item_title %></td>
|
||||
<td>
|
||||
<% if paypal_csv._gross.blank? %>
|
||||
<%= paypal_csv._type %>
|
||||
<% else %>
|
||||
<%= paypal_csv._gross %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td>
|
||||
<% if paypal_csv.payment.present? %>
|
||||
<%= link_to "Linked Payment", paypal_csv.payment %>
|
||||
<% else %>
|
||||
<%= link_to "Try to link email '#{paypal_csv._from_email_address}' at membership level '#{paypal_csv._gross.to_i}'", link_paypal_csv_path(paypal_csv) %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= link_to "Details", paypal_csv %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
15
app/views/paypal_csvs/new.html.erb
Normal file
15
app/views/paypal_csvs/new.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
|||
<style type="text/css">
|
||||
label {
|
||||
width: 10em;
|
||||
display: inline-block;}
|
||||
</style>
|
||||
|
||||
<%= form_tag('/paypal_csvs', :multipart => true) do |f| %>
|
||||
<div class="field">
|
||||
<%= label_tag :file %>
|
||||
<%= file_field_tag :file %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= submit_tag %>
|
||||
</div>
|
||||
<% end %>
|
17
app/views/paypal_csvs/show.html.erb
Normal file
17
app/views/paypal_csvs/show.html.erb
Normal file
|
@ -0,0 +1,17 @@
|
|||
<h2>PayPal CSV Item Details</h2>
|
||||
<% @paypal_csv.attributes.except("data","payment_id").each do |attr| %>
|
||||
<p>
|
||||
<b><%= attr.first.to_s %>:</b>
|
||||
<%= @paypal_csv.attributes[attr.first] %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<p>
|
||||
<% if @paypal_csv.payment.present? %>
|
||||
<%= link_to "Linked Payment", @paypal_csv.payment %>
|
||||
<% else %>
|
||||
<span class="alert">Couldn't link automatically. Please create payment manually or adjust the user account and try again to <%= link_to "link email '#{@paypal_csv._from_email_address}' at membership level '#{@paypal_csv._gross.to_i}'", link_paypal_csv_path(@paypal_csv) %>.</span>
|
||||
<% end %>
|
||||
|
||||
</p>
|
||||
<%= link_to "Back", paypal_csvs_path %>
|
18
app/views/settings/edit.html.erb
Normal file
18
app/views/settings/edit.html.erb
Normal file
|
@ -0,0 +1,18 @@
|
|||
<script src="http://code.jquery.com/jquery-migrate-1.2.1.js"></script>
|
||||
<script type="text/javascript" src="/wymeditor/wymeditor/jquery.wymeditor.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$('.wysiwyg').wymeditor();
|
||||
});
|
||||
</script>
|
||||
<%= form_tag(setting_path(@setting[:var]), :method => :put) do %>
|
||||
<h3>Editing <%= @setting[:var].titleize %></h3>
|
||||
<div class="field">
|
||||
<%= text_area_tag :value, @setting[:value], :cols => 50, :class => "wysiwyg" %><br/>
|
||||
</div>
|
||||
<em>Note: there is a /more_info page you can link to for wysiwyg purposes.</em>
|
||||
<div class="field">
|
||||
<%= submit_tag "Save", {:class => "wymupdate"} %><br/>
|
||||
<%= link_to "Back", settings_path %>
|
||||
</div>
|
||||
<% end %>
|
16
app/views/settings/index.html.erb
Normal file
16
app/views/settings/index.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<h2>Site-Wide Settings</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
<% @settings.each do |setting| %>
|
||||
<tr>
|
||||
<td><%= setting.first.titleize %></td>
|
||||
<td>"<%= setting.last.truncate(140) %>"</td>
|
||||
<% if can? :update, setting %>
|
||||
<td><%= link_to 'Edit', edit_setting_path(setting.first) %></td>
|
||||
<% end %>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
114
app/views/space_api/access.html.erb
Normal file
114
app/views/space_api/access.html.erb
Normal file
|
@ -0,0 +1,114 @@
|
|||
<h2 id="title">Door Control System</h2>
|
||||
<% if @output %>
|
||||
<p class="notice">
|
||||
<%= raw @output %>
|
||||
</p>
|
||||
<hr/>
|
||||
<% end %>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<style type="text/css">
|
||||
#status, #status span { display: inline-block; text-align: center; font-weight: bold; border-radius: 5px; }
|
||||
#status { width: 400px;}
|
||||
#status span { border: 1px solid black; width: 180px; padding: 5px; }
|
||||
#status span input { width: 100%; margin: 0.2em 0;}
|
||||
@media only screen and (max-width: 480px){
|
||||
#header a:not(#home_nav_link) { display: none; }
|
||||
#title {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 45px;
|
||||
}
|
||||
#status { width: 100%; }
|
||||
#status span { width: 45%; border: none; padding: 1%; margin: 1em 0; }
|
||||
#status span input { font-size: 1.8em; height: 2em;}
|
||||
}
|
||||
.open { background-color: green; }
|
||||
.closed { background-color: red; }
|
||||
.open input.unlock, .closed input.lock { background: #bbb; }
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function updateDoorStatus(){
|
||||
// grab status from space api
|
||||
$.get( "<%= space_api_path(:format => :json) %>", function( data ) {
|
||||
switch(data.status){
|
||||
case "doors_open=both":
|
||||
$( "#status" ).attr("class","open");
|
||||
$( "#door_1_status" ).attr("class","open");
|
||||
$( "#door_2_status" ).attr("class","open");
|
||||
break;
|
||||
case "doors_open=door1":
|
||||
$( "#status" ).attr("class","open");
|
||||
$( "#door_1_status" ).attr("class","open");
|
||||
$( "#door_2_status" ).attr("class","closed");
|
||||
break;
|
||||
case "doors_open=door2":
|
||||
$( "#status" ).attr("class","open");
|
||||
$( "#door_1_status" ).attr("class","closed");
|
||||
$( "#door_2_status" ).attr("class","open");
|
||||
break;
|
||||
case "doors_open=none":
|
||||
$( "#status" ).attr("class","closed");
|
||||
$( "#door_1_status" ).attr("class","closed");
|
||||
$( "#door_2_status" ).attr("class","closed");
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
function updateMacStatus(){
|
||||
$.get( "/macs.json", function( data ) {
|
||||
$("#mac_status").text(data.map(function(item){
|
||||
return item.name;
|
||||
}).join(", "));
|
||||
});
|
||||
}
|
||||
// run once
|
||||
updateDoorStatus();
|
||||
updateMacStatus();
|
||||
// and again every few seconds
|
||||
setInterval(updateDoorStatus, 10000);
|
||||
setInterval(updateDoorStatus, 60000);
|
||||
</script>
|
||||
<%= form_tag do %>
|
||||
<% unless user_signed_in? %>
|
||||
<p>
|
||||
<%= label_tag :user, "Email Address" %><br/>
|
||||
<%= text_field_tag :user %>
|
||||
</p>
|
||||
<p>
|
||||
<%= label_tag :pass, "Password" %><br/>
|
||||
<%= password_field_tag :pass %>
|
||||
</p>
|
||||
<% end %>
|
||||
<span id="status">
|
||||
<div>
|
||||
<span id="overall_status">
|
||||
Both<br/>
|
||||
<input type="submit" name="cmd" value="unlock" class="btn unlock">
|
||||
<input type="submit" name="cmd" value="lock" class="btn lock">
|
||||
</span>
|
||||
</div>
|
||||
<span id="door_1_status">
|
||||
Door 1<br/>
|
||||
<input type="submit" name="cmd" value="open-front" class="btn unlock">
|
||||
<input type="submit" name="cmd" value="unlock-front" class="btn unlock">
|
||||
<input type="submit" name="cmd" value="lock-front" class="btn lock">
|
||||
</span>
|
||||
<span id="door_2_status">
|
||||
Door 2<br/>
|
||||
<input type="submit" name="cmd" value="open-rear" class="btn unlock">
|
||||
<input type="submit" name="cmd" value="unlock-rear" class="btn unlock">
|
||||
<input type="submit" name="cmd" value="lock-rear" class="btn lock">
|
||||
</span>
|
||||
</span>
|
||||
<!--
|
||||
<h3>Alarm</h3>
|
||||
<p>
|
||||
<input type="submit" name="cmd" value="arm" class="btn">
|
||||
<input type="submit" name="cmd" value="disarm" class="btn">
|
||||
</p>
|
||||
-->
|
||||
<% end %>
|
||||
|
||||
<h3>Who's here?</h3>
|
||||
<p id="mac_status">
|
||||
</p>
|
11
app/views/space_api/index.html.erb
Normal file
11
app/views/space_api/index.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<h2>Space Status API
|
||||
<%= link_to 'JSON', space_api_path( :format => :json ), :class => 'btn' %>
|
||||
</h2>
|
||||
|
||||
<dl>
|
||||
<% @json.each do |key,value| %>
|
||||
<dt><%= key.humanize.capitalize %>:</dt>
|
||||
<dd><%= value %></dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
|
7
app/views/statistics/_index.html.erb
Normal file
7
app/views/statistics/_index.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<h2>Your Statistical Data</h2>
|
||||
<em>Data is power, and you've got the most: this system is programmed such that nobody else can see the graphs below but you! Use the JSON dumps to make something cool!</em>
|
||||
|
||||
<ul>
|
||||
<li><%= link_to 'MAC Address Data', mac_statistics_path %></li>
|
||||
<li><%= link_to 'Card Access Data', door_statistics_path %></li>
|
||||
</ul>
|
52
app/views/statistics/door_log.html.erb
Normal file
52
app/views/statistics/door_log.html.erb
Normal file
|
@ -0,0 +1,52 @@
|
|||
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="http://code.highcharts.com/highcharts.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
$('#graph').highcharts({
|
||||
chart: {
|
||||
type: 'column',
|
||||
zoomType : 'x'
|
||||
},
|
||||
title: {
|
||||
style : { fontSize: '10px' },
|
||||
text: "Click and Drag to Zoom."
|
||||
},
|
||||
xAxis: {
|
||||
title : { text : "Days" },
|
||||
type : 'datetime'
|
||||
},
|
||||
yAxis : {
|
||||
title : {
|
||||
text : "Accesses"
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: "Accesses",
|
||||
data: <%= raw @door_log_graph.to_json %>
|
||||
}]
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<h2>Your Card Access Data</h2>
|
||||
<%= link_to 'Download JSON', door_statistics_path+".json", :class => 'btn' %>
|
||||
<div id="graph" title="MAC Presence by Day" style="height: 250px; width: 500px; float: right;"></div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Action</th>
|
||||
<th>Card # (hex)</th>
|
||||
</tr>
|
||||
<% @door_logs.each do |log| %>
|
||||
<tr>
|
||||
<td><%= log.created_at %></td>
|
||||
<td><%= log.key %></td>
|
||||
<td><%= log.data.to_s(16) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
1
app/views/statistics/index.html.erb
Normal file
1
app/views/statistics/index.html.erb
Normal file
|
@ -0,0 +1 @@
|
|||
<%= render 'index' %>
|
60
app/views/statistics/mac_log.html.erb
Normal file
60
app/views/statistics/mac_log.html.erb
Normal file
|
@ -0,0 +1,60 @@
|
|||
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
|
||||
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
|
||||
<script src="http://code.highcharts.com/highcharts.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
$('#graph').highcharts({
|
||||
chart: {
|
||||
type: 'column',
|
||||
zoomType : 'x'
|
||||
},
|
||||
title: {
|
||||
style : { fontSize: '10px' },
|
||||
text: "Click and Drag to Zoom, Click the Legend to Turn Off Items."
|
||||
},
|
||||
xAxis: {
|
||||
title : { text : "Days" },
|
||||
type : 'datetime'
|
||||
},
|
||||
yAxis : {
|
||||
title : {
|
||||
text : "Hours"
|
||||
}
|
||||
},
|
||||
series: [
|
||||
<% @mac_log_graph.each do |mac, graph, element| %>
|
||||
{
|
||||
name: "<%= raw mac %>",
|
||||
data: <%= raw graph.to_json %>
|
||||
},
|
||||
<% end %>
|
||||
],
|
||||
tooltip : { valueSuffix : " hrs" }
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<h2>Your Mac Address Data</h2>
|
||||
<%= link_to 'Download JSON', mac_statistics_path+".json", :class => 'btn' %>
|
||||
<div id="graph" title="MAC Presence by Day" style="height: 250px; width: 500px; float: right;"></div>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Action</th>
|
||||
<th>MAC</th>
|
||||
<th>IP</th>
|
||||
</tr>
|
||||
<% @mac_logs.each do |log| %>
|
||||
<tr>
|
||||
<td><%= log.created_at %></td>
|
||||
<td><%= log.action %></td>
|
||||
<td><%= log.mac %></td>
|
||||
<td><%= log.ip %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
|
@ -11,13 +11,14 @@
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<% @user_certification.user_id = params[:user] if params[:user].present? %>
|
||||
<div class="field">
|
||||
<%= f.label :user_id, "User" %><br />
|
||||
<%= collection_select(:user_certification, :user_id, @users, :id, :name) %>
|
||||
<%= collection_select(:user_certification, :user_id, @users, :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :certification_id, "Certification" %><br />
|
||||
<%= collection_select(:user_certification, :certification_id, @certifications, :id, :name) %>
|
||||
<%= collection_select(:user_certification, :certification_id, @certifications, :id, :name, :include_blank => true) %>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<%= f.submit %>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<h1>User Certifications</h1>
|
||||
|
||||
<%= link_to 'New User Certification', new_user_certification_path %>
|
||||
<%= link_to 'New User Certification', new_user_certification_path if can? :create, UserCertification %>
|
||||
|
||||
<% @grouped_user_certs.sort.each do |cert, user_certifications| %>
|
||||
<dl class="collapsible">
|
||||
<dt><%= cert.name %></dt>
|
||||
<% user_certifications.sort{|a,b| a.user.name <=> b.user.name}.each do |user_certification| %>
|
||||
<% user_certifications.sort{|a,b| a.user_name <=> b.user_name}.each do |user_certification| %>
|
||||
<dd>
|
||||
<%= link_to user_certification.user.name, user_certification %>
|
||||
<%= link_to user_certification.user_name, user_certification %>
|
||||
</dd>
|
||||
<% end %>
|
||||
</dl>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<p>
|
||||
<b>User:</b>
|
||||
<%= @user_certification.user.name %>
|
||||
<%= link_to @user_certification.user.name, @user_certification.user %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -14,7 +14,12 @@
|
|||
</p>
|
||||
|
||||
<p>
|
||||
<b>Updated:</b> by <%= link_to @updated_by.name, @updated_by unless @updated_by.blank? %>
|
||||
<b>Updated:</b> by
|
||||
<% if @updated_by.blank? %>
|
||||
#<%= @user_certification.updated_by ||= "nil" %>
|
||||
<% else %>
|
||||
<%= link_to @updated_by.name, @updated_by %>
|
||||
<% end %>
|
||||
at <%= @user_certification.updated_at %>
|
||||
</p>
|
||||
|
||||
|
|
15
app/views/user_mailer/email.html.erb
Normal file
15
app/views/user_mailer/email.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
||||
</head>
|
||||
<body>
|
||||
<p><b>From:</b> <%= link_to @from_user.name, user_url(@from_user) %></p>
|
||||
<p>
|
||||
<%= simple_format @body %>
|
||||
</p>
|
||||
<p>
|
||||
<i>To reply, visit <%= link_to @url, @url %></i> .
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -4,7 +4,7 @@ Please contact them at <%= @user.email %><%= " or "+@user.phone.to_s unless @use
|
|||
new user orientation, waiver, welcome, payment help, etc.
|
||||
|
||||
User Details: <%= link_to @url+user_path(@user), @url+user_path(@user) %>
|
||||
Member Level: <%= simple_format @user.member_level %>
|
||||
Member Level: <%= simple_format @user.member_level_string %>
|
||||
|
||||
What skills, knowledge and experience do you bring to the community?
|
||||
<%= simple_format @user.current_skills %>
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
<div class="field">
|
||||
<%= f.label :email %><br />
|
||||
<%= f.email_field :email %>
|
||||
<%= f.check_box :email_visible %>
|
||||
<%= f.label :email_visible, "Show Email to All Members?" %>
|
||||
</div>
|
||||
<% if @user.id.blank? || !params[:password].nil? %>
|
||||
<div class="field">
|
||||
|
@ -38,6 +40,22 @@
|
|||
<a href="?password=edit">Change Password</a>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="field">
|
||||
<%= f.label :phone %><br />
|
||||
<%= f.text_field :phone %>
|
||||
<%= f.check_box :phone_visible %>
|
||||
<%= f.label :phone_visible, "Show Phone to All Members?" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :twitter_url %>
|
||||
<%= f.text_field :twitter_url, :placeholder => "https://twitter.com/heatsynclabs" %><br/>
|
||||
<%= f.label :facebook_url %>
|
||||
<%= f.text_field :facebook_url, :placeholder => "https://www.facebook.com/HeatSyncLabs" %><br/>
|
||||
<%= f.label :github_url %>
|
||||
<%= f.text_field :github_url, :placeholder => "https://github.com/heatsynclabs" %><br/>
|
||||
<%= f.label :website_url %>
|
||||
<%= f.text_field :website_url, :placeholder => "http://www.heatsynclabs.org" %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :waiver %><br />
|
||||
<%= f.date_select :waiver, :include_blank => 'true', :default => 'nil' %>
|
||||
|
@ -69,10 +87,6 @@
|
|||
<%= f.label :payee %><br />
|
||||
<%= f.text_field :payee%>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :phone %><br />
|
||||
<%= f.text_field :phone %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :current_skills, "What skills, knowledge and experience do you bring to the community?" %><br />
|
||||
<%= f.text_area :current_skills %>
|
||||
|
@ -85,6 +99,10 @@
|
|||
<%= f.label :marketing_source, "How'd you find out about HeatSync?" %><br />
|
||||
<%= f.text_area :marketing_source %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :exit_reason, "Reason for Leaving" %><br />
|
||||
<%= f.text_area :exit_reason %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= f.label :instructor, "Instructor?" %><br />
|
||||
<%= f.check_box :instructor %>
|
||||
|
|
95
app/views/users/_user_summary.html.erb
Normal file
95
app/views/users/_user_summary.html.erb
Normal file
|
@ -0,0 +1,95 @@
|
|||
<% user ||= @user #unless @user.blank? %>
|
||||
|
||||
<p>
|
||||
<b>Name:</b>
|
||||
<%= user.name %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Email:</b>
|
||||
<%= user.email %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Orientation?</b>
|
||||
<%= user.orientation.strftime("%B %d %Y") unless user.orientation.blank? %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<p>
|
||||
<b>Waiver?</b>
|
||||
<%= user.waiver.strftime("%B %d %Y") unless user.waiver.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Current Member?</b>
|
||||
<%= raw(user.member_status_symbol) %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Desired Member Level:</b>
|
||||
<%= user.member_level %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Payment Method:</b>
|
||||
<%= user.payment_method %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Payee:</b>
|
||||
<%= user.payee %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Phone:</b>
|
||||
<%= user.phone %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<b>Current Skills:</b>
|
||||
<%= simple_format user.current_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Desired Skills:</b>
|
||||
<%= simple_format user.desired_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Card:</b>
|
||||
<% if current_user.admin? then %>
|
||||
<% user.cards.each do |c| %>
|
||||
<%= link_to c.card_number, c %><%= "," unless c == user.cards.last %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= unless user.cards.blank? then raw("✓") end %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<b>Certifications:</b>
|
||||
<ul>
|
||||
<% user.certifications.each do |certification| %>
|
||||
<li><%= link_to certification.name, certification %></li>
|
||||
<% end %>
|
||||
<% if user.certifications.blank? %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Payments:</b>
|
||||
<ul>
|
||||
<% user.payments.each do |payment| %>
|
||||
<li><%= payment.date %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Created:</b>
|
||||
<%= user.created_at %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Last signed in:</b>
|
||||
<%= user.current_sign_in_at %>
|
||||
</p>
|
||||
<% end %>
|
139
app/views/users/activity.html.erb
Normal file
139
app/views/users/activity.html.erb
Normal file
|
@ -0,0 +1,139 @@
|
|||
<h1>Member Onboarding/Activity</h1>
|
||||
<a href="#new_users">New Users</a> |
|
||||
<a href="#members_without_cards">Members Without Cards</a> |
|
||||
<a href="#logins">Logins</a> |
|
||||
<a href="#zombies">Never-Logged-In Members</a>
|
||||
|
||||
|
||||
<h2><a name="new_users"></a>New Users</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Member Level</th>
|
||||
<th>Account Created</th>
|
||||
<th>Waiver</th>
|
||||
<th>Orientation</th>
|
||||
<th>Payment</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<% if !@new_users.blank? %>
|
||||
<% @new_users.sort_by(&:created_at).reverse!.each do |user| %>
|
||||
<tr<%= " class='hidden'" if user.hidden? %>>
|
||||
<td><%= link_to user.name, user %></td>
|
||||
<td><%= user.member_level_string %></td>
|
||||
<td><% if user.created_at.present? %>
|
||||
<%= distance_of_time_in_words(DateTime.now, user.created_at.to_date)+" ago" %>
|
||||
<% else %>
|
||||
<span class="alert">×</span>
|
||||
<% end %></td>
|
||||
<td><% if user.waiver.present? %>
|
||||
<%= distance_of_time_in_words(DateTime.now, user.waiver.to_date)+" ago" %>
|
||||
<% else %>
|
||||
<span class="alert">×</span>
|
||||
<% end %></td>
|
||||
<td><% if user.orientation.present? %>
|
||||
<%= distance_of_time_in_words(DateTime.now, user.orientation.to_date)+" ago" %>
|
||||
<% else %>
|
||||
<span class="alert">×</span>
|
||||
<% end %></td>
|
||||
<td><% if user.payments.present? %>
|
||||
<%= distance_of_time_in_words(Date.today, user.payments.maximum(:date))+" ago" %>
|
||||
<% else %>
|
||||
<span class="alert">×</span>
|
||||
<% end %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<h2><a name="members_without_cards"></a>Basic+ Members Without Cards</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Account Created</th>
|
||||
<th>Member Level</th>
|
||||
<th>Payment</th>
|
||||
<th>Card</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<% if !@cardless_users.blank? %>
|
||||
<% @cardless_users.sort_by(&:created_at).reverse!.each do |user| %>
|
||||
<tr<%= " class='hidden'" if user.hidden? %>>
|
||||
<td><%= link_to user.name, user %></td>
|
||||
<td><%= distance_of_time_in_words DateTime.now, user.created_at %> ago</td>
|
||||
<td><%= user.member_level_string %></td>
|
||||
<td><% if user.payments.present? %>
|
||||
<% last_payment = user.payments.maximum(:date) %>
|
||||
<% if Date.today-last_payment > 60 %>
|
||||
<span class="alert">
|
||||
<% else %>
|
||||
<span class="notice">
|
||||
<% end %>
|
||||
<%= distance_of_time_in_words(Date.today, user.payments.maximum(:date))+" ago" %>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="alert">×</span>
|
||||
<% end %></td>
|
||||
<td><% if user.cards.present? %>
|
||||
<span class="notice">✓</span>
|
||||
<% else %>
|
||||
<span class="alert">×</span>
|
||||
<% end %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
|
||||
<h2><a name="logins"></a>Logins</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Current Sign In</th>
|
||||
<th>Last Sign In</th>
|
||||
<th>Sign In Count</th>
|
||||
<th>Account Created</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<% if !@user_logins.blank? %>
|
||||
<% @user_logins.sort_by(&:current_sign_in_at).reverse!.each do |user| %>
|
||||
<tr<%= " class='hidden'" if user.hidden? %>>
|
||||
<td><%= link_to user.name, user %></td>
|
||||
<td><%= distance_of_time_in_words DateTime.now, user.current_sign_in_at %> ago</td>
|
||||
<td>
|
||||
<% if user.last_sign_in_at != user.current_sign_in_at %>
|
||||
<%= distance_of_time_in_words DateTime.now, user.last_sign_in_at %> ago
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= user.sign_in_count %> times</td>
|
||||
<td><%= distance_of_time_in_words DateTime.now, user.created_at %> ago</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
|
||||
<h2><a name="zombies"></a>Never-Logged-In Members</h2>
|
||||
<em>Excluding non-members</em>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Member Level</th>
|
||||
<th>Account Created</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<% if !@zombie_members.blank? %>
|
||||
<% @zombie_members.sort_by(&:created_at).reverse!.each do |user| %>
|
||||
<tr<%= " class='hidden'" if user.hidden? %>>
|
||||
<td><%= link_to user.name, user %></td>
|
||||
<td><%= user.member_level_string %></td>
|
||||
<td><%= distance_of_time_in_words DateTime.now, user.created_at %> ago</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
|
14
app/views/users/compose_email.html.erb
Normal file
14
app/views/users/compose_email.html.erb
Normal file
|
@ -0,0 +1,14 @@
|
|||
<h3>Send Email to <%= @user.name %></h3>
|
||||
<%= form_tag do %>
|
||||
<div class="field">
|
||||
<%= label_tag :subject %><br/>
|
||||
<%= text_field_tag :subject, @subject, :size => 52 %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= label_tag :body %><br/>
|
||||
<%= text_area_tag :body, @body, :cols => 40 %>
|
||||
</div>
|
||||
<div class="field">
|
||||
<%= submit_tag "Send", :class => "btn" %>
|
||||
</div>
|
||||
<% end %>
|
65
app/views/users/inactive.html.erb
Normal file
65
app/views/users/inactive.html.erb
Normal file
|
@ -0,0 +1,65 @@
|
|||
<h1>Inactive Users</h1>
|
||||
|
||||
<table>
|
||||
<col />
|
||||
<col />
|
||||
<% if current_user.admin? then %><col /><% end %>
|
||||
<col />
|
||||
<% if current_user.admin? %><col />
|
||||
<col class="col_highlight" /><% end %>
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>Name</th>
|
||||
<% if current_user.admin? then %><th>Email</th><% end %>
|
||||
<th>Certifications</th>
|
||||
<% if current_user.admin? then %>
|
||||
<th>Orientation?</th>
|
||||
<% end %>
|
||||
<th>Card?</th>
|
||||
<th>Pmt Method</th>
|
||||
<th>Desired Level</th>
|
||||
<th>Last Payment</th>
|
||||
<th>Joined</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<% if !@users.blank? %>
|
||||
<% @users.each do |user| %>
|
||||
<tr<%= " class='hidden'" if user.hidden? %>>
|
||||
<td><%= image_tag user.gravatar_url(:default => "http://members.heatsynclabs.org/assets/nil.png"), :class => :avatar %></td>
|
||||
<td><%= link_to user.name, user %></td>
|
||||
<% if current_user.admin? then %><td><%= user.email %></td><% end %>
|
||||
<td><% user.certifications.each do |c| %>
|
||||
<%= link_to c.name, c %><%= "," unless c.id == user.certifications.last.id %>
|
||||
<% end %></td>
|
||||
<% if current_user.admin? then %><td>
|
||||
<%= unless user.orientation.blank? then raw("<span class='hoverinfo' title='"+user.orientation.strftime("%B %d %Y")+"'>✓</span>") end %>
|
||||
</td><% end %>
|
||||
<td><%= unless user.cards.blank? then raw("<span class='iconinfo'>✓</span>") end %></td>
|
||||
<td><%= user.payment_method %></td>
|
||||
<td><%= user.member_level %></td>
|
||||
<td><% delinquency = user.delinquency %>
|
||||
<% if delinquency == 9999 %>
|
||||
No Payments
|
||||
<% else %>
|
||||
<%= (delinquency/30).to_s+" mo. ago" %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= user.created_at.to_date %></td>
|
||||
<td><%= link_to 'Edit', edit_user_path(user) if can? :update, user %></td>
|
||||
<td><%= link_to 'Destroy', user, :confirm => 'Are you sure? WARNING: THIS DOES NOT REMOVE THE USER FROM THE DOOR SYSTEM! DISABLE THEM FIRST.', :method => :delete if can? :destroy, user %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<% if current_user.orientation.blank? then %>
|
||||
<p class="alert">There's a lot more to see here, but our records show you haven't completed the new member orientation yet. If that's incorrect, please contact a volunteer.</p>
|
||||
<% end %>
|
||||
|
||||
<br />
|
|
@ -1,32 +1,48 @@
|
|||
<h1>HeatSync People</h1>
|
||||
|
||||
<% if can? :create, User %>
|
||||
<%= link_to 'New User', new_user_path %>
|
||||
<%= link_to 'New User', new_user_path %> |
|
||||
<% end %>
|
||||
<% if can? :manage, User %>
|
||||
<%= link_to 'Merge Users', users_merge_path %> |
|
||||
<% end %>
|
||||
<% if current_user.admin? %>
|
||||
<%= link_to 'Inactive Users', users_inactive_path %> |
|
||||
<%= link_to 'Recent Activity', users_activity_path %> |
|
||||
<% end %>
|
||||
<%= link_to 'New Members Report', users_new_member_report_path %>
|
||||
|
||||
<% @certifications = Certification.all.sort_by(&:id) %>
|
||||
<table>
|
||||
<col />
|
||||
<col />
|
||||
<% if current_user.admin? then %><col /><% end %>
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
<% if current_user.admin? %><col />
|
||||
<col class="col_highlight" /><% end %>
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
<col />
|
||||
<col class="col_highlight" />
|
||||
<% col_count = 0 %>
|
||||
<% @certifications.each do |c| %>
|
||||
<col <% if col_count.even? %>class="col_highlight"<% end %> />
|
||||
<% col_count = col_count + 1 %>
|
||||
<% end %>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><a href="?sort=name">Name</a></th>
|
||||
<th><a href="?sort=member">Member?</a></th>
|
||||
<% if current_user.admin? then %><th><a href="?sort=email">Email</a></th><% end %>
|
||||
<th><a href="?sort=certifications">Certifications</a></th>
|
||||
<% if current_user.admin? then %>
|
||||
<th><a href="?sort=orientation">Orientation?</a></th>
|
||||
<% end %>
|
||||
<th><a href="?sort=waiver">Waiver?</a></th>
|
||||
<th><a href="?sort=member">Member?</a></th>
|
||||
<th><a href="?sort=card">Card?</a></th>
|
||||
<th><a href="?sort=instructor">Instructor?</a></th>
|
||||
<% if current_user.admin? then %><th><a href="?sort=admin">Admin?</a></th><% end %>
|
||||
<% @certifications.each do |c| %>
|
||||
<th><a href="?sort=cert&cert=<%= c.id %>"><%= c.name %></a></th>
|
||||
<% end %>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
@ -36,18 +52,24 @@
|
|||
<tr<%= " class='hidden'" if user.hidden? %>>
|
||||
<td><%= image_tag user.gravatar_url(:default => "http://members.heatsynclabs.org/assets/nil.png"), :class => :avatar %></td>
|
||||
<td><%= link_to user.name, user %></td>
|
||||
<td><%= raw(user.member_status_symbol) %></td>
|
||||
<% if current_user.admin? then %><td><%= user.email %></td><% end %>
|
||||
<td><% user.certifications.each do |c| %>
|
||||
<%= link_to c.name, c %><%= "," unless c.id == user.certifications.last.id %>
|
||||
<% end %></td>
|
||||
<% if current_user.admin? then %><td>
|
||||
<%= unless user.orientation.blank? then raw("<span class='hoverinfo' title='"+user.orientation.strftime("%B %d %Y")+"'>✓</span>") end %>
|
||||
</td><% end %>
|
||||
<td><%= unless user.waiver.blank? then raw("<span class='hoverinfo' title='"+user.waiver.strftime("%B %d %Y")+"'>✓</span>") end %></td>
|
||||
<td><%= raw(user.member_status_symbol) %></td>
|
||||
<td><%= unless user.cards.blank? then raw("<span class='iconinfo'>✓</span>") end %></td>
|
||||
<td><%= if user.instructor? then raw("<span class='iconinfo'>✓</a>") end %></td>
|
||||
<% if current_user.admin? then %><td><%= if user.admin? then raw("<span class='iconinfo'>✓</a>") end %></td><% end %>
|
||||
<% @certifications.each do |c| %>
|
||||
<td>
|
||||
<% user.user_certifications.each do |u| %>
|
||||
<% if u.certification_id == c.id %>
|
||||
<%= link_to raw("<span class='iconinfo'>✓</span>"), u %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
<% end %>
|
||||
<td><%= link_to 'Edit', edit_user_path(user) if can? :update, user %></td>
|
||||
<td><%= link_to 'Destroy', user, :confirm => 'Are you sure? WARNING: THIS DOES NOT REMOVE THE USER FROM THE DOOR SYSTEM! DISABLE THEM FIRST.', :method => :delete if can? :destroy, user %></td>
|
||||
</tr>
|
||||
|
|
48
app/views/users/merge_view.html.erb
Normal file
48
app/views/users/merge_view.html.erb
Normal file
|
@ -0,0 +1,48 @@
|
|||
<style type="text/css">
|
||||
#user_to_merge_details, #user_to_keep_details,
|
||||
#user_to_merge_details p, #user_to_keep_details p {
|
||||
font-size: 12px;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Merging users</h1>
|
||||
|
||||
<%= form_tag('/users/merge', :method => :post) do %>
|
||||
<b>Everything except the email, password, name, id, hidden, and blank values will be moved to the "user to keep" UNLESS there is a value already there. The "user to merge" will be deleted.</b>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="field">
|
||||
<%= label_tag :user_to_keep, "User to Keep" %><br />
|
||||
<%= collection_select(:user, :to_keep, @users, :id, :name_with_email_and_visibility, :include_blank => true) %>
|
||||
</div>
|
||||
<div id="user_to_keep_details"></div>
|
||||
</td>
|
||||
<td style="font-size: 16px">◀◀</td>
|
||||
<td>
|
||||
<div class="field">
|
||||
<%= label_tag :user_to_merge, "User to Merge" %><br />
|
||||
<%= collection_select(:user, :to_merge, @users, :id, :name_with_email_and_visibility, :include_blank => true) %>
|
||||
</div>
|
||||
<div id="user_to_merge_details"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr/>
|
||||
<div class="actions">
|
||||
<%= submit_tag "Merge" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= link_to 'Back', users_path %>
|
||||
|
||||
<script>
|
||||
$("#user_to_keep").change(function(event,handler){
|
||||
$("#user_to_keep_details").load("/user_summary/"+event.target.value);
|
||||
});
|
||||
$("#user_to_merge").change(function(event,handler){
|
||||
$("#user_to_merge_details").load("/user_summary/"+event.target.value);
|
||||
});
|
||||
</script>
|
24
app/views/users/new_member_report.html.erb
Normal file
24
app/views/users/new_member_report.html.erb
Normal file
|
@ -0,0 +1,24 @@
|
|||
<h1>New Members</h1>
|
||||
<% if !@new_users.blank? %>
|
||||
<% @new_users.sort_by(&:created_at).reverse!.group_by{|u| u.created_at.beginning_of_month}.each do |g| %>
|
||||
<h2><%= g.first.to_formatted_s(:month_and_year) %></h2>
|
||||
<% g.last.each do |user| %>
|
||||
<p><b><%= user.name %> - <%= user.member_level_string %></b></p>
|
||||
<p><b>What skills, knowledge and experience do you bring to the community?</b><br/>
|
||||
<%= user.current_skills %>
|
||||
</p>
|
||||
<p><b>
|
||||
What skills, knowledge and experiences are you looking for in HeatSync?
|
||||
</b><br/>
|
||||
<%= user.desired_skills %>
|
||||
</p>
|
||||
<p><b>
|
||||
How'd you find out about HeatSync?
|
||||
</b><br/>
|
||||
<%= user.marketing_source %>
|
||||
</p>
|
||||
<p> </p>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
|
@ -1,31 +1,38 @@
|
|||
<%= image_tag @user.gravatar_url(:default => "http://members.heatsynclabs.org/assets/nil.png") %>
|
||||
|
||||
<p>
|
||||
<b>Name:</b>
|
||||
<h2>
|
||||
<%= image_tag @user.gravatar_url(:default => "http://members.heatsynclabs.org/assets/nil.png"), :class => 'avatar-large' %>
|
||||
<%= @user.name %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Waiver?</b>
|
||||
<%= @user.waiver.strftime("%B %d %Y") unless @user.waiver.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Current Member?</b>
|
||||
<%= raw(@user.member_status_symbol) %>
|
||||
</p>
|
||||
<%= link_to image_tag('/twitter.png', :class => 'social-icon', :title => "Twitter"), @user.twitter_url, :class => 'social-link' if @user.twitter_url.present? %>
|
||||
<%= link_to image_tag('/facebook.png', :class => 'social-icon', :title => "Facebook"), @user.facebook_url, :class => 'social-link' if @user.facebook_url.present? %>
|
||||
<%= link_to image_tag('/github.png', :class => 'social-icon', :title => "Github"), @user.github_url, :class => 'social-link' if @user.github_url.present? %>
|
||||
<%= link_to image_tag('/website.png', :class => 'social-icon', :title => "Website"), @user.website_url, :class => 'social-link' if @user.website_url.present? %>
|
||||
<%= link_to "Email User", user_compose_email_path(@user), :class => 'btn' %>
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
<b>Instructor?</b>
|
||||
<%= @user.instructor? %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? || @user.email_visible %>
|
||||
<p>
|
||||
<b>Email:</b>
|
||||
<%= @user.email %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.admin? || @user.phone_visible %>
|
||||
<p>
|
||||
<b>Phone:</b>
|
||||
<%= @user.phone %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<b>Current Skills:</b>
|
||||
<%= simple_format @user.current_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Desired Skills:</b>
|
||||
<%= simple_format @user.desired_skills %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Email:</b>
|
||||
<%= @user.email %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Orientation?</b>
|
||||
<%= @user.orientation.strftime("%B %d %Y") unless @user.orientation.blank? %>
|
||||
|
@ -44,7 +51,7 @@
|
|||
</p>
|
||||
<p>
|
||||
<b>Desired Member Level:</b>
|
||||
<%= @user.member_level %>
|
||||
<%= @user.member_level_string %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Payment Method:</b>
|
||||
|
@ -54,54 +61,76 @@
|
|||
<b>Payee:</b>
|
||||
<%= @user.payee %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Phone:</b>
|
||||
<%= @user.phone %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<b>Current Skills:</b>
|
||||
<%= simple_format @user.current_skills %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Desired Skills:</b>
|
||||
<%= simple_format @user.desired_skills %>
|
||||
</p>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Found HeatSync via:</b>
|
||||
<%= simple_format @user.marketing_source %>
|
||||
</p>
|
||||
<p>
|
||||
<b>Left HeatSync because:</b>
|
||||
<%= simple_format @user.exit_reason %>
|
||||
</p>
|
||||
<% end %>
|
||||
<p>
|
||||
<b>Card:</b>
|
||||
<% if current_user.admin? then %>
|
||||
<% @user.cards.each do |c| %>
|
||||
<%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= unless @user.cards.blank? then raw("✓") end %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<b>Certifications:</b>
|
||||
<b>Certifications: </b><%= link_to "+ Add", (new_user_certification_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, UserCertification %>
|
||||
<ul>
|
||||
<% @user.certifications.each do |certification| %>
|
||||
<li><%= link_to certification.name, certification %></li>
|
||||
<% end %>
|
||||
<% if @user.certifications.blank? %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
<b>Payments:</b>
|
||||
<ul>
|
||||
<% @payments.each do |payment| %>
|
||||
<li><%= payment.date %></li>
|
||||
<b>Card: </b><%= link_to "+ Add", (new_card_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, Card %>
|
||||
<% if current_user.admin? then %>
|
||||
<ul>
|
||||
<% @user.cards.each do |c| %>
|
||||
<li><%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<%= unless @user.cards.blank? then raw("✓") end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<b>Computers: </b><%= link_to "+ Add", new_mac_path, :class => 'btn' if can? :create, Mac %>
|
||||
<ul>
|
||||
<% @user.macs.each do |mac| %>
|
||||
<li><%= link_to mac.mac, mac %></li>
|
||||
<% end %>
|
||||
<% if @user.macs.blank? %><li>n/a</li><% end %>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<% if current_user.admin? then %>
|
||||
<b>Payments:</b>
|
||||
<ul>
|
||||
<% @payments.each do |payment| %>
|
||||
<li><%= link_to payment.date, payment %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<b>Last Payment:</b>
|
||||
<% last_payment = @user.delinquency %>
|
||||
<% if last_payment < 30 %>
|
||||
Less than a month ago
|
||||
<% else %>
|
||||
<%= last_payment/30 %> months ago
|
||||
<% end %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Waiver?</b>
|
||||
<%= @user.waiver.strftime("%B %d %Y") unless @user.waiver.blank? %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Instructor?</b>
|
||||
<%= @user.instructor? %>
|
||||
</p>
|
||||
|
||||
|
||||
<% if current_user.admin? then %>
|
||||
<p>
|
||||
|
|
|
@ -37,7 +37,7 @@ module Dooraccess
|
|||
config.encoding = "utf-8"
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
config.filter_parameters += [:password]
|
||||
config.filter_parameters += [:password, :pass]
|
||||
|
||||
# Use SQL instead of Active Record's schema dumper when creating the database.
|
||||
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# SQLite version 3.x
|
||||
# gem install sqlite3
|
||||
#
|
||||
# Ensure the SQLite 3 gem is defined in your Gemfile
|
||||
# gem 'sqlite3'
|
||||
development:
|
||||
adapter: sqlite3
|
||||
database: db/development.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
# Do not set this db to the same as development or production.
|
||||
test:
|
||||
adapter: sqlite3
|
||||
database: db/test.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
production:
|
||||
adapter: sqlite3
|
||||
database: db/production.sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
# adapter: postgresql
|
||||
# encoding: unicode
|
||||
# database: members
|
||||
# pool: 5
|
||||
# username: postgres
|
||||
# password:
|
54
config/database.yml.example
Normal file
54
config/database.yml.example
Normal file
|
@ -0,0 +1,54 @@
|
|||
# SQLite version 3.x
|
||||
# gem install sqlite3
|
||||
#
|
||||
# Ensure the SQLite 3 gem is defined in your Gemfile
|
||||
# gem 'sqlite3'
|
||||
|
||||
# development:
|
||||
# adapter: sqlite3
|
||||
# database: db/development.sqlite3
|
||||
# pool: 5
|
||||
# timeout: 5000
|
||||
|
||||
development:
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
database: YOUR_DATABASE_development
|
||||
host: localhost
|
||||
pool: 5
|
||||
username: YOUR_USERNAME_HERE
|
||||
password: YOUR_PASSWORD_HERE
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
# Do not set this db to the same as development or production.
|
||||
|
||||
# test:
|
||||
# adapter: sqlite3
|
||||
# database: db/test.sqlite3
|
||||
# pool: 5
|
||||
# timeout: 5000
|
||||
|
||||
test:
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
database: YOUR_DATABASE_test
|
||||
host: localhost
|
||||
pool: 5
|
||||
username: YOUR_USERNAME_HERE
|
||||
password: YOUR_PASSWORD_HERE
|
||||
|
||||
# production:
|
||||
# adapter: sqlite3
|
||||
# database: db/production.sqlite3
|
||||
# pool: 5
|
||||
# timeout: 5000
|
||||
|
||||
production:
|
||||
adapter: postgresql
|
||||
encoding: unicode
|
||||
database: YOUR_DATABASE_production
|
||||
host: localhost
|
||||
pool: 5
|
||||
username: YOUR_USERNAME_HERE
|
||||
password: YOUR_PASSWORD_HERE
|
2
config/initializers/dates.rb
Normal file
2
config/initializers/dates.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
Date::DATE_FORMATS[:month_and_year] = "%B %Y"
|
||||
Time::DATE_FORMATS[:month_and_year] = "%B %Y"
|
47
config/initializers/default_settings.rb
Normal file
47
config/initializers/default_settings.rb
Normal file
|
@ -0,0 +1,47 @@
|
|||
@@default_settings = {
|
||||
:welcome_title => "Welcome to the Hackerspace Members Site",
|
||||
:welcome_body => "<p>We are a member-driven community workshop where you can learn, make cool stuff, meet other cool people, and make your city a better place to live!</p><p>You don't have to be a member to come visit, but if you're interested in volunteering or being a member, feel free to sign up here! For more information, <a href=\"/more_info\">Click Here</a>.</p>",
|
||||
:more_info_page => "No info here yet, bug a member about filling this part out!",
|
||||
:member_resources_inset => "No info here yet, bug a member about filling this part out!",
|
||||
:analytics_code => "<!-- insert analytics code here -->",
|
||||
:space_api_json_template => '{
|
||||
"api" : "0.12",
|
||||
"space" : "Your Hackerspace Name Here",
|
||||
"logo" : "http://example.com/logo.png",
|
||||
"lat": 0,
|
||||
"lon": -0,
|
||||
"icon":{
|
||||
"open": "http://example.com/open.png",
|
||||
"closed":"http://example.com/closed.png"
|
||||
},
|
||||
"url" : "http://example.com",
|
||||
"address" : "123 main st, city, state, country",
|
||||
"contact" : {
|
||||
"phone" : "",
|
||||
"irc" : "",
|
||||
"twitter" : "",
|
||||
"ml" : ""
|
||||
},
|
||||
"cam" : [""],
|
||||
"feeds" : [{"name" : "",
|
||||
"url" : ""},
|
||||
{"name" : "",
|
||||
"url" : ""}],
|
||||
"apis" : {
|
||||
"oac" : {
|
||||
"url" : "http://this-apps-url.example.com/door_access",
|
||||
"description" : "https://github.com/heatsynclabs/Open-Source-Access-Control-Web-Interface"
|
||||
},
|
||||
"pamela" : {
|
||||
"url" : "http://this-apps-url.example.com/macs.json",
|
||||
"description" : "https://github.com/heatsynclabs/Open-Source-Access-Control-Web-Interface"
|
||||
}
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
if ActiveRecord::Base.connection.tables.include?('settings') and !defined?(::Rake)
|
||||
@@default_settings.each do |key, value|
|
||||
Setting.save_default(key, value)
|
||||
end
|
||||
end
|
|
@ -103,7 +103,7 @@ Devise.setup do |config|
|
|||
|
||||
# ==> Configuration for :rememberable
|
||||
# The time the user will be remembered without asking for credentials again.
|
||||
# config.remember_for = 2.weeks
|
||||
config.remember_for = 1.month
|
||||
|
||||
# If true, extends the user's remember period when remembered via cookie.
|
||||
# config.extend_remember_period = false
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
# If you change this key, all old signed cookies will become invalid!
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
Dooraccess::Application.config.secret_token = 'd258ec483070c67d9e7ba7bb8b6b506a30fb38d0d95ac561ef603785f4639a688747a4adf872f627acae9b57f44f822a0c4dc2f2fd3d8e6135ad0b491f72751f'
|
||||
Dooraccess::Application.config.secret_token = YOUR_RANDOM_STRING_HERE
|
|
@ -1,7 +1,18 @@
|
|||
Dooraccess::Application.routes.draw do
|
||||
match 'ipns/import' => 'ipns#import', :as => :import_ipn
|
||||
resources :ipns
|
||||
match 'ipns/:id/link' => 'ipns#link', :as => :link_ipn
|
||||
match 'ipns/:id/validate' => 'ipns#validate', :as => :validate_ipn
|
||||
|
||||
resources :paypal_csvs
|
||||
match 'paypal_csvs/:id/link' => 'paypal_csvs#link', :as => :link_paypal_csv
|
||||
|
||||
resources :payments
|
||||
|
||||
match 'statistics' => 'statistics#index', :as => :statistics
|
||||
match 'statistics/mac_log' => 'statistics#mac_log', :as => :mac_statistics
|
||||
match 'statistics/door_log' => 'statistics#door_log', :as => :door_statistics
|
||||
|
||||
resources :user_certifications
|
||||
|
||||
resources :certifications
|
||||
|
@ -18,23 +29,39 @@ Dooraccess::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
resources :users
|
||||
match 'user_summary/:id' => 'users#user_summary' # User summary view
|
||||
match 'users/activity' => 'users#activity' # User activity
|
||||
match 'users/new_member_report' => 'users#new_member_report' # New member report (For emailing)
|
||||
match 'users/merge' => 'users#merge_view', :via => :get # Merge view
|
||||
match 'users/merge' => 'users#merge_action', :via => :post # Merge action
|
||||
match 'users/inactive' => 'users#inactive' # Inactive users report
|
||||
resources :users do
|
||||
get 'email' => 'users#compose_email', :as => "compose_email"
|
||||
post 'email' => 'users#send_email'
|
||||
end
|
||||
match 'users/create' => 'users#create', :via => :post # Use POST users/create instead of POST users to avoid devise conflict
|
||||
|
||||
match 'cards/upload_all' => 'cards#upload_all', :as => :upload_all
|
||||
resources :cards
|
||||
match 'cards/:id/upload' => 'cards#upload', :as => :upload
|
||||
|
||||
match 'space_api' => 'space_api#index', :as => :space_api
|
||||
match 'space_api/access' => 'space_api#access', :via => :get, :as => :space_api_access
|
||||
match 'space_api/access' => 'space_api#access_post', :via => :post
|
||||
|
||||
match 'door_logs' => 'door_logs#index', :as => :door_logs
|
||||
match 'door_logs/download' => 'door_logs#download', :as => :download
|
||||
match 'door_logs/auto_download' => 'door_logs#auto_download', :as => :auto_download
|
||||
|
||||
match 'macs/scan' => 'macs#scan'
|
||||
match 'macs/import' => 'macs#import'
|
||||
match 'macs/history' => 'macs#history'
|
||||
resources :macs
|
||||
|
||||
resources :mac_logs
|
||||
|
||||
resources :settings, :only => [:index, :edit, :update]
|
||||
|
||||
match 'more_info' => 'home#more_info'
|
||||
root :to => "home#index"
|
||||
|
||||
# The priority is based upon order of creation:
|
||||
|
|
24
db/migrate/20130824062334_create_ipns.rb
Normal file
24
db/migrate/20130824062334_create_ipns.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
class CreateIpns < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :ipns do |t|
|
||||
t.integer :payment_id
|
||||
t.text :data
|
||||
t.string :txn_id
|
||||
t.string :txn_type
|
||||
t.string :first_name
|
||||
t.string :last_name
|
||||
t.string :payer_business_name
|
||||
t.string :payer_email
|
||||
t.string :payer_id
|
||||
t.string :auth_amount
|
||||
t.string :payment_date
|
||||
t.string :payment_fee
|
||||
t.string :payment_gross
|
||||
t.string :payment_status
|
||||
t.string :item_name
|
||||
t.string :payment_type
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
5
db/migrate/20130824072157_add_amount_to_payments.rb
Normal file
5
db/migrate/20130824072157_add_amount_to_payments.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddAmountToPayments < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :payments, :amount, :decimal
|
||||
end
|
||||
end
|
28
db/migrate/20130828104240_create_paypal_csvs.rb
Normal file
28
db/migrate/20130828104240_create_paypal_csvs.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
class CreatePaypalCsvs < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :paypal_csvs do |t|
|
||||
t.integer :payment_id
|
||||
t.text :data
|
||||
t.string :date
|
||||
t.string :_time
|
||||
t.string :_time_zone
|
||||
t.string :_name
|
||||
t.string :_type
|
||||
t.string :_status
|
||||
t.string :_currency
|
||||
t.string :_gross
|
||||
t.string :_fee
|
||||
t.string :_net
|
||||
t.string :_from_email_address
|
||||
t.string :_to_email_address
|
||||
t.string :_transaction_id
|
||||
t.string :_counterparty_status
|
||||
t.string :_address_status
|
||||
t.string :_item_title
|
||||
t.string :_item_id
|
||||
t.string :string
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
5
db/migrate/20130829070500_add_exit_reason_to_users.rb
Normal file
5
db/migrate/20130829070500_add_exit_reason_to_users.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddExitReasonToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :exit_reason, :string
|
||||
end
|
||||
end
|
10
db/migrate/20130829074549_add_social_media_to_users.rb
Normal file
10
db/migrate/20130829074549_add_social_media_to_users.rb
Normal file
|
@ -0,0 +1,10 @@
|
|||
class AddSocialMediaToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :twitter_url, :string
|
||||
add_column :users, :facebook_url, :string
|
||||
add_column :users, :github_url, :string
|
||||
add_column :users, :website_url, :string
|
||||
add_column :users, :email_visible, :boolean
|
||||
add_column :users, :phone_visible, :boolean
|
||||
end
|
||||
end
|
13
db/migrate/20130922060217_change_surveys_to_text.rb
Normal file
13
db/migrate/20130922060217_change_surveys_to_text.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class ChangeSurveysToText < ActiveRecord::Migration
|
||||
def up
|
||||
change_column :users, :current_skills, :text, :limit => nil
|
||||
change_column :users, :desired_skills, :text, :limit => nil
|
||||
change_column :users, :marketing_source, :text, :limit => nil
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :users, :current_skills, :string
|
||||
change_column :users, :desired_skills, :string
|
||||
change_column :users, :marketing_source, :string
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
class ChangeMemberLevelToInteger < ActiveRecord::Migration
|
||||
def up
|
||||
change_column :users, :member_level, :integer
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :users, :member_level, :string
|
||||
end
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
class ChangeUserExitReasonToText < ActiveRecord::Migration
|
||||
def up
|
||||
change_column :users, :exit_reason, :text, :limit => nil
|
||||
end
|
||||
|
||||
def down
|
||||
change_column :users, :exit_reason, :string
|
||||
end
|
||||
end
|
17
db/migrate/20130928112252_create_settings.rb
Normal file
17
db/migrate/20130928112252_create_settings.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
class CreateSettings < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :settings do |t|
|
||||
t.string :var, :null => false
|
||||
t.text :value, :null => true
|
||||
t.integer :thing_id, :null => true
|
||||
t.string :thing_type, :limit => 30, :null => true
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :settings, [ :thing_type, :thing_id, :var ], :unique => true
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :settings
|
||||
end
|
||||
end
|
88
db/schema.rb
88
db/schema.rb
|
@ -1,3 +1,4 @@
|
|||
# encoding: UTF-8
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
|
@ -10,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20130212083412) do
|
||||
ActiveRecord::Schema.define(:version => 20130928112252) do
|
||||
|
||||
create_table "cards", :force => true do |t|
|
||||
t.string "card_number"
|
||||
|
@ -35,6 +36,27 @@ ActiveRecord::Schema.define(:version => 20130212083412) do
|
|||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "ipns", :force => true do |t|
|
||||
t.integer "payment_id"
|
||||
t.text "data"
|
||||
t.string "txn_id"
|
||||
t.string "txn_type"
|
||||
t.string "first_name"
|
||||
t.string "last_name"
|
||||
t.string "payer_business_name"
|
||||
t.string "payer_email"
|
||||
t.string "payer_id"
|
||||
t.string "auth_amount"
|
||||
t.string "payment_date"
|
||||
t.string "payment_fee"
|
||||
t.string "payment_gross"
|
||||
t.string "payment_status"
|
||||
t.string "item_name"
|
||||
t.string "payment_type"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "mac_logs", :force => true do |t|
|
||||
t.string "mac"
|
||||
t.string "ip"
|
||||
|
@ -64,10 +86,47 @@ ActiveRecord::Schema.define(:version => 20130212083412) do
|
|||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.integer "created_by"
|
||||
t.decimal "amount"
|
||||
end
|
||||
|
||||
add_index "payments", ["user_id"], :name => "index_payments_on_user_id"
|
||||
|
||||
create_table "paypal_csvs", :force => true do |t|
|
||||
t.integer "payment_id"
|
||||
t.text "data"
|
||||
t.string "date"
|
||||
t.string "_time"
|
||||
t.string "_time_zone"
|
||||
t.string "_name"
|
||||
t.string "_type"
|
||||
t.string "_status"
|
||||
t.string "_currency"
|
||||
t.string "_gross"
|
||||
t.string "_fee"
|
||||
t.string "_net"
|
||||
t.string "_from_email_address"
|
||||
t.string "_to_email_address"
|
||||
t.string "_transaction_id"
|
||||
t.string "_counterparty_status"
|
||||
t.string "_address_status"
|
||||
t.string "_item_title"
|
||||
t.string "_item_id"
|
||||
t.string "string"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
create_table "settings", :force => true do |t|
|
||||
t.string "var", :null => false
|
||||
t.text "value"
|
||||
t.integer "thing_id"
|
||||
t.string "thing_type", :limit => 30
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "settings", ["thing_type", "thing_id", "var"], :name => "index_settings_on_thing_type_and_thing_id_and_var", :unique => true
|
||||
|
||||
create_table "user_certifications", :force => true do |t|
|
||||
t.integer "user_id"
|
||||
t.integer "certification_id"
|
||||
|
@ -79,35 +138,42 @@ ActiveRecord::Schema.define(:version => 20130212083412) do
|
|||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "name"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.string "email", :default => "", :null => false
|
||||
t.string "encrypted_password", :default => "", :null => false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", :default => 0
|
||||
t.integer "sign_in_count", :default => 0
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.boolean "admin"
|
||||
t.integer "member", :limit => 255
|
||||
t.integer "member"
|
||||
t.datetime "waiver"
|
||||
t.datetime "orientation"
|
||||
t.string "emergency_name"
|
||||
t.string "emergency_phone"
|
||||
t.string "emergency_email"
|
||||
t.string "member_level"
|
||||
t.integer "member_level"
|
||||
t.string "payment_method"
|
||||
t.string "phone"
|
||||
t.string "current_skills"
|
||||
t.string "desired_skills"
|
||||
t.text "current_skills"
|
||||
t.text "desired_skills"
|
||||
t.boolean "instructor"
|
||||
t.boolean "hidden"
|
||||
t.string "marketing_source"
|
||||
t.text "marketing_source"
|
||||
t.string "payee"
|
||||
t.boolean "accountant"
|
||||
t.text "exit_reason"
|
||||
t.string "twitter_url"
|
||||
t.string "facebook_url"
|
||||
t.string "github_url"
|
||||
t.string "website_url"
|
||||
t.boolean "email_visible"
|
||||
t.boolean "phone_visible"
|
||||
end
|
||||
|
||||
add_index "users", ["email"], :name => "index_users_on_email", :unique => true
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user