Changeset 56571d6 in indico
- Timestamp:
- 03/03/10 19:02:10 (3 years ago)
- Branches:
- master, burotel, hello-world-walkthrough, ipv6, new-webex, prov-dual-interface, v0.97-series, v0.98-series, v0.98.2, v0.98.3, v0.98b1, v0.98b2, v0.99, 051b2622c51afb171a1dedb46a0df4fbb0cbd02e, 0da0c1403bae8e51d8229f460181c71b9e6dda72
- Children:
- bf522c
- Parents:
- 2cc320
- git-author:
- David Martín Clavo <david.martin.clavo@…> (02/24/10 13:44:46)
- git-committer:
- Jose Benito <jose.benito.gonzalez@…> (03/03/10 19:02:10)
- Files:
-
- 1 added
- 8 edited
-
indico/MaKaC/common/TemplateExec.py (modified) (36 diffs)
-
indico/MaKaC/common/fossilize.py (modified) (7 diffs)
-
indico/MaKaC/fossils/user.py (added)
-
indico/MaKaC/services/implementation/user.py (modified) (15 diffs)
-
indico/MaKaC/user.py (modified) (108 diffs)
-
indico/MaKaC/webinterface/tpls/AdminPluginsOptionList.tpl (modified) (8 diffs)
-
indico/MaKaC/webinterface/tpls/UserBaskets.tpl (modified) (2 diffs)
-
indico/htdocs/js/indico/Management/Users.js (modified) (2 diffs)
-
tests/MaKaC_tests/common_tests/testFossilize.py (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
indico/MaKaC/common/TemplateExec.py
rbd21e7 r56571d6 40 40 41 41 class TemplateExecException( Exception ): 42 42 43 43 def __init__( self, value ): 44 44 self.value = value … … 47 47 if hasattr(value, 'problematic_templates'): 48 48 self.problematic_templates = value.problematic_templates 49 49 50 50 def __str__(self): 51 51 s = str( type(self.value).__name__) + ": " + str(self.value ) … … 54 54 if hasattr(self, 'problematic_templates'): 55 55 s += """ - - - -> {Python code generated from templates is available in %s/%s.tpl.error.py""" % ( ERROR_PATH, self.problematic_templates[0]) 56 56 57 57 for template_name in self.problematic_templates[1:]: 58 58 s += ", %s/%s.py"%(ERROR_PATH, template_name) 59 59 s += " file(s)}" 60 60 61 61 return s 62 62 63 63 def declareTemplate(newTemplateStyle=False): 64 64 65 65 objDict = globals()['_objDict'] 66 66 objDict['newTemplateStyle'] = newTemplateStyle … … 70 70 Use: 71 71 <% includeTpl( 'TemplateName', paramA = 2, paramB = 3 ) %> 72 """ 72 """ 73 73 74 74 # Resurrect dictionary from globals - ugly hack. 75 75 # In the recurrent exec, we still need an old dictCopy. 76 # This old dictCopy is resurrected from the global scope. 76 # This old dictCopy is resurrected from the global scope. 77 77 objDict = globals()['_dictCopy'] 78 78 for k, v in kwargs.iteritems(): … … 82 82 from MaKaC.webinterface import wcomponents 83 83 result = wcomponents.WTemplated(tplFileName).getHTML(objDict) 84 84 85 85 globals()['_objDict']["newTemplateStyle"] = True 86 86 87 87 print( result.replace('%', '%%') ) 88 88 … … 93 93 """ 94 94 includeTpl( 'ContextHelp', helpId = helpId, imgSrc = Config.getInstance().getSystemIconURL( "help" ) ) 95 95 96 96 def inlineContextHelp( helpContent ): 97 97 """ … … 99 99 Help content passed as argument helpContent. 100 100 """ 101 includeTpl( 'InlineContextHelp', helpContent = helpContent, imgSrc = Config.getInstance().getSystemIconURL( "help" ) ) 101 includeTpl( 'InlineContextHelp', helpContent = helpContent, imgSrc = Config.getInstance().getSystemIconURL( "help" ) ) 102 102 103 103 def escapeAttrVal( s ): … … 121 121 def verbose( s, default = "" ): 122 122 """ 123 Purpose: avoid showing "None" to user; show default value instead. 123 Purpose: avoid showing "None" to user; show default value instead. 124 124 """ 125 125 if isinstance( s, bool ) and s != None: … … 128 128 else: 129 129 return "no" 130 130 131 131 return s or default 132 132 … … 158 158 159 159 def roomClass( room ): 160 if room.isReservable: 160 if room.isReservable: 161 161 roomClass = "" 162 if not room.isReservable: 163 roomClass = "privateRoom" 164 if room.isReservable and room.resvsNeedConfirmation: 162 if not room.isReservable: 163 roomClass = "privateRoom" 164 if room.isReservable and room.resvsNeedConfirmation: 165 165 roomClass = "moderatedRoom" 166 166 return roomClass … … 186 186 Author: David Martin Clavo 187 187 """ 188 188 189 189 # stringfy objects inside a list 190 190 if isinstance(obj,list): 191 191 for i in range(0, len(obj)): 192 192 obj[i] = deepstr(obj[i]) 193 193 194 194 #stringfy objects inside a dictionary 195 195 if isinstance(obj,dict): … … 197 197 del obj[k] #we delete the old key 198 198 obj[deepstr(k)] = deepstr(v) 199 199 200 200 return str(obj) 201 201 … … 208 208 See BeautifulHTMLList.tpl and BeautifulHTMLDict.tpl to see how they are used. 209 209 In the CSS file, you should define classes like: ul.optionList1, ul.optionList2, ul.optionKey1 (the number is the level of recursivity) 210 -level: the level of recursivity. 210 -level: the level of recursivity. 211 211 """ 212 212 from MaKaC.webinterface import wcomponents … … 234 234 else: 235 235 return title 236 236 237 237 def escapeHTMLForJS(s): 238 238 """ Replaces some restricted characters in JS strings. … … 247 247 (backspace) -> \b 248 248 (form feed) -> \f 249 249 250 250 TODO: try to optimize this (or check if it's optimum already). 251 251 translate() doesn't work, because we are replacing characters by couples of characters. … … 260 260 """ 261 261 Enables template execution. 262 262 263 263 Template is a string mixing any text (HTML, e-mail, etc.) 264 264 with Python code. … … 267 267 268 268 Every Python expression put between <%= %> will be EVALUATED 269 and result will be put in place of expression. 270 269 and result will be put in place of expression. 270 271 271 Every Python statements put between <% %> will be EXECUTED. 272 272 Standard output (stdout) will be put in place of these statements. 273 273 (so you can do <% print %>) 274 274 275 275 Every strings put between %()s will be SUBSTITUTED with the 276 276 corresponding value from given dictionary. 277 277 278 278 Examples of templates: 279 279 280 280 # Example 1: 281 281 <tr><td> <%= 2 + 5 %> </td> </tr> 282 282 283 283 # Example 2: 284 284 Hello <%= person.fistName %>! 285 285 Your reservation for <%= period.startDT %> -- <%= period.endDT %> is confirmed. 286 286 287 287 # Example 3: 288 288 <html> … … 292 292 <body> 293 293 <h1> <%= room.name.capitalize() %> </h1> 294 294 295 295 <% import os %> <!-- Not necessary here - just to show you can do this --> 296 296 Let's skip odd columns. … … 300 300 <% for column in xrange( 0, 6 ): %> 301 301 <% if column % 2 == 0: %> 302 <td style="background-color:lightgray"> Row = <%= row %>, Column = <%= column %> </td> 302 <td style="background-color:lightgray"> Row = <%= row %>, Column = <%= column %> </td> 303 303 <% end %> 304 304 <% end %> … … 312 312 Template is execution context => objects live through the hole template, 313 313 and not only in their <% %> tag. 314 314 315 315 You can include another templates via includeTpl( 'TemplateName' ). 316 316 The child templates inherit execution context, so all parent objects 317 are available to it. 317 are available to it. 318 318 319 319 Restrictions: … … 321 321 => you CAN NOT use strings like "foo:goo" 322 322 => you CAN NOT initialize dictionaries dic = { a: 2, b: 3 } 323 => you can write statements like: for i in xrange( 0, 10 ): 323 => you can write statements like: for i in xrange( 0, 10 ): 324 324 2) You CAN NOT put blok in the same line as statement: 325 => BAD: 325 => BAD: 326 326 if a == 2: break 327 327 Use instead: 328 328 if a == 2: 329 329 break 330 330 331 331 These limitations are consequence of Python syntax-by-indentation rules. 332 332 """ … … 344 344 345 345 Returns resulting string. 346 346 347 347 tpl - template string 348 348 objDict - context dictionary; insert objects and strings there. 349 """ 349 """ 350 350 # IMPLEMENTATION 351 351 # General idea is to convert template into Python code and then execute it. 352 352 # With includeTpl(), these may go recurrent. 353 #global recurrenceLevel 353 #global recurrenceLevel 354 354 #recurrenceLevel += 1 355 355 … … 357 357 lastIx = 0 # Index of last Python code in template 358 358 indentLevel = 0 # Indentation level 359 359 360 360 # Copy the dictionary, since it will be modified. 361 361 # We do not want to mess up with the oryginal dict. 362 dictCopy = objDict.copy() 362 dictCopy = objDict.copy() 363 363 364 364 TemplateExec.__registerHelpers( dictCopy ) … … 371 371 globals()['_dictCopy'] = dictCopy 372 372 globals()['_objDict'] = objDict 373 373 374 374 while True: 375 375 ixSt, ixEnd, type, statement = TemplateExec.__nextPythonCode( tpl, lastIx ) 376 376 377 377 # Human text between Python codes: convert to Python code (print) 378 378 humanText = tpl[lastIx:ixSt] … … 380 380 humanText = TemplateExec.__neutralizeLastChar( humanText ) 381 381 pythonCode += '\n%ssys.stdout.write( """%s""" )' % ( TemplateExec.__indent( indentLevel ), humanText ) 382 383 if TemplateExec.__isBlockEnd( statement ): 382 383 if TemplateExec.__isBlockEnd( statement ): 384 384 indentLevel -= 1 385 385 386 386 # Deal with Python code 387 if statement == None: 387 if statement == None: 388 388 break 389 389 … … 396 396 pythonCode += "\n%s%s" % ( TemplateExec.__indent( indentLevel ), statement ) 397 397 # Try to find all trailing ':' <== OVERSIMPLIFIED 398 indentLevel += statement.count( ':' ) 398 indentLevel += statement.count( ':' ) 399 399 lastIx = ixEnd + 2 # Move after this Python code 400 400 401 try: 402 newTpl = TemplateExec.__executePythonCode( pythonCode, dictCopy, tplFilename ) 401 try: 402 newTpl = TemplateExec.__executePythonCode( pythonCode, dictCopy, tplFilename ) 403 403 except TemplateExecException, e: 404 404 405 405 try: open( ERROR_PATH + "/" + tplFilename + ".tpl.py", "w" ).write( pythonCode ) 406 406 except: pass 407 407 raise TemplateExecException( e ) 408 except Exception, e: 408 except Exception, e: 409 409 try: open( ERROR_PATH + "/" + tplFilename + ".tpl.error.py", "w" ).write( pythonCode ) 410 410 except: pass 411 411 raise TemplateExecException( e ) 412 412 #except: 413 # raise pythonCode 414 415 413 # raise pythonCode 414 415 416 416 try: 417 417 if (not objDict.has_key( "isIncluded" ) and \ … … 444 444 #recurrenceLevel -= 1 445 445 446 #if recurrenceLevel == 0 and globals().has_key( '_dictCopy' ): 446 #if recurrenceLevel == 0 and globals().has_key( '_dictCopy' ): 447 447 ## Clean up - we do not want to mess up with global scope 448 448 #global _dictCopy … … 453 453 454 454 # PRIVATE ================================================================ 455 455 456 456 @staticmethod 457 457 def __saveDebugInfo(e, tplFilename): … … 469 469 def __executePythonCode( pythonCode, objDict, tplFilename ): 470 470 global recurrenceLevel 471 # Execute the pythonCode ------------------------- 471 # Execute the pythonCode ------------------------- 472 472 473 473 # create file-like string to capture output … … 495 495 496 496 raise e 497 497 498 498 sys.stdout = stdoutBackup 499 499 sys.stderr = stderrBackup 500 500 501 501 newTpl = "" 502 502 503 503 s = codeErr.getvalue() 504 504 if s: newTpl += "<font color='red'>%s</font>" % s 505 505 506 506 s = codeOut.getvalue() 507 507 if s: newTpl += s 508 508 509 509 codeOut.close() 510 codeErr.close() 511 510 codeErr.close() 511 512 512 return newTpl 513 513 … … 582 582 except: 583 583 # if the connection to the database is not started, there is no need to set the variable and 584 # we avoid an error report. 584 # we avoid an error report. 585 585 # THIS IS NEEDED, when using JSContent. JSContent does not need connection to the database 586 586 # and this is causing an unexpected exception. … … 609 609 # allow fossilization 610 610 if not 'fossilize' in objDict: 611 from MaKaC.common import fossilize611 from MaKaC.common.fossilize import fossilize 612 612 objDict['fossilize'] = fossilize 613 613 #if not 'minfo' in objDict: … … 630 630 return INDENTATION * n 631 631 632 @staticmethod 632 @staticmethod 633 633 def __nextPythonCode( tpl, afterIx ): 634 634 """ 635 635 Returns a tuple: 636 ( 637 start index, 636 ( 637 start index, 638 638 end index, 639 639 type, … … 655 655 statement = tpl[ixSt + 3 : ixEnd].strip() 656 656 else: 657 type = 'NonIndentBlock' 657 type = 'NonIndentBlock' 658 658 statement = tpl[ixSt + 2 : ixEnd].strip() 659 660 659 660 661 661 return ( ixSt, ixEnd, type, statement ) 662 662 … … 695 695 <% for column in xrange( 0, 6 ): %> 696 696 <% if column % 2 == 0: %> 697 <td style="background-color:lightgray"> Row = <%= row %>, Column = <%= column %> </td> 697 <td style="background-color:lightgray"> Row = <%= row %>, Column = <%= column %> </td> 698 698 <% end %> 699 699 <% end %> … … 705 705 </html> 706 706 """ 707 707 708 708 dic = {} 709 709 dic['title'] = "Templating example" -
indico/MaKaC/common/fossilize.py
r046026 r56571d6 35 35 pass 36 36 37 class InvalidFossilException(Exception): 38 pass 39 37 40 class IFossil(zope.interface.Interface): 38 41 """ … … 46 49 """ 47 50 48 __nameRE = re.compile('^get(.*)$') 51 __fossilNameRE = re.compile('^I(.*)Fossil$') 52 __methodNameRE = re.compile('^get(.*)$') 53 49 54 50 55 @classmethod … … 52 57 """ 'De-camelcase' the name """ 53 58 54 m = cls.__ nameRE.match(name)59 m = cls.__methodNameRE.match(name) 55 60 56 61 if not m: … … 65 70 return map(lambda elem: cls.__fossilizeIterable(elem, interface, **kwargs), obj) 66 71 elif type(obj) == dict: 67 return dict((k, cls.__fossilizeIterable(v, interface, **kwargs)) for k,v in obj.iteritems())72 return dict((k, cls.__fossilizeIterable(v, interface, **kwargs)) for k,v in obj.iteritems()) 68 73 else: 69 74 return obj.fossilize(interface, **kwargs) … … 79 84 if not interface.providedBy(self): 80 85 raise WrongFossilTypeException("Interface '%s' not provided by '%s'" % (interface.__name__, self.__class__.__name__)) 86 87 fossilNameMatch = Fossilizable.__fossilNameRE.match(interface.getName()) 88 if fossilNameMatch is None: 89 raise InvalidFossilException("Invalid fossil name: %s. A fossil name should follow the pattern: I******Fossil." % interface.getName()) 81 90 82 91 result = {} … … 108 117 result[attrName] = methodResult 109 118 119 if "_type" in result or "_fossil" in result: 120 raise InvalidFossilException('"_type" or "_fossil" cannot be a fossil attribute name') 121 else: 122 result["_type"] = self.__class__.__name__ 123 innerFossilName = fossilNameMatch.group(1) 124 if innerFossilName: #we check that it's not an empty string 125 result["_fossil"] = innerFossilName[0].lower() + innerFossilName[1:] 126 else: 127 result["_fossil"] = "" 128 110 129 return result 111 130 … … 128 147 return map(lambda elem: fossilize(elem, interface, **kwargs), target) 129 148 elif t is dict: 130 return dict((k, fossilize(v, interface, **kwargs)) for k, v in target.iteritems())149 return dict((k, fossilize(v, interface, **kwargs)) for k, v in target.iteritems()) 131 150 else: 132 151 raise NonFossilizableException() -
indico/MaKaC/services/implementation/user.py
rf78b0c r56571d6 1 from MaKaC.services.implementation.base import ProtectedDisplayService 1 # -*- coding: utf-8 -*- 2 ## 3 ## This file is part of CDS Indico. 4 ## Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 CERN. 5 ## 6 ## CDS Indico is free software; you can redistribute it and/or 7 ## modify it under the terms of the GNU General Public License as 8 ## published by the Free Software Foundation; either version 2 of the 9 ## License, or (at your option) any later version. 10 ## 11 ## CDS Indico is distributed in the hope that it will be useful, but 12 ## WITHOUT ANY WARRANTY; without even the implied warranty of 13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 ## General Public License for more details. 15 ## 16 ## You should have received a copy of the GNU General Public License 17 ## along with CDS Indico; if not, write to the Free Software Foundation, Inc., 18 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 19 2 20 from MaKaC.services.implementation.base import LoggedOnlyService, ProtectedService 3 21 from MaKaC.services.implementation.base import ServiceBase 4 22 5 import MaKaC.conference as conference6 23 import MaKaC.user as user 7 24 from MaKaC.services.interface.rpc.common import ServiceError … … 11 28 12 29 import time 30 from MaKaC.fossils.user import IAvatarAllDetailsFossil, IAvatarDetailedFossil,\ 31 IAvatarMinimalFossil 32 from MaKaC.common.fossilize import fossilize 13 33 14 34 class UserListEvents(LoggedOnlyService): … … 17 37 LoggedOnlyService._checkParams(self) 18 38 19 self._time = self._params.get('time', None)39 self._time = self._params.get('time', None) 20 40 self._target = self.getAW().getUser() 21 41 … … 60 80 jsonData[event['id']] = event 61 81 62 return jsonData; 82 return jsonData 83 63 84 64 85 class UserAddToBasket(LoggedOnlyService): 86 65 87 def _checkParams(self): 66 88 LoggedOnlyService._checkParams(self) … … 83 105 84 106 for user in self._userList: 85 if (not self._target.getPersonalInfo().getBasket().addElement(user)): 86 raise ServiceError("ERR-U1","Element already exists in list!") 107 #we do not care if the user is already in the favourites 108 self._target.getPersonalInfo().getBasket().addElement(user) 109 87 110 88 111 class UserRemoveFromBasket(LoggedOnlyService): … … 101 124 if (self._obj == None): 102 125 raise ServiceError("ERR-U0","User does not exist!") 103 if (self._target.getPersonalInfo().getBasket().deleteElement(self._obj)): 104 return105 else:106 raise ServiceError("ERR-U2","Element not in list!") 126 127 #we do not care if the user is already out of the favourites 128 self._target.getPersonalInfo().getBasket().deleteElement(self._obj) 129 107 130 108 131 class UserListBasket(ProtectedService): … … 117 140 118 141 self._target = self.getAW().getUser() 142 self._detailLevel = self._params.get("detailLevel", "max") 119 143 120 144 def _getAnswer( self): … … 122 146 if self._target: 123 147 users = self._target.getPersonalInfo().getBasket().getUsers().values() 124 return DictPickler.pickle(users) 148 149 if self._detailLevel == "min": 150 fossilToUse = IAvatarMinimalFossil 151 elif self._detailLevel == "medium": 152 fossilToUse = IAvatarDetailedFossil 153 elif self._detailLevel == "max": 154 fossilToUse = IAvatarAllDetailsFossil 155 156 return fossilize(users, fossilToUse) 125 157 else: 126 158 return None … … 137 169 def _getAnswer( self): 138 170 return DictPickler.pickle(self._target.getPersonalInfo()) 171 139 172 140 173 class UserGetEmail(LoggedOnlyService): … … 151 184 raise ServiceError("ERR-U4","User is not logged in") 152 185 186 153 187 class UserSetPersonalInfo(LoggedOnlyService): 154 188 … … 157 191 158 192 self._target = self.getAW().getUser() 159 self._info = self._params.get("value", None)193 self._info = self._params.get("value", None) 160 194 161 195 def _getAnswer( self): … … 169 203 return DictPickler.pickle(pInfo) 170 204 205 171 206 class UserGetTimezone(ServiceBase): 172 207 … … 178 213 return tz 179 214 215 180 216 class UserGetSessionTimezone(ServiceBase): 181 217 … … 184 220 return tz 185 221 222 186 223 class UserGetSessionLanguage(ServiceBase): 187 224 … … 192 229 minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance() 193 230 return minfo.getLang() 231 194 232 195 233 methodMap = { -
indico/MaKaC/user.py
ra0203b r56571d6 20 20 ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 21 22 """Contains the classes that implement the user management subsystem 23 """ 22 from MaKaC.fossils.user import IAvatarMinimalFossil, IAvatarDetailedFossil,\ 23 IAvatarAllDetailsFossil 24 from MaKaC.common.fossilize import Fossilizable, fossilizes 24 25 from random import random 25 26 … … 54 55 from copy import copy 55 56 57 """Contains the classes that implement the user management subsystem 58 """ 59 56 60 class Group(Persistent): 57 61 """ … … 102 106 self.email = "" 103 107 return self.email 104 108 105 109 def addMember( self, newMember ): 106 110 if newMember == self: … … 112 116 newMember.linkTo(self, "member") 113 117 self._p_changed = 1 114 118 115 119 def removeMember( self, member ): 116 120 if member == None or member not in self.members: … … 144 148 continue 145 149 return 0 146 150 147 151 def canModify( self, aw ): 148 152 return self.canUserModify( aw.getUser() ) … … 158 162 159 163 class NiceGroup(Group): 160 164 161 165 groupType = "Nice" 162 166 163 167 def addMember( self, newMember ): 164 168 pass 165 169 166 170 def removeMember( self, member ): 167 171 pass … … 169 173 def getMemberList( self ): 170 174 return [] 171 175 172 176 def containsUser( self, avatar ): 173 177 if avatar == None: … … 178 182 return True 179 183 return False 180 184 181 185 def containsMember( self, member ): 182 186 return 0 183 187 184 188 class CERNGroup(Group): 185 189 186 190 groupType = "CERN" 187 191 188 192 def addMember( self, newMember ): 189 193 pass 190 194 191 195 def removeMember( self, member ): 192 196 pass 193 197 194 198 def getMemberList( self ): 195 199 params = urllib.urlencode( { 'ListName': self.name } ) … … 209 213 #print data 210 214 conn.close() 211 215 212 216 try: 213 217 doc = parseString( data ) … … 231 235 avatarLists.append( lst ) 232 236 return [ avList[0] for avList in avatarLists if avList ] 233 237 234 238 def containsUser( self, avatar ): 235 239 if avatar == None: … … 278 282 response = conn.getresponse() 279 283 data = response.read() 280 conn.close() 284 conn.close() 281 285 try: 282 286 doc = parseString(data) … … 299 303 _id="name" 300 304 301 def satisfies(self,group): 305 def satisfies(self,group): 302 306 for value in self._values: 303 307 if value.strip() != "": … … 349 353 def getLength( self ): 350 354 return self.getIndex().getLength() 351 355 352 356 def matchFirstLetter( self, letter, forceWithoutExtAuth=False ): 353 357 result = [] … … 364 368 pass 365 369 return result 366 370 367 371 def match(self,criteria,forceWithoutExtAuth=False, exact=False): 368 372 crit={} … … 381 385 result.append(gr) 382 386 return result 383 387 384 388 def updateCERNGroupMatch(self, name, exact=False): 385 389 if not exact: … … 408 412 gr.setDescription( _("""_("Mapping of the Nice group") %s""")%name+"<br><br>\nMembers list: https://websvc02.cern.ch/WinServices/Services/GroupManager/GroupManager.aspx") 409 413 self.add(gr) 410 411 412 413 class Avatar(Persistent ):414 """This class implements the representation of users inside the system. 415 Basically it contains personal data from them which is relevant for the 414 415 416 417 class Avatar(Persistent, Fossilizable): 418 """This class implements the representation of users inside the system. 419 Basically it contains personal data from them which is relevant for the 416 420 system. 417 421 """ 422 fossilizes(IAvatarMinimalFossil, IAvatarDetailedFossil, IAvatarAllDetailsFossil) 423 418 424 linkedToBase = {"category":{"creator":[], 419 425 "manager":[], … … 454 460 """Class constructor. 455 461 Attributes: 456 userData -- dictionary containing user data to map into the 457 avatar. Possible key values (those with * are 462 userData -- dictionary containing user data to map into the 463 avatar. Possible key values (those with * are 458 464 multiple): 459 465 name, surname, title, organisation*, addess*, … … 474 480 from MaKaC.common import utils 475 481 self.key = utils.newKey() #key to activate the account 476 self.registrants = {} 477 482 self.registrants = {} 483 478 484 minfo = info.HelperMaKaCInfo.getMaKaCInfoInstance() 479 485 self._lang = minfo.getLang() … … 491 497 #Fermi timezone awareness(end) # 492 498 ################################# 493 499 494 500 self.resetLinkedTo() 495 501 self.resetTimedLinkedEvents() 496 502 497 503 self.personalInfo = PersonalInfo() 498 504 499 505 if userData != None: 500 506 if userData.has_key( "name" ): … … 542 548 #Fermi timezone awareness(end) # 543 549 ################################ 544 550 545 551 ## def __getattribute__(self, attr): 546 552 ## if object.__getattribute__(self, '_p_getattr')(attr): 547 553 ## return Persistent.__getattribute__(self, attr) 548 ## 554 ## 549 555 ## #attributs that always get from this instance 550 556 ## if attr in ["_mergeTo", "getId", "id", "mergeTo", "_mergeFrom", "isMerged", "getMergeTo", "mergeFrom", \ 551 557 ## "unmergeFrom", "getMergeFromList"]: 552 558 ## return Persistent.__getattribute__(self,attr) 553 ## 554 ## #if _mergeTo, get attributs from the _mergeTo 559 ## 560 ## #if _mergeTo, get attributs from the _mergeTo 555 561 ## elif hasattr(self,"_mergeTo") and Persistent.__getattribute__(self,"_mergeTo") != None: 556 562 ## return Persistent.__getattribute__(self,"_mergeTo").__getattribute__(attr) 557 563 ## else: 558 564 ## return Persistent.__getattribute__(self,attr) 559 ## 565 ## 560 566 ## def __setattr__(self, attr, value): 561 567 ## if self._p_setattr(attr, value): 562 568 ## return Persistent.__setattr__(self, attr, value) 563 ## 569 ## 564 570 ## #attribute always set in this instance 565 571 ## if attr in ["_mergeTo", "id", "_mergeFrom"]: 566 572 ## Persistent.__setattr__(self, attr, value) 567 ## 573 ## 568 574 ## elif hasattr(self,"_mergeTo") and Persistent.__getattribute__(self,"_mergeTo") != None: 569 575 ## Persistent.__getattribute__(self,"_mergeTo").__setattr__(attr, value) 570 576 ## else: 571 577 ## Persistent.__setattr__(self, attr, value) 572 578 573 579 def mergeTo(self, av): 574 580 if av: … … 577 583 self._mergeTo.unmergeFrom(self) 578 584 self._mergeTo = av 579 585 580 586 def getMergeTo(self): 581 587 try: … … 584 590 self._mergeTo = None 585 591 return self._mergeTo 586 592 587 593 def isMerged(self): 588 594 if self.getMergeTo(): 589 595 return True 590 596 return False 591 597 592 598 def mergeFrom(self, av): 593 599 if not av in self.getMergeFromList(): 594 600 self._mergeFrom.append(av) 595 601 self._p_changed = 1 596 602 597 603 def unmergeFrom(self, av): 598 604 if av in self.getMergeFromList(): 599 605 self._mergeFrom.remove(av) 600 606 self._p_changed = 1 601 607 602 608 def getMergeFromList(self): 603 609 try: … … 606 612 self._mergeFrom = [] 607 613 return self._mergeFrom 608 614 609 615 def getKey( self ): 610 616 return self.key … … 613 619 self.linkedTo = copy(self.linkedToBase) 614 620 self._p_changed = 1 615 621 616 622 def getLinkedTo(self): 617 623 try: … … 620 626 self.resetLinkedTo() 621 627 return self.linkedTo 622 628 623 629 def getTimedLinkedEvents(self): 624 630 try: … … 627 633 self.resetTimedLinkedEvents() 628 634 return self.timedLinkedEvents 629 635 630 636 def resetTimedLinkedEvents(self): 631 637 632 638 ltt = self.getLinkedTo() 633 639 634 640 self.timedLinkedEvents = TimedLinkedEvents() 635 641 636 642 for registrantRole in ltt['registration']: 637 643 for registrant in ltt['registration'][registrantRole]: 638 644 self.timedLinkedEvents.addFuture(registrant.getConference(),registrantRole) 639 640 for confRole in ltt['conference']: 645 646 for confRole in ltt['conference']: 641 647 for conf in ltt['conference'][confRole]: 642 648 self.timedLinkedEvents.addFuture(conf,confRole) 643 649 644 650 645 651 def updateLinkedTo(self): … … 651 657 if role not in self.linkedTo[type].keys(): 652 658 self.linkedTo[type][role] = [] 653 659 654 660 def linkTo(self, obj, role): 655 661 self.updateLinkedTo() … … 661 667 self.linkedTo["category"][role].append(obj) 662 668 self._p_changed = 1 663 669 664 670 elif isinstance(obj, MaKaC.conference.Conference): 665 671 if not role in self.linkedTo["conference"].keys(): … … 668 674 if not obj in self.linkedTo["conference"][role]: 669 675 self.linkedTo["conference"][role].append(obj) 670 676 671 677 # add directly to the time-ordered list 672 678 self.getTimedLinkedEvents().addFuture(obj, role) 673 674 self._p_changed = 1 675 679 680 self._p_changed = 1 681 676 682 elif isinstance(obj, MaKaC.conference.Session): 677 683 if not role in self.linkedTo["session"].keys(): … … 681 687 self.linkedTo["session"][role].append(obj) 682 688 self._p_changed = 1 683 689 684 690 elif isinstance(obj, MaKaC.conference.Contribution): 685 691 if not role in self.linkedTo["contribution"].keys(): … … 689 695 self.linkedTo["contribution"][role].append(obj) 690 696 self._p_changed = 1 691 697 692 698 elif isinstance(obj, MaKaC.conference.Track): 693 699 if not role in self.linkedTo["track"].keys(): … … 697 703 self.linkedTo["track"][role].append(obj) 698 704 self._p_changed = 1 699 705 700 706 elif isinstance(obj, MaKaC.conference.Material): 701 707 if not role in self.linkedTo["material"].keys(): … … 705 711 self.linkedTo["material"][role].append(obj) 706 712 self._p_changed = 1 707 713 708 714 elif isinstance(obj, MaKaC.conference.Resource): 709 715 if not role in self.linkedTo["resource"].keys(): … … 713 719 self.linkedTo["resource"][role].append(obj) 714 720 self._p_changed = 1 715 721 716 722 elif isinstance(obj, MaKaC.review.Abstract): 717 723 if not role in self.linkedTo["abstract"].keys(): … … 721 727 self.linkedTo["abstract"][role].append(obj) 722 728 self._p_changed = 1 723 729 724 730 elif isinstance(obj, MaKaC.registration.Registrant): 725 731 if not role in self.linkedTo["registration"].keys(): … … 728 734 if not obj in self.linkedTo["registration"][role]: 729 735 self.linkedTo["registration"][role].append(obj) 730 736 731 737 # add directly to the time-ordered list 732 738 self.getTimedLinkedEvents().addFuture(obj.getConference(), role) 733 734 self._p_changed = 1 735 739 740 self._p_changed = 1 741 736 742 elif isinstance(obj, MaKaC.common.timerExec.Alarm): 737 743 if not role in self.linkedTo["alarm"].keys(): … … 741 747 self.linkedTo["alarm"][role].append(obj) 742 748 self._p_changed = 1 743 749 744 750 elif isinstance(obj, MaKaC.user.Group): 745 751 if not role in self.linkedTo["group"].keys(): … … 749 755 self.linkedTo["group"][role].append(obj) 750 756 self._p_changed = 1 751 757 752 758 elif isinstance(obj, MaKaC.evaluation.Submission): 753 759 if not role in self.linkedTo["evaluation"].keys(): … … 757 763 self.linkedTo["evaluation"][role].append(obj) 758 764 self._p_changed = 1 759 765 760 766 def getLinkTo( self, type, role ): 761 767 self.updateLinkedTo() … … 774 780 self.linkedTo["category"][role].remove(obj) 775 781 self._p_changed = 1 776 782 777 783 elif isinstance(obj, MaKaC.conference.Conference): 778 784 if not role in self.linkedTo["conference"].keys(): … … 781 787 if obj in self.linkedTo["conference"][role]: 782 788 self.linkedTo["conference"][role].remove(obj) 783 789 784 790 # remove from the time-ordered list 785 791 self.getTimedLinkedEvents().delete(obj, role) 786 787 self._p_changed = 1 788 792 793 self._p_changed = 1 794 789 795 elif isinstance(obj, MaKaC.conference.Session): 790 796 if not role in self.linkedTo["session"].keys(): … … 794 800 self.linkedTo["session"][role].remove(obj) 795 801 self._p_changed = 1 796 802 797 803 elif isinstance(obj, MaKaC.conference.Contribution): 798 804 if not role in self.linkedTo["contribution"].keys(): … … 802 808 self.linkedTo["contribution"][role].remove(obj) 803 809 self._p_changed = 1 804 810 805 811 elif isinstance(obj, MaKaC.conference.Track): 806 812 if not role in self.linkedTo["track"].keys(): … … 810 816 self.linkedTo["track"][role].remove(obj) 811 817 self._p_changed = 1 812 818 813 819 elif isinstance(obj, MaKaC.conference.Material): 814 820 if not role in self.linkedTo["material"].keys(): … … 818 824 self.linkedTo["material"][role].remove(obj) 819 825 self._p_changed = 1 820 826 821 827 elif isinstance(obj, MaKaC.review.Abstract): 822 828 if not role in self.linkedTo["abstract"].keys(): … … 826 832 self.linkedTo["abstract"][role].remove(obj) 827 833 self._p_changed = 1 828 834 829 835 elif isinstance(obj, MaKaC.registration.Registrant): 830 836 if not role in self.linkedTo["registration"].keys(): … … 833 839 if obj in self.linkedTo["registration"][role]: 834 840 self.linkedTo["registration"][role].remove(obj) 835 841 836 842 # remove from the time-ordered list 837 843 self.getTimedLinkedEvents().delete(obj.getConference(), role) 838 839 self._p_changed = 1 840 844 845 self._p_changed = 1 846 841 847 elif isinstance(obj, MaKaC.common.timerExec.Alarm): 842 848 if not role in self.linkedTo["alarm"].keys(): … … 846 852 self.linkedTo["alarm"][role].remove(obj) 847 853 self._p_changed = 1 848 854 849 855 elif isinstance(obj, MaKaC.user.Group): 850 856 if not role in self.linkedTo["group"].keys(): … … 854 860 self.linkedTo["group"][role].remove(obj) 855 861 self._p_changed = 1 856 862 857 863 elif isinstance(obj, MaKaC.evaluation.Submission): 858 864 if not role in self.linkedTo["evaluation"].keys(): … … 869 875 self.status = "activated" 870 876 return self.status 871 877 872 878 def setStatus( self, status ): 873 879 statIdx = indexes.IndexesHolder().getById("status") … … 876 882 self._p_changed = 1 877 883 statIdx.indexUser( self ) 878 884 879 885 def activateAccount( self ): 880 886 self.setStatus("activated") … … 882 888 def disabledAccount( self ): 883 889 self.setStatus("disabled") 884 890 885 891 def isActivated( self ): 886 892 return self.status == "activated" 887 893 888 894 def isDisabled( self ): 889 895 return self.status == "disabled" 890 896 891 897 def isNotConfirmed( self ): 892 898 return self.status == "Not confirmed" … … 914 920 915 921 def getSurName(self): 916 return self.surName 922 return self.surName 917 923 918 924 @Retrieves('MaKaC.user.Avatar', 'familyName') 919 925 def getFamilyName(self): 920 return self.surName 926 return self.surName 921 927 922 928 def getFullName(self): … … 925 931 surName = "%s, "%self.getSurName().upper() 926 932 return "%s%s"%(surName, self.getName()) 927 933 928 934 @Retrieves('MaKaC.user.Avatar', 'name') 929 935 def getStraightFullName(self): … … 997 1003 #Fermi timezone awareness(end) # 998 1004 ################################# 999 1005 1000 1006 def addAddress(self, newAddress): 1001 1007 self.address.append(newAddress) … … 1015 1021 def setEmail(self, email, item=0 ): 1016 1022 self.email = email.strip().lower() 1017 1023 1018 1024 def getEmails( self ): 1019 1025 return [self.email] + self.getSecondaryEmails() 1020 1026 1021 1027 @Retrieves('MaKaC.user.Avatar', 'email') 1022 1028 def getEmail( self ): 1023 1029 return self.email 1024 1030 1025 1031 def getSecondaryEmails(self): 1026 1032 try: … … 1029 1035 self.secondaryEmails = [] 1030 1036 return self.secondaryEmails 1031 1037 1032 1038 def addSecondaryEmail(self, email): 1033 1039 self.getSecondaryEmails() #create attribute if not exist 1034 1040 1035 1041 if not email in self.secondaryEmails: 1036 1042 self.secondaryEmails.append(email) 1037 1043 self._p_changed = 1 1038 1044 1039 1045 def removeSecondaryEmail(self, email): 1040 1046 self.getSecondaryEmails() #create attribute if not exist 1041 1047 1042 1048 if email in self.secondaryEmails: 1043 1049 self.secondaryEmails.remove(email) 1044 1050 self._p_changed = 1 1045 1051 1046 1052 def setSecondaryEmails(self, emailList): 1047 1053 self.secondaryEmails = emailList … … 1050 1056 l=[self.email] + self.getSecondaryEmails() 1051 1057 return email.lower().strip() in l 1052 1058 1053 1059 1054 1060 def addTelephone(self, newTel ): … … 1066 1072 def getTelephones(self): 1067 1073 return self.telephone 1068 1074 1069 1075 def getSecondaryTelephones(self): 1070 1076 return self.telephone[1:] … … 1084 1090 def getFaxes(self): 1085 1091 return self.fax 1086 1092 1087 1093 def addIdentity(self, newId): 1088 1094 if newId != None and (newId not in self.identities): 1089 1095 self.identities.append( newId ) 1090 1096 self._p_changed = 1 1091 1097 1092 1098 def removeIdentity(self, Id): 1093 1099 if Id in self.identities: … … 1108 1114 self.getRegistrants()[ n.getConference().getId() ] = n 1109 1115 self._p_changed = 1 1110 1116 1111 1117 def removeRegistrant(self, r): 1112 1118 if self.getRegistrants().has_key(r.getConference().getId()): 1113 1119 1114 1120 # unlink registrant from user 1115 1121 self.unlinkTo(r,'registrant') 1116 1122 1117 1123 del self.getRegistrants()[r.getConference().getId()] 1118 1124 self._p_changed = 1 … … 1139 1145 return True 1140 1146 return False 1141 1147 1142 1148 def hasSubmittedEvaluation(self, evaluation): 1143 1149 for submission in evaluation.getSubmissions(): … … 1145 1151 return True 1146 1152 return False 1147 1153 1148 1154 def containsUser( self, avatar ): 1149 1155 return avatar == self … … 1155 1161 def canUserModify( self, user ): 1156 1162 return user == self or (user in AdminList.getInstance().getList()) 1157 1163 1158 1164 def getLocator( self ): 1159 1165 d = Locator() … … 1163 1169 def delete(self): 1164 1170 TrashCanManager().add(self) 1165 1171 1166 1172 def recover(self): 1167 1173 TrashCanManager().remove(self) 1168 1174 1169 1175 # Room booking related 1170 1176 1171 1177 def isMemberOfSimbaList( self, simbaListName ): 1172 1178 try: … … 1201 1207 return True 1202 1208 return False 1203 1209 1204 1210 def getRooms( self ): 1205 1211 """ 1206 Returns list of rooms (RoomBase derived objects) this 1212 Returns list of rooms (RoomBase derived objects) this 1207 1213 user is responsible for. 1208 1214 """ 1209 1215 from MaKaC.rb_location import CrossLocationQueries 1210 1216 from MaKaC.rb_room import RoomBase 1211 1217 1212 1218 myRooms = CrossLocationQueries.getRooms( reallyAllFast = True ) 1213 1219 myRooms = [ room for room in myRooms if room.isOwnedBy( self ) ] … … 1216 1222 def getReservations(self): 1217 1223 """ 1218 Returns list of ALL reservations (ReservationBase 1224 Returns list of ALL reservations (ReservationBase 1219 1225 derived objects) this user has ever made. 1220 1226 """ … … 1222 1228 # resvs = [guid.getReservation() for guid in self.resvGuids] 1223 1229 # return resvs 1224 1230 1225 1231 from MaKaC.rb_location import CrossLocationQueries 1226 1232 from MaKaC.rb_reservation import ReservationBase 1227 1233 1228 1234 resvEx = ReservationBase() 1229 1235 resvEx.createdBy = str( self.id ) 1230 resvEx.isCancelled = None 1236 resvEx.isCancelled = None 1231 1237 resvEx.isRejected = None 1232 1238 resvEx.isArchival = None 1233 1239 1234 1240 myResvs = CrossLocationQueries.getReservations( resvExample = resvEx ) 1235 1241 return myResvs … … 1237 1243 def getReservationsOfMyRooms( self ): 1238 1244 """ 1239 Returns list of ALL reservations (ReservationBase 1245 Returns list of ALL reservations (ReservationBase 1240 1246 derived objects) this user has ever made. 1241 1247 """ … … 1243 1249 # resvs = [guid.getReservation() for guid in self.resvGuids] 1244 1250 # return resvs 1245 1251 1246 1252 from MaKaC.rb_location import CrossLocationQueries 1247 1253 from MaKaC.rb_reservation import ReservationBase 1248 1254 1249 1255 myRooms = self.getRooms() # Just to speed up 1250 1256 1251 1257 resvEx = ReservationBase() 1252 1258 resvEx.isCancelled = None 1253 1259 resvEx.isRejected = None 1254 1260 resvEx.isArchival = None 1255 1261 1256 1262 myResvs = CrossLocationQueries.getReservations( resvExample = resvEx, rooms = myRooms ) 1257 1263 return myResvs 1258 1259 1264 1265 1260 1266 def getPersonalInfo(self): 1261 1267 try: … … 1264 1270 self.personalInfo = PersonalInfo() 1265 1271 return self.personalInfo 1266 1272 1267 1273 def getLang(self): 1268 1274 try: … … 1272 1278 self._lang = minfo.getLang() 1273 1279 return self._lang 1274 1280 1275 1281 def setLang(self, lang): 1276 self._lang =lang 1282 self._lang =lang 1283 1277 1284 1278 1285 class AvatarHolder( ObjectHolder ): 1279 """Specialised ObjectHolder dealing with user (avatar) objects. Objects of 1280 this class represent an access point to Avatars of the application and 1281 provides different methods for accessing and retrieving them in several 1286 """Specialised ObjectHolder dealing with user (avatar) objects. Objects of 1287 this class represent an access point to Avatars of the application and 1288 provides different methods for accessing and retrieving them in several 1282 1289 ways. 1283 1290 """ … … 1292 1299 self.invalidateRoomManagerIdList() 1293 1300 return root["roomManagerIdList"] 1294 1301 1295 1302 def invalidateRoomManagerIdList( self ): 1296 1303 from MaKaC.rb_location import CrossLocationQueries 1297 1304 root = DBMgr.getInstance().getDBConnection().root() 1298 1305 allRooms = CrossLocationQueries.getRooms() 1299 1306 1300 1307 idList = [ room.getResponsible().id for room in allRooms ] 1301 1308 1302 1309 for room in allRooms: 1303 1310 if room.customAtts.get( 'Simba List' ): … … 1308 1315 avatars = groups[0].getMemberList() 1309 1316 idList += [ avatar.id for avatar in avatars ] 1310 1317 1311 1318 root["roomManagerIdList"] = idList 1312 1319 … … 1350 1357 auth = NiceAuthentication.NiceAuthenticator() 1351 1358 1352 1359 1353 1360 for email in dict.keys(): 1354 # TODO and TOSTUDY: result.keys should be replace it with 1361 # TODO and TOSTUDY: result.keys should be replace it with 1355 1362 # l=[]; for av in result.values(): l.append(av.getAllEmails()) 1356 1363 if not email in result.keys(): … … 1370 1377 result[av.getEmail()] = av 1371 1378 return result.values() 1372 1379 1373 1380 def _userMatchCriteria(self, av, criteria, exact): 1374 1381 if criteria.has_key("organisation"): … … 1384 1391 if not lMatch: 1385 1392 return False 1386 1393 1387 1394 if criteria.has_key("surName"): 1388 1395 if criteria["surName"]: … … 1393 1400 if not criteria["surName"].lower() in av.getSurName().lower(): 1394 1401 return False 1395 1402 1396 1403 if criteria.has_key("name"): 1397 1404 if criteria["name"]: … … 1402 1409 if not criteria["name"].lower() in av.getName().lower(): 1403 1410 return False 1404 1411 1405 1412 if criteria.has_key("email"): 1406 1413 if criteria["email"]: … … 1416 1423 return False 1417 1424 return True 1418 1419 1420 1421 1425 1426 1427 1428 1422 1429 def getById(self, id): 1423 1430 try: … … 1438 1445 dict["authenticator"].add(identity) 1439 1446 av.activateAccount() 1440 1447 1441 1448 #try: 1442 1449 self.add(av) 1443 1450 1444 1451 #except: 1445 1452 # av = self.match({'email': av.getEmail()}, exact=1, forceWithoutExtAuth=True)[0] 1446 1453 return av 1447 1454 1448 1455 1449 1456 def add(self,av): … … 1460 1467 indexes.IndexesHolder().getById(i).indexUser(av) 1461 1468 return id 1462 1463 1469 1470 1464 1471 def mergeAvatar(self, prin, merged): 1465 1472 #replace merged by prin in all object where merged is … … 1480 1487 cat.revokeAccess(merged) 1481 1488 cat.grantAccess(prin) 1482 1489 1483 1490 elif objType == "conference": 1484 1491 for role in links[objType].keys(): … … 1502 1509 conf.removeAuthorizedSubmitter(merged) 1503 1510 conf.addAuthorizedSubmitter(prin) 1504 1511 1505 1512 if objType == "session": 1506 1513 for role in links[objType].keys(): … … 1517 1524 ses.removeCoordinator(merged) 1518 1525 ses.addCoordinator(prin) 1519 1526 1520 1527 if objType == "contribution": 1521 1528 for role in links[objType].keys(): … … 1532 1539 contrib.revokeSubmission(merged) 1533 1540 contrib.grantSubmission(prin) 1534 1541 1535 1542 if objType == "track": 1536 1543 for role in links[objType].keys(): … … 1539 1546 track.removeCoordinator(merged) 1540 1547 track.addCoordinator(prin) 1541 1548 1542 1549 if objType == "material": 1543 1550 for role in links[objType].keys(): … … 1546 1553 mat.revokeAccess(merged) 1547 1554 mat.grantAccess(prin) 1548 1555 1549 1556 if objType == "file": 1550 1557 for role in links[objType].keys(): … … 1553 1560 mat.revokeAccess(merged) 1554 1561 mat.grantAccess(prin) 1555 1562 1556 1563 if objType == "abstract": 1557 1564 for role in links[objType].keys(): … … 1559 1566 for abstract in links[objType][role]: 1560 1567 abstract.setSubmitter(prin) 1561 1568 1562 1569 if objType == "registration": 1563 1570 for role in links[objType].keys(): … … 1565 1572 for reg in links[objType][role]: 1566 1573 reg.setAvatar(prin) 1567 1574 1568 1575 if objType == "alarm": 1569 1576 for role in links[objType].keys(): … … 1572 1579 alarm.removeToUser(merged) 1573 1580 alarm.addToUser(prin) 1574 1581 1575 1582 if objType == "group": 1576 1583 for role in links[objType].keys(): … … 1579 1586 group.removeMember(merged) 1580 1587 group.addMember(prin) 1581 1588 1582 1589 if objType == "evaluation": 1583 1590 for role in links[objType].keys(): … … 1590 1597 #prin ditn't answered to the same evaluation as merger's. 1591 1598 submission.setSubmitter(prin) 1592 1599 1593 1600 # remove merged from holder 1594 1601 self.remove(merged) … … 1598 1605 name = idxs.getById( 'name' ) 1599 1606 surName = idxs.getById( 'surName' ) 1600 1607 1601 1608 org.unindexUser(merged) 1602 1609 email.unindexUser(merged) 1603 1610 name.unindexUser(merged) 1604 1611 surName.unindexUser(merged) 1605 1612 1606 1613 # add merged email and logins to prin and merge users 1607 1614 for mail in merged.getEmails(): … … 1610 1617 id.setUser(prin) 1611 1618 prin.addIdentity(id) 1612 1619 1613 1620 merged.mergeTo(prin) 1614 1621 1615 1622 # reindex prin email 1616 1623 email.unindexUser(prin) 1617 1624 email.indexUser(prin) 1618 1625 1619 1626 def unmergeAvatar(self, prin, merged): 1620 1627 if not merged in prin.getMergeFromList(): 1621 1628 return False 1622 1629 merged.mergeTo(None) 1623 1630 1624 1631 idxs = indexes.IndexesHolder() 1625 1632 org = idxs.getById( 'organisation' ) … … 1627 1634 name = idxs.getById( 'name' ) 1628 1635 surName = idxs.getById( 'surName' ) 1629 1630 1636 1637 1631 1638 email.unindexUser(prin) 1632 1639 for mail in merged.getEmails(): 1633 1640 prin.removeSecondaryEmail(mail) 1634 1641 1635 1642 for id in merged.getIdentityList(): 1636 1643 prin.removeIdentity(id) 1637 1644 id.setUser(merged) 1638 1645 1639 1646 self.add(merged) 1640 1647 1641 1648 org.indexUser(merged) 1642 1649 email.indexUser(merged) 1643 1650 name.indexUser(merged) 1644 1651 surName.indexUser(merged) 1645 1652 1646 1653 email.indexUser(prin) 1647 1654 return True 1648 1655 1649 1656 1650 1657 1651 1658 # ToDo: This class should ideally derive from TreeHolder as it is thought to 1652 1659 # be a index over the "Principal" objects i.e. it will be a top indexing of 1653 # the contents of AvatarHolder and GroupHolder. This will allow to 1660 # the contents of AvatarHolder and GroupHolder. This will allow to 1654 1661 # transparently access to Principal objects from its id. To transparently 1655 # index all the objects AvatarHolder and GroupHolder must override the 1662 # index all the objects AvatarHolder and GroupHolder must override the 1656 1663 # "add" method and, apart from their normal operation, include an adding call 1657 1664 # for the PrincipalHolder. 1658 1665 # The problem is that I have experienced some troubles (it seems not to perform 1659 1666 # the adding of objects) while adding an object both to the AvatarHolder and 1660 # to this one; so, for the time being, I will implement it in a "dirty" and 1667 # to this one; so, for the time being, I will implement it in a "dirty" and 1661 1668 # non-optimal way to be able to continue working, but the trouble must be 1662 1669 # investigated and a better solution found. 1663 # I'll keep the ObjectHolder interface so it will be easier afterwards to 1670 # I'll keep the ObjectHolder interface so it will be easier afterwards to 1664 1671 # implement a more optimised solution (just this object needs to be modified) 1665 1672 class PrincipalHolder: … … 1667 1674 self.__gh = GroupHolder() 1668 1675 self.__ah = AvatarHolder() 1669 1676 1670 1677 def getById( self, id ): 1671 1678 try: … … 1680 1687 1681 1688 class LoginInfo: 1682 1689 1683 1690 def __init__(self, login, password): 1684 1691 self.setLogin( login ) … … 1701 1708 1702 1709 class TimedLinkedEvents(Persistent): 1703 1710 1704 1711 def __init__(self): 1705 1712 self._past = [] 1706 1713 self._present = [] 1707 1714 self._future = [] 1708 1715 1709 1716 def addPast(self, event, relation): 1710 1717 self._past.append((event, relation)) 1711 1718 self._p_changed = 1 1712 1719 1713 1720 def addPresent(self, event, relation): 1714 1721 self._present.append((event, relation)) 1715 1722 self._p_changed = 1 1716 1723 1717 1724 def addFuture(self, event, relation): 1718 1725 self._future.append((event, relation)) 1719 1726 self._p_changed = 1 1720 1727 1721 1728 def getPast(self): 1722 1729 return self._past 1723 1730 1724 1731 def getPresent(self): 1725 1732 return self._present 1726 1733 1727 1734 def getFuture(self): 1728 1735 return self._future 1729 1736 1730 1737 def sync(self): 1731 1738 1732 1739 now = datetime.now() 1733 1740 1734 1741 # Let's check past events 1735 1742 1736 1743 for elem in self._past: 1737 1744 if elem[0].getEndDate() > now: … … 1739 1746 self._past.remove(elem) 1740 1747 self._p_changed = 1 1741 1748 1742 1749 # pass "future" events to present and past 1743 1750 for elem in self._future[:]: 1744 # play consistent, iterate over a copy 1751 # play consistent, iterate over a copy 1745 1752 if elem[0].getStartDate() < now: 1746 1753 self.addPresent(elem[0],elem[1]) 1747 1754 self._future.remove(elem) 1748 1755 self._p_changed = 1 1749 1756 1750 1757 # pass present events to past or future 1751 1758 for elem in self._present[:]: … … 1759 1766 self._present.remove(elem) 1760 1767 self._p_changed = 1 1761 1762 1763 1768 1769 1770 1764 1771 def deleteFromList(self, list, elem, role): 1765 1772 1766 1773 for tuple in list[:]: 1767 1774 if (tuple == (elem, role)): … … 1770 1777 return True 1771 1778 return False 1772 1779 1773 1780 def delete(self, elem, role): 1774 1781 1775 1782 if (self.deleteFromList(self._past, elem, role) or 1776 1783 self.deleteFromList(self._present, elem, role) or … … 1780 1787 1781 1788 return False 1782 1789 1783 1790 class PersonalInfo(Persistent): 1784 1791 1785 1792 def __init__(self): 1786 1793 self._basket = PersonalBasket() 1787 1794 self._tabAdvancedMode = False # Basic set of tabs 1788 1795 self._p_changed = 1 1789 1796 1790 1797 @Retrieves('MaKaC.user.PersonalInfo', 'tabAdvancedMode') 1791 1798 def getTabAdvancedMode( self ): … … 1797 1804 self.setTabAdvancedMode(False) # (default) 1798 1805 return self._tabAdvancedMode 1799 1806 1800 1807 @Updates('MaKaC.user.PersonalInfo', 'tabAdvancedMode') 1801 def setTabAdvancedMode( self, mode ): 1808 def setTabAdvancedMode( self, mode ): 1802 1809 self._tabAdvancedMode = mode 1803 1810 self._p_changed = 1 1804 1811 1805 1812 1806 1813 def getBasket(self): 1807 1814 return self._basket 1808 1815 1809 1816 class PersonalBasket(Persistent): 1810 1817 … … 1818 1825 self._userGroups = {} 1819 1826 self._p_changed = 1 1820 1827 1821 1828 def __findAdequateDict(self, element): 1822 1829 1823 1830 if (type(element) == MaKaC.conference.Conference): 1824 1831 return self._events … … 1833 1840 else: 1834 1841 raise Exception( _("Unknown Element Type")) 1835 1836 def addElement(self, element): 1842 1843 def addElement(self, element): 1837 1844 dict = self.__findAdequateDict(element) 1838 1845 if (not dict.has_key(element.getId())): … … 1841 1848 return True 1842 1849 return False 1843 1850 1844 1851 def deleteElement(self, element): 1845 1852 res = self.__findAdequateDict(element).pop(element.getId(),None) 1846 1853 1847 1854 if res == None: 1848 1855 return False 1849 1856 1850 1857 self._p_changed = 1 1851 1858 return True 1852 1853 def hasElement(self, element): 1859 1860 def hasElement(self, element): 1854 1861 return self.__findAdequateDict(element).has_key(element.getId()) 1855 1862 1856 1863 def hasUserId(self, id): 1857 1864 return self._users.has_key(id) 1858 1865 1859 1866 def getUsers(self): 1860 1867 return self._users 1861 1862 1863 1868 1869 1870 -
indico/MaKaC/webinterface/tpls/AdminPluginsOptionList.tpl
rfd0c10 r56571d6 1 <% from MaKaC. common.PickleJar import DictPickler%>1 <% from MaKaC.fossils.user import IAvatarDetailedFossil %> 2 2 3 3 <% if ObjectType == "PluginType" :%> … … 7 7 <form method="post" action="<%= urlHandlers.UHAdminPluginsSaveOptions.getURL(Object, subtab = Index) %>" > 8 8 <% end %> 9 9 10 10 <table> 11 11 <% for option in Object.getOptionList(sorted = True, includeOnlyEditable = True, includeOnlyVisible = True): %> … … 21 21 <% name = Object.getOwner().getName() + '.' + Object.getName() + "." + option.getName() %> 22 22 <% end %> 23 23 24 24 <% if option.getType() == "users": %> 25 25 <div id="userList<%=name%>"> 26 26 </div> 27 27 28 28 <script type="text/javascript"> 29 29 var newPersonsHandler = function(userList, setResult) { … … 61 61 ); 62 62 } 63 63 64 64 var uf = new UserListField('PluginPeopleListDiv', 'PluginPeopleList', 65 <%= jsonEncode( DictPickler.pickle(option.getValue())) %>,65 <%= jsonEncode(fossilize(option.getValue(), IAvatarDetailedFossil)) %>, 66 66 null, 67 67 <%=jsonEncode(Favorites)%>, … … 130 130 <% value = str(option.getValue()) %> 131 131 <% end %> 132 132 133 133 <% if option.getType() == bool: %> 134 134 <% checked = '' %> … … 141 141 <input name="<%= name %>" type="text" size="50" value="<%= value %>"> 142 142 <% end %> 143 143 144 144 <% if option.hasActions(): %> 145 145 <% for action in option.getActions(): %> … … 169 169 </tr> 170 170 <% end %> 171 171 172 172 <% for option in Object.getOptionList(sorted = True, includeOnlyNonEditable = True, includeOnlyVisible = True): %> 173 173 <tr> … … 185 185 </tr> 186 186 <% end %> 187 187 188 188 <% if Object.hasAnyActions(includeOnlyNonAssociated = True): %> 189 189 <tr> -
indico/MaKaC/webinterface/tpls/UserBaskets.tpl
r342258 r56571d6 7 7 </div> 8 8 9 <script type="text/javascript"> 9 <script type="text/javascript"> 10 10 11 var userList = <%= offlineRequest(self._rh, 'user.favorites.listUsers', { }) %>;11 var userList = <%= offlineRequest(self._rh, 'user.favorites.listUsers', {"detailLevel": "medium"}) %>; 12 12 var removeUser = function(user, setResult){ 13 13 14 14 jsonRpc(Indico.Urls.JsonRpcService, "user.favorites.removeUser", 15 15 {value: [{'id': user.get('id')}]}, function(result, error){ … … 45 45 true, false, false, 46 46 addUsers, userListNothing, removeUser) 47 47 48 48 $E('basketContainer').set(uf.draw()); 49 49 -
indico/htdocs/js/indico/Management/Users.js
r57b5d5 r56571d6 506 506 each(newUserIds, function(newUserId) { 507 507 var newUser = self.allOptions.get(newUserId).clone(); 508 if (self.userList.get("existingAv"+newUserId)) { 509 self.userList.set("existingAv"+newUserId, null); 510 } 508 511 509 self.newProcess([newUser], function(result) { 512 510 if (result) { … … 570 568 571 569 each(initialUsers, function(user){ 572 if (any(user. isAvatar, false)) {570 if (any(user._type, null) === 'Avatar') { 573 571 self.userList.set('existingAv' + user.id, $O(user)); 574 572 } else { -
tests/MaKaC_tests/common_tests/testFossilize.py
r626e2c r56571d6 6 6 pass 7 7 8 class ISimpleFossil1 (IFossil):8 class ISimpleFossil1Fossil(IFossil): 9 9 def getB(self): 10 10 pass … … 14 14 getC.convert = lambda x: x.upper() 15 15 16 class ISimpleFossil2 (IFossil):16 class ISimpleFossil2Fossil(IFossil): 17 17 def getA(self): 18 18 pass … … 22 22 getC.convert = lambda x: x.title() 23 23 24 class IComplexFossil1 (IFossil):24 class IComplexFossil1Fossil(IFossil): 25 25 def getSimpleInstance(self): 26 26 pass 27 getSimpleInstance.result = ISimpleFossil2 27 getSimpleInstance.result = ISimpleFossil2Fossil 28 28 29 class IComplexFossil2 (IFossil):29 class IComplexFossil2Fossil(IFossil): 30 30 def getSimpleInstance(self): 31 31 pass 32 getSimpleInstance.result = ISimpleFossil2 33 getSimpleInstance.convert = lambda x: list(x.values())32 getSimpleInstance.result = ISimpleFossil2Fossil 33 getSimpleInstance.convert = lambda x: sorted(x.values()) 34 34 getSimpleInstance.name = 'mySimpleInstance' 35 35 36 36 class IDynamicFossil(IFossil): 37 37 def getA(self): … … 44 44 class SimpleClass(Fossilizable): 45 45 46 fossilizes(ISimpleFossil1 , ISimpleFossil2)47 46 fossilizes(ISimpleFossil1Fossil, ISimpleFossil2Fossil) 47 48 48 def __init__(self, a, b, c): 49 49 self.a = a … … 65 65 class ComplexClass(Fossilizable): 66 66 67 fossilizes(IComplexFossil1 , IComplexFossil2)67 fossilizes(IComplexFossil1Fossil, IComplexFossil2Fossil) 68 68 69 69 def getSimpleInstance(self): 70 70 return SimpleClass(1,'foo','bar') 71 72 71 72 73 73 class ConversionClass(object): 74 74 @classmethod 75 75 def multiply(cls, number, factor): 76 76 return number * factor 77 77 78 78 def sum(number, numberToBeAdded): 79 79 return number + numberToBeAdded 80 80 81 81 82 class I FossilWithConversion2(IFossil):82 class IWithConversion2Fossil(IFossil): 83 83 def getA(self): 84 84 pass 85 85 getA.convert = sum 86 86 87 class I FossilWithConversion(IFossil):87 class IWithConversionFossil(IFossil): 88 88 def getA(self): 89 89 pass … … 91 91 def getList(self): 92 92 pass 93 getList.result = I FossilWithConversion293 getList.result = IWithConversion2Fossil 94 94 95 95 class AnotherClass(Fossilizable): 96 fossilizes(I FossilWithConversion)96 fossilizes(IWithConversionFossil) 97 97 def __init__(self, a , list = []): 98 98 self.a = a … … 104 104 105 105 class AnotherChildrenClass(Fossilizable): 106 fossilizes(I FossilWithConversion2)106 fossilizes(IWithConversion2Fossil) 107 107 def __init__(self, a): 108 108 self.a = a … … 136 136 137 137 def testFossilizingSimpleClass(self): 138 self.assertEquals(self.s.fossilize(ISimpleFossil1 ),139 { "b": "a", "c":"FOO"})140 self.assertEquals(self.s.fossilize(ISimpleFossil2 ),141 { "a":1, "c":"Foo"})138 self.assertEquals(self.s.fossilize(ISimpleFossil1Fossil), 139 {'_type':'SimpleClass', '_fossil':'simpleFossil1', "b": "a", "c":"FOO"}) 140 self.assertEquals(self.s.fossilize(ISimpleFossil2Fossil), 141 {'_type':'SimpleClass', '_fossil':'simpleFossil2', "a":1, "c":"Foo"}) 142 142 143 143 def testFossilizingComplexClass(self): 144 self.assertEquals(self.c.fossilize(IComplexFossil1 ),145 {' simpleInstance': {'a': 1, 'c':'Bar'}})144 self.assertEquals(self.c.fossilize(IComplexFossil1Fossil), 145 {'_type':'ComplexClass', '_fossil':'complexFossil1', 'simpleInstance': {'_type':'SimpleClass', '_fossil':'simpleFossil2', 'a': 1, 'c':'Bar'}}) 146 146 147 147 def testFossilizingComplexClassWithConversion(self): 148 self.assertEquals(self.c.fossilize(IComplexFossil2 ),149 {' mySimpleInstance': [1,'Bar']})148 self.assertEquals(self.c.fossilize(IComplexFossil2Fossil), 149 {'_type':'ComplexClass', '_fossil':'complexFossil2', 'mySimpleInstance': [1, 'Bar', 'SimpleClass', 'simpleFossil2']}) 150 150 151 151 def testFossilizingWithInheritance(self): 152 152 d = DerivedClass(2,'b','bar') 153 self.assertEquals(d.fossilize(ISimpleFossil1 ),154 {" b": "b", "c":"BAR"})155 153 self.assertEquals(d.fossilize(ISimpleFossil1Fossil), 154 {"_type": "DerivedClass", "_fossil": "simpleFossil1", "b": "b", "c":"BAR"}) 155 156 156 def testFossilizeList(self): 157 157 d1 = SimpleClass(1, 'a', 'aaa') 158 158 d2 = SimpleClass(2, 'b', 'bbb') 159 159 l = [d1, d2] 160 self.assertEquals(fossilize(l, ISimpleFossil1 ),161 [{' b': 'a', 'c': 'AAA'}, {'b': 'b', 'c': 'BBB'}] )162 160 self.assertEquals(fossilize(l, ISimpleFossil1Fossil), 161 [{'_type':'SimpleClass', '_fossil':'simpleFossil1', 'b': 'a', 'c': 'AAA'}, {'_type':'SimpleClass', '_fossil':'simpleFossil1', 'b': 'b', 'c': 'BBB'}] ) 162 163 163 def testFossilizingWithDynamicFossil(self): 164 164 d = DerivedClass(2, 'bababa', 'bar') 165 self.assertEquals(d.fossilize(ISimpleFossil1 ),166 { "b": "bababa", "c":"BAR"})165 self.assertEquals(d.fossilize(ISimpleFossil1Fossil), 166 {'_type':'DerivedClass', '_fossil':'simpleFossil1', "b": "bababa", "c":"BAR"}) 167 167 self.assertEquals(d.fossilize(IDynamicFossil), 168 { "a": 2, "b":"BABABA"})169 168 {'_type':'DerivedClass', '_fossil':'dynamic', "a": 2, "b":"BABABA"}) 169 170 170 def testFossilizingWithConversion(self): 171 171 a1 = AnotherChildrenClass(10) 172 172 a2 = AnotherChildrenClass(20) 173 173 aFather = AnotherClass(1000, [a1, a2]) 174 self.assertEquals(aFather.fossilize(I FossilWithConversion, factor = 10, numberToBeAdded = 1),175 {' a': 10000, 'list': [{'a': 11}, {'a': 21}]})174 self.assertEquals(aFather.fossilize(IWithConversionFossil, factor = 10, numberToBeAdded = 1), 175 {'_type':'AnotherClass', '_fossil':'withConversion', 'a': 10000, 'list': [{'_type': 'AnotherChildrenClass', '_fossil': 'withConversion2', 'a': 11}, {'_type': 'AnotherChildrenClass', '_fossil': 'withConversion2', 'a': 21}]}) 176 176 177 177
Note: See TracChangeset
for help on using the changeset viewer.
