def __init__(self, db_settings, testing=False): self.testing = testing self.engine = create_engine( URL(**db_settings), isolation_level="SERIALIZABLE", # As we don't have a lot of IO, we can afford the highest isolation. echo=False, # Echo the SQL queries if testing. NOTE: removed, this breaks the tests pool_pre_ping=True, # Make sure the connection is OK before using it. ) # noinspection PyArgumentEqualDefault self.session_maker = sessionmaker( bind=self.engine, autoflush=True, # Flush at each query so that we can see our changes in the current session. autocommit=False, # Never auto-commit, we want proper transactions! ) if testing: self.session_maker = scoped_session(self.session_maker) # If testing, drop all tables & recreate them Base.metadata.drop_all(self.engine) Base.metadata.create_all(self.engine) else: # Create NainA table if not exists. (The other tables should already exist.) for retries in range(Database.RETRY_COUNT): try: LOG.info("connecting_to_database") Base.metadata.create_all( self.engine, tables=[NainA.__table__] ) LOG.info("connection_established") LOG.info("table_created") except OperationalError as e: LOG.warning("could_not_connect_to_database", extra={'exception': e}) if retries + 1 == Database.RETRY_COUNT: raise time.sleep(Database.RETRY_INTERVAL)
def get_logs(self, ctx, username) -> List[str]: """ User story: As an admin, I can retrieve the logs of a member, so I can help him troubleshoot their connection issues. :raise MemberNotFound """ # Fetch all the devices of the member to put them in the request # all_devices = get_all_devices(s) # q = s.query(all_devices, Adherent.login.label("login")) # q = q.join(Adherent, Adherent.id == all_devices.columns.adherent_id) # q = q.filter(Adherent.login == username) # mac_tbl = list(map(lambda x: x.mac, q.all())) # Check that the user exists in the system. result, _ = self.member_repository.search_member_by(ctx, username=username) if not result: raise MemberNotFoundError(username) # Do the actual log fetching. try: # TODO: Fetch all the devices and put them into this request. logs = self.logs_repository.get_logs(ctx, username, []) LOG.info('member_get_logs', extra=log_extra( ctx, username=username, )) return logs except LogFetchError: LOG.warning("log_fetch_failed", extra=log_extra(ctx, username=username)) return [] # We fail open here.
def new_membership(self, ctx, username, duration, payment_method, start_str=None) -> None: """ Core use case of ADH. Registers a membership. User story: As an admin, I can create a new membership record, so that a member can have internet access. :param payment_method: :param ctx: context :param username: username :param duration: duration of the membership in days :param start_str: optional start date of the membership :raise IntMustBePositiveException :raise NoPriceAssignedToThatDurationException :raise MemberNotFound :raise InvalidAdmin :raise UnknownPaymentMethod """ if start_str is None: return self.new_membership( ctx, username, duration, payment_method, start_str=datetime.datetime.now().isoformat()) if duration < 0: raise IntMustBePositive('duration') if duration not in self.config.PRICES: LOG.warning("create_membership_record_no_price_defined", extra=log_extra(ctx, duration=duration)) raise NoPriceAssignedToThatDuration(duration) start = string_to_date(start_str) end = start + datetime.timedelta(days=duration) # TODO check price. try: price = self.config.PRICES[duration] # Expresed in EUR. price_in_cents = price * 100 # Expressed in cents of EUR. duration_str = self.config.DURATION_STRING.get(duration, '') title = f'Internet - {duration_str}' self.money_repository.add_member_payment_record( ctx, price_in_cents, title, username, payment_method) self.membership_repository.create_membership( ctx, username, start, end) self.member_repository.update_member( ctx, username, departure_date=end.isoformat()) except InvalidAdmin: LOG.warning("create_membership_record_admin_not_found", extra=log_extra(ctx)) raise except UnknownPaymentMethod: LOG.warning("create_membership_record_unknown_payment_method", extra=log_extra(ctx, payment_method=payment_method)) raise LOG.info("create_membership_record", extra=log_extra(ctx, username=username, duration_in_days=duration, start_date=start.isoformat()))