From c6ec32146ea55bdaa337ceb4f41320ecad889a9d Mon Sep 17 00:00:00 2001 From: Andreas Romeyke <andreas.romeyke@slub-dresden.de> Date: Mon, 12 Sep 2022 15:13:51 +0200 Subject: [PATCH] - refactoring, renamed class - refactoring, class implements FormatValidationPlugin now - refactoring, removed dead code --- ...LUBMatroskaFFV1FormatValidationPlugin.xml} | 0 ...LUBMatroskaFFV1FormatValidationPlugin.java | 266 +++++++++ ...icalMetadataExtractorMediaConchPlugin.java | 532 ------------------ 3 files changed, 266 insertions(+), 532 deletions(-) rename PLUGIN-INF/{metadata_SLUBTechnicalMetadataExtractorMediaConchPlugin.xml => metadata_SLUBMatroskaFFV1FormatValidationPlugin.xml} (100%) create mode 100644 java/org/slub/rosetta/dps/repository/plugin/SLUBMatroskaFFV1FormatValidationPlugin.java delete mode 100644 java/org/slub/rosetta/dps/repository/plugin/SLUBTechnicalMetadataExtractorMediaConchPlugin.java diff --git a/PLUGIN-INF/metadata_SLUBTechnicalMetadataExtractorMediaConchPlugin.xml b/PLUGIN-INF/metadata_SLUBMatroskaFFV1FormatValidationPlugin.xml similarity index 100% rename from PLUGIN-INF/metadata_SLUBTechnicalMetadataExtractorMediaConchPlugin.xml rename to PLUGIN-INF/metadata_SLUBMatroskaFFV1FormatValidationPlugin.xml diff --git a/java/org/slub/rosetta/dps/repository/plugin/SLUBMatroskaFFV1FormatValidationPlugin.java b/java/org/slub/rosetta/dps/repository/plugin/SLUBMatroskaFFV1FormatValidationPlugin.java new file mode 100644 index 0000000..f5cd7a3 --- /dev/null +++ b/java/org/slub/rosetta/dps/repository/plugin/SLUBMatroskaFFV1FormatValidationPlugin.java @@ -0,0 +1,266 @@ +/* +2017-2022 by Andreas Romeyke (SLUB Dresden) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package org.slub.rosetta.dps.repository.plugin; + +import com.exlibris.dps.sdk.techmd.FormatValidationPlugin; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.math.BigInteger; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * SLUBTechnicalMetadataExtractorMediaConchPlugin + * + * @author andreas.romeyke@slub-dresden.de (Andreas Romeyke) + * @see com.exlibris.dps.sdk.techmd.FormatValidationPlugin + */ +public class SLUBTechnicalMetadataExtractorMediaConchPlugin implements FormatValidationPlugin { + private String mediaconch_binary_path; + private String mediaconch_current_profile_path; + private String mediaconch_upcoming_profile_path; + private final List<String> validationLog = new ArrayList<>(); + private boolean isvalid = false; + private boolean iswellformed = false; + private String md5CurrentProfile; + private String md5UpcomingProfile; + //static final ExLogger log = ExLogger.getExLogger(SLUBTechnicalMetadataExtractorMediaConchPlugin.class, ExLogger.VALIDATIONSTACK); + private boolean isDifferentProfile = true; + + /** constructor */ + public SLUBTechnicalMetadataExtractorMediaConchPlugin() { + //log.info("SLUBVirusCheckPlugin instantiated with host=" + host + " port=" + port + " timeout=" + timeout); + System.out.println("SLUBTechnicalMetadataExtractorMediaConchPlugin instantiated"); + } + + /** init params to configure the plugin via xml forms + * @param initp parameter map + */ + public void initParams(Map<String, String> initp) { + this.mediaconch_binary_path = initp.get("mediaconch_binary_path").trim(); + this.mediaconch_current_profile_path = initp.get("mediaconch_current_profile_path").trim(); + this.mediaconch_upcoming_profile_path = initp.get("mediaconch_upcoming_profile_path").trim(); + try { + checkFileExists(this.mediaconch_binary_path); + checkFileExists(this.mediaconch_current_profile_path); + checkFileExists(this.mediaconch_upcoming_profile_path); + this.md5CurrentProfile = md5SumOfFile( this.mediaconch_current_profile_path); + this.md5UpcomingProfile = md5SumOfFile( this.mediaconch_upcoming_profile_path); + this.isDifferentProfile = !this.md5UpcomingProfile.equals(this.md5CurrentProfile); + System.out.println("SLUBTechnicalMetadataExtractorMediaConchPlugin instantiated with " + + " mediaconch_binary_path=" + mediaconch_binary_path + + " mediaconch_current_profile_path=" + mediaconch_current_profile_path + + " mediaconch_upcoming_profile_path=" + mediaconch_upcoming_profile_path + + (isDifferentProfile ? "with different profiles" : "with same profile") + ); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + // TODO: Pfadstring, Prüfsumme, modification date für beide Profile + public String getProfile () { + String modified_current = modificationDateOfFile( this.mediaconch_current_profile_path); + String modified_upcoming = modificationDateOfFile( this.mediaconch_upcoming_profile_path); + /* there is no documentation in ExL API, therefore we use it to document the profile versions in a light way */ + return ( + "current profile:\n" + + " path=" + this.mediaconch_current_profile_path + "\n" + + " md5sum=" + this.md5CurrentProfile + "\n" + + " modification date=" + modified_current + "\n" + + "upcoming profile:\n" + + " path=" + this.mediaconch_upcoming_profile_path + "\n" + + " md5sum=" + this.md5UpcomingProfile + "\n" + + " modification date=" +modified_upcoming + "\n" + ); + } + + private void callMediaconch(String filePath, String profilePath) { + String execstring = this.mediaconch_binary_path + " " + filePath + " -p " + profilePath; + System.out.println("executing: " + execstring); + InputStreamReader process_out; + try { + Process p = Runtime.getRuntime().exec(execstring); + p.waitFor(); + process_out = new InputStreamReader(p.getInputStream()); + if (p.exitValue() == 0) { + isvalid = true; + iswellformed = true; + } else { // something wrong + isvalid = false; + iswellformed = false; + } + BufferedReader reader = new BufferedReader(process_out); + String line = reader.readLine(); + while (line != null) { + if (line.contains("pass!")) { + break; + } + System.out.println("MEDIACONCH line: " + line); + validationLog.add(line); + line = reader.readLine(); + } + reader.close(); + } catch (IOException e) { + //log.error("exception creation socket, clamd not available at host=" + host + "port=" + port, e); + System.out.println("ERROR: (actual) mediaconch not available, path=" + this.mediaconch_binary_path + ", " + e.getMessage()); + } catch (InterruptedException e) { + System.out.println("ERROR: call of mediaconch interrupted, path=" + this.mediaconch_binary_path + ", " + e.getMessage()); + } + } + + public String getAgentName() + { + return "mediaconch"; + } + + @Override + public boolean validateFormat(String filePath) { + // mediaconch validation, first using upcoming profile, if invalid then retry with current profile + callMediaconch(filePath, this.mediaconch_upcoming_profile_path); + if (this.isDifferentProfile && !isvalid) { + callMediaconch(filePath, this.mediaconch_current_profile_path); + } + + return isvalid; + } + + /** get agent version and signature version calling command VERSION + * + * @return string with version and signature version + */ + public String getAgent() { + StringBuilder response = new StringBuilder(); + response.append("mediaconch:\n"); + InputStreamReader process_out = null; + try { + String execstring = this.mediaconch_binary_path + " --Version"; + checkFileExists(this.mediaconch_binary_path); + Process p = Runtime.getRuntime().exec(execstring); + p.waitFor(); + process_out = new InputStreamReader(p.getInputStream()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + if (process_out != null) { + BufferedReader reader = new BufferedReader(process_out); + String line; + try { + line = reader.readLine(); + while (line != null) { + System.out.println(line); + response.append(line); + try { + line = reader.readLine(); + } catch (IOException e) { + e.printStackTrace(); + } + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return response.toString().trim(); + } + + @Override + public boolean isWellFormed() { + return this.iswellformed; + } + + @Override + public List<String> getErrors() { + return List.copyOf(this.validationLog); + } + + @Override + public boolean isValid() { + //System.out.println("DEBUG: is valid=" + this.isvalid); + return this.isvalid; + } + + private void checkFileExists (String filename) throws Exception { + File f = new File(filename); + if (! f.exists() ) { + System.out.println("ERROR: path=" + filename + " not available"); + throw new Exception("ERROR: path=" + filename + " not available"); + } + } + + private String md5SumOfFile(String filename ) { + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] b = Files.readAllBytes(Paths.get(filename)); + byte[] digest = md.digest(b); + String hexdigest = new BigInteger(1, digest).toString(16); + return hexdigest; + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + private String modificationDateOfFile(String filename ) { + try { + return Files.getLastModifiedTime(Paths.get(filename)).toString(); + } catch (IOException e) { + e.printStackTrace(); + } + return ""; + } + + /** stand-alone check, main file to call local installed clamd + * @param args list of files which should be scanned + */ + public static void main(String[] args) { + SLUBTechnicalMetadataExtractorMediaConchPlugin plugin = new SLUBTechnicalMetadataExtractorMediaConchPlugin(); + Map<String, String> initp = new HashMap<>(); + initp.put( "mediaconch_binary_path", "/usr/bin/mediaconch"); + initp.put( "mediaconch_current_profile_path", "/etc/mediaconch/profile.xml"); + initp.put( "mediaconch_upcoming_profile_path", "/etc/mediaconch/profile.xml"); + initp.put( "mediainfo_binary_path", "/usr/bin/mediainfo"); + plugin.initParams( initp ); + System.out.println("----------------------------------"); + System.out.println("Agent: '" + plugin.getAgent() + "'"); + System.out.println(); + for (String file : args) { + System.out.println("Validation RESULT: " + plugin.isValid()); + } + System.out.println("----------------------------------"); + System.out.println("getAgentName:"); + System.out.println( plugin.getAgentName()); + System.out.println("----------------------------------"); + System.out.println("getAgent:"); + System.out.println( plugin.getAgent()); + System.out.println("----------------------------------"); + System.out.println("getProfile:"); + System.out.println( plugin.getProfile()); + System.out.println("----------------------------------"); + } +} diff --git a/java/org/slub/rosetta/dps/repository/plugin/SLUBTechnicalMetadataExtractorMediaConchPlugin.java b/java/org/slub/rosetta/dps/repository/plugin/SLUBTechnicalMetadataExtractorMediaConchPlugin.java deleted file mode 100644 index 4b1555f..0000000 --- a/java/org/slub/rosetta/dps/repository/plugin/SLUBTechnicalMetadataExtractorMediaConchPlugin.java +++ /dev/null @@ -1,532 +0,0 @@ -/* -2017-2022 by Andreas Romeyke (SLUB Dresden) - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package org.slub.rosetta.dps.repository.plugin; - -import com.exlibris.core.sdk.strings.StringUtils; -import com.exlibris.dps.sdk.techmd.MDExtractorPlugin; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpression; -import javax.xml.xpath.XPathFactory; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.math.BigInteger; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * SLUBTechnicalMetadataExtractorMediaConchPlugin - * - * @author andreas.romeyke@slub-dresden.de (Andreas Romeyke) - * @see com.exlibris.dps.sdk.techmd.MDExtractorPlugin - */ -public class SLUBTechnicalMetadataExtractorMediaConchPlugin implements MDExtractorPlugin { - private String mediaconch_binary_path; - private String mediaconch_current_profile_path; - private String mediaconch_upcoming_profile_path; - private String mediainfo_binary_path; - private String xsltproc_binary_path; - private final static String TRANSFORMER_XSL = "/resources/transformer.xsl"; - private List<String> extractionErrors = new ArrayList<>(); - private final List<String> validationLog = new ArrayList<>(); - private boolean isvalid = false; - private boolean iswellformed = false; - private String md5CurrentProfile; - private String md5UpcomingProfile; - private boolean isDifferentProfile = true; - private final Map<String,String> attributes = new HashMap<>(); - //static final ExLogger log = ExLogger.getExLogger(SLUBTechnicalMetadataExtractorMediaConchPlugin.class, ExLogger.VALIDATIONSTACK); - private final static ArrayList<String> attributesMappedToDnxPropertiesOfTypeNumber = new ArrayList<String>() {{ - // HINT: based on FL 7.1100 mappings for mediainfo (https://github.com/rosetta-format-library/RosettaFormatLibrary/releases/tag/7.1100) - add("mediainfo.track.Audio.Duration"); // => audio.duration - add("mediainfo.track.Audio.SamplingRate"); // => audio.sampling_rate - add("mediainfo.track.Audio.StreamSize"); // => audio.stream_size - add("mediainfo.track.General.AudioCount"); // => general.audio_count - add("mediainfo.track.General.MenuCount"); // => general.menu_count - add("mediainfo.track.General.OtherCount"); // => general.other_count - add("mediainfo.track.General.StreamSize"); // => general.stream_size - add("mediainfo.track.General.TextCount"); // => general.text_count - add("mediainfo.track.General.VideoCount"); // => general.video_count - add("mediainfo.track.Video.BitRate"); // => video.bit_rate - add("mediainfo.track.Video.DisplayAspectRatio"); // => video.display_aspect_ratio - add("mediainfo.track.Video.Duration"); // => video.duration - add("mediainfo.track.Video.extra.MaxSlicesCount"); // => video.extra.max_slices_count - add("mediainfo.track.Video.FrameCount"); // => video.frame_count - }}; - - /** constructor */ - public SLUBTechnicalMetadataExtractorMediaConchPlugin() { - //log.info("SLUBVirusCheckPlugin instantiated with host=" + host + " port=" + port + " timeout=" + timeout); - System.out.println("SLUBTechnicalMetadataExtractorMediaConchPlugin instantiated"); - } - - /** init params to configure the plugin via xml forms - * @param initp parameter map - */ - public void initParams(Map<String, String> initp) { - this.mediaconch_binary_path = initp.get("mediaconch_binary_path").trim(); - this.mediaconch_current_profile_path = initp.get("mediaconch_current_profile_path").trim(); - this.mediaconch_upcoming_profile_path = initp.get("mediaconch_upcoming_profile_path").trim(); - this.mediainfo_binary_path = initp.get("mediainfo_binary_path").trim(); - this.xsltproc_binary_path = initp.get("xsltproc_binary_path").trim(); - try { - checkFileExists(this.mediainfo_binary_path); - checkFileExists(this.mediaconch_binary_path); - checkFileExists(this.xsltproc_binary_path); - checkFileExists(this.mediaconch_current_profile_path); - checkFileExists(this.mediaconch_upcoming_profile_path); - this.md5CurrentProfile = md5SumOfFile( this.mediaconch_current_profile_path); - this.md5UpcomingProfile = md5SumOfFile( this.mediaconch_upcoming_profile_path); - this.isDifferentProfile = ! this.md5UpcomingProfile.equals(this.md5CurrentProfile); - System.out.println("SLUBTechnicalMetadataExtractorMediaConchPlugin instantiated with " - + " mediaconch_binary_path=" + mediaconch_binary_path - + " mediaconch_current_profile_path=" + mediaconch_current_profile_path - + " mediaconch_upcoming_profile_path=" + mediaconch_upcoming_profile_path - + " mediainfo_binary_path=" + mediainfo_binary_path - + " xsltproc_binary_path=" + xsltproc_binary_path - ); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - // TODO: Pfadstring, Prüfsumme, modification date für beide Profile - public String getProfile () { - String modified_current = modificationDateOfFile( this.mediaconch_current_profile_path); - String modified_upcoming = modificationDateOfFile( this.mediaconch_upcoming_profile_path); - /* there is no documentation in ExL API, therefore we use it to document the profile versions in a light way */ - return ( - "current profile:\n" - + " path=" + this.mediaconch_current_profile_path + "\n" - + " md5sum=" + this.md5CurrentProfile + "\n" - + " modification date=" + modified_current + "\n" - + "upcoming profile:\n" - + " path=" + this.mediaconch_upcoming_profile_path + "\n" - + " md5sum=" + this.md5UpcomingProfile + "\n" - + " modification date=" +modified_upcoming + "\n" - ); - } - - @Override - public void extract(String filePath) throws Exception { - if (StringUtils.isEmptyString(this.mediaconch_binary_path)) { - throw new Exception("mediaconch_binary_path not found"); - } - if (StringUtils.isEmptyString(this.mediaconch_current_profile_path)) { - throw new Exception("mediaconch_profile_path not found"); - } - if (StringUtils.isEmptyString(this.mediainfo_binary_path)) { - throw new Exception("mediainfo_binary_path not found"); - } - checkFileExists(this.mediaconch_binary_path); - checkFileExists(this.mediaconch_current_profile_path); - checkFileExists(this.mediainfo_binary_path); - checkFileExists(this.xsltproc_binary_path); - // mediaconch validation, first using upcoming profile, if invalid then retry with current profile - callMediaconch(filePath, this.mediaconch_upcoming_profile_path); - if (isDifferentProfile && !isvalid) { - callMediaconch(filePath, this.mediaconch_current_profile_path); - } - // mediainfo metadata extraction - callMediainfoAndResultProcessing(filePath); - } - - private void callMediainfo(String file_to_extract_from, String temp_mediainfo_outputfile ) throws Exception { - String exec_mediainfo_string = this.mediainfo_binary_path + " -f --Output=XML " + file_to_extract_from; - System.out.println("executing: " + exec_mediainfo_string); - checkFileExists(this.mediainfo_binary_path); - InputStreamReader process_out; - try { - Process p = Runtime.getRuntime().exec(exec_mediainfo_string); - p.waitFor(); - process_out = new InputStreamReader(p.getInputStream()); - } catch (IOException e) { - //log.error("exception creation socket, clamd not available at host=" + host + "port=" + port, e); - System.out.println("ERROR: (actual) mediainfo not available, path=" + this.mediainfo_binary_path + ", " + e.getMessage()); - throw new Exception("ERROR: (actual) mediainfo not available, path=" + this.mediainfo_binary_path + ", " + e.getMessage()); - } - BufferedReader reader = new BufferedReader(process_out); - String line = reader.readLine(); - StringBuilder mediainfo_output = new StringBuilder(); - while (line != null) { - /* patch out mediainfo schema location because downloading of xsd is not allowed */ - /* example input: - <MediaInfo - xmlns="https://mediaarea.net/mediainfo" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="https://mediaarea.net/mediainfo https://mediaarea.net/mediainfo/mediainfo_2_0.xsd" - version="2.0"> - */ - String regex = "xsi:schemaLocation=\"[^\"]*\""; - String line_patched = line.replaceAll(regex, ""); - mediainfo_output.append(line_patched); - if (!line.equals(line_patched)) { - System.out.println("monkey patched line:\n- " + line + " to new line:\n+ " + line_patched); - } - line = reader.readLine(); - } - reader.close(); - FileWriter temp_media_outputstream = new FileWriter(temp_mediainfo_outputfile); - BufferedWriter temp_media_streamwriter = new BufferedWriter(temp_media_outputstream); - temp_media_streamwriter.append(mediainfo_output); - temp_media_streamwriter.flush(); - temp_media_outputstream.flush(); - temp_media_outputstream.close(); - temp_media_streamwriter.close(); - } - - private void callMediainfoAndResultProcessing(String filePath) throws Exception { - File temp_media_outputfile = File.createTempFile("mediainfo_outp", ".xml"); - temp_media_outputfile.deleteOnExit(); - callMediainfo(filePath, String.valueOf(temp_media_outputfile)); - if (temp_media_outputfile.length() > 0) { - File temp_media_transformed_outputfile = File.createTempFile("mediainfo_transf_", ".xml"); - temp_media_transformed_outputfile.deleteOnExit(); - //OutputStream temp_media_outputstream = new FileOutputStream(temp_media_outputfile); - transformMediainfoOutput(temp_media_outputfile, temp_media_transformed_outputfile); - if (temp_media_transformed_outputfile.length() > 0) { - /* TODO: read transformed outputfile and return attributes */ - extractAttributesOfTransformedResult(temp_media_transformed_outputfile); - } else { - throw new Exception( "size of intermediate transformed file '" + temp_media_transformed_outputfile + "' is zero, something broken"); - } - } else { - throw new Exception( "size of intermediate mediainfo file '" + temp_media_outputfile + "' is zero, something broken"); - } - temp_media_outputfile.delete(); - } - - private void transformMediainfoOutput(File temp_media_outputfile, File temp_media_transformed_outputfile) throws Exception { - File temp_xsdfile = createTempXsdFile(); - /* xslt transform */ - String exec_xsltproc_string = xsltproc_binary_path + " -o " + temp_media_transformed_outputfile + " " + temp_xsdfile + " " + temp_media_outputfile; - System.out.println("executing: " + exec_xsltproc_string); - InputStreamReader process_out; - try { - Process p = Runtime.getRuntime().exec(exec_xsltproc_string); - p.waitFor(); - process_out = new InputStreamReader(p.getInputStream()); - } catch (IOException e) { - //log.error("exception creation socket, clamd not available at host=" + host + "port=" + port, e); - System.out.println("ERROR: (actual) xsltproc not available, path=" + xsltproc_binary_path + ", " + e.getMessage()); - throw new Exception("ERROR: (actual) xsltproc not available, path=" + xsltproc_binary_path + ", " + e.getMessage()); - } finally { - temp_xsdfile.delete(); - } - } - - private File createTempXsdFile() throws Exception { - /* write xsd */ - File temp_xsdfile = File.createTempFile("mediainfo_style", ".xsd"); - InputStream stylestream = getClass().getResourceAsStream(TRANSFORMER_XSL); - if (stylestream == null) { - throw new Exception("stylestream not found!"); - } - Files.copy(stylestream, Path.of(String.valueOf(temp_xsdfile)), StandardCopyOption.REPLACE_EXISTING); - stylestream.close(); - return temp_xsdfile; - } - - private void extractAttributesOfTransformedResult(File temp_media_transformed_outputfile) throws Exception { - checkFileExists(String.valueOf(temp_media_transformed_outputfile)); - XPathFactory xPathfactory = XPathFactory.newInstance(); - XPath xpath = xPathfactory.newXPath(); - XPathExpression expr = xpath.compile("/mdExtractor/attributes/key"); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - Document temp_media_transformed_source = db.parse(temp_media_transformed_outputfile); - NodeList nl = (NodeList) expr.evaluate(temp_media_transformed_source, XPathConstants.NODESET); - int len = nl.getLength(); - for ( int i = 0; i < len; i++ ) { - Node node = nl.item(i); - String id = String.valueOf(node.getAttributes().getNamedItem("id").getTextContent()); - String value = node.getTextContent(); - attributes.put(id, value); - } - } - - private void callMediaconch(String filePath, String profilePath) throws Exception { - String execstring = this.mediaconch_binary_path + " " + filePath + " -p " + profilePath; - System.out.println("executing: " + execstring); - InputStreamReader process_out; - try { - Process p = Runtime.getRuntime().exec(execstring); - p.waitFor(); - process_out = new InputStreamReader(p.getInputStream()); - if (p.exitValue() == 0) { - isvalid = true; - iswellformed = true; - } else { // something wrong - isvalid = false; - iswellformed = false; - } - } catch (IOException e) { - //log.error("exception creation socket, clamd not available at host=" + host + "port=" + port, e); - System.out.println("ERROR: (actual) mediaconch not available, path=" + this.mediaconch_binary_path + ", " + e.getMessage()); - throw new Exception("ERROR: (actual) mediaconch not available, path=" + this.mediaconch_binary_path + ", " + e.getMessage()); - } - BufferedReader reader = new BufferedReader(process_out); - String line = reader.readLine(); - while (line != null) { - if (line.contains("pass!")) { - break; - } - System.out.println("MEDIACONCH line: " + line); - validationLog.add(line); - line = reader.readLine(); - - } - reader.close(); - extractionErrors = validationLog; - } - - public String getAgentName() - { - return "mediaconch"; - } - - /** get agent version and signature version calling command VERSION - * - * @return string with version and signature version - */ - public String getAgent() { - StringBuilder response = new StringBuilder(); - response.append("mediaconch:\n"); - - String[] executables = { - this.mediaconch_binary_path, - this.mediainfo_binary_path - }; - for (String executable : executables) { - String execstring = executable + " --Version"; - InputStreamReader process_out = null; - try { - checkFileExists( executable); - Process p = Runtime.getRuntime().exec(execstring); - p.waitFor(); - process_out = new InputStreamReader(p.getInputStream()); - } catch (IOException e) { - //log.error("exception creation socket, clamd not available at host=" + host + "port=" + port, e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } - if (process_out != null) { - BufferedReader reader = new BufferedReader(process_out); - String line; - try { - line = reader.readLine(); - while (line != null) { - System.out.println(line); - response.append(line); - try { - line = reader.readLine(); - } catch (IOException e) { - e.printStackTrace(); - } - } - reader.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - return response.toString().trim(); - } - - @Override - public String getAttributeByName(String attribute) { - if (attributes.containsKey(attribute)) { - return attributes.get(attribute); - } - // HINT: Rosetta expects a number of specific DNX properties instead of text - if (attributesMappedToDnxPropertiesOfTypeNumber.contains( attribute.toString() )) { - return "0"; // type NUMBER - } - return "not found"; // type TEXT & STRING - } - - @Override - public List<String> getExtractionErrors() { - List<String> extractionErrors = this.extractionErrors; - return Collections.unmodifiableList(extractionErrors); - } - - /* base is the property file from original mediainfo-plugin of FL working group */ - @Override - public List<String> getSupportedAttributeNames() { - //return new ArrayList<String>(attributes.keySet()); - List<String> available = new ArrayList<>(); - try { - XPathFactory xPathfactory = XPathFactory.newInstance(); - XPath xpath = xPathfactory.newXPath(); - XPathExpression expr = xpath.compile("//*[local-name()='properties']/*[local-name()='property']"); - //XPathExpression expr = xpath.compile("//text()"); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder db = dbf.newDocumentBuilder(); - InputStream stylestream = getClass().getResourceAsStream(TRANSFORMER_XSL); - Document temp_property_list_xml = db.parse(stylestream); - NodeList nl = (NodeList) expr.evaluate(temp_property_list_xml, XPathConstants.NODESET); - int len = nl.getLength(); - for (int i = 0; i < len; i++) { - Node node = nl.item(i); - String value = node.getTextContent(); - available.add(value); - } - } catch (Exception e) { - System.out.println("error in getSupportedAttributeNaes, " + e.getMessage()); - } - return available; - } - - @Override - public boolean isWellFormed() { - return this.iswellformed; - } - - @Override - public boolean isValid() { - //System.out.println("DEBUG: is valid=" + this.isvalid); - return this.isvalid; - } - @Override - public String getFormatName() { - return "FFV1/Matroska"; - } - - @Override - public String getFormatVersion() { - return "FFV1 v3, Matroska v1.4 (Pronom PUID: fmt/569)"; - } - - @Override - public Integer getImageCount() { // only relevant for image extractors - return 0; - } - - @Override - public String getMimeType() { - return "video/x-matroska"; - } - - private void checkFileExists (String filename) throws Exception { - File f = new File(filename); - if (! f.exists() ) { - System.out.println("ERROR: path=" + filename + " not available"); - throw new Exception("ERROR: path=" + filename + " not available"); - } - } - - private String md5SumOfFile(String filename ) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] b = Files.readAllBytes(Paths.get(filename)); - byte[] digest = md.digest(b); - String hexdigest = new BigInteger(1, digest).toString(16); - return hexdigest; - } catch (Exception e) { - e.printStackTrace(); - } - return ""; - } - - private String modificationDateOfFile(String filename ) { - try { - return Files.getLastModifiedTime(Paths.get(filename)).toString(); - } catch (IOException e) { - e.printStackTrace(); - } - return ""; - } - - /** stand-alone check, main file to call local installed clamd - * @param args list of files which should be scanned - */ - public static void main(String[] args) { - SLUBTechnicalMetadataExtractorMediaConchPlugin plugin = new SLUBTechnicalMetadataExtractorMediaConchPlugin(); - Map<String, String> initp = new HashMap<>(); - initp.put( "xsltproc_binary_path", "/usr/bin/xsltproc"); - initp.put( "mediaconch_binary_path", "/usr/bin/mediaconch"); - initp.put( "mediaconch_current_profile_path", "/etc/mediaconch/profile.xml"); - initp.put( "mediaconch_upcoming_profile_path", "/etc/mediaconch/profile.xml"); - initp.put( "mediainfo_binary_path", "/usr/bin/mediainfo"); - plugin.initParams( initp ); - System.out.println("----------------------------------"); - System.out.println("Agent: '" + plugin.getAgent() + "'"); - System.out.println(); - for (String file : args) { - try { - System.out.println("extracting from " + file); - plugin.extract(file); - } catch (Exception e) { - System.out.println("CALLERROR:"); - e.printStackTrace(); - return; - } - System.out.println("Validation RESULT: " + plugin.isValid()); - System.out.println("ERRORMESSAGE: " + plugin.getExtractionErrors()); - } - System.out.println("----------------------------------"); - System.out.println("getAgentName:"); - System.out.println( plugin.getAgentName()); - System.out.println("----------------------------------"); - System.out.println("getAgent:"); - System.out.println( plugin.getAgent()); - System.out.println("----------------------------------"); - System.out.println("getSupportedAttributeNames:"); - System.out.println( plugin.getSupportedAttributeNames()); - System.out.println("----------------------------------"); - System.out.println("getFormatName:"); - System.out.println( plugin.getFormatName()); - System.out.println("----------------------------------"); - System.out.println("getFormatVersion:"); - System.out.println( plugin.getFormatVersion()); - System.out.println("----------------------------------"); - System.out.println("getMimeType:"); - System.out.println( plugin.getMimeType()); - System.out.println("----------------------------------"); - System.out.println("getProfile:"); - System.out.println( plugin.getProfile()); - System.out.println("----------------------------------"); - System.out.println("getAttributeByName (summarized):"); - for (Map.Entry<String, String> m : plugin.attributes.entrySet()) { - String s = m.getKey() + " -> " + m.getValue(); - System.out.println(s); - } - } -} -- GitLab