r368 - in trunk/bow-ui/src/main: java/org/chorem/bow java/org/chorem/bow/action/bookmark java/org/chorem/bow/action/preference resources resources/i18n webapp/WEB-INF/jsp webapp/WEB-INF/jsp/inc webapp/css webapp/img xmi
Author: bpoussin Date: 2013-09-26 20:18:46 +0200 (Thu, 26 Sep 2013) New Revision: 368 Url: http://chorem.org/projects/bow/repository/revisions/368 Log: fixes #360: Check if the alias is correct fixes #470: Take screenshot of bookmarked web page and use it as icon for bookmark Added: trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/ScreenshotAction.java trunk/bow-ui/src/main/webapp/img/camera.png Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BookmarkUtils.java trunk/bow-ui/src/main/java/org/chorem/bow/BowConfig.java trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java trunk/bow-ui/src/main/java/org/chorem/bow/BowUtils.java trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/AddOrUpdateAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties trunk/bow-ui/src/main/resources/struts.xml trunk/bow-ui/src/main/webapp/WEB-INF/jsp/home.jsp trunk/bow-ui/src/main/webapp/WEB-INF/jsp/inc/bookmark.jsp trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp trunk/bow-ui/src/main/webapp/css/bookmark.css trunk/bow-ui/src/main/xmi/bow-model.zargo Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BookmarkUtils.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BookmarkUtils.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BookmarkUtils.java 2013-09-26 18:18:46 UTC (rev 368) @@ -23,6 +23,9 @@ */ package org.chorem.bow; +import java.net.URI; +import java.net.URL; +import java.net.URLEncoder; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -30,6 +33,13 @@ import java.util.Date; import java.util.Set; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; import org.nuiton.wikitty.entities.Element; import org.nuiton.wikitty.query.WikittyQuery; import org.nuiton.wikitty.query.WikittyQueryMaker; @@ -199,4 +209,62 @@ return ""; } + /** + * retourne l'image du site passer en parametre + * @param url + * @return + */ + public static byte[] getScreenshot(String url) { + byte[] result = null; + try { + String ssu = BowConfig.getScreenshotURL(); + url = URLEncoder.encode(url, "UTF-8"); + String imageUrl = String.format(ssu, url); + result = getImage(imageUrl); + } catch (Exception eee) { + log.info("Can't encode URL: " + url, eee); + } + return result; + } + + /** + * retourne le favicon du site passe en parametre + * @param urlString + * @return + */ + public static byte[] getFavicon(String urlString) { + byte[] result = null; + try { + URL url = new URI(urlString).toURL(); + URL favURL = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/favicon.ico"); + result = getImage(favURL.toExternalForm()); + return result; + } catch (Exception eee) { + log.info("Can't parse URL: " + urlString, eee); + } + return result; + } + + protected static byte[] getImage(String url) { + byte[] result = null; + try { + log.debug("try to connect get image : " + url); + + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpGet httpGet = new HttpGet(url); + CloseableHttpResponse response = httpclient.execute(httpGet); + + try { + HttpEntity entity = response.getEntity(); + result = IOUtils.toByteArray(entity.getContent()); + // ensure it is fully consumed + EntityUtils.consume(entity); + } finally { + response.close(); + } + } catch (Exception eee) { + log.info("Can't get result for url: " + url, eee); + } + return result; + } } Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BowConfig.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BowConfig.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BowConfig.java 2013-09-26 18:18:46 UTC (rev 368) @@ -145,6 +145,28 @@ } /** + * Get bow screenshot url server as string. + * Default bow applicationConfig will be used + * + * @return screenshot url + * @since 1.3 + */ + public static String getScreenshotURL() { + return getScreenshotURL(getConfig()); + } + + /** + * Get bow screenshot url server as string. + * + * @param config bow configuration + * @return screenshot url + * @since 1.3 + */ + public static String getScreenshotURL(ApplicationConfig config) { + return config.getOption(BowConfigOption.BOW_SCREENSHOT_URL.key); + } + + /** * Get bow smtp server as string. * Default bow applicationConfig will be used * Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BowConfigOption.java 2013-09-26 18:18:46 UTC (rev 368) @@ -47,6 +47,10 @@ "alias.url", _("bow.config.alias.url.description"), "alias/", String.class, false, false), + BOW_SCREENSHOT_URL( + "bow.screenshot.url", + _("bow.config.bow.screenshot.url.description"), + "http://screenshotweb.codelutin.com/screenshotweb.cgi?URL=%s&FILENAME=screenshot.png&VIEWPORT=1024*1182&CLIPRECT=0*0*1024*1182&SCALE=65x75", String.class, false, false), BOW_SMTPSERVER( "bow.smtpServer", _("bow.config.bow.smtpServer.description"), Modified: trunk/bow-ui/src/main/java/org/chorem/bow/BowUtils.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/BowUtils.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/BowUtils.java 2013-09-26 18:18:46 UTC (rev 368) @@ -33,6 +33,7 @@ import java.util.HashSet; import java.util.Set; import java.util.UUID; +import org.apache.commons.codec.binary.Base64; import org.nuiton.wikitty.query.WikittyQuery; import org.nuiton.wikitty.query.WikittyQueryMaker; @@ -40,9 +41,16 @@ public static final String BOW_DATE_SHORT_PATTERN = "yyyy/MM/dd"; - private BowUtils() { + /** + * public to use easily in jsp + */ + public BowUtils() { } + public static String toBase64(byte[] b) { + return Base64.encodeBase64String(b); + } + /** * Retourne toujours une date valide. Si date est null, on prend la date * du jour @@ -66,8 +74,7 @@ * @return empty string or string without blank at begin and end */ public static String normalizeString(String s) { - String result = StringUtils.defaultIfBlank(s, ""); - result = result.trim(); + String result = StringUtils.trimToEmpty(s); return result; } Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/AddOrUpdateAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/AddOrUpdateAction.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/AddOrUpdateAction.java 2013-09-26 18:18:46 UTC (rev 368) @@ -23,11 +23,13 @@ */ package org.chorem.bow.action.bookmark; +import java.util.Date; import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.bow.BookmarkUtils; import org.chorem.bow.BowBookmark; +import org.chorem.bow.BowBookmarkImpl; import org.chorem.bow.BowProxy; import org.chorem.bow.BowUser; import org.chorem.bow.BowUtils; @@ -135,115 +137,245 @@ return redirectTo; } +// @Override +// public String execute() { +// String result = SUCCESS; +// try { +// BowProxy proxy = getBowProxy(); +// BowBookmark bookmark = null; +// BowBookmark bookmarkToModify = null; +// +// BowUser user = getBowSession().getUser(); +// String userId = user.getWikittyId(); +// if (StringUtils.isNotBlank(bookmarkId)) { +// bookmarkToModify = proxy.restore(BowBookmark.class, bookmarkId); +// } +// if (log.isDebugEnabled()) { +// log.debug("Change old wikitty: " + bookmarkToModify); +// } +// +// // gere le cas d'une mise a jour ou d'un ajout via le formulaire +// if (name != null) { +// // Si l'alias prive souhaite est deja utilise on ne l'accept pas +// // Si l'alias public souhaite est deja utilise on ne l'accept pas +// // TODO sletellier 20110416 : return error message when public or private alias is already used +// WikittyQuery privateAliasCriteria = null; +// WikittyQuery publicAliasCriteria = null; +// if (StringUtils.isNotEmpty(privateAlias)) { +// privateAliasCriteria = new WikittyQueryMaker().and() +// .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, privateAlias) +// .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, userId) +// .end().setLimit(0); +// } +// if (StringUtils.isNotEmpty(publicAlias)) { +// publicAliasCriteria = new WikittyQueryMaker() +// .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PUBLICALIAS, publicAlias) +// .end().setLimit(0); +// } +// WikittyQueryResult<String>[] aliasResult = proxy.findAllByQuery( +// privateAliasCriteria, publicAliasCriteria); +// +// if (aliasResult[0] != null && aliasResult[0].getTotalResult() > 0) { +// if (bookmarkToModify == null) { +// privateAlias = ""; +// } else { +// privateAlias = bookmarkToModify.getPrivateAlias(); +// } +// } +// if (aliasResult[1] != null && aliasResult[1].getTotalResult() > 0) { +// if (bookmarkToModify == null) { +// publicAlias = ""; +// } else { +// publicAlias = bookmarkToModify.getPublicAlias(); +// } +// } +// +// if (bookmarkToModify == null) { +// bookmark = BookmarkUtils.createBookmark( +// link, name, tags, user, privateAlias, publicAlias, null); +// } else { +// BookmarkUtils.updateBookmark( +// bookmarkToModify, name, link, tags, privateAlias, publicAlias); +// } +// } else { //This part is for the bookmark addition by script +// if (nameAndTags != null) { +// bookmark = BookmarkUtils.createBookmark(link, nameAndTags, user); +// } +// } +// // si on a reussi a creer le bookmark, on regarde s'il ne faut pas +// // le fusionner avec un deja existant +// if (bookmark != null && !bookmark.getDescription().isEmpty() +// && !bookmark.getOwner().isEmpty()) { +// +// // looking for already bookmark with same url, to fusion them +// String link = bookmark.getLink(); +// WikittyQuery criteria = new WikittyQueryMaker().and() +// .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_LINK, link) +// .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, userId) +// .end(); +// BowBookmark oldBookmark = +// proxy.findByQuery(BowBookmark.class, criteria); +// if (oldBookmark != null) { +// // fusionne les descriptions et les tags +// // par contre on prend le dernier privateAlias prive choisi par +// // l'utilisateur s'il y en a un +// String description = oldBookmark.getDescription(); +// if (!StringUtils.isEmpty(bookmark.getDescription())) { +// description += "\n"; +// description += BowUtils.formatDate( +// bookmark.getCreationDate()) + ": "; +// description += bookmark.getDescription(); +// } +// +// oldBookmark.setDescription(description); +// oldBookmark.addAllLabels(bookmark.getLabels()); +// String privateAlias = bookmark.getPrivateAlias(); +// if (!StringUtils.isEmpty(privateAlias)) { +// oldBookmark.setPrivateAlias(privateAlias); +// } +// +// bookmark = oldBookmark; +// } +// +// } +// +// if (bookmark != null || bookmarkToModify != null) { +// proxy.store(bookmark, bookmarkToModify); //Stores the bookmark if everything is ok +// addActionMessage(_("bow.bookmark.add.successful")); +// if (log.isDebugEnabled()) { +// log.debug("Adding URL"); +// } +// } +// redirectTo = BowUtils.redirectTo(tagLine, fullTextLine); +// } catch (Exception eee) { +// result = ERROR; +// addActionError(_("bow.error.internal")); +// log.error(eee.getMessage(), eee); +// } +// return result; +// } + @Override public String execute() { String result = SUCCESS; try { BowProxy proxy = getBowProxy(); BowBookmark bookmark = null; - BowBookmark bookmarkToModify = null; + // gere le cas d'une mise a jour ou d'un ajout via le formulaire + if (name == null) { + // on est dans le cas ou l'ajout a ete fait par le scriptlet qui + // utilise une seul chaine pour name et tags, on decoupe + // et on continue normalement + nameAndTags = StringUtils.trimToEmpty(nameAndTags); + name = StringUtils.substringBeforeLast(nameAndTags, "|"); + tags = StringUtils.substringAfterLast(nameAndTags, "|"); + } + + + // on met toutes les valeurs dans le bon format + name = BowUtils.normalizeString(name); + link = BowUtils.normalizeUrl(link); + tags = BowUtils.normalizeString(tags); + privateAlias = BowUtils.normalizeString(privateAlias); + publicAlias = BowUtils.normalizeString(publicAlias); + + BowUser user = getBowSession().getUser(); String userId = user.getWikittyId(); if (StringUtils.isNotBlank(bookmarkId)) { - bookmarkToModify = proxy.restore(BowBookmark.class, bookmarkId); - } - if (log.isDebugEnabled()) { - log.debug("Change old wikitty: " + bookmarkToModify); - } - - // gere le cas d'une mise a jour ou d'un ajout via le formulaire - if (name != null) { - // Si l'alias prive souhaite est deja utilise on ne l'accept pas - // Si l'alias public souhaite est deja utilise on ne l'accept pas - // TODO sletellier 20110416 : return error message when public or private alias is already used - WikittyQuery privateAliasCriteria = null; - WikittyQuery publicAliasCriteria = null; - if (StringUtils.isNotEmpty(privateAlias)) { - privateAliasCriteria = new WikittyQueryMaker().and() - .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, privateAlias) - .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, userId) - .end().setLimit(0); + // on modifie un bookmark existant et on a deja son id + bookmark = proxy.restore(BowBookmark.class, bookmarkId); + if (log.isDebugEnabled()) { + log.debug("Change old wikitty: " + bookmark); } - if (StringUtils.isNotEmpty(publicAlias)) { - publicAliasCriteria = new WikittyQueryMaker() - .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PUBLICALIAS, publicAlias) - .end().setLimit(0); + } else { + WikittyQuery criteria = new WikittyQueryMaker().and() + .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_LINK, link) + .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, userId) + .end(); + bookmark = + proxy.findByQuery(BowBookmark.class, criteria); + if (bookmark != null) { + // on modifie le bookmark qui a la meme url que celle a ajouter + // on fusionne les descriptions + String description = bookmark.getDescription(); + name = description +"\n" + + BowUtils.formatDate(new Date()) + ": " + name; + // on fusionne les tags + tags += " " + BookmarkUtils.getBookmarkTagsString(bookmark); } - WikittyQueryResult<String>[] aliasResult = proxy.findAllByQuery( - privateAliasCriteria, publicAliasCriteria); + } - if (aliasResult[0] != null && aliasResult[0].getTotalResult() > 0) { - if (bookmarkToModify == null) { - privateAlias = ""; - } else { - privateAlias = bookmarkToModify.getPrivateAlias(); - } + // on a pas retrouve de bookmark a modifier, on en cree un nouveau + if (bookmark == null) { + bookmark = new BowBookmarkImpl(); + bookmark.setClick(0); + bookmark.setOwner(user); + bookmark.addReader(user); // only owner can read it + bookmark.setCreationDate(new Date()); + + if (user.getScreenshot()) { + // on essaie de prendre l'image du site que l'on ajoute + byte[] screenshot = BookmarkUtils.getScreenshot(link); + bookmark.setScreenshot(screenshot); } - if (aliasResult[1] != null && aliasResult[1].getTotalResult() > 0) { - if (bookmarkToModify == null) { - publicAlias = ""; - } else { - publicAlias = bookmarkToModify.getPublicAlias(); - } - } - if (bookmarkToModify == null) { - bookmark = BookmarkUtils.createBookmark( - link, name, tags, user, privateAlias, publicAlias, null); - } else { - BookmarkUtils.updateBookmark( - bookmarkToModify, name, link, tags, privateAlias, publicAlias); + if (user.getFavicon()) { + // on essaie de recuperer le favicone + byte[] favicone = BookmarkUtils.getFavicon(link); + bookmark.setFavicon(favicone); } - } else { //This part is for the bookmark addition by script - if (nameAndTags != null) { - bookmark = BookmarkUtils.createBookmark(link, nameAndTags, user); + } else { + if (log.isDebugEnabled()) { + log.debug("Change old bookmark: " + bookmark); } } - // si on a reussi a creer le bookmark, on regarde s'il ne faut pas - // le fusionner avec un deja existant - if (bookmark != null && !bookmark.getDescription().isEmpty() - && !bookmark.getOwner().isEmpty()) { - // looking for already bookmark with same url, to fusion them - String link = bookmark.getLink(); - WikittyQuery criteria = new WikittyQueryMaker().and() - .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_LINK, link) - .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, userId) - .end(); - BowBookmark oldBookmark = - proxy.findByQuery(BowBookmark.class, criteria); - if (oldBookmark != null) { - // fusionne les descriptions et les tags - // par contre on prend le dernier privateAlias prive choisi par - // l'utilisateur s'il y en a un - String description = oldBookmark.getDescription(); - if (!StringUtils.isEmpty(bookmark.getDescription())) { - description += "\n"; - description += BowUtils.formatDate( - bookmark.getCreationDate()) + ": "; - description += bookmark.getDescription(); - } + // on met a jour les infos + bookmark.setDescription(name); + bookmark.setLink(link); + bookmark.setLabels(BowUtils.getWords(tags)); - oldBookmark.setDescription(description); - oldBookmark.addAllLabels(bookmark.getLabels()); - String privateAlias = bookmark.getPrivateAlias(); - if (!StringUtils.isEmpty(privateAlias)) { - oldBookmark.setPrivateAlias(privateAlias); - } - bookmark = oldBookmark; + // Si l'alias prive souhaite est deja utilise on ne l'accept pas + // Si l'alias public souhaite est deja utilise on ne l'accept pas + if (StringUtils.isEmpty(privateAlias)) { + bookmark.setPrivateAlias(""); + } else { + WikittyQuery privateAliasCriteria = new WikittyQueryMaker().and() + .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PRIVATEALIAS, privateAlias) + .eq(BowBookmark.FQ_FIELD_WIKITTYAUTHORISATION_OWNER, userId) + .end().setLimit(0); + WikittyQueryResult<String> aliasResult = proxy.findAllByQuery( + privateAliasCriteria); + if (aliasResult.getTotalResult() == 0) { + bookmark.setPrivateAlias(privateAlias); + } else { + addActionMessage(_("bow.alias.already.exists", privateAlias)); } - } - if (bookmark != null || bookmarkToModify != null) { - proxy.store(bookmark, bookmarkToModify); //Stores the bookmark if everything is ok - addActionMessage(_("bow.bookmark.add.successful")); - if (log.isDebugEnabled()) { - log.debug("Adding URL"); + if (StringUtils.isEmpty(publicAlias)) { + bookmark.setPublicAlias(""); + } else { + WikittyQuery publicAliasCriteria = new WikittyQueryMaker() + .eq(BowBookmark.FQ_FIELD_BOWBOOKMARK_PUBLICALIAS, publicAlias) + .end().setLimit(0); + WikittyQueryResult<String> aliasResult = proxy.findAllByQuery( + publicAliasCriteria); + if (aliasResult.getTotalResult() == 0) { + bookmark.setPublicAlias(publicAlias); + } else { + addActionMessage(_("bow.alias.already.exists", publicAlias)); } } + + proxy.store(bookmark); //Stores the bookmark if everything is ok + addActionMessage(_("bow.bookmark.add.successful")); + if (log.isDebugEnabled()) { + log.debug("Adding URL"); + } redirectTo = BowUtils.redirectTo(tagLine, fullTextLine); } catch (Exception eee) { result = ERROR; @@ -252,4 +384,5 @@ } return result; } + } \ No newline at end of file Added: trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/ScreenshotAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/ScreenshotAction.java (rev 0) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/ScreenshotAction.java 2013-09-26 18:18:46 UTC (rev 368) @@ -0,0 +1,103 @@ +/* + * #%L + * bow + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2010 - 2011 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero 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 Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.bow.action.bookmark; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.chorem.bow.BookmarkUtils; +import org.chorem.bow.BowBookmark; +import org.chorem.bow.BowProxy; +import org.chorem.bow.BowUtils; +import org.chorem.bow.action.BowBaseAction; + +/** + * Met a jour le screenshot d'un bookmark + * + * @author poussin + */ +public class ScreenshotAction extends BowBaseAction { + + private static final long serialVersionUID = 820566716695285561L; + private static final Log log = LogFactory.getLog(ScreenshotAction.class); + + protected String id; + + protected String redirectTo; + + /** @return the id */ + public String getId() { + return id; + } + + /** @param id the bookmarkId to set */ + public void setId(String id) { + this.id = id; + } + + /** @return the redirectTo */ + public String getRedirectTo() { + return redirectTo; + } + + /** Removes a bookmark */ + @Override + public String execute() { + if (StringUtils.isNotEmpty(id)) { + try { + BowProxy proxy = getBowProxy(); + BowBookmark bookmark = proxy.restore(BowBookmark.class, id); + if (bookmark != null) { + boolean changed = false; + String link = bookmark.getLink(); + + // on essaie de prendre l'image + byte[] screenshot = BookmarkUtils.getScreenshot(link); + if (ArrayUtils.isNotEmpty(screenshot) ) { + bookmark.setScreenshot(screenshot); + changed = true; + addActionMessage(_("bow.bookmark.screenshot.updated.successful")); + } + // on essaie de recuperer le favicone + byte[] favicone = BookmarkUtils.getFavicon(link); + if (ArrayUtils.isNotEmpty(favicone)) { + bookmark.setFavicon(favicone); + changed = true; + addActionMessage(_("bow.bookmark.favicon.updated.successful")); + } + + if (changed) { + proxy.store(bookmark); + } + } + } catch (Exception eee) { + addActionError(_("bow.error.internal")); + log.error("Can't do action", eee); + } + } + redirectTo = BowUtils.redirectTo(tagLine, fullTextLine); + return SUCCESS; + } +} \ No newline at end of file Property changes on: trunk/bow-ui/src/main/java/org/chorem/bow/action/bookmark/ScreenshotAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/PreferenceBaseAction.java 2013-09-26 18:18:46 UTC (rev 368) @@ -78,6 +78,10 @@ protected String colors; + protected boolean screenshot; + + protected boolean favicon; + protected String tagsNb; protected String bookmarksHomePage; @@ -132,6 +136,22 @@ this.colors = colors; } + public boolean isScreenshot() { + return screenshot; + } + + public void setScreenshot(boolean screenshot) { + this.screenshot = screenshot; + } + + public boolean isFavicon() { + return favicon; + } + + public void setFavicon(boolean favicon) { + this.favicon = favicon; + } + /** @return the tagsNb */ public String getTagsNb() { return tagsNb; @@ -308,6 +328,8 @@ } setColors(user.getColors()); + setScreenshot(user.getScreenshot()); + setFavicon(user.getFavicon()); setTagsNb(String.valueOf(user.getTags())); setBookmarksHomePage(String.valueOf(user.getBookmarks())); } Modified: trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java =================================================================== --- trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/java/org/chorem/bow/action/preference/UpdateSiteAction.java 2013-09-26 18:18:46 UTC (rev 368) @@ -70,6 +70,9 @@ BowProxy proxy = session.getProxy(); BowUser preference = session.getUser(); + preference.setScreenshot(screenshot); + preference.setFavicon(favicon); + preference.setColors(colors); if (StringUtils.isNotBlank(tagsNb)) { preference.setTags(Integer.valueOf(tagsNb)); Modified: trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties =================================================================== --- trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/resources/i18n/bow-ui_en_GB.properties 2013-09-26 18:18:46 UTC (rev 368) @@ -15,9 +15,11 @@ bow.bookmark.add.successful=Bookmark successfully added bow.bookmark.badFileFormat=Bad bookmarks file format \: unsuccessful import (expected Netscape-like bookmarks file) bow.bookmark.description=Description +bow.bookmark.favicon.updated.successful= bow.bookmark.import.delete.successful=The imported bookmarks were deleted successfully bow.bookmark.import.successful=The bookmarks were imported successfully bow.bookmark.remove.successful=The bookmark was removed successfully +bow.bookmark.screenshot.updated.successful= bow.bookmark.tag.deleted=The tag was removed successfully bow.bookmark.tags=Tags bow.bookmark.update.successful=The bookmark was updated successfully @@ -30,6 +32,7 @@ bow.config.bow.prefix.search.fulltext.description= bow.config.bow.prefix.suggestion.alias.description= bow.config.bow.prefix.suggestion.fulltext.description= +bow.config.bow.screenshot.url.description= bow.config.bow.smtpServer.description=smtp server address bow.config.bow.url.description=Web server bow URL bow.config.configFileName.description=bow configuration file @@ -68,6 +71,8 @@ bow.mail.badFormat=Your email format is incorrect and therefore the email hasn't been sent bow.mail.sendError=An error occurred while sending email bow.opensearch.result=%s results +bow.permanent.link.search= +bow.permanent.link.suggestion= bow.preference.opensearch.prefix.separator=OpenSeach prefix separator bow.preferences.badCurrentPassword=Your current password is incorrect bow.preferences.bookmarksHomePage=Number of bookmarks displayed on the home page @@ -76,6 +81,7 @@ bow.preferences.currentPassword=Current password bow.preferences.emailAldyExists=This email address is already linked with another account bow.preferences.export.bookmarks=Export bookmarks +bow.preferences.favicon= bow.preferences.import.bookmarks=Import bookmarks bow.preferences.import.submit=Import bow.preferences.importExport=Import / Export @@ -96,6 +102,7 @@ bow.preferences.opensearch.value=Value bow.preferences.opensearch.web.search.prefix=Search on the Web bow.preferences.regenPermToken=Regenerate permanent token +bow.preferences.screenshot= bow.preferences.searchEngineUrlResults=Search Engine URL Results ('{'searchTerms'}' will be replaced by your text) bow.preferences.searchEngineUrlSuggestions=Search Engine URL Suggestions bow.preferences.siteLook=Site look @@ -157,6 +164,8 @@ bow.search.results.deleted=Search results deleted successfully bow.search.submit=Search bow.search.title=Search +bow.temporary.link.search= +bow.temporary.link.suggestion= bow.token.generate.successful=The token has been regenerated successfully popup.addurl.alias.private=Private alias popup.addurl.alias.public=Public alias Modified: trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties =================================================================== --- trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/resources/i18n/bow-ui_fr_FR.properties 2013-09-26 18:18:46 UTC (rev 368) @@ -15,9 +15,11 @@ bow.bookmark.add.successful=Marque-page ajout\u00E9 avec succ\u00E8s bow.bookmark.badFileFormat=Mauvais format de fichier de favoris \: import impossible (le format de type Netscape n'est pas support\u00E9) bow.bookmark.description=Description +bow.bookmark.favicon.updated.successful= bow.bookmark.import.delete.successful=Les marque-pages import\u00E9s ont \u00E9t\u00E9 supprim\u00E9s avec succ\u00E8s bow.bookmark.import.successful=Les marque-pages ont \u00E9t\u00E9 import\u00E9s avec succ\u00E8s bow.bookmark.remove.successful=Le marque-page a \u00E9t\u00E9 supprim\u00E9 avec succ\u00E8s +bow.bookmark.screenshot.updated.successful= bow.bookmark.tag.deleted=Le tag a \u00E9t\u00E9 supprim\u00E9 avec succ\u00E8s bow.bookmark.tags=Tags bow.bookmark.update.successful=Le marque-page a \u00E9t\u00E9 mis \u00E0 jour avec succ\u00E8s @@ -30,6 +32,7 @@ bow.config.bow.prefix.search.fulltext.description= bow.config.bow.prefix.suggestion.alias.description= bow.config.bow.prefix.suggestion.fulltext.description= +bow.config.bow.screenshot.url.description= bow.config.bow.smtpServer.description=Adresse du serveur de mail bow.config.bow.url.description=Url public du serveur bow bow.config.configFileName.description=Fichier de configuration de bow @@ -68,6 +71,8 @@ bow.mail.badFormat=Votre adresse email est mal form\u00E9e \: aucun mail n''a pu \u00EAtre envoy\u00E9 bow.mail.sendError=Une erreur s''est produite lors de l''envoi du mail bow.opensearch.result=%s r\u00E9sultats +bow.permanent.link.search= +bow.permanent.link.suggestion= bow.preference.opensearch.prefix.separator=Separateur de pr\u00E9fix bow.preferences.badCurrentPassword=Votre mot de passe actuel est incorrect bow.preferences.bookmarksHomePage=Nombre de marque-pages affich\u00E9s @@ -76,6 +81,7 @@ bow.preferences.currentPassword=Mot de passe actuel bow.preferences.emailAldyExists=Cette addresse email est d\u00E9j\u00E0 utilis\u00E9e par un autre compte bow.preferences.export.bookmarks=Exporter les marque-pages +bow.preferences.favicon= bow.preferences.import.bookmarks=Importer des marques-pages bow.preferences.import.submit=Importer bow.preferences.importExport=Import / Export @@ -96,6 +102,7 @@ bow.preferences.opensearch.value=Valeur bow.preferences.opensearch.web.search.prefix=Recherche Web bow.preferences.regenPermToken=Reg\u00E9n\u00E9rer le token permanent +bow.preferences.screenshot= bow.preferences.searchEngineUrlResults=Search Engine URL Results ('{'searchTerms'}' sera remplac\u00E9 par votre recherche) bow.preferences.searchEngineUrlSuggestions=Search Engine URL Suggestions bow.preferences.siteLook=Pr\u00E9f\u00E9rences du site @@ -157,6 +164,8 @@ bow.search.results.deleted=Les r\u00E9sultats de la recherche ont \u00E9t\u00E9 supprim\u00E9s avec succ\u00E8s bow.search.submit=Rechercher bow.search.title=Recherche +bow.temporary.link.search= +bow.temporary.link.suggestion= bow.token.generate.successful=Le token a \u00E9t\u00E9 reg\u00E9n\u00E9r\u00E9 avec succ\u00E8s popup.addurl.alias.private=Alias priv\u00E9 popup.addurl.alias.public=Alias public Modified: trunk/bow-ui/src/main/resources/struts.xml =================================================================== --- trunk/bow-ui/src/main/resources/struts.xml 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/resources/struts.xml 2013-09-26 18:18:46 UTC (rev 368) @@ -132,6 +132,10 @@ <result name="error">/WEB-INF/jsp/home.jsp</result> <result>/WEB-INF/jsp/home.jsp</result> </action> + <action name="screenshotBookmark" class="org.chorem.bow.action.bookmark.ScreenshotAction"> + <result name="error" type="redirect">${redirectTo}</result> + <result type="redirect">${redirectTo}</result> + </action> <action name="removeBookmark" class="org.chorem.bow.action.bookmark.RemoveAction"> <result name="error" type="redirect">${redirectTo}</result> <result type="redirect">${redirectTo}</result> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/home.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/home.jsp 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/home.jsp 2013-09-26 18:18:46 UTC (rev 368) @@ -80,7 +80,7 @@ </div> <div class="content"> <s:if test="searchResult.bookmarks.empty"> - <p class="nobookmarks"><s:text name="bow.bookmarks.noBookmarks" /></p> + <p class="nobookmarks"><s:text name="bow.bookmarks.noBookmarks" /></p> </s:if> <s:else> <s:iterator value="searchResult.bookmarks" var="bookmark"> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/inc/bookmark.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/inc/bookmark.jsp 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/inc/bookmark.jsp 2013-09-26 18:18:46 UTC (rev 368) @@ -24,49 +24,92 @@ <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <%@taglib prefix="sj" uri="/struts-jquery-tags" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib uri="http://java.sun.com/jsp/jstl/functions"prefix="fn" %> +<jsp:useBean id="bowUtils" class="org.chorem.bow.BowUtils"></jsp:useBean> <div class="bookmark" xmlns:s="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" xmlns:jsp="http://java.sun.com/JSP/Page"> <div class="bookmarkhead"> - <p class="date"><s:property value="#bookmark.creationDate"/></p> - <s:a cssClass="alias" href="%{config.aliasUrl + #bookmark.wikittyId}.action" - title="%{#bookmark.link}" target="_blank"> - a:<s:property value="%{#bookmark.privateAlias}" /> - </s:a> - <s:if test="%{!#bookmark.publicAlias.empty}"> - <s:a cssClass="alias" href="%{config.aliasUrl + #bookmark.publicAlias}.action" - title="%{#bookmark.link}" target="_blank"> - <s:property value="%{#bookmark.publicAlias}" /> - </s:a> - </s:if> - <s:url var="editBookmark" action="editBookmark" escapeAmp="true"> - <s:param name="id" value="%{#bookmark.wikittyId}" /> - <s:param name="tagLine" value="%{tagLine}" /> - <s:param name="fullTextLine" value="%{fullTextLine}" /> - <s:param name="order" value="%{order}"/> - <s:param name="first" value="%{first}"/> - </s:url> - <s:a cssClass="edit" href="%{editBookmark}"/> - - <s:url var="removeBookmark" action="removeBookmark" escapeAmp="true"> - <s:param name="bookmarkId" value="%{#bookmark.wikittyId}" /> - <s:param name="tagLine" value="%{tagLine}" /> - <s:param name="fullTextLine" value="%{fullTextLine}" /> - <s:param name="order" value="%{order}"/> - <s:param name="first" value="%{first}"/> - </s:url> - <s:a cssClass="supprim" href="%{removeBookmark}" - onclick="return deleteConfirmation('%{#removeBookmark}','%{#bookmark.link}');"></s:a> + <span class="left"> + <s:set var="favicon" value="#bookmark.favicon"/> + <c:if test="${fn:length(favicon) > 0}"> + <img class="favicon" src="data:image/png;base64,${bowUtils.toBase64(favicon)}"/> + </c:if> + <c:if test="${fn:length(favicon) <= 0}"> + <img src="img/ptit-livre.jpg"/> + </c:if> + </span> + <span class="left date"><s:property value="#bookmark.creationDate"/></span> + <span class="left"> + <s:if test="%{!#bookmark.privateAlias.empty}"> + <s:a cssClass="alias" href="%{config.aliasUrl + #bookmark.wikittyId}.action" + title="%{#bookmark.link}" target="_blank"> + a:<s:property value="%{#bookmark.privateAlias}" /> + </s:a> + </s:if> + </span> + <span class="left"> + <s:if test="%{!#bookmark.publicAlias.empty}"> + <s:a cssClass="alias" href="%{config.aliasUrl + #bookmark.publicAlias}.action" + title="%{#bookmark.link}" target="_blank"> + a:<s:property value="%{#bookmark.publicAlias}" /> + </s:a> + </s:if> + </span> + <span class="spacemax"></span> + <span class="right"> + <s:url var="screenshotBookmark" action="screenshotBookmark" escapeAmp="true"> + <s:param name="id" value="%{#bookmark.wikittyId}" /> + <s:param name="tagLine" value="%{tagLine}" /> + <s:param name="fullTextLine" value="%{fullTextLine}" /> + <s:param name="order" value="%{order}"/> + <s:param name="first" value="%{first}"/> + </s:url> + <s:a cssClass="screenshotLink" href="%{screenshotBookmark}"/> + </span> + <span class="right"> + <s:url var="editBookmark" action="editBookmark" escapeAmp="true"> + <s:param name="id" value="%{#bookmark.wikittyId}" /> + <s:param name="tagLine" value="%{tagLine}" /> + <s:param name="fullTextLine" value="%{fullTextLine}" /> + <s:param name="order" value="%{order}"/> + <s:param name="first" value="%{first}"/> + </s:url> + <s:a cssClass="edit" href="%{editBookmark}"/> + </span> + <span class="right"> + <s:url var="removeBookmark" action="removeBookmark" escapeAmp="true"> + <s:param name="bookmarkId" value="%{#bookmark.wikittyId}" /> + <s:param name="tagLine" value="%{tagLine}" /> + <s:param name="fullTextLine" value="%{fullTextLine}" /> + <s:param name="order" value="%{order}"/> + <s:param name="first" value="%{first}"/> + </s:url> + <s:a cssClass="supprim" href="%{removeBookmark}" + onclick="return deleteConfirmation('%{#removeBookmark}','%{#bookmark.link}');"></s:a> + </span> </div> <div class="bookmarkcontenu"> <s:a title="%{#bookmark.link}" href="alias/%{#bookmark.wikittyId}.action" target="_blank"> - <div class="screenshot"></div> + <div class="screenshot"> + <s:set var="screenshot" value="#bookmark.screenshot"/> + <c:if test="${fn:length(screenshot) > 0}"> + <img src="data:image/png;base64,${bowUtils.toBase64(screenshot)}"/> + </c:if> + <c:if test="${fn:length(screenshot) <= 0}"> + <img src="img/livreG.jpg"/> + </c:if> + </div> </s:a> <div class="click"><s:property value="%{#bookmark.click}" /></div> <div class="description"> + <p> + <s:a href="alias/%{#bookmark.wikittyId}.action"><s:property value="%{#bookmark.link}"/></s:a> + </p> <h3><s:text name="bow.bookmark.description" /> :</h3> <p> <s:property value="%{#bookmark.description}"/> Modified: trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp =================================================================== --- trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/webapp/WEB-INF/jsp/preferences.jsp 2013-09-26 18:18:46 UTC (rev 368) @@ -25,12 +25,6 @@ <%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@taglib prefix="s" uri="/struts-tags" %> -<%-- -PreferenceBaseAction action = PreferenceBaseAction.getAction(); -PreferenceBaseAction.DefaultPrefix defaultAction = action.getDefaultAction(); -PreferenceBaseAction.DefaultPrefix defaultPrefix = action.getDefaultPrefix(); ---%> - <html xmlns:s="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" xmlns:jsp="http://java.sun.com/JSP/Page"> <head> @@ -51,6 +45,30 @@ <s:set var="temporaryToken" value="bowSession.getTemporaryToken()" /> <ul> <li> + <s:a title="%{getText('bow.temporary.link.searchDescription')}" + href="openSearchResult.action?token=%{temporaryToken}&q={searchTerms}"> + <s:text name="bow.temporary.link.search" /> + </s:a> + </li> + <li> + <s:a title="%{getText('bow.permanent.link.searchDescription')}" + href="openSearchResult.action?token=%{permanentToken}&q={searchTerms}"> + <s:text name="bow.permanent.link.search" /> + </s:a> + </li> + <li> + <s:a title="%{getText('bow.temporary.link.suggestionDescription')}" + href="openSearchSuggestion.action?token=%{temporaryToken}&q={searchTerms}"> + <s:text name="bow.temporary.link.suggestion" /> + </s:a> + </li> + <li> + <s:a title="%{getText('bow.permanent.link.suggestionDescription')}" + href="openSearchSuggestion.action?token=%{permanentToken}&q={searchTerms}"> + <s:text name="bow.permanent.link.suggestion" /> + </s:a> + </li> + <li> <s:a title="%{getText('bow.rightMenu.bookmark.temporaryLinkDescription')}" href="javascript:var%20url=location.href;var%20nameAndTags=prompt('Entrez%20le%20nom%20du%20lien%20et%20la%20liste%20des%20tags%20sous%20la%20forme:%20name|tag1%20tag2%20tag3',%20document.title+'|');var%20link='%{config.bowUrl}addUrl.action?token=%{temporaryToken}&link='+encodeURIComponent(url)+'&nameAndTags='+encodeURIComponent(nameAndTags);var%20script=document.createElement('script');script.src=link;script.type='text/javascript';document.body.appendChild(script);void(0);"> <s:text name="bow.rightMenu.bookmark.temporaryLink" /> @@ -122,6 +140,12 @@ <s:form name="updateSitePref" action="updateSitePref" theme="simple"> <s:hidden name="removedPrefix" value="-1"/> + <s:text name="bow.preferences.screenshot"/><br/> + <s:checkbox name="screenshot" labelposition="left"/><br/> + + <s:text name="bow.preferences.favicon"/><br/> + <s:checkbox name="favicon" labelposition="left"/><br/> + <s:text name="bow.preferences.tagsNb"/><br/> <s:textfield name="tagsNb" labelposition="top"/><br/> Modified: trunk/bow-ui/src/main/webapp/css/bookmark.css =================================================================== --- trunk/bow-ui/src/main/webapp/css/bookmark.css 2013-09-25 05:36:58 UTC (rev 367) +++ trunk/bow-ui/src/main/webapp/css/bookmark.css 2013-09-26 18:18:46 UTC (rev 368) @@ -83,6 +83,16 @@ word-wrap:break-word; } +.spacemax { + width: 100%; +} + +.bookmark .favicon { + width: 32px; + height: 32px; + float:left; +} + .bookmark .bookmarkhead{ width:100%; height:32px; @@ -105,6 +115,16 @@ margin-top:10px; } +.bookmark .bookmarkhead .screenshotLink{ + position:absolute; + margin-top: 10px; + top:0; + right:64px; + width:31px; + height:32px; + background:url('../img/camera.png') no-repeat; +} + .bookmark .bookmarkhead .edit{ background:url('../img/edit.jpg') no-repeat; width:31px; @@ -128,8 +148,8 @@ font-weight:bold; font-size:14px; line-height:32px; - padding-left:40px; - background:url('../img/ptit-livre.jpg') no-repeat; + /*padding-left:40px;*/ + /*background:url('../img/ptit-livre.jpg') no-repeat;*/ height:32px; display:block; text-decoration:none; @@ -150,7 +170,7 @@ margin:5px 10px; width:100px; height:75px; - background:url('../img/livreG.jpg') no-repeat; + /*background:url('../img/livreG.jpg') no-repeat;*/ } .bookmark .description{ Added: trunk/bow-ui/src/main/webapp/img/camera.png =================================================================== (Binary files differ) Property changes on: trunk/bow-ui/src/main/webapp/img/camera.png ___________________________________________________________________ Added: svn:mime-type + image/png Modified: trunk/bow-ui/src/main/xmi/bow-model.zargo =================================================================== (Binary files differ)
participants (1)
-
bpoussin@users.chorem.org