mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Publishing:
- Added start of the Flickr channel. Channel creation and authorisation is complete (written as a new Spring Social module). API not currently working. - Fixed a problem with SlideShare API: it relies on the file extension to determine the type of the file, so needed to alter the way the files are sent. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29085 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -27,5 +27,6 @@
|
|||||||
<import resource="classpath*:alfresco/youtube-publishing-context.xml" />
|
<import resource="classpath*:alfresco/youtube-publishing-context.xml" />
|
||||||
<import resource="classpath*:alfresco/twitter-publishing-context.xml" />
|
<import resource="classpath*:alfresco/twitter-publishing-context.xml" />
|
||||||
<import resource="classpath*:alfresco/slideshare-publishing-context.xml" />
|
<import resource="classpath*:alfresco/slideshare-publishing-context.xml" />
|
||||||
|
<import resource="classpath*:alfresco/flickr-publishing-context.xml" />
|
||||||
<import resource="classpath*:alfresco/domain/*-context.xml" />
|
<import resource="classpath*:alfresco/domain/*-context.xml" />
|
||||||
</beans>
|
</beans>
|
||||||
|
36
config/alfresco/flickr-publishing-context.xml
Normal file
36
config/alfresco/flickr-publishing-context.xml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
<bean parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
|
||||||
|
<property name="models">
|
||||||
|
<list>
|
||||||
|
<value>alfresco/model/flickrPublishingModel.xml</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="flickrDeliveryChannelType" class="org.alfresco.repo.publishing.flickr.FlickrChannelType" parent="baseChannelType" >
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
<property name="publishingHelper" ref="flickrPublishingHelper" />
|
||||||
|
<property name="actionService" ref="ActionService" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="flickrPublishingHelper" class="org.alfresco.repo.publishing.flickr.FlickrPublishingHelper">
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
<property name="connectionFactory">
|
||||||
|
<bean class="org.springframework.social.flickr.connect.FlickrConnectionFactory">
|
||||||
|
<constructor-arg value="cc61f5d37569cec8c04fce8b4db3f37d" />
|
||||||
|
<constructor-arg value="75f29c6fc18a1b0c" />
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="publish_flickr" parent="action-executer" class="org.alfresco.repo.publishing.flickr.FlickrPublishAction">
|
||||||
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
<property name="taggingService" ref="TaggingService" />
|
||||||
|
<property name="contentService" ref="ContentService" />
|
||||||
|
<property name="flickrHelper" ref="flickrPublishingHelper" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
47
config/alfresco/model/flickrPublishingModel.xml
Normal file
47
config/alfresco/model/flickrPublishingModel.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<model name="flickr:publishingmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
|
||||||
|
|
||||||
|
<description>Alfresco Flickr Publishing Content Model</description>
|
||||||
|
<author>Alfresco</author>
|
||||||
|
<published>2011-07-13</published>
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<imports>
|
||||||
|
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
|
||||||
|
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys" />
|
||||||
|
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
|
||||||
|
<import uri="http://www.alfresco.org/model/publishing/1.0" prefix="pub" />
|
||||||
|
</imports>
|
||||||
|
|
||||||
|
<namespaces>
|
||||||
|
<namespace uri="http://www.alfresco.org/model/publishing/flickr/1.0" prefix="flickr" />
|
||||||
|
</namespaces>
|
||||||
|
|
||||||
|
<types>
|
||||||
|
<type name="flickr:DeliveryChannel">
|
||||||
|
<title>Flickr Delivery Channel</title>
|
||||||
|
<description>Node type used to represent Flickr delivery channels</description>
|
||||||
|
<parent>pub:DeliveryChannel</parent>
|
||||||
|
<mandatory-aspects>
|
||||||
|
<aspect>pub:OAuth1DeliveryChannelAspect</aspect>
|
||||||
|
</mandatory-aspects>
|
||||||
|
</type>
|
||||||
|
|
||||||
|
</types>
|
||||||
|
|
||||||
|
<aspects>
|
||||||
|
<aspect name="flickr:AssetAspect">
|
||||||
|
<title>Flickr Asset</title>
|
||||||
|
<description>Applied to a node that has been published to Flickr</description>
|
||||||
|
<properties>
|
||||||
|
<property name="flickr:assetId">
|
||||||
|
<title>Flickr asset Id</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
|
<property name="flickr:assetUrl">
|
||||||
|
<title>Flickr Asset URL</title>
|
||||||
|
<type>d:text</type>
|
||||||
|
</property>
|
||||||
|
</properties>
|
||||||
|
</aspect>
|
||||||
|
</aspects>
|
||||||
|
</model>
|
@@ -30,6 +30,7 @@
|
|||||||
<bean id="slideshareDeliveryChannelType" class="org.alfresco.repo.publishing.slideshare.SlideShareChannelType" parent="baseChannelType" >
|
<bean id="slideshareDeliveryChannelType" class="org.alfresco.repo.publishing.slideshare.SlideShareChannelType" parent="baseChannelType" >
|
||||||
<property name="actionService" ref="ActionService" />
|
<property name="actionService" ref="ActionService" />
|
||||||
<property name="nodeService" ref="NodeService" />
|
<property name="nodeService" ref="NodeService" />
|
||||||
|
<property name="publishingHelper" ref="slidesharePublishingHelper" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -107,7 +107,6 @@
|
|||||||
<bean id="urlShortener" class="org.alfresco.repo.urlshortening.BitlyUrlShortenerImpl" >
|
<bean id="urlShortener" class="org.alfresco.repo.urlshortening.BitlyUrlShortenerImpl" >
|
||||||
<property name="username" value="${urlshortening.bitly.username}" />
|
<property name="username" value="${urlshortening.bitly.username}" />
|
||||||
<property name="apiKey" value="${urlshortening.bitly.api.key}" />
|
<property name="apiKey" value="${urlshortening.bitly.api.key}" />
|
||||||
<property name="urlLength" value="${urlshortening.bitly.url.length}" />
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
BIN
config/test/alfresco/TestImageFile.png
Normal file
BIN
config/test/alfresco/TestImageFile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
@@ -175,16 +175,18 @@ public class ChannelServiceImpl implements ChannelService
|
|||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public void deleteChannel(String siteId, String channelName)
|
public void deleteChannel(Channel channel)
|
||||||
{
|
{
|
||||||
Set<NodeRef> containers = getAllChannelContainers(siteId);
|
List<NodeRef> allChannelNodes = new ArrayList<NodeRef>();
|
||||||
for (NodeRef channelContainer : containers)
|
NodeRef editorialNode = channel.getNodeRef();
|
||||||
|
allChannelNodes.add(editorialNode);
|
||||||
|
for (AssociationRef assoc : nodeService.getSourceAssocs(editorialNode, PublishingModel.ASSOC_EDITORIAL_CHANNEL))
|
||||||
{
|
{
|
||||||
NodeRef channel = nodeService.getChildByName(channelContainer, ContentModel.ASSOC_CONTAINS, channelName);
|
allChannelNodes.add(assoc.getSourceRef());
|
||||||
if (channel != null)
|
}
|
||||||
{
|
for (NodeRef channelNode : allChannelNodes)
|
||||||
nodeService.deleteNode(channel);
|
{
|
||||||
}
|
nodeService.deleteNode(channelNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -97,7 +97,8 @@ public class ChannelServiceImplIntegratedTest extends AbstractPublishingIntegrat
|
|||||||
{
|
{
|
||||||
testCreateChannel();
|
testCreateChannel();
|
||||||
|
|
||||||
channelService.deleteChannel(siteId, channelName);
|
Channel channel = channelService.getChannel(siteId, channelName);
|
||||||
|
channelService.deleteChannel(channel);
|
||||||
|
|
||||||
List<Channel> channels = channelService.getChannels(siteId);
|
List<Channel> channels = channelService.getChannels(siteId);
|
||||||
assertTrue(channels.isEmpty());
|
assertTrue(channels.isEmpty());
|
||||||
|
@@ -24,10 +24,7 @@ import org.alfresco.service.cmr.repository.NodeService;
|
|||||||
import org.springframework.social.connect.Connection;
|
import org.springframework.social.connect.Connection;
|
||||||
import org.springframework.social.facebook.api.Facebook;
|
import org.springframework.social.facebook.api.Facebook;
|
||||||
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
|
import org.springframework.social.facebook.connect.FacebookConnectionFactory;
|
||||||
import org.springframework.social.oauth1.OAuthToken;
|
|
||||||
import org.springframework.social.oauth2.AccessGrant;
|
import org.springframework.social.oauth2.AccessGrant;
|
||||||
import org.springframework.social.twitter.api.Twitter;
|
|
||||||
import org.springframework.social.twitter.connect.TwitterConnectionFactory;
|
|
||||||
|
|
||||||
public class FacebookPublishingHelper
|
public class FacebookPublishingHelper
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.AbstractChannelType;
|
||||||
|
import org.alfresco.repo.publishing.PublishingModel;
|
||||||
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.action.ActionService;
|
||||||
|
import org.alfresco.service.cmr.publishing.channels.Channel;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
|
import org.springframework.social.oauth1.AuthorizedRequestToken;
|
||||||
|
import org.springframework.social.oauth1.OAuth1Operations;
|
||||||
|
import org.springframework.social.oauth1.OAuth1Parameters;
|
||||||
|
import org.springframework.social.oauth1.OAuthToken;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
|
public class FlickrChannelType extends AbstractChannelType
|
||||||
|
{
|
||||||
|
public final static String ID = "flickr";
|
||||||
|
private NodeService nodeService;
|
||||||
|
private FlickrPublishingHelper publishingHelper;
|
||||||
|
private ActionService actionService;
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPublishingHelper(FlickrPublishingHelper flickrPublishingHelper)
|
||||||
|
{
|
||||||
|
this.publishingHelper = flickrPublishingHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActionService(ActionService actionService)
|
||||||
|
{
|
||||||
|
this.actionService = actionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPublish()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPublishStatusUpdates()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUnpublish()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QName getChannelNodeType()
|
||||||
|
{
|
||||||
|
return FlickrPublishingModel.TYPE_DELIVERY_CHANNEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId()
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<QName> getSupportedContentTypes()
|
||||||
|
{
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getSupportedMimetypes()
|
||||||
|
{
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publish(NodeRef nodeToPublish, Map<QName, Serializable> properties)
|
||||||
|
{
|
||||||
|
Action publishAction = actionService.createAction(FlickrPublishAction.NAME);
|
||||||
|
actionService.executeAction(publishAction, nodeToPublish);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unpublish(NodeRef nodeToUnpublish, Map<QName, Serializable> properties)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateStatus(Channel channel, String status, Map<QName, Serializable> properties)
|
||||||
|
{
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNodeUrl(NodeRef node)
|
||||||
|
{
|
||||||
|
String url = null;
|
||||||
|
if (node != null && nodeService.exists(node) && nodeService.hasAspect(node, FlickrPublishingModel.ASPECT_ASSET))
|
||||||
|
{
|
||||||
|
url = (String)nodeService.getProperty(node, FlickrPublishingModel.PROP_ASSET_URL);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthorisationUrl(Channel channel, String callbackUrl)
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("channel", channel);
|
||||||
|
ParameterCheck.mandatory("callbackUrl", callbackUrl);
|
||||||
|
if (!ID.equals(channel.getChannelType().getId()))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid channel type: " + channel.getChannelType().getId());
|
||||||
|
}
|
||||||
|
OAuth1Operations oauthOperations = publishingHelper.getConnectionFactory().getOAuthOperations();
|
||||||
|
OAuthToken requestToken = oauthOperations.fetchRequestToken(callbackUrl, null);
|
||||||
|
|
||||||
|
NodeRef channelNodeRef = channel.getNodeRef();
|
||||||
|
nodeService.setProperty(channelNodeRef, PublishingModel.PROP_OAUTH1_TOKEN_SECRET, requestToken.getSecret());
|
||||||
|
nodeService.setProperty(channelNodeRef, PublishingModel.PROP_OAUTH1_TOKEN_VALUE, requestToken.getValue());
|
||||||
|
|
||||||
|
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
|
||||||
|
params.add("perms", "delete");
|
||||||
|
OAuth1Parameters oauthParams = new OAuth1Parameters(callbackUrl, params);
|
||||||
|
return oauthOperations.buildAuthorizeUrl(requestToken.getValue(), oauthParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean acceptAuthorisationCallback(Channel channel, Map<String, String[]> callbackHeaders,
|
||||||
|
Map<String, String[]> callbackParams)
|
||||||
|
{
|
||||||
|
boolean authorised = false;
|
||||||
|
String[] verifier = callbackParams.get("oauth_verifier");
|
||||||
|
if (verifier != null)
|
||||||
|
{
|
||||||
|
OAuth1Operations oauthOperations = publishingHelper.getConnectionFactory().getOAuthOperations();
|
||||||
|
NodeRef channelNodeRef = channel.getNodeRef();
|
||||||
|
|
||||||
|
Map<QName, Serializable> currentProps = nodeService.getProperties(channelNodeRef);
|
||||||
|
String tokenValue = (String) currentProps.get(PublishingModel.PROP_OAUTH1_TOKEN_VALUE);
|
||||||
|
String tokenSecret = (String) currentProps.get(PublishingModel.PROP_OAUTH1_TOKEN_SECRET);
|
||||||
|
OAuthToken token = new OAuthToken(tokenValue, tokenSecret);
|
||||||
|
OAuthToken accessToken = oauthOperations.exchangeForAccessToken(new AuthorizedRequestToken(token, verifier[0]), null);
|
||||||
|
|
||||||
|
Map<QName, Serializable> newProps = new HashMap<QName, Serializable>();
|
||||||
|
newProps.put(PublishingModel.PROP_OAUTH1_TOKEN_VALUE, accessToken.getValue());
|
||||||
|
newProps.put(PublishingModel.PROP_OAUTH1_TOKEN_SECRET, accessToken.getSecret());
|
||||||
|
getChannelService().updateChannel(channel, newProps);
|
||||||
|
authorised = true;
|
||||||
|
}
|
||||||
|
return authorised;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
||||||
|
import org.alfresco.repo.content.filestore.FileContentReader;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.Flickr;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.MediaOperations;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.PhotoMetadata;
|
||||||
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.tagging.TaggingService;
|
||||||
|
import org.alfresco.util.TempFileProvider;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.social.connect.Connection;
|
||||||
|
|
||||||
|
public class FlickrPublishAction extends ActionExecuterAbstractBase
|
||||||
|
{
|
||||||
|
private final static Log log = LogFactory.getLog(FlickrPublishAction.class);
|
||||||
|
|
||||||
|
public static final String NAME = "publish_flickr";
|
||||||
|
|
||||||
|
private NodeService nodeService;
|
||||||
|
private ContentService contentService;
|
||||||
|
private TaggingService taggingService;
|
||||||
|
private FlickrPublishingHelper flickrHelper;
|
||||||
|
|
||||||
|
public void setFlickrHelper(FlickrPublishingHelper helper)
|
||||||
|
{
|
||||||
|
this.flickrHelper = helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentService(ContentService contentService)
|
||||||
|
{
|
||||||
|
this.contentService = contentService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaggingService(TaggingService taggingService)
|
||||||
|
{
|
||||||
|
this.taggingService = taggingService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void executeImpl(Action action, NodeRef nodeToPublish)
|
||||||
|
{
|
||||||
|
ContentReader reader = contentService.getReader(nodeToPublish, ContentModel.PROP_CONTENT);
|
||||||
|
if (reader.exists())
|
||||||
|
{
|
||||||
|
File contentFile;
|
||||||
|
boolean deleteContentFileOnCompletion = false;
|
||||||
|
if (FileContentReader.class.isAssignableFrom(reader.getClass()))
|
||||||
|
{
|
||||||
|
// Grab the content straight from the content store if we can...
|
||||||
|
contentFile = ((FileContentReader) reader).getFile();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ...otherwise copy it to a temp file and use the copy...
|
||||||
|
File tempDir = TempFileProvider.getLongLifeTempDir("flickr");
|
||||||
|
contentFile = TempFileProvider.createTempFile("flickr", "", tempDir);
|
||||||
|
reader.getContent(contentFile);
|
||||||
|
deleteContentFileOnCompletion = true;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Resource res = new FileSystemResource(contentFile);
|
||||||
|
Connection<Flickr> connection = flickrHelper.getConnectionForPublishNode(nodeToPublish);
|
||||||
|
|
||||||
|
String name = (String) nodeService.getProperty(nodeToPublish, ContentModel.PROP_NAME);
|
||||||
|
String title = (String) nodeService.getProperty(nodeToPublish, ContentModel.PROP_TITLE);
|
||||||
|
if (title == null || title.length() == 0)
|
||||||
|
{
|
||||||
|
title = name;
|
||||||
|
}
|
||||||
|
String description = (String) nodeService.getProperty(nodeToPublish, ContentModel.PROP_DESCRIPTION);
|
||||||
|
if (description == null || description.length() == 0)
|
||||||
|
{
|
||||||
|
description = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaOperations mediaOps = connection.getApi().mediaOperations();
|
||||||
|
PhotoMetadata metadata = mediaOps.createPhotoMetadata();
|
||||||
|
metadata.setTitle(title);
|
||||||
|
metadata.setDescription(description);
|
||||||
|
String id = mediaOps.postPhoto(res, metadata);
|
||||||
|
log.info("Posted image " + name + " to Flickr with id " + id);
|
||||||
|
nodeService.setProperty(nodeToPublish, FlickrPublishingModel.PROP_ASSET_ID, id);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (deleteContentFileOnCompletion)
|
||||||
|
{
|
||||||
|
contentFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addParameterDefinitions(List<ParameterDefinition> paramList)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.PublishingModel;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.Flickr;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.connect.FlickrConnectionFactory;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.springframework.social.connect.Connection;
|
||||||
|
import org.springframework.social.oauth1.OAuthToken;
|
||||||
|
|
||||||
|
public class FlickrPublishingHelper
|
||||||
|
{
|
||||||
|
private NodeService nodeService;
|
||||||
|
private FlickrConnectionFactory connectionFactory;
|
||||||
|
|
||||||
|
public void setNodeService(NodeService nodeService)
|
||||||
|
{
|
||||||
|
this.nodeService = nodeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnectionFactory(FlickrConnectionFactory connectionFactory)
|
||||||
|
{
|
||||||
|
this.connectionFactory = connectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlickrConnectionFactory getConnectionFactory()
|
||||||
|
{
|
||||||
|
return connectionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Connection<Flickr> getConnectionForPublishNode(NodeRef publishNode)
|
||||||
|
{
|
||||||
|
Connection<Flickr> connection = null;
|
||||||
|
NodeRef channelNode = nodeService.getPrimaryParent(publishNode).getParentRef();
|
||||||
|
if (nodeService.exists(channelNode)
|
||||||
|
&& nodeService.hasAspect(channelNode, PublishingModel.ASPECT_OAUTH1_DELIVERY_CHANNEL))
|
||||||
|
{
|
||||||
|
String tokenValue = (String) nodeService.getProperty(channelNode, PublishingModel.PROP_OAUTH1_TOKEN_VALUE);
|
||||||
|
String tokenSecret = (String) nodeService.getProperty(channelNode, PublishingModel.PROP_OAUTH1_TOKEN_SECRET);
|
||||||
|
Boolean danceComplete = (Boolean) nodeService.getProperty(channelNode, PublishingModel.PROP_AUTHORISATION_COMPLETE);
|
||||||
|
|
||||||
|
if (danceComplete)
|
||||||
|
{
|
||||||
|
OAuthToken token = new OAuthToken(tokenValue, tokenSecret);
|
||||||
|
connection = connectionFactory.createConnection(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2011 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.repo.publishing.flickr;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brian
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface FlickrPublishingModel
|
||||||
|
{
|
||||||
|
public static final String NAMESPACE = "http://www.alfresco.org/model/publishing/flickr/1.0";
|
||||||
|
public static final String PREFIX = "flickr";
|
||||||
|
|
||||||
|
public static final QName TYPE_DELIVERY_CHANNEL = QName.createQName(NAMESPACE, "DeliveryChannel");
|
||||||
|
|
||||||
|
public static final QName ASPECT_ASSET = QName.createQName(NAMESPACE, "AssetAspect");
|
||||||
|
public static final QName PROP_ASSET_ID = QName.createQName(NAMESPACE, "assetId");
|
||||||
|
public static final QName PROP_ASSET_URL = QName.createQName(NAMESPACE, "assetUrl");
|
||||||
|
}
|
158
source/java/org/alfresco/repo/publishing/flickr/FlickrTest.java
Normal file
158
source/java/org/alfresco/repo/publishing/flickr/FlickrTest.java
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.alfresco.repo.publishing.flickr;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.repo.publishing.EnvironmentImpl;
|
||||||
|
import org.alfresco.repo.publishing.PublishingModel;
|
||||||
|
import org.alfresco.repo.publishing.PublishingQueueImpl;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||||
|
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||||
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.action.Action;
|
||||||
|
import org.alfresco.service.cmr.action.ActionService;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.publishing.channels.Channel;
|
||||||
|
import org.alfresco.service.cmr.publishing.channels.ChannelService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.site.SiteService;
|
||||||
|
import org.alfresco.service.cmr.site.SiteVisibility;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.BaseSpringTest;
|
||||||
|
import org.alfresco.util.GUID;
|
||||||
|
import org.apache.commons.fileupload.MultipartStream;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Brian
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FlickrTest extends BaseSpringTest
|
||||||
|
{
|
||||||
|
protected ServiceRegistry serviceRegistry;
|
||||||
|
protected SiteService siteService;
|
||||||
|
protected FileFolderService fileFolderService;
|
||||||
|
protected NodeService nodeService;
|
||||||
|
protected String siteId;
|
||||||
|
protected PublishingQueueImpl queue;
|
||||||
|
protected EnvironmentImpl environment;
|
||||||
|
protected NodeRef docLib;
|
||||||
|
|
||||||
|
private ChannelService channelService;
|
||||||
|
|
||||||
|
private RetryingTransactionHelper transactionHelper;
|
||||||
|
|
||||||
|
public void onSetUp() throws Exception
|
||||||
|
{
|
||||||
|
serviceRegistry = (ServiceRegistry) getApplicationContext().getBean("ServiceRegistry");
|
||||||
|
channelService = (ChannelService) getApplicationContext().getBean("channelService");
|
||||||
|
AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName());
|
||||||
|
siteService = serviceRegistry.getSiteService();
|
||||||
|
fileFolderService = serviceRegistry.getFileFolderService();
|
||||||
|
nodeService = serviceRegistry.getNodeService();
|
||||||
|
transactionHelper = serviceRegistry.getRetryingTransactionHelper();
|
||||||
|
|
||||||
|
siteId = GUID.generate();
|
||||||
|
siteService.createSite("test", siteId, "Site created by publishing test", "Site created by publishing test",
|
||||||
|
SiteVisibility.PUBLIC);
|
||||||
|
docLib = siteService.createContainer(siteId, SiteService.DOCUMENT_LIBRARY, ContentModel.TYPE_FOLDER, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTearDown()
|
||||||
|
{
|
||||||
|
siteService.deleteSite(siteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testBlank()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//Note that this test isn't normally run, as it requires a valid Flickr OAuth token.
|
||||||
|
//To run it, remove the initial 'x' from the method name and set the appropriate values where the
|
||||||
|
//text "YOUR_OAUTH_TOKEN_VALUE" and "YOUR_OAUTH_TOKEN_SECRET" appear. Note that these can be quite tricky to obtain...
|
||||||
|
public void xtestFlickrPublishAndUnpublishActions() throws Exception
|
||||||
|
{
|
||||||
|
final NodeRef contentNode = transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
||||||
|
{
|
||||||
|
public NodeRef execute() throws Throwable
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
|
||||||
|
props.put(PublishingModel.PROP_OAUTH1_TOKEN_VALUE, "YOUR_OAUTH_TOKEN_VALUE");
|
||||||
|
props.put(PublishingModel.PROP_OAUTH1_TOKEN_SECRET, "YOUR_OAUTH_TOKEN_SECRET");
|
||||||
|
props.put(PublishingModel.PROP_AUTHORISATION_COMPLETE, Boolean.TRUE);
|
||||||
|
|
||||||
|
Channel channel = channelService.createChannel(siteId, FlickrChannelType.ID, "FlickrTestChannel", props);
|
||||||
|
//This looks a little odd, but a new channel always has its "authorisation complete" flag
|
||||||
|
//forced off initially. This will force it on for this channel...
|
||||||
|
channelService.updateChannel(channel, props);
|
||||||
|
|
||||||
|
NodeRef channelNode = channel.getNodeRef();
|
||||||
|
Resource file = new ClassPathResource("test/alfresco/TestImageFile.png");
|
||||||
|
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||||
|
contentProps.put(ContentModel.PROP_NAME, "Test Image");
|
||||||
|
NodeRef contentNode = nodeService.createNode(channelNode, ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "testImage"),
|
||||||
|
ContentModel.TYPE_CONTENT, contentProps).getChildRef();
|
||||||
|
ContentService contentService = serviceRegistry.getContentService();
|
||||||
|
ContentWriter writer = contentService.getWriter(contentNode, ContentModel.PROP_CONTENT, true);
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_IMAGE_PNG);
|
||||||
|
writer.putContent(file.getFile());
|
||||||
|
return contentNode;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
MultipartStream stream = new MultipartStream(null, null);
|
||||||
|
transactionHelper.doInTransaction(new RetryingTransactionCallback<NodeRef>()
|
||||||
|
{
|
||||||
|
public NodeRef execute() throws Throwable
|
||||||
|
{
|
||||||
|
ActionService actionService = serviceRegistry.getActionService();
|
||||||
|
Action publishAction = actionService.createAction(FlickrPublishAction.NAME);
|
||||||
|
actionService.executeAction(publishAction, contentNode);
|
||||||
|
Map<QName, Serializable> props = nodeService.getProperties(contentNode);
|
||||||
|
Assert.assertTrue(nodeService.hasAspect(contentNode, FlickrPublishingModel.ASPECT_ASSET));
|
||||||
|
Assert.assertNotNull(props.get(FlickrPublishingModel.PROP_ASSET_ID));
|
||||||
|
|
||||||
|
System.out.println("Asset id: " + props.get(FlickrPublishingModel.PROP_ASSET_ID));
|
||||||
|
|
||||||
|
// Action unpublishAction = actionService.createAction(YouTubeUnpublishAction.NAME);
|
||||||
|
// actionService.executeAction(unpublishAction, contentNode);
|
||||||
|
// props = nodeService.getProperties(contentNode);
|
||||||
|
// Assert.assertFalse(nodeService.hasAspect(contentNode, YouTubePublishingModel.ASPECT_ASSET));
|
||||||
|
// Assert.assertNull(props.get(YouTubePublishingModel.PROP_ASSET_ID));
|
||||||
|
// Assert.assertNull(props.get(YouTubePublishingModel.PROP_PLAYER_URL));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.MediaOperations;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.impl.FlickrTemplate;
|
||||||
|
import org.springframework.social.ApiBinding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface specifying a basic set of operations for interacting with Facebook.
|
||||||
|
* Implemented by {@link FlickrTemplate}.
|
||||||
|
*
|
||||||
|
* @author Craig Walls
|
||||||
|
*/
|
||||||
|
public interface Flickr extends ApiBinding
|
||||||
|
{
|
||||||
|
boolean test();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API for performing operations on albums, photos, and videos.
|
||||||
|
*/
|
||||||
|
MediaOperations mediaOperations();
|
||||||
|
}
|
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api;
|
||||||
|
|
||||||
|
import org.springframework.social.facebook.api.ImageType;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.client.ResponseExtractor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines low-level operations against Facebook's Graph API
|
||||||
|
* @author Craig Walls
|
||||||
|
*/
|
||||||
|
public interface GraphApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an object, extracting it into the type via the given {@link ResponseExtractor}.
|
||||||
|
* Requires appropriate permission to fetch the object.
|
||||||
|
* @param objectId the Facebook object's ID
|
||||||
|
* @param type the Java type to fetch
|
||||||
|
* @return an Java object representing the requested Facebook object.
|
||||||
|
*/
|
||||||
|
<T> T fetchObject(String objectId, Class<T> type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an object, extracting it into the type via the given {@link ResponseExtractor}.
|
||||||
|
* Requires appropriate permission to fetch the object.
|
||||||
|
* @param objectId the Facebook object's ID
|
||||||
|
* @param type the Java type to fetch
|
||||||
|
* @param queryParameters query parameters to include in the request
|
||||||
|
* @return an Java object representing the requested Facebook object.
|
||||||
|
*/
|
||||||
|
<T> T fetchObject(String objectId, Class<T> type, MultiValueMap<String, String> queryParameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches connections, extracting them into a Java type via the given {@link ResponseExtractor}.
|
||||||
|
* Requires appropriate permission to fetch the object connection.
|
||||||
|
* @param objectId the ID of the object to retrieve the connections for.
|
||||||
|
* @param connectionType the connection type.
|
||||||
|
* @param type the Java type to fetch
|
||||||
|
* @param fields the fields to include in the response.
|
||||||
|
* @return a list of Java objects representing the Facebook objects in the connections.
|
||||||
|
*/
|
||||||
|
<T> T fetchConnections(String objectId, String connectionType, Class<T> type, String... fields);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches connections, extracting them into a Java type via the given {@link ResponseExtractor}.
|
||||||
|
* Requires appropriate permission to fetch the object connection.
|
||||||
|
* @param objectId the ID of the object to retrieve the connections for.
|
||||||
|
* @param connectionType the connection type.
|
||||||
|
* @param type the Java type to fetch
|
||||||
|
* @param queryParameters query parameters to include in the request
|
||||||
|
* @return a list of Java objects representing the Facebook objects in the connections.
|
||||||
|
*/
|
||||||
|
<T> T fetchConnections(String objectId, String connectionType, Class<T> type, MultiValueMap<String, String> queryParameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an image as an array of bytes.
|
||||||
|
* @param objectId the object ID
|
||||||
|
* @param connectionType the connection type
|
||||||
|
* @param imageType the type of image to retrieve (eg., small, normal, large, or square)
|
||||||
|
* @return an image as an array of bytes.
|
||||||
|
*/
|
||||||
|
byte[] fetchImage(String objectId, String connectionType, ImageType imageType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publishes data to an object's connection.
|
||||||
|
* Requires appropriate permission to publish to the object connection.
|
||||||
|
* @param objectId the object ID to publish to.
|
||||||
|
* @param connectionType the connection type to publish to.
|
||||||
|
* @param data the data to publish to the connection.
|
||||||
|
* @return the ID of the newly published object.
|
||||||
|
*/
|
||||||
|
String publish(String objectId, String connectionType, MultiValueMap<String, Object> data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publishes data to an object's connection.
|
||||||
|
* Requires appropriate permission to publish to the object connection.
|
||||||
|
* This differs from publish() only in that it doesn't attempt to extract the ID from the response.
|
||||||
|
* This is because some publish operations do not return an ID in the response.
|
||||||
|
* @param objectId the object ID to publish to.
|
||||||
|
* @param connectionType the connection type to publish to.
|
||||||
|
* @param data the data to publish to the connection.
|
||||||
|
*/
|
||||||
|
void post(String objectId, String connectionType, MultiValueMap<String, String> data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an object.
|
||||||
|
* Requires appropriate permission to delete the object.
|
||||||
|
* @param objectId the object ID
|
||||||
|
*/
|
||||||
|
void delete(String objectId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes an object connection.
|
||||||
|
* Requires appropriate permission to delete the object connection.
|
||||||
|
* @param objectId the object ID
|
||||||
|
* @param connectionType the connection type
|
||||||
|
*/
|
||||||
|
void delete(String objectId, String connectionType);
|
||||||
|
|
||||||
|
static final String GRAPH_API_URL = "https://graph.facebook.com/";
|
||||||
|
|
||||||
|
static final String OBJECT_URL = GRAPH_API_URL + "{objectId}";
|
||||||
|
|
||||||
|
static final String CONNECTION_URL = OBJECT_URL + "/{connection}";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api;
|
||||||
|
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.FileSystemResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.social.ApiException;
|
||||||
|
import org.springframework.social.InsufficientPermissionException;
|
||||||
|
import org.springframework.social.MissingAuthorizationException;
|
||||||
|
|
||||||
|
|
||||||
|
public interface MediaOperations {
|
||||||
|
|
||||||
|
PhotoMetadata createPhotoMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a photo to an album created specifically for the application.
|
||||||
|
* Requires "publish_stream" permission.
|
||||||
|
* If no album exists for the application, it will be created.
|
||||||
|
* @param photo A {@link Resource} for the photo data. The given Resource must implement the getFilename() method (such as {@link FileSystemResource} or {@link ClassPathResource}).
|
||||||
|
* @return the ID of the photo.
|
||||||
|
* @throws ApiException if there is an error while communicating with Facebook.
|
||||||
|
* @throws InsufficientPermissionException if the user has not granted "publish_stream" permission.
|
||||||
|
* @throws MissingAuthorizationException if FacebookTemplate was not created with an access token.
|
||||||
|
*/
|
||||||
|
String postPhoto(Resource photo, PhotoMetadata metadata);
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api;
|
||||||
|
|
||||||
|
public interface PhotoMetadata
|
||||||
|
{
|
||||||
|
|
||||||
|
void setDescription(String description);
|
||||||
|
|
||||||
|
void setTitle(String title);
|
||||||
|
|
||||||
|
String getDescription();
|
||||||
|
|
||||||
|
String getTitle();
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public interface UserOperations {
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api.impl;
|
||||||
|
|
||||||
|
import org.springframework.social.MissingAuthorizationException;
|
||||||
|
|
||||||
|
class AbstractFlickrOperations {
|
||||||
|
|
||||||
|
private final boolean isAuthorized;
|
||||||
|
|
||||||
|
public AbstractFlickrOperations(boolean isAuthorized) {
|
||||||
|
this.isAuthorized = isAuthorized;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void requireAuthorization() {
|
||||||
|
if (!isAuthorized) {
|
||||||
|
throw new MissingAuthorizationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api.impl;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.client.ClientHttpResponse;
|
||||||
|
import org.springframework.social.ExpiredAuthorizationException;
|
||||||
|
import org.springframework.social.InsufficientPermissionException;
|
||||||
|
import org.springframework.social.InternalServerErrorException;
|
||||||
|
import org.springframework.social.InvalidAuthorizationException;
|
||||||
|
import org.springframework.social.MissingAuthorizationException;
|
||||||
|
import org.springframework.social.NotAuthorizedException;
|
||||||
|
import org.springframework.social.OperationNotPermittedException;
|
||||||
|
import org.springframework.social.ResourceNotFoundException;
|
||||||
|
import org.springframework.social.RevokedAuthorizationException;
|
||||||
|
import org.springframework.social.UncategorizedApiException;
|
||||||
|
import org.springframework.social.facebook.api.NotAFriendException;
|
||||||
|
import org.springframework.social.facebook.api.ResourceOwnershipException;
|
||||||
|
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclass of {@link DefaultResponseErrorHandler} that handles errors from Facebook's
|
||||||
|
* Graph API, interpreting them into appropriate exceptions.
|
||||||
|
* @author Craig Walls
|
||||||
|
*/
|
||||||
|
class FlickrErrorHandler extends DefaultResponseErrorHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleError(ClientHttpResponse response) throws IOException {
|
||||||
|
Map<String, String> errorDetails = extractErrorDetailsFromResponse(response);
|
||||||
|
if (errorDetails == null) {
|
||||||
|
handleUncategorizedError(response, errorDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleFacebookError(response.getStatusCode(), errorDetails);
|
||||||
|
|
||||||
|
// if not otherwise handled, do default handling and wrap with UncategorizedApiException
|
||||||
|
handleUncategorizedError(response, errorDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasError(ClientHttpResponse response) throws IOException {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody()));
|
||||||
|
return super.hasError(response) || (reader.ready() && reader.readLine().startsWith("{\"error\":"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Examines the error data returned from Facebook and throws the most applicable exception.
|
||||||
|
* @param errorDetails a Map containing a "type" and a "message" corresponding to the Graph API's error response structure.
|
||||||
|
*/
|
||||||
|
void handleFacebookError(HttpStatus statusCode, Map<String, String> errorDetails) {
|
||||||
|
// Can't trust the type to be useful. It's often OAuthException, even for things not OAuth-related.
|
||||||
|
// Can rely only on the message (which itself isn't very consistent).
|
||||||
|
String message = errorDetails.get("message");
|
||||||
|
|
||||||
|
if (statusCode == HttpStatus.OK) {
|
||||||
|
if (message.contains("Some of the aliases you requested do not exist")) {
|
||||||
|
throw new ResourceNotFoundException(message);
|
||||||
|
}
|
||||||
|
} else if (statusCode == HttpStatus.BAD_REQUEST) {
|
||||||
|
if (message.contains("Unknown path components")) {
|
||||||
|
throw new ResourceNotFoundException(message);
|
||||||
|
} else if (message.equals("An access token is required to request this resource.")) {
|
||||||
|
throw new MissingAuthorizationException();
|
||||||
|
} else if (message.equals("An active access token must be used to query information about the current user.")) {
|
||||||
|
throw new MissingAuthorizationException();
|
||||||
|
} else if (message.startsWith("Error validating access token")) {
|
||||||
|
if (message.contains("Session has expired at unix time")) {
|
||||||
|
throw new ExpiredAuthorizationException();
|
||||||
|
} else if (message.contains("The session has been invalidated because the user has changed the password.")) {
|
||||||
|
throw new RevokedAuthorizationException();
|
||||||
|
} else if (message.contains("The session is invalid because the user logged out.")) {
|
||||||
|
throw new RevokedAuthorizationException();
|
||||||
|
} else if (message.contains("has not authorized application")) {
|
||||||
|
// Per https://developers.facebook.com/blog/post/500/, this could be in the message when the user removes the application.
|
||||||
|
// In reality, "The session has been invalidated because the user has changed the password." is what you get in that case.
|
||||||
|
// Leaving this check in place in case there FB does return this message (could be a bug in FB?)
|
||||||
|
throw new RevokedAuthorizationException();
|
||||||
|
} else {
|
||||||
|
throw new InvalidAuthorizationException(message);
|
||||||
|
}
|
||||||
|
} else if (message.equals("Error validating application.")) { // Access token with incorrect app ID
|
||||||
|
throw new InvalidAuthorizationException(message);
|
||||||
|
} else if (message.equals("Invalid access token signature.")) { // Access token that fails signature validation
|
||||||
|
throw new InvalidAuthorizationException(message);
|
||||||
|
}
|
||||||
|
} else if (statusCode == HttpStatus.UNAUTHORIZED) {
|
||||||
|
throw new NotAuthorizedException(message);
|
||||||
|
} else if (statusCode == HttpStatus.FORBIDDEN) {
|
||||||
|
if (message.contains("Requires extended permission")) {
|
||||||
|
String requiredPermission = message.split(": ")[1];
|
||||||
|
throw new InsufficientPermissionException(requiredPermission);
|
||||||
|
} else {
|
||||||
|
throw new OperationNotPermittedException(message);
|
||||||
|
}
|
||||||
|
} else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR) {
|
||||||
|
if (message.equals("User must be an owner of the friendlist")) { // watch for pattern in similar message in other resources
|
||||||
|
throw new ResourceOwnershipException(message);
|
||||||
|
} else if (message.equals("The member must be a friend of the current user.")) {
|
||||||
|
throw new NotAFriendException(message);
|
||||||
|
} else {
|
||||||
|
throw new InternalServerErrorException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleUncategorizedError(ClientHttpResponse response, Map<String, String> errorDetails) {
|
||||||
|
try {
|
||||||
|
super.handleError(response);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (errorDetails != null) {
|
||||||
|
throw new UncategorizedApiException(errorDetails.get("message"), e);
|
||||||
|
} else {
|
||||||
|
throw new UncategorizedApiException("No error details from Facebook", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attempts to extract Facebook error details from the response.
|
||||||
|
* Returns null if the response doesn't match the expected JSON error response.
|
||||||
|
*/
|
||||||
|
private Map<String, String> extractErrorDetailsFromResponse(ClientHttpResponse response) throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api.impl;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.Flickr;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.MediaOperations;
|
||||||
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
|
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.social.NotAuthorizedException;
|
||||||
|
import org.springframework.social.oauth1.AbstractOAuth1ApiBinding;
|
||||||
|
import org.springframework.social.support.ClientHttpRequestFactorySelector;
|
||||||
|
import org.springframework.social.support.URIBuilder;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>This is the central class for interacting with Facebook.</p>
|
||||||
|
* <p>
|
||||||
|
* There are some operations, such as searching, that do not require OAuth
|
||||||
|
* authentication. In those cases, you may use a {@link FlickrTemplate} that is
|
||||||
|
* created through the default constructor and without any OAuth details.
|
||||||
|
* Attempts to perform secured operations through such an instance, however,
|
||||||
|
* will result in {@link NotAuthorizedException} being thrown.
|
||||||
|
* </p>
|
||||||
|
* @author Craig Walls
|
||||||
|
*/
|
||||||
|
public class FlickrTemplate extends AbstractOAuth1ApiBinding implements Flickr {
|
||||||
|
private final String REST_ENDPOINT = "http://api.flickr.com/services/rest/";
|
||||||
|
private String consumerKey;
|
||||||
|
|
||||||
|
private MediaOperations mediaOperations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of FacebookTemplate.
|
||||||
|
* This constructor creates a new FacebookTemplate able to perform unauthenticated operations against Facebook's Graph API.
|
||||||
|
* Some operations do not require OAuth authentication.
|
||||||
|
* For example, retrieving a specified user's profile or feed does not require authentication (although the data returned will be limited to what is publicly available).
|
||||||
|
* A FacebookTemplate created with this constructor will support those operations.
|
||||||
|
* Those operations requiring authentication will throw {@link NotAuthorizedException}.
|
||||||
|
*/
|
||||||
|
public FlickrTemplate() {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of FacebookTemplate.
|
||||||
|
* This constructor creates the FacebookTemplate using a given access token.
|
||||||
|
* @param accessToken An access token given by Facebook after a successful OAuth 2 authentication (or through Facebook's JS library).
|
||||||
|
*/
|
||||||
|
public FlickrTemplate(String consumerKey, String consumerSecret, String accessToken, String accessTokenSecret) {
|
||||||
|
super(consumerKey, consumerSecret, accessToken, accessTokenSecret);
|
||||||
|
this.consumerKey = consumerKey;
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSubApis() {
|
||||||
|
mediaOperations = new MediaTemplate(consumerKey, getRestTemplate(), isAuthorized());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRequestFactory(ClientHttpRequestFactory requestFactory) {
|
||||||
|
// Wrap the request factory with a BufferingClientHttpRequestFactory so that the error handler can do repeat reads on the response.getBody()
|
||||||
|
super.setRequestFactory(ClientHttpRequestFactorySelector.bufferRequests(requestFactory));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaOperations mediaOperations() {
|
||||||
|
return mediaOperations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<HttpMessageConverter<?>> getMessageConverters() {
|
||||||
|
List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
|
||||||
|
messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||||
|
return messageConverters;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private helpers
|
||||||
|
private void initialize() {
|
||||||
|
getRestTemplate().setErrorHandler(new FlickrErrorHandler());
|
||||||
|
// Wrap the request factory with a BufferingClientHttpRequestFactory so that the error handler can do repeat reads on the response.getBody()
|
||||||
|
super.setRequestFactory(ClientHttpRequestFactorySelector.bufferRequests(getRestTemplate().getRequestFactory()));
|
||||||
|
initSubApis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test()
|
||||||
|
{
|
||||||
|
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
|
||||||
|
params.add("api_key", consumerKey);
|
||||||
|
params.add("format", "json");
|
||||||
|
params.add("method", "flickr.test.login");
|
||||||
|
params.add("nojsoncallback", "1");
|
||||||
|
URI uri = URIBuilder.fromUri(REST_ENDPOINT).queryParams(params).build();
|
||||||
|
getRestTemplate().getForObject(uri, String.class);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api.impl;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.MediaOperations;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.PhotoMetadata;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.impl.AbstractFlickrOperations;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.social.support.URIBuilder;
|
||||||
|
import org.springframework.util.LinkedMultiValueMap;
|
||||||
|
import org.springframework.util.MultiValueMap;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
class MediaTemplate extends AbstractFlickrOperations implements MediaOperations
|
||||||
|
{
|
||||||
|
private final RestTemplate restTemplate;
|
||||||
|
private String consumerKey;
|
||||||
|
|
||||||
|
public MediaTemplate(String consumerKey, RestTemplate restTemplate, boolean isAuthorizedForUser)
|
||||||
|
{
|
||||||
|
super(isAuthorizedForUser);
|
||||||
|
this.restTemplate = restTemplate;
|
||||||
|
this.consumerKey = consumerKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String postPhoto(Resource photo, PhotoMetadata metadata)
|
||||||
|
{
|
||||||
|
requireAuthorization();
|
||||||
|
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
|
||||||
|
parts.set("api_key", consumerKey);
|
||||||
|
if (metadata.getDescription() != null)
|
||||||
|
parts.set("description", metadata.getDescription());
|
||||||
|
parts.set("photo", photo);
|
||||||
|
if (metadata.getTitle() != null)
|
||||||
|
parts.set("title", metadata.getTitle());
|
||||||
|
URI uri = URIBuilder.fromUri("http://api.flickr.com/services/upload/").build();
|
||||||
|
String response = restTemplate.postForObject(uri, parts, String.class);
|
||||||
|
return (String) response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PhotoMetadata createPhotoMetadata()
|
||||||
|
{
|
||||||
|
return new PhotoMetadataImpl();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,29 @@
|
|||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api.impl;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.PhotoMetadata;
|
||||||
|
|
||||||
|
public class PhotoMetadataImpl implements PhotoMetadata
|
||||||
|
{
|
||||||
|
private String title;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public String getTitle()
|
||||||
|
{
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title)
|
||||||
|
{
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription()
|
||||||
|
{
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description)
|
||||||
|
{
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.api.impl;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.UserOperations;
|
||||||
|
|
||||||
|
class UserTemplate extends AbstractFlickrOperations implements UserOperations {
|
||||||
|
|
||||||
|
public UserTemplate(boolean isAuthorized)
|
||||||
|
{
|
||||||
|
super(isAuthorized);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.connect;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.Flickr;
|
||||||
|
import org.springframework.social.ApiException;
|
||||||
|
import org.springframework.social.connect.ApiAdapter;
|
||||||
|
import org.springframework.social.connect.ConnectionValues;
|
||||||
|
import org.springframework.social.connect.UserProfile;
|
||||||
|
import org.springframework.social.connect.UserProfileBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Facebook ApiAdapter implementation.
|
||||||
|
*
|
||||||
|
* @author Keith Donald
|
||||||
|
*/
|
||||||
|
public class FlickrAdapter implements ApiAdapter<Flickr>
|
||||||
|
{
|
||||||
|
|
||||||
|
public boolean test(Flickr flickr)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
flickr.test();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (ApiException e)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConnectionValues(Flickr facebook, ConnectionValues values)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserProfile fetchUserProfile(Flickr facebook)
|
||||||
|
{
|
||||||
|
return new UserProfileBuilder().setName("Brian").setFirstName("Brian").setLastName(
|
||||||
|
"Brian").setEmail("Brian").setUsername("Brian").build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateStatus(Flickr facebook, String message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.connect;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.Flickr;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.connect.FlickrAdapter;
|
||||||
|
import org.springframework.social.connect.support.OAuth1ConnectionFactory;
|
||||||
|
|
||||||
|
public class FlickrConnectionFactory extends OAuth1ConnectionFactory<Flickr> {
|
||||||
|
|
||||||
|
public FlickrConnectionFactory(String consumerKey, String consumerSecret) {
|
||||||
|
super("flickr", new FlickrServiceProvider(consumerKey, consumerSecret), new FlickrAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.connect;
|
||||||
|
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.Flickr;
|
||||||
|
import org.alfresco.repo.publishing.flickr.springsocial.api.impl.FlickrTemplate;
|
||||||
|
import org.springframework.social.oauth1.AbstractOAuth1ServiceProvider;
|
||||||
|
import org.springframework.social.oauth1.OAuth1Template;
|
||||||
|
|
||||||
|
public class FlickrServiceProvider extends AbstractOAuth1ServiceProvider<Flickr> {
|
||||||
|
|
||||||
|
public FlickrServiceProvider(String consumerKey, String consumerSecret) {
|
||||||
|
super(consumerKey, consumerSecret, new OAuth1Template(consumerKey, consumerSecret,
|
||||||
|
"http://www.flickr.com/services/oauth/request_token",
|
||||||
|
"http://www.flickr.com/services/oauth/authorize",
|
||||||
|
"http://www.flickr.com/services/oauth/access_token"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Flickr getApi(String accessToken, String secret) {
|
||||||
|
return new FlickrTemplate(getConsumerKey(), getConsumerSecret(), accessToken, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* Flickr service provider connection repository and API adapter implementations.
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.publishing.flickr.springsocial.connect;
|
@@ -22,9 +22,7 @@ import java.io.Serializable;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
import org.alfresco.repo.content.MimetypeMap;
|
|
||||||
import org.alfresco.repo.publishing.AbstractChannelType;
|
import org.alfresco.repo.publishing.AbstractChannelType;
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
import org.alfresco.service.cmr.action.ActionService;
|
import org.alfresco.service.cmr.action.ActionService;
|
||||||
@@ -36,28 +34,11 @@ import org.alfresco.service.namespace.QName;
|
|||||||
public class SlideShareChannelType extends AbstractChannelType
|
public class SlideShareChannelType extends AbstractChannelType
|
||||||
{
|
{
|
||||||
public final static String ID = "slideshare";
|
public final static String ID = "slideshare";
|
||||||
private final static Set<String> DEFAULT_MIME_TYPES = new TreeSet<String>();
|
|
||||||
|
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private ActionService actionService;
|
private ActionService actionService;
|
||||||
private Set<String> permittedMimeTypes = Collections.unmodifiableSet(DEFAULT_MIME_TYPES);
|
private SlideSharePublishingHelper publishingHelper;
|
||||||
|
|
||||||
static
|
|
||||||
{
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_PPT);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_PDF);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_OPENDOCUMENT_PRESENTATION);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_OPENXML_PRESENTATION);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_IWORK_KEYNOTE);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_IWORK_PAGES);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_TEXT_PLAIN);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_OPENDOCUMENT_TEXT);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_TEXT_CSV);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_EXCEL);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_OPENXML_WORDPROCESSING);
|
|
||||||
DEFAULT_MIME_TYPES.add(MimetypeMap.MIMETYPE_OPENDOCUMENT_SPREADSHEET);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setNodeService(NodeService nodeService)
|
public void setNodeService(NodeService nodeService)
|
||||||
{
|
{
|
||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
@@ -68,13 +49,9 @@ public class SlideShareChannelType extends AbstractChannelType
|
|||||||
this.actionService = actionService;
|
this.actionService = actionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPermittedMimeTypes(Set<String> permittedMimeTypes)
|
public void setPublishingHelper(SlideSharePublishingHelper publishingHelper)
|
||||||
{
|
{
|
||||||
if (permittedMimeTypes == null)
|
this.publishingHelper = publishingHelper;
|
||||||
{
|
|
||||||
permittedMimeTypes = Collections.emptySet();
|
|
||||||
}
|
|
||||||
this.permittedMimeTypes = Collections.unmodifiableSet(permittedMimeTypes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -116,7 +93,7 @@ public class SlideShareChannelType extends AbstractChannelType
|
|||||||
@Override
|
@Override
|
||||||
public Set<String> getSupportedMimetypes()
|
public Set<String> getSupportedMimetypes()
|
||||||
{
|
{
|
||||||
return permittedMimeTypes;
|
return publishingHelper.getAllowedMimeTypes().keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -24,7 +24,6 @@ import java.util.List;
|
|||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
|
||||||
import org.alfresco.repo.content.filestore.FileContentReader;
|
|
||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
@@ -38,6 +37,7 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import com.benfante.jslideshare.SlideShareAPI;
|
import com.benfante.jslideshare.SlideShareAPI;
|
||||||
|
import com.benfante.jslideshare.messages.Slideshow;
|
||||||
|
|
||||||
public class SlideSharePublishAction extends ActionExecuterAbstractBase
|
public class SlideSharePublishAction extends ActionExecuterAbstractBase
|
||||||
{
|
{
|
||||||
@@ -84,20 +84,19 @@ public class SlideSharePublishAction extends ActionExecuterAbstractBase
|
|||||||
if (reader.exists())
|
if (reader.exists())
|
||||||
{
|
{
|
||||||
File contentFile;
|
File contentFile;
|
||||||
|
String mime = reader.getMimetype();
|
||||||
|
|
||||||
|
String extension = slideShareHelper.getAllowedMimeTypes().get(mime);
|
||||||
|
if (extension == null) extension = "";
|
||||||
|
|
||||||
boolean deleteContentFileOnCompletion = false;
|
boolean deleteContentFileOnCompletion = false;
|
||||||
if (FileContentReader.class.isAssignableFrom(reader.getClass()))
|
|
||||||
{
|
//SlideShare seems to work entirely off file extension, so we always copy onto the
|
||||||
//Grab the content straight from the content store if we can...
|
//file system and upload from there.
|
||||||
contentFile = ((FileContentReader)reader).getFile();
|
File tempDir = TempFileProvider.getLongLifeTempDir("slideshare");
|
||||||
}
|
contentFile = TempFileProvider.createTempFile("slideshare", extension, tempDir);
|
||||||
else
|
reader.getContent(contentFile);
|
||||||
{
|
deleteContentFileOnCompletion = true;
|
||||||
//...otherwise copy it to a temp file and use the copy...
|
|
||||||
File tempDir = TempFileProvider.getLongLifeTempDir("slideshare");
|
|
||||||
contentFile = TempFileProvider.createTempFile("slideshare", "", tempDir);
|
|
||||||
reader.getContent(contentFile);
|
|
||||||
deleteContentFileOnCompletion = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||||
String title = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
|
String title = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_TITLE);
|
||||||
@@ -121,8 +120,17 @@ public class SlideSharePublishAction extends ActionExecuterAbstractBase
|
|||||||
|
|
||||||
String assetId = api.uploadSlideshow(usernamePassword.getFirst(), usernamePassword.getSecond(), title,
|
String assetId = api.uploadSlideshow(usernamePassword.getFirst(), usernamePassword.getSecond(), title,
|
||||||
contentFile, description, tags.toString(), false, false, false, false, false);
|
contentFile, description, tags.toString(), false, false, false, false, false);
|
||||||
// String url = api.getSlideshow(assetId).getPermalink();
|
|
||||||
String url = null;
|
String url = null;
|
||||||
|
Slideshow slides = api.getSlideshow(assetId);
|
||||||
|
if (slides != null)
|
||||||
|
{
|
||||||
|
url = slides.getPermalink();
|
||||||
|
if (log.isInfoEnabled())
|
||||||
|
{
|
||||||
|
log.info("SlideShare has provided a URL for asset " + assetId + ": " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (log.isInfoEnabled())
|
if (log.isInfoEnabled())
|
||||||
{
|
{
|
||||||
log.info("File " + name + " has been published to SlideShare with id " + assetId + " at URL " + url);
|
log.info("File " + name + " has been published to SlideShare with id " + assetId + " at URL " + url);
|
||||||
|
@@ -18,6 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.publishing.slideshare;
|
package org.alfresco.repo.publishing.slideshare;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.publishing.PublishingModel;
|
import org.alfresco.repo.publishing.PublishingModel;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
@@ -28,6 +33,24 @@ import com.benfante.jslideshare.SlideShareConnector;
|
|||||||
|
|
||||||
public class SlideSharePublishingHelper
|
public class SlideSharePublishingHelper
|
||||||
{
|
{
|
||||||
|
private final static Map<String,String> DEFAULT_MIME_TYPES = new TreeMap<String,String>();
|
||||||
|
static
|
||||||
|
{
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_PPT, ".ppt");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_PDF, ".pdf");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_OPENDOCUMENT_PRESENTATION, ".odp");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_OPENXML_PRESENTATION, ".pptx");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_IWORK_KEYNOTE, "");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_IWORK_PAGES, "");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_TEXT_PLAIN, ".txt");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_OPENDOCUMENT_TEXT, ".odt");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_TEXT_CSV, ".csv");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_EXCEL, ".xls");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_OPENXML_WORDPROCESSING, ".docx");
|
||||||
|
DEFAULT_MIME_TYPES.put(MimetypeMap.MIMETYPE_OPENDOCUMENT_SPREADSHEET, ".ods");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> allowedMimeTypes = Collections.unmodifiableMap(DEFAULT_MIME_TYPES);
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private SlideShareConnector slideshareConnector;
|
private SlideShareConnector slideshareConnector;
|
||||||
|
|
||||||
@@ -41,6 +64,16 @@ public class SlideSharePublishingHelper
|
|||||||
this.slideshareConnector = slideshareConnector;
|
this.slideshareConnector = slideshareConnector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getAllowedMimeTypes()
|
||||||
|
{
|
||||||
|
return allowedMimeTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedMimeTypes(Map<String, String> allowedMimeTypes)
|
||||||
|
{
|
||||||
|
this.allowedMimeTypes = Collections.unmodifiableMap(allowedMimeTypes);
|
||||||
|
}
|
||||||
|
|
||||||
public SlideShareAPI getSlideShareApi()
|
public SlideShareAPI getSlideShareApi()
|
||||||
{
|
{
|
||||||
return createApiObject();
|
return createApiObject();
|
||||||
|
@@ -17,7 +17,7 @@ public class BitlyUrlShortenerImpl implements UrlShortener
|
|||||||
{
|
{
|
||||||
private static final Log log = LogFactory.getLog(BitlyUrlShortenerImpl.class);
|
private static final Log log = LogFactory.getLog(BitlyUrlShortenerImpl.class);
|
||||||
|
|
||||||
private int urlLength;
|
private int urlLength = 20;
|
||||||
private String username;
|
private String username;
|
||||||
private String apiKey = "R_ca15c6c89e9b25ccd170bafd209a0d4f";
|
private String apiKey = "R_ca15c6c89e9b25ccd170bafd209a0d4f";
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
|
@@ -64,11 +64,10 @@ public interface ChannelService
|
|||||||
Channel createChannel(String siteId, String channelTypeId, String name, Map<QName, Serializable> properties);
|
Channel createChannel(String siteId, String channelTypeId, String name, Map<QName, Serializable> properties);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the channel with the specified name on the specified Share site.
|
* Remove the specified channel.
|
||||||
* @param siteId The identifier of the Share site that contains the channel to be deleted.
|
* @param channel The channel to delete.
|
||||||
* @param channelName The name of the channel that is to be deleted.
|
|
||||||
*/
|
*/
|
||||||
void deleteChannel(String siteId, String channelName);
|
void deleteChannel(Channel channel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename the specified channel
|
* Rename the specified channel
|
||||||
|
Reference in New Issue
Block a user