85 Commits

Author SHA1 Message Date
a1ef8a5fd5 User cert tweaks (handling nulls) 2013-08-24 02:23:12 -07:00
75e4907a9c Usability tweaks, creating merges, fixing issues 2013-05-23 23:25:09 -07:00
20a007cac5 Instructors can delete their own certs; hidden users are hidden in drop-downs; admins can see last user login; prepping for postgres 2013-05-03 00:16:02 -07:00
719b9447ab Merge branch 'pamela' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into pamela 2013-02-18 23:29:44 -07:00
8a7fe29f6d Changing lapsed member math to be more accurate & give more info 2013-02-18 23:29:06 -07:00
e630c81298 Resolving nil error for access cards / logs 2013-02-14 23:00:01 -07:00
cefd4b3878 Added nice front page stuff, fixing sqlite issues, adding user payments to profiles 2013-02-14 00:29:22 -07:00
ed75ea0e90 Adding payments 2013-02-12 01:58:17 -07:00
3fb774d057 Adding note to macs json feed 2013-02-09 05:05:06 -07:00
0ced399651 Adjusted profile page to make avatar more clear 2013-02-09 04:21:42 -07:00
02920837e2 Updated new user email to include survey and link to user 2013-02-09 04:11:58 -07:00
63913c0be3 Forgot migration from previous commit. Also added links to home page 2013-02-09 04:01:21 -07:00
ac66cb0cbe Added "how did you hear about us" to user. 2013-02-09 03:47:07 -07:00
1f63709887 Reporting door access logs on each card's page; also card access stats for last 7 days 2013-02-09 03:32:26 -07:00
3f3eb1ed65 Allowed admins to see hidden users, added "no orientation" message to main page and hid new people from non-oriented people 2013-02-09 02:51:35 -07:00
f1b752a4c4 Updating homepage to display cooler door/mac stats 2013-02-09 02:40:38 -07:00
2d0735e914 Replaced "authok" with "ok" on OAC-Ethernet API, changing to match 2013-02-09 02:08:43 -07:00
d156edd683 Updating how macs are stored/viewed 2013-02-09 02:08:29 -07:00
1b64a6b931 Changing email to 2013-02-01 05:03:18 -07:00
1239d6682b Added mailer to notify on new user 2013-02-01 04:44:05 -07:00
50171effad Allowing JSON 2013-02-01 03:58:26 -07:00
43e2cdba78 Finished mac filtering, display, permissions, etc 2013-02-01 03:37:30 -07:00
f3498ddcac Added mac logs, improved mac editing/viewing 2013-02-01 00:06:13 -07:00
04764af983 Got macs working 2013-01-31 22:39:33 -07:00
998558cd30 Figured out mac saving issue 2013-01-31 21:25:54 -07:00
048ce52111 Renaming pamela to macs 2013-01-31 20:48:27 -07:00
a7e999614c Adding pamela but I'm dumb and messed up routing 2013-01-31 20:33:40 -07:00
6673573e36 Updated front page stats to fix dupes 2013-01-31 19:15:35 -07:00
75851ed88d Merge branch 'master' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into members 2013-01-26 02:46:21 -07:00
a022b72eb9 Update README.rdoc 2013-01-26 02:42:27 -07:00
37106f65e0 Added the logo 2013-01-26 02:40:30 -07:00
1865123201 Lots of styling; avatars, payment methods, and more. 2013-01-26 02:21:41 -07:00
8ab6fa10ea Trying to get dynamic helptext for selecting payment methods 2013-01-25 22:30:05 -07:00
e9c648d36e Updating style and ordering of user index 2013-01-25 21:11:01 -07:00
7193ec832c Making user certs collapsible, adding a recompilation script 2013-01-25 20:31:23 -07:00
c547af5391 Updated permissions for deletion and styling for hidden items 2013-01-25 18:21:42 -07:00
3d00bbed03 Finishing touches on abilities and registration form 2013-01-25 13:47:44 -07:00
2327340b71 More UI tweaks and sorting 2013-01-25 11:11:39 -07:00
0b6975a655 Minor UI tweaks 2013-01-25 09:28:32 -07:00
95374a8c1f Moving password field and fixing a nil error in appcontroller 2013-01-25 08:45:43 -07:00
6d0a7b165a Made some changes to the css and asset compiling settings 2013-01-25 07:48:13 -07:00
bb7b2aeca5 Updated some more form styling 2013-01-25 07:23:06 -07:00
7cadcabdce Updated routes and user form to avoid user-create conflicts with devise 2013-01-25 07:11:22 -07:00
63b1b05010 Updating styling, fixing some errors, and adding cert logging 2013-01-25 06:52:19 -07:00
653fcc3112 Fine tuned abilities and updated how membership is tracked 2013-01-25 06:01:02 -07:00
6e77b2bf68 Adding user_certifications relation, and paperclip gem 2013-01-25 03:50:53 -07:00
43d949dc1d Adding certifications; messed up adding certification_users so not staging those 2013-01-25 03:12:25 -07:00
fe283b051f Allowing nil waiver/orientation dates, adjusting permissions of users 2013-01-25 01:49:32 -07:00
d44ae6a69f Halfway done with adding new user fields 2013-01-10 23:11:41 -07:00
cc3857604b Updated door logs to work with new schema 2012-12-15 20:37:44 -07:00
4fc18013d9 Merge branch 'members' of github.com:Geekner/Open-Source-Access-Control-Web-Interface into members 2012-12-01 23:51:52 -07:00
31f220e121 Merge branch 'members' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into members 2012-12-01 23:10:19 -07:00
257c1e5a8b Updated email address 2012-12-01 23:09:35 -07:00
Matthew Shepard
0b5978d4ef Add active status to user show/edit. 2012-10-16 22:59:35 -07:00
1a9c77fbce Merge pull request #1 from Geekner/members
Added registration fields to users table
2012-10-16 21:52:33 -07:00
Matthew Shepard
4ad622e906 Added registration fields to users table 2012-10-16 14:46:21 -07:00
d1ef1e7db9 Recreated user forms, updated abilities, linked cards and users 2012-10-14 06:23:35 -07:00
0254f9aa2c Moved card stuff from users model to new card model 2012-10-14 05:46:19 -07:00
ccd432a67d Changed timezone to Arizona, added log guide 2012-09-16 21:01:21 -07:00
dc0586045f Created auto-download ability 2012-09-16 03:24:54 -07:00
152d6e4e03 Got auto-detection in logs working, improved user index readability 2012-09-16 02:53:45 -07:00
5174b4c50c Added password change option 2012-09-16 02:27:01 -07:00
cd4f689400 Getting mailer working 2012-09-15 23:43:19 -07:00
daa202131c Reversed order of door log, added date column 2012-09-15 22:52:17 -07:00
d73ea31625 Updating user.rb with door_access_url variables 2012-09-15 22:22:58 -07:00
f3443a3a82 Fixed merge conflict with mailer url, need to remove this from git as well 2012-09-15 21:44:06 -07:00
ed8d284619 Added card number interpretation to log 2012-09-15 21:41:11 -07:00
1f74d13ba7 Created readme and made config.yml.example match Open_Access_Control_Ethernet 2012-09-15 20:50:03 -07:00
921ba21a40 Had to modify door log model and add config.yml to avoid storing password in git 2012-09-15 20:41:17 -07:00
93e77b692f Got abilities working on index; next need to separate users from members from cards. 2012-09-15 18:41:55 -07:00
0bc5858101 Merged more conflicts 2012-09-15 17:44:30 -07:00
d3b8ad7222 Merge branch 'master' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface
Conflicts:
	.gitignore
	Gemfile
	Gemfile.lock
	app/controllers/door_logs_controller.rb
	app/controllers/users_controller.rb
	app/models/user.rb
	app/views/door_logs/download.html.erb
	app/views/door_logs/show.html.erb
	app/views/layouts/application.html.erb
	app/views/users/show.html.erb
	app/views/users/upload.html.erb
	app/views/users/upload_all.html.erb
	config/environments/development.rb
	config/environments/production.rb
	config/routes.rb
	db/schema.rb
2012-09-15 17:34:55 -07:00
03d99741e5 Trying to get ability filtering down but failing on collections 2012-09-03 23:20:00 -07:00
1e4dcfd9f3 Finished adding user profile stuff 2012-09-03 21:56:37 -07:00
33a9363b0d Adding admin role and devise views 2012-09-03 20:34:40 -07:00
f3a05d64c1 Adding ability authorizing in cancan 2012-09-02 04:45:42 -07:00
c80c3bbe5c Added cancan 2012-09-02 04:37:34 -07:00
8c36b67cfb Require user account 2012-09-02 04:19:13 -07:00
99f24fe144 Reinstalled devise to user model and migration 2012-09-02 04:12:26 -07:00
72f5a1202a Added notice and alert to application layout 2012-09-02 02:59:29 -07:00
62fb513491 Installed Devise and created a home controller/route 2012-09-02 02:57:34 -07:00
6df97cc3a7 Updated gitignore and production env to work on hsl-web 2012-09-02 02:40:41 -07:00
7f623cf2ec Remove db seeds 2012-08-30 23:38:13 -07:00
8b775d9172 Got door logs working 2012-08-24 23:28:00 -07:00
b28efe046c Got uploading working 2012-08-24 21:14:51 -07:00
170 changed files with 3739 additions and 505 deletions

6
.gitignore vendored
View File

@@ -13,3 +13,9 @@
# Ignore all logfiles and tempfiles. # Ignore all logfiles and tempfiles.
/log/*.log /log/*.log
/tmp /tmp
# Ignore compiled assets
/public/assets
# Ignore config file
/config/config.yml

View File

@@ -23,8 +23,12 @@ end
gem 'jquery-rails' gem 'jquery-rails'
gem 'devise'
gem "cancan"
# To use ActiveModel has_secure_password # To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0' gem 'bcrypt-ruby', '~> 3.0.0'
# To use Jbuilder templates for JSON # To use Jbuilder templates for JSON
# gem 'jbuilder' # gem 'jbuilder'
@@ -37,3 +41,6 @@ gem 'jquery-rails'
# To use debugger # To use debugger
# gem 'ruby-debug' # gem 'ruby-debug'
#gem "paperclip", "~> 3.0"
gem 'gravtastic'

View File

@@ -29,7 +29,9 @@ GEM
i18n (~> 0.6) i18n (~> 0.6)
multi_json (~> 1.0) multi_json (~> 1.0)
arel (3.0.2) arel (3.0.2)
bcrypt-ruby (3.0.1)
builder (3.0.0) builder (3.0.0)
cancan (1.6.8)
coffee-rails (3.2.2) coffee-rails (3.2.2)
coffee-script (>= 2.2.0) coffee-script (>= 2.2.0)
railties (~> 3.2.0) railties (~> 3.2.0)
@@ -37,9 +39,15 @@ GEM
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.3.3) coffee-script-source (1.3.3)
devise (2.1.1)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
warden (~> 1.2.1)
erubis (2.7.0) erubis (2.7.0)
execjs (1.4.0) execjs (1.4.0)
multi_json (~> 1.0) multi_json (~> 1.0)
gravtastic (3.2.6)
hike (1.2.1) hike (1.2.1)
i18n (0.6.0) i18n (0.6.0)
journey (1.0.4) journey (1.0.4)
@@ -54,6 +62,7 @@ GEM
treetop (~> 1.4.8) treetop (~> 1.4.8)
mime-types (1.19) mime-types (1.19)
multi_json (1.3.6) multi_json (1.3.6)
orm_adapter (0.1.0)
polyglot (0.3.3) polyglot (0.3.3)
rack (1.4.1) rack (1.4.1)
rack-cache (1.2) rack-cache (1.2)
@@ -101,12 +110,18 @@ GEM
uglifier (1.2.7) uglifier (1.2.7)
execjs (>= 0.3.0) execjs (>= 0.3.0)
multi_json (~> 1.3) multi_json (~> 1.3)
warden (1.2.1)
rack (>= 1.0)
PLATFORMS PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
bcrypt-ruby (~> 3.0.0)
cancan
coffee-rails (~> 3.2.1) coffee-rails (~> 3.2.1)
devise
gravtastic
jquery-rails jquery-rails
json json
rails (= 3.2.3) rails (= 3.2.3)

View File

@@ -1,261 +1,15 @@
== Welcome to Rails == Open Access Control Web Interface
Web software for managing a database of members in a collaborative grassroots workshop,
and also controlling Arclight of 23b Hackerspace's Arduino access control system
via Ethernet ( see: https://github.com/zyphlar/Open_Access_Control_Ethernet )
Rails is a web-application framework that includes everything needed to create https://github.com/zyphlar/Open-Source-Access-Control-Web-Interface
database-backed web applications according to the Model-View-Control pattern.
This pattern splits the view (also called the presentation) into "dumb" Copyright Will Bradley, 2012-2013
templates that are primarily responsible for inserting pre-built data in between Distributed under a Creative Commons Attribution 3.0 license http://creativecommons.org/licenses/by/3.0/
HTML tags. The model contains the "smart" domain objects (such as Account,
Product, Person, Post) that holds all the business logic and knows how to
persist themselves to a database. The controller handles the incoming requests
(such as Save New Account, Update Product, Show Post) by manipulating the model
and directing data to the view.
In Rails, the model is handled by what's called an object-relational mapping To use:
layer entitled Active Record. This layer allows you to present the data from * Load into a Rails 3 environment
database rows as objects and embellish these data objects with business logic * Rename config/config.yml.example to config/config.yml and edit appropriately
methods. You can read more about Active Record in * Use the Rails console to create a new User and set user.admin = true
link:files/vendor/rails/activerecord/README.html. * Run bundle install, rake db:migrate, etc.
The controller and view are handled by the Action Pack, which handles both
layers by its two parts: Action View and Action Controller. These two layers
are bundled in a single package due to their heavy interdependence. This is
unlike the relationship between the Active Record and Action Pack that is much
more separate. Each of these packages can be used independently outside of
Rails. You can read more about Action Pack in
link:files/vendor/rails/actionpack/README.html.
== Getting Started
1. At the command prompt, create a new Rails application:
<tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
2. Change directory to <tt>myapp</tt> and start the web server:
<tt>cd myapp; rails server</tt> (run with --help for options)
3. Go to http://localhost:3000/ and you'll see:
"Welcome aboard: You're riding Ruby on Rails!"
4. Follow the guidelines to start developing your application. You can find
the following resources handy:
* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
* Ruby on Rails Tutorial Book: http://www.railstutorial.org/
== Debugging Rails
Sometimes your application goes wrong. Fortunately there are a lot of tools that
will help you debug it and get it back on the rails.
First area to check is the application log files. Have "tail -f" commands
running on the server.log and development.log. Rails will automatically display
debugging and runtime information to these files. Debugging info will also be
shown in the browser on requests from 127.0.0.1.
You can also log your own messages directly into the log file from your code
using the Ruby logger class from inside your controllers. Example:
class WeblogController < ActionController::Base
def destroy
@weblog = Weblog.find(params[:id])
@weblog.destroy
logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
end
end
The result will be a message in your log file along the lines of:
Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
More information on how to use the logger is at http://www.ruby-doc.org/core/
Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
several books available online as well:
* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
These two books will bring you up to speed on the Ruby language and also on
programming in general.
== Debugger
Debugger support is available through the debugger command when you start your
Mongrel or WEBrick server with --debugger. This means that you can break out of
execution at any point in the code, investigate and change the model, and then,
resume execution! You need to install ruby-debug to run the server in debugging
mode. With gems, use <tt>sudo gem install ruby-debug</tt>. Example:
class WeblogController < ActionController::Base
def index
@posts = Post.all
debugger
end
end
So the controller will accept the action, run the first line, then present you
with a IRB prompt in the server window. Here you can do things like:
>> @posts.inspect
=> "[#<Post:0x14a6be8
@attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>,
#<Post:0x14a6620
@attributes={"title"=>"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
>> @posts.first.title = "hello from a debugger"
=> "hello from a debugger"
...and even better, you can examine how your runtime objects actually work:
>> f = @posts.first
=> #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
>> f.
Display all 152 possibilities? (y or n)
Finally, when you're ready to resume execution, you can enter "cont".
== Console
The console is a Ruby shell, which allows you to interact with your
application's domain model. Here you'll have all parts of the application
configured, just like it is when the application is running. You can inspect
domain models, change values, and save to the database. Starting the script
without arguments will launch it in the development environment.
To start the console, run <tt>rails console</tt> from the application
directory.
Options:
* Passing the <tt>-s, --sandbox</tt> argument will rollback any modifications
made to the database.
* Passing an environment name as an argument will load the corresponding
environment. Example: <tt>rails console production</tt>.
To reload your controllers and models after launching the console run
<tt>reload!</tt>
More information about irb can be found at:
link:http://www.rubycentral.org/pickaxe/irb.html
== dbconsole
You can go to the command line of your database directly through <tt>rails
dbconsole</tt>. You would be connected to the database with the credentials
defined in database.yml. Starting the script without arguments will connect you
to the development database. Passing an argument will connect you to a different
database, like <tt>rails dbconsole production</tt>. Currently works for MySQL,
PostgreSQL and SQLite 3.
== Description of Contents
The default directory structure of a generated Ruby on Rails application:
|-- app
| |-- assets
| |-- images
| |-- javascripts
| `-- stylesheets
| |-- controllers
| |-- helpers
| |-- mailers
| |-- models
| `-- views
| `-- layouts
|-- config
| |-- environments
| |-- initializers
| `-- locales
|-- db
|-- doc
|-- lib
| `-- tasks
|-- log
|-- public
|-- script
|-- test
| |-- fixtures
| |-- functional
| |-- integration
| |-- performance
| `-- unit
|-- tmp
| |-- cache
| |-- pids
| |-- sessions
| `-- sockets
`-- vendor
|-- assets
`-- stylesheets
`-- plugins
app
Holds all the code that's specific to this particular application.
app/assets
Contains subdirectories for images, stylesheets, and JavaScript files.
app/controllers
Holds controllers that should be named like weblogs_controller.rb for
automated URL mapping. All controllers should descend from
ApplicationController which itself descends from ActionController::Base.
app/models
Holds models that should be named like post.rb. Models descend from
ActiveRecord::Base by default.
app/views
Holds the template files for the view that should be named like
weblogs/index.html.erb for the WeblogsController#index action. All views use
eRuby syntax by default.
app/views/layouts
Holds the template files for layouts to be used with views. This models the
common header/footer method of wrapping views. In your views, define a layout
using the <tt>layout :default</tt> and create a file named default.html.erb.
Inside default.html.erb, call <% yield %> to render the view using this
layout.
app/helpers
Holds view helpers that should be named like weblogs_helper.rb. These are
generated for you automatically when using generators for controllers.
Helpers can be used to wrap functionality for your views into methods.
config
Configuration files for the Rails environment, the routing map, the database,
and other dependencies.
db
Contains the database schema in schema.rb. db/migrate contains all the
sequence of Migrations for your schema.
doc
This directory is where your application documentation will be stored when
generated using <tt>rake doc:app</tt>
lib
Application specific libraries. Basically, any kind of custom code that
doesn't belong under controllers, models, or helpers. This directory is in
the load path.
public
The directory available for the web server. Also contains the dispatchers and the
default HTML files. This should be set as the DOCUMENT_ROOT of your web
server.
script
Helper scripts for automation and generation.
test
Unit and functional tests along with fixtures. When using the rails generate
command, template test files will be generated for you and placed in this
directory.
vendor
External libraries that the application depends on. Also includes the plugins
subdirectory. If the app has frozen rails, those gems also go here, under
vendor/rails/. This directory is in the load path.

BIN
app/assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
app/assets/images/nil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View 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/

View 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/

View 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/

View 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/

View 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/

View File

@@ -0,0 +1,3 @@
jQuery ->
$('.collapsible dt').click ->
$(this).parent().toggleClass('expanded')

View File

@@ -1,3 +1,7 @@
# Place all the behaviors and hooks related to the matching controller here. # Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js. # All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
jQuery ->
$('#user_payment_method').change ->
$('.payment_instructions').hide()
$('#pmt_'+$(this).val()).show()

View File

@@ -11,3 +11,4 @@
*= require_self *= require_self
*= require_tree . *= require_tree .
*/ */
.caption { display: inline-block; background-color: #eee; border: 1px solid #333; border-radius: 5px; margin-bottom: 1em; }

View File

@@ -0,0 +1,3 @@
// Place all the styles related to the Certifications controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@@ -0,0 +1,4 @@
// Place all the styles related to the home controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
table, td { vertical-align: top }

View File

@@ -0,0 +1,3 @@
// Place all the styles related to the MacLogs controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@@ -0,0 +1,4 @@
// Place all the styles related to the pamela controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.hidden { color: #ccc; }

View File

@@ -0,0 +1,3 @@
// Place all the styles related to the Payments controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@@ -4,6 +4,7 @@ body {
font-family: verdana, arial, helvetica, sans-serif; font-family: verdana, arial, helvetica, sans-serif;
font-size: 13px; font-size: 13px;
line-height: 18px; line-height: 18px;
margin: 0;
} }
p, ol, ul, td { p, ol, ul, td {
@@ -35,10 +36,28 @@ div {
} }
} }
#header {
background-color: #eee; border: 1px solid #ddd;
border-bottom-left-radius: 1em;
border-bottom-right-radius: 1em;
padding: 0.5em;
}
#header a {
margin-right: 1em;
}
#logo {
height: 2.0em;
width: 2.0em;
}
#notice { #notice {
color: green; color: green;
} }
#content { margin: 1em; }
.field_with_errors { .field_with_errors {
padding: 2px; padding: 2px;
background-color: red; background-color: red;
@@ -67,3 +86,13 @@ div {
list-style: square; list-style: square;
} }
} }
table { border-spacing: 0; }
td, th { padding: 0.5em; }
.col_highlight { background-color: #ccc; }
dt { font-weight: bold; }
.notice { color: green; }
.alert { color: red; }
.hidden, .hidden a { color: #ccc; }
.payment_instructions { display: none }

View File

@@ -0,0 +1,10 @@
// Place all the styles related to the UserCertifications controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.collapsible dt { cursor: pointer; }
.collapsible dt:before { content: '\229e'; }
.collapsible dd { display: none; }
.expanded dt:before { content: '\229f'; }
.expanded dd { display: block; }

View File

@@ -1,3 +1,13 @@
// Place all the styles related to the users controller here. // Place all the styles related to the users controller here.
// They will automatically be included in application.css. // They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/ // You can use Sass (SCSS) here: http://sass-lang.com/
.iconinfo, .hoverinfo { font-size: 1.5em; }
.hoverinfo { cursor: progress; }
.payment_links { background-color: #ddd; padding: 1em; border-radius: 1em;
display: inline-block; float: right; }
.avatar { height: 2em; width: 2em; }
textarea { height: 10em; }

View File

@@ -1,3 +1,15 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
protect_from_forgery protect_from_forgery
rescue_from CanCan::AccessDenied do |exception|
if !current_user.nil? && current_user.orientation.blank? then
flash[:alert] = "Sorry, you probably need to complete New Member Orientation before having access to this page. <br/>Please check your email and schedule a New Member Orientation with a volunteer."
else
flash[:alert] = "Nothing to see here!"
end
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 end

View File

@@ -0,0 +1,128 @@
class CardsController < ApplicationController
load_and_authorize_resource
before_filter :authenticate_user!
# GET /cards
# GET /cards.json
def index
#@cards = Card.all
#authorize! :read, @cards
@cards = @cards.sort_by{|e| e[:id]}
if can? :read, DoorLog then
Rails.logger.info "CARD STATS:"
most_active_count = 0
@most_active_card = nil
@cards.each do |card|
card_num_R = card.card_number.to_i(16)%32767
Rails.logger.info card_num_R
card[:accesses_this_week] = DoorLog.where('key = "G" AND data =? AND created_at > ?', card_num_R, DateTime.now - 7.days).order("created_at DESC").count
Rails.logger.info card[:accesses_this_week]
if(card[:accesses_this_week] > most_active_count) then
Rails.logger.info "ACTIVE"
most_active_count = card[:accesses_this_week]
@most_active_card = card
end
end
end
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @cards }
end
end
# GET /cards/1
# GET /cards/1.json
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")
end
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @card }
end
end
# PUT /cards/1/upload
def upload
#@card = Card.find(params[:id])
@upload_result = @card.upload_to_door
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @upload_result }
end
end
# PUT /cards/upload_all
def upload_all
@upload_result = Card.upload_all_to_door
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @upload_result }
end
end
# GET /cards/new
# GET /cards/new.json
def new
#@card = Card.new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @card }
end
end
# GET /cards/1/edit
def edit
#@card = Card.find(params[:id])
end
# POST /cards
# POST /cards.json
def create
#@card = Card.new(params[:card])
respond_to do |format|
if @card.save
format.html { redirect_to cards_url, :notice => 'Card was successfully created.' }
format.json { render :json => @card, :status => :created, :location => @card }
else
format.html { render :action => "new" }
format.json { render :json => @card.errors, :status => :unprocessable_entity }
end
end
end
# PUT /cards/1
# PUT /cards/1.json
def update
#@card = Card.find(params[:id])
respond_to do |format|
if @card.update_attributes(params[:card])
format.html { redirect_to cards_url, :notice => 'Card was successfully updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => @card.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /cards/1
# DELETE /cards/1.json
def destroy
#@card = Card.find(params[:id])
@card.destroy
respond_to do |format|
format.html { redirect_to cards_url, :notice => 'Card successfully deleted.' }
format.json { head :no_content }
end
end
end

View File

@@ -0,0 +1,84 @@
class CertificationsController < ApplicationController
load_and_authorize_resource :certification
load_and_authorize_resource :user, :through => :certification
before_filter :authenticate_user!
# GET /certifications
# GET /certifications.json
def index
@certifications = @certifications.sort_by(&:name)
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @certifications }
end
end
# GET /certifications/1
# GET /certifications/1.json
def show
@certification_users = []
#TODO: make a better SQL query for this
@certification.users.sort_by(&:name).each do |user|
@certification_users.push user if can? :read, user
end
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @certification }
end
end
# GET /certifications/new
# GET /certifications/new.json
def new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @certification }
end
end
# GET /certifications/1/edit
def edit
end
# POST /certifications
# POST /certifications.json
def create
respond_to do |format|
if @certification.save
format.html { redirect_to Certification, :notice => 'Certification was successfully created.' }
format.json { render :json => @certification, :status => :created, :location => @certification }
else
format.html { render :action => "new" }
format.json { render :json => @certification.errors, :status => :unprocessable_entity }
end
end
end
# PUT /certifications/1
# PUT /certifications/1.json
def update
respond_to do |format|
if @certification.update_attributes(params[:certification])
format.html { redirect_to Certification, :notice => 'Certification was successfully updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => @certification.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /certifications/1
# DELETE /certifications/1.json
def destroy
@certification.destroy
respond_to do |format|
format.html { redirect_to certifications_url }
format.json { head :no_content }
end
end
end

View File

@@ -1,8 +1,11 @@
class DoorLogsController < ApplicationController class DoorLogsController < ApplicationController
authorize_resource :except => :auto_download
before_filter :authenticate_user!, :except => :auto_download
# GET /door_logs # GET /door_logs
# GET /door_logs.json # GET /door_logs.json
def index def index
@door_logs = DoorLog.all @door_logs = DoorLog.find(:all, :order => "created_at DESC", :limit => 500)
respond_to do |format| respond_to do |format|
format.html # index.html.erb format.html # index.html.erb
@@ -10,19 +13,7 @@ class DoorLogsController < ApplicationController
end end
end end
# GET /door_logs/1 # GET /door_logs/download
# GET /door_logs/1.json
# def show
# @door_log = DoorLog.find(params[:id])
#
# respond_to do |format|
# format.html # show.html.erb
# format.json { render :json => @door_log }
# end
# end
# GET /door_logs/1
# GET /door_logs/1.json
def download def download
@results = DoorLog.download_from_door @results = DoorLog.download_from_door
@@ -32,63 +23,15 @@ class DoorLogsController < ApplicationController
end end
end end
# # GET /door_logs/new # GET /door_logs/auto_download
# # GET /door_logs/new.json def auto_download
# def new @results = DoorLog.download_from_door
# @door_log = DoorLog.new
#
# respond_to do |format|
# format.html # new.html.erb
# format.json { render :json => @door_log }
# end
# end
# GET /door_logs/1/edit respond_to do |format|
# def edit format.html # show.html.erb
# @door_log = DoorLog.find(params[:id]) format.json { render :json => @results }
# end end
end
# POST /door_logs
# POST /door_logs.json
# def create
# @door_log = DoorLog.new(params[:door_log])
#
# respond_to do |format|
# if @door_log.save
# format.html { redirect_to @door_log, :notice => 'Door log was successfully created.' }
# format.json { render :json => @door_log, :status => :created, :location => @door_log }
# else
# format.html { render :action => "new" }
# format.json { render :json => @door_log.errors, :status => :unprocessable_entity }
# end
# end
# end
# PUT /door_logs/1
# PUT /door_logs/1.json
# def update
# @door_log = DoorLog.find(params[:id])
#
# respond_to do |format|
# if @door_log.update_attributes(params[:door_log])
# format.html { redirect_to @door_log, :notice => 'Door log was successfully updated.' }
# format.json { head :no_content }
# else
# format.html { render :action => "edit" }
# format.json { render :json => @door_log.errors, :status => :unprocessable_entity }
# end
# end
# end
# DELETE /door_logs/1
# DELETE /door_logs/1.json
# def destroy
# @door_log = DoorLog.find(params[:id])
# @door_log.destroy
#
# respond_to do |format|
# format.html { redirect_to door_logs_url }
# format.json { head :no_content }
# end
# end
end end

View File

@@ -0,0 +1,24 @@
class HomeController < ApplicationController
def index
@num_certs = UserCertification.count
@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
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_macs = Mac.count
@recent_macs = Mac.where("since > ?", DateTime.now - 1.day).count
respond_to do |format|
format.html # index.html.erb
end
end
end

View File

@@ -0,0 +1,9 @@
class MacLogsController < ApplicationController
load_and_authorize_resource :mac_log
before_filter :authenticate_user!
def index
@mac_logs = MacLog.desc.limit(1000)
end
end

View File

@@ -0,0 +1,251 @@
class MacsController < ApplicationController
load_and_authorize_resource :mac, :except => [:index, :scan, :import]
load_and_authorize_resource :user, :through => :mac, :except => [:index, :show, :scan, :import]
#require "active_record"
require "optparse"
#require "rubygems"
def index
#@active_macs = Mac.where(:active => true, :hidden => false)
#@active_macs += Mac.where(:active => true, :hidden => nil)
# De-dupe users for the public
if can? :update, Mac then
@active_macs = Mac.where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).includes(:user).order("users.name ASC")
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")
end
@hidden_macs = Mac.where("macs.active = ? AND macs.hidden = ?", true, true).order("note ASC")
@all_macs = Mac.find(:all, :order => "LOWER(mac)")
respond_to do |format|
format.html
format.json {
@filtered_macs = Mac.select("macs.mac, users.name, macs.note").where("macs.active = ? AND (macs.hidden IS NULL OR macs.hidden = ?)", true, false).joins(:user)
render :json => @filtered_macs
}
end
end
# GET /macs/1
# GET /macs/1.json
def show
@mac = Mac.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @macs }
end
end
# GET /macs/new
# GET /macs/new.json
def new
@mac = Mac.new
if can? :manage, Mac then
@users = User.accessible_by(current_ability).sort_by(&:name)
else
@users = [current_user]
end
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @mac }
end
end
# GET /macs/1/edit
def edit
@mac = Mac.find(params[:id])
if can? :manage, Mac then
@users = User.accessible_by(current_ability).sort_by(&:name)
else
@users = [current_user]
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 }
else
format.html { render :action => "new" }
format.json { render :json => @mac.errors, :status => :unprocessable_entity }
end
end
end
# PUT /macs/1
# PUT /macs/1.json
def update
#Log who updated this
@mac = Mac.find(params[:id])
@mac.assign_attributes(params[:mac])
#@mac.user_id = params[:mac][:user_id]
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 updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => @mac.errors, :status => :unprocessable_entity }
end
end
end
def scan
Rails.logger.info "starting scan..."
# 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[: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[: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_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
}
}.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])
#class Mac < 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 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
}
# 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
end #def scan
def import
require 'csv'
csv_text = File.read('mac_log.csv')
csv = CSV.parse(csv_text)
@output = []
csv.each do |row|
@output += [row[1], Mac.create({:mac => row[0], :note => row[1], :hidden => row[2]}) ]
end
end
end

View File

@@ -0,0 +1,88 @@
class PaymentsController < ApplicationController
load_and_authorize_resource :payment
load_and_authorize_resource :user, :through => :payment
before_filter :authenticate_user!
# Load users and certs based on current ability
before_filter do
@users = User.where(:hidden => false).where("member_level > 10").accessible_by(current_ability).sort_by(&:name_with_payee_and_member_level)
end
before_filter :only => [:create, :update] do
@payment.created_by = current_user.id
end
# GET /payments
# GET /payments.json
def index
@payments = @payments.order("date DESC")
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @payments }
end
end
# GET /payments/1
# GET /payments/1.json
def show
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @payment }
end
end
# GET /payments/new
# GET /payments/new.json
def new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @payment }
end
end
# GET /payments/1/edit
def edit
end
# POST /payments
# POST /payments.json
def create
Rails.logger.warn "payment:"
Rails.logger.warn @payment.inspect
respond_to do |format|
if @payment.save
format.html { redirect_to payments_url, :notice => 'Payment was successfully created.' }
format.json { render :json => @payment, :status => :created, :location => @payment }
else
format.html { render :action => "new" }
format.json { render :json => @payment.errors, :status => :unprocessable_entity }
end
end
end
# PUT /payments/1
# PUT /payments/1.json
def update
respond_to do |format|
if @payment.update_attributes(params[:payment])
format.html { redirect_to payments_url, :notice => 'Payment was successfully updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => @payment.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /payments/1
# DELETE /payments/1.json
def destroy
@payment.destroy
respond_to do |format|
format.html { redirect_to payments_url }
format.json { head :no_content }
end
end
end

View File

@@ -0,0 +1,14 @@
class RegistrationsController < Devise::RegistrationsController
protected
# After signup
def after_sign_up_path_for(resource)
'/users/edit/?flash=welcome_msg'
end
# After edit
def after_update_path_for(resource)
'/users/edit'
end
end

View File

@@ -0,0 +1,94 @@
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
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)
@certifications = Certification.accessible_by(current_ability).sort_by(&:name)
end
# GET /user_certifications
# GET /user_certifications.json
def index
@grouped_user_certs = @user_certifications.group_by { |uc| uc.certification }
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @user_certifications }
end
end
# GET /user_certifications/1
# GET /user_certifications/1.json
def show
@created_by = User.find(@user_certification.created_by) unless @user_certification.created_by.blank?
@updated_by = User.find(@user_certification.updated_by) unless @user_certification.updated_by.blank?
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @user_certification }
end
end
# GET /user_certifications/new
# GET /user_certifications/new.json
def new
respond_to do |format|
format.html # new.html.erb
format.json { render :json => @user_certification }
end
end
# GET /user_certifications/1/edit
def edit
end
# POST /user_certifications
# POST /user_certifications.json
def create
#Log who created this
@user_certification.created_by = current_user.id
respond_to do |format|
if @user_certification.save
format.html { redirect_to UserCertification, :notice => 'User certification was successfully created.' }
format.json { render :json => @user_certification, :status => :created, :location => @user_certification }
else
format.html { render :action => "new" }
format.json { render :json => @user_certification.errors, :status => :unprocessable_entity }
end
end
end
# PUT /user_certifications/1
# PUT /user_certifications/1.json
def update
#Log who updated this
@user_certification.updated_by = current_user.id
respond_to do |format|
if @user_certification.update_attributes(params[:user_certification])
format.html { redirect_to UserCertification, :notice => 'User certification was successfully updated.' }
format.json { head :no_content }
else
format.html { render :action => "edit" }
format.json { render :json => @user_certification.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /user_certifications/1
# DELETE /user_certifications/1.json
def destroy
@user_certification.destroy
respond_to do |format|
format.html { redirect_to user_certifications_url }
format.json { head :no_content }
end
end
end

View File

@@ -1,8 +1,31 @@
class UsersController < ApplicationController class UsersController < ApplicationController
load_and_authorize_resource
before_filter :authenticate_user!
# GET /users # GET /users
# GET /users.json # GET /users.json
def index def index
@users = User.all case params[:sort]
when "name"
@users = @users.sort_by(&:name)
when "certifications"
@users = @users.sort_by{ |u| [-u.certifications.count,u.name] }
when "orientation"
@users = @users.sort_by{ |u| [-u.orientation.to_i,u.name] }
when "waiver"
@users = @users.sort_by{ |u| [-u.waiver.to_i,u.name] }
when "member"
@users = @users.sort_by{ |u| [-u.member_status.to_i,u.name] }
when "card"
@users = @users.sort_by{ |u| [-u.cards.count,u.name] }
when "instructor"
@users = @users.sort{ |a,b| [b.instructor.to_s,a.name] <=> [a.instructor.to_s,b.name] }
when "admin"
@users = @users.sort{ |a,b| [b.admin.to_s,a.name] <=> [a.admin.to_s,b.name] }
else
@users = @users.sort_by(&:name)
end
respond_to do |format| respond_to do |format|
format.html # index.html.erb format.html # index.html.erb
@@ -13,40 +36,24 @@ class UsersController < ApplicationController
# GET /users/1 # GET /users/1
# GET /users/1.json # GET /users/1.json
def show def show
@user = User.find(params[:id]) @payments = Payment.where(:user_id => @user.id).order('date desc').limit(10)
respond_to do |format| respond_to do |format|
format.html # show.html.erb format.html # show.html.erb
format.json { render :json => @user } format.json { render :json => @user }
end end
end end
# PUT /users/1/upload # GET /user_summary/1
def upload def user_summary
@user = User.find(params[:id])
@upload_result = @user.upload_to_door
respond_to do |format| respond_to do |format|
format.html # show.html.erb format.html { render :partial => "user_summary" } # show.html.erb
format.json { render :json => @upload_result } format.json { render :json => @user }
end end
end
# PUT /users/upload_all
def upload_all
@upload_result = User.upload_all_to_door
respond_to do |format|
format.html # show.html.erb
format.json { render :json => @upload_result }
end
end end
# GET /users/new # GET /users/new
# GET /users/new.json # GET /users/new.json
def new def new
@user = User.new
respond_to do |format| respond_to do |format|
format.html # new.html.erb format.html # new.html.erb
format.json { render :json => @user } format.json { render :json => @user }
@@ -55,17 +62,14 @@ class UsersController < ApplicationController
# GET /users/1/edit # GET /users/1/edit
def edit def edit
@user = User.find(params[:id])
end end
# POST /users # POST /users
# POST /users.json # POST /users.json
def create def create
@user = User.new(params[:user])
respond_to do |format| respond_to do |format|
if @user.save if @user.save
format.html { redirect_to @user, :notice => 'User was successfully created.' } format.html { redirect_to users_url, :notice => 'User was successfully created.' }
format.json { render :json => @user, :status => :created, :location => @user } format.json { render :json => @user, :status => :created, :location => @user }
else else
format.html { render :action => "new" } format.html { render :action => "new" }
@@ -77,11 +81,9 @@ class UsersController < ApplicationController
# PUT /users/1 # PUT /users/1
# PUT /users/1.json # PUT /users/1.json
def update def update
@user = User.find(params[:id])
respond_to do |format| respond_to do |format|
if @user.update_attributes(params[:user]) if @user.update_attributes(params[:user])
format.html { redirect_to @user, :notice => 'User was successfully updated.' } format.html { redirect_to users_url, :notice => 'User was successfully updated.' }
format.json { head :no_content } format.json { head :no_content }
else else
format.html { render :action => "edit" } format.html { render :action => "edit" }
@@ -90,14 +92,44 @@ class UsersController < ApplicationController
end end
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
# DELETE /users/1.json # DELETE /users/1.json
def destroy def destroy
@user = User.find(params[:id])
@user.destroy @user.destroy
respond_to do |format| respond_to do |format|
format.html { redirect_to users_url } format.html { redirect_to users_url, :notice => 'User successfully deleted.' }
format.json { head :no_content } format.json { head :no_content }
end end
end end

View File

@@ -1,2 +1,4 @@
module ApplicationHelper module ApplicationHelper
@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 end

View File

@@ -0,0 +1,2 @@
module CertificationsHelper
end

View File

@@ -0,0 +1,2 @@
module HomeHelper
end

View File

@@ -0,0 +1,2 @@
module MacLogsHelper
end

View File

@@ -0,0 +1,2 @@
module PamelaHelper
end

View File

@@ -0,0 +1,2 @@
module PaymentsHelper
end

View File

@@ -0,0 +1,2 @@
module UserCertificationsHelper
end

View File

@@ -0,0 +1,13 @@
class UserMailer < ActionMailer::Base
default :from => "wiki@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
end
end

75
app/models/ability.rb Normal file
View File

@@ -0,0 +1,75 @@
class Ability
include CanCan::Ability
def initialize(user)
# Anonymous can read mac
can :read, Mac
if !user.nil?
# By default, users can only see their own stuff
can :read, Card, :user_id => user.id
can :read, Certification
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, UserCertification, :user_id => user.id
# Instructors can manage certs and see users
if user.instructor?
can :manage, Certification
can [:create,:read], User, :hidden => [nil,false]
can [:create,:read], UserCertification
can [:update,:destroy], UserCertification, :created_by => user.id
end
# Users can see others' stuff if they've been oriented
unless user.orientation.blank?
can :read, User, :hidden => [nil,false]
can :read, UserCertification
end
# Accountants can manage all
if user.accountant?
can :manage, Payment
end
# Admins can manage all
if user.admin?
can :manage, :all
end
# Prevent all destruction for now
#cannot :destroy, User
#cannot :destroy, Card
cannot :destroy, Certification
cannot :destroy, Mac
cannot :destroy, MacLog
#cannot :destroy, UserCertification
cannot :destroy, DoorLog
# no exception for destroying payments
end
# Define abilities for the passed in user here. For example:
#
# user ||= User.new # guest user (not logged in)
# if user.admin?
# can :manage, :all
# else
# can :read, :all
# end
#
# The first argument to `can` is the action you are giving the user permission to do.
# If you pass :manage it will apply to every action. Other common actions here are
# :read, :create, :update and :destroy.
#
# The second argument is the resource the user can perform the action on. If you pass
# :all it will apply to every resource. Otherwise pass a Ruby class of the resource.
#
# The third argument is an optional hash of conditions to further filter the objects.
# For example, here the user can only update published articles.
#
# can :update, Article, :published => true
#
# See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities
end
end

77
app/models/card.rb Normal file
View File

@@ -0,0 +1,77 @@
class Card < ActiveRecord::Base
require 'open-uri'
attr_accessible :id, :user_id, :name, :card_number, :card_permissions
validates_uniqueness_of :id,:card_number
belongs_to :user
def upload_to_door
# load config values
door_access_url = APP_CONFIG['door_access_url']
door_access_password = APP_CONFIG['door_access_password']
# connect to door access system
source = open("#{door_access_url}?e=#{door_access_password}").read
results = source.scan(/ok/)
if(results.size > 0) then
#only continue if we've got an OK login
cardid = self.id.to_s.rjust(3, '0') #TODO: provide ability for
cardperm = self.card_permissions.to_s.rjust(3, '0')
cardnum = self.card_number.rjust(8, '0')
source = open("#{door_access_url}?m#{cardid}&p#{cardperm}&t#{cardnum}").read
results = source.scan(/cur/)
#logout
open("#{door_access_url}?e=0000")
if(results.size > 0) then
#only return true if we got some kind of decent response
return true
else
# We didn't get a decent response.
return false
end
else
# We didn't get an OK login.
return false
end
end
def self.upload_all_to_door
@cards = Card.all
@end_results = Array.new
# load config values
door_access_url = APP_CONFIG['door_access_url']
door_access_password = APP_CONFIG['door_access_password']
source = open("#{door_access_url}?e=#{door_access_password}").read
results = source.scan(/ok/)
if(results.size > 0) then
@cards.each do |u|
#only continue if we've got an OK login
cardid = u.id.to_s.rjust(3, '0')
cardperm = u.card_permissions.to_s.rjust(3, '0')
cardnum = u.card_number.rjust(8, '0')
source = open("#{door_access_url}?m#{cardid}&p#{cardperm}&t#{cardnum}").read
results = source.scan(/cur/)
if(results.size > 0) then
#only return true if we got some kind of decent response
@end_results.push([cardid,"OK"])
else
@end_results.push([cardid,"FAIL"])
end
end
#logout
open("#{door_access_url}?e=0000")
else
@end_results.push([cardid,"FAIL"])
end
return @end_results
end
end

View File

@@ -0,0 +1,5 @@
class Certification < ActiveRecord::Base
attr_accessible :description, :name
has_many :user_certifications
has_many :users, :through => :user_certifications
end

View File

@@ -3,14 +3,18 @@ class DoorLog < ActiveRecord::Base
require 'open-uri' require 'open-uri'
def self.download_from_door def self.download_from_door
# do shit here # load config values
source = open("http://192.168.1.177?e=1234").read door_access_url = APP_CONFIG['door_access_url']
results = source.scan(/authok/) door_access_password = APP_CONFIG['door_access_password']
# connect to door access system
source = open("#{door_access_url}?e=#{door_access_password}").read
results = source.scan(/ok/)
if(results.size > 0) then if(results.size > 0) then
@end_results = Array.new @end_results = Array.new
#only continue if we've got an OK login #only continue if we've got an OK login
source = open("http://192.168.1.177?z").read source = open("#{door_access_url}?z").read
results = source.scan(/(.*): (.*)\r\n/) results = source.scan(/(.*): (.*)\r\n/)
results.each do |r| results.each do |r|
@@ -20,9 +24,9 @@ class DoorLog < ActiveRecord::Base
end end
#clear log #clear log
open("http://192.168.1.177?y") open("#{door_access_url}?y")
#logout #logout
open("http://192.168.1.177?e=0000") open("#{door_access_url}?e=0000")
if(results.size > 0) then if(results.size > 0) then
#only return true if we got some kind of decent response #only return true if we got some kind of decent response

6
app/models/mac.rb Normal file
View File

@@ -0,0 +1,6 @@
class Mac < ActiveRecord::Base
belongs_to :user
attr_accessible :active, :ip, :mac, :refreshed, :since, :hidden, :note, :user_id
validates_uniqueness_of :mac, :case_sensitive => false
end

5
app/models/mac_log.rb Normal file
View File

@@ -0,0 +1,5 @@
class MacLog < ActiveRecord::Base
attr_accessible :action, :ip, :mac
scope :desc, order("mac_logs.created_at DESC")
end

15
app/models/payment.rb Normal file
View File

@@ -0,0 +1,15 @@
class Payment < ActiveRecord::Base
belongs_to :user
attr_accessible :date, :user_id, :created_by
validates_presence_of :user_id, :date, :created_by
validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.'
def human_date
if date.year < DateTime.now.year
date.strftime("%b %e, %y")
else
date.strftime("%b %e")
end
end
end

View File

@@ -1,68 +1,158 @@
class User < ActiveRecord::Base class User < ActiveRecord::Base
require 'open-uri' include Gravtastic
gravtastic :size => 120, :default => ""
attr_accessible :card_id, :card_number, :card_permissions, :name # Include default devise modules. Others available are:
validates_uniqueness_of :card_id, :card_number # :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
def upload_to_door # Setup accessible (or protected) attributes for your model
# do shit here 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
source = open("http://192.168.1.177?e=1234").read
results = source.scan(/authok/)
if(results.size > 0) then
#only continue if we've got an OK login
usernum = self.card_id.to_s.rjust(3, '0')
userperm = self.card_permissions.to_s.rjust(3, '0')
cardnum = self.card_number.rjust(8, '0')
source = open("http://192.168.1.177?m#{usernum}&p#{userperm}&t#{cardnum}").read has_many :cards
results = source.scan(/cur/) has_many :user_certifications
has_many :certifications, :through => :user_certifications
has_many :payments
#logout after_create :send_new_user_email
open("http://192.168.1.177?e=0000")
if(results.size > 0) then def absorb_user(user_to_absorb)
#only return true if we got some kind of decent response # copy all attributes except email, password, name, and anything that isn't blank on the destination
return true 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.save!
Rails.logger.info "PAYMENT AFTER: "+payment.inspect
}
user_to_absorb.destroy
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}"
else
"#{payee} for #{name} - #{member_level_string}"
end
end
def member_level_string
case self.member_level.to_i
when 0
"None"
when 1
"Unable"
when 10..24
"Volunteer"
when 25..49
"Associate ($25)"
when 50..99
"Basic ($50)"
when 100..999
"Plus ($100)"
end
end
def member_status
case self.member_level.to_i
when 0
if self.payments.count > 0 then
2
else else
# We didn't get a decent response. -1
return false
end end
else when 1
# We didn't get an OK login. 1
return false when 10..24
end 10
end when 25..999
if self.payments.count > 0 then
def self.upload_all_to_door if self.payments.last.date < (DateTime.now - 45.days)
@users = User.all 3
@end_results = Array.new
source = open("http://192.168.1.177?e=1234").read
results = source.scan(/authok/)
if(results.size > 0) then
@users.each do |u|
#only continue if we've got an OK login
usernum = u.card_id.to_s.rjust(3, '0')
userperm = u.card_permissions.to_s.rjust(3, '0')
cardnum = u.card_number.rjust(8, '0')
source = open("http://192.168.1.177?m#{usernum}&p#{userperm}&t#{cardnum}").read
results = source.scan(/cur/)
if(results.size > 0) then
#only return true if we got some kind of decent response
@end_results.push([usernum,"OK"])
else else
@end_results.push([usernum,"FAIL"]) case self.member_level.to_i
when 25..49
25
when 50..99
50
when 100..999
100
end
end end
else
return 0
end end
#logout
open("http://192.168.1.177?e=0000")
else
@end_results.push([usernum,"FAIL"])
end end
return @end_results
end 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'>&#9684;</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)'>&#9676;</span>"
else
case self.member_level.to_i
when 25..49
"<span class='hoverinfo' title='#{member_level_string}'>&#9681;</span>"
when 50..99
"<span class='hoverinfo' title='#{member_level_string}'>&#9685;</span>"
when 100..999
"<span class='hoverinfo' title='#{member_level_string}'>&#9679;</span>"
end
end
else
"<span class='hoverinfo' title='No Payments'>?</span>"
end
end
end
private
def send_new_user_email
Rails.logger.info UserMailer.new_user_email(self).deliver
end
end end

View File

@@ -0,0 +1,16 @@
class UserCertification < ActiveRecord::Base
attr_accessible :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

View File

@@ -0,0 +1,37 @@
<%= form_for(@card) do |f| %>
<% if @card.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@card.errors.count, "error") %> prohibited this card from being saved:</h2>
<ul>
<% @card.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user %><br />
<%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name) %>
</div>
<div class="field">
<%= f.label :name, "Card Note" %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :id, "Card DB ID" %><br />
<%= f.number_field :id, :in => 10...201 %>
</div>
<div class="field">
<%= f.label :card_number, "Card Number" %><br />
<%= f.text_field :card_number %>
</div>
<div class="field">
<%= f.label :card_permissions %><br />
<%= f.select :card_permissions, [["Enabled",1],["Disabled",255]] %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<h1>Editing card</h1>
<%= render 'form' %>
<%= link_to 'Show', @card %> |
<%= link_to 'Back', cards_path %>

View File

@@ -0,0 +1,52 @@
<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 %>
<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)
</p>
<table>
<col />
<col />
<col class="col_highlight" />
<col />
<col class="col_highlight" />
<tr>
<th>User</th>
<th>Note</th>
<th>DB ID</th>
<th>Card #</th>
<th>Access?</th>
<th>Accesses Last 7 Days</th>
<th></th>
<th></th>
<th></th>
</tr>
<% if !@cards.blank? %>
<% @cards.each do |card| %>
<tr>
<td>
<% if card.user.nil? %>
n/a
<% else %>
<%= link_to card.user.name , card %>
<% end %>
</td>
<td><%= card.name %></td>
<td><%= card.id %></td>
<td><%= card.card_number %></td>
<td><%= if card.card_permissions == 1 then "Access" end %></td>
<td><%= card.accesses_this_week unless card.accesses_this_week < 1 %></td>
<td><%= link_to 'Upload', upload_path(card) if can? :upload, card %></td>
<td><%= link_to 'Edit', edit_card_path(card) if can? :update, card %></td>
<td><%= link_to 'Destroy', card, :confirm => 'Are you sure? WARNING: THIS DOES NOT REMOVE THE CARD FROM THE DOOR SYSTEM! DISABLE AND UPLOAD IT FIRST.', :method => :delete if can? :destroy, card %></td>
</tr>
<% end %>
<% end %>
</table>
<br />

View File

@@ -0,0 +1,5 @@
<h1>New card</h1>
<%= render 'form' %>
<%= link_to 'Back', cards_path %>

View File

@@ -0,0 +1,39 @@
<p>
<b>User:</b>
<%= link_to @card.user.name, @card.user unless @card.user.blank? %>
</p>
<p>
<b>Card Note:</b>
<%= @card.name %>
</p>
<p>
<b>Card DB ID:</b>
<%= @card.id %>
</p>
<p>
<b>Card Number:</b>
<%= @card.card_number %>
</p>
<p>
<b>Card Permissions:</b>
<%= if @card.card_permissions == 1 then "Enabled" else "Disabled" end %>
</p>
<% if can? :read, DoorLog %>
<p>
<b>Access attempts:</b>
<ul>
<% @door_logs.each do |log| %>
<li><%= log.created_at %></li>
<% end %>
</ul>
</p>
<% end %>
<%= link_to 'Upload to Door', upload_path(@card) if can? :upload, @card %>
<% if can? :update, @card then %><%= link_to 'Edit', edit_card_path(@card) %> |<% end %>
<%= link_to 'Back', cards_path %>

View File

@@ -0,0 +1,14 @@
<% if @upload_result %>
<p>
<b>Upload result:</b>
<%= @card.card_number %> uploaded successfully.
</p>
<% else %>
<p>
<b>Upload result:</b>
Error uploading <%= @card.card_number %>.
</p>
<% end %>
<%= link_to 'Back', cards_path %>

View File

@@ -1,4 +1,3 @@
<p id="notice"><%= notice %></p>
<p> <p>
<b>Upload results:</b> <b>Upload results:</b>
@@ -10,4 +9,4 @@
</p> </p>
<%= link_to 'Back', users_path %> <%= link_to 'Back', cards_path %>

View File

@@ -0,0 +1,25 @@
<%= form_for(@certification) do |f| %>
<% if @certification.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@certification.errors.count, "error") %> prohibited this certification from being saved:</h2>
<ul>
<% @certification.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<h1>Editing certification</h1>
<%= render 'form' %>
<%= link_to 'Show', @certification %> |
<%= link_to 'Back', certifications_path %>

View File

@@ -0,0 +1,15 @@
<h1>Certification Classes</h1>
<%= link_to 'Create Certification', new_certification_path if can? :create, Certification %>
<ul>
<% @certifications.each do |certification| %>
<li><%= link_to certification.name, certification %>
<% if can? :update, certification %> | <%= link_to 'Edit', edit_certification_path(certification) %><% end %>
<% if can? :destroy, certification %> | <%= link_to 'Destroy', certification, :confirm => 'Are you sure?', :method => :delete %><% end %>
</li>
<% end %>
</ul>
<br />

View File

@@ -0,0 +1,5 @@
<h1>New certification</h1>
<%= render 'form' %>
<%= link_to 'Back', certifications_path %>

View File

@@ -0,0 +1,20 @@
<p>
<b>Name:</b>
<%= @certification.name %>
</p>
<p>
<b>Description:</b>
<%= 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>
<% if can? :update, @certification %><%= link_to 'Edit', edit_certification_path(@certification) %> |<% end %>
<%= link_to 'Back', certifications_path %>

View File

@@ -0,0 +1,12 @@
<h2>Resend confirmation instructions</h2>
<%= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Resend confirmation instructions" %></div>
<% end %>
<%= render "devise/shared/links" %>

View File

@@ -0,0 +1,5 @@
<p>Welcome <%= @resource.email %>!</p>
<p>You can confirm your account email through the link below:</p>
<p><%= link_to 'Confirm my account', confirmation_url(@resource, :confirmation_token => @resource.confirmation_token) %></p>

View File

@@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>
<p>Someone has requested a link to change your password, and you can do this through the link below.</p>
<p><%= link_to 'Change my password', edit_password_url(@resource, :reset_password_token => @resource.reset_password_token) %></p>
<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>

View File

@@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>
<p>Your account has been locked due to an excessive amount of unsuccessful sign in attempts.</p>
<p>Click the link below to unlock your account:</p>
<p><%= link_to 'Unlock my account', unlock_url(@resource, :unlock_token => @resource.unlock_token) %></p>

View File

@@ -0,0 +1,16 @@
<h2>Change your password</h2>
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f| %>
<%= devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>
<div><%= f.label :password, "New password" %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Change my password" %></div>
<% end %>
<%= render "devise/shared/links" %>

View File

@@ -0,0 +1,12 @@
<h2>Forgot your password?</h2>
<%= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Send me reset password instructions" %></div>
<% end %>
<%= render "devise/shared/links" %>

View File

@@ -0,0 +1,69 @@
<% 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/>
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 :name, "Full Name" %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email %>
</div>
<div class="field">
<%= f.label :phone %><br />
<%= f.text_field :phone %>
</div>
<div class="field">
<%= f.label :emergency_name, "Emergency Contact Name" %><br />
<%= f.text_field :emergency_name %>
</div>
<div class="field">
<%= f.label :emergency_phone %><br />
<%= f.text_field :emergency_phone %>
</div>
<div class="field">
<%= 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 %>
</div>
<div class="field">
<%= f.label :desired_skills, "What skills, knowledge and experiences are you looking for in HeatSync?" %><br />
<%= f.text_area :desired_skills %>
</div>
<div class="field">
<%= f.label :marketing_source, "How'd you find out about HeatSync?" %><br />
<%= f.text_area :marketing_source %>
</div>
<div><%= f.label :password %><% if params[:action]!='new' %> <em>(Only if you want to change your password)</em><% end %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<% if params[:action]!='new' %>
<div><%= f.label :current_password, "Type Your Current Password" %> <em>(For your account's security)</em><br />
<%= f.password_field :current_password %></div>
<% end %>
<div><%= f.submit button_label %></div>
<% end %>

View File

@@ -0,0 +1,85 @@
<h2>Profile:</h2>
<%= devise_error_messages! %>
<div class="payment_links">
<% if can? :read, resource.payments then %>
<h3>Recorded Payments:</h3>
<ul>
<% resource.payments.each do |payment| %>
<li><%= payment.date %></li>
<% end %>
</ul>
<hr/>
<% end %>
<% if resource.payment_method == "Dwolla" %>
<h3>Dwolla Payment Link</h3>
<% 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" %>
<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" %>
<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>
<% 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" %>
<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">
<input type="hidden" name="hosted_button_id" value="SZWVLPAG79XCN">
<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" %>
<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">
<input type="hidden" name="hosted_button_id" value="GEAMCMZZKC4AW">
<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" %>
<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">
<input type="hidden" name="hosted_button_id" value="L7XVC2GUJJR5A">
<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>
<% else %>
Hmm, your membership level doesn't appear to be at $25/50/100...
<% end %>
<% elsif resource.payment_method == "BillPay" %>
<h3>Bill Pay Info</h3>
<p>Have your bank send a monthly check to HeatSync Labs Treasurer, 140 W Main St, Mesa AZ 85201 <strong>Electronic or advance payments are appreciated!</strong></p>
<% elsif resource.payment_method == "Check" %>
<h3>Check Payment Info</h3>
<p>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. <strong>Electronic or advance payments are appreciated!</strong></p>
<% elsif resource.payment_method == "Cash" %>
<p>Put in the drop safe at the Lab with a deposit slip firmly attached each month. <strong>Electronic or advance payments are appreciated!</strong></p>
<% else %>
<h3>Payment Links</h3>
<p>Normally you'd see payment buttons here, but you don't seem to have an electronic payment option selected...</p>
<% end %>
</div>
<div class="caption">
<%= link_to image_tag(resource.gravatar_url), "https://www.gravatar.com", :title => "Adjust your photo at Gravatar.com" %><br/>
Adjust your photo <br/>at Gravatar.com
</div>
<%= render :partial => "user", :locals => { :resource => resource, :html => { :method => :put }, :button_label => "Update Profile" } %>
<%= render "devise/shared/links" %>
<%= link_to "Back", :back %>

View File

@@ -0,0 +1,7 @@
<h2>Membership Application</h2>
<%= devise_error_messages! %>
<%= render :partial => "user", :locals => { :resource => resource, :button_label => "Sign Up", :html => nil } %>
<%= render "devise/shared/links" %>

View File

@@ -0,0 +1,17 @@
<h2>Sign in</h2>
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<% if devise_mapping.rememberable? -%>
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<div><%= f.submit "Sign in" %></div>
<% end %>
<%= render "devise/shared/links" %>

View File

@@ -0,0 +1,25 @@
<%- if controller_name != 'sessions' %>
<%= link_to "Sign in", new_session_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end -%>
<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
<% end -%>
<% end -%>

View File

@@ -0,0 +1,12 @@
<h2>Resend unlock instructions</h2>
<%= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f| %>
<%= devise_error_messages! %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.submit "Resend unlock instructions" %></div>
<% end %>
<%= render "devise/shared/links" %>

View File

@@ -0,0 +1,6 @@
<p>
<b>Download results:</b>
<%= !@results.nil? %>
</p>

View File

@@ -1,4 +1,3 @@
<p id="notice"><%= notice %></p>
<p> <p>
<b>Download results:</b> <b>Download results:</b>

View File

@@ -1,8 +1,49 @@
<h1>Listing door_logs</h1> <h1>Door Logs</h1>
<%= link_to 'Download Door Logs', download_path %> <%= link_to 'Download Door Logs', download_path %>
<a href="#" onclick="$('#log-guide').toggle();">Show Log Guide</a>
<div id="log-guide" style="display: none;">
<pre>
Guide to Card Number storage:
cardnum = (R+(r*32767)), convert to hex
Guide to log keys and data:
* A=alarm armed (# level)
* a=added user (# usernum)
* C=keypad command (# command)
* c=second half
* c=checked user (0=failed, #=found usernum)
* D=denied access (# card num)
* d=second half
* d=deleted user (# usernum)
* E=second (#=second)
* F=priv fail (0=wrong pw, 1=too many attempts, 2=not logged in)
* f=second half
* f=card fail (#=usermask)
* G=granted access (# card num)
* g=second half of card
* H=hour (#=hour)
* i=attempt to write to invalid eeprom address (# usernum)
* I=attempt to delete from invalid eeprom address (# usernum)
* L=locked (1=door1, 2=door2, 3=bedtime)
* M=minute (#=minute)
* m=alarm state (# level)
* R=read tag (# card num)
* r=second half of tag
* Q=superuser authed (#=superuser)
* S=auth (0=privileged mode enabled)
* s=alarm sensor (# zone)
* t=alarm trained (#=sensor value)
* T=alarm triggered (0)
* U=unlocked door (1=door1, 2=door2, # card num)
* u=second half of card
* Z=user db cleared (0)
* z=log cleared (0)
</pre>
</div>
<table> <table>
<tr> <tr>
<th>Date</th>
<th>Key</th> <th>Key</th>
<th>Data</th> <th>Data</th>
<th></th> <th></th>
@@ -10,10 +51,33 @@
<th></th> <th></th>
</tr> </tr>
<% @divided_tmp = nil %>
<% @door_logs.each do |door_log| %> <% @door_logs.each do |door_log| %>
<tr> <tr>
<td><%= door_log.created_at %></td>
<td><%= door_log.key %></td> <td><%= door_log.key %></td>
<td><%= door_log.data %></td> <td><%= door_log.data %></td>
<%
if door_log.key == 'r' || door_log.key == 'd' ||door_log.key == 'g'
@divided_tmp = door_log.data.to_i
elsif (door_log.key == 'R' || door_log.key == 'D' || door_log.key == 'G') && !@divided_tmp.nil? %>
<td>
<%= case door_log.key
when 'R'
"Read"
when 'D'
"Denied"
when 'G'
"Granted"
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.user.name+")" unless @card.nil? %>
</td>
<% else
@divided_tmp = nil
end %>
</tr> </tr>
<% end %> <% end %>
</table> </table>

View File

@@ -1,4 +1,3 @@
<p id="notice"><%= notice %></p>
<p> <p>
<b>Key:</b> <b>Key:</b>

View File

@@ -0,0 +1,66 @@
<h1>Welcome to the HeatSync Labs Members App.</h1>
<% if !user_signed_in? then %>
<p>You can sign up to become a member here!</p>
<% 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 %>
<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 %>
<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>
<% end %>
</ul>
<% end %>
<h2>Cool Stats:</h2>
<dl>
<dt># of People in this DB:</dt>
<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 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>
<dt># of Computers in this DB:</dt>
<dd><%= @num_macs %> (<%= @recent_macs %> seen today)</dd>
</dl>
</td>
<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>
</td>
</tr>
</table>

View File

@@ -1,17 +1,33 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Dooraccess</title> <title>hsl_members(<%= controller.controller_name %>.<%= controller.action_name %><%= "["+params[:id]+"]" unless params[:id].blank? %>)</title>
<%= stylesheet_link_tag "application", :media => "all" %> <%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %> <%= javascript_include_tag "application" %>
<%= csrf_meta_tags %> <%= csrf_meta_tags %>
</head> </head>
<body> <body>
<div id="header"> <div id="header">
<a href="/users">Users</a> <a href="/" title="Home"><img src="/assets/logo.png" id="logo" /></a>
<a href="/door_logs">Logs</a> <%= link_to 'People', users_path if can? :read, User %>
<%= link_to 'Access Cards', cards_path if can? :manage, Card %>
<% if can? :manage, 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) %>
<% 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? %>
<%= link_to 'Membership Application', new_user_registration_path unless user_signed_in? %>
</div> </div>
<div id="content">
<p class="notice"><%= raw(notice) %></p>
<p class="alert"><%= raw(alert) %></p>
<%= yield %> <%= yield %>
</div>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,10 @@
<table>
<% @mac_logs.each do |mac_log| %>
<tr>
<td><%= mac_log.mac %></td>
<td><%= mac_log.ip %></td>
<td><%= mac_log.action %></td>
<td><%= mac_log.created_at %></td>
</tr>
<% end %>
</table>

View File

@@ -0,0 +1,33 @@
<%= 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>
<ul>
<% @mac.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_id, "User" %><br />
<%= collection_select(:mac, :user_id, @users, :id, :name, :include_blank => true) %>
</div>
<div class="field">
<%= f.label :mac %><br />
<%= f.text_field :mac %>
</div>
<div class="field">
<%= f.label :note %><br />
<%= f.text_field :note %>
</div>
<div class="field">
<%= f.label :hidden %><br />
<%= f.check_box :hidden %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<h1>Editing Mac</h1>
<%= render 'form' %>
<%= link_to 'Show', @mac %> |
<%= link_to 'Back', macs_path %>

View File

@@ -0,0 +1 @@
<%= @output %>

View File

@@ -0,0 +1,47 @@
<h2>What machines are on our network?</h2>
<%= link_to "New MAC registration", new_mac_path if can? :create, Mac %>
<ul class="mac_list">
<%
@active_macs.each do |mac|
Rails.logger.info mac.inspect %>
<li>
<span title="<%= mac.mac if user_signed_in? %><%= " - "+mac.ip.to_s if can? :read_details, mac %><%= " - "+((Time.now - mac.since) / 1.hour).round(1).to_s+" hours" if can? :manage, mac %>">
<%= mac.user.name unless mac.user.blank? %>
<%= mac.mac if mac.user.blank? %>
<%= "("+mac.note+")" unless mac.note.blank? %></span>
<%= link_to ' Edit', edit_mac_path(mac) if can? :update, mac %> <br/>
</li>
<% end %>
</ul>
<% if can? :read_details, Mac %>
<ul class="mac_list hidden">
<% @hidden_macs.each do |mac| %>
<li>
<span title="<%= mac.mac %><%= " - "+mac.ip.to_s if can? :read_details, mac %><%= " - "+((Time.now - mac.since) / 1.hour).round(1).to_s+" hours" if can? :manage, mac %>">
<%= mac.user.name unless mac.user.blank? %>
<%= "("+mac.note+")" unless mac.note.blank? %></span>
<%= link_to ' Edit', edit_mac_path(mac) if can? :update, mac %> <br/>
</li>
<% end %>
</ul>
<% end %>
<% if can? :manage, Mac %>
<h3>All Macs</h3>
<table>
<% @all_macs.each do |mac| %>
<tr <%= raw('class="hidden"') if mac.hidden? %>>
<td><%= mac.mac.downcase %> </td>
<td><%= mac.user.name unless mac.user.blank? %></td>
<td><%= "("+mac.note+")" unless mac.note.blank? %></td>
<td><%= if mac.active? then raw("<strong>Here</strong>") else "Gone" end %></td>
<td><%= ((Time.now - mac.since) / 1.hour).round(1).to_s+" hours" unless mac.since.blank? %></td>
<td><%= link_to 'Edit', edit_mac_path(mac) %></td>
</tr>
<% end %>
</table>
<% end %>

View File

@@ -0,0 +1,5 @@
<h1>New Mac</h1>
<%= render 'form' %>
<%= link_to 'Back', macs_path %>

View File

@@ -0,0 +1,5 @@
Scanning...
<% @log.each do |log| %>
<%= log.mac %> =
<%= log.ip %><br/>
<% end %>

View File

@@ -0,0 +1,27 @@
<p>
<b>User:</b>
<%= @mac.user.name unless @mac.user.blank? %>
</p>
<p>
<b>Mac:</b>
<%= @mac.mac %>
</p>
<p>
<b>Note:</b>
<%= @mac.note %>
</p>
<p>
<b>Hidden:</b>
<%= @mac.hidden %>
</p>
<p>
<b>IP:</b>
<%= @mac.ip %>
</p>
<%= link_to 'Edit', edit_mac_path(@mac) %> |
<%= link_to 'Back', macs_path %>

View File

@@ -0,0 +1,25 @@
<%= form_for(@payment) do |f| %>
<% if @payment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@payment.errors.count, "error") %> prohibited this payment from being saved:</h2>
<ul>
<% @payment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_id, "User" %><br />
<%= collection_select(:payment, :user_id, @users, :id, :name_with_payee_and_member_level) %> (inactive members are not shown.)
</div>
<div class="field">
<%= f.label :date, "Paid for month beginning" %><br />
<%= f.date_select :date, :default => (DateTime.now - 1.month) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<h1>Editing payment</h1>
<%= render 'form' %>
<%= link_to 'Show', @payment %> |
<%= link_to 'Back', payments_path %>

View File

@@ -0,0 +1,24 @@
<h1>Listing payments</h1>
<%= link_to 'New Payment', new_payment_path %>
<br />
<table>
<tr>
<th>User</th>
<th>Paid for month <br/>beginning</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @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><%= link_to 'Details', payment %></td>
<td><%= link_to 'Edit', edit_payment_path(payment) %></td>
</tr>
<% end %>
</table>

View File

@@ -0,0 +1,5 @@
<h1>New payment</h1>
<%= render 'form' %>
<%= link_to 'Back', payments_path %>

View File

@@ -0,0 +1,29 @@
<p>
<b>User:</b>
<%= @payment.user.name_with_payee_and_member_level unless @payment.user.blank? %>
</p>
<p>
<b>Paid for month beginning:</b>
<%= @payment.date %>
</p>
<p>
<b>Last Modified by:</b>
<%= user = @users.find{|u| u.id == @payment.created_by}; link_to user.name, user unless user.blank? %>
</p>
<p>
<b>Created date:</b>
<%= @payment.created_at %>
</p>
<p>
<b>Updated date:</b>
<%= @payment.updated_at %>
</p>
<%= 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 %> |
<%= link_to 'Back', payments_path %>

View File

@@ -0,0 +1,25 @@
<%= form_for(@user_certification) do |f| %>
<% if @user_certification.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@user_certification.errors.count, "error") %> prohibited this User Certification from being saved:</h2>
<ul>
<% @user_certification.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :user_id, "User" %><br />
<%= collection_select(:user_certification, :user_id, @users, :id, :name) %>
</div>
<div class="field">
<%= f.label :certification_id, "Certification" %><br />
<%= collection_select(:user_certification, :certification_id, @certifications, :id, :name) %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,6 @@
<h1>Editing User Certification</h1>
<%= render 'form' %>
<%= link_to 'Show', @user_certification %> |
<%= link_to 'Back', user_certifications_path %>

View File

@@ -0,0 +1,15 @@
<h1>User Certifications</h1>
<%= link_to 'New User Certification', new_user_certification_path %>
<% @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| %>
<dd>
<%= link_to user_certification.user_name, user_certification %>
</dd>
<% end %>
</dl>
<% end %>

View File

@@ -0,0 +1,5 @@
<h1>New User Certification</h1>
<%= render 'form' %>
<%= link_to 'Back', user_certifications_path %>

View File

@@ -0,0 +1,36 @@
<p>
<b>User:</b>
<%= @user_certification.user_name %>
</p>
<p>
<b>Certification:</b>
<%= @user_certification.certification.name %>
</p>
<p>
<b>Created:</b> by <%= link_to @created_by.name, @created_by unless @created_by.blank? %>
at <%= @user_certification.created_at %>
</p>
<p>
<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>
<p>
<% if can? :update, @user_certification %>
<%= link_to 'Edit', edit_user_certification_path(@user_certification) %> |
<% end %>
<% if can? :destroy, @user_certification %>
<%= link_to 'Delete', @user_certification, :confirm => "Are you sure you want to destroy this user's certification?", :method => :delete %> |
<% end %>
<%= link_to 'Back', user_certifications_path %>
</p>

View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
</head>
<body>
<h2><%= @user.name %> just signed up.</h2>
<p>
Please contact them at <%= @user.email %><%= " or "+@user.phone.to_s unless @user.phone.blank? %> to set up a
new user orientation, waiver, welcome, payment help, etc.
</p>
<p>
User Details: <%= link_to @url+user_path(@user), @url+user_path(@user) %>
</p>
<p>
<b>Member Level:</b>
<%= simple_format @user.member_level_string %>
</p>
<p>
<b>What skills, knowledge and experience do you bring to the community?</b>
<%= simple_format @user.current_skills %>
</p>
<p>
<b>What skills, knowledge and experiences are you looking for in HeatSync?</b>
<%= simple_format @user.desired_skills %>
</p>
<p>
<b>How'd you find out about HeatSync?</b>
<%= simple_format @user.marketing_source %>
</p>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More