diff options
author | heather <unknown> | 2011-05-16 18:04:10 -0400 |
---|---|---|
committer | heather <unknown> | 2011-05-16 18:04:10 -0400 |
commit | 59534cc14e8d58554b40ce68769c834791a4be96 (patch) | |
tree | 1b0374200337de941713d010f77f8060c56852db | |
parent | 5ab09f1ef6532d02cc0cda6cb49e91ea2d93209f (diff) | |
download | d2-59534cc14e8d58554b40ce68769c834791a4be96.tar.bz2 d2-59534cc14e8d58554b40ce68769c834791a4be96.tar.xz d2-59534cc14e8d58554b40ce68769c834791a4be96.zip |
adding Empty to detail table
-rw-r--r-- | lib/d2/bin/d2_db_setup.py | 33 | ||||
-rw-r--r-- | lib/d2/bin/d2_svg_processor.py | 128 |
2 files changed, 130 insertions, 31 deletions
diff --git a/lib/d2/bin/d2_db_setup.py b/lib/d2/bin/d2_db_setup.py index 42963cc..511677e 100644 --- a/lib/d2/bin/d2_db_setup.py +++ b/lib/d2/bin/d2_db_setup.py | |||
@@ -12,6 +12,7 @@ from d2.db import Detail | |||
12 | from d2.db import OccupantType | 12 | from d2.db import OccupantType |
13 | from d2.db import Occupant | 13 | from d2.db import Occupant |
14 | from d2.app.model.static import StaticData | 14 | from d2.app.model.static import StaticData |
15 | from d2.app.adapters.detail import DetailAdapter | ||
15 | 16 | ||
16 | 17 | ||
17 | class Args(object): | 18 | class Args(object): |
@@ -238,6 +239,35 @@ class PopulateEmptyOccupant(object): | |||
238 | 'occupant_type_id=:occupant_type_id').params( | 239 | 'occupant_type_id=:occupant_type_id').params( |
239 | occupant_type_id=occupant_type_id_for_empty).first() | 240 | occupant_type_id=occupant_type_id_for_empty).first() |
240 | 241 | ||
242 | |||
243 | class PopulateEmptyInDetail(object): | ||
244 | |||
245 | def __init__(self, config): | ||
246 | self._log = config.log | ||
247 | self._db = config.db | ||
248 | self._detail_adapter = DetailAdapter.load(Config.load()) | ||
249 | |||
250 | def __call__(self): | ||
251 | s = StaticData.load(self._db) | ||
252 | occupant_id_for_empty = s().occupant.empty | ||
253 | detail_type_id_for_name = s().detail_type.name | ||
254 | if not self._get(occupant_id_for_empty, | ||
255 | detail_type_id_for_name): | ||
256 | self._detail_adapter.insert_occupant_detail( | ||
257 | occupant_id_for_empty, | ||
258 | detail_type_id_for_name, | ||
259 | u'Empty') | ||
260 | message = "Empty was added to detail" | ||
261 | self._log.info(message) | ||
262 | |||
263 | def _get(self, occupant_id_for_empty, | ||
264 | detail_type_id_for_name): | ||
265 | return self._detail_adapter.fetch_occupant_detail( | ||
266 | occupant_id_for_empty, | ||
267 | detail_type_id_for_name) | ||
268 | |||
269 | |||
270 | |||
241 | class Populate(object): | 271 | class Populate(object): |
242 | 272 | ||
243 | def __init__(self, config): | 273 | def __init__(self, config): |
@@ -245,7 +275,8 @@ class Populate(object): | |||
245 | self._tables = [ | 275 | self._tables = [ |
246 | PopulateDetailType(self.config), | 276 | PopulateDetailType(self.config), |
247 | PopulateOccupantType(self.config), | 277 | PopulateOccupantType(self.config), |
248 | PopulateEmptyOccupant(self.config) | 278 | PopulateEmptyOccupant(self.config), |
279 | PopulateEmptyInDetail(self.config) | ||
249 | ] | 280 | ] |
250 | 281 | ||
251 | def fill_tables(self, args): | 282 | def fill_tables(self, args): |
diff --git a/lib/d2/bin/d2_svg_processor.py b/lib/d2/bin/d2_svg_processor.py index 97c6801..3981ae5 100644 --- a/lib/d2/bin/d2_svg_processor.py +++ b/lib/d2/bin/d2_svg_processor.py | |||
@@ -44,6 +44,10 @@ 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', | ||
48 | '3C1': 'AREA_ID-0', | ||
49 | '3D13A1': 'AREA_ID'} | ||
50 | |||
47 | MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4'] | 51 | MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4'] |
48 | 52 | ||
49 | GROUP_ID_ROOM = {'draft': '3D13A1', | 53 | GROUP_ID_ROOM = {'draft': '3D13A1', |
@@ -76,26 +80,44 @@ NAME_CORRECTIONS = {u'Deb Smith': u'Deborah Smith', | |||
76 | u'Brian Staneck': u'Brian Stanek'} | 80 | u'Brian Staneck': u'Brian Stanek'} |
77 | 81 | ||
78 | 82 | ||
83 | MANUAL_PLOT_COORDINATES = {'ID1': [2, 3], | ||
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 | |||
79 | floor_plan_data = {} | 95 | floor_plan_data = {} |
80 | 96 | ||
81 | ntwk_number_data = {} | 97 | ntwk_number_data = {} |
82 | 98 | ||
99 | manually_added_plot = {} | ||
100 | |||
83 | NTWK_ID_PATTERN = re.compile("([A-Z]+)(\d+)") | 101 | NTWK_ID_PATTERN = re.compile("([A-Z]+)(\d+)") |
84 | 102 | ||
85 | class Args(object): | 103 | class Args(object): |
86 | 104 | ||
87 | DESCRIPTION = "Process svg for d2" | 105 | DESCRIPTION = "Process svg for d2" |
88 | DEFAULT_MASTER_SVG = 'combined_master_v6.svg' | 106 | DEFAULT_MASTER_SVG = 'combined_master_v6.svg' |
89 | DEFAULT_MASTER_SPREADSHEET = 'FloorPlan1.xls' | 107 | DEFAULT_FLOOR_PLAN_XLS = 'FloorPlan1.xls' |
108 | DEFAULT_CONFERENCE_ROOM_XLS = 'ConferenceWorkroom.xls' | ||
109 | |||
110 | MASTER_SVG_HELP = "The full path of the master svg. "\ | ||
111 | "(default: {default})" | ||
90 | 112 | ||
91 | MASTER_SVG_HELP = "The full path of the master svg file "\ | 113 | FLOOR_PLAN_XLS_HELP = "The full path of the floor plan xls. "\ |
92 | "files: (default: {default})" | 114 | "(default: {default})" |
93 | 115 | ||
94 | MASTER_XLS_HELP = "The full path of the master spreadsheet file "\ | 116 | CONFERENCE_ROOM_XLS_HELP = "The full path of the conference "\ |
95 | "files: (default: {default})" | 117 | "room xls. (default: {default})" |
96 | 118 | ||
97 | MASTER_OUTPUT_DIR_HELP = "The full path of the output directory "\ | 119 | MASTER_OUTPUT_DIR_HELP = "The full path of the output directory. "\ |
98 | ': (default: {default})' | 120 | '(default: {default})' |
99 | 121 | ||
100 | def __init__(self, config): | 122 | def __init__(self, config): |
101 | self._config = config | 123 | self._config = config |
@@ -114,7 +136,8 @@ class Args(object): | |||
114 | 136 | ||
115 | def __call__(self): | 137 | def __call__(self): |
116 | self._master_svg_file() | 138 | self._master_svg_file() |
117 | self._spread_sheet_file() | 139 | self._floor_plan_xls() |
140 | self._conference_room_xls() | ||
118 | self._output_directory() | 141 | self._output_directory() |
119 | args = self.parser.parse_args() | 142 | args = self.parser.parse_args() |
120 | args.config = self._config | 143 | args.config = self._config |
@@ -144,15 +167,26 @@ class Args(object): | |||
144 | help=self.MASTER_SVG_HELP.format(default=default_path) | 167 | help=self.MASTER_SVG_HELP.format(default=default_path) |
145 | ) | 168 | ) |
146 | 169 | ||
147 | def _spread_sheet_file(self): | 170 | def _floor_plan_xls(self): |
148 | default_path = os.path.join( | 171 | default_path = os.path.join( |
149 | self._config.data_directory, | 172 | self._config.data_directory, |
150 | self.DEFAULT_MASTER_SPREADSHEET) | 173 | self.DEFAULT_FLOOR_PLAN_XLS) |
151 | self.parser.add_argument( | 174 | self.parser.add_argument( |
152 | '--master-spreadsheet', | 175 | '--floor-plan-xls', |
153 | type=str, | 176 | type=str, |
154 | default=default_path, | 177 | default=default_path, |
155 | help=self.MASTER_XLS_HELP.format(default=default_path) | 178 | help=self.FLOOR_PLAN_XLS_HELP.format(default=default_path) |
179 | ) | ||
180 | |||
181 | def _conference_room_xls(self): | ||
182 | default_path = os.path.join( | ||
183 | self._config.data_directory, | ||
184 | self.DEFAULT_CONFERENCE_ROOM_XLS) | ||
185 | self.parser.add_argument( | ||
186 | '--conference-room-xls', | ||
187 | type=str, | ||
188 | default=default_path, | ||
189 | help=self.CONFERENCE_ROOM_XLS_HELP.format(default=default_path) | ||
156 | ) | 190 | ) |
157 | 191 | ||
158 | def _output_directory(self): | 192 | def _output_directory(self): |
@@ -166,13 +200,15 @@ class Args(object): | |||
166 | help=self.MASTER_OUTPUT_DIR_HELP.format(default=default_path) | 200 | help=self.MASTER_OUTPUT_DIR_HELP.format(default=default_path) |
167 | ) | 201 | ) |
168 | 202 | ||
169 | class ParseFloorPlanXLS(object): | 203 | class ParseFloorPlanConferenceRoomXLS(object): |
170 | 204 | ||
171 | MULTIPLE_RECORD_ERROR = "Data Error: xls has multiple records for {0} "\ | 205 | MULTIPLE_RECORD_ERROR = "Data Error: floor plan xls has multiple records for {0} "\ |
172 | "in room {1}" | 206 | "in room {1}" |
173 | 207 | ||
174 | def __init__(self): | 208 | def __init__(self): |
209 | self._log_obj = None | ||
175 | self._make = namedtuple('cubeInfo', 'name net_jack1 net_jack2') | 210 | self._make = namedtuple('cubeInfo', 'name net_jack1 net_jack2') |
211 | self._make_plot = namedtuple('addedPlot', 'abs_x, abs_y') | ||
176 | 212 | ||
177 | def _determine_room(self, s): | 213 | def _determine_room(self, s): |
178 | """@params s: spread sheet's name, such as "QA 3A1" contains | 214 | """@params s: spread sheet's name, such as "QA 3A1" contains |
@@ -185,7 +221,7 @@ class ParseFloorPlanXLS(object): | |||
185 | return room | 221 | return room |
186 | return '' | 222 | return '' |
187 | 223 | ||
188 | def _process_sheet(self, sh, room_name, log_obj): | 224 | def _process_floor_plan_sheet(self, sh, room_name): |
189 | for rownum in range(2, sh.nrows): | 225 | for rownum in range(2, sh.nrows): |
190 | name = unicode(sh.cell(rowx=rownum, colx=0).value) | 226 | name = unicode(sh.cell(rowx=rownum, colx=0).value) |
191 | cube = sh.cell(rowx=rownum, colx=2).value | 227 | cube = sh.cell(rowx=rownum, colx=2).value |
@@ -195,20 +231,44 @@ class ParseFloorPlanXLS(object): | |||
195 | if room_name not in floor_plan_data: | 231 | if room_name not in floor_plan_data: |
196 | floor_plan_data[room_name] = {} | 232 | floor_plan_data[room_name] = {} |
197 | if cube in floor_plan_data[room_name]: | 233 | if cube in floor_plan_data[room_name]: |
198 | log_obj.error(self.MULTIPLE_RECORD_ERROR.format(cube, | 234 | self._log_obj.error(self.MULTIPLE_RECORD_ERROR.format(cube, |
199 | room_name)) | 235 | room_name)) |
200 | else: | 236 | else: |
201 | floor_plan_data[room_name][cube] = self._make(name, | 237 | floor_plan_data[room_name][cube] = self._make(name, |
202 | net_jack1, | 238 | net_jack1, |
203 | net_jack2) | 239 | net_jack2) |
204 | 240 | ||
241 | def _process_conference_room_sheet(self, sh, room_name): | ||
242 | for rownum in range(2, sh.nrows): | ||
243 | name = unicode(sh.cell(rowx=rownum, colx=0).value) | ||
244 | cube = sh.cell(rowx=rownum, colx=2).value | ||
245 | if name and cube: | ||
246 | if room_name not in floor_plan_data: | ||
247 | floor_plan_data[room_name] = {} | ||
248 | floor_plan_data[room_name][cube] = self._make(name, "", "") | ||
249 | if cube[:2] == 'ID': | ||
250 | if room_name not in manually_added_plot: | ||
251 | manually_added_plot[room_name] = {} | ||
252 | manually_added_plot[room_name][cube] = self._make_plot( | ||
253 | MANUAL_PLOT_COORDINATES[cube][0], | ||
254 | MANUAL_PLOT_COORDINATES[cube][1]) | ||
255 | |||
205 | def __call__(self, args): | 256 | def __call__(self, args): |
206 | wb = xlrd.open_workbook(args.master_spreadsheet) | 257 | self._log_obj = args.log |
258 | wb = xlrd.open_workbook(args.floor_plan_xls) | ||
207 | for sheet_name in wb.sheet_names(): | 259 | for sheet_name in wb.sheet_names(): |
208 | room_name = self._determine_room(sheet_name) | 260 | room_name = self._determine_room(sheet_name) |
209 | if room_name: | 261 | if room_name: |
210 | self._process_sheet(wb.sheet_by_name(sheet_name), | 262 | self._process_floor_plan_sheet(wb.sheet_by_name(sheet_name), |
211 | room_name, args.log) | 263 | room_name) |
264 | |||
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) | ||
212 | 272 | ||
213 | class CreateStructureSVG(object): | 273 | class CreateStructureSVG(object): |
214 | 274 | ||
@@ -320,7 +380,6 @@ class CreateStructureSVG(object): | |||
320 | class PopulateTables(object): | 380 | class PopulateTables(object): |
321 | 381 | ||
322 | OUTPUT_NTWK_ID_FILENAME = 'ntwk_id.svg' | 382 | OUTPUT_NTWK_ID_FILENAME = 'ntwk_id.svg' |
323 | OUTPUT_JSON_FILENAME = 'ntwk_number_data.json' | ||
324 | TABLES = [u'forge', u'label_coordinate', u'plot'] | 383 | TABLES = [u'forge', u'label_coordinate', u'plot'] |
325 | 384 | ||
326 | TRANSFORM_MATRIX_ERROR = "Error: transform matrix of {0} not implemented" | 385 | TRANSFORM_MATRIX_ERROR = "Error: transform matrix of {0} not implemented" |
@@ -329,7 +388,7 @@ class PopulateTables(object): | |||
329 | NO_CLOSEBY_NTWK_ID_ERROR = "Data Error: cannot find closest_ntwk_id "\ | 388 | NO_CLOSEBY_NTWK_ID_ERROR = "Data Error: cannot find closest_ntwk_id "\ |
330 | "in room_name: {0}, x: {1} y: {2}, current name shown {3}" | 389 | "in room_name: {0}, x: {1} y: {2}, current name shown {3}" |
331 | NO_AREA_INFO_ERROR = "Data Error: cannot find area info for {0} {1}" | 390 | NO_AREA_INFO_ERROR = "Data Error: cannot find area info for {0} {1}" |
332 | NO_OCCUPANT_DETAIL = "Data Errot: cannot find {0} in occupant_detail" | 391 | NO_OCCUPANT_DETAIL = "Data Error: cannot find {0} in occupant_detail" |
333 | 392 | ||
334 | 393 | ||
335 | def __init__(self): | 394 | def __init__(self): |
@@ -423,6 +482,20 @@ class PopulateTables(object): | |||
423 | ntwk_id, | 482 | ntwk_id, |
424 | plot_id) | 483 | plot_id) |
425 | 484 | ||
485 | # Process manually added plot identifiers | ||
486 | #TODO: manually added plots need to be in svg as well | ||
487 | for (room_name, info) in manually_added_plot.items(): | ||
488 | for (ntwk_id, xy_info) in info.items(): | ||
489 | plot_id = self._add_to_tables(xy_info.abs_x, | ||
490 | xy_info.abs_y, | ||
491 | ntwk_id) | ||
492 | self._add_to_ntwk_number_data(xy_info.abs_x, | ||
493 | xy_info.abs_y, | ||
494 | room_name, | ||
495 | ntwk_id, | ||
496 | plot_id) | ||
497 | |||
498 | |||
426 | def _add_to_tables(self, x, y, ntwk_id): | 499 | def _add_to_tables(self, x, y, ntwk_id): |
427 | """ insert into plot table, | 500 | """ insert into plot table, |
428 | add an empty user to the plot in forge table, | 501 | add an empty user to the plot in forge table, |
@@ -570,8 +643,10 @@ class PopulateTables(object): | |||
570 | id="{0}_NAME_LABEL".format(approx_room_name)) | 643 | id="{0}_NAME_LABEL".format(approx_room_name)) |
571 | 644 | ||
572 | room_name_label_id = NAME_LABEL_ID.get(approx_room_name) | 645 | room_name_label_id = NAME_LABEL_ID.get(approx_room_name) |
646 | room_area_label_id = CONFERENCE_LABEL_ID.get(approx_room_name) | ||
573 | for el in node: | 647 | for el in node: |
574 | if el.attrib['id'] == room_name_label_id: | 648 | if el.attrib['id'] == room_name_label_id or \ |
649 | el.attrib['id'] == room_area_label_id: | ||
575 | for sub_el in el: | 650 | for sub_el in el: |
576 | if sub_el.tag == '{{{0}}}text'.format(NSMAP['svg']): | 651 | if sub_el.tag == '{{{0}}}text'.format(NSMAP['svg']): |
577 | tspan_elem = sub_el.xpath('./svg:tspan', | 652 | tspan_elem = sub_el.xpath('./svg:tspan', |
@@ -813,13 +888,6 @@ class PopulateTables(object): | |||
813 | output_ntwk_id_fileobj: | 888 | output_ntwk_id_fileobj: |
814 | output_ntwk_id_fileobj.write(self._get_ntwk_id_svg()) | 889 | output_ntwk_id_fileobj.write(self._get_ntwk_id_svg()) |
815 | 890 | ||
816 | output_json_filepath = os.path.join( | ||
817 | args.data_directory, | ||
818 | args.project + '_' + self.OUTPUT_JSON_FILENAME | ||
819 | ) | ||
820 | with open(output_json_filepath, 'wb') as output_json_fileobj: | ||
821 | output_json_fileobj.write(json.dumps(ntwk_number_data)) | ||
822 | |||
823 | self._get_name_label_svg() | 891 | self._get_name_label_svg() |
824 | 892 | ||
825 | class Util(object): | 893 | class Util(object): |
@@ -859,7 +927,7 @@ class Process(object): | |||
859 | def __init__(self): | 927 | def __init__(self): |
860 | self._chain = [ | 928 | self._chain = [ |
861 | CreateStructureSVG(), | 929 | CreateStructureSVG(), |
862 | ParseFloorPlanXLS(), | 930 | ParseFloorPlanConferenceRoomXLS(), |
863 | PopulateTables(), | 931 | PopulateTables(), |
864 | ] | 932 | ] |
865 | 933 | ||