Commit 8fe41bb4 authored by Benoit Lavenier's avatar Benoit Lavenier

Add OG Data URL to share profile and page easily on social network

parent 00d26ef5
# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
#-------------------------------------------------------------------------------
# Already used licenses in project :
# - ASL, version 2
# - Apache 2.0
# - Apache License 2.0
# - Apache License Version 2.0
# - BSD License
# - BSD licence
# - CC0 1.0 Universal
# - CDDL
# - CDDL+GPL
# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
# - Common Development and Distribution License (CDDL) v1.0
# - Dual license consisting of the CDDL v1.1 and GPL v2
# - Eclipse Public License 1.0
# - GPLv2+CE
# - General Public License (GPL) v3
# - Indiana University Extreme! Lab Software License, vesion 1.1.1
# - LGPL, version 2.1
# - Lesser General Public License (LGPL) v 3.0
# - Lesser General Public License (LPGL)
# - Lesser General Public License (LPGL) v 2.1
# - Lesser General Public License (LPGL) version 3.0
# - MIT License
# - New BSD License
# - Public Domain, per Creative Commons CC0
# - The Apache Software License, Version 2.0
#-------------------------------------------------------------------------------
# Please fill the missing licenses for dependencies :
#
#
#Fri May 18 18:26:32 CEST 2018
commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0
org.antlr--antlr-runtime--3.3=BSD License
...@@ -261,6 +261,10 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> { ...@@ -261,6 +261,10 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
return settings.getAsInt("duniter.retry.waitDuration", 5000); return settings.getAsInt("duniter.retry.waitDuration", 5000);
} }
public String getShareBaseUrl() {
return settings.get("duniter.share.base.url");
}
public Peer checkAndGetPeer() { public Peer checkAndGetPeer() {
if (StringUtils.isBlank(getNodeBmaHost())) { if (StringUtils.isBlank(getNodeBmaHost())) {
logger.error("ERROR: node host is required"); logger.error("ERROR: node host is required");
......
...@@ -14,7 +14,8 @@ import org.elasticsearch.common.logging.Loggers; ...@@ -14,7 +14,8 @@ import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.rest.*; import org.elasticsearch.rest.*;
import org.nuiton.i18n.I18n; import org.nuiton.i18n.I18n;
import org.stringtemplate.v4.*; import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import java.util.Locale; import java.util.Locale;
...@@ -31,23 +32,27 @@ public abstract class AbstractRestShareLinkAction extends BaseRestHandler { ...@@ -31,23 +32,27 @@ public abstract class AbstractRestShareLinkAction extends BaseRestHandler {
private OGDataResolver resolver; private OGDataResolver resolver;
private STGroup templates; private STGroup templates;
private String urlPattern;
public AbstractRestShareLinkAction(Settings settings, RestController controller, Client client, public AbstractRestShareLinkAction(Settings settings, RestController controller, Client client,
String indexName, String indexName,
String typeName, String typeName,
String shareBaseUrl,
OGDataResolver resolver OGDataResolver resolver
) { ) {
super(settings, controller, client); super(settings, controller, client);
log = Loggers.getLogger("duniter.rest." + indexName, settings, String.format("[%s]", indexName)); log = Loggers.getLogger("duniter.rest." + indexName, settings, String.format("[%s]", indexName));
String pathPattern = String.format("/%s/%s/%s/_share", indexName, typeName, "%s");
controller.registerHandler(GET, controller.registerHandler(GET,
String.format("/%s/%s/{id}/_share", indexName, typeName), String.format(pathPattern, "{id}"),
this); this);
this.urlPattern = (shareBaseUrl != null ? shareBaseUrl : "") + pathPattern;
this.resolver = resolver; this.resolver = resolver;
// Configure springtemplate engine // Configure springtemplate engine
this.templates = STUtils.newSTGroup("org/duniter/elasticsearch/templates"); this.templates = STUtils.newSTGroup("org/duniter/elasticsearch/templates");
Preconditions.checkNotNull(this.templates.getInstanceOf("html_share"), "Unable to load ST template for share page"); Preconditions.checkNotNull(this.templates.getInstanceOf("html_share"), "Unable to load ST template for share page");
} }
@Override @Override
...@@ -68,8 +73,11 @@ public abstract class AbstractRestShareLinkAction extends BaseRestHandler { ...@@ -68,8 +73,11 @@ public abstract class AbstractRestShareLinkAction extends BaseRestHandler {
template.add("description", data.description); template.add("description", data.description);
template.add("siteName", data.siteName); template.add("siteName", data.siteName);
template.add("image", data.image); template.add("image", data.image);
template.add("url", data.url); template.add("url", String.format(urlPattern, id));
template.add("redirectUrl", data.url);
template.add("locale", data.locale); template.add("locale", data.locale);
template.add("imageHeight", data.imageHeight);
template.add("imageWidth", data.imageWidth);
if (StringUtils.isNotBlank(data.url)) { if (StringUtils.isNotBlank(data.url)) {
Locale locale = data.locale != null ? new Locale(data.locale) : I18n.getDefaultLocale(); Locale locale = data.locale != null ? new Locale(data.locale) : I18n.getDefaultLocale();
template.add("redirectMessage", I18n.l(locale, "duniter4j.share.redirection.help")); template.add("redirectMessage", I18n.l(locale, "duniter4j.share.redirection.help"));
......
...@@ -10,4 +10,7 @@ public class OGData { ...@@ -10,4 +10,7 @@ public class OGData {
public String imageType; public String imageType;
public String siteName; public String siteName;
public Integer imageHeight;
public Integer imageWidth;
} }
html_share(type, title, summary, description, image, siteName, locale, url, redirectMessage) ::= << html_share(type, title, summary, description, image, imageHeight, imageWidth, siteName, locale, url, redirectUrl, redirectMessage) ::= <<
<!DOCTYPE html>
<html prefix="og: http://ogp.me/ns#"> <html prefix="og: http://ogp.me/ns#">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
...@@ -30,17 +31,28 @@ html_share(type, title, summary, description, image, siteName, locale, url, redi ...@@ -30,17 +31,28 @@ html_share(type, title, summary, description, image, siteName, locale, url, redi
$if(image)$ $if(image)$
<meta property="og:image" content="$image$" /> <meta property="og:image" content="$image$" />
$endif$ $endif$
$if(imageHeight)$
<meta property="og:image:height" content="$imageHeight$" />
$endif$
$if(imageWidth)$
<meta property="og:image:width" content="$imageWidth$" />
$endif$
$if(locale)$ $if(locale)$
<meta property="og:locale" content="$locale$" /> <meta property="og:locale" content="$locale$" />
$endif$ $endif$
$if(url)$ $if(url)$
<meta property="og:url" content="$url$" /> <meta property="og:url" content="$url$"/>
$endif$
$if(redirectUrl)$
<script type="text/javascript"> <script type="text/javascript">
window.location.href = "$url$" window.location.href = "$redirectUrl$"
</script> </script>
<META HTTP-EQUIV="Refresh" CONTENT="0; URL=$url$"> <!--<META HTTP-EQUIV="Refresh" CONTENT="0; URL=$redirectUrl$">
-->
$endif$ $endif$
</head> </head>
<body> <body>
...@@ -54,9 +66,9 @@ html_share(type, title, summary, description, image, siteName, locale, url, redi ...@@ -54,9 +66,9 @@ html_share(type, title, summary, description, image, siteName, locale, url, redi
<p>$description$</p> <p>$description$</p>
$if(url)$ $if(redirectUrl)$
<p> <p>
$redirectMessage$ <a href='$url$'>$title$</a>. $redirectMessage$ <a href='$redirectUrl$'>$title$</a>.
</p> </p>
$endif$ $endif$
</body> </body>
......
...@@ -220,7 +220,7 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> { ...@@ -220,7 +220,7 @@ public class PluginSettings extends AbstractLifecycleComponent<PluginSettings> {
return this.settings.get("duniter.user.share.site.name", "Cesium"); return this.settings.get("duniter.user.share.site.name", "Cesium");
} }
public String getBaseUrl() { public String getShareBaseUrl() {
return settings.get("duniter.share.base.url"); return settings.get("duniter.share.base.url");
} }
......
...@@ -10,10 +10,8 @@ import org.duniter.elasticsearch.rest.share.AbstractRestShareLinkAction; ...@@ -10,10 +10,8 @@ import org.duniter.elasticsearch.rest.share.AbstractRestShareLinkAction;
import org.duniter.elasticsearch.user.PluginSettings; import org.duniter.elasticsearch.user.PluginSettings;
import org.duniter.elasticsearch.user.dao.page.PageIndexDao; import org.duniter.elasticsearch.user.dao.page.PageIndexDao;
import org.duniter.elasticsearch.user.dao.page.PageRecordDao; import org.duniter.elasticsearch.user.dao.page.PageRecordDao;
import org.duniter.elasticsearch.user.model.UserProfile;
import org.duniter.elasticsearch.user.model.page.RegistryRecord; import org.duniter.elasticsearch.user.model.page.RegistryRecord;
import org.duniter.elasticsearch.user.service.PageService; import org.duniter.elasticsearch.user.service.PageService;
import org.duniter.elasticsearch.user.service.UserService;
import org.duniter.elasticsearch.util.opengraph.OGData; import org.duniter.elasticsearch.util.opengraph.OGData;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.inject.Inject;
...@@ -23,7 +21,6 @@ import org.nuiton.i18n.I18n; ...@@ -23,7 +21,6 @@ import org.nuiton.i18n.I18n;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Locale;
public class RestPageShareLinkAction extends AbstractRestShareLinkAction { public class RestPageShareLinkAction extends AbstractRestShareLinkAction {
...@@ -32,6 +29,7 @@ public class RestPageShareLinkAction extends AbstractRestShareLinkAction { ...@@ -32,6 +29,7 @@ public class RestPageShareLinkAction extends AbstractRestShareLinkAction {
final PluginSettings pluginSettings, final PluginSettings pluginSettings,
final PageService service) { final PageService service) {
super(settings, controller, client, PageIndexDao.INDEX, PageRecordDao.TYPE, super(settings, controller, client, PageIndexDao.INDEX, PageRecordDao.TYPE,
pluginSettings.getShareBaseUrl(),
createResolver(pluginSettings, service)); createResolver(pluginSettings, service));
} }
...@@ -60,9 +58,13 @@ public class RestPageShareLinkAction extends AbstractRestShareLinkAction { ...@@ -60,9 +58,13 @@ public class RestPageShareLinkAction extends AbstractRestShareLinkAction {
// og:image // og:image
if (record.getThumbnail() != null && StringUtils.isNotBlank(record.getThumbnail().get("_content_type"))) { if (record.getThumbnail() != null && StringUtils.isNotBlank(record.getThumbnail().get("_content_type"))) {
String baseUrl = pluginSettings.getBaseUrl(); String baseUrl = pluginSettings.getShareBaseUrl();
data.image = StringUtils.isBlank(baseUrl) ? "" : baseUrl; data.image = StringUtils.isBlank(baseUrl) ? "" : baseUrl;
data.image += RestImageAttachmentAction.computeImageUrl(PageIndexDao.INDEX, PageRecordDao.TYPE, id, RegistryRecord.PROPERTY_THUMBNAIL, record.getThumbnail().get("_content_type")); data.image += RestImageAttachmentAction.computeImageUrl(PageIndexDao.INDEX, PageRecordDao.TYPE, id, RegistryRecord.PROPERTY_THUMBNAIL, record.getThumbnail().get("_content_type"));
// FIXME : use a greater image ? at least 200px x 200px for FaceBook
data.imageHeight = 100;
data.imageWidth = 100;
} }
// og:url // og:url
...@@ -94,8 +96,10 @@ public class RestPageShareLinkAction extends AbstractRestShareLinkAction { ...@@ -94,8 +96,10 @@ public class RestPageShareLinkAction extends AbstractRestShareLinkAction {
// default og:image // default og:image
if (StringUtils.isBlank(data.image)) { if (StringUtils.isBlank(data.image)) {
data.image = pluginSettings.getCesiumUrl() + "/img/logo_128px.png"; data.image = pluginSettings.getCesiumUrl() + "/img/logo_200px.png";
data.imageType = "image/png"; data.imageType = "image/png";
data.imageHeight = 200;
data.imageWidth = 200;
} }
return data; return data;
......
package org.duniter.elasticsearch.user.rest.user; package org.duniter.elasticsearch.user.rest.user;
import com.google.common.collect.Maps;
import com.google.common.html.HtmlEscapers; import com.google.common.html.HtmlEscapers;
import org.duniter.core.exception.BusinessException; import org.duniter.core.exception.BusinessException;
import org.duniter.core.exception.TechnicalException; import org.duniter.core.exception.TechnicalException;
...@@ -29,9 +28,10 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction { ...@@ -29,9 +28,10 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction {
final PluginSettings pluginSettings, final PluginSettings pluginSettings,
final UserService userService) { final UserService userService) {
super(settings, controller, client, UserService.INDEX, UserService.PROFILE_TYPE, super(settings, controller, client, UserService.INDEX, UserService.PROFILE_TYPE,
pluginSettings.getShareBaseUrl(),
createResolver(pluginSettings, userService)); createResolver(pluginSettings, userService));
if (StringUtils.isBlank(pluginSettings.getBaseUrl())) { if (StringUtils.isBlank(pluginSettings.getShareBaseUrl())) {
log.warn(I18n.t("duniter4j.es.share.error.noBaseUrl", "duniter.share.base.url")); log.warn(I18n.t("duniter4j.es.share.error.noBaseUrl", "duniter.share.base.url"));
} }
} }
...@@ -57,6 +57,7 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction { ...@@ -57,6 +57,7 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction {
else { else {
locale = I18n.getDefaultLocale(); locale = I18n.getDefaultLocale();
} }
data.locale = locale.toString();
String pubkey = I18n.l(locale, "duniter.user.share.pubkey", id); String pubkey = I18n.l(locale, "duniter.user.share.pubkey", id);
...@@ -81,9 +82,11 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction { ...@@ -81,9 +82,11 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction {
// og:image // og:image
if (profile.getAvatar() != null && StringUtils.isNotBlank(profile.getAvatar().getContentType())) { if (profile.getAvatar() != null && StringUtils.isNotBlank(profile.getAvatar().getContentType())) {
String baseUrl = pluginSettings.getBaseUrl(); String baseUrl = pluginSettings.getShareBaseUrl();
data.image = StringUtils.isBlank(baseUrl) ? "" : baseUrl; data.image = StringUtils.isBlank(baseUrl) ? "" : baseUrl;
data.image += RestImageAttachmentAction.computeImageUrl(UserService.INDEX, UserService.PROFILE_TYPE, id, UserProfile.PROPERTY_AVATAR, profile.getAvatar().getContentType()); data.image += RestImageAttachmentAction.computeImageUrl(UserService.INDEX, UserService.PROFILE_TYPE, id, UserProfile.PROPERTY_AVATAR, profile.getAvatar().getContentType());
data.imageHeight = 100;
data.imageWidth = 100;
} }
// og:url // og:url
...@@ -116,8 +119,10 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction { ...@@ -116,8 +119,10 @@ public class RestUserShareLinkAction extends AbstractRestShareLinkAction {
// default og:image // default og:image
if (StringUtils.isBlank(data.image)) { if (StringUtils.isBlank(data.image)) {
data.image = pluginSettings.getCesiumUrl() + "/img/logo_128px.png"; data.image = pluginSettings.getCesiumUrl() + "/img/logo_200px.png";
data.imageType = "image/png"; data.imageType = "image/png";
data.imageHeight = 200;
data.imageWidth = 200;
} }
return data; return data;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment