package com.vaguehope.onosendai.payload; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.content.Context; import com.vaguehope.onosendai.config.Account; import com.vaguehope.onosendai.config.Config; import com.vaguehope.onosendai.model.Meta; import com.vaguehope.onosendai.model.MetaType; import com.vaguehope.onosendai.model.MetaUtils; import com.vaguehope.onosendai.model.Tweet; import com.vaguehope.onosendai.provider.NetworkType; import com.vaguehope.onosendai.provider.ServiceRef; import com.vaguehope.onosendai.util.DateHelper; import com.vaguehope.onosendai.util.EqualHelper; import com.vaguehope.onosendai.util.LogWrapper; import com.vaguehope.onosendai.util.StringHelper; public final class PayloadUtils { // http://www.regular-expressions.info/unicode.html private static final Pattern HASHTAG_PATTERN = Pattern.compile( "\\B([#|\uFF03][a-z0-9_\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff\\u3040-\\u309F\\u30A0-\\u30FF]+)", Pattern.CASE_INSENSITIVE); private static final LogWrapper LOG = new LogWrapper("PU"); private PayloadUtils () { throw new AssertionError(); } public static PayloadList makePayloads (final Context context, final Config conf, final Tweet tweet) { final Account account = MetaUtils.accountFromMeta(tweet, conf); final Set<Payload> set = new LinkedHashSet<Payload>(); set.add(new PrincipalPayload(tweet)); if (account != null) convertMeta(context, account, tweet, set); replyToOwner(account, tweet, set); extractUrls(tweet, set); extractHashTags(tweet, set); if (account != null) { repliesAndExtractMentions(account, tweet, set); addShareOptions(account, tweet, set); } return new PayloadList(new ArrayList<Payload>(set)); } private static void addShareOptions (final Account account, final Tweet tweet, final Set<Payload> set) { if (account.getProvider() == null) return; switch (account.getProvider()) { case TWITTER: set.add(new SharePayload(tweet, NetworkType.TWITTER)); break; case SUCCESSWHALE: final Meta svcMeta = tweet.getFirstMetaOfType(MetaType.SERVICE); final ServiceRef serviceRef = svcMeta != null ? ServiceRef.parseServiceMeta(svcMeta) : null; final NetworkType networkType = serviceRef != null ? serviceRef.getType() : null; if (networkType == NetworkType.FACEBOOK) set.add(new AddCommentPayload(account, tweet)); set.add(new SharePayload(tweet, networkType)); break; default: set.add(new SharePayload(tweet)); break; } } private static void convertMeta (final Context context, final Account account, final Tweet tweet, final Set<Payload> ret) { final List<Meta> metas = tweet.getMetas(); if (metas == null) return; for (final Meta meta : metas) { final Payload payload = metaToPayload(context, account, tweet, meta); if (payload != null) ret.add(payload); } } private static Payload metaToPayload (final Context context, final Account account, final Tweet tweet, final Meta meta) { switch (meta.getType()) { case MEDIA: return new MediaPayload(tweet, meta); case ALT_TEXT: return new PlaceholderPayload(tweet, meta.getData()); case HASHTAG: return new HashTagPayload(tweet, meta); case MENTION: return new MentionPayload(account, tweet, meta); case URL: return new LinkPayload(tweet, meta); case EDIT_SID: return new EditPayload(tweet, meta); case DELETED: return new PlaceholderPayload(tweet, String.format("Deleted at %s.", //ES DateHelper.formatDateTime(context, TimeUnit.SECONDS.toMillis(meta.toLong(0L))))); case INREPLYTO: case SERVICE: case ACCOUNT: case FEED_HASH: case POST_TIME: case QUOTED_SID: return null; default: LOG.e("Unknown meta type: %s", meta.getType()); return null; } } private static void extractUrls (final Tweet tweet, final Set<Payload> ret) { if (payloadsContainsType(ret, PayloadType.LINK)) return; if (payloadsContainsType(ret, PayloadType.MEDIA)) return; final String text = tweet.getBody(); if (text == null || text.isEmpty()) return; final Matcher m = StringHelper.URL_PATTERN.matcher(text); while (m.find()) { String g = m.group(); if (g.startsWith("(") && g.endsWith(")")) g = g.substring(1, g.length() - 1); ret.add(new LinkPayload(tweet, g)); } } private static void extractHashTags (final Tweet tweet, final Set<Payload> set) { if (payloadsContainsType(set, PayloadType.HASHTAG)) return; final String text = tweet.getBody(); if (text == null || text.isEmpty()) return; final Matcher m = HASHTAG_PATTERN.matcher(text); while (m.find()) { final String g = m.group(); set.add(new HashTagPayload(tweet, g)); } } private static void replyToOwner (final Account account, final Tweet tweet, final Set<Payload> set) { if (tweet.getUsername() != null) set.add(new MentionPayload( account, tweet, StringHelper.firstLine(tweet.getUsername()), StringHelper.firstLine(tweet.getFullname()))); } private static void repliesAndExtractMentions (final Account account, final Tweet tweet, final Set<Payload> set) { final String tweetUsername = StringHelper.firstLine(tweet.getUsername()); final String tweetFullname = StringHelper.firstLine(tweet.getFullname()); List<String> allMentions = null; for (final Meta meta : tweet.getMetas()) { if (meta.getType() == MetaType.MENTION && !EqualHelper.equal(tweetUsername, meta.getData())) { if (allMentions == null) allMentions = new ArrayList<String>(); allMentions.add(meta.getData()); } } if (allMentions != null && tweetUsername != null) { set.add(new MentionPayload(account, tweet, tweetUsername, tweetFullname, allMentions.toArray(new String[allMentions.size()]))); } } private static boolean payloadsContainsType (final Collection<Payload> col, final PayloadType type) { for (final Payload p : col) { if (type == p.getType()) return true; } return false; } }