def sync_bed_counts(self, bedcounts_df, user=None): self.prepare() bedcounts_df = bedcounts_df[BC_COLUMNS] # First check that all ICUs exist: icu_names = set(bedcounts_df['icu_name'].unique()) db_icus = dict((icu.name, icu) for icu in self.db.get_icus()) # Make sure each bedcount has an existent ICU: icu_diff = icu_names - set(db_icus.keys()) if len(icu_diff) > 0: raise KeyError( f"Missing ICUs in DB: {icu_diff}. Please add them first.") # Now we are sure all ICUs are present so we can insert without checking: for idx, bc in bedcounts_df.iterrows(): if bc['create_date'].tzinfo != tz.tzutc(): raise ValueError("Timestamps must be in UTC, got {}".format( bc['create_date'].tzinfo)) item = bc.to_dict() # Replace icu_name with corresponding ID: item['icu_id'] = db_icus[item['icu_name']].icu_id del item['icu_name'] item['last_modified'] = item['create_date'] # import ipdb; ipdb.set_trace() logging.info(f"Inserting BedCount: {item} into DB.") self.db.update_bed_count_for_icu(user, store.BedCount(**item), force=not user)
def prepare_data(self, icu, locale) -> list: link = {'key': 'ICU (update link)', 'value': icu.name} link['link'] = self.link_fn(icu.users[0], icu) if icu.users else None result = [link] bed_count = icu.bed_counts[-1] if icu.bed_counts else store.BedCount() bed_count_dict = bed_count.to_dict(max_depth=0) last = bed_count_dict.pop('create_date', None) last = None if last is None else last.timestamp() display_date = time_utils.localewise_time_ago(last, locale=locale) stale = time_utils.is_stale( last, days_threshold=self.config.server.num_days_for_stale) result.append({ 'key': 'since_update', 'value': display_date, 'warning': stale, 'sort_value': 0 if last is None else last, 'link': False, }) to_pop = [ 'rowid', 'icu_id', 'message', 'create_date', 'last_modified', 'icu' ] for key in to_pop: bed_count_dict.pop(key, None) result.extend(self.format_list_item(bed_count_dict)) return result
def test_add(self): example = self.icus[7] insert_time = self.insert_time + datetime.timedelta(seconds=1) self.db.update_bed_count_for_icu( self.admin_id, store.BedCount(icu_id=self.icus[1].icu_id, n_covid_occ=12, n_covid_free=4, create_date=insert_time)) self.db.update_bed_count_for_icu( self.admin_id, store.BedCount(icu_id=example.icu_id, n_covid_occ=1, n_covid_free=19, create_date=insert_time)) tree = icu_tree.ICUTree() icus = self.db.get_icus() bedcounts = self.db.get_latest_bed_counts() tree.add_many(icus, bedcounts) self.assertEqual(tree.level, 'country') self.assertGreater(len(tree.children), 0) self.assertIn(example.region.name, tree.children) self.assertEqual(tree.occ, 13) self.assertEqual(tree.free, 23) self.assertEqual(tree.total, 36) self.assertFalse(tree.is_leaf) idf = tree.children[example.region.name] self.assertEqual(len(idf.children), 4) self.assertFalse(idf.is_leaf) self.assertIn(example.dept, idf.children) vdm = idf.children[example.dept] self.assertEqual(len(vdm.children), 2) self.assertFalse(vdm.is_leaf) self.assertIn(example.city, vdm.children) creteil = vdm.children[example.city] self.assertEqual(len(creteil.children), 2) self.assertFalse(creteil.is_leaf) self.assertIn(example.name, creteil.children) icu8_node = creteil.children[example.name] self.assertTrue(icu8_node.is_leaf) self.assertEqual(icu8_node.total, 20)
def add(self, icu, bedcount): if not self.should_add(icu, bedcount): return bedcount = bedcount if bedcount is not None else store.BedCount() self.set_basic_information(icu) self.account_for_beds(bedcount) self.propagate(icu, bedcount)
async def process(self): async for item in self.queue: try: item.pop('icu_name', None) # Here we do not necessarily have acccess to the user. # We force the update. # TODO(olivier): should we send the user id in the token? self.db.update_bed_count_for_icu( None, store.BedCount(**item), force=True) finally: self.queue.task_done()
async def process(self): async for item in self.queue: try: user_id = item.pop('user_id', None) if user_id is None: logging.error("No user in request") return self.db.update_bed_count_for_icu(user_id, store.BedCount(**item)) finally: self.queue.task_done()
def test_prepare_data(self): icu = self.handler.db.get_icu(self.icuid) bedcount = store.BedCount(icu_id=icu.icu_id, n_covid_occ=12, n_covid_free=4) self.handler.db.update_bed_count_for_icu(self.admin_id, bedcount) icu = self.handler.db.get_icu(self.icuid) data = self.handler.prepare_data(icu) self.assertIsInstance(data, list) self.assertGreater(len(data), 0) for k in ['key', 'value', 'link']: self.assertIn(k, data[0])
def get_icu_data_by_id(self, icu_id, locale=None, def_val=0): """Returns the dictionary of counts for the given icu.""" bed_count = self.db.get_bed_count_for_icu(icu_id) bed_count = bed_count if bed_count is not None else store.BedCount() # In case there is a weird corner case, we don't want to crash the form: last_update = bed_count.last_modified if last_update is not None: last_update = last_update.timestamp() data = bed_count.to_dict() apply_default(data, value=def_val, prefix='n_') data['since_update'] = time_utils.localewise_time_ago(last_update, locale) data['home_route'] = home.HomeHandler.ROUTE data['update_route'] = self.ROUTE return data
def populate_db(self): self.admin_id = self.db.add_default_admin() r1 = self.db.add_region(self.admin_id, store.Region(name='IDF')) r2 = self.db.add_region(self.admin_id, store.Region(name='PACA')) self.db.add_icu( self.admin_id, store.ICU(name='icu1', region_id=r1, dept='75', city='Paris', telephone='+65123')) self.db.add_icu( self.admin_id, store.ICU(name='icu2', region_id=r1, dept='75', city='Paris')) self.db.add_icu( self.admin_id, store.ICU(name='icu3', region_id=r1, dept='92', city='Clamart')) self.db.add_icu( self.admin_id, store.ICU(name='icu4', region_id=r1, dept='93', city='Bobigny')) self.db.add_icu( self.admin_id, store.ICU(name='icu5', region_id=r1, dept='93', city='Saint-Denis')) self.db.add_icu( self.admin_id, store.ICU(name='icu6', region_id=r1, dept='94', city='Vitry')) self.db.add_icu( self.admin_id, store.ICU(name='icu7', region_id=r1, dept='94', city='Creteil')) self.db.add_icu( self.admin_id, store.ICU(name='icu8', region_id=r1, dept='94', city='Creteil')) self.db.add_icu( self.admin_id, store.ICU(name='icu9', region_id=r2, dept='13', city='Marseille')) self.icus = self.db.get_icus() self.regions = self.db.get_regions() self.insert_time = datetime.datetime(2020, 4, 8, 11, 13) # Adding bedcounts: here we cheat a bit since we insert zeros counts # to have those bedcounts on the map and simplify the maths. for icu in self.icus: count = store.BedCount(icu_id=icu.icu_id, create_date=self.insert_time) self.db.update_bed_count_for_icu(self.admin_id, count)
def migrate_bedcounts(self): # From oldest to newest counts df = self.old_db.get_bedcount( get_history=True).sort_values('update_ts') logging.info('migrating {} bedcounts'.format(df.shape[0])) new_icus = {i.name: i for i in self.new_db.get_icus()} for _, bc_row in df.iterrows(): counts = bc_row.to_dict() icu_name = counts.pop('icu_name', None) counts['last_modified'] = datetime.fromtimestamp( counts.pop('update_ts')) counts['create_date'] = counts['last_modified'] new_bedcount = store.BedCount(**counts) self.new_db.update_bed_count_for_icu(None, new_bedcount, force=True)
def prepare_data(self, icu) -> list: result = [{ 'key': 'icu (update link)', 'value': icu.name, 'link': self.link_fn(icu.icu_id, icu.name) }] bed_count = icu.bed_counts[-1] if icu.bed_counts else store.BedCount() bed_count_dict = bed_count.to_dict(max_depth=0) locale = self.get_user_locale() last = bed_count_dict.pop('last_modified', None) last = None if last is None else last.timestamp() for key in ['rowid', 'icu_id', 'message', 'create_date', 'icu']: bed_count_dict.pop(key, None) bed_count_dict['since_update'] = time_utils.localewise_time_ago( last, locale=locale) result.extend(self.format_list_item(bed_count_dict)) return result
def test_account_for_beds(self): tree = icu_tree.ICUTree() bd = store.BedCount(n_covid_occ=34, n_covid_free=6) tree.account_for_beds(bd) self.assertEqual(tree.total, 40)