Fix attachment marcxml generation
[cds-indico.git] / indico / MaKaC / common / output.py
blob3bc48522ebc9dcff9bc6a98f0b11eb738d499d1c
1 # This file is part of Indico.
2 # Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
4 # Indico is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3 of the
7 # License, or (at your option) any later version.
9 # Indico is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with Indico; if not, see <http://www.gnu.org/licenses/>.
17 from datetime import datetime
18 from flask import request
19 from hashlib import md5
20 from pytz import timezone
21 from sqlalchemy.orm import joinedload
23 import string
24 from indico.util.json import dumps
25 import StringIO
27 from lxml import etree
29 import MaKaC.conference as conference
30 import MaKaC.schedule as schedule
31 import MaKaC.webinterface.urlHandlers as urlHandlers
32 from MaKaC.webinterface.linking import RoomLinker
33 from xmlGen import XMLGen
34 import os
35 from math import ceil
36 from MaKaC.i18n import _
37 from MaKaC.common.timezoneUtils import DisplayTZ
38 from MaKaC.common.utils import getHierarchicalId, resolveHierarchicalId
39 from MaKaC.common.cache import MultiLevelCache, MultiLevelCacheEntry
40 from MaKaC.common.TemplateExec import escapeHTMLForJS
42 from indico.core.config import Config
43 from indico.modules.attachments.models.attachments import AttachmentType, Attachment
44 from indico.modules.attachments.models.folders import AttachmentFolder
45 from indico.modules.rb.models.locations import Location
46 from indico.modules.rb.models.rooms import Room
47 from indico.modules.users.legacy import AvatarUserWrapper
48 from indico.modules.groups.legacy import LDAPGroupWrapper
49 from indico.util.event import uniqueId
50 from indico.web.flask.util import url_for
53 # TODO This really needs to be fixed... no i18n and strange implementation using month names as keys
54 def stringToDate( str ):
55 months = { "January":1, "February":2, "March":3, "April":4, "May":5, "June":6, "July":7, "August":8, "September":9, "October":10, "November":11, "December":12 }
56 [ day, month, year ] = str.split("-")
57 return datetime(int(year),months[month],int(day))
60 class XSLTransformer:
62 def __init__(self, stylesheet):
63 # instanciate stylesheet object
64 styledoc = etree.parse(stylesheet)
65 self.__style = etree.XSLT(styledoc)
67 def process (self, xml):
69 doc = etree.parse(StringIO.StringIO(xml))
70 # compute the transformation
71 result = self.__style(doc)
73 return str(result)
76 class outputGenerator(object):
77 """
78 this class generates the application standard XML (getBasicXML)
79 and also provides a method to format it using an XSLt stylesheet
80 (getFormattedOutput method)
81 """
83 def __init__(self, aw, XG = None):
84 self.__aw = aw
85 if XG != None:
86 self._XMLGen = XG
87 else:
88 self._XMLGen = XMLGen()
89 self._config = Config.getInstance()
90 self.text = ""
91 self.time_XML = 0
92 self.time_HTML = 0
93 self.cache = XMLCache()
95 from MaKaC.webinterface.webFactoryRegistry import WebFactoryRegistry
96 self.webFactory = WebFactoryRegistry()
98 def _generateMaterialList(self, obj):
99 """
100 Generates a list containing all the materials, with the
101 corresponding Ids for those that already exist
104 # yes, this may look a bit redundant, but materialRegistry isn't
105 # bound to a particular target
106 materialRegistry = obj.getMaterialRegistry()
107 return materialRegistry.getMaterialList(obj.getConference())
109 def _getRecordCollection(self, obj):
110 if obj.hasAnyProtection():
111 return "INDICOSEARCH.PRIVATE"
112 else:
113 return "INDICOSEARCH.PUBLIC"
115 def getOutput(self, conf, stylesheet, vars=None, includeSession=1, includeContribution=1, includeSubContribution=1, includeMaterial=1, showSession="all", showDate="all", showContribution="all"):
116 # get xml conference
117 xml = self._getBasicXML(conf, vars, includeSession,includeContribution,includeSubContribution,includeMaterial,showSession,showDate,showContribution)
118 if not os.path.exists(stylesheet):
119 self.text = _("Cannot find stylesheet")
120 if os.path.basename(stylesheet) == "xml.xsl":
121 self.text = xml
122 else:
123 # instanciate the XSL tool
124 parser = XSLTransformer(stylesheet)
125 self.text = parser.process(xml)
126 return self.text
129 def getFormattedOutput(self, rh, conf, stylesheet, vars=None, includeSession=1,includeContribution=1,includeSubContribution=1,includeMaterial=1,showSession="all",showDate="all",showContribution="all"):
131 conf: conference object
132 stylesheet: path to the xsl file
134 self.getOutput(conf, stylesheet, vars, includeSession, includeContribution, includeSubContribution, includeMaterial, showSession, showDate, showContribution)
135 html = self.text
136 if request.is_secure:
137 baseURL = Config.getInstance().getBaseURL()
138 baseSecureURL = urlHandlers.setSSLPort(Config.getInstance().getBaseSecureURL())
139 html = html.replace(baseURL, baseSecureURL)
140 html = html.replace(escapeHTMLForJS(baseURL), escapeHTMLForJS(baseSecureURL))
141 return html
143 def _getBasicXML(self, conf, vars, includeSession, includeContribution, includeSubContribution, includeMaterial, showSession="all", showDate="all", showContribution="all", showSubContribution="all", out=None):
145 conf: conference object
147 if not out:
148 out = self._XMLGen
149 #out.initXml()
150 out.openTag("iconf")
151 self._confToXML(conf, vars, includeSession, includeContribution, includeSubContribution, includeMaterial, showSession, showDate, showContribution, out=out)
152 out.closeTag("iconf")
153 return out.getXml()
155 def _userToXML(self, obj, user, out):
156 out.openTag("user")
157 out.writeTag("title", user.getTitle())
158 out.writeTag("name", "", [["first", user.getFirstName()], ["middle", ""], ["last", user.getFamilyName()]])
159 out.writeTag("organization", user.getAffiliation())
161 if obj.canModify(self.__aw):
162 out.writeTag("email", user.getEmail())
164 out.writeTag("emailHash", md5(user.getEmail()).hexdigest())
166 try:
167 out.writeTag("userid",user.id)
168 except:
169 pass
170 out.closeTag("user")
172 def _getRoom(self, room, location):
173 room_name = room.getName()
174 if location:
175 rb_room = Room.find_first(Room.name == room_name, Location.name == location.getName(), _join=Room.location)
176 if rb_room:
177 # use the full name instead
178 return rb_room.full_name
179 return room_name
181 def _generateLinkField(self, url, obj, text, out):
182 out.openTag("datafield", [["tag", "856"], ["ind1", "4"], ["ind2", " "]])
183 out.writeTag("subfield", str(url.getURL(obj)), [["code", "u"]])
184 out.writeTag("subfield", text, [["code", "y"]])
185 out.closeTag("datafield")
187 def _generateACLDatafield(self, eType, memberList, objId, out):
189 Generates a specific MARCXML 506 field containing the ACL
191 if eType:
192 out.openTag("datafield", [["tag", "506"],
193 ["ind1", "1"], ["ind2", " "]])
194 for memberId in memberList:
195 out.writeTag("subfield", memberId, [["code", "d"]])
196 out.writeTag("subfield", eType, [["code", "f"]])
198 else:
199 out.openTag("datafield", [["tag", "506"], ["ind1", "0"],
200 ["ind2", " "]])
202 # define which part of the record the list concerns
203 if objId is not None:
204 out.writeTag("subfield", "INDICO.%s" % \
205 objId, [["code", "3"]])
207 out.closeTag("datafield")
209 def _generateAccessList(self, obj=None, out=None, acl=None, objId=None):
211 Generate a comprehensive access list showing all users and e-groups who
212 may access this object, taking into account the permissions and access
213 lists of its owners.
214 obj could be a Conference, Session, Contribution, Material, Resource
215 or SubContribution object.
218 if acl is None:
219 acl = obj.getRecursiveAllowedToAccessList()
221 # Populate two lists holding email/group strings instead of
222 # Avatar/Group objects
223 allowed_logins = set()
224 allowed_groups = []
226 for user_obj in acl:
227 if isinstance(user_obj, AvatarUserWrapper):
228 # user names for all non-local accounts
229 for (provider, identifier) in user_obj.user.iter_identifiers():
230 if provider != 'indico':
231 allowed_logins.add(identifier)
232 elif isinstance(user_obj, LDAPGroupWrapper):
233 allowed_groups.append(user_obj.getId())
234 else:
235 allowed_logins.add(user_obj.getId())
237 if len(allowed_groups) + len(allowed_logins) > 0:
238 # Create XML list of groups
239 if len(allowed_groups) > 0:
240 self._generateACLDatafield('group', allowed_groups, objId, out)
242 # Create XML list of emails
243 if len(allowed_logins) > 0:
244 self._generateACLDatafield('username', allowed_logins, objId, out)
245 else:
246 # public record
247 self._generateACLDatafield(None, None, objId, out)
249 def _confToXML(self,
250 conf,
251 vars,
252 includeSession = 1,
253 includeContribution = 1,
254 includeSubContribution = 1,
255 includeMaterial = 1,
256 showSession = "all",
257 showDate = "all",
258 showContribution = "all",
259 showSubContribution = "all",
260 showWithdrawed = True,
261 useSchedule = True,
262 out = None,
263 recordingManagerTags = None):
265 if not out:
266 out = self._XMLGen
267 if vars and vars.has_key("frame") and vars["frame"] == "no":
268 modificons = 0
269 else:
270 modificons = 1
272 out.writeTag("ID", conf.getId())
274 if conf.getOwnerList():
275 out.writeTag("category", conf.getOwnerList()[0].getName())
276 else:
277 out.writeTag("category", "")
279 out.writeTag("parentProtection", dumps(conf.getAccessController().isProtected()))
280 out.writeTag("materialList", dumps(self._generateMaterialList(conf)))
282 if conf.canModify(self.__aw) and vars and modificons:
283 out.writeTag("modifyLink", vars["modifyURL"])
284 if conf.canModify( self.__aw ) and vars and modificons:
285 out.writeTag("materialLink", True)
286 if conf.canModify( self.__aw ) and vars and vars.has_key("cloneURL") and modificons:
287 out.writeTag("cloneLink", vars["cloneURL"])
288 if vars and vars.has_key("iCalURL"):
289 out.writeTag("iCalLink", vars["iCalURL"])
291 if conf.getOrgText() != "":
292 out.writeTag("organiser", conf.getOrgText())
294 out.openTag("announcer")
295 chair = conf.getCreator()
296 if chair != None:
297 self._userToXML(conf, chair, out)
298 out.closeTag("announcer")
300 sinfo = conf.getSupportInfo()
302 if sinfo.getEmail() != '':
303 out.writeTag("supportEmail", sinfo.getEmail(), [["caption", sinfo.getCaption()]])
305 keywords = conf.getKeywords()
306 keywords = keywords.replace("\r\n", "\n")
307 keywordsList = filter (lambda a: a != '', keywords.split("\n"))
308 if keywordsList:
309 out.openTag("keywords")
310 for keyword in keywordsList:
311 out.writeTag("keyword",keyword.strip())
312 out.closeTag("keywords")
314 rnh = conf.getReportNumberHolder()
315 rns = rnh.listReportNumbers()
316 if len(rns) != 0:
317 for rn in rns:
318 out.openTag("repno")
319 out.writeTag("system",rn[0])
320 out.writeTag("rn",rn[1])
321 out.closeTag("repno")
323 out.writeTag("title",conf.getTitle())
325 out.writeTag("description",conf.getDescription())
327 if conf.getParticipation().displayParticipantList() :
328 out.writeTag("participants",conf.getParticipation().getPresentParticipantListText())
330 evaluation = conf.getEvaluation()
331 if evaluation.isVisible() and evaluation.inEvaluationPeriod() and evaluation.getNbOfQuestions()>0 :
332 out.writeTag("evaluationLink",urlHandlers.UHConfEvaluationDisplay.getURL(conf))
334 out.writeTag("closed", str(conf.isClosed()))
336 if conf.getLocationList()!=[] or conf.getRoom():
337 out.openTag("location")
338 loc=None
339 for l in conf.getLocationList():
340 if l.getName() != "":
341 loc=l
342 out.writeTag("name",l.getName())
343 out.writeTag("address",l.getAddress())
344 if conf.getRoom():
345 roomName = self._getRoom(conf.getRoom(), loc)
346 out.writeTag("room", roomName)
347 url=RoomLinker().getURL(conf.getRoom(), loc)
348 if url != "":
349 out.writeTag("roomMapURL",url)
350 else:
351 out.writeTag("room","")
352 out.closeTag("location")
354 tzUtil = DisplayTZ(self.__aw,conf)
355 tz = tzUtil.getDisplayTZ()
356 adjusted_startDate = conf.getAdjustedStartDate(tz)
357 adjusted_endDate = conf.getAdjustedEndDate(tz)
358 out.writeTag("startDate","%d-%s-%sT%s:%s:00" %(adjusted_startDate.year, string.zfill(adjusted_startDate.month,2), string.zfill(adjusted_startDate.day,2), string.zfill(adjusted_startDate.hour,2), string.zfill(adjusted_startDate.minute,2)))
359 out.writeTag("endDate","%d-%s-%sT%s:%s:00" %(adjusted_endDate.year, string.zfill(adjusted_endDate.month,2), string.zfill(adjusted_endDate.day,2), string.zfill(adjusted_endDate.hour,2), string.zfill(adjusted_endDate.minute,2)))
360 out.writeTag("creationDate",conf.getCreationDate().astimezone(timezone(tz)).strftime("%Y-%m-%dT%H:%M:%S"))
361 out.writeTag("modificationDate",conf.getModificationDate().strftime("%Y-%m-%dT%H:%M:%S"))
362 out.writeTag("timezone","%s" %(tz))
364 uList = conf.getChairList()
365 if len(uList) > 0 or conf.getChairmanText() != "":
366 out.openTag("chair")
367 for chair in uList:
368 self._userToXML(conf, chair, out)
369 if conf.getChairmanText() != "":
370 out.writeTag("UnformatedUser",conf.getChairmanText())
371 out.closeTag("chair")
374 # Keep track of days that have some slots that will be displayed
375 nonEmptyDays = set()
377 # This case happens when called by RecordingManager to generate XML for a contribution:
378 if showContribution != "all" and conf.getContributionById(showContribution) != None:
379 self._contribToXML(conf.getContributionById(showContribution),vars,includeSubContribution,includeMaterial,conf, showSubContribution=showSubContribution,out=out, recordingManagerTags=recordingManagerTags)
380 elif useSchedule:
381 confSchedule = conf.getSchedule()
382 if showDate == "all":
383 entrylist = confSchedule.getEntries()
384 else:
385 entrylist = confSchedule.getEntriesOnDay(timezone(tz).localize(stringToDate(showDate)))
386 for entry in entrylist:
387 if type(entry) is schedule.BreakTimeSchEntry: #TODO: schedule.BreakTimeSchEntry doesn't seem to exist!
388 self._breakToXML(entry, out=out)
389 nonEmptyDays.add(entry.getStartDate().date())
390 elif type(entry) is conference.ContribSchEntry:
391 owner = entry.getOwner()
392 if owner.canView(self.__aw):
393 if includeContribution:
394 if showWithdrawed or not isinstance(owner.getCurrentStatus(), conference.ContribStatusWithdrawn):
395 self._contribToXML(owner,vars,includeSubContribution,includeMaterial,conf, showSubContribution=showSubContribution,out=out)
396 nonEmptyDays.add(owner.getStartDate().date())
397 elif type(entry) is schedule.LinkedTimeSchEntry: #TODO: schedule.LinkedTimeSchEntry doesn't seem to exist!
398 owner = entry.getOwner()
399 if type(owner) is conference.Contribution:
400 if owner.canView(self.__aw):
401 if includeContribution:
402 if showWithdrawed or not isinstance(owner.getCurrentStatus(), conference.ContribStatusWithdrawn):
403 self._contribToXML(owner,vars,includeSubContribution,includeMaterial,conf, out=out)
404 nonEmptyDays.add(owner.getStartDate().date())
405 elif type(owner) is conference.Session:
406 if owner.canView(self.__aw):
407 if includeSession and (showSession == "all" or owner.getId() == showSession):
408 self._sessionToXML(owner,vars,includeContribution,includeMaterial, showWithdrawed=showWithdrawed, out=out, recordingManagerTags=recordingManagerTags)
409 nonEmptyDays.add(owner.getStartDate().date())
410 elif type(owner) is conference.SessionSlot:
411 if owner.getSession().canView(self.__aw):
412 if includeSession and (showSession == "all" or owner.getSession().getId() == showSession):
413 self._slotToXML(owner,vars,includeContribution,includeMaterial, showWithdrawed=showWithdrawed, out=out, recordingManagerTags=recordingManagerTags)
414 nonEmptyDays.add(owner.getStartDate().date())
415 else:
416 confSchedule = conf.getSchedule()
417 for entry in confSchedule.getEntries():
418 if type(entry) is conference.ContribSchEntry:
419 owner = entry.getOwner()
420 if owner.canView(self.__aw):
421 if includeContribution:
422 self._contribToXML(owner,vars,includeSubContribution,includeMaterial,conf,showSubContribution=showSubContribution,out=out, recordingManagerTags=recordingManagerTags)
423 nonEmptyDays.add(owner.getStartDate().date())
424 sessionList = conf.getSessionList()
425 for session in sessionList: # here is the part that displays all the sessions (for the RecordingManager, anyway). It should be changed to check if showSession has been set.
426 if session.canAccess(self.__aw) and includeSession and (showSession == 'all' or str(session.getId()) == str(showSession)):
427 self._sessionToXML(session, vars, includeContribution, includeMaterial, showWithdrawed=showWithdrawed, useSchedule=False, out=out, recordingManagerTags=recordingManagerTags)
428 nonEmptyDays.add(session.getStartDate().date())
430 nonEmptyDays = list(nonEmptyDays)
431 nonEmptyDays.sort()
433 if vars:
434 daysPerRow = vars.get("daysPerRow", None)
435 firstDay = vars.get("firstDay", None)
436 lastDay = vars.get("lastDay", None)
438 if daysPerRow or firstDay or lastDay:
439 if firstDay:
440 firstDay = timezone(tz).localize(stringToDate(firstDay)).date()
441 nonEmptyDays = filter(lambda day: day >= firstDay, nonEmptyDays)
443 if lastDay:
444 lastDay = timezone(tz).localize(stringToDate(lastDay)).date()
445 nonEmptyDays = filter(lambda day: day <= lastDay, nonEmptyDays)
447 if daysPerRow:
448 daysPerRow = int(daysPerRow)
450 if not daysPerRow or daysPerRow > len(nonEmptyDays):
451 daysPerRow = len(nonEmptyDays)
453 if daysPerRow > 0:
454 numOfRows = int(ceil(len(nonEmptyDays) / float(daysPerRow)))
455 for row in range(0, numOfRows):
456 fromDate = nonEmptyDays[row * daysPerRow]
457 toIndex = (row + 1) * daysPerRow - 1
458 if toIndex >= len(nonEmptyDays):
459 toIndex = len(nonEmptyDays) - 1
460 toDate = nonEmptyDays[toIndex]
461 out.openTag("line")
462 out.writeTag("fromDate", "%d%s%s" % (fromDate.year, string.zfill(fromDate.month, 2), string.zfill(fromDate.day, 2)))
463 out.writeTag("toDate", "%d%s%s" % (toDate.year, string.zfill(toDate.month, 2), string.zfill(toDate.day, 2)))
464 out.closeTag("line")
465 else:
466 out.openTag("line")
467 out.writeTag("fromDate", "%d%s%s" % (adjusted_startDate.year, string.zfill(adjusted_startDate.month, 2), string.zfill(adjusted_startDate.day, 2)))
468 out.writeTag("toDate", "%d%s%s" % (adjusted_endDate.year, string.zfill(adjusted_endDate.month, 2), string.zfill(adjusted_endDate.day, 2)))
469 out.closeTag("line")
471 mList = conf.getAllMaterialList()
472 for mat in mList:
473 if mat.canView(self.__aw) and mat.getTitle() != "Internal Page Files":
474 if includeMaterial:
475 self._materialToXML(mat, vars, out=out)
477 def _sessionToXML(self,
478 session,
479 vars,
480 includeContribution,
481 includeMaterial,
482 includeSubContribution = 1,
483 showContribution = None,
484 showSubContribution = "all",
485 showWithdrawed = True,
486 useSchedule = True,
487 out = None,
488 recordingManagerTags = None):
490 if not out:
491 out = self._XMLGen
492 if vars and vars.has_key("frame") and vars["frame"] == "no":
493 modificons = 0
494 else:
495 modificons = 1
496 out.openTag("session", [["color", session.getColor()], ["textcolor", session.getTextColor()]])
497 out.writeTag("ID", session.getId())
499 if session.getCode() not in ["no code", ""]:
500 out.writeTag("code",session.getCode())
501 else:
502 out.writeTag("code",session.getId())
503 if (session.canModify( self.__aw ) or session.canCoordinate(self.__aw)) and vars and modificons:
504 out.writeTag("modifyLink",vars["sessionModifyURLGen"](session))
505 if (session.canModify( self.__aw ) or session.canCoordinate(self.__aw)) and vars and modificons:
506 out.writeTag("materialLink", True)
507 out.writeTag("title",session.title)
508 out.writeTag("description",session.description)
509 cList = session.getConvenerList()
510 if len(cList) != 0:
511 out.openTag("convener")
512 for conv in cList:
513 self._userToXML(session, conv, out)
514 if session.getConvenerText() != "":
515 out.writeTag("UnformatedUser",session.getConvenerText())
516 out.closeTag("convener")
517 l = session.getLocation()
518 if l!=None or session.getRoom():
519 out.openTag("location")
520 if l!=None:
521 out.writeTag("name",l.getName())
522 out.writeTag("address",l.getAddress())
523 if session.getRoom():
524 roomName = self._getRoom(session.getRoom(), l)
525 out.writeTag("room", roomName)
526 url=RoomLinker().getURL(session.getRoom(), l)
527 if url != "":
528 out.writeTag("roomMapURL",url)
529 else:
530 out.writeTag("room","")
531 out.closeTag("location")
532 try:
533 displayMode = self.__aw._currentUser.getDisplayTZMode()
534 except:
535 # not logged in, use meeting timezone
536 displayMode = 'Meeting'
537 if displayMode == 'Meeting':
538 tz = session.getConference().getTimezone()
539 else:
540 tz = self.__aw._currentUser.getTimezone()
541 startDate = session.getStartDate().astimezone(timezone(tz))
542 out.writeTag("startDate","%d-%s-%sT%s:%s:00" %(startDate.year, string.zfill(startDate.month,2), string.zfill(startDate.day,2),string.zfill(startDate.hour,2), string.zfill(startDate.minute,2)))
543 endDate = session.startDate + session.duration
544 out.writeTag("endDate","%d-%s-%sT%s:%s:00" %(endDate.year, string.zfill(endDate.month,2), string.zfill(endDate.day,2),string.zfill(endDate.hour,2), string.zfill(endDate.minute,2)))
545 out.writeTag("duration","%s:%s" %(string.zfill((datetime(1900,1,1)+session.duration).hour,2), string.zfill((datetime(1900,1,1)+session.duration).minute,2)))
546 if includeContribution:
547 if useSchedule:
548 sessionSchedule = session.getSchedule()
549 for entry in sessionSchedule.getEntries():
550 if type(entry) is schedule.BreakTimeSchEntry: #TODO: schedule.BreakTimeSchEntry doesn't seem to exist!
551 self._breakToXML(entry, out=out)
552 elif type(entry) is schedule.LinkedTimeSchEntry: #TODO: schedule.LinkedTimeSchEntry doesn't seem to exist!
553 owner = entry.getOwner()
554 if type(owner) is conference.Contribution:
555 if owner.canView(self.__aw):
556 if showWithdrawed or not isinstance(owner.getCurrentStatus(), conference.ContribStatusWithdrawn):
557 self._contribToXML(owner,vars,includeSubContribution,includeMaterial, session.getConference(),out=out, recordingManagerTags=recordingManagerTags) # needs to be re-done?
558 else:
559 for contrib in session.getContributionList():
560 if contrib.canView(self.__aw):
561 if showWithdrawed or not isinstance(contrib.getCurrentStatus(), conference.ContribStatusWithdrawn):
562 self._contribToXML(contrib, vars, includeSubContribution,includeMaterial, session.getConference(),out=out, recordingManagerTags=recordingManagerTags) # needs to be re-done
564 mList = session.getAllMaterialList()
565 for mat in mList:
566 self._materialToXML(mat, vars, out=out)
568 out.closeTag("session")
570 def _slotToXML(self,slot,vars,includeContribution,includeMaterial, showWithdrawed=True, out=None, recordingManagerTags=None):
571 if not out:
572 out = self._XMLGen
573 session = slot.getSession()
574 conf = session.getConference()
575 if vars and vars.has_key("frame") and vars["frame"] == "no":
576 modificons = 0
577 else:
578 modificons = 1
579 out.openTag("session", [["color", session.getColor()],["textcolor", session.getTextColor()]])
580 out.writeTag("ID", session.getId())
582 out.writeTag("parentProtection", dumps(session.getAccessController().isProtected()))
583 out.writeTag("materialList", dumps(self._generateMaterialList(session)))
586 slotId = session.getSortedSlotList().index(slot)
587 slotCode = slotId + 1
588 if session.getCode() not in ["no code", ""]:
589 out.writeTag("code","%s-%s" % (session.getCode(),slotCode))
590 else:
591 out.writeTag("code","sess%s-%s" % (session.getId(),slotCode))
592 if (session.canModify( self.__aw ) or session.canCoordinate(self.__aw)) and vars and modificons:
593 out.writeTag("slotId", slotId)
594 url = urlHandlers.UHSessionModifSchedule.getURL(session)
595 ttLink = "%s#%s.s%sl%s" % (url, session.getStartDate().strftime('%Y%m%d'), session.getId(), slotId)
596 out.writeTag("sessionTimetableLink",ttLink)
597 if (session.canModify( self.__aw ) or session.canCoordinate(self.__aw)) and vars and modificons:
598 out.writeTag("materialLink", True)
599 title = session.title
600 if slot.getTitle() != "" and slot.getTitle() != title:
601 title += ": %s" % slot.getTitle()
602 out.writeTag("title",title)
603 out.writeTag("description",session.description)
604 cList = slot.getConvenerList()
605 if len(cList) != 0:
606 out.openTag("convener")
607 for conv in cList:
608 self._userToXML(slot, conv, out)
609 if session.getConvenerText() != "":
610 out.writeTag("UnformatedUser",session.getConvenerText())
611 out.closeTag("convener")
612 l = slot.getLocation()
613 room = slot.getRoom()
614 if not conf.getEnableSessionSlots():
615 l = session.getLocation()
616 room = session.getRoom()
617 if l!=None or room:
618 out.openTag("location")
619 if l!=None:
620 out.writeTag("name",l.getName())
621 out.writeTag("address",l.getAddress())
622 if room:
623 roomName = self._getRoom(room, l)
624 out.writeTag("room", roomName)
625 url=RoomLinker().getURL(room, l)
626 if url != "":
627 out.writeTag("roomMapURL",url)
628 else:
629 out.writeTag("room","")
630 out.closeTag("location")
631 tzUtil = DisplayTZ(self.__aw,conf)
632 tz = tzUtil.getDisplayTZ()
633 startDate = slot.getStartDate().astimezone(timezone(tz))
634 endDate = slot.getEndDate().astimezone(timezone(tz))
635 out.writeTag("startDate","%d-%s-%sT%s:%s:00" %(startDate.year, string.zfill(startDate.month,2), string.zfill(startDate.day,2),string.zfill(startDate.hour,2), string.zfill(startDate.minute,2)))
636 out.writeTag("endDate","%d-%s-%sT%s:%s:00" %(endDate.year, string.zfill(endDate.month,2), string.zfill(endDate.day,2),string.zfill(endDate.hour,2), string.zfill(endDate.minute,2)))
637 out.writeTag("duration","%s:%s" %(string.zfill((datetime(1900,1,1)+slot.duration).hour,2), string.zfill((datetime(1900,1,1)+slot.duration).minute,2)))
638 if includeContribution:
639 for entry in slot.getSchedule().getEntries():
640 if type(entry) is schedule.BreakTimeSchEntry: #TODO: schedule.BreakTimeSchEntry doesn't seem to exist!
641 self._breakToXML(entry, out=out)
642 else:
643 owner = entry.getOwner()
644 if isinstance(owner, conference.AcceptedContribution) or isinstance(owner, conference.Contribution):
645 if owner.canView(self.__aw):
646 if showWithdrawed or not isinstance(owner.getCurrentStatus(), conference.ContribStatusWithdrawn):
647 self._contribToXML(owner,vars,1,includeMaterial, conf,out=out)
648 mList = session.getAllMaterialList()
649 for mat in mList:
650 self._materialToXML(mat, vars, out=out)
651 out.closeTag("session")
653 def _contribToXML(self,
654 contribution,
655 vars,
656 includeSubContribution,
657 includeMaterial,
658 conf,
659 showSubContribution = "all",
660 out = None,
661 recordingManagerTags = None):
662 if not out:
663 out = self._XMLGen
664 if vars and vars.has_key("frame") and vars["frame"] == "no":
665 modificons = 0
666 else:
667 modificons = 1
668 out.openTag("contribution", [["color",contribution.getColor()],["textcolor",contribution.getTextColor()]])
669 out.writeTag("ID",contribution.getId())
671 out.writeTag("parentProtection", dumps(contribution.getAccessController().isProtected()))
672 out.writeTag("materialList", dumps(self._generateMaterialList(contribution)))
674 if contribution.getBoardNumber() != "":
675 out.writeTag("board",contribution.getBoardNumber())
676 if contribution.getTrack() != None:
677 out.writeTag("track",contribution.getTrack().getTitle())
678 if contribution.getType() != None:
679 out.openTag("type")
680 out.writeTag("id",contribution.getType().getId())
681 out.writeTag("name",contribution.getType().getName())
682 out.closeTag("type")
683 if contribution.canModify( self.__aw ) and vars and modificons:
684 out.writeTag("modifyLink",vars["contribModifyURLGen"](contribution))
685 if (contribution.canModify( self.__aw ) or contribution.canUserSubmit(self.__aw.getUser())) and vars and modificons:
686 out.writeTag("materialLink", True)
687 keywords = contribution.getKeywords()
688 keywords = keywords.replace("\r\n", "\n")
689 keywordsList = filter (lambda a: a != '', keywords.split("\n"))
690 if keywordsList:
691 out.openTag("keywords")
692 for keyword in keywordsList:
693 out.writeTag("keyword",keyword.strip())
694 out.closeTag("keywords")
695 rnh = contribution.getReportNumberHolder()
696 rns = rnh.listReportNumbers()
697 if len(rns) != 0:
698 for rn in rns:
699 out.openTag("repno")
700 out.writeTag("system",rn[0])
701 out.writeTag("rn",rn[1])
702 out.closeTag("repno")
703 out.writeTag("title",contribution.title)
704 sList = contribution.getSpeakerList()
705 if len(sList) != 0:
706 out.openTag("speakers")
707 for sp in sList:
708 self._userToXML(contribution, sp, out)
709 if contribution.getSpeakerText() != "":
710 out.writeTag("UnformatedUser",contribution.getSpeakerText())
711 out.closeTag("speakers")
712 primaryAuthorList = contribution.getPrimaryAuthorList()
713 if len(primaryAuthorList) != 0:
714 out.openTag("primaryAuthors")
715 for sp in primaryAuthorList:
716 self._userToXML(contribution, sp, out)
717 out.closeTag("primaryAuthors")
718 coAuthorList = contribution.getCoAuthorList()
719 if len(coAuthorList) != 0:
720 out.openTag("coAuthors")
721 for sp in coAuthorList:
722 self._userToXML(contribution, sp, out)
723 out.closeTag("coAuthors")
724 l = contribution.getLocation()
725 if l != None or contribution.getRoom():
726 out.openTag("location")
727 if l!=None:
728 out.writeTag("name",l.getName())
729 out.writeTag("address",l.getAddress())
730 if contribution.getRoom():
731 roomName = self._getRoom(contribution.getRoom(), l)
732 out.writeTag("room", roomName)
733 url=RoomLinker().getURL(contribution.getRoom(), l)
734 if url != "":
735 out.writeTag("roomMapURL",url)
736 else:
737 out.writeTag("room","")
738 out.closeTag("location")
739 tzUtil = DisplayTZ(self.__aw,conf)
740 tz = tzUtil.getDisplayTZ()
742 startDate = None
743 if contribution.startDate:
744 startDate = contribution.startDate.astimezone(timezone(tz))
746 if startDate:
747 endDate = startDate + contribution.duration
748 out.writeTag("startDate","%d-%s-%sT%s:%s:00" %(startDate.year, string.zfill(startDate.month,2), string.zfill(startDate.day,2),string.zfill(startDate.hour,2), string.zfill(startDate.minute,2)))
749 out.writeTag("endDate","%d-%s-%sT%s:%s:00" %(endDate.year, string.zfill(endDate.month,2), string.zfill(endDate.day,2),string.zfill(endDate.hour,2), string.zfill(endDate.minute,2)))
750 if contribution.duration:
751 out.writeTag("duration","%s:%s" %(string.zfill((datetime(1900,1,1)+contribution.duration).hour,2), string.zfill((datetime(1900,1,1)+contribution.duration).minute,2)))
752 out.writeTag("abstract",contribution.getDescription())
753 matList = contribution.getAllMaterialList()
754 for mat in matList:
755 if mat.canView(self.__aw):
756 if includeMaterial:
757 self._materialToXML(mat, vars, out=out)
758 else:
759 out.writeTag("material",out.writeTag("id",mat.id))
760 for subC in contribution.getSubContributionList():
761 if includeSubContribution:
762 if showSubContribution == 'all' or str(showSubContribution) == str(subC.getId()):
763 self._subContributionToXML(subC, vars, includeMaterial, out=out, recordingManagerTags=recordingManagerTags)
765 out.closeTag("contribution")
768 def _subContributionToXML(self,
769 subCont,
770 vars,
771 includeMaterial,
772 out = None,
773 recordingManagerTags = None):
775 if not out:
776 out = self._XMLGen
777 if vars and vars.has_key("frame") and vars["frame"] == "no":
778 modificons = 0
779 else:
780 modificons = 1
781 out.openTag("subcontribution")
782 out.writeTag("ID",subCont.getId())
784 out.writeTag("parentProtection", dumps(subCont.getContribution().getAccessController().isProtected()))
785 out.writeTag("materialList", dumps(self._generateMaterialList(subCont)))
787 if subCont.canModify( self.__aw ) and vars and modificons:
788 out.writeTag("modifyLink",vars["subContribModifyURLGen"](subCont))
789 if (subCont.canModify( self.__aw ) or subCont.canUserSubmit( self.__aw.getUser())) and vars and modificons:
790 out.writeTag("materialLink", True)
791 rnh = subCont.getReportNumberHolder()
792 rns = rnh.listReportNumbers()
793 if len(rns) != 0:
794 for rn in rns:
795 out.openTag("repno")
796 out.writeTag("system",rn[0])
797 out.writeTag("rn",rn[1])
798 out.closeTag("repno")
799 out.writeTag("title",subCont.title)
800 sList = subCont.getSpeakerList()
801 if len(sList) > 0 or subCont.getSpeakerText() != "":
802 out.openTag("speakers")
803 for sp in sList:
804 self._userToXML(subCont, sp, out)
805 if subCont.getSpeakerText() != "":
806 out.writeTag("UnformatedUser",subCont.getSpeakerText())
807 if len(sList) > 0 or subCont.getSpeakerText() != "":
808 out.closeTag("speakers")
809 out.writeTag("duration","%s:%s"%((string.zfill((datetime(1900,1,1)+subCont.getDuration()).hour,2), string.zfill((datetime(1900,1,1)+subCont.getDuration()).minute,2))))
810 out.writeTag("abstract",subCont.getDescription())
811 matList = subCont.getAllMaterialList()
812 for mat in matList:
813 if mat.canView(self.__aw):
814 if includeMaterial:
815 self._materialToXML(mat, vars, out=out)
817 out.closeTag("subcontribution")
819 def _materialToXML(self,mat, vars, out=None):
820 if not out:
821 out = self._XMLGen
822 out.openTag("material")
823 out.writeTag("ID",mat.getId())
824 out.writeTag("title",mat.title)
825 out.writeTag("description",mat.description)
826 out.writeTag("type",mat.type)
827 if vars:
828 out.writeTag("displayURL",vars["materialURLGen"](mat))
829 types = {"pdf" :{"mapsTo" : "pdf", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "pdf_small.png"), "imgAlt" : "pdf file"},
830 "doc" :{"mapsTo" : "doc", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "word.png"), "imgAlt" : "word file"},
831 "docx" :{"mapsTo" : "doc", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "word.png"), "imgAlt" : "word file"},
832 "ppt" :{"mapsTo" : "ppt", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "powerpoint.png"), "imgAlt" : "powerpoint file"},
833 "pptx" :{"mapsTo" : "ppt", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "powerpoint.png"), "imgAlt" : "powerpoint file"},
834 "xls" :{"mapsTo" : "xls", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "excel.png"), "imgAlt" : "excel file"},
835 "xlsx" :{"mapsTo" : "xls", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "excel.png"), "imgAlt" : "excel file"},
836 "sxi" :{"mapsTo" : "odp", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "impress.png"), "imgAlt" : "presentation file"},
837 "odp" :{"mapsTo" : "odp", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "impress.png"), "imgAlt" : "presentation file"},
838 "sxw" :{"mapsTo" : "odt", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "writer.png"), "imgAlt" : "writer file"},
839 "odt" :{"mapsTo" : "odt", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "writer.png"), "imgAlt" : "writer file"},
840 "sxc" :{"mapsTo" : "ods", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "calc.png"), "imgAlt" : "spreadsheet file"},
841 "ods" :{"mapsTo" : "ods", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "calc.png"), "imgAlt" : "spreadsheet file"},
842 "other" :{"mapsTo" : "other", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "file_small.png"), "imgAlt" : "unknown type file"},
843 "link" :{"mapsTo" : "link", "imgURL" : "%s/%s"%(Config.getInstance().getImagesBaseURL(), "link.png"), "imgAlt" : "link"}}
845 if len(mat.getResourceList()) > 0:
846 out.openTag("files")
847 processedFiles = []
848 for res in mat.getResourceList():
849 try:
850 type = res.getFileType().lower()
852 try:
853 fileType = types[type]["mapsTo"]
854 except KeyError:
855 fileType = "other"
857 if vars:
858 filename = res.getFileName()
859 if filename in processedFiles:
860 filename = "%s-%s"%(processedFiles.count(filename)+1, filename)
861 out.openTag("file")
862 out.writeTag("name",filename)
863 out.writeTag("type", fileType)
864 out.writeTag("url",vars["resourceURLGen"](res))
865 out.closeTag("file")
866 processedFiles.append(res.getFileName())
867 except:
868 out.openTag("file")
869 out.writeTag("name", str(res.getURL()))
870 out.writeTag("type", "link")
871 out.writeTag("url", str(res.getURL()))
872 out.closeTag("file")
873 out.closeTag("files")
875 # Used to enumerate types in the stylesheet. The order of the icons
876 # showed for the materials will be the one specified here
877 # TODO: find a way to avoid this hard coded list and get it from types
878 # typeList = set([ type["mapsTo"] for type in types.values()])
880 typeList = ["doc", "ppt", "pdf", "odt", "odp", "ods", "other", "link"]
882 out.openTag("types")
883 for type in typeList:
884 out.openTag("type")
885 out.writeTag("name", types[type]["mapsTo"])
886 out.writeTag("imgURL", types[type]["imgURL"])
887 out.writeTag("imgAlt", types[type]["imgAlt"])
888 out.closeTag("type")
889 out.closeTag("types")
891 if mat.isItselfProtected():
892 out.writeTag("locked","yes")
893 out.closeTag("material")
895 def _resourcesToXML(self, rList, out=None):
896 if not out:
897 out = self._XMLGen
898 out.openTag("resources")
899 for res in rList:
900 if res.canView(self.__aw):
901 self._resourceToXML(res, out=out)
902 out.closeTag("resources")
904 def _resourceToXML(self,res, out=None):
905 if not out:
906 out = self._XMLGen
907 if type(res) == conference.LocalFile:
908 self._resourceFileToXML(res, out=out)
909 else:
910 self._resourceLinkToXML(res, out=out)
912 def _resourceLinkToXML(self,res, out=None):
913 if not out:
914 out = self._XMLGen
915 out.openTag("resourceLink")
916 out.writeTag("name",res.getName())
917 out.writeTag("description",res.getDescription())
918 out.writeTag("url",res.getURL())
919 out.closeTag("resourceLink")
921 def _resourceFileToXML(self,res, out=None):
922 if not out:
923 out = self._XMLGen
924 out.openTag("resourceFile")
925 out.writeTag("name",res.getName())
926 out.writeTag("description",res.getDescription())
927 out.writeTag("type",res.fileType)
928 out.writeTag("url",res.getURL())
929 out.writeTag("fileName",res.getFileName())
930 out.writeTag("duration","1")#TODO:DURATION ISN'T ESTABLISHED
931 cDate = res.getCreationDate()
932 creationDateStr = "%d-%s-%sT%s:%s:00Z" %(cDate.year, string.zfill(cDate.month,2), string.zfill(cDate.day,2), string.zfill(cDate.hour,2), string.zfill(cDate.minute,2))
933 out.writeTag("creationDate",creationDateStr)
934 out.closeTag("resourceFile")
936 def _breakToXML(self,br, out=None):
937 if not out:
938 out = self._XMLGen
939 out.openTag("break", [["color", br.getColor()], ["textcolor", br.getTextColor()]])
940 out.writeTag("name", br.getTitle())
941 tzUtil = DisplayTZ(self.__aw, br.getOwner())
942 tz = tzUtil.getDisplayTZ()
943 startDate = br.getStartDate().astimezone(timezone(tz))
944 endDate = br.getEndDate().astimezone(timezone(tz))
945 out.writeTag("startDate", "%d-%s-%sT%s:%s:00" % (startDate.year, string.zfill(startDate.month, 2), string.zfill(startDate.day, 2), string.zfill(startDate.hour, 2), string.zfill(startDate.minute, 2)))
946 out.writeTag("endDate", "%d-%s-%sT%s:%s:00" % (endDate.year, string.zfill(endDate.month, 2), string.zfill(endDate.day, 2), string.zfill(endDate.hour, 2), string.zfill(endDate.minute, 2)))
947 out.writeTag("duration","%s:%s"%((string.zfill((datetime(1900,1,1)+br.getDuration()).hour,2), string.zfill((datetime(1900,1,1)+br.getDuration()).minute,2))))
948 if br.getDescription() != "":
949 out.writeTag("description", br.getDescription())
950 l = br.getLocation()
951 if l != None or br.getRoom():
952 out.openTag("location")
953 if l!=None:
954 out.writeTag("name",l.getName())
955 out.writeTag("address",l.getAddress())
956 if br.getRoom():
957 roomName = self._getRoom(br.getRoom(), l)
958 out.writeTag("room", roomName)
959 url=RoomLinker().getURL(br.getRoom(), l)
960 if url != "":
961 out.writeTag("roomMapURL",url)
962 else:
963 out.writeTag("room","")
964 out.closeTag("location")
965 out.closeTag("break")
968 def confToXML(self,
969 conf,
970 includeSession,
971 includeContribution,
972 includeMaterial,
973 showSession = "all",
974 showContribution = "all",
975 showSubContribution = "all",
976 out = None,
977 overrideCache = False,
978 recordingManagerTags = None):
979 """overrideCache = True apparently means force it NOT to use the cache. """
981 if not out:
982 out = self._XMLGen
983 #try to get a cache
984 version = "ses-%s_cont-%s_mat-%s_sch-%s" % (includeSession,
985 includeContribution,
986 includeMaterial,
987 False)
988 obj = None
989 if not overrideCache:
990 obj = self.cache.loadObject(version, conf)
991 if obj:
992 xml = obj.getContent()
993 else:
994 temp = XMLGen(init=False)
995 self._confToXML(conf,
996 None,
997 includeSession,
998 includeContribution,
999 includeMaterial,
1000 showSession = showSession,
1001 showDate = "all",
1002 showContribution = showContribution,
1003 showSubContribution = showSubContribution,
1004 showWithdrawed = False,
1005 useSchedule = False,
1006 out = temp,
1007 recordingManagerTags = recordingManagerTags)
1008 xml = temp.getXml()
1009 self.cache.cacheObject(version, xml, conf)
1011 out.writeXML(xml)
1014 def confToXMLMarc21(self,conf,includeSession=1,includeContribution=1,includeMaterial=1,out=None, overrideCache=False):
1016 if not out:
1017 out = self._XMLGen
1018 #try to get a cache
1019 version = "MARC21_ses-%s_cont-%s_mat-%s"%(includeSession,includeContribution,includeMaterial)
1020 obj = None
1021 if not overrideCache:
1022 obj = self.cache.loadObject(version, conf)
1023 if obj:
1024 xml = obj.getContent()
1025 else:
1026 # No cache, build the XML
1027 temp = XMLGen(init=False)
1028 self._confToXMLMarc21(conf,includeSession,includeContribution,includeMaterial, out=temp)
1029 xml = temp.getXml()
1030 # save XML in cache
1031 self.cache.cacheObject(version, xml, conf)
1032 out.writeXML(xml)
1034 def _confToXMLMarc21(self,conf,includeSession=1,includeContribution=1,includeMaterial=1,out=None):
1035 if not out:
1036 out = self._XMLGen
1038 out.openTag("datafield",[["tag","245"],["ind1"," "],["ind2"," "]])
1039 out.writeTag("subfield",conf.getTitle(),[["code","a"]])
1040 out.closeTag("datafield")
1042 out.writeTag("leader", "00000nmm 2200000uu 4500")
1043 out.openTag("datafield",[["tag","111"],["ind1"," "],["ind2"," "]])
1044 out.writeTag("subfield",conf.title,[["code","a"]])
1046 # XXX: If there is ROOM and not LOCATION....There will be information missed.
1047 for l in conf.getLocationList():
1048 loc = ""
1049 if l.getName() != "":
1050 loc = conf.getLocation().getName()
1051 if l.getAddress() != "":
1052 loc = loc +", "+conf.getLocation().getAddress()
1054 if conf.getRoom():
1055 roomName = self._getRoom(conf.getRoom(), l)
1056 loc = loc + ", " + roomName
1058 if l.getName() != "":
1059 out.writeTag("subfield",loc,[["code","c"]])
1061 sd = conf.getStartDate()
1062 ed = conf.getEndDate()
1063 out.writeTag("subfield","%d-%s-%sT%s:%s:00Z" %(sd.year, string.zfill(sd.month,2), string.zfill(sd.day,2), string.zfill(sd.hour,2), string.zfill(sd.minute,2)),[["code","9"]])
1064 out.writeTag("subfield","%d-%s-%sT%s:%s:00Z" %(ed.year, string.zfill(ed.month,2), string.zfill(ed.day,2), string.zfill(ed.hour,2), string.zfill(ed.minute,2)),[["code","z"]])
1066 out.writeTag("subfield", uniqueId(conf),[["code","g"]])
1067 out.closeTag("datafield")
1069 for path in conf.getCategoriesPath():
1070 out.openTag("datafield",[["tag","650"],["ind1"," "],["ind2","7"]])
1071 out.writeTag("subfield", ":".join(path), [["code","a"]])
1072 out.closeTag("datafield")
1074 ####################################
1075 # Fermi timezone awareness #
1076 ####################################
1077 #if conf.getStartDate() is not None:
1078 # out.openTag("datafield",[["tag","518"],["ind1"," "],["ind2"," "]])
1079 # out.writeTag("subfield","%d-%s-%sT%s:%s:00Z" %(conf.getStartDate().year, string.zfill(conf.getStartDate().month,2), string.zfill(conf.getStartDate().day,2), string.zfill(conf.getStartDate().hour,2), string.zfill(conf.getStartDate().minute,2)),[["code","d"]])
1080 # out.closeTag("datafield")
1081 #sd = conf.getAdjustedStartDate(tz)
1082 sd = conf.getStartDate()
1083 if sd is not None:
1084 out.openTag("datafield",[["tag","518"],["ind1"," "],["ind2"," "]])
1085 out.writeTag("subfield","%d-%s-%sT%s:%s:00Z" %(sd.year, string.zfill(sd.month,2), string.zfill(sd.day,2), string.zfill(sd.hour,2), string.zfill(sd.minute,2)),[["code","d"]])
1086 out.closeTag("datafield")
1087 ####################################
1088 # Fermi timezone awareness(end) #
1089 ####################################
1091 out.openTag("datafield",[["tag","520"],["ind1"," "],["ind2"," "]])
1092 out.writeTag("subfield",conf.getDescription(),[["code","a"]])
1093 out.closeTag("datafield")
1095 if conf.getReportNumberHolder().listReportNumbers():
1096 out.openTag("datafield",[["tag","088"],["ind1"," "],["ind2"," "]])
1097 for report in conf.getReportNumberHolder().listReportNumbers():
1098 out.writeTag("subfield",report[1],[["code","a"]])
1099 out.closeTag("datafield")
1102 out.openTag("datafield",[["tag","653"],["ind1","1"],["ind2"," "]])
1103 keywords = conf.getKeywords()
1104 keywords = keywords.replace("\r\n", "\n")
1105 for keyword in keywords.split("\n"):
1106 out.writeTag("subfield",keyword,[["code","a"]])
1107 out.closeTag("datafield")
1109 import MaKaC.webinterface.simple_event as simple_event
1110 import MaKaC.webinterface.meeting as meeting
1111 type = "Conference"
1112 if self.webFactory.getFactory(conf) == simple_event.WebFactory:
1113 type = "Lecture"
1114 elif self.webFactory.getFactory(conf) == meeting.WebFactory:
1115 type = "Meeting"
1116 out.openTag("datafield",[["tag","650"],["ind1","2"],["ind2","7"]])
1117 out.writeTag("subfield",type,[["code","a"]])
1118 out.closeTag("datafield")
1119 #### t o d o
1121 #out.openTag("datafield",[["tag","650"],["ind1","3"],["ind2","7"]])
1122 #out.writeTag("subfield",,[["code","a"]])
1123 #out.closeTag("datafield")
1126 # tag 700 chair name
1127 uList = conf.getChairList()
1128 for chair in uList:
1129 out.openTag("datafield",[["tag","906"],["ind1"," "],["ind2"," "]])
1130 nom = chair.getFamilyName() + " " + chair.getFirstName()
1131 out.writeTag("subfield",nom,[["code","p"]])
1132 out.writeTag("subfield",chair.getAffiliation(),[["code","u"]])
1133 out.closeTag("datafield")
1136 #out.openTag("datafield",[["tag","856"],["ind1","4"],["ind2"," "]])
1137 if includeMaterial:
1138 self.materialToXMLMarc21(conf, out=out)
1139 #out.closeTag("datafield")
1141 if conf.note:
1142 self.noteToXMLMarc21(conf.note, out=out)
1144 #if respEmail != "":
1145 # out.openTag("datafield",[["tag","859"],["ind1"," "],["ind2"," "]])
1146 # out.writeTag("subfield",respEmail,[["code","f"]])
1147 # out.closeTag("datafield")
1148 # tag 859 email
1149 uList = conf.getChairList()
1150 for chair in uList:
1151 out.openTag("datafield",[["tag","859"],["ind1"," "],["ind2"," "]])
1152 out.writeTag("subfield",chair.getEmail(),[["code","f"]])
1153 out.closeTag("datafield")
1155 edate = conf.getCreationDate()
1156 creaDate = datetime( edate.year, edate.month, edate.day )
1158 out.openTag("datafield",[["tag","961"],["ind1"," "],["ind2"," "]])
1159 out.writeTag("subfield","%d-%s-%sT"%(creaDate.year, string.zfill(creaDate.month,2), string.zfill(creaDate.day,2)),[["code","x"]])
1160 out.closeTag("datafield")
1162 edate = conf.getModificationDate()
1163 modifDate = datetime( edate.year, edate.month, edate.day )
1165 out.openTag("datafield",[["tag","961"],["ind1"," "],["ind2"," "]])
1166 out.writeTag("subfield","%d-%s-%sT"%(modifDate.year, string.zfill(modifDate.month,2), string.zfill(modifDate.day,2)),[["code","c"]])
1167 out.closeTag("datafield")
1169 out.openTag("datafield",[["tag","980"],["ind1"," "],["ind2"," "]])
1170 out.writeTag("subfield", self._getRecordCollection(conf), [["code","a"]])
1171 out.closeTag("datafield")
1173 out.openTag("datafield",[["tag","970"],["ind1"," "],["ind2"," "]])
1174 out.writeTag("subfield","INDICO." + uniqueId(conf),[["code","a"]])
1175 out.closeTag("datafield")
1177 self._generateLinkField(urlHandlers.UHConferenceDisplay, conf,
1178 "Event details", out)
1180 self._generateAccessList(conf, out, objId=uniqueId(conf))
1182 def contribToXMLMarc21(self,cont,includeMaterial=1, out=None, overrideCache=False):
1183 if not out:
1184 out = self._XMLGen
1185 #try to get a cache
1186 version = "MARC21_mat-%s"%(includeMaterial)
1187 obj = None
1188 if not overrideCache:
1189 obj = self.cache.loadObject(version, cont)
1190 if obj:
1191 xml = obj.getContent()
1192 else:
1193 # No cache, build the XML
1194 temp = XMLGen(init=False)
1195 self._contribToXMLMarc21(cont,includeMaterial, out=temp)
1196 xml = temp.getXml()
1197 # save XML in cache
1198 self.cache.cacheObject(version, xml, cont)
1199 out.writeXML(xml)
1202 def _contribToXMLMarc21(self,cont,includeMaterial=1, out=None):
1203 if not out:
1204 out = self._XMLGen
1206 out.writeTag("leader", "00000nmm 2200000uu 4500")
1207 out.openTag("datafield", [["tag", "035"], ["ind1", " "], ["ind2", " "]])
1208 out.writeTag("subfield", "INDICO.%s" % uniqueId(cont), [["code", "a"]])
1209 out.closeTag("datafield")
1211 out.openTag("datafield", [["tag", "035"], ["ind1", " "], ["ind2", " "]])
1212 out.writeTag("subfield", uniqueId(cont), [["code", "a"]])
1213 out.writeTag("subfield", "Indico", [["code", "9"]])
1214 out.closeTag("datafield")
1216 out.openTag("datafield", [["tag", "245"], ["ind1", " "], ["ind2", " "]])
1217 out.writeTag("subfield", cont.getTitle(), [["code", "a"]])
1218 out.closeTag("datafield")
1220 out.openTag("datafield", [["tag", "300"], ["ind1", " "], ["ind2", " "]])
1221 out.writeTag("subfield", cont.getDuration(), [["code", "a"]])
1222 out.closeTag("datafield")
1224 out.openTag("datafield", [["tag", "111"], ["ind1", " "], ["ind2", " "]])
1225 out.writeTag("subfield", uniqueId(cont.getConference()), [["code", "g"]])
1226 out.closeTag("datafield")
1228 edate = cont.getModificationDate()
1229 modifDate = datetime(edate.year, edate.month, edate.day)
1231 out.openTag("datafield", [["tag", "961"], ["ind1", " "], ["ind2", " "]])
1232 out.writeTag("subfield", "%d-%s-%sT" % (modifDate.year, string.zfill(modifDate.month, 2),
1233 string.zfill(modifDate.day, 2)), [["code", "c"]])
1234 out.closeTag("datafield")
1236 for path in cont.getConference().getCategoriesPath():
1237 out.openTag("datafield", [["tag", "650"], ["ind1", " "], ["ind2", "7"]])
1238 out.writeTag("subfield", ":".join(path), [["code", "a"]])
1239 out.closeTag("datafield")
1241 l = cont.getLocation()
1242 if (l and l.getName() != "") or cont.getStartDate() is not None:
1243 out.openTag("datafield", [["tag", "518"], ["ind1", " "], ["ind2", " "]])
1244 if l:
1245 if l.getName() != "":
1246 out.writeTag("subfield", l.getName(), [["code", "r"]])
1247 if cont.getStartDate() is not None:
1248 out.writeTag("subfield", "%d-%s-%sT%s:%s:00Z" % (cont.getStartDate().year,
1249 string.zfill(cont.getStartDate().month, 2), string.zfill(cont.getStartDate().day, 2),
1250 string.zfill(cont.getStartDate().hour, 2), string.zfill(cont.getStartDate().minute, 2)),
1251 [["code", "d"]])
1252 out.writeTag("subfield", "%d-%s-%sT%s:%s:00Z" % (cont.getEndDate().year,
1253 string.zfill(cont.getEndDate().month, 2), string.zfill(cont.getEndDate().day, 2),
1254 string.zfill(cont.getEndDate().hour, 2), string.zfill(cont.getEndDate().minute, 2)),
1255 [["code", "h"]])
1256 out.closeTag("datafield")
1258 out.openTag("datafield", [["tag", "520"], ["ind1", " "], ["ind2", " "]])
1259 out.writeTag("subfield", cont.getDescription(), [["code", "a"]])
1260 out.closeTag("datafield")
1262 out.openTag("datafield", [["tag", "611"], ["ind1", "2"], ["ind2", "4"]])
1263 out.writeTag("subfield", cont.getConference().getTitle(), [["code", "a"]])
1264 out.closeTag("datafield")
1267 if cont.getReportNumberHolder().listReportNumbers():
1268 out.openTag("datafield",[["tag","088"],["ind1"," "],["ind2"," "]])
1269 for report in cont.getReportNumberHolder().listReportNumbers():
1270 out.writeTag("subfield",report[1],[["code","a"]])
1271 out.closeTag("datafield")
1273 out.openTag("datafield",[["tag","653"],["ind1","1"],["ind2"," "]])
1274 keywords = cont.getKeywords()
1275 keywords = keywords.replace("\r\n", "\n")
1276 for keyword in keywords.split("\n"):
1277 out.writeTag("subfield",keyword,[["code","a"]])
1278 out.closeTag("datafield")
1280 out.openTag("datafield",[["tag","650"],["ind1","1"],["ind2","7"]])
1281 out.writeTag("subfield","SzGeCERN",[["code","2"]])
1282 if cont.getTrack():
1283 out.writeTag("subfield",cont.getTrack().getTitle(),[["code","a"]])
1284 out.closeTag("datafield")
1286 # tag 700 Speaker name
1287 aList = cont.getAuthorList()
1288 sList = cont.getSpeakerList()
1289 list = {}
1290 auth = cont.getPrimaryAuthorList()
1291 if auth:
1292 auth = auth[0]
1293 list[auth] = ["Primary Author"]
1294 for user in aList:
1295 if user in list:
1296 if user != auth:
1297 list[user].append("Author")
1298 else:
1299 list[user] = ["Author"]
1301 for user in sList:
1302 if user in list:
1303 list[user].append("Speaker")
1304 else:
1305 list[user] = ["Speaker"]
1307 if auth:
1308 user = auth
1309 out.openTag("datafield",[["tag","100"],["ind1"," "],["ind2"," "]])
1310 fullName = auth.getFamilyName() + " " + auth.getFirstName()
1311 out.writeTag("subfield",fullName,[["code","a"]])
1312 for val in list[user]:
1313 out.writeTag("subfield",val,[["code","e"]])
1314 out.writeTag("subfield",auth.getAffiliation(),[["code","u"]])
1315 out.closeTag("datafield")
1316 del list[auth]
1318 for user in list.keys():
1319 out.openTag("datafield",[["tag","700"],["ind1"," "],["ind2"," "]])
1320 fullName = user.getFamilyName() + " " + user.getFirstName()
1321 out.writeTag("subfield",fullName,[["code","a"]])
1322 for val in list[user]:
1323 out.writeTag("subfield",val,[["code","e"]])
1324 out.writeTag("subfield",user.getAffiliation(),[["code","u"]])
1325 out.closeTag("datafield")
1327 if includeMaterial:
1328 self.materialToXMLMarc21(cont, out=out)
1330 if cont.note:
1331 self.noteToXMLMarc21(cont.note, out=out)
1333 out.openTag("datafield",[["tag","962"],["ind1"," "],["ind2"," "]])
1334 out.writeTag("subfield","INDICO.%s"%uniqueId(cont.getConference()),[["code","b"]])
1335 out.closeTag("datafield")
1337 out.openTag("datafield",[["tag","970"],["ind1"," "],["ind2"," "]])
1338 confcont = "INDICO." + uniqueId(cont)
1339 out.writeTag("subfield",confcont,[["code","a"]])
1340 out.closeTag("datafield")
1342 out.openTag("datafield",[["tag","980"],["ind1"," "],["ind2"," "]])
1343 out.writeTag("subfield", self._getRecordCollection(cont), [["code","a"]])
1344 out.closeTag("datafield")
1346 self._generateLinkField(urlHandlers.UHContributionDisplay,
1347 cont, "Contribution details", out)
1348 self._generateLinkField(urlHandlers.UHConferenceDisplay,
1349 cont.getConference(), "Event details", out)
1351 self._generateAccessList(cont, out, objId=uniqueId(cont))
1352 ####
1356 def subContribToXMLMarc21(self,subCont,includeMaterial=1, out=None, overrideCache=False):
1357 if not out:
1358 out = self._XMLGen
1359 #try to get a cache
1360 version = "MARC21_mat-%s"%(includeMaterial)
1361 obj = None
1362 if not overrideCache:
1363 obj = self.cache.loadObject(version, subCont)
1364 if obj:
1365 xml = obj.getContent()
1366 else:
1367 # No cache, build the XML
1368 temp = XMLGen(init=False)
1369 self._subContribToXMLMarc21(subCont,includeMaterial, out=temp)
1370 xml = temp.getXml()
1371 # save XML in cache
1372 self.cache.cacheObject(version, xml, subCont)
1373 out.writeXML(xml)
1376 def _subContribToXMLMarc21(self,subCont,includeMaterial=1, out=None):
1377 if not out:
1378 out = self._XMLGen
1380 out.writeTag("leader", "00000nmm 2200000uu 4500")
1381 out.openTag("datafield",[["tag","035"],["ind1"," "],["ind2"," "]])
1382 out.writeTag("subfield","INDICO.%s" % (uniqueId(subCont)), [["code","a"]])
1383 out.closeTag("datafield")
1385 out.openTag("datafield",[["tag","035"],["ind1"," "],["ind2"," "]])
1386 out.writeTag("subfield",uniqueId(subCont), [["code","a"]])
1387 out.writeTag("subfield","Indico",[["code","9"]])
1388 out.closeTag("datafield")
1390 out.openTag("datafield",[["tag","245"],["ind1"," "],["ind2"," "]])
1391 out.writeTag("subfield",subCont.getTitle(),[["code","a"]])
1392 out.closeTag("datafield")
1394 out.openTag("datafield",[["tag","300"],["ind1"," "],["ind2"," "]])
1395 out.writeTag("subfield",subCont.getDuration(),[["code","a"]])
1396 out.closeTag("datafield")
1398 out.openTag("datafield",[["tag","111"],["ind1"," "],["ind2"," "]])
1399 out.writeTag("subfield", uniqueId(subCont.getConference()), [["code","g"]])
1400 out.closeTag("datafield")
1402 if subCont.getReportNumberHolder().listReportNumbers():
1403 out.openTag("datafield",[["tag","088"],["ind1"," "],["ind2"," "]])
1404 for report in subCont.getReportNumberHolder().listReportNumbers():
1405 out.writeTag("subfield",report[1],[["code","a"]])
1406 out.closeTag("datafield")
1409 out.openTag("datafield",[["tag","653"],["ind1","1"],["ind2"," "]])
1410 keywords = subCont.getKeywords()
1411 keywords = keywords.replace("\r\n", "\n")
1412 for keyword in keywords.split("\n"):
1413 out.writeTag("subfield",keyword,[["code","a"]])
1414 out.closeTag("datafield")
1417 for path in subCont.getConference().getCategoriesPath():
1418 out.openTag("datafield",[["tag","650"],["ind1"," "],["ind2","7"]])
1419 out.writeTag("subfield", ":".join(path), [["code","a"]])
1420 out.closeTag("datafield")
1422 l=subCont.getLocation()
1423 if (l and l.getName() != "") or subCont.getContribution().getStartDate() is not None:
1424 out.openTag("datafield",[["tag","518"],["ind1"," "],["ind2"," "]])
1425 if l:
1426 if l.getName() != "":
1427 out.writeTag("subfield",l.getName(),[["code","r"]])
1428 if subCont.getContribution().getStartDate() is not None:
1429 out.writeTag("subfield","%d-%s-%sT%s:%s:00Z" %(subCont.getContribution().getStartDate().year, string.zfill(subCont.getContribution().getStartDate().month,2), string.zfill(subCont.getContribution().getStartDate().day,2), string.zfill(subCont.getContribution().getStartDate().hour,2), string.zfill(subCont.getContribution().getStartDate().minute,2)),[["code","d"]])
1430 out.closeTag("datafield")
1432 out.openTag("datafield",[["tag","520"],["ind1"," "],["ind2"," "]])
1433 out.writeTag("subfield",subCont.getDescription(),[["code","a"]])
1434 out.closeTag("datafield")
1436 out.openTag("datafield",[["tag","611"],["ind1","2"],["ind2","4"]])
1437 out.writeTag("subfield",subCont.getConference().getTitle(),[["code","a"]])
1438 out.closeTag("datafield")
1440 out.openTag("datafield",[["tag","650"],["ind1","1"],["ind2","7"]])
1441 out.writeTag("subfield","SzGeCERN",[["code","2"]])
1442 if subCont.getContribution().getTrack():
1443 out.writeTag("subfield",subCont.getContribution().getTrack().getTitle(),[["code","a"]])
1444 out.closeTag("datafield")
1447 # tag 700 Speaker name
1448 aList = subCont.getContribution().getAuthorList()
1449 sList = subCont.getSpeakerList()
1450 list = {}
1451 auth = subCont.getContribution().getPrimaryAuthorList()
1452 if auth:
1453 auth = auth[0]
1454 list[auth] = ["Primary Author"]
1455 for user in aList:
1456 if user in list:
1457 if user != auth:
1458 list[user].append("Author")
1459 else:
1460 list[user] = ["Author"]
1462 for user in sList:
1463 if user in list:
1464 list[user].append("Speaker")
1465 else:
1466 list[user] = ["Speaker"]
1468 if auth:
1469 user = auth
1470 out.openTag("datafield",[["tag","100"],["ind1"," "],["ind2"," "]])
1471 fullName = auth.getFamilyName() + " " + auth.getFirstName()
1472 out.writeTag("subfield",fullName,[["code","a"]])
1473 for val in list[user]:
1474 out.writeTag("subfield",val,[["code","e"]])
1475 out.writeTag("subfield",auth.getAffiliation(),[["code","u"]])
1476 out.closeTag("datafield")
1477 del list[auth]
1479 for user in list.keys():
1480 out.openTag("datafield",[["tag","700"],["ind1"," "],["ind2"," "]])
1481 fullName = user.getFamilyName() + " " + user.getFirstName()
1482 out.writeTag("subfield",fullName,[["code","a"]])
1483 for val in list[user]:
1484 out.writeTag("subfield",val,[["code","e"]])
1485 out.writeTag("subfield",user.getAffiliation(),[["code","u"]])
1486 out.closeTag("datafield")
1488 if includeMaterial:
1489 self.materialToXMLMarc21(subCont, out=out)
1491 if subCont.note:
1492 self.noteToXMLMarc21(subCont.note, out=out)
1494 out.openTag("datafield",[["tag","962"],["ind1"," "],["ind2"," "]])
1495 out.writeTag("subfield","INDICO.%s"%uniqueId(subCont.getConference()),[["code","b"]])
1496 out.closeTag("datafield")
1498 out.openTag("datafield",[["tag","970"],["ind1"," "],["ind2"," "]])
1499 confcont = "INDICO." + uniqueId(subCont)
1500 out.writeTag("subfield",confcont,[["code","a"]])
1501 out.closeTag("datafield")
1503 out.openTag("datafield",[["tag","980"],["ind1"," "],["ind2"," "]])
1504 out.writeTag("subfield", self._getRecordCollection(subCont), [["code","a"]])
1505 out.closeTag("datafield")
1507 self._generateLinkField(urlHandlers.UHSubContributionDisplay, subCont,
1508 "Contribution details", out)
1509 self._generateLinkField(urlHandlers.UHConferenceDisplay,
1510 subCont.getConference(), "Event details", out)
1512 self._generateAccessList(subCont, out, objId=uniqueId(subCont))
1514 def materialToXMLMarc21(self, obj, out=None):
1515 if not out:
1516 out = self._XMLGen
1518 for attachment in (Attachment.find(~AttachmentFolder.is_deleted, AttachmentFolder.linked_object == obj,
1519 is_deleted=False, _join=AttachmentFolder)
1520 .options(joinedload(Attachment.legacy_mapping))):
1521 if attachment.can_access(self.__aw.getUser().user):
1522 self.resourceToXMLMarc21(attachment, out)
1523 self._generateAccessList(acl=self._attachment_access_list(attachment), out=out,
1524 objId=self._attachment_unique_id(attachment))
1526 def resourceToXMLMarc21(self, res, out=None):
1527 if not out:
1528 out = self._XMLGen
1529 if res.type == AttachmentType.file:
1530 self.resourceFileToXMLMarc21(res, out=out)
1531 else:
1532 self.resourceLinkToXMLMarc21(res, out=out)
1534 @classmethod
1535 def _attachment_unique_id(self, attachment):
1536 unique_id = "INDICO." + uniqueId(attachment.folder.linked_object)
1537 if attachment.legacy_mapping:
1538 unique_id += "m{}.{}".format(attachment.legacy_mapping.material_id, attachment.legacy_mapping.resource_id)
1539 else:
1540 unique_id += "a{}".format(attachment.id)
1542 return unique_id
1544 @classmethod
1545 def _attachment_access_list(self, attachment):
1547 linked_object = attachment.folder.linked_object
1548 manager_list = set(linked_object.getRecursiveManagerList())
1550 if attachment.is_protected:
1551 return {e.as_legacy for e in attachment.acl} | manager_list
1552 if attachment.is_inheriting and attachment.folder.is_protected:
1553 return {e.as_legacy for e in attachment.folder.acl} | manager_list
1554 else:
1555 return linked_object.getRecursiveAllowedToAccessList()
1557 def resourceLinkToXMLMarc21(self, attachment, out=None):
1558 if not out:
1559 out = self._XMLGen
1561 out.openTag("datafield", [["tag", "856"], ["ind1", "4"], ["ind2", " "]])
1562 out.writeTag("subfield", attachment.description, [["code", "a"]])
1563 out.writeTag("subfield", attachment.absolute_download_url, [["code", "u"]])
1564 out.writeTag("subfield", self._attachment_unique_id(attachment), [["code", "3"]])
1565 out.writeTag("subfield", "resource", [["code", "x"]])
1566 out.writeTag("subfield", "external", [["code", "z"]])
1567 out.writeTag("subfield", attachment.title, [["code", "y"]])
1568 out.closeTag("datafield")
1570 def resourceFileToXMLMarc21(self, attachment, out=None):
1571 if not out:
1572 out = self._XMLGen
1574 out.openTag("datafield", [["tag", "856"], ["ind1", "4"], ["ind2", " "]])
1575 out.writeTag("subfield", attachment.description, [["code", "a"]])
1576 out.writeTag("subfield", attachment.file.size, [["code", "s"]])
1578 out.writeTag("subfield", attachment.absolute_download_url, [["code", "u"]])
1579 out.writeTag("subfield", self._attachment_unique_id(attachment), [["code", "3"]])
1580 out.writeTag("subfield", attachment.title, [["code", "y"]])
1581 out.writeTag("subfield", "stored", [["code", "z"]])
1582 out.writeTag("subfield", "resource", [["code", "x"]])
1583 out.closeTag("datafield")
1585 def noteToXMLMarc21(self, note, out=None):
1586 if not out:
1587 out = self._XMLGen
1588 out.openTag('datafield', [['tag', '856'], ['ind1', '4'], ['ind2', ' ']])
1589 out.writeTag('subfield', url_for('event_notes.view', note, _external=True), [['code', 'u']])
1590 out.writeTag('subfield', '{} - Minutes'.format(note.linked_object.getTitle()), [['code', 'y']])
1591 out.writeTag('subfield', 'INDICO.{}'.format(uniqueId(note)), [['code', '3']])
1592 out.writeTag('subfield', 'resource', [['code', 'x']])
1593 out.closeTag('datafield')
1596 class XMLCacheEntry(MultiLevelCacheEntry):
1597 def __init__(self, objId):
1598 MultiLevelCacheEntry.__init__(self)
1599 self.id = objId
1601 def getId(self):
1602 return self.id
1604 @classmethod
1605 def create(cls, content, obj):
1606 entry = cls(getHierarchicalId(obj))
1607 entry.setContent(content)
1608 return entry
1611 class XMLCache(MultiLevelCache):
1613 _entryFactory = XMLCacheEntry
1615 def __init__(self):
1616 MultiLevelCache.__init__(self, 'xml')
1619 def isDirty(self, mtime, object):
1620 modDate = resolveHierarchicalId(object.getId())._modificationDS
1621 fileModDate = timezone("UTC").localize(
1622 datetime.utcfromtimestamp(mtime))
1624 # check file system date vs. event date
1625 return (modDate > fileModDate)
1627 def _generatePath(self, entry):
1629 Generate the actual hierarchical location
1632 # a205.0 -> /cachedir/a/a2/a205/0
1634 tree = entry.getId().split('.')
1635 return [tree[0][0], tree[0][0:2]] + tree