def update(csv_file, add_missing, dry_run): """Update the Burotels from a CSV file.""" num_changes = 0 num_adds = 0 num_removes = 0 r = csv.reader(csv_file) valid_ids = {id_ for id_, in db.session.query(Room.id)} for room_id, division, building, floor, number, verbose_name, owner_email, acl_row, action in r: owner = get_user(owner_email) acl = {get_principal(principal) for principal in acl_row.split(';')} if acl_row else None data = { 'id': int(room_id.decode('utf-8-sig')) if room_id else None, 'division': division, 'building': building, 'floor': floor, 'number': number, 'verbose_name': verbose_name, 'owner': owner, 'acl_entries': ({owner} | acl) if acl else {owner}, 'action': action or 'UPDATE' } if not data['id'] and action != 'ADD': print(cformat('%{yellow}! Only ADD lines can have an empty Desk ID. Ignoring line.')) continue if add_missing and data['action'] == 'UPDATE' and data['id'] not in valid_ids: data['action'] = 'ADD' print(cformat('%{yellow}! Desk with ID {} not found; adding it.').format(room_id)) if data['action'] == 'UPDATE': room = get_room(room_id) if not room: continue changes = check_changed_fields(room, data) if changes: num_changes += 1 _print_changes(room, changes) if not dry_run: change_room(room, changes) elif data['action'] == 'ADD': existing_room = Room.query.filter(Room.building == building, Room.floor == floor, Room.number == number, Room.verbose_name == verbose_name).first() if existing_room: # a room with the exact same designation already exists print(cformat("%{yellow}!%{reset} A desk with the name %{cyan}{}%{reset} already exists") .format(existing_room.full_name)) continue print(cformat("%{green!}+%{reset} New desk %{cyan}{}/{}-{} {}").format( building, floor, number, verbose_name)) num_adds += 1 if not dry_run: room = Room(building=building, floor=floor, number=number, division=division, verbose_name=verbose_name, owner=owner, location=get_location(building), protection_mode=ProtectionMode.protected, reservations_need_confirmation=True) room.update_principal(owner, full_access=True) if acl: for principal in acl: room.update_principal(principal, full_access=True) db.session.add(room) elif data['action'] == 'REMOVE': room = get_room(room_id) if not room: continue print(cformat('%{red}-%{reset} {}').format(room.full_name)) if not dry_run: room.is_deleted = True num_removes += 1 print((cformat('\n%{cyan}Total:%{reset} %{green}+%{reset}{} %{yellow}\u00b1%{reset}{} %{red}-%{reset}{} ') .format(num_adds, num_changes, num_removes))) if not dry_run: db.session.commit()
def fetch_rooms(self, connection, room_name=None): self._logger.debug("Fetching room information...") counter = Counter() foundation_rooms = [] coordinates = self.fetch_buildings_coordinates(connection) cursor = connection.cursor() if room_name: cursor.execute( 'SELECT * FROM foundation_pub.meeting_rooms WHERE ID = :room_name', room_name=room_name) else: cursor.execute( 'SELECT * FROM foundation_pub.meeting_rooms ORDER BY ID') for row in cursor: counter['found'] += 1 data = self._prepare_row(row, cursor) room_id = data['ID'] try: room_data, email_warning = self._parse_room_data( data, coordinates, room_id) manager_group = data.get('EMAIL_LIST') self._logger.debug("Fetched data for room with id='%s'", room_id) except SkipRoom as e: counter['skipped'] += 1 self._logger.info("Skipped room %s: %s", room_id, e) continue room = Room.query.filter_by(building=room_data['building'], floor=room_data['floor'], number=room_data['number'], location=self._location).first() if room_data['owner'] is None: del room_data['owner'] if room is None: counter['skipped'] += 1 self._logger.info("Skipped room %s: %s", room_id, email_warning[0] % email_warning[1:]) continue elif not room.is_deleted: self._logger.warning(*email_warning) # Insert new room if room is None: room = Room() self._location.rooms.append(room) counter['inserted'] += 1 self._logger.info("Created new room '%s'", room_id) else: counter['updated'] += 1 # Update room data self._update_room(room, room_data) new_managers = set() if manager_group is not None: group = GroupProxy(manager_group.strip(), provider='cern-ldap') if group.group is None: self._logger.warning("Group '%s' does not exist in LDAP", manager_group) new_managers.add(group) current_managers = room.get_manager_list() for principal in current_managers - new_managers: room.update_principal(principal, full_access=False) for principal in new_managers - current_managers: room.update_principal(principal, full_access=True) self._logger.info("Updated room '%s' information", room_id) foundation_rooms.append(room) # Deactivate rooms not found in Foundation indico_rooms = Room.find( Room.name == room_name) if room_name else Room.find( location=self._location) rooms_to_deactivate = ( room for room in indico_rooms if room not in foundation_rooms and not room.is_deleted) for room in rooms_to_deactivate: self._logger.info("Deactivated room '%s'", room.full_name) room.is_deleted = True counter['deactivated'] += 1 self._logger.info("Deactivated %d rooms not found in Foundation", counter['deactivated']) db.session.commit() self._logger.info( "Rooms summary: %d in Foundation - %d skipped - %d inserted - %d updated - %d deactivated", counter['found'], counter['skipped'], counter['inserted'], counter['updated'], counter['deactivated'])