polyhoraire 1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|