/**
*
*/
package com.googlecode.flickr2twitter.impl.picasa;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.logging.Logger;
import com.google.api.client.googleapis.auth.authsub.AuthSubSingleUseTokenRequestUrl;
import com.google.gdata.client.photos.PicasawebService;
import com.google.gdata.data.Person;
import com.google.gdata.data.photos.AlbumFeed;
import com.google.gdata.data.photos.PhotoEntry;
import com.google.gdata.data.photos.UserFeed;
import com.googlecode.flickr2twitter.core.ServiceRunner;
import com.googlecode.flickr2twitter.datastore.MyPersistenceManagerFactory;
import com.googlecode.flickr2twitter.datastore.model.GlobalServiceConfiguration;
import com.googlecode.flickr2twitter.datastore.model.GlobalSourceApplicationService;
import com.googlecode.flickr2twitter.datastore.model.User;
import com.googlecode.flickr2twitter.datastore.model.UserSourceServiceConfig;
import com.googlecode.flickr2twitter.exceptions.TokenAlreadyRegisteredException;
import com.googlecode.flickr2twitter.impl.picasa.model.PicasaPhoto;
import com.googlecode.flickr2twitter.intf.IServiceAuthorizer;
import com.googlecode.flickr2twitter.intf.ISourceServiceProvider;
import com.googlecode.flickr2twitter.model.IPhoto;
import com.googlecode.flickr2twitter.org.apache.commons.lang3.StringUtils;
/**
* @author Toby Yu(yuyang226@gmail.com)
*
*/
public class SourceServiceProviderPicasa implements ISourceServiceProvider<IPhoto>, IServiceAuthorizer {
public static final String ID = "picasa";
public static final String DISPLAY_NAME = "Picasa Web Album";
public static final String KEY_TOKEN = "token";
private static final Logger log = Logger.getLogger(SourceServiceProviderPicasa.class.getName());
public static final String HOSTED_DOMAIN = "flickr2twitter.googlecode.com";
public static final String CONSUMER_KEY = "anonymous";
public static final String CONSUMER_SECRET = "anonymous";
public static final String USER_ID_DEFAULT = "default";
public static final String URL_PICASAWEB = "http://picasaweb.google.com/";
public static final String URL_ALBUM = "http://picasaweb.google.com/data/feed/api/user/default?kind=album";
public static final String URL_ACTIVITIES = "http://picasaweb.google.com/data/feed/api/user/default?kind=photo&max-results=25";
private static final String SCOPE = "http://picasaweb.google.com/data";
public static final String CALLBACK_URL = "picasacallback.jsp";
/**
*
*/
public SourceServiceProviderPicasa() {
super();
}
/* (non-Javadoc)
* @see com.googlecode.flickr2twitter.intf.ISourceServiceProvider#getLatestItems(com.googlecode.flickr2twitter.datastore.model.GlobalServiceConfiguration, com.googlecode.flickr2twitter.datastore.model.UserSourceServiceConfig)
*/
@Override
public List<IPhoto> getLatestItems(GlobalServiceConfiguration globalConfig,
GlobalSourceApplicationService globalSvcConfig,
UserSourceServiceConfig sourceService,
long currentTime) throws Exception {
PicasawebService webService = new PicasawebService(HOSTED_DOMAIN);
String sessionToken = sourceService.getServiceAccessToken();
webService.setAuthSubToken(sessionToken, null);
URL feedUrl = new URL(URL_ACTIVITIES);
Date pastTime = sourceService.getLastUpdateTime();
if (pastTime == null) {
Calendar past = Calendar.getInstance(TimeZone.getTimeZone(ServiceRunner.TIMEZONE_UTC));
long newTime = currentTime - globalConfig.getMinUploadTime();
past.setTimeInMillis(newTime);
pastTime = past.getTime();
}
AlbumFeed feed = webService.getFeed(feedUrl, AlbumFeed.class);
log.info("Trying to find photos uploaded for user " + sourceService.getServiceUserId()
+ " after " + pastTime.toString() + " from "
+ feed.getPhotoEntries().size() + " new photos");
List<IPhoto> photos = new ArrayList<IPhoto>();
for(PhotoEntry photo : feed.getPhotoEntries()) {
PicasaPhoto pPhoto = new PicasaPhoto(photo);
log.fine("processing photo: " + photo.getTitle().getPlainText()
+ ", date uploaded: " + pPhoto.getDatePosted());
//TODO check whether the photo is private
if (pPhoto.getDatePosted().after(pastTime)) {
log.info(photo.getTitle() + ", URL: " + pPhoto.getUrl()
+ ", date uploaded: " + pPhoto.getDatePosted()
+ ", GEO: " + pPhoto.getGeoData());
photos.add(pPhoto);
}
}
return photos;
}
/* (non-Javadoc)
* @see com.googlecode.flickr2twitter.intf.IServiceAuthorizer#readyAuthorization(java.lang.String, java.util.Map)
*/
@Override
public String readyAuthorization(String userEmail, Map<String, Object> data)
throws Exception {
if (data == null || data.containsKey(KEY_TOKEN) == false) {
throw new IllegalArgumentException("Invalid data: " + data);
}
User user = MyPersistenceManagerFactory.getUser(userEmail);
if (user == null) {
throw new IllegalArgumentException(
"Can not find the specified user: " + userEmail);
}
String token = String.valueOf(data.get("token"));
PicasawebService webService = new PicasawebService(HOSTED_DOMAIN);
webService.setAuthSubToken(token, null);
URL feedUrl = new URL(URL_ALBUM);
UserFeed myUserFeed = webService.getFeed(feedUrl, UserFeed.class);
List<Person> persons = myUserFeed.getAuthors();
Person person = null;
if (persons.isEmpty() == false) {
person = persons.get(0);
}
String userId = USER_ID_DEFAULT;
if (person.getUri() != null && person.getUri().startsWith(URL_PICASAWEB)) {
userId = StringUtils.substringAfterLast(person.getUri(), "/");
}
StringBuffer buf = new StringBuffer();
buf.append("Authentication success\n");
// This token can be used until the user revokes it.
buf.append("Token: " + token);
buf.append("\n");
buf.append("UserId: " + userId);
buf.append("\n");
buf.append("Realname: " + person.getName());
buf.append("\n");
buf.append("User Site: " + person.getUri());
for (UserSourceServiceConfig service : MyPersistenceManagerFactory
.getUserSourceServices(user)) {
if (token.equals(service.getServiceAccessToken())) {
throw new TokenAlreadyRegisteredException(token, userEmail);
}
}
UserSourceServiceConfig serviceConfig = new UserSourceServiceConfig();
serviceConfig.setServiceUserId(userId);
serviceConfig.setServiceUserName(person != null ? person.getName() : USER_ID_DEFAULT);
serviceConfig.setServiceAccessToken(token);
serviceConfig.setServiceProviderId(ID);
serviceConfig.setUserEmail(userEmail);
if (person != null) {
serviceConfig.setUserSiteUrl(person.getUri());
}
MyPersistenceManagerFactory.addSourceServiceApp(userEmail, serviceConfig);
return buf.toString();
}
/* (non-Javadoc)
* @see com.googlecode.flickr2twitter.intf.IServiceAuthorizer#requestAuthorization()
*/
@Override
public Map<String, Object> requestAuthorization(String baseUrl) throws Exception {
GlobalSourceApplicationService globalAppConfig = MyPersistenceManagerFactory
.getGlobalSourceAppService(ID);
if (globalAppConfig == null
|| ID.equalsIgnoreCase(globalAppConfig.getProviderId()) == false) {
throw new IllegalArgumentException(
"Invalid source service provider: " + globalAppConfig);
}
Map<String, Object> result = new HashMap<String, Object>();
if (baseUrl.endsWith("/oauth")) {
baseUrl = StringUtils.left(baseUrl, baseUrl.length() - "/oauth".length());
}
String nextUrl = baseUrl + "/" + CALLBACK_URL;
String scope = SCOPE;
AuthSubSingleUseTokenRequestUrl authorizeUrl = new AuthSubSingleUseTokenRequestUrl();
authorizeUrl.hostedDomain = HOSTED_DOMAIN;
authorizeUrl.nextUrl = nextUrl;
authorizeUrl.scope = scope;
authorizeUrl.session = 1;
String authorizationUrl = authorizeUrl.build();
log.info("Picasa Authorization URL: " + authorizationUrl);
result.put("url", authorizationUrl);
return result;
}
/* (non-Javadoc)
* @see com.googlecode.flickr2twitter.intf.IServiceProvider#createDefaultGlobalApplicationConfig()
*/
@Override
public GlobalSourceApplicationService createDefaultGlobalApplicationConfig() {
GlobalSourceApplicationService result = new GlobalSourceApplicationService();
result.setAppName(DISPLAY_NAME);
result.setProviderId(ID);
result.setDescription("The Google's online photo storage service");
result.setSourceAppApiKey(CONSUMER_KEY);
result.setSourceAppSecret(CONSUMER_SECRET);
result.setAuthPagePath(CALLBACK_URL);
result.setImagePath("/services/picasa/images/picasa_100.gif");
return result;
}
/* (non-Javadoc)
* @see com.googlecode.flickr2twitter.intf.IServiceProvider#getId()
*/
@Override
public String getId() {
return ID;
}
}