diff options
-rw-r--r-- | lib/d2/app/controllers/svg_text.py | 4 | ||||
-rw-r--r-- | lib/d2/bin/d2_agi_db_setup.py | 39 | ||||
-rw-r--r-- | lib/d2/bin/d2_svg_processor.py | 161 | ||||
-rw-r--r-- | templates/index.html | 2 |
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 | |||
9 | from d2.db import Floor | 9 | from d2.db import Floor |
10 | from d2.db import OccupantType | 10 | from d2.db import OccupantType |
11 | from d2.db import Occupant | 11 | from d2.db import Occupant |
12 | from d2.app.adapters.detail import DetailAdapter | ||
12 | 13 | ||
13 | class Args(object): | 14 | class 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 | ||
97 | class PopulateSpecialOccupants(object): | 98 | class 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 | |||
139 | class PopulateTables(object): | 164 | class 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 | ||
47 | CONFERENCE_LABEL_ID = {'3B1': 'AREA_ID-6', | 47 | CONFERENCE_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 | ||
51 | MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4'] | 51 | MAIN_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 | ||
82 | floor_plan_by_ntwk_id = {} | ||
82 | 83 | ||
83 | MANUAL_PLOT_COORDINATES = {'ID1': [2, 3], | 84 | floor_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 | |||
95 | floor_plan_data = {} | ||
96 | 85 | ||
97 | ntwk_number_data = {} | 86 | ntwk_number_data = {} |
98 | 87 | ||
@@ -201,13 +190,21 @@ class Args(object): | |||
201 | ) | 190 | ) |
202 | 191 | ||
203 | class ParseFloorPlanConferenceRoomXLS(object): | 192 | class 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 | ||
273 | class CreateStructureSVG(object): | 269 | class 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"); |