package com.vaguehope.onosendai.provider.twitter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import twitter4j.Relationship;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.StatusUpdate;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.UserList;
import twitter4j.conf.ConfigurationBuilder;
import com.vaguehope.onosendai.config.Account;
import com.vaguehope.onosendai.model.Meta;
import com.vaguehope.onosendai.model.Tweet;
import com.vaguehope.onosendai.model.TweetBuilder;
import com.vaguehope.onosendai.model.TweetList;
import com.vaguehope.onosendai.util.ImageMetadata;
import com.vaguehope.onosendai.util.IoHelper;
import com.vaguehope.onosendai.util.StringHelper;
public class TwitterProvider {
private final ConcurrentMap<String, Twitter> accounts;
public TwitterProvider () {
this.accounts = new ConcurrentHashMap<String, Twitter>();
}
public void addAccount (final Account account) {
if (this.accounts.containsKey(account.getId())) return;
final TwitterFactory tf = makeTwitterFactory(account);
final Twitter t = tf.getInstance();
this.accounts.putIfAbsent(account.getId(), t);
}
private Twitter getTwitter (final Account account) {
final Twitter t = this.accounts.get(account.getId());
if (t != null) return t;
addAccount(account);
return this.accounts.get(account.getId());
}
public void shutdown () {
this.accounts.clear();
}
public TweetList getTweets (final TwitterFeed feed, final Account account, final long sinceId, final boolean hdMedia) throws TwitterException {
return getTweets(feed, account, sinceId, hdMedia, null);
}
public TweetList getTweets (final TwitterFeed feed, final Account account, final long sinceId, final boolean hdMedia, final Collection<Meta> extraMetas) throws TwitterException {
return feed.getTweets(account, getTwitter(account), sinceId, hdMedia, extraMetas);
}
public Tweet getTweet (final Account account, final long id, final boolean hdMedia) throws TwitterException {
return getTweet(account, id, hdMedia, null);
}
public Tweet getTweet (final Account account, final long id, final boolean hdMedia, final Collection<Meta> extraMetas) throws TwitterException {
final Twitter t = getTwitter(account);
return TwitterUtils.convertTweet(account, t.showStatus(id), t.getId(), hdMedia, extraMetas, null);
}
public Tweet post (final Account account, final String body, final long inReplyTo, final ImageMetadata media) throws TwitterException, IOException {
InputStream attachmentIs = null;
try {
final StatusUpdate s = new StatusUpdate(body);
if (inReplyTo > 0) s.setInReplyToStatusId(inReplyTo);
if (media != null && media.exists()) {
attachmentIs = media.open();
s.setMedia(media.getName(), attachmentIs);
}
final Status u = getTwitter(account).updateStatus(s);
return new TweetBuilder()
.id(String.valueOf(u.getId()))
// TODO fill in other fields?
.build();
}
finally {
IoHelper.closeQuietly(attachmentIs);
}
}
public void rt (final Account account, final long id) throws TwitterException {
getTwitter(account).retweetStatus(id);
}
public void fav (final Account account, final long id) throws TwitterException {
getTwitter(account).createFavorite(id);
}
public void delete (final Account account, final long id) throws TwitterException {
getTwitter(account).destroyStatus(id);
}
public List<String> getListSlugs(final Account account) throws TwitterException {
return getListSlugs(account, null);
}
public List<String> getListSlugs(final Account account, final String ownerScreenName) throws TwitterException {
final Twitter t = getTwitter(account);
final ResponseList<UserList> lists;
if (StringHelper.isEmpty(ownerScreenName)) {
lists = t.getUserLists(t.getId());
}
else {
lists = t.getUserLists(ownerScreenName);
}
final List<String> slugs = new ArrayList<String>();
for (final UserList list : lists) {
slugs.add(list.getSlug());
}
return slugs;
}
public User getUser (final Account account, final String screenName) throws TwitterException {
return getTwitter(account).showUser(screenName);
}
public Relationship getRelationship (final Account account, final User otherUser) throws TwitterException {
final Twitter t = getTwitter(account);
return t.showFriendship(t.getId(), otherUser.getId());
}
public void follow (final Account account, final User targetUser) throws TwitterException {
getTwitter(account).createFriendship(targetUser.getId());
}
public void unfollow (final Account account, final User targetUser) throws TwitterException {
getTwitter(account).destroyFriendship(targetUser.getId());
}
private static TwitterFactory makeTwitterFactory (final Account account) {
final ConfigurationBuilder cb = new ConfigurationBuilder()
.setOAuthConsumerKey(account.getConsumerKey())
.setOAuthConsumerSecret(account.getConsumerSecret())
.setOAuthAccessToken(account.getAccessToken())
.setOAuthAccessTokenSecret(account.getAccessSecret())
.setTweetModeExtended(true)
.setIncludeExtAltTextEnabled(true);
return new TwitterFactory(cb.build());
}
}