/* * Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.com> * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ package org.geometerplus.fbreader.network; import java.io.*; import java.net.*; import org.geometerplus.zlibrary.core.constants.MimeTypes; import org.geometerplus.zlibrary.core.filesystem.ZLFile; import org.geometerplus.zlibrary.core.image.ZLFileImage; import org.geometerplus.zlibrary.core.image.ZLLoadableImage; import org.geometerplus.zlibrary.core.network.ZLNetworkManager; import org.geometerplus.zlibrary.core.network.ZLNetworkException; import org.geometerplus.fbreader.Paths; public final class NetworkImage extends ZLLoadableImage implements MimeTypes { public final String Url; public NetworkImage(String url, String mimeType) { super(mimeType); Url = url; new File(Paths.networkCacheDirectory()).mkdirs(); } private static final String TOESCAPE = "<>:\"|?*\\"; public static String makeImageFilePath(String url, String mimeType) { URI uri; try { uri = new URI(url); } catch (java.net.URISyntaxException ex) { return null; } String host = uri.getHost(); StringBuilder path = new StringBuilder(host); if (host.startsWith("www.")) { path.delete(0, 4); } path.insert(0, File.separator); path.insert(0, Paths.networkCacheDirectory()); int index = path.length(); path.append(uri.getPath()); int nameIndex = index; while (index < path.length()) { char ch = path.charAt(index); if (TOESCAPE.indexOf(ch) != -1) { path.setCharAt(index, '_'); } if (ch == '/') { if (index + 1 == path.length()) { path.deleteCharAt(index); } else { path.setCharAt(index, '_'); nameIndex = index + 1; } } ++index; } String ext = null; if (MIME_IMAGE_PNG.equals(mimeType)) { ext = ".png"; } else if (MIME_IMAGE_JPEG.equals(mimeType)) { if (path.length() > 5 && path.substring(path.length() - 5).equals(".jpeg")) { ext = ".jpeg"; } else { ext = ".jpg"; } } if (ext == null) { int j = path.lastIndexOf("."); if (j > nameIndex) { ext = path.substring(j); path.delete(j, path.length()); } else { ext = ""; } } else if (path.length() > ext.length() && path.substring(path.length() - ext.length()).equals(ext)) { path.delete(path.length() - ext.length(), path.length()); } String query = uri.getQuery(); if (query != null) { index = 0; while (index < query.length()) { int j = query.indexOf("&", index); if (j == -1) { j = query.length(); } String param = query.substring(index, j); if (!param.startsWith("username=") && !param.startsWith("password=") && !param.endsWith("=")) { int k = path.length(); path.append("_").append(param); while (k < path.length()) { char ch = path.charAt(k); if (TOESCAPE.indexOf(ch) != -1 || ch == '/') { path.setCharAt(k, '_'); } ++k; } } index = j + 1; } } return path.append(ext).toString(); } public String getFilePath() { return makeImageFilePath(Url, mimeType()); } @Override public int sourceType() { return SourceType.NETWORK; } @Override public String getId() { return Url; } public String getURI() { // TODO: implement return null; } @Override public void synchronize() { synchronizeInternal(false); } @Override public void synchronizeFast() { synchronizeInternal(true); } private final void synchronizeInternal(boolean doFast) { if (isSynchronized()) { return; } try { final String path = getFilePath(); if (path == null) { // TODO: error message ??? return; } final int index = path.lastIndexOf(File.separator); if (index != -1) { final String dir = path.substring(0, index); final File dirFile = new File(dir); if (!dirFile.exists() && !dirFile.mkdirs()) { // TODO: error message ??? return; } if (!dirFile.exists() || !dirFile.isDirectory()) { // TODO: error message ??? return; } } final File imageFile = new File(path); if (imageFile.exists()) { final long diff = System.currentTimeMillis() - imageFile.lastModified(); final long valid = 7 * 24 * 60 * 60 * 1000; // one week in milliseconds; FIXME: hardcoded const if (diff >= 0 && diff <= valid) { return; } imageFile.delete(); } if (doFast) { return; } try { ZLNetworkManager.Instance().downloadToFile(Url, imageFile); } catch (ZLNetworkException e) { } } finally { setSynchronized(); } } @Override public byte[] byteData() { if (!isSynchronized()) { return null; } final String path = getFilePath(); if (path == null) { return null; } return new ZLFileImage(mimeType(), ZLFile.createFileByPath(path)).byteData(); } }