VC: Fix error on clone page for legacy-ID events
[cds-indico.git] / indico / MaKaC / roomMapping.py
blob01b309f2c1dc5363d34c0eba6e9e22af37adffb9
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 import re
19 from persistent import Persistent
20 from sqlalchemy.orm import load_only, noload
22 from indico.core.config import Config
23 from indico.util.caching import memoize_request
24 from MaKaC.common import filters
25 from MaKaC.common.ObjectHolders import ObjectHolder
26 from MaKaC.common.Locators import Locator
29 class RoomMapperHolder(ObjectHolder):
30 """
31 """
32 idxName = "roomsMapping"
33 counterName = "ROOMS_MAPPING"
35 def match(self,criteria, exact=False):
36 crit={}
37 for f,v in criteria.items():
38 crit[f]=[v]
39 if crit.has_key("roommappername"):
40 crit["name"] = crit["roommappername"]
41 f=RoomMapperFilter(_RoomMapperFilterCriteria(crit),None)
42 return f.apply(self.getList(), exact)
45 class RoomMapper(Persistent):
47 def __init__(self, data=None):
48 self._id=""
49 self_name=""
50 self._description=""
51 self._baseMapURL=""
52 self._regexps=[]
53 self._placeName=""
54 if data is not None:
55 self.setValues(data)
57 def setValues(self, d):
58 self.setName(d.get("name","-- no name --"))
59 self.setDescription(d.get("description",""))
60 self.setBaseMapURL(d.get("url",""))
61 self.setPlaceName(d.get("placeName",""))
62 self.clearRegularExpressions()
63 for i in d.get("regexps","").split("\r\n"):
64 if i.strip() != "":
65 self.addRegularExpression(i)
67 def getValues(self):
68 d={}
69 d["name"]=self.getName()
70 d["description"]=self.getDescription()
71 d["mapURL"]=self.getMapURL()
72 d["placeName"]=self.getPlaceName()
73 return d
75 def setId(self,id):
76 self._id=id
78 def getId(self):
79 return self._id
81 def getName(self):
82 return self._name
84 def setName(self, name):
85 self._name=name
87 def getDescription(self):
88 return self._description
90 def setDescription(self, desc):
91 self._description=desc
93 def getBaseMapURL(self):
94 return self._baseMapURL
96 def setBaseMapURL(self, url):
97 self._baseMapURL=url
99 def getPlaceName(self):
100 return self._placeName
102 def setPlaceName(self,pname):
103 self._placeName=pname
105 def getRegularExpressions(self):
106 return self._regexps
108 def addRegularExpression(self,re):
109 self._regexps.append(re)
111 def clearRegularExpressions(self):
112 self._regexps=[]
114 def applyRegularExpressions(self, roomName):
115 """Returns the groupdict of attributes we have to pass to the Map URL or None if no matching"""
116 for regexp in self.getRegularExpressions():
117 p = re.compile(regexp)
118 m = p.match(roomName)
119 if m:
120 return m.groupdict()
121 return None
123 @memoize_request
124 def getMapURL(self, roomName):
125 groupdict = self.applyRegularExpressions(roomName)
126 if groupdict:
127 return self.getBaseMapURL().format(**groupdict)
128 if not roomName:
129 return ''
130 if Config.getInstance().getIsRoomBookingActive():
131 from indico.modules.rb.models.rooms import Room
132 room = (Room.query
133 .options(load_only('building', 'floor', 'number'), noload('owner'))
134 .filter_by(name=roomName)
135 .first())
136 if room:
137 if all(field in self.getBaseMapURL() for field in ['{building}','{floor}','{roomNr}']):
138 return self.getBaseMapURL().format(**{'building': str(room.building),
139 'floor': room.floor,
140 'roomNr': room.number})
141 return ""
142 getCompleteMapURL = getMapURL
144 def getLocator( self ):
145 d = Locator()
146 d["roomMapperId"] = self.getId()
147 return d
150 class _RoomMapperFFBasicName(filters.FilterField):
152 Use when the filter is comparing basic strings
155 def _getBasicNameFunc(self, room_mapper):
157 returns the method that will provide the string value to use in the comparison
159 pass
161 def satisfies(self, room_mapper, exact=False):
162 for value in self._values:
163 if value is not None and value.strip() != "":
164 if value.strip() == "*":
165 return True
166 if exact:
167 if self._getBasicNameFunc(room_mapper)().lower().strip() == value.lower().strip():
168 return True
169 else:
170 if str(self._getBasicNameFunc(room_mapper)()).lower().find((str(value).strip().lower())) != -1:
171 return True
172 return False
175 class _RoomMapperFFName(_RoomMapperFFBasicName):
176 _id = "name"
178 def _getBasicNameFunc(self, room_mapper):
179 return room_mapper.getName
182 class _RoomMapperFFPlaceName(_RoomMapperFFBasicName):
183 _id = "placename"
185 def _getBasicNameFunc(self, room_mapper):
186 return room_mapper.getPlaceName
189 class _RoomMapperFilterCriteria(filters.FilterCriteria):
191 _availableFields = {"name": _RoomMapperFFName,
192 "placename": _RoomMapperFFPlaceName}
194 def __init__(self, criteria={}):
195 filters.FilterCriteria.__init__(self, None, criteria)
197 def satisfies(self, value, exact=False):
198 for field in self._fields.values():
199 if not field.satisfies(value, exact):
200 return False
201 return True
204 class RoomMapperFilter(filters.SimpleFilter):
205 """Performs filtering and sorting over a list of abstracts.
208 def apply(self,targetList, exact=False):
211 result = []
212 if self._filter:
213 #self._filter.optimise()
214 for item in targetList:
215 if self._filter.satisfies( item, exact ):
216 result.append( item )
217 else:
218 result = targetList
219 if self._sorting:
220 if self._sorting.getField():
221 result.sort( self._sorting.compare )
222 return result