2 # -*- coding: utf-8 -*-
8 import xml
.dom
.minidom
as dom
12 from base64
import b64decode
, b64encode
13 from urllib
import URLopener
, urlencode
14 from urllib2
import build_opener
, HTTPCookieProcessor
, URLError
15 from cookielib
import CookieJar
18 CONFIG_DIR
= user
.home
+os
.sep
+".config"+os
.sep
+"ade-programme"+os
.sep
19 CONFIG_FILE
= "config.xml"
20 BASE_IMG_URL
= "http://web.univ-ubs.fr/ade/imageEt?projectId=3&idPianoD\
21 ay=0%2C1%2C2%2C3%2C4&width=800&height=500&lunchName=REPAS&displayMode=1\
22 057855&showLoad=false&ttl=1272441274368&displayConfId=8"
25 class AdeConnectionUtil
:
34 """ Initialisation de AdeConnectionUtil
35 Cette méthode permet de construire le connecteur de site et le
36 gestionnaire de cookie."""
38 self
.connection
= build_opener(HTTPCookieProcessor(self
.CJ
))
40 def setIds(self
, newusername
, newpassword
):
41 """ Initialisation des username password
42 Sans ceux-ci, impossible de se connecter."""
43 checkType(newusername
, str)
44 checkType(newpassword
, str)
46 self
.username
= newusername
47 self
.password
= newpassword
49 def getConnection(self
, force
= False, username
= None, password
= None):
50 """ Méthode appelée par toutes les autres méthodes de la classe
51 Elle permet de voir si on a déjà récupérer les cookies nécéssaires
52 à la connection sur Ade. """
53 if force
:self
.connected
= False
54 if not(username
and password
):
55 username
= self
.username
56 password
= self
.password
57 if not(self
.connected
):
59 u
= self
.connection
.open("https://cas.univ-ubs.fr/login").read()
60 f
= '<input type="hidden" name="lt" value="'
62 r
= u
.rfind('" />\n\t\t\t\t\t\t<input type="hidden" name="_eventId"')
69 "submit":"SE CONNECTER"
72 self
.connection
.open("https://cas.univ-ubs.fr/login", params
)
74 u
= self
.connection
.open("http://web.univ-ubs.fr/edt/ade/custom/myplanning/myPlanning.jsp?top=top.moniframeesup")
76 f
= '<FRAME src="../../'
78 r
= u
.rfind('" name="planning">')
84 self
.connection
.open("http://web.univ-ubs.fr/edt/ade/"+data
)
90 """ Méthode permettant de connaitre les différents groups attachés
91 à l'année qu'est en train de suivre l'élève qui se connecte. """
95 u
= self
.connection
.open("http://web.univ-ubs.fr/ade/standard/gui/tree.jsp?forceLoad=false&isDirect=true")
97 """start = u.find("treelineselected")
98 end = u.rfind("treelineselected")
99 u = u[start:end+300]"""
100 u
= string
.join(string
.split(u
, "javascript:check("), "<DEB>")
101 u
= string
.join(string
.split(u
, ", 'true');\">"), "<SEP>")
102 u
= string
.join(string
.split(u
, ", 'false');\">"), "<SEP>")
103 u
= string
.join(string
.split(u
, "</a>"), "<FIN>")
104 list = re
.findall("<DEB>([0-9]*)<SEP>([0-9a-zA-Z -]*)<FIN>", u
)
106 groups
[i
[1]] = int(i
[0])
111 def getCorrectId(self
):
112 """ Permet d'obtenir un identifiant unique afin de pouvoir télécharger
113 les plannings et autres informations... """
114 if not(self
.identifier
):
117 u
= self
.connection
.open("http://web.univ-ubs.fr/ade/custom/modules/plannings/imagemap.jsp?width=800&height=600")
119 f
= '<img border=0 src="/ade/imageEt?identifier='
121 r
= u
.rfind('&projectId=3&idPianoWeek=')
122 self
.identifier
= u
[l
+len(f
):r
]
125 return self
.identifier
127 def getConnected(self
, username
= None, password
= None):
128 if username
and password
:
129 self
.getConnection(True, username
, password
)
131 self
.getConnection(True)
132 return self
.connected
134 class AdeProgrammeUtils
:
135 connection
= AdeConnectionUtil()
140 """ Constructeur de la classe AdeProgrammeUtils
141 Il vérifie si les fichiers de configurations sont présents et,
142 le cas échéant en crée un. """
143 if not(os
.path
.exists(CONFIG_DIR
)):
146 if not(os
.path
.isfile(CONFIG_FILE
)):
147 # Basic configuration of the file
148 self
.setBasicDocument()
151 self
.document
= dom
.parse(CONFIG_FILE
)
152 self
.makeCorrectIds()
153 con
= self
.getConnectionIds()
154 self
.connection
.setIds(str(con
["username"]), str(con
["password"]))
155 except xml
.parsers
.expat
.ExpatError
:
156 # Basic configuration of the file
157 self
.setBasicDocument()
160 def setBasicDocument(self
):
161 """ Permet de mettre le contenu minimal du document. """
162 # Basic configuration of the file
163 self
.document
= dom
.Document()
164 root
= self
.document
.createElement("data")
166 # It's the first run for the application
167 firstrun
= self
.document
.createElement("merge")
168 root
.appendChild(firstrun
)
169 firstrun
.setAttribute("id", "firstrun")
170 firstrun
.setAttribute("value", "True")
172 self
.document
.appendChild(root
)
173 self
.makeCorrectIds()
175 def makeCorrectIds(self
):
176 """ Permet de lier les id aux identifiants des neuds pour pouvoir
177 y accéder par le getElementById. """
178 for i
in self
.document
.getElementsByTagName("*"):
179 if i
.hasAttribute("id"):
180 i
.setIdAttribute("id")
182 def saveDocument(self
):
183 """ Permet de sauvegarder le fichier de configuration. """
185 f
= open(CONFIG_FILE
, "w")
186 f
.write(self
.document
.toxml())
189 def isFirstRun(self
):
190 """ Permet de connaitre si c'est le premier démarrage de
193 firstrun
= self
.document
.getElementById("firstrun")
195 if firstrun
.hasAttribute("value"):
196 values
= ("False", "True")
197 val
= firstrun
.getAttribute("value")
199 ret
= bool(int(values
.index(val
)))
202 def setFirstRun(self
, newfirstrun
):
203 """ Permet de définir si le permier démarrage est fini. """
204 checkType(newfirstrun
, bool)
206 root
= self
.document
.firstChild
207 firstrun
= self
.document
.getElementById("firstrun")
209 firstrun
= self
.document
.createElement("merge")
210 firstrun
.setAttribute("id", "firstrun")
211 firstrun
.setIdAttribute("id")
212 root
.appendChild(firstrun
)
213 firstrun
.setAttribute("value", str(newfirstrun
))
216 def setConnectionIds(self
, newusername
, newpassword
):
217 """ Permet à l'utilisateur de changer ses identifiants. """
218 checkType(newusername
, str)
219 checkType(newpassword
, str)
221 self
.connection
.setIds(newusername
, newpassword
)
222 root
= self
.document
.firstChild
223 username
= self
.document
.getElementById("username")
224 password
= self
.document
.getElementById("password")
226 username
= self
.document
.createElement("merge")
227 username
.setAttribute("id", "username")
228 username
.setIdAttribute("id")
229 root
.appendChild(username
)
230 username
.setAttribute("value", newusername
)
232 password
= self
.document
.createElement("merge")
233 password
.setAttribute("id", "password")
234 password
.setIdAttribute("id")
235 root
.appendChild(password
)
236 password
.setAttribute("value", b64encode(newpassword
))
239 def getConnectionIds(self
):
240 """ Permet à l'utilisateur d'obtenir ses identifiants. """
241 username
= self
.document
.getElementById("username")
242 password
= self
.document
.getElementById("password")
247 if username
and username
.hasAttribute("value"):
248 ret
["username"] = username
.getAttribute("value")
249 if password
and password
.hasAttribute("value"):
250 ret
["password"] = b64decode(password
.getAttribute("value"))
253 def refreshGroups(self
):
254 """ Permet de rafraichir la liste des groupes utiles à
256 groupTable
= self
.connection
.getGroups()
257 root
= self
.document
.firstChild
258 groups
= self
.document
.getElementById("groups")
260 groups
= self
.document
.createElement("merge")
261 groups
.setAttribute("id", "groups")
262 groups
.setIdAttribute("id")
263 root
.appendChild(groups
)
265 while groups
.hasChildNodes():
266 groups
.removeChild(groups
.firstChild
)
268 node
= self
.document
.createElement("merge")
269 node
.setAttribute("name", i
)
270 node
.setAttribute("value", str(groupTable
[i
]))
271 groups
.appendChild(node
)
275 """ Permet d'obtenir la liste des groupes. """
277 groups
= self
.document
.getElementById("groups")
279 first
= groups
.firstChild
283 if node
.hasAttribute("name") and node
.hasAttribute("value"):
284 #groupTable[node.getAttribute("name")] = int(node.getAttribute("value"))
285 groupTable
.append(node
.getAttribute("name"))
286 node
= node
.nextSibling
291 def getGroupsIds(self
):
292 """ Permet d'obtenir la liste des groupes et des identifiants
293 qui y son rattachés. """
295 groups
= self
.document
.getElementById("groups")
297 first
= groups
.firstChild
301 if node
.hasAttribute("name") and node
.hasAttribute("value"):
302 groupTable
[node
.getAttribute("name")] = int(node
.getAttribute("value"))
303 node
= node
.nextSibling
308 def getUserGroup(self
):
309 """ Permet de connaitre le groupe de l'utilisateur. """
311 group
= self
.document
.getElementById("usergroup")
312 if group
and group
.hasAttribute("value"):
313 usergroup
= int(group
.getAttribute("value"))
314 groups
= self
.getGroupsIds()
316 if usergroup
== groups
[i
]:
320 def setUserGroup(self
, grpName
):
321 """ Permet de définir le groupe de l'utilisateur. """
322 checkType(grpName
, str)
324 if grpName
in self
.getGroups():
325 numGrp
= self
.getGroupsIds()[grpName
]
326 root
= self
.document
.firstChild
327 group
= self
.document
.getElementById("usergroup")
329 group
= self
.document
.createElement("merge")
330 group
.setAttribute("id", "usergroup")
331 group
.setIdAttribute("id")
332 root
.appendChild(group
)
333 group
.setAttribute("value", str(numGrp
))
336 def getPlanning(self
, semaine
, groupId
= None, identifier
= None):
337 """ Permet d'avoir l'addresse du planning dans le dossier tmp. """
338 checkType(semaine
, int)
339 if groupId
:checkType(groupId
, str)
341 if self
.getUserGroup():
342 groupId
= self
.getUserGroup()
345 groupId
= self
.getGroupsIds()[groupId
]
347 if identifier
:checkType(identifier
, str)
349 identifier
= self
.connection
.getCorrectId()
351 num
= (semaine
+ 18) % 53
352 url
= BASE_IMG_URL
+'&idPianoWeek='+str(num
)+'&idTree='+str(groupId
)+'&identifier='+identifier
353 file = self
.uo
.retrieve(url
)[0]
356 def checkType(object, req
):
357 if type(object) != req
:
358 raise TypeError(str(type(object))+" recieved "+str(req
)+" expected.")