diff --git a/demo/.classpath b/demo/.classpath index c9a20ce..f1fbd8d 100644 --- a/demo/.classpath +++ b/demo/.classpath @@ -8,5 +8,9 @@ + + + + diff --git a/demo/src/net/imgseek/server/demo/Iskdaemon_demo.gwt.xml b/demo/src/net/imgseek/server/demo/Iskdaemon_demo.gwt.xml index 7c8c54a..0258393 100644 --- a/demo/src/net/imgseek/server/demo/Iskdaemon_demo.gwt.xml +++ b/demo/src/net/imgseek/server/demo/Iskdaemon_demo.gwt.xml @@ -12,7 +12,10 @@ - + + + + diff --git a/demo/src/net/imgseek/server/demo/client/Iskdaemon_demo.java b/demo/src/net/imgseek/server/demo/client/Iskdaemon_demo.java index baf3c53..150ef57 100644 --- a/demo/src/net/imgseek/server/demo/client/Iskdaemon_demo.java +++ b/demo/src/net/imgseek/server/demo/client/Iskdaemon_demo.java @@ -20,6 +20,13 @@ */ package net.imgseek.server.demo.client; +import gwtupload.client.IUploadStatus.Status; +import gwtupload.client.IUploader; +import gwtupload.client.IUploader.OnFinishUploaderHandler; +import gwtupload.client.IUploader.UploadedInfo; +import gwtupload.client.MultiUploader; + +import java.util.ArrayList; import java.util.List; import net.imgseek.server.demo.shared.DbImageResult; @@ -46,6 +53,7 @@ public class Iskdaemon_demo implements EntryPoint, ValueChangeHandler { private static final int GRID_COLS = 4; private static final int NUMRES = 12; + private static final NumberFormat df = NumberFormat.getFormat("#.##"); /** * Create a remote service proxy to talk to the server-side Isk service. @@ -54,6 +62,28 @@ public class Iskdaemon_demo implements EntryPoint, ValueChangeHandler { .create(IskDemoService.class); private final Grid resultsGrid = new Grid(3, GRID_COLS); + private final MultiUploader uploaderControl = new MultiUploader(); + + private OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() { + public void onFinish(IUploader uploader) { + if (uploader.getStatus() == Status.SUCCESS) { + // The server sends useful information to the client by default + UploadedInfo info = uploader.getServerInfo(); + List result = new ArrayList(); + String ps[] = info.message.split(";"); + + for (int i = 0; i < ps.length / 3; i++) { + DbImageResult nr = new DbImageResult(); + nr.setId(Integer.parseInt(ps[i * 3])); + nr.setScore(Double.parseDouble(ps[i * 3 + 1])); + nr.setUrl(ps[i * 3 + 2]); + result.add(nr); + } + showResults(result); + uploaderControl.reset(); + } + } + }; /** * This is the entry point method. @@ -63,11 +93,20 @@ public void onModuleLoad() { RootPanel.get("main").add(mvp); HorizontalPanel hhp = new HorizontalPanel(); mvp.add(hhp); - hhp.add(new HTML("

isk-daemon example

")); + hhp.add(new HTML("

isk-daemon example

")); hhp.add(new HTML( - "

isk-daemon is an open source database server capable of adding content-based (visual) image searching to any image related website or software. Click on the '+ similar' link below each image to search by visual similarity. See more details about this demo, including source code.

")); + "

isk-daemon is an open source database server capable of adding content-based (visual) image searching to any image related website or software. Click on the '+ similar' link below each image to search by visual similarity. You can also upload your own image by clicking on the 'Choose file' button below. See more details about this demo, including source code.

")); hhp.add(new Hyperlink("Random images", "similar-0")); + // Create a new uploader panel and attach it to the document + + uploaderControl.setAutoSubmit(true); + mvp.add(uploaderControl); + + // Add a finish handler which will load the image once the upload + // finishes + uploaderControl.addOnFinishUploadHandler(onFinishUploaderHandler); + mvp.add(resultsGrid); mvp.add(new HTML( "
Copyright 2012 imgSeek project. Sample images are copyrighted by Caltech 256. Includes 30,607 images, covering a large number of categories.")); @@ -83,6 +122,27 @@ public void onModuleLoad() { History.fireCurrentHistoryState(); } + private void showResults(List result) { + resultsGrid.clear(); + int i = 0; + + for (DbImageResult res : result) { + VerticalPanel rvp = new VerticalPanel(); + rvp.setStyleName("dotted"); + rvp.add(new Image(res.getUrl())); + HorizontalPanel hc = new HorizontalPanel(); + String scoreLabel = "(random) "; + if (res.getScore() > 0) + scoreLabel = df.format(res.getScore()) + "%"; + hc.add(new Label(scoreLabel)); + hc.add(new Hyperlink(" + similar", "similar-" + res.getId())); + rvp.add(hc); + + resultsGrid.setWidget(i / GRID_COLS, i % GRID_COLS, rvp); + i++; + } + } + @Override public void onValueChange(ValueChangeEvent event) { int tid = 0; @@ -92,8 +152,6 @@ public void onValueChange(ValueChangeEvent event) { e.printStackTrace(); } - final NumberFormat df = NumberFormat.getFormat("#.##"); - iskDemoService.queryImgID(tid, NUMRES, false, new AsyncCallback>() { public void onFailure(Throwable caught) { @@ -101,27 +159,9 @@ public void onFailure(Throwable caught) { } public void onSuccess(List result) { - resultsGrid.clear(); - int i = 0; - - for (DbImageResult res : result) { - VerticalPanel rvp = new VerticalPanel(); - rvp.setStyleName("dotted"); - rvp.add(new Image(res.getUrl())); - HorizontalPanel hc = new HorizontalPanel(); - String scoreLabel = "(random) "; - if (res.getScore() > 0) - scoreLabel = df.format(res.getScore()) + "%"; - hc.add(new Label(scoreLabel)); - hc.add(new Hyperlink(" + similar", "similar-" - + res.getId())); - rvp.add(hc); - - resultsGrid.setWidget(i / GRID_COLS, i % GRID_COLS, - rvp); - i++; - } + showResults(result); } + }); } -} +} \ No newline at end of file diff --git a/demo/src/net/imgseek/server/demo/server/IskDaemonClient.java b/demo/src/net/imgseek/server/demo/server/IskDaemonClient.java new file mode 100644 index 0000000..6805dea --- /dev/null +++ b/demo/src/net/imgseek/server/demo/server/IskDaemonClient.java @@ -0,0 +1,29 @@ +package net.imgseek.server.demo.server; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.xmlrpc.client.XmlRpcClient; +import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; + +public class IskDaemonClient { + public XmlRpcClient client; + + public IskDaemonClient() { + + XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); + try { + config.setServerURL(new URL("http://127.0.0.1:31128/RPC")); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } // isk-daemon + // XML-RPC + // endpoint + // URL + config.setEnabledForExtensions(true); + this.client = new XmlRpcClient(); + this.client.setConfig(config); + + } +} \ No newline at end of file diff --git a/demo/src/net/imgseek/server/demo/server/IskDemoServiceImpl.java b/demo/src/net/imgseek/server/demo/server/IskDemoServiceImpl.java index 4e1fe96..ab488fa 100644 --- a/demo/src/net/imgseek/server/demo/server/IskDemoServiceImpl.java +++ b/demo/src/net/imgseek/server/demo/server/IskDemoServiceImpl.java @@ -20,8 +20,6 @@ */ package net.imgseek.server.demo.server; -import java.net.MalformedURLException; -import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -30,8 +28,6 @@ import net.imgseek.server.demo.shared.DbImageResult; import org.apache.xmlrpc.XmlRpcException; -import org.apache.xmlrpc.client.XmlRpcClient; -import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; import com.google.gwt.user.server.rpc.RemoteServiceServlet; @@ -43,23 +39,13 @@ public class IskDemoServiceImpl extends RemoteServiceServlet implements IskDemoService { private static final int DB_NUM_IMGS = 30607; // total number of images on - // DB. Used for quickly - // selecting random ids - private XmlRpcClient client; - private ImageDb imgIdDb = new ImageDb(); + private IskDaemonClient iskClient = new IskDaemonClient(); private Random generator; + private ImageDb imgIdDb = new ImageDb(); - public IskDemoServiceImpl() throws MalformedURLException { + public IskDemoServiceImpl() { super(); - XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl(); - config.setServerURL(new URL("http://127.0.0.1:31128/RPC")); // isk-daemon - // XML-RPC - // endpoint - // URL - config.setEnabledForExtensions(true); - client = new XmlRpcClient(); - client.setConfig(config); generator = new Random(1958027); } @@ -83,7 +69,7 @@ public List queryImgID(long id, int numres, boolean fast) { // searching by default on DB Space 1 Object[] params = new Object[] { 1, (int) id, numres, fast }; try { - Object[] result = (Object[]) client.execute("queryImgID", + Object[] result = (Object[]) iskClient.client.execute("queryImgID", params); for (Object res : result) { Object[] r = (Object[]) res; diff --git a/demo/src/net/imgseek/server/demo/server/UploadServlet.java b/demo/src/net/imgseek/server/demo/server/UploadServlet.java new file mode 100644 index 0000000..3081ad9 --- /dev/null +++ b/demo/src/net/imgseek/server/demo/server/UploadServlet.java @@ -0,0 +1,119 @@ +package net.imgseek.server.demo.server; + +import gwtupload.server.UploadAction; +import gwtupload.server.exceptions.UploadActionException; +import gwtupload.shared.UConsts; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import net.imgseek.server.demo.shared.DbImageResult; + +import org.apache.commons.fileupload.FileItem; +import org.apache.xmlrpc.XmlRpcException; + +/** + * This class sends by email, all the fields and files received by GWTUpload + * servlet. + * + * @author Manolo Carrasco MoƱino + * + */ +public class UploadServlet extends UploadAction { + private IskDaemonClient iskClient = new IskDaemonClient(); + + private static final long serialVersionUID = 1L; + + Hashtable receivedContentTypes = new Hashtable(); + /** + * Maintain a list with received files and their content types. + */ + Hashtable receivedFiles = new Hashtable(); + + private ImageDb imgIdDb = new ImageDb(); + + /** + * Override executeAction to save the received files in a custom place and + * delete this items from session. + */ + @Override + public String executeAction(HttpServletRequest request, + List sessionFiles) throws UploadActionException { + String response = ""; + List dbImageList = new ArrayList(); + int cont = 0; + for (FileItem item : sessionFiles) { + if (false == item.isFormField()) { + cont++; + try { + // / Create a new file based on the remote file name in the + // client + // String saveName = + // item.getName().replaceAll("[\\\\/><\\|\\s\"'{}()\\[\\]]+", + // "_"); + // File file =new File("/tmp/" + saveName); + + // / Create a temporary file placed in /tmp (only works in + // unix) + // File file = File.createTempFile("upload-", ".bin", new + // File("/tmp")); + + // / Create a temporary file placed in the default system + // temp folder + byte[] data = item.get(); + // searching by default on DB Space 1 + Object[] params = new Object[] { 1, data, 12, false }; + try { + Object[] result = (Object[]) iskClient.client.execute( + "queryImgBlob", params); + for (Object res : result) { + Object[] r = (Object[]) res; + int rid = (Integer) r[0]; + response += (rid + ";"); + response += (r[1] + ";"); + response += (this.imgIdDb.getUrlForImg(rid) + ";"); + } + + // return ""; + } catch (XmlRpcException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } catch (Exception e) { + throw new UploadActionException(e.getMessage()); + } + } + } + + // / Remove files from session because we have a copy of them + removeSessionFileItems(request); + + // / Send your customized message to the client. + return response; + } + + /** + * Get the content of an uploaded file. + */ + @Override + public void getUploadedFile(HttpServletRequest request, + HttpServletResponse response) throws IOException { + String fieldName = request.getParameter(UConsts.PARAM_SHOW); + File f = receivedFiles.get(fieldName); + if (f != null) { + response.setContentType(receivedContentTypes.get(fieldName)); + FileInputStream is = new FileInputStream(f); + copyFromInputStreamToOutputStream(is, response.getOutputStream()); + } else { + renderXmlResponse(request, response, XML_ERROR_ITEM_NOT_FOUND); + } + } +} diff --git a/demo/war/WEB-INF/lib/commons-fileupload-1.2.1.jar b/demo/war/WEB-INF/lib/commons-fileupload-1.2.1.jar new file mode 100644 index 0000000..7db423e Binary files /dev/null and b/demo/war/WEB-INF/lib/commons-fileupload-1.2.1.jar differ diff --git a/demo/war/WEB-INF/lib/commons-io-1.4.jar b/demo/war/WEB-INF/lib/commons-io-1.4.jar new file mode 100644 index 0000000..133dc6c Binary files /dev/null and b/demo/war/WEB-INF/lib/commons-io-1.4.jar differ diff --git a/demo/war/WEB-INF/lib/gwtupload-0.6.4.jar b/demo/war/WEB-INF/lib/gwtupload-0.6.4.jar new file mode 100644 index 0000000..b6bdc81 Binary files /dev/null and b/demo/war/WEB-INF/lib/gwtupload-0.6.4.jar differ diff --git a/demo/war/WEB-INF/lib/log4j-1.2.13.jar b/demo/war/WEB-INF/lib/log4j-1.2.13.jar new file mode 100644 index 0000000..dde9972 Binary files /dev/null and b/demo/war/WEB-INF/lib/log4j-1.2.13.jar differ diff --git a/demo/war/WEB-INF/web.xml b/demo/war/WEB-INF/web.xml index 67ed815..767c8b4 100644 --- a/demo/war/WEB-INF/web.xml +++ b/demo/war/WEB-INF/web.xml @@ -5,6 +5,32 @@ version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"> + + + maxSize + 512000 + + + + slowUploads + 0 + + + + uploadServlet + + net.imgseek.server.demo.server.UploadServlet + + + + uploadServlet + *.gupld + + iskDemoServlet diff --git a/src/core/imgdbapi.py b/src/core/imgdbapi.py index d416393..c57f0fb 100644 --- a/src/core/imgdbapi.py +++ b/src/core/imgdbapi.py @@ -116,7 +116,7 @@ def queryImgBlob(dbId, data, numres=12, sketch=0, fast=False): dbId = int(dbId) numres = int(numres) - return imgDB.queryImgBlob(dbId, data, numres,sketch,fast) + return imgDB.queryImgBlob(dbId, data.data, numres,sketch,fast) def queryImgPath(dbId, path, numres=12, sketch=0, fast=False): """ diff --git a/src/imgSeekLib/ImageDB.py b/src/imgSeekLib/ImageDB.py index 688c382..52f20f5 100644 --- a/src/imgSeekLib/ImageDB.py +++ b/src/imgSeekLib/ImageDB.py @@ -238,6 +238,7 @@ def addDir(self, dbId, path, recurse): return addedCount @utils.requireKnownDbId + @utils.dumpArgs def removeDb(self, dbId): if imgdb.removedb(dbId): del self.dbSpaces[dbId] @@ -245,6 +246,7 @@ def removeDb(self, dbId): return False @utils.requireKnownDbId + @utils.dumpArgs def addImageBlob(self, dbId, data, newid = None): dbSpace = self.dbSpaces[dbId] @@ -267,6 +269,7 @@ def addImageBlob(self, dbId, data, newid = None): return res @utils.requireKnownDbId + @utils.dumpArgs def addImage(self, dbId, fname,newid = None): dbSpace = self.dbSpaces[dbId] @@ -371,6 +374,7 @@ def getAddPerMinCount(self,dbId): return self.dbSpaces[dbId].lastAddPerMin @utils.requireKnownDbId + @utils.dumpArgs def addKeywordImg(self, dbId, imgId, hash): return imgdb.addKeywordImg(dbId, imgId, hash) @@ -397,7 +401,6 @@ def getAllImgsByKeywords(self,dbId, numres, kwJoinType, keywords): @utils.requireKnownDbId def queryImgIDFastKeywords(self,dbId, imgId, numres, kwJoinType, keywords): return imgdb.queryImgIDFastKeywords(dbId, imgId, numres, kwJoinType, keywords) - @utils.requireKnownDbId def queryImgIDKeywords(self,dbId, imgId, numres, kwJoinType, keywords, fast=False): @@ -429,14 +432,17 @@ def getKeywordsImg(self,dbId, imgId): return res @utils.requireKnownDbId + @utils.dumpArgs def removeAllKeywordImg(self,dbId, imgId): return imgdb.removeAllKeywordImg(dbId, imgId) @utils.requireKnownDbId + @utils.dumpArgs def removeKeywordImg(self,dbId, imgId, hash): return imgdb.removeKeywordImg(dbId, imgId, hash) @utils.requireKnownDbId + @utils.dumpArgs def addKeywordsImg(self,dbId, imgId, hashes): return imgdb.addKeywordsImg(dbId, imgId, hashes) @@ -457,6 +463,7 @@ def queryImgBlob(self,dbId,data,numres,sketch=0,fast = False): return res @utils.requireKnownDbId + @utils.dumpArgs def queryImgPath(self,dbId,path,numres,sketch=0, fast = False): dbSpace = self.dbSpaces[dbId] @@ -473,6 +480,7 @@ def queryImgPath(self,dbId,path,numres,sketch=0, fast = False): return res @utils.requireKnownDbId + @utils.dumpArgs def queryImgID(self,dbId,qid,numres,sketch=0,fast = False): dbSpace = self.dbSpaces[dbId]