/* * Copyright (C) 2016 Patrick Favre-Bulle * * 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 at.favre.tools.dconvert.ui; import at.favre.tools.dconvert.arg.*; import org.apache.commons.cli.*; import java.io.File; import java.text.MessageFormat; import java.util.HashSet; import java.util.Locale; import java.util.ResourceBundle; import java.util.Set; /** * Handles parsing of command line arguments */ public class CLIInterpreter { public static final String COMPRESSION_QUALITY_ARG = "compressionQuality"; public static final String THREADS_ARG = "threads"; public final static String SOURCE_ARG = "src"; public final static String SCALE_ARG = "scale"; public final static String PLATFORM_ARG = "platform"; public final static String UPSCALING_ALGO_ARG = "algorithmUpscaling"; public final static String DOWNSCALING_ALGO_ARG = "algorithmDownscaling"; public static final String OUT_COMPRESSION_ARG = "outCompression"; public static final String ROUNDING_MODE_ARG = "roundingMode"; public static final String DST_ARG = "dst"; public static final String VERBOSE_ARG = "verbose"; public static final String SKIP_EXISTING_ARG = "skipExisting"; public static final String SCALE_IS_HEIGHT_DP_ARG = "scaleIsHeightDp"; public static Arguments parse(String[] args) { ResourceBundle strings = ResourceBundle.getBundle("bundles.strings", Locale.getDefault()); Options options = setupOptions(strings); CommandLineParser parser = new DefaultParser(); Arguments.Builder builder; try { CommandLine commandLine = parser.parse(options, args); if (commandLine.hasOption("gui")) { return Arguments.START_GUI; } if (commandLine.hasOption("h") || commandLine.hasOption("help")) { printHelp(options); return null; } if (commandLine.hasOption("v") || commandLine.hasOption("version")) { System.out.println("Version: " + CLIInterpreter.class.getPackage().getImplementationVersion()); return null; } String scaleRawParam = commandLine.getOptionValue(SCALE_ARG).toLowerCase(); boolean dp = false; if (scaleRawParam.contains("dp")) { dp = true; scaleRawParam = scaleRawParam.replace("dp", "").trim(); } builder = new Arguments.Builder(new File(commandLine.getOptionValue(SOURCE_ARG)), Float.parseFloat(scaleRawParam)); if (dp && commandLine.hasOption(SCALE_IS_HEIGHT_DP_ARG)) { builder.scaleMode(EScaleMode.DP_HEIGHT); } else if (dp && !commandLine.hasOption(SCALE_IS_HEIGHT_DP_ARG)) { builder.scaleMode(EScaleMode.DP_WIDTH); } else { builder.scaleMode(EScaleMode.FACTOR); } if (commandLine.hasOption(DST_ARG)) { builder.dstFolder(new File(commandLine.getOptionValue(DST_ARG))); } float compressionQuality = Arguments.DEFAULT_COMPRESSION_QUALITY; if (commandLine.hasOption(COMPRESSION_QUALITY_ARG)) { compressionQuality = Float.valueOf(commandLine.getOptionValue(COMPRESSION_QUALITY_ARG)); } if (commandLine.hasOption(OUT_COMPRESSION_ARG)) { switch (commandLine.getOptionValue(OUT_COMPRESSION_ARG)) { case "strict": builder.compression(EOutputCompressionMode.SAME_AS_INPUT_STRICT); break; case "png": builder.compression(EOutputCompressionMode.AS_PNG); break; case "jpg": builder.compression(EOutputCompressionMode.AS_JPG, compressionQuality); break; case "gif": builder.compression(EOutputCompressionMode.AS_GIF); break; case "bmp": builder.compression(EOutputCompressionMode.AS_BMP); break; case "png+jpg": builder.compression(EOutputCompressionMode.AS_JPG_AND_PNG, compressionQuality); break; default: System.err.println("unknown compression type: " + commandLine.getOptionValue(OUT_COMPRESSION_ARG)); } } Set<EPlatform> platformSet = new HashSet<>(EPlatform.values().length); if (commandLine.hasOption(PLATFORM_ARG)) { switch (commandLine.getOptionValue(PLATFORM_ARG)) { case "all": platformSet = EPlatform.getAll(); break; case "android": platformSet.add(EPlatform.ANDROID); break; case "ios": platformSet.add(EPlatform.IOS); break; case "win": platformSet.add(EPlatform.WINDOWS); break; case "web": platformSet.add(EPlatform.WEB); break; default: System.err.println("unknown mode: " + commandLine.getOptionValue(PLATFORM_ARG)); } builder.platform(platformSet); } if (commandLine.hasOption(UPSCALING_ALGO_ARG)) { builder.upScaleAlgorithm(EScalingAlgorithm.getByName(commandLine.getOptionValue(UPSCALING_ALGO_ARG))); } if (commandLine.hasOption(DOWNSCALING_ALGO_ARG)) { builder.downScaleAlgorithm(EScalingAlgorithm.getByName(commandLine.getOptionValue(DOWNSCALING_ALGO_ARG))); } if (commandLine.hasOption(ROUNDING_MODE_ARG)) { switch (commandLine.getOptionValue(ROUNDING_MODE_ARG)) { case "round": builder.scaleRoundingStragy(RoundingHandler.Strategy.ROUND_HALF_UP); break; case "ceil": builder.scaleRoundingStragy(RoundingHandler.Strategy.CEIL); break; case "floor": builder.scaleRoundingStragy(RoundingHandler.Strategy.FLOOR); break; default: System.err.println("unknown mode: " + commandLine.getOptionValue(ROUNDING_MODE_ARG)); } } if (commandLine.hasOption(THREADS_ARG)) { builder.threadCount(Integer.valueOf(commandLine.getOptionValue(THREADS_ARG))); } builder.skipUpscaling(commandLine.hasOption("skipUpscaling")); builder.skipExistingFiles(commandLine.hasOption(SKIP_EXISTING_ARG)); builder.includeAndroidLdpiTvdpi(commandLine.hasOption("androidIncludeLdpiTvdpi")); builder.verboseLog(commandLine.hasOption(VERBOSE_ARG)); builder.haltOnError(commandLine.hasOption("haltOnError")); builder.createMipMapInsteadOfDrawableDir(commandLine.hasOption("androidMipmapInsteadOfDrawable")); builder.antiAliasing(commandLine.hasOption("antiAliasing")); builder.enablePngCrush(commandLine.hasOption("postProcessorPngCrush")); builder.postConvertWebp(commandLine.hasOption("postProcessorWebp")); builder.dryRun(commandLine.hasOption("dryRun")); builder.enableMozJpeg(commandLine.hasOption("postProcessorMozJpeg")); builder.keepUnoptimizedFilesPostProcessor(commandLine.hasOption("keepOriginalPostProcessedFiles")); builder.iosCreateImagesetFolders(commandLine.hasOption("iosCreateImagesetFolders")); builder.clearDirBeforeConvert(commandLine.hasOption("clean")); return builder.build(); } catch (Exception e) { System.err.println("Could not parse args: " + e.getMessage()); } return null; } private static void printHelp(Options options) { HelpFormatter help = new HelpFormatter(); help.setWidth(110); help.setLeftPadding(4); help.printHelp("converter", "version: " + CLIInterpreter.class.getPackage().getImplementationVersion(), options, "", true); } private static Options setupOptions(ResourceBundle bundle) { Options options = new Options(); Option srcOpt = Option.builder(SOURCE_ARG).required().argName("path to file or folder").hasArg(true).desc(bundle.getString("arg.descr.cmd.src")).build(); Option srcScaleOpt = Option.builder(SCALE_ARG).argName("[float]|[int]dp").hasArg(true).desc(bundle.getString("arg.descr.cmd.scale")).build(); Option dstOpt = Option.builder(DST_ARG).hasArg(true).argName("path").desc(bundle.getString("arg.descr.cmd.dst")).build(); Option platform = Option.builder(PLATFORM_ARG).hasArg(true).argName("all|android|ios|win|web").desc(MessageFormat.format(bundle.getString("arg.descr.cmd.platform"), Arguments.DEFAULT_PLATFORM)).build(); Option threadCount = Option.builder(THREADS_ARG).argName("1-8").hasArg(true).desc(MessageFormat.format(bundle.getString("arg.descr.cmd.threads"), String.valueOf(Arguments.DEFAULT_THREAD_COUNT))).build(); Option roundingHandler = Option.builder(ROUNDING_MODE_ARG).argName("round|ceil|floor").hasArg(true).desc(MessageFormat.format(bundle.getString("arg.descr.cmd.rounding"), Arguments.DEFAULT_ROUNDING_STRATEGY)).build(); Option compression = Option.builder(OUT_COMPRESSION_ARG).hasArg(true).argName("png|jpg|gif|bmp").desc(bundle.getString("arg.descr.cmd.outcompression")).build(); Option compressionQuality = Option.builder(COMPRESSION_QUALITY_ARG).hasArg(true).argName("0.0-1.0").desc(MessageFormat.format(bundle.getString("arg.descr.cmd.compression"), String.valueOf(Arguments.DEFAULT_COMPRESSION_QUALITY))).build(); Option upScalingAlgo = Option.builder(UPSCALING_ALGO_ARG).hasArg(true).argName(EScalingAlgorithm.getCliArgString(EScalingAlgorithm.Type.UPSCALING)).desc(MessageFormat.format(bundle.getString("arg.descr.scalingalgo"), Arguments.DEFAULT_PLATFORM)).build(); Option downScalingAlgo = Option.builder(DOWNSCALING_ALGO_ARG).hasArg(true).argName(EScalingAlgorithm.getCliArgString(EScalingAlgorithm.Type.DOWNSCALING)).desc(MessageFormat.format(bundle.getString("arg.descr.scalingalgo"), Arguments.DEFAULT_PLATFORM)).build(); Option skipExistingFiles = Option.builder(SKIP_EXISTING_ARG).desc(bundle.getString("arg.descr.skipexisting")).build(); Option androidIncludeLdpiTvdpi = Option.builder("androidIncludeLdpiTvdpi").desc(bundle.getString("arg.descr.androidmipmap")).build(); Option mipmapInsteadOfDrawable = Option.builder("androidMipmapInsteadOfDrawable").desc(bundle.getString("arg.descr.androidldpi")).build(); Option iosCreateImagesetFolders = Option.builder("iosCreateImagesetFolders").desc(bundle.getString("arg.descr.iosimageset")).build(); Option skipUpscaling = Option.builder("skipUpscaling").desc(bundle.getString("arg.descr.skipupscaling")).build(); Option verboseLog = Option.builder(VERBOSE_ARG).desc(bundle.getString("arg.descr.cmd.verbose")).build(); Option haltOnError = Option.builder("haltOnError").desc(bundle.getString("arg.descr.halterror")).build(); Option antiAliasing = Option.builder("antiAliasing").desc(bundle.getString("arg.descr.antialiasing")).build(); Option enablePngCrush = Option.builder("postProcessorPngCrush").desc(bundle.getString("arg.descr.pngcrush")).build(); Option postWebpConvert = Option.builder("postProcessorWebp").desc(bundle.getString("arg.descr.webp")).build(); Option keepUnPostProcessed = Option.builder("keepOriginalPostProcessedFiles").desc(bundle.getString("arg.descr.keeporiginal")).build(); Option dpScaleIsHeight = Option.builder(SCALE_IS_HEIGHT_DP_ARG).desc(bundle.getString("arg.descr.cmd.dpIsHeight")).build(); Option dryRun = Option.builder("dryRun").desc(bundle.getString("arg.descr.dryrun")).build(); Option enableMozJpeg = Option.builder("postProcessorMozJpeg").desc(bundle.getString("arg.descr.mozjpeg")).build(); Option cleanBeforeConvert = Option.builder("clean").desc(bundle.getString("arg.descr.clean")).build(); Option help = Option.builder("h").longOpt("help").desc(bundle.getString("arg.descr.cmd.help")).build(); Option version = Option.builder("v").longOpt("version").desc(bundle.getString("arg.descr.cmd.version")).build(); Option gui = Option.builder("gui").desc(bundle.getString("arg.descr.cmd.gui")).build(); OptionGroup mainArgs = new OptionGroup(); mainArgs.addOption(srcOpt).addOption(help).addOption(version).addOption(gui); mainArgs.setRequired(true); options.addOption(srcScaleOpt).addOption(dstOpt); options.addOption(platform).addOption(compression).addOption(compressionQuality).addOption(threadCount).addOption(roundingHandler) .addOption(upScalingAlgo).addOption(downScalingAlgo); options.addOption(skipExistingFiles).addOption(skipUpscaling).addOption(androidIncludeLdpiTvdpi).addOption(verboseLog) .addOption(antiAliasing).addOption(dryRun).addOption(haltOnError).addOption(mipmapInsteadOfDrawable) .addOption(enablePngCrush).addOption(postWebpConvert).addOption(dpScaleIsHeight).addOption(enableMozJpeg) .addOption(keepUnPostProcessed).addOption(iosCreateImagesetFolders).addOption(cleanBeforeConvert); options.addOptionGroup(mainArgs); return options; } }