source: extensions/jiwigo-ws-api/src/main/java/fr/mael/jiwigo/dao/impl/ImageDaoImpl.java @ 10714

Last change on this file since 10714 was 10714, checked in by mlg, 13 years ago

Adds support for method pwg.categories.delete
(allows to delete a category).

File size: 13.1 KB
Line 
1package fr.mael.jiwigo.dao.impl;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.IOException;
6import java.io.InputStreamReader;
7import java.io.UnsupportedEncodingException;
8import java.net.HttpURLConnection;
9import java.security.NoSuchAlgorithmException;
10import java.util.ArrayList;
11import java.util.HashMap;
12import java.util.List;
13
14import org.apache.http.HttpEntity;
15import org.apache.http.HttpResponse;
16import org.apache.http.client.ClientProtocolException;
17import org.apache.http.client.methods.HttpPost;
18import org.apache.http.entity.BufferedHttpEntity;
19import org.apache.http.entity.mime.MultipartEntity;
20import org.apache.http.entity.mime.content.FileBody;
21import org.apache.http.entity.mime.content.StringBody;
22import org.slf4j.Logger;
23import org.slf4j.LoggerFactory;
24import org.w3c.dom.Document;
25import org.w3c.dom.Element;
26import org.w3c.dom.Node;
27import org.w3c.dom.NodeList;
28
29import sun.misc.BASE64Encoder;
30import fr.mael.jiwigo.dao.ImageDao;
31import fr.mael.jiwigo.om.Image;
32import fr.mael.jiwigo.transverse.enumeration.MethodsEnum;
33import fr.mael.jiwigo.transverse.exception.FileAlreadyExistsException;
34import fr.mael.jiwigo.transverse.exception.JiwigoException;
35import fr.mael.jiwigo.transverse.exception.ProxyAuthenticationException;
36import fr.mael.jiwigo.transverse.exception.WrongChunkSizeException;
37import fr.mael.jiwigo.transverse.session.SessionManager;
38import fr.mael.jiwigo.transverse.session.impl.SessionManagerImpl;
39import fr.mael.jiwigo.transverse.util.Tools;
40
41/*
42 *  jiwigo-ws-api Piwigo webservice access Api
43 *  Copyright (c) 2010-2011 Mael mael@le-guevel.com
44 *                All Rights Reserved
45 *
46 *  This library is free software. It comes without any warranty, to
47 *  the extent permitted by applicable law. You can redistribute it
48 *  and/or modify it under the terms of the Do What The Fuck You Want
49 *  To Public License, Version 2, as published by Sam Hocevar. See
50 *  http://sam.zoy.org/wtfpl/COPYING for more details.
51 */
52/**
53
54 * Dao of the images
55 * @author mael
56 *
57 */
58public class ImageDaoImpl implements ImageDao {
59
60    /**
61     * Logger
62     */
63    private final Logger LOG = LoggerFactory.getLogger(ImageDaoImpl.class);
64
65    /**
66     * cache to avoid downloading image for each access
67     */
68    private HashMap<Integer, List<Image>> cache;
69
70    /**
71     *
72     */
73    private Integer firstCatInCache;
74
75    private SessionManager sessionManager;
76
77    private ArrayList<File> filesToSend;
78
79    public ImageDaoImpl() {
80        cache = new HashMap<Integer, List<Image>>();
81    }
82
83    /**
84     * Lists all images
85     * @return the list of images
86     * @throws IOException
87     * @throws ProxyAuthenticationException
88     */
89    public List<Image> list(boolean refresh) throws JiwigoException {
90        return listByCategory(null, refresh);
91    }
92
93    /**
94     * Listing of the images for a category
95     * @param categoryId the id of the category
96     * @return the list of images
97     * @throws IOException
98     * @throws ProxyAuthenticationException
99     */
100    public List<Image> listByCategory(Integer categoryId, boolean refresh) throws JiwigoException {
101        if (refresh || cache.get(categoryId) == null) {
102            Document doc = null;
103            if (categoryId != null) {
104                doc = sessionManager.executeReturnDocument(MethodsEnum.LISTER_IMAGES.getLabel(), "cat_id",
105                        String.valueOf(categoryId));
106            } else {
107                doc = sessionManager.executeReturnDocument(MethodsEnum.LISTER_IMAGES.getLabel());
108            }
109            Element element = (Element) doc.getDocumentElement().getElementsByTagName("images").item(0);
110            List<Image> images = getImagesFromElement(element);
111            cache.remove(categoryId);
112            cache.put(categoryId, images);
113            if (firstCatInCache == null) {
114                firstCatInCache = categoryId;
115            }
116            return images;
117        } else {
118            return cache.get(categoryId);
119        }
120    }
121
122    /**
123     * Creation of an image<br/>
124     * Sequence : <br/>
125     * <li>
126     * <ul>sending of the thumbnail in base64, thanks to the method addchunk.</ul>
127     * <ul>sending of the image in base64, thanks to the method addchunk</ul>
128     * <ul>using of the add method to add the image to the database<ul>
129     * </li>
130     * Finally, the response of the webservice is checked
131     *
132     * @param image the image to create
133     * @return true if the creation of the image was the successful
134     * @throws IOException
135     * @throws NoSuchAlgorithmException
136     * @throws WrongChunkSizeException
137     * @throws JiwigoException
138     * @throws Exception
139     */
140    //TODO ne pas continuer si une des reponses precedentes est negative
141    public boolean create(Image image, Double chunkSize) throws FileAlreadyExistsException, IOException,
142            ProxyAuthenticationException, NoSuchAlgorithmException, WrongChunkSizeException, JiwigoException {
143        //thumbnail converted to base64
144        BASE64Encoder base64 = new BASE64Encoder();
145
146        String thumbnailBase64 = base64.encode(Tools.getBytesFromFile(image.getThumbnail()));
147        //sends the thumbnail and gets the result
148        Document reponseThumb = (sessionManager.executeReturnDocument(MethodsEnum.ADD_CHUNK.getLabel(), "data",
149                thumbnailBase64, "type", "thumb", "position", "1", "original_sum",
150                Tools.getMD5Checksum(image.getOriginale().getAbsolutePath())));
151
152        //begin feature:0001827
153        int chunk = chunkSize.intValue();
154        if (chunk == 0) {
155            throw new WrongChunkSizeException("Error : the chunk size cannot be 0");
156        }
157        filesToSend = Tools.splitFile(image.getOriginale(), chunk);
158        boolean echec = false;
159        for (int i = 0; i < filesToSend.size(); i++) {
160            File fichierAEnvoyer = filesToSend.get(i);
161            String originaleBase64 = base64.encode(Tools.getBytesFromFile(fichierAEnvoyer));
162            Document reponseOriginale = (sessionManager.executeReturnDocument(MethodsEnum.ADD_CHUNK.getLabel(), "data",
163                    originaleBase64, "type", "file", "position", String.valueOf(i), "original_sum",
164                    Tools.getMD5Checksum(image.getOriginale().getAbsolutePath())));
165            if (!Tools.checkOk(reponseOriginale)) {
166                echec = true;
167                break;
168            }
169        }
170        //end
171
172        //add the image in the database and get the result of the webservice
173        Document reponseAjout = (sessionManager.executeReturnDocument(MethodsEnum.ADD_IMAGE.getLabel(), "file_sum",
174                Tools.getMD5Checksum(image.getOriginale().getAbsolutePath()), "thumbnail_sum",
175                Tools.getMD5Checksum(image.getThumbnail().getCanonicalPath()), "position", "1", "original_sum",
176                Tools.getMD5Checksum(image.getOriginale().getAbsolutePath()), "categories",
177                String.valueOf(image.getIdCategory()), "name", image.getName(), "author", sessionManager.getLogin(),
178                "level", image.getPrivacyLevel()));
179        if (LOG.isDebugEnabled()) {
180            LOG.debug("Response add : " + Tools.documentToString(reponseAjout));
181        }
182        //      System.out.println(Main.sessionManager.executerReturnString("pwg.images.add", "file_sum", Outil
183        //              .getMD5Checksum(image.getOriginale().getAbsolutePath()), "thumbnail_sum", Outil.getMD5Checksum(image
184        //              .getThumbnail().getCanonicalPath()), "position", "1", "original_sum", Outil.getMD5Checksum(image
185        //              .getOriginale().getAbsolutePath()), "categories", String.valueOf(image.getIdCategory()), "name", image
186        //              .getName(), "author", Main.sessionManager.getLogin()));
187        //      Document reponsePrivacy = null;
188        //      if (Outil.checkOk(reponseAjout)) {
189        //          reponsePrivacy = Main.sessionManager.executerReturnDocument(MethodsEnum.SET_PRIVACY_LEVEL.getLabel());
190        //      }
191        boolean reussite = true;
192        if (!Tools.checkOk(reponseThumb) || echec || !Tools.checkOk(reponseAjout)) {
193            reussite = false;
194        }
195        deleteTempFiles();
196        return reussite;
197
198    }
199
200    /**
201     * Add tags to an image
202     * @param imageId id of the image
203     * @param tagId ids of the tags
204     * @throws IOException
205     * @throws ProxyAuthenticationException
206     */
207    public boolean addTags(Integer imageId, String tagId) throws JiwigoException {
208        Document doc = sessionManager.executeReturnDocument(MethodsEnum.SET_INFO.getLabel(), "image_id",
209                String.valueOf(imageId), "tag_ids", tagId);
210        try {
211            return Tools.checkOk(doc);
212        } catch (FileAlreadyExistsException e) {
213            LOG.error(Tools.getStackTrace(e));
214            return false;
215        }
216
217    }
218
219    /**
220     * parse an element to find images
221     * @param element the element to parse
222     * @return the list of images
223     */
224    private List<Image> getImagesFromElement(Element element) {
225        //      List<Element> listElement = (List<Element>) element.getChildren("image");
226        NodeList listImages = element.getElementsByTagName("image");
227        ArrayList<Image> images = new ArrayList<Image>();
228        for (int i = 0; i < listImages.getLength(); i++) {
229            Node nodeImage = listImages.item(i);
230            if (nodeImage.getNodeType() == Node.ELEMENT_NODE) {
231                Element im = (Element) nodeImage;
232                Image myImage = new Image();
233                myImage.setThumbnailUrl(im.getAttribute("tn_url"));
234                myImage.setUrl(im.getAttribute("element_url"));
235                myImage.setWidth(Integer.valueOf(im.getAttribute("width")));
236                myImage.setHeight(Integer.valueOf(im.getAttribute("height")));
237                myImage.setFile(im.getAttribute("file"));
238                myImage.setSeen(Integer.valueOf(im.getAttribute("hit")));
239                myImage.setIdentifier(Integer.valueOf(im.getAttribute("id")));
240                myImage.setName(Tools.getStringValueDom(im, "name"));
241                Element elementCategories = (Element) im.getElementsByTagName("categories").item(0);
242                if (elementCategories != null) {
243                    Element elementCategory = (Element) elementCategories.getElementsByTagName("category").item(0);
244                    myImage.setIdCategory(Integer.valueOf(elementCategory.getAttribute("id")));
245                    if (myImage.getName() == null) {
246                        myImage.setName(myImage.getFile());
247                    }
248                }
249                images.add(myImage);
250            }
251        }
252        return images;
253    }
254
255    /**
256     * Search images
257     * @param searchString the string to search
258     * @return the list of images matching the string
259     * @throws IOException
260     * @throws ProxyAuthenticationException
261     */
262    public List<Image> search(String searchString) throws JiwigoException {
263        Document doc = sessionManager.executeReturnDocument(MethodsEnum.SEARCH.getLabel(), "query", searchString);
264        LOG.debug(Tools.documentToString(doc));
265        Element element = (Element) doc.getDocumentElement().getElementsByTagName("images").item(0);
266        return getImagesFromElement(element);
267
268    }
269
270    private void deleteTempFiles() {
271        File file = new File(System.getProperty("java.io.tmpdir") + "/originale.jpg");
272        file.delete();
273        file = new File(System.getProperty("java.io.tmpdir") + "/thumb.jpg");
274        file.delete();
275        for (File tempCut : filesToSend) {
276            tempCut.delete();
277        }
278
279    }
280
281    public void addSimple(File file, Integer category, String title) throws JiwigoException {
282        HttpPost httpMethod = new HttpPost(((SessionManagerImpl) sessionManager).getUrl());
283
284        //      nameValuePairs.add(new BasicNameValuePair("method", "pwg.images.addSimple"));
285        //      for (int i = 0; i < parametres.length; i += 2) {
286        //          nameValuePairs.add(new BasicNameValuePair(parametres[i], parametres[i + 1]));
287        //      }
288        //      method.setEntity(new UrlEncodedFormEntity(nameValuePairs));
289
290        if (file != null) {
291            MultipartEntity multipartEntity = new MultipartEntity();
292
293            //          String string = nameValuePairs.toString();
294            // dirty fix to remove the enclosing entity{}
295            //          String substring = string.substring(string.indexOf("{"),
296            //                          string.lastIndexOf("}") + 1);
297            try {
298                multipartEntity.addPart("method", new StringBody(MethodsEnum.ADD_SIMPLE.getLabel()));
299                multipartEntity.addPart("category", new StringBody(category.toString()));
300                multipartEntity.addPart("name", new StringBody(title));
301            } catch (UnsupportedEncodingException e) {
302                throw new JiwigoException(e);
303            }
304
305            //          StringBody contentBody = new StringBody(substring,
306            //                          Charset.forName("UTF-8"));
307            //          multipartEntity.addPart("entity", contentBody);
308            FileBody fileBody = new FileBody(file);
309            multipartEntity.addPart("image", fileBody);
310            ((HttpPost) httpMethod).setEntity(multipartEntity);
311        }
312
313        HttpResponse response;
314        StringBuilder sb = new StringBuilder();
315        try {
316            response = ((SessionManagerImpl) sessionManager).getClient().execute(httpMethod);
317
318            int responseStatusCode = response.getStatusLine().getStatusCode();
319
320            switch (responseStatusCode) {
321            case HttpURLConnection.HTTP_CREATED:
322                break;
323            case HttpURLConnection.HTTP_OK:
324                break;
325            case HttpURLConnection.HTTP_BAD_REQUEST:
326                throw new JiwigoException("status code was : " + responseStatusCode);
327            case HttpURLConnection.HTTP_FORBIDDEN:
328                throw new JiwigoException("status code was : " + responseStatusCode);
329            case HttpURLConnection.HTTP_NOT_FOUND:
330                throw new JiwigoException("status code was : " + responseStatusCode);
331            default:
332                throw new JiwigoException("status code was : " + responseStatusCode);
333            }
334
335            HttpEntity resultEntity = response.getEntity();
336            BufferedHttpEntity responseEntity = new BufferedHttpEntity(resultEntity);
337
338            BufferedReader reader = new BufferedReader(new InputStreamReader(responseEntity.getContent()));
339            String line;
340
341            try {
342                while ((line = reader.readLine()) != null) {
343                    sb.append(line);
344                    sb.append("\n");
345                }
346            } finally {
347                reader.close();
348            }
349        } catch (ClientProtocolException e) {
350            throw new JiwigoException(e);
351        } catch (IOException e) {
352            throw new JiwigoException(e);
353        }
354        String stringResult = sb.toString();
355
356    }
357
358    public SessionManager getSessionManager() {
359        return sessionManager;
360    }
361
362    public void setSessionManager(SessionManager sessionManager) {
363        this.sessionManager = sessionManager;
364    }
365}
Note: See TracBrowser for help on using the repository browser.