package brickinvetory;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Method;
import org.json.JSONArray;
import org.json.JSONObject;
/**
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* @author Jarema Czajkowski
* @version 0.029
* @since 02/09/2016
*
*/
public class FixImages {
private static final String urlTemplate = "http://rebrickable.com/api/get_part?key=%s&format=json&part_id=%s&inc_ext=1";
private static final String appVersion = "0.029";
private static final String[] errCodes = {"INVALIDKEY","NOPART","INVALIDFORMAT"};
private static Options appOptions;
public static void main(String[] args) throws Exception {
Console console = System.console();
if (console == null) {
System.out.println("Unable to fetch console");
return;
}
appOptions = new Options();
Option opt1 = new Option("k" ,"api-key" ,true ,"To be able to directly accessing the various Rebrickable functions and data you must use vaild API key");
opt1.setRequired(true);
appOptions.addOption(opt1);
Option opt2 = new Option("s" ,"source" ,true ,"Get plain text file with comma|semicolon-separated values, needed to process request");
opt2.setArgName("FILE");
appOptions.addOption(opt2);
Option opt3 = new Option("o" ,"output" ,true ,"Destination directory to place file after download");
opt3.setRequired(true);
opt3.setArgName("DIR");
appOptions.addOption(opt3);
Option opt4 = new Option("c" ,"default-color" ,true ,"A value used when color of you choice does not exist");
opt4.setArgName("NUMBER");
appOptions.addOption(opt4);
appOptions.addOption(new Option("h" ,"help" ,false ,"Show this help message and exit"));
appOptions.addOption(new Option("u" ,"use-default-url" ,false ,"URL of the main part image (tries to use most common color)"));
CommandLineParser parser = new DefaultParser();
if (args.length==0) {
printHelp();
System.exit(1);
}
CommandLine cmd = null;
try {
cmd = parser.parse(appOptions ,args);
} catch (ParseException ex) {
List argList = Arrays.asList(args);
if(argList.contains("-h") || argList.contains("--help"))
printHelp();
else
System.out.println(ex.getLocalizedMessage());
System.exit(1);
}
if (cmd.hasOption("help")) {
printHelp();
System.exit(1);
}
String apiKey = cmd.getOptionValue("api-key");
String sourcePath = cmd.getOptionValue("source");
String outputPath = cmd.getOptionValue("output");
String defaultColor = cmd.getOptionValue("default-color");
boolean defaultURL = cmd.hasOption("use-default-url");
StringBuilder userData = new StringBuilder();
if (sourcePath != null) {
File fileObj = new File(sourcePath);
boolean canRead;
try {
canRead = fileObj.isFile() && fileObj.canRead();
} catch (Exception ex) {
canRead = false;
}
if (canRead) {
FileInputStream fis = new FileInputStream(fileObj);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
String line = null;
while ((line = reader.readLine()) != null) {
line = line.replaceAll("[^a-zA-Z0-9_.,;]" ,"").replace(";" ,",");
if (!isBlank(line)) {
userData.append(line);
userData.append("\n");
}
}
reader.close();
} else {
System.out.println(String.format("%s is not readable" ,fileObj.getName()));
System.exit(1);
}
}
int partDownloaded = 0;
int partExcluded = 0;
if (userData.length() > 10) {
String[] lines = userData.toString().split("\n");
for(String s: lines) {
String[] data = s.split(",");
String partFile = data[0];
String partID = partFile.replaceFirst("[.][^.]+$" ,"");
String partColor;
try {
partColor= data[1];
} catch(Exception ex) {
partColor= "-1";
}
boolean success = true;
if ( !isBlank(apiKey) && !isBlank(partID) ) {
System.out.println(String.format("Part #%s", partID));
String sourceURI = String.format(urlTemplate ,apiKey ,partID);
String responseStr = null;
JSONObject responseJson = null;
try {
responseStr = readJsonFromUrl(sourceURI);
responseJson= new JSONObject(responseStr);
} catch (Exception ex) {
success = false;
if(Arrays.asList(errCodes).contains(responseStr))
System.out.println(responseStr);
else
System.out.println("INVALIDDATA");
}
if (responseJson != null) {
String partURL;
try {
partURL = buildUrl(responseJson ,partColor ,defaultColor);
} catch (Exception ex) {
partURL = "";
}
boolean isPartURL = partURL.matches("^[a-zA-Z]++://[a-zA-Z.]++/img/[a-zA-Z0-9./]++$");
if (!isPartURL && defaultURL) {
partURL = responseJson.optString("part_img_url");;
isPartURL = true;
}
if(isPartURL) {
Path partpath = Paths.get(outputPath ,partColor ,partFile);
File dirpath = partpath.getParent().toFile();
if (!dirpath.exists()) dirpath.mkdirs();
System.out.println(partURL);
boolean isFile = true;
try {
downloadResource(partURL ,partpath.toString());
} catch (FileNotFoundException|MalformedURLException ex) {
success= false;
isFile = false;
System.out.println("NOPART");
} finally {
if (isFile)
try {
BufferedImage partimage = ImageIO.read(partpath.toFile());
int targetHeight = 60;
int targetWidth = (targetHeight*partimage.getWidth())/partimage.getHeight();
BufferedImage scaledImg = Scalr.resize(partimage, Method.QUALITY, targetWidth, targetHeight, Scalr.OP_ANTIALIAS);
ImageIO.write(scaledImg ,fileExtension(partpath.toFile().getName() ,true) ,partpath.toFile());
System.out.println("Saved into: " +dirpath.toString());
} catch (IOException ex) {
success = false;
System.out.println("IOERROR");
}
}
} else { success = false; System.out.println("NOPART"); }
}
}
if (success) partDownloaded += 1; else partExcluded +=1;
}
};
System.out.println(String.format("\nDownloaded %d\tExcluded %d", partDownloaded , partExcluded));
}
private static void printHelp() {
HelpFormatter formatter = new HelpFormatter();
String header = String.format("Brick Inventory Image Downloader %s\nCopyright (c) 2016 Jarema Czajkowski\n\n" ,appVersion);
formatter.printHelp("FixImages.jar" ,header ,appOptions ,"" ,true);
}
private static boolean isBlank(String str) {
return str == null ? true : str.trim().length() <=0;
}
private static String fileExtension(String str, boolean withoutDot) {
int index = str.lastIndexOf(".");
String ext = "";
if (index > 0) {
if (withoutDot) index++;
ext = str.substring(index).toLowerCase();
}
return ext ;
}
private static boolean colorExist(JSONArray json, String color) {
if (json != null)
for(int n = 0;n 0) {
for(int n = 0;n