package io.lumify.imageMetadataExtractor; import com.drew.imaging.ImageMetadataReader; import com.drew.metadata.Metadata; import io.lumify.core.ingest.graphProperty.GraphPropertyWorkData; import io.lumify.core.ingest.graphProperty.GraphPropertyWorker; import io.lumify.core.ingest.graphProperty.GraphPropertyWorkerPrepareData; import io.lumify.core.model.properties.LumifyProperties; import io.lumify.core.model.properties.MediaLumifyProperties; import io.lumify.core.util.LumifyLogger; import io.lumify.core.util.LumifyLoggerFactory; import io.lumify.gpw.util.FileSizeUtil; import io.lumify.imageMetadataHelper.*; import org.securegraph.Element; import org.securegraph.Property; import org.securegraph.Vertex; import org.securegraph.mutation.ExistingElementMutation; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class ImageMetadataGraphPropertyWorker extends GraphPropertyWorker { private static final LumifyLogger LOGGER = LumifyLoggerFactory.getLogger(ImageMetadataGraphPropertyWorker.class); private static final String MULTI_VALUE_KEY = ImageMetadataGraphPropertyWorker.class.getName(); private String fileSizeIri; private String dateTakenIri; private String deviceMakeIri; private String deviceModelIri; private String geoLocationIri; private String headingIri; private String metadataIri; private String widthIri; private String heightIri; @Override public boolean isLocalFileRequired() { return true; } @Override public void prepare(GraphPropertyWorkerPrepareData workerPrepareData) throws Exception { super.prepare(workerPrepareData); headingIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.imageHeading"); geoLocationIri = getOntologyRepository().getRequiredPropertyIRIByIntent("geoLocation"); dateTakenIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.dateTaken"); deviceMakeIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.deviceMake"); deviceModelIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.deviceModel"); widthIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.width"); heightIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.height"); metadataIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.metadata"); fileSizeIri = getOntologyRepository().getRequiredPropertyIRIByIntent("media.fileSize"); } private void setProperty(String iri, Object value, ExistingElementMutation<Vertex> mutation, org.securegraph.Metadata metadata, GraphPropertyWorkData data, List<String> properties) { if (iri != null && value != null) { mutation.addPropertyValue(MULTI_VALUE_KEY, iri, value, metadata, data.getVisibility()); properties.add(iri); } } @Override public void execute(InputStream in, GraphPropertyWorkData data) throws Exception { org.securegraph.Metadata metadata = data.createPropertyMetadata(); ExistingElementMutation<Vertex> mutation = data.getElement().prepareMutation(); List<String> properties = new ArrayList<String>(); File imageFile = data.getLocalFile(); if (imageFile != null) { Metadata imageMetadata = null; try { imageMetadata = ImageMetadataReader.readMetadata(imageFile); } catch (Exception e) { LOGGER.error("Could not read metadata from imageFile: %s", imageFile, e); } if (imageMetadata != null) { setProperty(dateTakenIri, DateExtractor.getDateDefault(imageMetadata), mutation, metadata, data, properties); setProperty(deviceMakeIri, MakeExtractor.getMake(imageMetadata), mutation, metadata, data, properties); setProperty(deviceModelIri, ModelExtractor.getModel(imageMetadata), mutation, metadata, data, properties); setProperty(geoLocationIri, GeoPointExtractor.getGeoPoint(imageMetadata), mutation, metadata, data, properties); setProperty(headingIri, HeadingExtractor.getImageHeading(imageMetadata), mutation, metadata, data, properties); setProperty(metadataIri, LeftoverMetadataExtractor.getAsJSON(imageMetadata).toString(), mutation, metadata, data, properties); } Integer width = imageMetadata != null ? DimensionsExtractor.getWidthViaMetadata(imageMetadata) : DimensionsExtractor.getWidthViaBufferedImage(imageFile); setProperty(widthIri, width, mutation, metadata, data, properties); Integer height = imageMetadata != null ? DimensionsExtractor.getHeightViaMetadata(imageMetadata) : DimensionsExtractor.getHeightViaBufferedImage(imageFile); setProperty(heightIri, height, mutation, metadata, data, properties); setProperty(fileSizeIri, FileSizeUtil.getSize(imageFile), mutation, metadata, data, properties); } mutation.save(getAuthorizations()); getGraph().flush(); for (String propertyName : properties) { getWorkQueueRepository().pushGraphPropertyQueue(data.getElement(), MULTI_VALUE_KEY, propertyName); } } @Override public boolean isHandled(Element element, Property property) { if (property == null) { return false; } if (property.getName().equals(MediaLumifyProperties.VIDEO_FRAME.getPropertyName())) { return false; } String mimeType = LumifyProperties.MIME_TYPE.getMetadataValue(property.getMetadata(), null); if (mimeType != null && ( mimeType.startsWith("image/png") || mimeType.startsWith("image/jpeg") || mimeType.startsWith("image/tiff"))) { return true; } return false; } }