aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorheather <unknown>2011-05-16 18:04:10 -0400
committerheather <unknown>2011-05-16 18:04:10 -0400
commit59534cc14e8d58554b40ce68769c834791a4be96 (patch)
tree1b0374200337de941713d010f77f8060c56852db
parent5ab09f1ef6532d02cc0cda6cb49e91ea2d93209f (diff)
downloadd2-59534cc14e8d58554b40ce68769c834791a4be96.tar.bz2
d2-59534cc14e8d58554b40ce68769c834791a4be96.tar.xz
d2-59534cc14e8d58554b40ce68769c834791a4be96.zip
adding Empty to detail table
-rw-r--r--lib/d2/bin/d2_db_setup.py33
-rw-r--r--lib/d2/bin/d2_svg_processor.py128
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
12from d2.db import OccupantType 12from d2.db import OccupantType
13from d2.db import Occupant 13from d2.db import Occupant
14from d2.app.model.static import StaticData 14from d2.app.model.static import StaticData
15from d2.app.adapters.detail import DetailAdapter
15 16
16 17
17class Args(object): 18class 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
243class 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
241class Populate(object): 271class 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
47CONFERENCE_LABEL_ID = {'3B1': 'AREA_ID-6',
48 '3C1': 'AREA_ID-0',
49 '3D13A1': 'AREA_ID'}
50
47MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4'] 51MAIN_ROOM_NODES = ['draft', 'draft-3', 'draft-4']
48 52
49GROUP_ID_ROOM = {'draft': '3D13A1', 53GROUP_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
83MANUAL_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
79floor_plan_data = {} 95floor_plan_data = {}
80 96
81ntwk_number_data = {} 97ntwk_number_data = {}
82 98
99manually_added_plot = {}
100
83NTWK_ID_PATTERN = re.compile("([A-Z]+)(\d+)") 101NTWK_ID_PATTERN = re.compile("([A-Z]+)(\d+)")
84 102
85class Args(object): 103class 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
169class ParseFloorPlanXLS(object): 203class 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
213class CreateStructureSVG(object): 273class CreateStructureSVG(object):
214 274
@@ -320,7 +380,6 @@ class CreateStructureSVG(object):
320class PopulateTables(object): 380class 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
825class Util(object): 893class 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