Пример #1
0
def process_image(incontext,
                  root,
                  destination,
                  dirname,
                  basename,
                  category,
                  title_from_filename=True):
    source_path = os.path.join(root, dirname, basename)

    metadata = metadata_for_media_file(root,
                                       os.path.join(dirname, basename),
                                       title_from_filename=title_from_filename)

    name, _ = os.path.splitext(basename)
    name = name.lower()
    destination_path = os.path.join(destination, dirname, name)
    utils.makedirs(destination_path)
    transform_files = []
    transform_metadata = collections.defaultdict(list)
    transforms = evaluate_tests(
        incontext.configuration.media["profiles"]["default"], {
            "basename": os.path.basename(source_path),
            "metadata": metadata
        })
    for transform in transforms:
        transform_extension = extension_for_format(source_path,
                                                   transform.format)
        transform_destination = os.path.join(
            destination_path, transform.basename) + transform_extension
        result = transform.perform(source=source_path,
                                   destination=transform_destination)
        if not isinstance(result, TransformResult):
            raise AssertionError("Invalid result type.")
        transform_files.extend(result.files)
        transform_documents = []
        for document in result.documents:
            document["filename"] = os.path.join(name, document["filename"])
            document["url"] = os.path.join("/", dirname,
                                           name) + document["url"]
            transform_documents.append(document)
        for set in transform.sets:
            transform_metadata[set].extend(transform_documents)

    metadata["category"] = category
    metadata["template"] = "photo.html"  # TODO: Pass this in as a default.
    metadata["path"] = converters.ensure_leading_slash(
        os.path.join(dirname, basename))
    for key, value in transform_metadata.items():
        metadata[key] = value if len(value) > 1 else value[
            0]  # Single arrays should be direct values.
    if metadata["scale"] is None:  # Ensure images have a scale.
        metadata["scale"] = 1

    metadata_document = store.Document(metadata['url'], metadata,
                                       os.path.getmtime(source_path))
    incontext.environment["DOCUMENT_STORE"].add(metadata_document)

    return {'files': transform_files, 'urls': [metadata['url']]}
Пример #2
0
    def inner(path):

        root, dirname, basename = utils.tripple(from_directory, path)
        destination = os.path.join(to_directory, dirname, basename)
        utils.makedirs(os.path.join(to_directory, dirname))

        data = gallery.metadata_for_media_file(
            root,
            os.path.join(dirname, basename),
            title_from_filename=title_from_filename)
        data["category"] = category
        data[
            "template"] = "photo.html"  # TODO: Change this to be part of the configuration.

        name, _ = os.path.splitext(basename)
        mp4_name = "%s.mp4" % name
        mp4_path = os.path.join(to_directory, dirname, mp4_name)
        if not os.path.exists(mp4_path):
            subprocess.check_call([
                "ffmpeg", "-y", "-i", path, "-vcodec", "h264", "-acodec",
                "aac", "-strict", "-2", "-vf", "scale=1080:trunc(ow/a/2)*2",
                "-loglevel", LOG_LEVEL_PANIC, mp4_path
            ])

        thumbnail_name = "%s-thumbnail.jpg" % name
        thumbnail_path = os.path.join(to_directory, dirname, thumbnail_name)
        if not os.path.exists(thumbnail_path):
            subprocess.check_call([
                "ffmpeg", "-y", "-i", path, "-ss", "00:00:1.000", "-vframes",
                "1", "-loglevel", LOG_LEVEL_PANIC, thumbnail_path
            ])

        size = gallery.get_size(thumbnail_path, 1)
        data["thumbnail"] = utils.merge_dictionaries(
            {
                'filename': thumbnail_name,
                'url': os.path.join("/", dirname, thumbnail_name)
            }, size)
        data["video"] = utils.merge_dictionaries(
            {
                'filename': mp4_name,
                'url': os.path.join("/", dirname, mp4_name)
            }, size)

        data["path"] = converters.ensure_leading_slash(path)

        document = store.Document(data["url"], data, os.path.getmtime(path))
        incontext.environment["DOCUMENT_STORE"].add(document)

        return {'files': [mp4_path, thumbnail_path], 'urls': [document.url]}
Пример #3
0
def frontmatter_document(root, path, default_category='general'):
    """
    Parse the contents of a frontmatter document as a DocumentStore Document.

    @param root: Root of the site.
    @type root: str
    @param path: Document path, relative to the root of the site.
    @type path: str

    @return: Document representing the contents of the frontmatter document.
    @rtype: store.Document
    """
    data = {}
    data = merge_dictionaries(data, read_frontmatter(os.path.join(root, path)))
    data = merge_dictionaries(data, {key: value for key, value in parse_path(path).items()
                                     if ((key != "title" or "title" not in data) and
                                         (key != "date" or "date" not in data))})
    data["path"] = ensure_leading_slash(path)
    if "category" not in data:
        data["category"] = default_category
    return store.Document(data['url'], data, os.path.getmtime(os.path.join(root, path)))
Пример #4
0
def process_image(incontext,
                  root,
                  destination,
                  dirname,
                  basename,
                  category,
                  title_from_filename=True):
    source_path = os.path.join(root, dirname, basename)
    identifier = generate_identifier(basename)
    destination_dir = os.path.join(destination, dirname)
    destination_path = os.path.join(destination_dir, basename)
    markdown_path = os.path.join(destination_dir, "%s.markdown" % identifier)
    name, ext = os.path.splitext(basename)
    utils.makedirs(destination_dir)

    metadata = load_metadata(markdown_path)

    DEFAULT_PROFILES = {
        "image": {
            "width": 1600,
            "scale": 1
        },
        "thumbnail": {
            "height": 240,
            "scale": 2
        },
    }

    EQUIRECTANGULAR_PROFILES = {
        "image": {
            "width": 10000,
            "scale": 1
        },
        "thumbnail": {
            "height": 240,
            "scale": 2
        },
    }

    # Use the common path parsing from converters to ensure we pick up information like the title, etc.
    metadata = converters.parse_path(os.path.join(dirname, basename),
                                     title_from_filename=title_from_filename)

    # Read data from the EXIF and add it to the metadata

    exif_data = exif(source_path)

    # Select title with priority: Title, ObjectName
    if "ObjectName" in exif_data:
        metadata["title"] = exif_data["ObjectName"]
    if "Title" in exif_data:
        metadata["title"] = exif_data["Title"]

    metadata["content"] = first_value_or_none(
        exif_data,
        ["ImageDescription", "Description", "ArtworkContentDescription"])

    if "DateTimeOriginal" in exif_data:
        metadata["date"] = exif_data["DateTimeOriginal"]

    if "ProjectionType" in exif_data:
        metadata["projection"] = exif_data["ProjectionType"]
        logging.debug(f"projection = {metadata['projection']}")

    # Read the location from the exif.
    if "GPSLatitude" in exif_data and "GPSLongitude" in exif_data:
        metadata["location"] = {
            "latitude": exif_data["GPSLatitude"],
            "longitude": exif_data["GPSLongitude"]
        }

    # Determine which profiles to use; we use a different profile for equirectangular projections.
    # TODO: In an ideal world we would allow all of this special case behaviour to be configured in site.yaml
    #       so there are no custom modifications required to the script.
    profiles = DEFAULT_PROFILES
    if "projection" in metadata and metadata["projection"] == "equirectangular":
        profiles = EQUIRECTANGULAR_PROFILES

    # Generate the various different image sizes.
    # TODO: Consider making this common code for all images.
    for profile_name, profile_details in profiles.items():

        filename = "%s-%s%s" % (identifier, profile_name.replace("_",
                                                                 "-"), ext)
        if profile_name == "image":
            filename = "%s%s" % (identifier, ext)

        scale = 1
        if "scale" in profile_details:
            scale = profile_details["scale"]
        width = None
        if "width" in profile_details:
            width = profile_details["width"]
        height = None
        if "height" in profile_details:
            height = profile_details["height"]

        source_scale = metadata["scale"] if metadata["scale"] is not None else 1

        # TODO: Rename generate_thumbnail.
        metadata[profile_name] = generate_thumbnail(source_path, destination,
                                                    dirname, filename,
                                                    (width, height),
                                                    source_scale, scale)

    # Configure the page details.
    metadata["category"] = category
    metadata["template"] = "photo.html"  # TODO: Pass this in as a default.
    metadata["path"] = converters.ensure_leading_slash(
        os.path.join(dirname, basename))

    metadata_document = store.Document(metadata['url'], metadata,
                                       os.path.getmtime(source_path))
    incontext.environment["DOCUMENT_STORE"].add(metadata_document)

    files = [markdown_path] + [
        os.path.join(destination, dirname, metadata[f]["filename"])
        for f in profiles.keys()
    ]
    files = [
        os.path.join(destination, dirname, metadata[f]["filename"])
        for f in profiles.keys()
    ]
    return {'files': files, 'urls': [metadata['url']]}