polyhoraire 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ require 'polyhoraire'
2
+ require 'polyhoraire/period'
3
+ require 'nokogiri'
4
+
5
+ class Poly::Course
6
+ @periodes = Hash.new
7
+ attr_reader :acronym, :name, :professor, :group, :labGroup, :creditNbr, :periods
8
+ attr_writer :acronym, :name, :professor, :group, :labGroup, :creditNbr
9
+
10
+ def self.from_nokogiri(doc)
11
+ courses = Array.new
12
+
13
+ nodeSet = doc.xpath("//cour")
14
+ nodeSet.each do |node|
15
+ course = self.new
16
+
17
+ course.acronym = node.attribute("sigle").text
18
+ course.name = node.xpath("nom").text
19
+ course.professor = node.xpath("prof").text
20
+ course.group = node.xpath("groupeTheorie").text
21
+ course.labGroup = node.xpath("groupeLaboratoire").text
22
+ course.creditNbr = node.xpath("nombreCredits").text
23
+
24
+ course.addPeriods(doc)
25
+
26
+ courses.push(course)
27
+ end
28
+ return courses
29
+ end
30
+
31
+ def addPeriods (xml)
32
+ @periods = Poly::Period.from_nokogiri(xml,@acronym)
33
+ end
34
+
35
+ def description
36
+ name + '\n' +
37
+ '\t\t - Professeur : ' + professor + '\n' +
38
+ '\t\t - Groupe cours : ' + group + '\n' +
39
+ '\t\t - Groupe lab : ' + labGroup
40
+ end
41
+ end
@@ -0,0 +1,69 @@
1
+ require 'polyhoraire'
2
+
3
+ require 'nokogiri'
4
+
5
+ class Poly::Period
6
+ include Poly
7
+ attr_reader :from, :to,:week, :weekDay, :group, :location, :isLab
8
+
9
+ def initialize(from,to,week,weekDay,group,location,isLab)
10
+ @from = from
11
+ @to = to
12
+ @week = week
13
+ @weekDay = weekDay
14
+ @group = group
15
+ @location = location
16
+ @isLab = isLab
17
+ end
18
+
19
+ def self.from_nokogiri(doc, acronym)
20
+ nodeSet = doc.xpath("//evenement[sigle = '" + acronym + "']")
21
+ if nodeSet.nil? || nodeSet.empty?
22
+ raise ArgumentError
23
+ else
24
+ periods = Array.new
25
+ nodeSet.each do |node|
26
+ periods.push self.parse_node(node)
27
+ end
28
+
29
+ return periods
30
+ end
31
+ end
32
+
33
+ def dates(trimester,week,day)
34
+ return @trimester.week[week][day]
35
+ end
36
+
37
+ def to_s
38
+ puts "---"
39
+ puts "From : " + @from + " To : " + @to + " On day : " + @weekDay
40
+ puts "---"
41
+ end
42
+
43
+ private
44
+
45
+ def self.parse_node(node)
46
+ moment = node.xpath("moment")
47
+
48
+ from = moment.attribute('debut').text
49
+ to = moment.attribute('fin').text
50
+ week = extractWeek(moment.attribute('semaine').text)
51
+ weekDay = moment.attribute('jour').text.to_i
52
+ group = node.xpath("groupe").text
53
+ location = node.xpath("local").text
54
+ isLab = node.attribute("type").text == "lab"
55
+
56
+ self.new(from,to,week,weekDay,group,location,isLab)
57
+ end
58
+
59
+ def self.extractWeek(string)
60
+ case string
61
+ when 'B1'
62
+ return 1
63
+ when 'B2'
64
+ return 2
65
+ else
66
+ return 0
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,202 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet version="1.0"
3
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4
+ xmlns:str="http://exslt.org/strings"
5
+ xmlns:exslt="http://exslt.org/common"
6
+ xmlns:fn="http://www.w3.org/2005/xpath-functions"
7
+ exclude-result-prefixes="str fn exslt">
8
+
9
+
10
+ <!-- Pour la transformation d'identidees -->
11
+ <xsl:template>
12
+ <xsl:call-template name="IdentityTransform"/>
13
+ </xsl:template>
14
+
15
+ <xsl:template name="IdentityTransform">
16
+ <xsl:copy>
17
+ <xsl:apply-templates select="@*|node()"/>
18
+ </xsl:copy>
19
+ </xsl:template>
20
+
21
+ <xsl:template match="/">
22
+ <poly>
23
+ <informations>
24
+ <xsl:for-each select="html/body/center/table[2]/tr/td/table/tr[position() &gt; 1 and position() &lt; last()]">
25
+ <xsl:element name="cour">
26
+ <xsl:attribute name="sigle"><xsl:value-of select="normalize-space(td)"/></xsl:attribute>
27
+ <nom><xsl:value-of select="normalize-space(td[2]/node())"/></nom>
28
+ <prof><xsl:value-of select="normalize-space(td[2]/node()[last()])"/></prof>
29
+ <groupeTheorie><xsl:value-of select="normalize-space(td[3])"/></groupeTheorie>
30
+ <groupeLaboratoire><xsl:value-of select="normalize-space(td[4])"/></groupeLaboratoire>
31
+ <nombreCredits><xsl:value-of select="normalize-space(td[5])"/></nombreCredits>
32
+ </xsl:element>
33
+ </xsl:for-each>
34
+ </informations>
35
+ <horaire>
36
+ <xsl:call-template name="tJournee"> <xsl:with-param name="numero" select="1"/> </xsl:call-template>
37
+ <xsl:call-template name="tJournee"> <xsl:with-param name="numero" select="2"/> </xsl:call-template>
38
+ <xsl:call-template name="tJournee"> <xsl:with-param name="numero" select="3"/> </xsl:call-template>
39
+ <xsl:call-template name="tJournee"> <xsl:with-param name="numero" select="4"/> </xsl:call-template>
40
+ <xsl:call-template name="tJournee"> <xsl:with-param name="numero" select="5"/> </xsl:call-template>
41
+ </horaire>
42
+ </poly>
43
+ </xsl:template>
44
+
45
+ <xsl:template name="tJournee">
46
+ <xsl:param name="numero"/>
47
+
48
+ <xsl:variable name="journee">
49
+ <xsl:for-each select="html/body/center/table[3]/tr/td/table/tr/td[position() = ($numero + 1)]">
50
+ <xsl:choose>
51
+ <xsl:when test="./font">
52
+ <xsl:element name="periode">
53
+ <xsl:attribute name="heure">
54
+ <xsl:value-of select="substring-before(string(../td[position()=1]),'h') + 0"/>
55
+ <xsl:text>:</xsl:text>
56
+ <xsl:value-of select="substring-after(string(../td[position()=1]),'h') + 0"/>
57
+ </xsl:attribute>
58
+
59
+ <xsl:for-each select="font/node()">
60
+ <xsl:choose>
61
+ <xsl:when test="contains(string(.), 'Lab')">
62
+ <infoSemaine><xsl:call-template name="IdentityTransform"/></infoSemaine>
63
+ </xsl:when>
64
+ <xsl:when test="contains(string(.), '(')">
65
+ <infoCour><xsl:call-template name="IdentityTransform"/></infoCour>
66
+ </xsl:when>
67
+ </xsl:choose>
68
+ </xsl:for-each>
69
+ </xsl:element>
70
+ </xsl:when>
71
+
72
+ <xsl:otherwise>
73
+ <xsl:element name="periode">
74
+ <xsl:attribute name="heure">
75
+ <xsl:value-of select="substring-before(string(../td[position()=1]),'h') + 0"/>
76
+ <xsl:text>:</xsl:text>
77
+ <xsl:value-of select="substring-after(string(../td[position()=1]),'h') + 0"/>
78
+ </xsl:attribute>
79
+
80
+ <xsl:for-each select="node()">
81
+ <xsl:choose>
82
+ <xsl:when test="contains(string(.), 'Lab')">
83
+ <infoSemaine><xsl:call-template name="IdentityTransform"/></infoSemaine>
84
+ </xsl:when>
85
+ <xsl:when test="contains(string(.), '(')">
86
+ <infoCour><xsl:call-template name="IdentityTransform"/></infoCour>
87
+ </xsl:when>
88
+ </xsl:choose>
89
+ </xsl:for-each>
90
+ </xsl:element>
91
+
92
+ </xsl:otherwise>
93
+ </xsl:choose>
94
+
95
+
96
+ </xsl:for-each>
97
+ </xsl:variable>
98
+
99
+ <xsl:variable name="heures">
100
+ <xsl:for-each select="exslt:node-set($journee)">
101
+ <xsl:for-each select="periode">
102
+ <xsl:variable name="listeCoursPrecedents">
103
+ <xsl:for-each select="preceding-sibling::periode[1]/infoCour">
104
+ <xsl:value-of select="."/>
105
+ </xsl:for-each>
106
+ </xsl:variable>
107
+ <xsl:for-each select="./infoCour">
108
+ <xsl:choose>
109
+ <xsl:when test="not(contains(string($listeCoursPrecedents),string(.)))">
110
+ <xsl:element name="debut">
111
+
112
+ <xsl:choose>
113
+ <xsl:when test="following-sibling::*[1 and name()='infoSemaine']">
114
+ <xsl:attribute name="type">lab</xsl:attribute>
115
+ <xsl:attribute name="semaine">
116
+ <xsl:choose>
117
+ <xsl:when test="contains(string(following-sibling::*[1 and name()='infoSemaine']),'B1')">B1</xsl:when>
118
+ <xsl:when test="contains(string(following-sibling::*[1 and name()='infoSemaine']),'B2')">B2</xsl:when>
119
+ </xsl:choose>
120
+ </xsl:attribute>
121
+ </xsl:when>
122
+ <xsl:otherwise>
123
+ <xsl:attribute name="type">cours</xsl:attribute>
124
+ </xsl:otherwise>
125
+ </xsl:choose>
126
+
127
+ <xsl:attribute name="cour"><xsl:value-of select="str:tokenize(.)"/></xsl:attribute>
128
+ <xsl:attribute name="groupe"><xsl:value-of select="substring(string(str:tokenize(string(.))[2]),2,2)"/></xsl:attribute>
129
+ <xsl:attribute name="local"><xsl:value-of select="str:tokenize(.)[3]"/></xsl:attribute>
130
+ <xsl:attribute name="heure"><xsl:value-of select="../@heure"/></xsl:attribute>
131
+ </xsl:element>
132
+ </xsl:when>
133
+ </xsl:choose>
134
+ </xsl:for-each>
135
+
136
+ <xsl:variable name="listeCoursSuivants">
137
+ <xsl:for-each select="following-sibling::periode[1]/infoCour">
138
+ <xsl:value-of select="."/>
139
+ </xsl:for-each>
140
+ </xsl:variable>
141
+
142
+ <xsl:for-each select="./infoCour">
143
+ <xsl:choose>
144
+ <xsl:when test="not(contains(string($listeCoursSuivants),string(.)))">
145
+ <xsl:element name="fin">
146
+ <xsl:attribute name="cour"><xsl:value-of select="str:tokenize(.)"/></xsl:attribute>
147
+ <xsl:attribute name="groupe"><xsl:value-of select="substring(string(str:tokenize(string(.))[2]),2,2)"/></xsl:attribute>
148
+ <xsl:attribute name="local"><xsl:value-of select="str:tokenize(.)[3]"/></xsl:attribute>
149
+ <xsl:attribute name="heure">
150
+ <xsl:value-of select="substring-before(string(../@heure),':') + 1"/>
151
+ <xsl:text>:</xsl:text>
152
+ <xsl:value-of select="substring-after(string(../@heure),':') + 0"/>
153
+ </xsl:attribute>
154
+
155
+ </xsl:element>
156
+ </xsl:when>
157
+ </xsl:choose>
158
+ </xsl:for-each>
159
+
160
+ </xsl:for-each>
161
+ </xsl:for-each>
162
+ </xsl:variable>
163
+
164
+
165
+ <xsl:for-each select="exslt:node-set($heures)">
166
+ <xsl:for-each select="./debut">
167
+ <evenement>
168
+ <xsl:attribute name="type">
169
+ <xsl:value-of select="@type"></xsl:value-of>
170
+ </xsl:attribute>
171
+ <moment>
172
+ <xsl:attribute name="semaine">
173
+ <xsl:value-of select="@semaine"/>
174
+ </xsl:attribute>
175
+ <xsl:attribute name="jour">
176
+ <xsl:value-of select="$numero"/>
177
+ </xsl:attribute>
178
+ <xsl:attribute name="debut">
179
+ <xsl:value-of select="@heure"/>
180
+ </xsl:attribute>
181
+ <xsl:attribute name="fin">
182
+ <xsl:value-of select="following-sibling::fin[@cour = current()/@cour]/@heure"/>
183
+ </xsl:attribute>
184
+ </moment>
185
+ <sigle>
186
+ <xsl:value-of select="@cour"/>
187
+ </sigle>
188
+ <groupe>
189
+ <xsl:value-of select="@groupe"/>
190
+ </groupe>
191
+ <local>
192
+ <xsl:value-of select="@local"/>
193
+ </local>
194
+ </evenement>
195
+ </xsl:for-each>
196
+ </xsl:for-each>
197
+
198
+ </xsl:template>
199
+
200
+
201
+
202
+ </xsl:stylesheet>
@@ -0,0 +1,55 @@
1
+ require 'polyhoraire'
2
+ require 'polyhoraire/trimester'
3
+ require 'polyhoraire/course'
4
+
5
+ class Poly::Schedule
6
+ include Poly
7
+ attr_reader :trimester
8
+
9
+ # Trimesters : Hash of the possible trimesters {:id => :label}
10
+ # postParams : PostParams obtained from the connection
11
+ def initialize(auth,trimester)
12
+ @params = auth.postParams
13
+ @trimesters = auth.trimesters
14
+
15
+ @trimester = Poly::Trimester.fromYAML(trimester)
16
+
17
+ get(trimester)
18
+ end
19
+
20
+ def to_xml
21
+ to_xml_doc.to_s
22
+ end
23
+
24
+ def to_xml_doc
25
+ html = @response.body.to_s
26
+ # Too much spaces, substring-after wont work in some case if their still have trailling character '&#160;'
27
+ html.gsub!("&#160;","")
28
+
29
+ doc = Nokogiri::HTML(html) do |config|
30
+ config.noent
31
+ end
32
+
33
+ xsl = Nokogiri::XSLT(File.read(Poly::XSLDocs[:poly2XML]))
34
+
35
+ return xsl.transform(doc)
36
+ end
37
+
38
+ def courses
39
+ doc = to_xml_doc
40
+ Poly::Course.from_nokogiri(doc)
41
+ end
42
+
43
+ private
44
+
45
+ def get(trimester)
46
+ raise "Invalid trimester" unless trimesterValid?(trimester)
47
+
48
+ @params['trimestre'] = trimester
49
+ @response = fetch(Poly::URL[:schedule],@params)
50
+ end
51
+
52
+ def trimesterValid?(id)
53
+ return @trimesters.has_key?(id.to_s)
54
+ end
55
+ end
@@ -0,0 +1,98 @@
1
+ require 'polyhoraire'
2
+ require 'yaml'
3
+
4
+ class Poly::Trimester
5
+ attr_reader :week, :starts
6
+
7
+ DAY_RANGE = (1..5)
8
+ WEEK_RANGE = (1..2)
9
+
10
+ # Create from a YAML file wich is situated in 'conf/trimesters.yaml'
11
+ def self.fromYAML(trimesterID)
12
+ config = YAML.load_file(Poly::userConfDir + "/trimesters.yaml")
13
+ raise ArgumentError, "Invalid trimester : " + trimesterID.to_s unless config.include?(trimesterID)
14
+ selected = config[trimesterID]
15
+
16
+
17
+ starts = selected['starts']
18
+ schoolBreak = selected['schoolBreak']
19
+ ends = selected['ends']
20
+ holidays = selected['holidays']
21
+ exceptions = selected['exceptions']
22
+
23
+ return self.new(starts, schoolBreak, ends, holidays, exceptions)
24
+ end
25
+
26
+ # period : Period object for wich you want every dates it occurs
27
+ # Returns the list of dates for the course period
28
+ def getDates(period)
29
+ if period.week == 0
30
+ dates = @week[1][period.weekDay] + @week[2][period.weekDay]
31
+ return dates.sort
32
+ end
33
+ return @week[period.week][period.weekDay].sort
34
+ end
35
+
36
+ private
37
+
38
+ def initialize(starts, schoolBreak, ends, holidays, exceptions)
39
+ @starts = starts
40
+ @schoolBreak = schoolBreak
41
+ @ends = ends
42
+ @holidays = holidays
43
+ @exceptions = exceptions
44
+
45
+ @week = Hash.new
46
+ generateDates
47
+ end
48
+
49
+ def generateDates
50
+ WEEK_RANGE.each do |w|
51
+ @week[w] = Hash.new
52
+ DAY_RANGE.each do |d|
53
+ @week[w][d] = datesFor(d,w)
54
+ end
55
+ end
56
+ end
57
+
58
+ def datesFor(day,week)
59
+
60
+ raise ArgumentError, "Day not in accepted range" unless DAY_RANGE.cover?(day)
61
+ raise ArgumentError, "Week not in accepted range" unless WEEK_RANGE.cover?(week)
62
+ starts = @starts + day-1 + 7*(week-1)
63
+
64
+ dates = Array.new
65
+ dates = datesUntil(starts,@schoolBreak)
66
+ dates += datesUntil(dates.last + 21,@ends)
67
+ dates += exceptionDates(day,week)
68
+
69
+ return dates
70
+ end
71
+
72
+ def exceptionDates(day,week)
73
+ dates = Array.new
74
+ @exceptions.each do |date, changedTo|
75
+ if changedTo['week'] == 'b' + week.to_s and changedTo['day'] == day
76
+ dates.push(date)
77
+ end
78
+ end
79
+
80
+ return dates
81
+ end
82
+
83
+ def datesUntil(from, to)
84
+ dates = Array.new
85
+
86
+ iDate = from
87
+ while (iDate <=> to) == -1
88
+ dates.push(iDate) unless dayChanged?(iDate)
89
+ iDate += 14
90
+ end
91
+ return dates
92
+ end
93
+
94
+ def dayChanged?(date)
95
+ @exceptions.has_key?(date) or @holidays.include?(date)
96
+ end
97
+
98
+ end