package com.vaguehope.onosendai.provider.instapaper;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import com.vaguehope.onosendai.config.Account;
import com.vaguehope.onosendai.model.Meta;
import com.vaguehope.onosendai.model.MetaType;
import com.vaguehope.onosendai.model.Tweet;
import com.vaguehope.onosendai.provider.NetworkType;
import com.vaguehope.onosendai.provider.ServiceRef;
import com.vaguehope.onosendai.provider.twitter.TwitterUrls;
import com.vaguehope.onosendai.util.HttpClientFactory;
import com.vaguehope.onosendai.util.StringHelper;
public class InstapaperProvider {
private final AtomicReference<Instapaper> clientRef;
private final HttpClientFactory httpClientFactory;
public InstapaperProvider () {
this.clientRef = new AtomicReference<Instapaper>();
this.httpClientFactory = new HttpClientFactory();
}
public void shutdown () {
this.httpClientFactory.shutdown();
}
private Instapaper getAccount (final Account account) {
final Instapaper client = this.clientRef.get();
if (client != null && client.getAccount().equals(account)) {
return client;
}
else if (client == null) {
final Instapaper instpaper = new Instapaper(account, this.httpClientFactory);
if (!this.clientRef.compareAndSet(null, instpaper)) throw new IllegalStateException("Only one instapaper account at a time is supported.");
return instpaper;
}
throw new IllegalStateException("Only one instapaper account at a time is supported.");
}
public void testAccountLogin (final Account account) throws IOException {
getAccount(account).testLogin();
}
public void add (final Account account, final Tweet tweet) throws IOException {
final Meta linkMeta = findLink(tweet);
final String linkUrl = linkMeta != null && linkMeta.hasData() ? linkMeta.getData() : null;
final String linkTitle = linkMeta != null && linkMeta.hasTitle() ? linkMeta.getTitle() : null;
final NetworkType networkType = findNetworkType(tweet);
final String title;
final String tweetUrl;
if (networkType == NetworkType.FACEBOOK) {
title = String.format("%s %s",
linkTitle != null ? linkTitle + " via" : "Post by", //ES
StringHelper.firstLine(tweet.getFullname()));
tweetUrl = facebookUrlOf(tweet);
}
else if (tweet.getSid() != null) {
title = String.format("%s %s (@%s)",
linkTitle != null ? linkTitle + " via" : "Tweet by", //ES
StringHelper.firstLine(tweet.getFullname()),
StringHelper.firstLine(tweet.getUsername()));
tweetUrl = TwitterUrls.tweet(tweet);
}
else {
title = linkUrl != null ? linkTitle : "Text saved by you"; // Leave title null so Instapaper fills it in. //ES
tweetUrl = null;
}
final String url;
final String summary;
if (linkUrl != null) {
url = linkUrl;
summary = tweet.getBody() + (tweetUrl != null ? "\n[" + tweetUrl + "]" : "");
}
else {
url = tweetUrl != null ? tweetUrl : "http://localhost/nourl/" + System.currentTimeMillis();
summary = tweet.getBody();
}
getAccount(account).add(url, title, summary);
}
private static Meta findLink (final Tweet tweet) {
final Meta meta = tweet.getFirstMetaOfType(MetaType.URL);
if (meta != null) return meta;
final Matcher m = StringHelper.URL_PATTERN.matcher(tweet.getBody());
while (m.find()) {
String g = m.group();
if (g.startsWith("(") && g.endsWith(")")) g = g.substring(1, g.length() - 1);
return new Meta(MetaType.URL, g);
}
return null;
}
private static NetworkType findNetworkType (final Tweet tweet) {
final Meta svcMeta = tweet.getFirstMetaOfType(MetaType.SERVICE);
final ServiceRef serviceRef = svcMeta != null ? ServiceRef.parseServiceMeta(svcMeta) : null;
return serviceRef != null ? serviceRef.getType() : null;
}
private static String facebookUrlOf (final Tweet tweet) {
final String tweetSid = tweet.getSid();
final int x = tweetSid.indexOf('_');
if (x > 0) {
final String userId = tweetSid.substring(0, x);
final String statusId = tweetSid.substring(x + 1);
return "https://www.facebook.com/" + userId + "/posts/" + statusId;
}
return "http://localhost/invalidfacebookpostid/uid/" + tweet.getSid();
}
}