polyhoraire 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Readme.rdoc +13 -0
- data/bin/polyhoraire +98 -0
- data/lib/google.atom.xsl +228 -0
- data/lib/google.xml.xsl +189 -0
- data/lib/google_exporter.rb +125 -0
- data/lib/html.xsl +256 -0
- data/lib/polyhoraire.rb +46 -0
- data/lib/polyhoraire/auth.rb +106 -0
- data/lib/polyhoraire/course.rb +41 -0
- data/lib/polyhoraire/period.rb +69 -0
- data/lib/polyhoraire/poly2XML.xsl +202 -0
- data/lib/polyhoraire/schedule.rb +55 -0
- data/lib/polyhoraire/trimester.rb +98 -0
- data/lib/setup.rb +25 -0
- data/test/asset/schedule.xml +115 -0
- data/test/polyhoraire/test_auth.rb +21 -0
- data/test/polyhoraire/test_course.rb +25 -0
- data/test/polyhoraire/test_period.rb +21 -0
- data/test/polyhoraire/test_schedule.rb +32 -0
- data/test/polyhoraire/test_trimester.rb +75 -0
- data/test/test_google_exporter.rb +29 -0
- data/test/ts_offline.rb +7 -0
- data/test/ts_online.rb +3 -0
- metadata +70 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'google/api_client'
|
3
|
+
require 'nokogiri'
|
4
|
+
require 'yaml'
|
5
|
+
require 'tzinfo'
|
6
|
+
|
7
|
+
class GoogleExporter
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
auth
|
11
|
+
@tz = TZInfo::Timezone.get('America/Montreal')
|
12
|
+
@sentEvents = Array.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def send(schedule,toCalID)
|
16
|
+
@sentEvents = Array.new
|
17
|
+
@sentCalendarID = toCalID
|
18
|
+
|
19
|
+
schedule.courses.each do |course|
|
20
|
+
course.periods.each do |period|
|
21
|
+
|
22
|
+
courseBeginsOn = schedule.trimester.starts + period.weekDay - 1
|
23
|
+
courseBeginsOn += 7 if period.week == 2
|
24
|
+
event = {
|
25
|
+
'summary' => course.acronym + '(' + period.group + ') ' + (period.isLab ? '[Lab]' : '') ,
|
26
|
+
'location' => period.location,
|
27
|
+
'timeZone' => 'America/Montreal',
|
28
|
+
'start' => {
|
29
|
+
'dateTime' => dateTime(courseBeginsOn, period.from),
|
30
|
+
'timeZone' => 'America/Montreal'
|
31
|
+
},
|
32
|
+
'end' => {
|
33
|
+
'dateTime' => dateTime(courseBeginsOn, period.to),
|
34
|
+
'timeZone' => 'America/Montreal'
|
35
|
+
},
|
36
|
+
'recurrence' => [
|
37
|
+
'RDATE;VALUE=DATE:' + rDates(schedule.trimester,period)
|
38
|
+
]
|
39
|
+
}
|
40
|
+
|
41
|
+
result = @client.execute(:api_method => @service.events.insert,
|
42
|
+
:parameters => {'calendarId' => toCalID},
|
43
|
+
:body_object => event,
|
44
|
+
:headers => {'Content-Type' => 'application/json'})
|
45
|
+
@sentEvents.push(result)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def deleteEvent(eventID,calendarID)
|
51
|
+
result = @client.execute(:api_method => @service.events.delete,
|
52
|
+
:parameters => {'calendarId' => calendarID, 'eventId' => eventID})
|
53
|
+
end
|
54
|
+
|
55
|
+
def deleteSentEvents
|
56
|
+
@sentEvents.each do |event|
|
57
|
+
deleteEvent(event.data.id,@sentCalendarID)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def selectCalendar(idUrl)
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# return : hash[:calendarID => :calendarName]
|
66
|
+
def calendarList
|
67
|
+
list = Hash.new
|
68
|
+
|
69
|
+
page_token = nil
|
70
|
+
result = client.execute(:api_method => service.calendar_list.list)
|
71
|
+
while true
|
72
|
+
entries = result.data.items
|
73
|
+
entries.each do |e|
|
74
|
+
list[e.id] = e.summary
|
75
|
+
end
|
76
|
+
if !(page_token = result.data.next_page_token)
|
77
|
+
break
|
78
|
+
end
|
79
|
+
result = client.execute(:api_method => service.calendar_list.list,
|
80
|
+
:parameters => {'pageToken' => page_token})
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def auth
|
85
|
+
oauth_yaml = YAML.load_file(Poly::userConfDir + '/google-api.yaml')
|
86
|
+
client = Google::APIClient.new
|
87
|
+
client.authorization.client_id = oauth_yaml["client_id"]
|
88
|
+
client.authorization.client_secret = oauth_yaml["client_secret"]
|
89
|
+
client.authorization.scope = oauth_yaml["scope"]
|
90
|
+
client.authorization.refresh_token = oauth_yaml["refresh_token"]
|
91
|
+
client.authorization.access_token = oauth_yaml["access_token"]
|
92
|
+
|
93
|
+
if client.authorization.refresh_token && client.authorization.expired?
|
94
|
+
client.authorization.fetch_access_token!
|
95
|
+
end
|
96
|
+
|
97
|
+
@service = client.discovered_api('calendar', 'v3')
|
98
|
+
|
99
|
+
@client = client
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def dateTime(date, time)
|
105
|
+
date = DateTime.parse(date.to_s + ' ' + time)
|
106
|
+
date = @tz.local_to_utc(date)
|
107
|
+
date.strftime('%FT%TZ')
|
108
|
+
end
|
109
|
+
|
110
|
+
def rDates(trimester,period)
|
111
|
+
str = ''
|
112
|
+
trimester.getDates(period).each do |date|
|
113
|
+
date = DateTime.parse(date.to_s + ' ' + period.from)
|
114
|
+
date = @tz.local_to_utc(date)
|
115
|
+
str += date.strftime('%Y%m%dT%H%M%SZ,')
|
116
|
+
end
|
117
|
+
str.chomp(',')
|
118
|
+
end
|
119
|
+
|
120
|
+
def to_calendar(xmlDoc)
|
121
|
+
xsl = Nokogiri::XSLT(File.read(Poly::XSLDocs[:exportGoogle]))
|
122
|
+
xsl.transform(xmlDoc)
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
data/lib/html.xsl
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<xsl:stylesheet version="1.0"
|
3
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions"
|
4
|
+
xmlns:php="http://php.net/xsl" xmlns:url="http://whatever/java/java.net.URLEncoder"
|
5
|
+
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:batch='http://schemas.google.com/gdata/batch'
|
6
|
+
xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gCal='http://schemas.google.com/gCal/2005'
|
7
|
+
xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/"CkYFSHg-fyp7ImA9WxRVGUo."'
|
8
|
+
exclude-result-prefixes="atom gCal openSearch gd fn url php">
|
9
|
+
|
10
|
+
|
11
|
+
<xsl:output encoding="UTF-8" method="html" indent="yes" />
|
12
|
+
<xsl:param name="app" />
|
13
|
+
|
14
|
+
<xsl:template match="/">
|
15
|
+
<xsl:apply-templates select="/root/form" />
|
16
|
+
<xsl:apply-templates select="/root/atom:feed" />
|
17
|
+
<xsl:apply-templates select="/root/linkButton" />
|
18
|
+
|
19
|
+
|
20
|
+
<xsl:element name="ul">
|
21
|
+
<xsl:apply-templates select="/root/addedRecently" />
|
22
|
+
</xsl:element>
|
23
|
+
</xsl:template>
|
24
|
+
|
25
|
+
<xsl:template match="addedRecently">
|
26
|
+
<xsl:if test="position() = 1">
|
27
|
+
<xsl:element name="h1">
|
28
|
+
<xsl:text>Modification récentes</xsl:text>
|
29
|
+
</xsl:element>
|
30
|
+
</xsl:if>
|
31
|
+
<xsl:element name="li">
|
32
|
+
<xsl:value-of select="."/>
|
33
|
+
</xsl:element>
|
34
|
+
</xsl:template>
|
35
|
+
|
36
|
+
<xsl:template
|
37
|
+
match="atom:feed[atom:id = 'http://www.google.com/calendar/feeds/default/allcalendars/full']">
|
38
|
+
<h3>Choix du calendrier</h3>
|
39
|
+
<table>
|
40
|
+
<xsl:apply-templates select="atom:entry" />
|
41
|
+
</table>
|
42
|
+
</xsl:template>
|
43
|
+
|
44
|
+
<xsl:template match="atom:feed"></xsl:template>
|
45
|
+
|
46
|
+
<xsl:template
|
47
|
+
match="atom:feed[atom:id = 'http://www.google.com/calendar/feeds/default/owncalendars/full']">
|
48
|
+
<xsl:element name="h1">
|
49
|
+
<xsl:text>Étape 2 : Choisir le calendrier</xsl:text>
|
50
|
+
</xsl:element>
|
51
|
+
<xsl:element name="ul">
|
52
|
+
<xsl:apply-templates select="atom:entry" />
|
53
|
+
</xsl:element>
|
54
|
+
</xsl:template>
|
55
|
+
|
56
|
+
<xsl:template match="atom:feed[contains(string(atom:id),'/batch/')]">
|
57
|
+
<xsl:if test="not(descendant::batch:status/@code = '201')">
|
58
|
+
<xsl:variable name="calendarUrl">
|
59
|
+
<xsl:value-of select="substring-before(descendant::atom:id, 'batch')" />
|
60
|
+
<xsl:text>batch</xsl:text>
|
61
|
+
</xsl:variable>
|
62
|
+
<xsl:call-template name="linkButton">
|
63
|
+
<xsl:with-param name="title">
|
64
|
+
Réessayer
|
65
|
+
</xsl:with-param>
|
66
|
+
<xsl:with-param name="link">?app=PolyHoraire&action=send
|
67
|
+
<xsl:value-of select="atom:title" />
|
68
|
+
&calendar=
|
69
|
+
<xsl:value-of select="$calendarUrl" />
|
70
|
+
</xsl:with-param>
|
71
|
+
|
72
|
+
</xsl:call-template>
|
73
|
+
</xsl:if>
|
74
|
+
<xsl:element name="table">
|
75
|
+
<xsl:apply-templates select="descendant::atom:entry" />
|
76
|
+
</xsl:element>
|
77
|
+
</xsl:template>
|
78
|
+
|
79
|
+
<xsl:template match="atom:entry[namespace::batch]">
|
80
|
+
<xsl:element name="tr">
|
81
|
+
<xsl:element name="td">
|
82
|
+
<xsl:value-of select="descendant::atom:title" />
|
83
|
+
</xsl:element>
|
84
|
+
<xsl:element name="td">
|
85
|
+
<xsl:choose>
|
86
|
+
<xsl:when test="descendant::batch:status/@code = '201'">
|
87
|
+
<xsl:attribute name="class">
|
88
|
+
<xsl:text>succes</xsl:text>
|
89
|
+
</xsl:attribute>
|
90
|
+
<xsl:element name="strong">
|
91
|
+
<xsl:text>Réussis</xsl:text>
|
92
|
+
</xsl:element>
|
93
|
+
</xsl:when>
|
94
|
+
<xsl:otherwise>
|
95
|
+
<xsl:attribute name="class">
|
96
|
+
<xsl:text>failed</xsl:text>
|
97
|
+
</xsl:attribute>
|
98
|
+
<xsl:element name="strong">
|
99
|
+
<xsl:text>Manqué</xsl:text>
|
100
|
+
</xsl:element>
|
101
|
+
</xsl:otherwise>
|
102
|
+
|
103
|
+
</xsl:choose>
|
104
|
+
</xsl:element>
|
105
|
+
</xsl:element>
|
106
|
+
|
107
|
+
</xsl:template>
|
108
|
+
|
109
|
+
<xsl:template match="atom:entry">
|
110
|
+
<xsl:element name="li">
|
111
|
+
<xsl:attribute name="class">
|
112
|
+
<xsl:text>linkButton</xsl:text>
|
113
|
+
</xsl:attribute>
|
114
|
+
<xsl:element name="span">
|
115
|
+
<xsl:attribute name="class">
|
116
|
+
<xsl:text>gradientBox</xsl:text>
|
117
|
+
</xsl:attribute>
|
118
|
+
<xsl:attribute name="style">
|
119
|
+
<xsl:text>background-color:</xsl:text>
|
120
|
+
<xsl:value-of select="gCal:color/@value" />
|
121
|
+
<xsl:text>;</xsl:text>
|
122
|
+
</xsl:attribute>
|
123
|
+
</xsl:element>
|
124
|
+
<xsl:element name="a">
|
125
|
+
<xsl:attribute name="href">
|
126
|
+
<xsl:text>?app=</xsl:text>
|
127
|
+
<xsl:value-of select="$app" />
|
128
|
+
<xsl:text>&action=send&calendar=</xsl:text>
|
129
|
+
<xsl:text>https://www.google.com/calendar/feeds/</xsl:text>
|
130
|
+
<xsl:value-of
|
131
|
+
select="substring-after(string(atom:id),'http://www.google.com/calendar/feeds/default/owncalendars/full/')" />
|
132
|
+
<xsl:text>/private/full/batch</xsl:text>
|
133
|
+
<!--
|
134
|
+
<xsl:choose>
|
135
|
+
<xsl:when test="function-available(url:encode)">
|
136
|
+
<xsl:value-of select="url:encode(atom:id)"/>
|
137
|
+
</xsl:when>
|
138
|
+
<xsl:when test="function-available(fn:encode-for-uri)">
|
139
|
+
<xsl:value-of select="fn:encode-for-uri(atom:id)"></xsl:value-of>
|
140
|
+
</xsl:when>
|
141
|
+
<xsl:otherwise>
|
142
|
+
<xsl:value-of select="php:function('urlencode',string(atom:id))"></xsl:value-of>
|
143
|
+
</xsl:otherwise>
|
144
|
+
</xsl:choose>
|
145
|
+
-->
|
146
|
+
</xsl:attribute>
|
147
|
+
<xsl:value-of select="atom:title" />
|
148
|
+
</xsl:element>
|
149
|
+
</xsl:element>
|
150
|
+
</xsl:template>
|
151
|
+
|
152
|
+
|
153
|
+
<xsl:template match="section[@name='signIn']">
|
154
|
+
<form action="?action=getSchedule" method="post">
|
155
|
+
<fieldset>
|
156
|
+
<legend>Identifiants du dossier étudiant</legend>
|
157
|
+
<div>
|
158
|
+
<label for="codeAcces">Code d'accèes</label>
|
159
|
+
<input type="text" id="codeAcces" />
|
160
|
+
</div>
|
161
|
+
<div>
|
162
|
+
<label for="motDePasse">Mot de passe</label>
|
163
|
+
<input type="password" id="motDePasse" />
|
164
|
+
</div>
|
165
|
+
<div>
|
166
|
+
<label for="dateDeNaissance">Date de naissance (AAMMJJ)</label>
|
167
|
+
<input type="text" id="dateDeNaissance" />
|
168
|
+
</div>
|
169
|
+
<button type="submit">Récupérer l'horaire</button>
|
170
|
+
</fieldset>
|
171
|
+
</form>
|
172
|
+
</xsl:template>
|
173
|
+
|
174
|
+
<xsl:template match="form">
|
175
|
+
<xsl:element name="form">
|
176
|
+
<xsl:attribute name="action">
|
177
|
+
<xsl:text>?app=</xsl:text>
|
178
|
+
<xsl:value-of select="$app" />
|
179
|
+
<xsl:text>&action=</xsl:text>
|
180
|
+
<xsl:value-of select="@action" />
|
181
|
+
</xsl:attribute>
|
182
|
+
<xsl:attribute name="method">
|
183
|
+
<xsl:text>post</xsl:text>
|
184
|
+
</xsl:attribute>
|
185
|
+
<xsl:apply-templates select="fieldset" />
|
186
|
+
</xsl:element>
|
187
|
+
</xsl:template>
|
188
|
+
|
189
|
+
<xsl:template match="fieldset">
|
190
|
+
<xsl:element name="fieldset">
|
191
|
+
<xsl:element name="legend">
|
192
|
+
<xsl:value-of select="@name" />
|
193
|
+
</xsl:element>
|
194
|
+
<xsl:apply-templates select="input|button" />
|
195
|
+
|
196
|
+
</xsl:element>
|
197
|
+
</xsl:template>
|
198
|
+
|
199
|
+
|
200
|
+
<xsl:template match="input">
|
201
|
+
<xsl:element name="div">
|
202
|
+
<xsl:element name="label">
|
203
|
+
<xsl:attribute name="for">
|
204
|
+
<xsl:value-of select="@id" />
|
205
|
+
</xsl:attribute>
|
206
|
+
<xsl:value-of select="@label" />
|
207
|
+
</xsl:element>
|
208
|
+
<xsl:element name="input">
|
209
|
+
<xsl:attribute name="type">
|
210
|
+
<xsl:value-of select="@type" />
|
211
|
+
</xsl:attribute>
|
212
|
+
<xsl:attribute name="name">
|
213
|
+
<xsl:value-of select="@id" />
|
214
|
+
</xsl:attribute>
|
215
|
+
</xsl:element>
|
216
|
+
</xsl:element>
|
217
|
+
</xsl:template>
|
218
|
+
|
219
|
+
<xsl:template match="button">
|
220
|
+
<xsl:element name="div">
|
221
|
+
<xsl:element name="button">
|
222
|
+
<xsl:attribute name="type">
|
223
|
+
<xsl:value-of select="@type" />
|
224
|
+
</xsl:attribute>
|
225
|
+
<xsl:value-of select="." />
|
226
|
+
</xsl:element>
|
227
|
+
</xsl:element>
|
228
|
+
</xsl:template>
|
229
|
+
|
230
|
+
<xsl:template match="linkButton">
|
231
|
+
<xsl:element name="a">
|
232
|
+
<xsl:attribute name="href">
|
233
|
+
<xsl:value-of select="@href" />
|
234
|
+
</xsl:attribute>
|
235
|
+
<xsl:attribute name="class">
|
236
|
+
<xsl:text>linkButton</xsl:text>
|
237
|
+
</xsl:attribute>
|
238
|
+
<xsl:value-of select="." />
|
239
|
+
</xsl:element>
|
240
|
+
</xsl:template>
|
241
|
+
|
242
|
+
<xsl:template name="linkButton">
|
243
|
+
<xsl:param name="link" />
|
244
|
+
<xsl:param name="title" />
|
245
|
+
<xsl:element name="a">
|
246
|
+
<xsl:attribute name="href">
|
247
|
+
<xsl:value-of select="$link" />
|
248
|
+
</xsl:attribute>
|
249
|
+
<xsl:attribute name="class">
|
250
|
+
<xsl:text>linkButton</xsl:text>
|
251
|
+
</xsl:attribute>
|
252
|
+
<xsl:value-of select="$title" />
|
253
|
+
</xsl:element>
|
254
|
+
</xsl:template>
|
255
|
+
|
256
|
+
</xsl:stylesheet>
|
data/lib/polyhoraire.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
|
8
|
+
module Poly
|
9
|
+
|
10
|
+
URL = {
|
11
|
+
:connection => "https://www4.polymtl.ca/servlet/ValidationServlet",
|
12
|
+
:schedule => "https://www4.polymtl.ca/servlet/PresentationHorairePersServlet"
|
13
|
+
}
|
14
|
+
|
15
|
+
XSLDocs = {
|
16
|
+
:poly2XML => File.dirname(__FILE__).to_s + "/polyhoraire/poly2XML.xsl",
|
17
|
+
:exportGoogle => File.dirname(__FILE__).to_s + "/google.xml.xsl"
|
18
|
+
}
|
19
|
+
|
20
|
+
@userConfDir = 'conf'
|
21
|
+
|
22
|
+
def self.userConfDir
|
23
|
+
@userConfDir
|
24
|
+
end
|
25
|
+
def self.userConfDir=(value)
|
26
|
+
@userConfDir = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch(uri,params)
|
30
|
+
url = URI.parse(uri)
|
31
|
+
|
32
|
+
req = Net::HTTP::Post.new(url.path)
|
33
|
+
req.form_data = params
|
34
|
+
con = Net::HTTP.new(url.host, url.port)
|
35
|
+
con.use_ssl = true
|
36
|
+
response = con.start {|http| http.request(req)}
|
37
|
+
|
38
|
+
case response
|
39
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
40
|
+
return response
|
41
|
+
else
|
42
|
+
response.error!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'polyhoraire'
|
2
|
+
|
3
|
+
class Poly::Auth
|
4
|
+
include Poly
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@postParams = Hash.new
|
8
|
+
@trimesters = Hash.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def connect(user, password, bday)
|
12
|
+
params = {
|
13
|
+
"code" => user,
|
14
|
+
"nip" => password,
|
15
|
+
"naissance" => bday }
|
16
|
+
response = fetch(Poly::URL[:connection],params)
|
17
|
+
extractInformation(response)
|
18
|
+
setStatus(response)
|
19
|
+
end
|
20
|
+
|
21
|
+
def connected?
|
22
|
+
return @connected
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def credentialsValid?(user,password,bday)
|
27
|
+
connect(user,password,bday)
|
28
|
+
return connected?
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# Getters
|
33
|
+
def postParams
|
34
|
+
return @postParams
|
35
|
+
end
|
36
|
+
def trimesters
|
37
|
+
return @trimesters
|
38
|
+
end
|
39
|
+
def error
|
40
|
+
return @error
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
def extractInformation(response)
|
50
|
+
doc = Nokogiri::HTML(response.body.to_s)
|
51
|
+
@trimesters = extractTrimesters(doc)
|
52
|
+
@postParams = extractPostParams(doc)
|
53
|
+
end
|
54
|
+
|
55
|
+
def extractTrimesters(doc)
|
56
|
+
trimesterList = doc.xpath("//select[@name = 'selTrimHorPers']/option")
|
57
|
+
|
58
|
+
trimesters = Hash.new()
|
59
|
+
trimesterList.each do |node|
|
60
|
+
trimesters[node.get_attribute(:value)] = node.content
|
61
|
+
end
|
62
|
+
return trimesters
|
63
|
+
end
|
64
|
+
|
65
|
+
def extractPostParams(doc)
|
66
|
+
hiddenFields = doc.xpath("//input[@name != 'trimestre']")
|
67
|
+
|
68
|
+
postParams = Hash.new()
|
69
|
+
hiddenFields.each do |node|
|
70
|
+
postParams[node.get_attribute(:name)] = node.get_attribute(:value)
|
71
|
+
end
|
72
|
+
return postParams
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
def setStatus(response)
|
81
|
+
doc = Nokogiri::HTML(response.body.to_s)
|
82
|
+
nodes = doc.xpath("//center/font[@color = '#FF0000']")
|
83
|
+
if nodes.empty?
|
84
|
+
@connected = true
|
85
|
+
else
|
86
|
+
@connected = false
|
87
|
+
|
88
|
+
# Extract the error number and message
|
89
|
+
@error = extractError(nodes.first)
|
90
|
+
raise "Not connected"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def extractError(node)
|
95
|
+
error = node.content
|
96
|
+
error.delete! ")"
|
97
|
+
splitted = error.split("(")
|
98
|
+
|
99
|
+
error = Hash.new
|
100
|
+
error[:number] = splitted[1]
|
101
|
+
error[:message] = splitted[0]
|
102
|
+
|
103
|
+
return error
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|