Exemple #1
0
def _get_derived_website_content_data(request_data: dict,
                                      site_config: SiteConfig,
                                      website_pk: str) -> dict:
    """Derives values that should be added to the request data if a WebsiteContent object is being created"""
    added_data = {}
    if "text_id" not in request_data:
        added_data["text_id"] = uuid_string()
    content_type = request_data.get("type")
    config_item = (site_config.find_item_by_name(
        name=content_type) if content_type is not None else None)
    is_page_content = False
    if site_config and config_item is not None:
        is_page_content = site_config.is_page_content(config_item)
        added_data["is_page_content"] = is_page_content
    dirpath = request_data.get("dirpath")
    if dirpath is None and config_item is not None and is_page_content:
        dirpath = config_item.file_target
        added_data["dirpath"] = dirpath
    slug_key = config_item.item.get(
        "slug") if config_item is not None else None
    if not slug_key:
        slug_key = "title"
    slug = (added_data.get(slug_key) or request_data.get(slug_key)
            or request_data.get("metadata", {}).get(slug_key))
    if slug is not None:
        added_data["filename"] = get_valid_new_filename(
            website_pk=website_pk,
            dirpath=dirpath,
            filename_base=slugify(get_valid_base_filename(slug, content_type)),
        )
    return added_data
Exemple #2
0
 def for_content(
         site_config: SiteConfig,
         website_content: WebsiteContent) -> BaseContentFileSerializer:
     """
     Given a WebsiteContent object and site config, returns a serializer object of the correct type for
     serializing the WebsiteContent object into file contents.
     """
     if website_content.is_page_content:
         return HugoMarkdownFileSerializer(site_config=site_config)
     config_item = site_config.find_item_by_name(website_content.type)
     destination_filepath = config_item.file_target
     if not destination_filepath:
         raise ValueError(
             f"WebsiteContent object is not page content, but has no 'file' destination in config ({website_content.text_id})."
         )
     file_ext = get_file_extension(destination_filepath)
     if file_ext == "json":
         cls = JsonFileSerializer
     elif file_ext in {"yml", "yaml"}:
         # HACK: Hugo-specific logic for properly transforming data if the "menu" widget is used
         if _has_menu_fields(config_item):
             cls = HugoMenuYamlFileSerializer
         else:
             cls = YamlFileSerializer
     else:
         raise ValueError(
             f"Website content cannot be serialized to a file ({website_content.text_id})."
         )
     return cls(site_config=site_config)
Exemple #3
0
def _transform_hugo_menu_data(website_content: WebsiteContent,
                              site_config: SiteConfig) -> dict:
    """
    Adds 'url' property to internal links in menu data.

    Returns the dict of all values that will be serialized to the target file, including the transformed
    "menu" fields.
    """
    config_item = site_config.find_item_by_name(website_content.type)
    menu_fields = {
        field["name"]
        for field in config_item.fields
        if field.get("widget") == CONTENT_MENU_FIELD
    }
    transformed_menu_fields = {}
    for field_name, field_data in website_content.metadata.items():
        if field_name not in menu_fields:
            continue
        uuid_content_map = _get_uuid_content_map(field_data)
        result_menu_items = []
        for menu_item in field_data:
            updated_menu_item = menu_item
            # Add/update the 'url' value if this is an internal link
            if menu_item["identifier"] in uuid_content_map:
                menu_item_content = uuid_content_map[menu_item["identifier"]]
                updated_menu_item["url"] = get_destination_url(
                    menu_item_content, site_config)
            result_menu_items.append(updated_menu_item)
        transformed_menu_fields[field_name] = result_menu_items
    return {**website_content.metadata, **transformed_menu_fields}
def test_find_config_item_name_singleton(basic_site_config):
    """SiteConfig.find_item_by_name should return a singleton config item if one is found with the given name"""
    site_config = SiteConfig(basic_site_config)
    config_item = next(item for item in site_config.iter_items()
                       if item.is_file_item())
    assert config_item is not None
    assert site_config.find_item_by_name(config_item.name) == config_item
    assert site_config.find_item_by_name("other-name-123") is None
Exemple #5
0
def create_gdrive_resource_content(drive_file: DriveFile):
    """Create a WebsiteContent resource from a Google Drive file"""
    try:
        resource_type = get_resource_type(drive_file.s3_key)
        resource = drive_file.resource
        if not resource:
            site_config = SiteConfig(drive_file.website.starter.config)
            config_item = site_config.find_item_by_name(
                name=CONTENT_TYPE_RESOURCE)
            dirpath = config_item.file_target if config_item else None
            basename, _ = os.path.splitext(drive_file.name)

            filename = get_valid_new_filename(
                website_pk=drive_file.website.pk,
                dirpath=dirpath,
                filename_base=slugify(
                    get_valid_base_filename(basename, CONTENT_TYPE_RESOURCE)),
            )
            resource_type_fields = {
                field: resource_type
                for field in settings.RESOURCE_TYPE_FIELDS
            }
            resource = WebsiteContent.objects.create(
                website=drive_file.website,
                title=drive_file.name,
                file=drive_file.s3_key,
                type=CONTENT_TYPE_RESOURCE,
                is_page_content=True,
                dirpath=dirpath,
                filename=filename,
                metadata={
                    **SiteConfig(drive_file.website.starter.config).generate_item_metadata(
                        CONTENT_TYPE_RESOURCE,
                        cls=WebsiteContent,
                        file_type=drive_file.mime_type,
                        **resource_type_fields,
                    )
                },
            )
        else:
            resource.file = drive_file.s3_key
            resource.save()
        drive_file.resource = resource
        drive_file.update_status(DriveFileStatus.COMPLETE)
    except:  # pylint:disable=bare-except
        log.exception("Error creating resource for drive file %s",
                      drive_file.file_id)
        drive_file.sync_error = (
            f"Could not create a resource from google drive file {drive_file.name}"
        )
        drive_file.update_status(DriveFileStatus.FAILED)
Exemple #6
0
def get_destination_filepath(content: WebsiteContent,
                             site_config: SiteConfig) -> Optional[str]:
    """
    Returns the full filepath where the equivalent file for the WebsiteContent record should be placed
    """
    if content.is_page_content:
        return os.path.join(content.dirpath,
                            f"{content.filename}.{WEBSITE_CONTENT_FILETYPE}")
    config_item = site_config.find_item_by_name(name=content.type)
    if config_item is None:
        log.error(
            "Config item not found (content: %s, name value missing from config: %s)",
            (content.id, content.text_id),
            content.type,
        )
        return None
    if config_item.is_file_item():
        return config_item.file_target
    log.error(
        "Invalid config item: is_page_content flag is False, and config item is not 'file'-type (content: %s)",
        (content.id, content.text_id),
    )
    return None
Exemple #7
0
 def get_config_file_field(self) -> Dict:
     """Get the site config file field for the object, if any"""
     site_config = SiteConfig(self.website.starter.config)
     content_config = site_config.find_item_by_name(self.type)
     if content_config:
         return site_config.find_file_field(content_config)