gsr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +22 -0
  4. data/README.md +41 -0
  5. data/Rakefile +2 -0
  6. data/gsr.gemspec +19 -0
  7. data/lib/gsr.rb +123 -0
  8. data/lib/gsr/version.rb +5 -0
  9. metadata +68 -0
@@ -0,0 +1,18 @@
1
+ main.rb
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gsr.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Matt Parmett
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # gsr.rb: A Ruby library for reserving Wharton GSRs #
2
+
3
+ gsr.rb is a simple Ruby library that allows your application to easily book and cancel Wharton Group Study Room (GSR) reservations.
4
+
5
+ ## How to use gsr.rb ##
6
+
7
+ *This section will change as gsr.rb is developed. As such, this section may not be fully accurate, but I will try to keep the instructions as current as possible.*
8
+
9
+ ### Make a reservation ###
10
+
11
+ To reserve a GSR for 60 minutes at noon on 9/18/2012 on the second floor:
12
+
13
+ ```ruby
14
+ require 'gsr.rb'
15
+ concierge = GSR.new(spike_username, spike_password)
16
+ concierge.reserve('floor' => '2', 'start_time' => Time.new(2012, 9, 18, 12, 0, 0), 'duration' => 60)
17
+ ```
18
+
19
+ ```floor``` takes strings ```""```, ```"F"```, ```"G"```, ```"2"```, or ```"3"```. The empty string, to which ```floor``` defaults, means any floor is acceptable.
20
+
21
+ ```start_time``` takes a Time object specifying the desired starting date and time (defaults to ```Time.now```).
22
+
23
+ ```duration``` takes an integer with a value of ```30```, ```60```, or ```90```. If another integer is given, gsr.rb rounds up to the next largest interval. ```duration``` defaults to ```90```.
24
+
25
+ ### Cancel a reservation ###
26
+
27
+ To cancel the reservation closest to the current time (more specific cancellation functionality may be added in the future):
28
+
29
+ ```ruby
30
+ require 'gsr.rb'
31
+ concierge = GSR.new(spike_username, spike_password)
32
+ concierge.cancel
33
+ ```
34
+
35
+ ## Warnings ##
36
+
37
+ Security-wise, this probably isn't the most secure way to handle the spike username and password. The user/pass combo is sent through a form on a secure web page, but no additional encryption/hashing is done on the credentials. Still, if gsr.rb is incorporated into a Heroku app, for example, the spike credentials could be stored securely as environment variables.
38
+
39
+ ## TODO ##
40
+ * More robust cancellation system?
41
+ * Create gem
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/gsr/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = "Matt Parmett"
6
+ gem.email = "parm289@yahoo.com"
7
+ gem.description = %q{Ruby wrapper for the Wharton GSR Reservation System}
8
+ gem.summary = %q{Ruby wrapper for the Wharton GSR Reservation System}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "gsr"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Gsr::Ruby::VERSION
17
+
18
+ gem.add_dependency "mechanize"
19
+ end
@@ -0,0 +1,123 @@
1
+ require 'mechanize'
2
+ require 'open-uri'
3
+
4
+ #Utility time methods
5
+ class Time
6
+ #Converts start_time from time to formatted string
7
+ def format_start_time()
8
+ #Hour logic
9
+ if self.hour < 0
10
+ raise "Invalid self specified: hour can't be negative"
11
+ elsif self.hour == 0
12
+ hour = 12
13
+ half = "AM"
14
+ elsif self.hour == 12
15
+ hour = 12
16
+ half = "PM"
17
+ elsif self.hour > 12
18
+ hour = self.hour - 12
19
+ half = "PM"
20
+ else # 0 < self.hour < 12
21
+ hour = self.hour
22
+ half = "AM"
23
+ end
24
+
25
+ #Minute logic
26
+ if self.min < 10
27
+ min = "0" + self.min.to_s
28
+ else
29
+ min = self.min.to_s
30
+ end
31
+
32
+ return hour.to_s + ':' + min + " " + half
33
+ end
34
+
35
+ #Converts start_date from date to formatted string
36
+ def format_start_date()
37
+ if Date.valid_date?(self.year, self.month, self.day)
38
+ return self.month.to_s + '/' + self.day.to_s
39
+ else
40
+ raise "Invalid start date specified."
41
+ end
42
+ end
43
+ end
44
+
45
+ # GSR class handles making GSR reservations
46
+ class GSR
47
+ attr_accessor :username, :password, :spike_root_url
48
+
49
+ def initialize(username, password, spike_root_url = "http://spike.wharton.upenn.edu/m/gsr.cfm?logout=true")
50
+ @username = username
51
+ @password = password
52
+ @spike_root_url = spike_root_url
53
+ end
54
+
55
+ # Logs in to spike using mechanize
56
+ def spike_login()
57
+ agent = Mechanize.new
58
+ login = agent.get(self.spike_root_url) #Go to login page
59
+ loginform = agent.page.forms.first #Select login form
60
+ loginform.username = self.username
61
+ loginform.password = self.password
62
+ gsr = agent.submit(loginform, loginform.buttons.first) #Submit form and log in
63
+ return {'agent' => agent, 'gsr' => gsr}
64
+ end
65
+
66
+ #Reserves the GSR
67
+ #requirements is an optional hash with keys:
68
+ #floor (string [F, G, 2, 3]), start_time (Time), duration (integer, minutes [30,60, or 90])
69
+ def reserve(requirements)
70
+ #Check if we have a non-kosher floor and revert to default
71
+ requirements['floor'] = "" if !(requirements['floor'].nil?) and
72
+ !(["", "F", "G", "2", "3"].include? requirements['floor'])
73
+
74
+ #Default args
75
+ default_options = {'floor' => "", 'start_time' => Time.now, 'duration' => 90}
76
+ args = default_options.merge(requirements)
77
+
78
+ #Convert start_date and start_time from date and time to correct form format
79
+ start_time = args['start_time'].format_start_time
80
+ start_date = args['start_time'].format_start_date
81
+
82
+ #Duration logic - round to 30, 60, or 90 (nearest)
83
+ unless requirements['duration'].nil?
84
+ if args['duration'] <= 30
85
+ args['duration'] = 30
86
+ elsif args['duration'] <= 60
87
+ args['duration'] = 60
88
+ else
89
+ args['duration'] = 90
90
+ end
91
+ end
92
+
93
+ agent = spike_login()['agent'] # Mechanize agent at successful login page
94
+ gsr = spike_login()['gsr'] # Mechanize page = successful login page
95
+ gsrform = gsr.form_with(:action => 'https://spike.wharton.upenn.edu/m/gsr.cfm') #Select GSR form
96
+
97
+ #Input GSR info
98
+ gsrform.preferred_floor = args['floor']
99
+ gsrform.start_date = start_date
100
+ gsrform.start_time = start_time
101
+ gsrform.duration = args['duration']
102
+
103
+ #Submit reservation
104
+ submit = agent.submit(gsrform, gsrform.buttons.first)
105
+
106
+ #Check if successful
107
+ raise "Error reserving GSR. Check supplied parameters." if submit.link_with(:text => 'Cancel').nil?
108
+
109
+ end
110
+
111
+ #Cancels most recent GSR reservation
112
+ def cancel()
113
+ agent = spike_login()['agent'] # Mechanize agent at successful login page
114
+ gsr = spike_login()['gsr'] # Mechanize page = successful login page
115
+
116
+ cancel = gsr.link_with(:text => 'Cancel')
117
+ if (cancel.nil?)
118
+ raise "Error: You have no GSR reservation to cancel."
119
+ else
120
+ gsr = cancel.click
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,5 @@
1
+ module Gsr
2
+ module Ruby
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gsr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matt Parmett
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mechanize
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Ruby wrapper for the Wharton GSR Reservation System
31
+ email: parm289@yahoo.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - .gitignore
37
+ - Gemfile
38
+ - LICENSE
39
+ - README.md
40
+ - Rakefile
41
+ - gsr.gemspec
42
+ - lib/gsr.rb
43
+ - lib/gsr/version.rb
44
+ homepage: ''
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.23
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: Ruby wrapper for the Wharton GSR Reservation System
68
+ test_files: []