def wrapper(*args, **kwargs):
        job_description = f"{func.__name__} {args}"
        logger.info(build_job_log_message(job=job_description, status=JobStatus.STARTED))
        result = func(*args, **kwargs)

        logger.info(build_job_log_message(job=job_description, status=JobStatus.ENDED))
        return result
Beispiel #2
0
def log_redis_connection_status():
    try:
        conn.ping()
        logger.info("Worker: redis connection OK")

    except redis.exceptions.ConnectionError as e:
        logger.critical("Worker: redis connection KO: %s", e)
Beispiel #3
0
def save_reimbursable_thing_offer(venue: VenueSQLEntity):
    paid_reimbursable_offer = create_offer_with_thing_product(
        venue, thing_name="Roman cool", thing_type=ThingType.LIVRE_EDITION)
    reimbursable_stock = create_stock(offer=paid_reimbursable_offer, price=30)
    repository.save(reimbursable_stock)
    logger.info("created 1 reimbursable thing offer with 1 paid stock of 30 €")
    return reimbursable_stock
def create_industrial_criteria() -> dict:
    logger.info("create_industrial_criteria")

    criteria_by_name = {}

    criterion1 = Criterion()
    criterion1.name = "Bonne offre d’appel"
    criterion1.description = "Offre déjà beaucoup réservée par les autres jeunes"
    criteria_by_name[criterion1.name] = criterion1

    criterion2 = Criterion()
    criterion2.name = "Mauvaise accroche"
    criterion2.description = "Offre ne possédant pas une accroche de qualité suffisante"
    criteria_by_name[criterion2.name] = criterion2

    criterion3 = Criterion()
    criterion3.name = "Offre de médiation spécifique"
    criterion3.description = "Offre possédant une médiation orientée pour les jeunes de 18 ans"
    criteria_by_name[criterion3.name] = criterion3

    repository.save(*criteria_by_name.values())

    logger.info("created %d criteria", len(criteria_by_name))

    return criteria_by_name
def get_zip_file_from_ftp(zip_file_name: str, folder_name: str) -> ZipFile:
    data_file = BytesIO()
    data_file.name = zip_file_name
    file_path = "RETR " + folder_name + "/" + zip_file_name
    logger.info("Downloading file %s", file_path)
    connect_to_titelive_ftp().retrbinary(file_path, data_file.write)
    return ZipFile(data_file, "r")
Beispiel #6
0
def create_industrial_thing_stocks(thing_offers_by_name):
    logger.info("create_industrial_thing_stocks")

    thing_stocks_by_name = {}
    short_names_to_increase_price = []

    thing_offer_items = list(thing_offers_by_name.items())

    thing_offer_items_with_stocks = remove_every(thing_offer_items, THING_OFFERS_WITH_STOCK_REMOVE_MODULO)

    for thing_offer_item_with_stocks in thing_offer_items_with_stocks:
        (thing_offer_with_stocks_name, thing_offer_with_stocks) = thing_offer_item_with_stocks
        quantity = 20

        short_name = get_occurrence_short_name(thing_offer_with_stocks_name)
        price = get_price_by_short_name(short_name)
        price_counter = short_names_to_increase_price.count(short_name)
        if price_counter > 2:
            price = price + price_counter
        short_names_to_increase_price.append(short_name)

        name = thing_offer_with_stocks_name + " / " + str(quantity) + " / " + str(price)
        thing_stocks_by_name[name] = create_stock_from_offer(thing_offer_with_stocks, quantity=quantity, price=price)

    repository.save(*thing_stocks_by_name.values())

    logger.info("created %d thing_stocks", len(thing_stocks_by_name))
def send_payments_details(payments: List[Payment],
                          recipients: List[str]) -> None:
    if not recipients:
        raise Exception(
            "[BATCH][PAYMENTS] Missing PASS_CULTURE_PAYMENTS_DETAILS_RECIPIENTS in environment variables"
        )

    if all(
            map(lambda x: x.currentStatus.status == TransactionStatus.ERROR,
                payments)):
        logger.warning(
            "[BATCH][PAYMENTS] Not sending payments details as all payments have an ERROR status"
        )
    else:
        details = create_all_payments_details(payments)
        csv = generate_payment_details_csv(details)
        logger.info("[BATCH][PAYMENTS] Sending %s details of %s payments",
                    len(details), len(payments))
        logger.info("[BATCH][PAYMENTS] Recipients of email : %s", recipients)
        try:
            send_payment_details_email(csv, recipients)
        except MailServiceException as exception:
            logger.exception(
                "[BATCH][PAYMENTS] Error while sending payment details email to MailJet: %s",
                exception)
Beispiel #8
0
def create_industrial_pro_users(offerers_by_name: Dict) -> Dict:
    logger.info("create_industrial_pro_users")

    users_by_name = {}

    offerers = list(offerers_by_name.values())

    for index, departement_code in enumerate(departement_codes):

        for pro_count in range(PROS_COUNT):
            email = "pctest.pro{}.{}@example.com".format(
                departement_code, pro_count)
            user = create_user(
                reset_password_token_validity_limit=datetime.utcnow() +
                timedelta(hours=24),
                is_beneficiary=False,
                date_of_birth=None,
                departement_code=str(departement_code),
                email=email,
                first_name="PC Test Pro",
                is_admin=False,
                last_name="{} {}".format(departement_code, pro_count),
                postal_code="{}100".format(departement_code),
                public_name="PC Test Pro {} {}".format(departement_code,
                                                       pro_count),
            )
            users_by_name["pro{} {}".format(departement_code,
                                            pro_count)] = user
            UserOffererFactory(offerer=offerers[index], user=user)

    repository.save(*users_by_name.values())

    logger.info("created %d users", len(users_by_name))

    return users_by_name
Beispiel #9
0
def create_industrial_bookings(offers_by_name, users_by_name):
    logger.info("create_industrial_bookings")

    bookings_by_name = {}

    list_of_users_with_no_more_money = []

    token = 100000

    active_offers_with_stocks = {
        booking_key: offer
        for booking_key, offer in offers_by_name.items()
        if offer.venue.managingOfferer.isValidated is True
        and len(offer.stocks) > 0
    }

    for (user_name, user) in users_by_name.items():
        if (user.firstName != "PC Test Jeune" or "has-signed-up" in user_name
                or "has-filled-cultural-survey" in user_name):
            continue

        if "has-booked-some" in user.email:
            _create_has_booked_some_bookings(bookings_by_name,
                                             active_offers_with_stocks, user,
                                             user_name)
        else:
            token = _create_bookings_for_other_beneficiaries(
                bookings_by_name, list_of_users_with_no_more_money,
                active_offers_with_stocks, token, user, user_name)

    repository.save(*bookings_by_name.values())

    logger.info("created %d bookings", len(bookings_by_name))
Beispiel #10
0
def cancel_banned_bookings() -> None:
    logger.info("[CANCEL BANNED BOOKINGS] START")
    bookings_to_update = get_bookings_banned_and_sent()
    bookings_in_error = []
    updated_bookings = []

    for booking in bookings_to_update:
        booking.isCancelled = True
        booking.isUsed = False
        booking.dateUsed = None
        try:
            repository.save(booking)
            updated_bookings.append(booking.id)
        except ApiErrors as error:
            logger.exception("%s for booking %s", error.errors, booking.id)
            bookings_in_error.append(booking.id)

    logger.info("%i BOOKINGS UPDATED", len(updated_bookings))
    logger.info("LIST OF UPDATED BOOKINGS")
    logger.info(updated_bookings)

    if len(bookings_in_error) > 0:
        logger.error("LIST OF BOOKINGS IN ERROR")
        logger.error(bookings_in_error)

    logger.info("[CANCEL BANNED BOOKINGS] END")
def create_industrial_venue_types() -> List[VenueType]:
    logger.info("create_industrial_venue_types")

    labels = [
        "Arts visuels, arts plastiques et galeries",
        "Centre culturel",
        "Cours et pratique artistiques",
        "Culture scientifique",
        "Festival",
        "Jeux / Jeux vidéos",
        "Librairie",
        "Bibliothèque ou médiathèque",
        "Musée",
        "Musique - Disquaire",
        "Musique - Magasin d’instruments",
        "Musique - Salle de concerts",
        "Offre numérique",
        "Patrimoine et tourisme",
        "Cinéma - Salle de projections",
        "Spectacle vivant",
        "Autre",
    ]

    venue_types = [create_venue_type(label=label) for label in labels]

    repository.save(*venue_types)

    logger.info("created %i venue types", len(venue_types))

    return venue_types
Beispiel #12
0
def create_industrial_admin_users():
    logger.info("create_industrial_admin_users")

    users_by_name = {}

    for departement_code in departement_codes:

        for admin_count in range(ADMINS_COUNT):
            email = "pctest.admin{}.{}@btmx.fr".format(departement_code,
                                                       admin_count)
            users_by_name["admin{} {}".format(
                departement_code, admin_count)] = create_user(
                    reset_password_token_validity_limit=datetime.utcnow() +
                    timedelta(hours=24),
                    is_beneficiary=False,
                    date_of_birth=None,
                    departement_code=str(departement_code),
                    email=email,
                    first_name="PC Test Admin",
                    is_admin=True,
                    last_name="{} {}".format(departement_code, admin_count),
                    postal_code="{}100".format(departement_code),
                    public_name="PC Test Admin {} {}".format(
                        departement_code, admin_count),
                )

    repository.save(*users_by_name.values())

    logger.info("created %d users", len(users_by_name))

    return users_by_name
Beispiel #13
0
def create_industrial_payments():
    logger.info("create_industrial_payments")

    pending_payments, not_processable_payments = generate_new_payments()

    logger.info("created %d payments",
                len(pending_payments + not_processable_payments))
def create_industrial_user_offerers(users_by_name, offerers_by_name):
    logger.info("create_industrial_user_offerers")

    user_offerers_by_name = {}

    # special validation
    user = users_by_name["pro93 real-validation"]
    offerer = offerers_by_name["414819409 lat:48.8 lon:1.48"]
    user_offerers_by_name["pro93 real-validation / 414819409 lat:48.8 lon:1.48"] = create_user_offerer(
        offerer=offerer, user=user
    )

    # loop on users
    for (user_name, user) in users_by_name.items():

        for (offerer_name, offerer) in offerers_by_name.items():

            if (
                PostalCode(offerer.postalCode).get_departement_code() != user.departementCode
                or "real-validation" in user_name
            ):
                continue

            user_offerers_by_name["{} / {}".format(user_name, offerer_name)] = create_user_offerer(
                offerer=offerer, user=user
            )

    repository.save(*user_offerers_by_name.values())

    logger.info("created %d user_offerers", len(user_offerers_by_name))

    return user_offerers_by_name
Beispiel #15
0
def _run_indexing(client: Redis, venue_provider: Dict) -> None:
    venue_provider_id = venue_provider["id"]
    provider_id = venue_provider["providerId"]
    venue_id = venue_provider["venueId"]

    run_algolia_venue_provider_command = (
        f"python src/pcapi/scripts/pc.py process_venue_provider_offers_for_algolia "
        f"--provider-id {provider_id} "
        f"--venue-provider-id {venue_provider_id} "
        f"--venue-id {venue_id}")
    try:
        container_id = run_process_in_one_off_container(
            run_algolia_venue_provider_command)
        add_venue_provider_currently_in_sync(
            client=client,
            container_id=container_id,
            venue_provider_id=venue_provider_id)
        logger.info(
            "[ALGOLIA][Worker] Indexing offers from VenueProvider %s in container %s",
            venue_provider_id, container_id)
    except ScalingoApiException as error:
        logger.exception(
            "[ALGOLIA][Worker] Error indexing offers from VenueProvider %s with errors: %s",
            venue_provider_id,
            error,
        )
Beispiel #16
0
def create_industrial_event_stocks(event_occurrences_by_name):
    logger.info("create_industrial_event_stocks")

    event_stocks_by_name = {}
    short_names_to_increase_price = []

    event_occurrence_items = list(event_occurrences_by_name.items())

    event_occurrence_items_with_stocks = remove_every(
        event_occurrence_items, EVENT_OCCURRENCES_WITH_STOCKS_REMOVE_MODULO
    )

    for event_occurrence_item_with_stocks in event_occurrence_items_with_stocks:
        (event_occurrence_with_stocks_name, event_occurrence_with_stocks) = event_occurrence_item_with_stocks
        available = 10

        short_name = get_occurrence_short_name(event_occurrence_with_stocks_name)
        price = get_price_by_short_name(short_name)
        price_counter = short_names_to_increase_price.count(short_name)
        if price_counter > 2:
            price = price + price_counter
        short_names_to_increase_price.append(short_name)

        if event_occurrence_with_stocks["offer"].product.offerType["value"] == str(EventType.ACTIVATION):
            price = 0

        name = event_occurrence_with_stocks_name + " / " + str(available) + " / " + str(price)

        event_stocks_by_name[name] = create_stock_from_event_occurrence(
            event_occurrence_with_stocks, price=price, quantity=available
        )

    repository.save(*event_stocks_by_name.values())

    logger.info("created %d event_stocks", len(event_stocks_by_name))
Beispiel #17
0
def create_beneficiary_user() -> User:
    import_status = ImportStatus.CREATED
    beneficiary_user = create_user(email=f"{str(import_status)}@email.com")

    repository.save(beneficiary_user)
    logger.info("created 1 beneficiary user")

    return beneficiary_user
Beispiel #18
0
def create_industrial_webapp_users():
    logger.info("create_industrial_webapp_users")

    users_by_name = {}

    validation_prefix, validation_suffix = "AZERTY", 123
    validation_suffix += 1

    for departement_code in departement_codeS:

        for tag in WEBAPP_TAGS:
            short_tag = "".join([chunk[0].upper() for chunk in tag.split("-")])

            if tag == "has-signed-up":
                reset_password_token = "{}{}".format(validation_prefix,
                                                     validation_suffix)
                validation_suffix += 1
            else:
                reset_password_token = None

            cultural_survey_id = None
            needs_to_fill_cultural_survey = False
            has_seen_tutorials = True

            if tag == "has-filled-cultural-survey":
                has_seen_tutorials = False

            if tag == "has-signed-up":
                cultural_survey_id = uuid.uuid4()
                needs_to_fill_cultural_survey = True
                has_seen_tutorials = False

            email = "pctest.jeune{}.{}@btmx.fr".format(departement_code, tag)

            users_by_name["jeune{} {}".format(
                departement_code, tag
            )] = create_user(
                cultural_survey_id=cultural_survey_id,
                departement_code=str(departement_code),
                email=email,
                first_name="PC Test Jeune",
                date_of_birth=datetime(2003, 1, 1),
                has_seen_tutorials=has_seen_tutorials,
                last_name="{} {}".format(departement_code, short_tag),
                needs_to_fill_cultural_survey=needs_to_fill_cultural_survey,
                postal_code="{}100".format(departement_code),
                public_name="PC Test Jeune {} {}".format(
                    departement_code, short_tag),
                reset_password_token=reset_password_token,
                reset_password_token_validity_limit=datetime.utcnow() +
                timedelta(hours=24),
            )

    repository.save(*users_by_name.values())

    logger.info("created %d users", len(users_by_name))

    return users_by_name
Beispiel #19
0
def create_industrial_algolia_indexed_objects() -> None:
    if settings.ALGOLIA_TRIGGER_INDEXATION:
        logger.info("create_industrial_algolia_objects")
        offer_ids = Offer.query.with_entities(Offer.id).all()
        clear_index()
        delete_all_indexed_offers(client=app.redis_client)
        process_eligible_offers(client=app.redis_client,
                                offer_ids=offer_ids,
                                from_provider_update=False)
def save_sandbox(name, with_clean=True):
    if with_clean:
        logger.info("Cleaning database")
        clean_all_database()
        logger.info("All databases cleaned")

    script_name = "sandbox_" + name
    sandbox_module = getattr(scripts, script_name)
    sandbox_module.save_sandbox()
Beispiel #21
0
def _modify_allocine_price_rule_for_venue(
        allocine_venue_provider: AllocineVenueProvider,
        new_price: Decimal) -> None:
    venue_provider_price_rule = AllocineVenueProviderPriceRule.query.filter_by(
        allocineVenueProviderId=allocine_venue_provider.id).one_or_none()
    if venue_provider_price_rule is not None:
        venue_provider_price_rule.price = new_price
        repository.save(venue_provider_price_rule)
        logger.info("Venue priceRule updated")
def _delete_user_offerers_from_rows(csv_rows: Iterable) -> None:
    user_offerers_successful = []
    user_offerers_in_error = []

    csv_rows_iterable = iter(csv_rows)
    headers = next(csv_rows_iterable)
    for row in csv_rows_iterable:
        if _is_blank_row(row):
            continue

        row = dict(zip(headers, row))
        user_id = row[USER_ID_COLUMN_HEADER]
        offerer_id = row[OFFERER_ID_COLUMN_HEADER]

        user_offerer = find_one_or_none_by_user_id_and_offerer_id(
            int(user_id), int(offerer_id))
        if user_offerer is None:
            continue

        user_offerer_id = user_offerer.id

        logger.info(
            "[DELETE USER_OFFERERS FROM FILE] Suppression du rattachement pour le user d'id %s et l'offerer "
            "d'id %s est lancée",
            user_id,
            offerer_id,
        )

        try:
            repository.delete(user_offerer)
            logger.info(
                "[DELETE USER_OFFERERS FROM FILE] Suppression du rattachement pour le user d'id %s et l'offerer "
                "d'id %s réussie",
                user_id,
                offerer_id,
            )
            user_offerers_successful.append(user_offerer_id)
        except ApiErrors as error:
            logger.exception(
                "[DELETE USER_OFFERERS FROM FILE] %s pour le rattachement avec le user d'id %s et l'offerer d'id %s",
                error.errors,
                user_id,
                offerer_id,
            )
            user_offerers_in_error.append(user_offerer_id)

    logger.info("[DELETE USER_OFFERERS FROM FILE] %i RATTACHEMENT SUPPRIMES",
                len(user_offerers_successful))
    logger.info(
        "[DELETE USER_OFFERERS FROM FILE] LISTE DES RATTACHEMENT SUPPRIMES")
    logger.info(user_offerers_successful)

    if len(user_offerers_in_error) > 0:
        logger.error(
            "[DELETE USER_OFFERERS FROM FILE] LISTE DES RATTACHEMENTS EN ERREUR"
        )
        logger.error(user_offerers_in_error)
Beispiel #23
0
    def is_accessible(self):
        authorized = current_user.is_authenticated and current_user.isAdmin

        if authorized:
            logger.info("[ADMIN] Accès autorisé à l'interface d'administation pour %s", current_user)
        else:
            logger.warning("[ADMIN] Tentative d'accès non autorisé à l'interface d'administation par %s", current_user)

        return authorized
Beispiel #24
0
def log_database_connection_status() -> None:
    with app.app_context():
        if check_database_connection():
            logger.info("Worker: database connection OK")
        else:
            logger.critical("Worker: database connection KO")
        db.session.remove()
        db.session.close()
        db.engine.dispose()
Beispiel #25
0
def create_or_update_users(rows: Iterable[dict]) -> List[User]:
    # The purpose of this function is to recreate test users on
    # staging after the staging database is reset. It's not meant to
    # be used anywhere else, and certainly not on production.
    if settings.IS_PROD:
        raise ValueError(
            "This function is not supposed to be run on production")

    users = []
    for row in rows:
        user = find_user_by_email(row["Mail"])
        birthdate = datetime.strptime(row["Date de naissance"], "%Y-%m-%d")
        if user:
            user.dateOfBirth = birthdate
            user.setPassword(settings.STAGING_TEST_USER_PASSWORD)
        else:
            user = users_api.create_account(
                email=row["Mail"],
                password=settings.STAGING_TEST_USER_PASSWORD,
                birthdate=birthdate,
                is_email_validated=True,
                send_activation_mail=False,
            )
            deposit = payments_api.create_deposit(user, "import_users (csv)")
            repository.save(deposit)

        user.isBeneficiary = True
        user.lastName = row["Nom"]
        user.firstName = row["Prénom"]
        user.publicName = f"{user.firstName} {user.lastName}"
        user.phoneNumber = row["Téléphone"]
        user.departementCode = row["Département"]
        user.postalCode = row["Code postal"]
        repository.save(user)

        users.append(user)
        logger.info("Created or updated user=%s from CSV import", user.id)

    admin = find_user_by_email("*****@*****.**")
    if not admin:
        admin = users_api.create_account(
            email="*****@*****.**",
            password=settings.STAGING_TEST_USER_PASSWORD,
            birthdate=datetime(1946, 12, 24),
            is_email_validated=True,
            send_activation_mail=False,
        )
    admin.setPassword(settings.STAGING_TEST_USER_PASSWORD)
    admin.isAdmin = True
    admin.isBeneficiary = False
    admin.firstName = "Jeanne"
    admin.lastName = "Admin"
    admin.publicName = f"{user.firstName} {user.lastName}"
    repository.save(admin)
    logger.info("Created or updated admin user=%s", admin.id)
    return users
Beispiel #26
0
def save_paid_online_book_offer(venue: VenueSQLEntity):
    paid_reimbursable_offer = create_offer_with_thing_product(
        venue,
        thing_name="Roman cool",
        thing_type=ThingType.LIVRE_EDITION,
        url="https://mycoolbook.fr")
    reimbursable_stock = create_stock(offer=paid_reimbursable_offer, price=20)
    repository.save(reimbursable_stock)
    logger.info("created 1 online book offer with 1 paid stock of 20 €")
    return reimbursable_stock
Beispiel #27
0
    def wrapper(*args, **kwargs):
        start_time = time.time()
        logger.info(build_cron_log_message(name=func.__name__, status=CronStatus.STARTED))

        result = func(*args, **kwargs)

        end_time = time.time()
        duration = end_time - start_time
        logger.info(build_cron_log_message(name=func.__name__, status=CronStatus.ENDED, duration=duration))
        return result
Beispiel #28
0
def batch_indexing_offers_in_algolia_by_offer(client: Redis) -> None:
    offer_ids = get_offer_ids(client=client)

    if len(offer_ids) > 0:
        logger.info("[ALGOLIA] processing %i offers...", len(offer_ids))
        process_eligible_offers(client=client,
                                offer_ids=offer_ids,
                                from_provider_update=False)
        delete_offer_ids(client=client)
        logger.info("[ALGOLIA] %i offers processed!", len(offer_ids))
Beispiel #29
0
def get_movies_showtimes(
    api_key: str, theater_id: str, get_movies_showtimes_from_api: Callable = get_movies_showtimes_from_allocine
) -> iter:
    api_response = get_movies_showtimes_from_api(api_key, theater_id)
    movies_showtimes = api_response["movieShowtimeList"]["edges"]
    movies_number = api_response["movieShowtimeList"]["totalCount"]
    filtered_movies_showtimes = _exclude_movie_showtimes_with_special_event_type(movies_showtimes)

    logger.info("[ALLOCINE] Total : %s movies", movies_number)

    return iter(filtered_movies_showtimes)
Beispiel #30
0
def iterate_rows_for_user_offerers(csv_rows: List[List[str]]) -> List:
    user_offerers = []
    for row in csv_rows:
        if _is_header_or_blank_line(row):
            continue

        user_offerer = create_activated_user_offerer(row)
        if user_offerer:
            user_offerers.append(user_offerer)
            logger.info("Enregistrement de %s comptes pro", len(user_offerers))
    return user_offerers