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.
@@ -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