diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index 4a9191d860d..78e04e47569 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -112,6 +112,17 @@ jsoup 1.5.2 + + de.schlichtherle.truezip + truezip-file + 7.6.3 + + + de.schlichtherle.truezip + truezip-driver-zip + 7.6.3 + + diff --git a/Mage.Client/src/main/java/mage/client/util/FileUtils.java b/Mage.Client/src/main/java/mage/client/util/FileUtils.java deleted file mode 100644 index 47884b981c9..00000000000 --- a/Mage.Client/src/main/java/mage/client/util/FileUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -package mage.client.util; - -import java.io.File; - -public class FileUtils { - public static File getTempDir(String key) { - String tmpDir = System.getProperty("java.io.tmpdir"); - String sep = System.getProperty("file.separator"); - - if (!tmpDir.endsWith(sep)) - tmpDir += sep; - - tmpDir += key + "-" + java.util.UUID.randomUUID().toString(); - - File dir = new File(tmpDir); - if (!dir.mkdirs()) { - throw new RuntimeException("couldn't create temp directory " + tmpDir); - } - - return dir; - - } -} diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java index 3372681a47b..9a71f5da1a7 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/DownloadPictures.java @@ -1,5 +1,10 @@ package org.mage.plugins.card.images; +import de.schlichtherle.truezip.file.TArchiveDetector; +import de.schlichtherle.truezip.file.TConfig; +import de.schlichtherle.truezip.file.TFile; +import de.schlichtherle.truezip.file.TFileOutputStream; +import de.schlichtherle.truezip.fs.FsOutputOption; import mage.cards.Card; import mage.client.dialog.PreferencesDialog; import mage.remote.Connection; @@ -61,6 +66,9 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab public static void main(String[] args) { startDownload(null, null, null); + TConfig config = TConfig.get(); + config.setArchiveDetector(new TArchiveDetector("zip")); + config.getOutputPreferences().set(FsOutputOption.STORE); } public static void startDownload(JFrame frame, Set allCards, String imagesPath) { @@ -204,7 +212,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } public static boolean checkForNewCards(Set allCards, String imagesPath) { - File file; + TFile file; for (Card card : allCards) { if (card.getCardNumber() > 0 && !card.getExpansionSetCode().isEmpty()) { CardInfo url = new CardInfo(card.getName(), card.getExpansionSetCode(), card.getCardNumber(), 0, false, card.canTransform(), card.isNightCard()); @@ -212,9 +220,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (basicLandPattern.matcher(card.getName()).matches()) { withCollectorId = true; } - file = new File(CardImageUtils.getImagePath(url, withCollectorId, imagesPath)); - if (!file.exists()) + file = new TFile(CardImageUtils.getImagePath(url, withCollectorId, imagesPath)); + if (!file.exists()) { return true; + } } } return false; @@ -267,7 +276,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab log.error(e); } - File file; + TFile file; /** * check to see which cards we already have @@ -277,7 +286,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (basicLandPattern.matcher(card.getName()).matches()) { withCollectorId = true; } - file = new File(CardImageUtils.getImagePath(card, withCollectorId, imagesPath)); + file = new TFile(CardImageUtils.getImagePath(card, withCollectorId, imagesPath)); if (!file.exists()) { cardsToDownload.add(card); } @@ -300,16 +309,11 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private static ArrayList getTokenCardUrls() throws RuntimeException { ArrayList list = new ArrayList(); - HashSet filter = new HashSet(); InputStream in = DownloadPictures.class.getClassLoader().getResourceAsStream("card-pictures-tok.txt"); - readImageURLsFromFile(in, list, filter); - return list; - } - private static void readImageURLsFromFile(InputStream in, ArrayList list, Set filter) throws RuntimeException { if (in == null) { log.error("resources input stream is null"); - return; + return list; } BufferedReader reader = null; @@ -361,6 +365,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } } + return list; } @Override @@ -414,7 +419,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab } if (url != null) { - Runnable task = new DownloadTask(card, new URL(url), imagesPath); + Runnable task = new DownloadTask(card, new URL(url)); executor.execute(task); } else { synchronized (sync) { @@ -439,38 +444,34 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab private CardInfo card; private URL url; - private String imagesPath; - public DownloadTask(CardInfo card, URL url, String imagesPath) { + public DownloadTask(CardInfo card, URL url) { this.card = card; this.url = url; - this.imagesPath = imagesPath; } @Override public void run() { try { - createDirForCard(card, imagesPath); - boolean withCollectorId = false; if (basicLandPattern.matcher(card.getName()).matches()) { withCollectorId = true; } - File fileOut = new File(CardImageUtils.getImagePath(card, withCollectorId)); + File temporaryFile = new File(Constants.IO.imageBaseDir + File.separator + card.hashCode() + "." + card.getName() + ".jpg"); BufferedInputStream in = new BufferedInputStream(url.openConnection(p).getInputStream()); - BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileOut)); + BufferedOutputStream out = new BufferedOutputStream(new TFileOutputStream(temporaryFile)); byte[] buf = new byte[1024]; - int len = 0; + int len; while ((len = in.read(buf)) != -1) { // user cancelled if (cancel) { in.close(); out.flush(); out.close(); - // delete what was written so far - fileOut.delete(); + temporaryFile.delete(); + return; } out.write(buf, 0, len); } @@ -479,8 +480,10 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab out.flush(); out.close(); + TFile outputFile = new TFile(CardImageUtils.getImagePath(card, withCollectorId)); if (card.isTwoFacedCard()) { - BufferedImage image = ImageIO.read(fileOut); + BufferedImage image = ImageIO.read(temporaryFile); + temporaryFile.delete(); if (image.getHeight() == 470) { BufferedImage renderedImage = new BufferedImage(265, 370, BufferedImage.TYPE_INT_RGB); renderedImage.getGraphics(); @@ -491,20 +494,23 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab graphics2D.drawImage(image, 0, 0, 265, 370, 41, 62, 306, 432, null); } graphics2D.dispose(); - writeImageToFile(renderedImage, fileOut); + writeImageToFile(renderedImage, outputFile); } + } else { + new TFile(temporaryFile).cp_rp(outputFile); + temporaryFile.delete(); } - synchronized (sync) { - update(cardIndex + 1); - } } catch (Exception e) { log.error(e, e); } + synchronized (sync) { + update(cardIndex + 1); + } } - private void writeImageToFile(BufferedImage image, File file) throws IOException { + private void writeImageToFile(BufferedImage image, TFile file) throws IOException { Iterator iter = ImageIO.getImageWritersByFormatName("jpg"); ImageWriter writer = (ImageWriter) iter.next(); @@ -512,21 +518,17 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); iwp.setCompressionQuality(0.96f); - FileImageOutputStream output = new FileImageOutputStream(file); + File tempFile = new File(Constants.IO.imageBaseDir + File.separator + image.hashCode() + file.getName()); + FileImageOutputStream output = new FileImageOutputStream(tempFile); writer.setOutput(output); IIOImage image2 = new IIOImage(image, null, null); writer.write(null, image2, iwp); writer.dispose(); output.close(); - } - } - private static File createDirForCard(CardInfo card, String imagesPath) throws Exception { - File setDir = new File(CardImageUtils.getImageDir(card, imagesPath)); - if (!setDir.exists()) { - setDir.mkdirs(); + new TFile(tempFile).cp_rp(file); + tempFile.delete(); } - return setDir; } private void update(int card) { @@ -545,7 +547,7 @@ public class DownloadPictures extends DefaultBoundedRangeModel implements Runnab if (basicLandPattern.matcher(cardInfo.getName()).matches()) { withCollectorId = true; } - File file = new File(CardImageUtils.getImagePath(cardInfo, withCollectorId)); + TFile file = new TFile(CardImageUtils.getImagePath(cardInfo, withCollectorId)); if (file.exists()) { cardsIterator.remove(); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java index a2ed1ea6f18..f390c4d0e1f 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/images/ImageCache.java @@ -4,19 +4,20 @@ import com.google.common.base.Function; import com.google.common.collect.ComputationException; import com.google.common.collect.MapMaker; import com.mortennobel.imagescaling.ResampleOp; +import de.schlichtherle.truezip.file.TFile; +import de.schlichtherle.truezip.file.TFileInputStream; +import de.schlichtherle.truezip.file.TFileOutputStream; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.imageio.ImageIO; import mage.view.CardView; import org.apache.log4j.Logger; import org.mage.plugins.card.constants.Constants; import org.mage.plugins.card.utils.CardImageUtils; -import javax.imageio.ImageIO; -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.File; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - /** * This class stores ALL card images in a cache with soft values. this means * that the images may be garbage collected when they are not needed any more, but will @@ -65,21 +66,27 @@ public class ImageCache { CardInfo info = new CardInfo(name, set, collectorId, type); - if (collectorId == 0) info.setToken(true); + if (collectorId == 0) { + info.setToken(true); + } String path = CardImageUtils.getImagePath(info); - if (path == null) return null; - File file = new File(path); + if (path == null) { + return null; + } + TFile file = new TFile(path); if (thumbnail && path.endsWith(".jpg")) { - String thumbnailPath = path.replace(".jpg", ".thumb.jpg"); - File thumbnailFile = new File(thumbnailPath); + String thumbnailPath = path.replace(".zip", ".thumb.zip"); + TFile thumbnailFile = new TFile(thumbnailPath); if (thumbnailFile.exists()) { //log.debug("loading thumbnail for " + key + ", path="+thumbnailPath); return loadImage(thumbnailFile); } else { BufferedImage image = loadImage(file); image = getWizardsCard(image); - if (image == null) return null; + if (image == null) { + return null; + } //log.debug("creating thumbnail for " + key); return makeThumbnail(image, thumbnailPath); } @@ -91,10 +98,11 @@ public class ImageCache { "Requested image doesn't fit the requirement for key (##): " + key); } } catch (Exception ex) { - if (ex instanceof ComputationException) + if (ex instanceof ComputationException) { throw (ComputationException) ex; - else + } else { throw new ComputationException(ex); + } } } }); @@ -138,8 +146,9 @@ public class ImageCache { // legitimate, happens when a card has no image return null; } catch (ComputationException ex) { - if (ex.getCause() instanceof NullPointerException) + if (ex.getCause() instanceof NullPointerException) { return null; + } log.error(ex,ex); return null; } @@ -163,13 +172,15 @@ public class ImageCache { * file to load image from * @return {@link BufferedImage} */ - public static BufferedImage loadImage(File file) { + public static BufferedImage loadImage(TFile file) { BufferedImage image = null; if (!file.exists()) { return null; } try { - image = ImageIO.read(file); + TFileInputStream inputStream = new TFileInputStream(file); + image = ImageIO.read(inputStream); + inputStream.close(); } catch (Exception e) { log.error(e, e); } @@ -179,10 +190,12 @@ public class ImageCache { public static BufferedImage makeThumbnail(BufferedImage original, String path) { BufferedImage image = getResizedImage(original, Constants.THUMBNAIL_SIZE_FULL); - File imagePath = new File(path); + TFile imageFile = new TFile(path); try { //log.debug("thumbnail path:"+path); - ImageIO.write(image, "jpg", imagePath); + TFileOutputStream outputStream = new TFileOutputStream(imageFile); + ImageIO.write(image, "jpg", outputStream); + outputStream.close(); } catch (Exception e) { log.error(e,e); } @@ -203,8 +216,9 @@ public class ImageCache { int tgtWidth = Constants.CARD_SIZE_FULL.width; int tgtHeight = Constants.CARD_SIZE_FULL.height; - if (srcWidth == tgtWidth && srcHeight == tgtHeight) + if (srcWidth == tgtWidth && srcHeight == tgtHeight) { return original; + } ResampleOp resampleOp = new ResampleOp(tgtWidth, tgtHeight); BufferedImage image = resampleOp.filter(original, null); @@ -216,8 +230,9 @@ public class ImageCache { * panel For future use. */ private static BufferedImage getFullSizeImage(BufferedImage original, double scale) { - if (scale == 1) + if (scale == 1) { return original; + } ResampleOp resampleOp = new ResampleOp((int) (original.getWidth() * scale), (int) (original.getHeight() * scale)); BufferedImage image = resampleOp.filter(original, null); return image; @@ -239,12 +254,14 @@ public class ImageCache { public static BufferedImage getImage(CardView card, int width, int height) { String key = getKey(card); BufferedImage original = getImage(key); - if (original == null) + if (original == null) { return null; + } double scale = Math.min((double) width / original.getWidth(), (double) height / original.getHeight()); - if (scale > 1) + if (scale > 1) { scale = 1; + } return getFullSizeImage(original, scale); } diff --git a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java index 075038a370b..a5480b53fd6 100644 --- a/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java +++ b/Mage.Client/src/main/java/org/mage/plugins/card/utils/CardImageUtils.java @@ -1,12 +1,11 @@ package org.mage.plugins.card.utils; +import de.schlichtherle.truezip.file.TFile; +import java.util.HashMap; import org.mage.plugins.card.constants.Constants; import org.mage.plugins.card.images.CardInfo; import org.mage.plugins.card.properties.SettingsManager; -import java.io.File; -import java.util.HashMap; - public class CardImageUtils { private static HashMap pathCache = new HashMap(); @@ -22,17 +21,17 @@ public class CardImageUtils { String filePath; String suffix = ".jpg"; - File file = null; + TFile file; if (card.isToken()) { if (pathCache.containsKey(card)) { return pathCache.get(card); } filePath = getTokenImagePath(card); - file = new File(filePath); + file = new TFile(filePath); if (!file.exists()) { filePath = searchForCardImage(card); - file = new File(filePath); + file = new TFile(filePath); } if (file.exists()) { @@ -40,11 +39,11 @@ public class CardImageUtils { } } else { filePath = getImagePath(card, false); - file = new File(filePath); + file = new TFile(filePath); if (!file.exists()) { filePath = getImagePath(card, true); - file = new File(filePath); + file = new TFile(filePath); } } @@ -53,7 +52,7 @@ public class CardImageUtils { */ if (file == null || !file.exists()) { filePath = cleanString(card.getName()) + suffix; - file = new File(filePath); + file = new TFile(filePath); } if (file.exists()) { @@ -66,17 +65,16 @@ public class CardImageUtils { private static String getTokenImagePath(CardInfo card) { String filename = getImagePath(card, false); - File file = new File(filename); + TFile file = new TFile(filename); if (!file.exists()) { CardInfo updated = new CardInfo(card); updated.setName(card.getName() + " 1"); filename = getImagePath(updated, false); - file = new File(filename); + file = new TFile(filename); if (!file.exists()) { updated = new CardInfo(card); updated.setName(card.getName() + " 2"); filename = getImagePath(updated, false); - file = new File(filename); } } @@ -84,14 +82,14 @@ public class CardImageUtils { } private static String searchForCardImage(CardInfo card) { - File file = null; - String path = ""; + TFile file; + String path; CardInfo c = new CardInfo(card); for (String set : SettingsManager.getIntance().getTokenLookupOrder()) { c.setSet(set); path = getTokenImagePath(c); - file = new File(path); + file = new TFile(path); if (file.exists()) { pathCache.put(card, path); return path; @@ -106,9 +104,9 @@ public class CardImageUtils { char c; for (int i = 0; i < in.length(); i++) { c = in.charAt(i); - if (c == ' ' || c == '-') + if (c == ' ' || c == '-') { out.append('_'); - else if (Character.isLetterOrDigit(c)) { + } else if (Character.isLetterOrDigit(c)) { out.append(c); } } @@ -134,9 +132,9 @@ public class CardImageUtils { String set = updateSet(card.getSet(), false).toUpperCase(); String imagesDir = (imagesPath != null ? imagesPath : Constants.IO.imageBaseDir); if (card.isToken()) { - return imagesDir + File.separator + "TOK" + File.separator + set; + return imagesDir + TFile.separator + "TOK" + ".zip" + TFile.separator + set; } else { - return imagesDir + File.separator + set; + return imagesDir + TFile.separator + set + ".zip" + TFile.separator + set; } } @@ -148,9 +146,9 @@ public class CardImageUtils { String type = card.getType() != 0 ? " " + Integer.toString(card.getType()) : ""; String name = card.getName(); if (withCollector) { - return getImageDir(card, imagesPath) + File.separator + name + "." + card.getCollectorId() + ".full.jpg"; + return getImageDir(card, imagesPath) + TFile.separator + name + "." + card.getCollectorId() + ".full.jpg"; } else { - return getImageDir(card, imagesPath) + File.separator + name + type + ".full.jpg"; + return getImageDir(card, imagesPath) + TFile.separator + name + type + ".full.jpg"; } } }