egduphsphonebookadapt 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +15 -0
  2. data/lib/egduphsphonebookadapt.rb +162 -0
  3. metadata +52 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDRhYWNiM2ZlMGNlMTliYTg1ZDY4OWM0NDUyMDUwNzhmYmIxZGZjNA==
5
+ data.tar.gz: !binary |-
6
+ NzBkMTZhZWY5ZTNmYzQyZjY2M2Y0NWMzNmI3MDAzNWUyODk5ZWEwNw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZGYzZjJmNjUwNTQ1NzlmZWYwZTViMjk2NWY3OGRiZmQyNTdiYTMwNDc3OWFl
10
+ YWY1YTY1MGRiZjUzMDdiYzU3NGU3ZjZkMjg0NWE4MGQzMzJmZDgyNTI4MWJj
11
+ OGQ1NzNhNGU5ODZkOThjOTZjYzY0MDZjNjA1ZWU5MjY4Y2YzZmM=
12
+ data.tar.gz: !binary |-
13
+ ZjE1NTkxOGI0ZDI0M2YzYjk0YjcyNDBiMTFlYWY3ZTBiYWE2NmNkNjhkY2M4
14
+ YTA3NmI4MzE3MTJjODJkMDExZjc5MWEwMzMyMDE5MTUyNTc0ZGFkMDM3MTVm
15
+ Y2NlNGE2MTQ5ZGMxZTJkMmE1ZWE1YzhhNmVhZWU4NWRiZDI4ZDU=
@@ -0,0 +1,162 @@
1
+ require 'json'
2
+ require "date"
3
+ #require 'mechanize'
4
+ require 'yaml'
5
+ require 'nokogiri'
6
+
7
+ class Phonebook
8
+
9
+ def initialize
10
+ @agent = new_agent
11
+ end
12
+
13
+ def onVPN?
14
+ @VPN
15
+ end
16
+
17
+ def search_results(name_hash, options = nil)
18
+ page = search_result_page(name_hash)
19
+ results = create_hash_from_page(page)
20
+ results = results.flatten.to_json if options != nil && options[:format] =~ /json/i
21
+ results
22
+ end
23
+
24
+ def self.search_results(name_hash, options = nil)
25
+ p = Phonebook.new
26
+ results = p.search_results(name_hash, options)
27
+ end
28
+
29
+ def get_entire_phonebook()
30
+ first_page = search_result_page(:first => '', :last => '')
31
+ results = []
32
+ current_page = first_page
33
+ #while (current_page.forms.first.buttons[-3].name == 'ctl00$CPHBody$GridView1$ctl14$ImgBtnNextPage') do
34
+ 10.times do
35
+ results = results + create_hash_from_page(current_page)
36
+ next_page_button = current_page.forms.first.buttons[-3]
37
+ current_page = current_page.forms.first.submit(next_page_button)
38
+ end
39
+ results
40
+ end
41
+
42
+
43
+ EMAIL_REGEX = /[\w+\-.]+@[a-z\d\-.]+\.[a-z]+/i
44
+ def new_agent
45
+ begin
46
+ agent = Mechanize.new
47
+ agent.get('http://uphsxnet.uphs.upenn.edu/pb/main/search.aspx')
48
+ @VPN = true
49
+ rescue Mechanize::ResponseCodeError
50
+ @VPN = false
51
+ raise 'You Are Not On The Intranet'
52
+ end
53
+ agent
54
+ end
55
+
56
+ def create_hash_from_page(page, options = nil)
57
+ array_of_raw_text_hashes = pull_result_text_strings(page)
58
+ result = []
59
+ array_of_raw_text_hashes.each do |person|
60
+ result << parse_person_hash(person)
61
+ end
62
+ result
63
+ end
64
+
65
+ def get_source_code_from_page(page)
66
+ if page.class.to_s == 'String'
67
+ page[400...page.length]
68
+ else
69
+ page.body[400...page.body.length]
70
+ end
71
+ end
72
+
73
+ def pull_result_text_strings(page)
74
+ source_code = get_source_code_from_page(page)
75
+ result = []
76
+
77
+ Nokogiri::HTML(source_code).css('.record').each do |lines|
78
+ result.push(lines.inner_text)
79
+ end
80
+ num_of_results = result.length/3
81
+ array_of_results = []
82
+ (0...num_of_results).each do |person|
83
+ count = person * 3
84
+ array_of_results.push({:name_string => result[count], :location_string => result[count+1], :contact_info_string => result[count+2]})
85
+ end
86
+ array_of_results
87
+ end
88
+
89
+ def parse_location_string(location)
90
+ location.scan(/\S*\b/).inject do |memo, word|
91
+ memo = "#{memo} #{word}"
92
+ end
93
+ end
94
+
95
+ def parse_person_hash(person)
96
+ return {
97
+ :name => parse_name_string(person[:name_string]),
98
+ :location => parse_location_string(person[:location_string]),
99
+ :contact_info => parse_contact_information(person[:contact_info_string])
100
+ }
101
+ end
102
+
103
+ def parse_name_string(string)
104
+ string.strip.match(/\A.*/)[0].rstrip
105
+ end
106
+
107
+ def parse_contact_information(string)
108
+ numbers = string.scan(/\(\d\d\d\) \d\d\d-\d\d\d\d \(\D*\)/)
109
+ if numbers == nil
110
+ return "no matches found while searching the result string"
111
+ end
112
+ result = {}
113
+ numbers.each do |number|
114
+ key = number.match(/\(\D*\)/)
115
+ key = key[0]
116
+ key = key[1...(key.length-1)]
117
+
118
+ val = number.match(/\(\d\d\d\) \d\d\d-\d\d\d\d/)[0]
119
+ result[key] = val
120
+ end
121
+ result['email'] = string.match(EMAIL_REGEX)[0] if string =~ EMAIL_REGEX
122
+ result
123
+ end
124
+
125
+ def search_results_text_string(name_hash)
126
+ pull_result_text_strings search_result_page(name_hash)
127
+ end
128
+
129
+ def search_result_page(name_hash)
130
+ @agent.post(search_uri, full_search_form(name_hash))
131
+ end
132
+
133
+ def full_search_form(name_hash)
134
+ params = basic_params
135
+ params[first_name_key], params[last_name_key] = name_hash[:first], name_hash[:last]
136
+ params
137
+ end
138
+ def search_uri
139
+ uri = URI("http://uphsxnet.uphs.upenn.edu/pb/main/Results.aspx")
140
+ end
141
+ def last_name_key
142
+ 'ctl00$CPHBody$TxtLastName'
143
+ end
144
+ def first_name_key
145
+ 'ctl00$CPHBody$TxtFirstName'
146
+ end
147
+ def basic_params
148
+ params = {
149
+ '__EVENTTARGET' => '',
150
+ '__EVENTARGUMENT' => '',
151
+ '__LASTFOCUS' => '',
152
+ '__VIEWSTATE' => "/wEPDwUJODE4NDE2OTMxD2QWAmYPZBYKAgEPFCsAAmQQFgJmAgEWAhYCHgtOYXZpZ2F0ZVVybAUdaHR0cDovL3VwaHNuZXQudXBocy51cGVubi5lZHUWAh8ABTJodHRwOi8vdXBoc3huZXQudXBocy51cGVubi5lZHUvcGIvbWFpbi9TZWFyY2guYXNweBYCAgECAWQCAg8PFgIfAAUyaHR0cDovL3VwaHN4bmV0LnVwaHMudXBlbm4uZWR1L3BiL21haW4vU2VhcmNoLmFzcHhkZAIDDw8WAh8ABTRodHRwczovL3d3dy5wZW5ubWVkaWNpbmUub3JnL3BiL21haW4vQWRkUHJvZmlsZS5hc3B4ZGQCBA8PFgIfAAVHaHR0cDovL3VwaHN4bmV0LnVwaHMudXBlbm4uZWR1L3dhZ2Zvcm0vTWFpblBhZ2UuYXNweD9jb25maWc9UGhvbmVCS0RlcHRkZAIFD2QWAgIBD2QWAgIBD2QWAmYPZBYCAhEPZBYEAgUPEGRkFgBkAgkPEGRkFgFmZBgBBR5fX0NvbnRyb2xzUmVxdWlyZVBvc3RCYWNrS2V5X18WAQUWY3RsMDAkQ1BIQm9keSRDaGtTb3VuZCO/QfmaJs0Nh7aMMG5a5fouPscW",
153
+ "__PREVIOUSPAGE" =>"LGvxaPcY7PZkrvDYFcvX-pr62ylAE4Y2Ygd52Jnh4xSGP8-Lpp6hYdYZYUwcmra0pcKk8cdIkCNrfp6LC-oGF67F8BeWSmaOW7d9mS_LzPUWNWRt0",
154
+ '__EVENTVALIDATION' => "/wEWDQL9sunMAQL1+8m8BALz3azcAgKm1KVQAuzb4JIJArCQl/MLAq25g7YOApncg6QMAoT1l+EJAtLMyJIJApDxvY0FAs+B3aUKApji1LEP2V0HX+LWQa+Ohm8tjlJWtmwvVs0=",
155
+ 'ctl00$CPHBody$LbEntity' => 'ALL',
156
+ 'ctl00$CPHBody$DdlDiv' => "ALL",
157
+ 'ctl00$CPHBody$TxtNumber' => '',
158
+ 'ctl00$CPHBody$HidSession' => '',
159
+ 'ctl00$CPHBody$BtnSubmit' => "Search"}
160
+ end
161
+
162
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: egduphsphonebookadapt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ platform: ruby
6
+ authors:
7
+ - Eugene Gitelman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ! "The class gives you a search function, which takes a hash in form
14
+ of {:first => first_name, :last => last_name} and returns an array of hashes corresponding
15
+ to results. you can send an options hash with :form => 'json' \n to
16
+ get the results as JSON \n\n example: Phonebook.new.search_results(:first
17
+ => 'Bob', :last => 'Jones') will produce '[{:name=>Jones, Bob, :location=>HUP Medicine
18
+ \ Department of 3400 Spruce St, :contact_info=>{Office=>(215) 5555-5555, Cell=>(215)
19
+ 555-5555, email=>Bob.jones@uphs.upenn.edu}}]' \n \n this is an
20
+ array, even if there is only one result. Can also call Phonebook.search_results(name_hash,
21
+ options)"
22
+ email:
23
+ - eugyev@gmail.com
24
+ executables: []
25
+ extensions: []
26
+ extra_rdoc_files: []
27
+ files:
28
+ - lib/egduphsphonebookadapt.rb
29
+ homepage:
30
+ licenses: []
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.2.2
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: pulls data for UPHS phonebook. ONLY on VPN
52
+ test_files: []