aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/d2/app/controllers/svg_text.py4
-rw-r--r--lib/d2/bin/d2_agi_db_setup.py39
-rw-r--r--lib/d2/bin/d2_svg_processor.py161
-rw-r--r--templates/index.html2
4 files changed, 128 insertions, 78 deletions
diff --git a/lib/d2/app/controllers/svg_text.py b/lib/d2/app/controllers/svg_text.py
index 4ffc5cf..1c4d37e 100644
--- a/lib/d2/app/controllers/svg_text.py
+++ b/lib/d2/app/controllers/svg_text.py
@@ -43,7 +43,9 @@ class SvgTextController(BaseController):
43 plot_id=forge_record.plot_id, 43 plot_id=forge_record.plot_id,
44 detail_type_id=self._static.detail_type.name).first() 44 detail_type_id=self._static.detail_type.name).first()
45 if coordinate: 45 if coordinate:
46 out.append(self.MAKE_ROW(forge_record.occupant_id, 46 out.append(self.MAKE_ROW(
47 "{0}_{1}".format(forge_record.occupant_id,
48 forge_record.plot_id),
47 occupant_record.occupant_type.name, 49 occupant_record.occupant_type.name,
48 label, 50 label,
49 coordinate.x, 51 coordinate.x,
diff --git a/lib/d2/bin/d2_agi_db_setup.py b/lib/d2/bin/d2_agi_db_setup.py
index 2df60ef..a53e5b8 100644
--- a/lib/d2/bin/d2_agi_db_setup.py
+++ b/lib/d2/bin/d2_agi_db_setup.py
@@ -9,6 +9,7 @@ from d2.db import Room
9from d2.db import Floor 9from d2.db import Floor
10from d2.db import OccupantType 10from d2.db import OccupantType
11from d2.db import Occupant 11from d2.db import Occupant
12from d2.app.adapters.detail import DetailAdapter
12 13
13class Args(object): 14class Args(object):
14 15
@@ -95,6 +96,10 @@ class PopulateMap(object):
95 location_id=map.get('location_id')).first() 96 location_id=map.get('location_id')).first()
96 97
97class PopulateSpecialOccupants(object): 98class PopulateSpecialOccupants(object):
99 """
100 Data from LDAP does not contain these data.
101 Manually insert them in occupant and detail tables
102 """
98 103
99 NAMES = {'person': [u'CSR', u'Temp'], 104 NAMES = {'person': [u'CSR', u'Temp'],
100 'work area': [u'Cirith Ungol', u'Orodruin'], 105 'work area': [u'Cirith Ungol', u'Orodruin'],
@@ -105,37 +110,57 @@ class PopulateSpecialOccupants(object):
105 def __init__(self, config): 110 def __init__(self, config):
106 self._log = config.log 111 self._log = config.log
107 self._db = config.db 112 self._db = config.db
113 self._detail_adapter = DetailAdapter.load(Config.load())
108 114
109 def __call__(self): 115 def __call__(self):
110 s = StaticData.load(self._db) 116 s = StaticData.load(self._db)
111 occupant_type_id_for_person = s().occupant_type.person 117
112 for type, names in self.NAMES.iteritems(): 118 for type, names in self.NAMES.iteritems():
113 if type == 'person': 119 if type == 'person':
114 type_id = s().occupant_type.person 120 occupant_type_id = s().occupant_type.person
121 detail_type_id = s().detail_type.last_name
115 elif type == 'work area': 122 elif type == 'work area':
116 type_id = s().occupant_type.work_area 123 occupant_type_id = s().occupant_type.work_area
124 detail_type_id = s().detail_type.name
117 elif type == 'restroom': 125 elif type == 'restroom':
118 type_id = s().occupant_type.restroom 126 occupant_type_id = s().occupant_type.restroom
127 detail_type_id = s().detail_type.name
119 128
120 for name in names: 129 for name in names:
121 if not self._get(name): 130 if not self._get_occupant(name):
122 data = dict(occupant_type_id = type_id, 131 data = dict(occupant_type_id = occupant_type_id,
123 key = self._get_key(name), 132 key = self._get_key(name),
124 active = True) 133 active = True)
125 obj = Occupant.from_dict(data) 134 obj = Occupant.from_dict(data)
126 self._db.session.add(obj) 135 self._db.session.add(obj)
127 self._db.session.commit() 136 self._db.session.commit()
137 occupant_id = obj.id
128 message = "{0} occupant was added".format(name) 138 message = "{0} occupant was added".format(name)
129 self._log.info(message) 139 self._log.info(message)
140 else:
141 occupant_id = self._get_occupant(name).id
142
143 if not self._get_detail(detail_type_id, name):
144 self._detail_adapter.insert_occupant_detail(
145 occupant_id,
146 detail_type_id,
147 name)
148 message = "{0} was added to detail".format(name)
149 self._log.info(message)
130 150
131 def _get_key(self, name): 151 def _get_key(self, name):
132 return unicode(hashlib.md5(unicode(name)).hexdigest()) 152 return unicode(hashlib.md5(unicode(name)).hexdigest())
133 153
134 def _get(self, name): 154 def _get_occupant(self, name):
135 return self._db.session.query(Occupant).filter( 155 return self._db.session.query(Occupant).filter(
136 'key=:key').params( 156 'key=:key').params(
137 key=self._get_key(name)).first() 157 key=self._get_key(name)).first()
138 158
159 def _get_detail(self, detail_type_id, data):
160 return self._detail_adapter.fetch_detail_by_type_data(
161 detail_type_id,
162 data)
163
139class PopulateTables(object): 164class PopulateTables(object):
140 165
141 def __init__(self, config): 166 def __init__(self, config):
diff --git a/lib/d2/bin/d2_svg_processor.py b/lib/d2/bin/d2_svg_processor.py
index 3981ae5..d3d7815 100644
--- a/lib/d2/bin/d2_svg_processor.py
+++ b/lib/d2/bin/d2_svg_processor.py
@@ -44,8 +44,8 @@ NAME_LABEL_ID = {'3D13A1': 'NAME',
44 '3C1': 'NAME-2', 44 '3C1': 'NAME-2',
45 '3B1': 'NAME-6'} 45 '3B1': 'NAME-6'}
46 46
47CONFERENCE_LABEL_ID = {'3B1': 'AREA_ID-6', 47CONFERENCE_LABEL_ID = {'3C1': 'AREA_ID-6',
48 '3C1': 'AREA_ID-0', 48 '3B1': 'AREA_ID-0',
49 '3D13A1': 'AREA_ID'} 49 '3D13A1': 'AREA_ID'}
50 50
51MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4'] 51MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4']
@@ -79,20 +79,9 @@ NAME_CORRECTIONS = {u'Deb Smith': u'Deborah Smith',
79 u'Sally Babcock': u'Sally Schriner', 79 u'Sally Babcock': u'Sally Schriner',
80 u'Brian Staneck': u'Brian Stanek'} 80 u'Brian Staneck': u'Brian Stanek'}
81 81
82floor_plan_by_ntwk_id = {}
82 83
83MANUAL_PLOT_COORDINATES = {'ID1': [2, 3], 84floor_plan_by_name = {}
84 'ID2': [3, 4],
85 'ID3': [3, 4],
86 'ID4': [3, 4],
87 'ID5': [3, 4],
88 'ID6': [3, 4],
89 'ID7': [3, 4],
90 'ID8': [3, 4],
91 'ID9': [3, 4],
92 'ID10': [3, 4]
93 }
94
95floor_plan_data = {}
96 85
97ntwk_number_data = {} 86ntwk_number_data = {}
98 87
@@ -201,13 +190,21 @@ class Args(object):
201 ) 190 )
202 191
203class ParseFloorPlanConferenceRoomXLS(object): 192class ParseFloorPlanConferenceRoomXLS(object):
193 """
194 after process the xls sheet, info is kept in two dictionaries:
195
196 floor_plan_by_ntwk_id[room_name][ntwk_id] = [name, net_jack1, net_jack2]
197 floor_plan_by_name[room_name][name] = [ntwk_id]
198 """
204 199
205 MULTIPLE_RECORD_ERROR = "Data Error: floor plan xls has multiple records for {0} "\ 200 MULTIPLE_NTWK_ID_IN_ONE_ROOM_ERROR = "Data Error: floor plan xls has "\
206 "in room {1}" 201 "multiple records for ntwk_id {0} in room {1}"
202 MULTIPLE_NAME_IN_ONE_ROOM_ERROR = "Warning: floor plan xls has "\
203 "multiple records for name {0} in room {1}"
207 204
208 def __init__(self): 205 def __init__(self):
209 self._log_obj = None 206 self._log_obj = None
210 self._make = namedtuple('cubeInfo', 'name net_jack1 net_jack2') 207 self._make_cube_info = namedtuple('cubeInfo', 'name net_jack1 net_jack2')
211 self._make_plot = namedtuple('addedPlot', 'abs_x, abs_y') 208 self._make_plot = namedtuple('addedPlot', 'abs_x, abs_y')
212 209
213 def _determine_room(self, s): 210 def _determine_room(self, s):
@@ -221,54 +218,53 @@ class ParseFloorPlanConferenceRoomXLS(object):
221 return room 218 return room
222 return '' 219 return ''
223 220
224 def _process_floor_plan_sheet(self, sh, room_name): 221 def _process_sheet(self, sh, room_name):
225 for rownum in range(2, sh.nrows): 222 for rownum in range(2, sh.nrows):
226 name = unicode(sh.cell(rowx=rownum, colx=0).value) 223 name = unicode(sh.cell(rowx=rownum, colx=0).value)
227 cube = sh.cell(rowx=rownum, colx=2).value 224 cube = sh.cell(rowx=rownum, colx=2).value
228 if name and cube: 225 if name and cube:
229 net_jack1 = unicode(sh.cell(rowx=rownum, colx=3).value) 226 net_jack1 = unicode(sh.cell(rowx=rownum, colx=3).value)
230 net_jack2 = unicode(sh.cell(rowx=rownum, colx=4).value) 227 net_jack2 = unicode(sh.cell(rowx=rownum, colx=4).value)
231 if room_name not in floor_plan_data: 228 if room_name not in floor_plan_by_ntwk_id:
232 floor_plan_data[room_name] = {} 229 floor_plan_by_ntwk_id[room_name] = {}
233 if cube in floor_plan_data[room_name]: 230 if room_name not in floor_plan_by_name:
234 self._log_obj.error(self.MULTIPLE_RECORD_ERROR.format(cube, 231 floor_plan_by_name[room_name] = {}
235 room_name)) 232
233 if cube in floor_plan_by_ntwk_id[room_name]:
234 self._log_obj.error(
235 self.MULTIPLE_NTWK_ID_IN_ONE_ROOM_ERROR.format(
236 cube,
237 room_name))
236 else: 238 else:
237 floor_plan_data[room_name][cube] = self._make(name, 239 floor_plan_by_ntwk_id[room_name][cube] = \
238 net_jack1, 240 self._make_cube_info(name, net_jack1, net_jack2)
239 net_jack2) 241
240 242 if name.lower() in floor_plan_by_name[room_name]:
241 def _process_conference_room_sheet(self, sh, room_name): 243 self._log_obj.error(
242 for rownum in range(2, sh.nrows): 244 self.MULTIPLE_NAME_IN_ONE_ROOM_ERROR.format(
243 name = unicode(sh.cell(rowx=rownum, colx=0).value) 245 name.lower(),
244 cube = sh.cell(rowx=rownum, colx=2).value 246 room_name))
245 if name and cube: 247 else:
246 if room_name not in floor_plan_data: 248 floor_plan_by_name[room_name][name.lower()] = cube
247 floor_plan_data[room_name] = {} 249
248 floor_plan_data[room_name][cube] = self._make(name, "", "")
249 if cube[:2] == 'ID': 250 if cube[:2] == 'ID':
250 if room_name not in manually_added_plot: 251 if room_name not in manually_added_plot:
251 manually_added_plot[room_name] = {} 252 manually_added_plot[room_name] = {}
252 manually_added_plot[room_name][cube] = self._make_plot( 253 manually_added_plot[room_name][cube] = self._make_plot(
253 MANUAL_PLOT_COORDINATES[cube][0], 254 sh.cell(rowx=rownum, colx=8).value,
254 MANUAL_PLOT_COORDINATES[cube][1]) 255 sh.cell(rowx=rownum, colx=9).value)
255 256
257
258
256 def __call__(self, args): 259 def __call__(self, args):
257 self._log_obj = args.log 260 self._log_obj = args.log
258 wb = xlrd.open_workbook(args.floor_plan_xls) 261 for file_obj in (args.floor_plan_xls, args.conference_room_xls):
259 for sheet_name in wb.sheet_names(): 262 wb = xlrd.open_workbook(file_obj)
260 room_name = self._determine_room(sheet_name) 263 for sheet_name in wb.sheet_names():
261 if room_name: 264 room_name = self._determine_room(sheet_name)
262 self._process_floor_plan_sheet(wb.sheet_by_name(sheet_name), 265 if room_name:
263 room_name) 266 self._process_sheet(wb.sheet_by_name(sheet_name), room_name)
264 267
265 wb = xlrd.open_workbook(args.conference_room_xls)
266 for sheet_name in wb.sheet_names():
267 room_name = self._determine_room(sheet_name)
268 if room_name:
269 self._process_conference_room_sheet(
270 wb.sheet_by_name(sheet_name),
271 room_name)
272 268
273class CreateStructureSVG(object): 269class CreateStructureSVG(object):
274 270
@@ -482,10 +478,11 @@ class PopulateTables(object):
482 ntwk_id, 478 ntwk_id,
483 plot_id) 479 plot_id)
484 480
485 # Process manually added plot identifiers 481 def _add_manually_added_plots(self):
486 #TODO: manually added plots need to be in svg as well 482 #TODO: manually added plots need to be in svg as well
487 for (room_name, info) in manually_added_plot.items(): 483 for (room_name, info) in manually_added_plot.items():
488 for (ntwk_id, xy_info) in info.items(): 484 for (ntwk_id, xy_info) in info.items():
485 print ntwk_id, xy_info.abs_x, xy_info.abs_y
489 plot_id = self._add_to_tables(xy_info.abs_x, 486 plot_id = self._add_to_tables(xy_info.abs_x,
490 xy_info.abs_y, 487 xy_info.abs_y,
491 ntwk_id) 488 ntwk_id)
@@ -586,6 +583,7 @@ class PopulateTables(object):
586 view_box_ymin, 583 view_box_ymin,
587 view_box_height, 584 view_box_height,
588 main_el_matrix) 585 main_el_matrix)
586 self._add_manually_added_plots()
589 return etree.tostring(ntwk_id_svg) 587 return etree.tostring(ntwk_id_svg)
590 588
591 589
@@ -651,6 +649,13 @@ class PopulateTables(object):
651 if sub_el.tag == '{{{0}}}text'.format(NSMAP['svg']): 649 if sub_el.tag == '{{{0}}}text'.format(NSMAP['svg']):
652 tspan_elem = sub_el.xpath('./svg:tspan', 650 tspan_elem = sub_el.xpath('./svg:tspan',
653 namespaces=NSMAP)[0] 651 namespaces=NSMAP)[0]
652 current_name_shown = ""
653 tspan_elem = sub_el.xpath('./svg:tspan',
654 namespaces=NSMAP)
655 for ts in tspan_elem:
656 current_name_shown += ts.text + " "
657 current_name_shown = current_name_shown[:-1]
658
654 transform_matrix = sub_el.attrib['transform'] 659 transform_matrix = sub_el.attrib['transform']
655 matrices = list(base_matrices) 660 matrices = list(base_matrices)
656 matrices.insert(0, transform_matrix) 661 matrices.insert(0, transform_matrix)
@@ -670,13 +675,29 @@ class PopulateTables(object):
670 room_name, 675 room_name,
671 abs_x, 676 abs_x,
672 abs_y) 677 abs_y)
678 if el.attrib['id'] == "AREA_ID-6":
679 print "closest_ntwk_id: ", closest_ntwk_id, room_name
673 680
674 current_name_shown = "" 681 if not closest_ntwk_id:
675 tspan_elem = sub_el.xpath('./svg:tspan', 682 print "looking for XXX{0}XXX".format(current_name_shown.lower())
676 namespaces=NSMAP) 683 # try to find ntwk_id using floor_plan_by_name
677 for ts in tspan_elem: 684 if current_name_shown.lower() in \
678 current_name_shown += " " + ts.text 685 floor_plan_by_name[room_name]:
679 686 closest_ntwk_id = floor_plan_by_name[
687 room_name][
688 current_name_shown.lower()]
689 print "USE floor_plan_by_name ", closest_ntwk_id
690 else:
691 # try to trim "conference room" for match
692 conf_room_name = current_name_shown.lower()\
693 .replace(" conference room", "")
694 print "looking for XXX{0}XXX".format(conf_room_name)
695 if conf_room_name in \
696 floor_plan_by_name[room_name]:
697 closest_ntwk_id = floor_plan_by_name[
698 room_name][
699 conf_room_name]
700 print "USE floor_plan_by_name ", closest_ntwk_id
680 if not closest_ntwk_id: 701 if not closest_ntwk_id:
681 self._log_obj.error( 702 self._log_obj.error(
682 self.NO_CLOSEBY_NTWK_ID_ERROR.format( 703 self.NO_CLOSEBY_NTWK_ID_ERROR.format(
@@ -784,22 +805,24 @@ class PopulateTables(object):
784 net_jack2 information 805 net_jack2 information
785 """ 806 """
786 info = None 807 info = None
787 if ntwk_id in floor_plan_data[room_name]: 808 if ntwk_id in floor_plan_by_ntwk_id[room_name]:
788 info = floor_plan_data[room_name][ntwk_id] 809 info = floor_plan_by_ntwk_id[room_name][ntwk_id]
789 else: 810 else:
790 normalized_id = self._get_normalized_ntwk_id(ntwk_id) 811 normalized_id = self._get_normalized_ntwk_id(ntwk_id)
791 if normalized_id in floor_plan_data[room_name]: 812 if normalized_id in floor_plan_by_ntwk_id[room_name]:
792 info = floor_plan_data[room_name][normalized_id] 813 info = floor_plan_by_ntwk_id[room_name][normalized_id]
793 else: 814 else:
794 # try to add these weird symbols at the end... 815 # try to add these weird symbols at the end...
795 normalized_id_with_C = normalized_id + "-C" 816 normalized_id_with_C = normalized_id + "-C"
796 if normalized_id_with_C in floor_plan_data[room_name]: 817 if normalized_id_with_C in floor_plan_by_ntwk_id[room_name]:
797 info = floor_plan_data[room_name][normalized_id_with_C] 818 info = floor_plan_by_ntwk_id[room_name][
819 normalized_id_with_C]
798 else: 820 else:
799 # try to add these weird symbols... 821 # try to add these weird symbols...
800 normalized_id_IDF = normalized_id + "/IDF" 822 normalized_id_IDF = normalized_id + "/IDF"
801 if normalized_id_IDF in floor_plan_data[room_name]: 823 if normalized_id_IDF in floor_plan_by_ntwk_id[room_name]:
802 info = floor_plan_data[room_name][normalized_id_IDF] 824 info = floor_plan_by_ntwk_id[room_name][
825 normalized_id_IDF]
803 else: 826 else:
804 self._log_obj.error(self.NO_AREA_INFO_ERROR.format( 827 self._log_obj.error(self.NO_AREA_INFO_ERROR.format(
805 room_name, 828 room_name,
@@ -844,7 +867,7 @@ class PopulateTables(object):
844 if not occupant_id: 867 if not occupant_id:
845 detail = self._search_adapter.search(info.name) 868 detail = self._search_adapter.search(info.name)
846 if len(detail) == 1: 869 if len(detail) == 1:
847 occupant_id = detail[0].id 870 occupant_id = detail[0].occupant_id
848 871
849 if not occupant_id: 872 if not occupant_id:
850 self._log_obj.error(self.NO_OCCUPANT_DETAIL.format(info.name)) 873 self._log_obj.error(self.NO_OCCUPANT_DETAIL.format(info.name))
diff --git a/templates/index.html b/templates/index.html
index 89a1e9d..9a504a5 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -78,7 +78,7 @@
78 function emphasize() 78 function emphasize()
79 { 79 {
80 {% if (len(forges) > 0) %} 80 {% if (len(forges) > 0) %}
81 var e = document.getElementById("{{forges[0].occupant_id}}"); 81 var e = document.getElementById("{{forges[0].occupant_id}}_{{forges[0].plot_id}}");
82 if (e) 82 if (e)
83 { 83 {
84 e.setAttributeNS(null, "fill", "red"); 84 e.setAttributeNS(null, "fill", "red");