def run_create_tutorials() -> None:
    fb_db = auth.firebaseDB()
    ref = fb_db.reference("v2/tutorialDrafts/")
    tutorial_drafts = ref.get()

    if tutorial_drafts is None:
        logger.info("There are no tutorial drafts in firebase.")
        return None

    for tutorial_draft_id, tutorial_draft in tutorial_drafts.items():
        tutorial_draft["tutorialDraftId"] = tutorial_draft_id
        project_type = tutorial_draft["projectType"]
        project_name = tutorial_draft["name"]

        try:
            tutorial = ProjectType(project_type).tutorial(tutorial_draft)
            tutorial.create_tutorial_groups()
            tutorial.create_tutorial_tasks()
            tutorial.save_tutorial()
            send_slack_message(MessageType.SUCCESS, project_name,
                               tutorial.projectId)
            logger.info(f"Success: Tutorial Creation ({project_name})")
        except CustomError:
            ref = fb_db.reference(f"v2/tutorialDrafts/{tutorial_draft_id}")
            ref.set({})
            send_slack_message(MessageType.FAIL, project_name,
                               tutorial.projectId)
            logger.exception(
                "Failed: Project Creation ({0}))".format(project_name))
            sentry.capture_exception()
        continue
def run_create_projects():
    """
    Create projects from submitted project drafts.

    Get project drafts from Firebase.
    Create projects with groups and tasks.
    Save created projects, groups and tasks to Firebase and Postgres.
    """

    fb_db = auth.firebaseDB()
    ref = fb_db.reference("v2/projectDrafts/")
    project_drafts = ref.get()

    if project_drafts is None:
        logger.info("There are no project drafts in firebase.")
        return None

    for project_draft_id, project_draft in project_drafts.items():
        project_draft["projectDraftId"] = project_draft_id
        project_type = project_draft["projectType"]
        project_name = project_draft["name"]
        try:
            # Create a project object using appropriate class (project type).
            project = ProjectType(project_type).constructor(project_draft)
            # TODO: here the project.geometry attribute is overwritten
            #  this is super confusing since it's not a geojson anymore
            #  but this is what we set initially,
            #  e.g. in tile_map_service_grid/project.py
            #  project.geometry is set to a list of wkt geometries now
            #  this can't be handled in postgres,
            #  postgres expects just a string not an array
            #  validated_geometries should be called during init already
            #  for the respective project types

            project.geometry = project.validate_geometries()
            project.create_groups()
            project.calc_required_results()
            # Save project and its groups and tasks to Firebase and Postgres.
            project.save_project()
            send_slack_message(MessageType.SUCCESS, project_name,
                               project.projectId)
            logger.info("Success: Project Creation ({0})".format(project_name))
        except CustomError as e:
            ref = fb_db.reference(f"v2/projectDrafts/{project_draft_id}")
            ref.set({})

            # check if project could be initialized
            try:
                project_id = project.projectId
            except UnboundLocalError:
                project_id = None

            send_slack_message(MessageType.FAIL, project_name, project_id,
                               str(e))
            logger.exception(
                "Failed: Project Creation ({0}))".format(project_name))
            sentry.capture_exception()
        continue
def set_status_in_firebase(project_id: str, project_name: str,
                           new_status: str) -> None:
    """Change status of a project in Firebase."""
    # change status in firebase
    fb_db = firebaseDB()
    fb_db.reference(f"v2/projects/{project_id}/status").set(new_status)
    logger.info(
        f"set project status to '{new_status}' for project {project_id}")

    # send slack message
    if new_status == "finished":
        send_slack_message(MessageType.PROJECT_STATUS_FINISHED, project_name,
                           project_id)
    elif new_status == "active":
        send_slack_message(MessageType.PROJECT_STATUS_ACTIVE, project_name,
                           project_id)