def handle_publish_event()

in microservices/learning_object_service/src/services/content_version_handler.py [0:0]


def handle_publish_event(linked_lr_uuid, content_version_uuid):
  """
        This function publishes a particular learning resource.
        When a document is published, it is connected to the
        hierarchy and replaces old document. The status of all
        previous documents is set as unpublished and the new one
        is marked as published.
        -------------------------------------------------------------
        Input:
            linked_lr_uuid: `str`
                This is the uuid of the learning resource
                which is currently connected to the hierarchy.
            content_version_uuid: `str`
                This is the uuid of the learning resource
                which should be marked as published.
                If the content_version_uuid is not passed, then
                the document will be published against itself if its
                a draft. Otherwise an error will be thrown that we
                cannot publish an document that is currently published.
        -------------------------------------------------------------
        Output:
            published_content_dict: `dict`
                This will be the dict of the published LR document.
                All the other versions of the LR Contents will be marked
                as unpublished.
    """
  try:

    connected_lr = LearningResource.find_by_uuid(linked_lr_uuid)
    connected_lr_dict = connected_lr.get_fields(reformat_datetime=True)

    # verify connected_lr
    parent_nodes = connected_lr_dict.get("parent_nodes")\
                    .get("learning_objects")
    if parent_nodes is not None:
      for node_id in parent_nodes:
        parent_node = LearningObject.find_by_uuid(node_id).get_fields(
            reformat_datetime=True)
        child_nodes = parent_node.get("child_nodes").get("learning_resources")
        if child_nodes is not None:
          if connected_lr.uuid not in child_nodes:
            raise ValidationError(
                "Given resource uuid is not connected to a valid parent")

    # Publish timestamp
    publish_timestamp = datetime.now()

    if content_version_uuid is None or \
      content_version_uuid == linked_lr_uuid:

      unpublish_other_versions(connected_lr.uuid)

      # Validate if user is trying to publish the same document
      if connected_lr.status == "published":
        raise ValidationError(
            "Cannot publish content that is currently published.")

      # pylint: disable = line-too-long
      if connected_lr.resource_path == "":
        raise ValidationError(
          f"resource_path is empty for Learning Resource with uuid {linked_lr_uuid}"
        )

      # publish the connected LR
      connected_lr.status = "published"
      connected_lr.last_published_on = publish_timestamp
      connected_lr.update()

      return connected_lr.get_fields(reformat_datetime=True)
    else:
      lr_doc = LearningResource.find_by_uuid(content_version_uuid)

      if lr_doc.status == "initial" and \
        lr_doc.resource_path == "":
        raise ValidationError(
          "Resource path cannot be empty for a resource to be published"
        )

      unpublish_other_versions(content_version_uuid)

      # Validate if user is trying to publish the same document
      if lr_doc.status == "published":
        raise ValidationError(
            "Cannot publish content that is currently published.")

      connected_published_document = None

      if lr_doc.status == "unpublished":
        # Handle republish scenario
        # ---------------------------------------

        resource_path = lr_doc.resource_path
        resource_type = lr_doc.type
        parent_uuid = content_version_uuid

        # Create a versioned document
        new_lr = UpdateLearningResourceModel(
            resource_path=resource_path, type=resource_type)
        new_lr_dict = new_lr.dict()
        new_document = CommonAPIHandler.create_versioned_document(
            LearningResource, parent_uuid, new_lr_dict)
        new_document_obj = LearningResource.find_by_uuid(new_document["uuid"])
        new_document_obj.status = "published"
        new_document_obj.is_implicit = True
        new_document_obj.last_published_on = publish_timestamp
        new_document_obj.update()

        # pylint: disable = line-too-long
        # connected_published_document = new_document_obj.get_fields(reformat_datetime=True)

        published_document = new_document_obj.get_fields(reformat_datetime=True)
        connected_document = connected_lr.get_fields(reformat_datetime=True)

        connected_published_document = update_hierarchy_references(
            connected_document, published_document, LearningResource)

        lazy_sync(new_document_obj.uuid, connected_lr.uuid)
      else:
        # Handle simple publish scenario
        # ---------------------------------------

        if lr_doc.resource_path == "":
          raise ValidationError(
            f"Resource Path is empty for Learning resource with uuid {lr_doc.uuid}"
          )

        # Publish required document
        lr_doc.status = "published"
        lr_doc.last_published_on = publish_timestamp
        lr_doc.update()

        published_document = lr_doc.get_fields(reformat_datetime=True)
        connected_document = connected_lr.get_fields(reformat_datetime=True)

        connected_published_document = update_hierarchy_references(
            connected_document, published_document, LearningResource)

        lazy_sync(lr_doc.uuid, connected_lr.uuid)

      return connected_published_document

  except ResourceNotFoundException as e:
    raise ResourceNotFound(str(e)) from e
  except ValidationError as e:
    raise BadRequest(str(e)) from e
  except InternalServerError as e:
    raise InternalServerException(str(e)) from e