/*
* Firetweet - Twitter client for Android
*
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.getlantern.firetweet.util;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.v4.util.LongSparseArray;
import android.util.Log;
import org.getlantern.firetweet.Constants;
import org.getlantern.firetweet.model.ListResponse;
import org.getlantern.firetweet.model.ParcelableUser;
import org.getlantern.firetweet.model.SingleResponse;
import org.getlantern.firetweet.provider.FiretweetDataStore.Notifications;
import org.getlantern.firetweet.provider.FiretweetDataStore.UnreadCounts;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import twitter4j.DirectMessage;
import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.User;
import com.crashlytics.android.Crashlytics;
import static org.getlantern.firetweet.util.Utils.getTwitterInstance;
public class TwitterWrapper implements Constants {
public static int clearNotification(final Context context, final int notificationType, final long accountId) {
final Uri.Builder builder = Notifications.CONTENT_URI.buildUpon();
builder.appendPath(String.valueOf(notificationType));
if (accountId > 0) {
builder.appendPath(String.valueOf(accountId));
}
return context.getContentResolver().delete(builder.build(), null, null);
}
public static int clearUnreadCount(final Context context, final int position) {
if (context == null || position < 0) return 0;
final Uri uri = UnreadCounts.CONTENT_URI.buildUpon().appendPath(String.valueOf(position)).build();
return context.getContentResolver().delete(uri, null, null);
}
public static SingleResponse<Boolean> deleteProfileBannerImage(final Context context, final long account_id) {
final Twitter twitter = getTwitterInstance(context, account_id, false);
if (twitter == null) return new SingleResponse<>(false, null);
try {
twitter.removeProfileBannerImage();
return new SingleResponse<>(true, null);
} catch (final TwitterException e) {
Crashlytics.logException(e);
return new SingleResponse<>(false, e);
}
}
public static int removeUnreadCounts(final Context context, final int position, final long account_id,
final long... status_ids) {
if (context == null || position < 0 || status_ids == null || status_ids.length == 0)
return 0;
int result = 0;
final Uri.Builder builder = UnreadCounts.CONTENT_URI.buildUpon();
builder.appendPath(String.valueOf(position));
builder.appendPath(String.valueOf(account_id));
builder.appendPath(FiretweetArrayUtils.toString(status_ids, ',', false));
result += context.getContentResolver().delete(builder.build(), null, null);
return result;
}
public static int removeUnreadCounts(final Context context, final int position, final LongSparseArray<Set<Long>> counts) {
if (context == null || position < 0 || counts == null) return 0;
int result = 0;
for (int i = 0, j = counts.size(); i < j; i++) {
final long key = counts.keyAt(i);
final Set<Long> value = counts.valueAt(i);
final Uri.Builder builder = UnreadCounts.CONTENT_URI.buildUpon();
builder.appendPath(String.valueOf(position));
builder.appendPath(String.valueOf(key));
builder.appendPath(CollectionUtils.toString(value, ',', false));
result += context.getContentResolver().delete(builder.build(), null, null);
}
return result;
}
@NonNull
public static User showUser(final Twitter twitter, final long id, final String screenName) throws TwitterException {
if (twitter.getId() == id || twitter.getScreenName().equalsIgnoreCase(screenName)) {
return twitter.verifyCredentials();
} else if (id != -1) {
return twitter.showUser(id);
} else if (screenName != null) {
return twitter.showUser(screenName);
}
throw new IllegalArgumentException();
}
@NonNull
public static User showUserAlternative(final Twitter twitter, final long id, final String screenName)
throws TwitterException {
final String searchScreenName;
if (screenName != null) {
searchScreenName = screenName;
} else if (id != -1) {
searchScreenName = twitter.showFriendship(twitter.getId(), id).getTargetUserScreenName();
} else
throw new IllegalArgumentException();
final Paging paging = new Paging();
paging.count(1);
if (id != -1) {
final ResponseList<Status> timeline = twitter.getUserTimeline(id, paging);
for (final Status status : timeline) {
final User user = status.getUser();
if (user.getId() == id) return user;
}
} else {
final ResponseList<Status> timeline = twitter.getUserTimeline(screenName, paging);
for (final Status status : timeline) {
final User user = status.getUser();
if (searchScreenName.equalsIgnoreCase(user.getScreenName()))
return user;
}
}
for (final User user : twitter.searchUsers(searchScreenName, 1)) {
if (user.getId() == id || searchScreenName.equalsIgnoreCase(user.getScreenName()))
return user;
}
throw new TwitterException("can't find user");
}
@NonNull
public static User tryShowUser(final Twitter twitter, final long id, final String screenName)
throws TwitterException {
try {
return showUser(twitter, id, screenName);
} catch (final TwitterException e) {
Crashlytics.logException(e);
if (e.getCause() instanceof IOException)
throw e;
}
return showUserAlternative(twitter, id, screenName);
}
public static SingleResponse<ParcelableUser> updateProfile(final Context context, final long account_id,
final String name, final String url, final String location, final String description) {
final Twitter twitter = getTwitterInstance(context, account_id, false);
if (twitter != null) {
try {
final User user = twitter.updateProfile(name, url, location, description);
return new SingleResponse<>(new ParcelableUser(user, account_id), null);
} catch (final TwitterException e) {
Crashlytics.logException(e);
return new SingleResponse<>(null, e);
}
}
return SingleResponse.getInstance();
}
public static void updateProfileBannerImage(final Context context, final long accountId,
final Uri imageUri, final boolean deleteImage)
throws FileNotFoundException, TwitterException {
final Twitter twitter = getTwitterInstance(context, accountId, false);
updateProfileBannerImage(context, twitter, imageUri, deleteImage);
}
public static void updateProfileBannerImage(final Context context, final Twitter twitter,
final Uri imageUri, final boolean deleteImage)
throws FileNotFoundException, TwitterException {
InputStream is;
try {
is = context.getContentResolver().openInputStream(imageUri);
twitter.updateProfileBannerImage(is);
} finally {
if (deleteImage && "file".equals(imageUri.getScheme())) {
final File file = new File(imageUri.getPath());
if (!file.delete()) {
Log.w(LOGTAG, String.format("Unable to delete %s", file));
}
}
}
}
public static User updateProfileImage(final Context context, final Twitter twitter,
final Uri imageUri, final boolean deleteImage)
throws FileNotFoundException, TwitterException {
InputStream is;
try {
is = context.getContentResolver().openInputStream(imageUri);
return twitter.updateProfileImage(is);
} finally {
if (deleteImage && "file".equals(imageUri.getScheme())) {
final File file = new File(imageUri.getPath());
if (!file.delete()) {
Log.w(LOGTAG, String.format("Unable to delete %s", file));
}
}
}
}
public static User updateProfileImage(final Context context, final long accountId,
final Uri imageUri, final boolean deleteImage)
throws FileNotFoundException, TwitterException {
final Twitter twitter = getTwitterInstance(context, accountId, true);
return updateProfileImage(context, twitter, imageUri, deleteImage);
}
public static final class MessageListResponse extends TwitterListResponse<DirectMessage> {
public final boolean truncated;
public MessageListResponse(final long accountId, final Exception exception) {
this(accountId, -1, -1, null, false, exception);
}
public MessageListResponse(final long accountId, final List<DirectMessage> list) {
this(accountId, -1, -1, list, false, null);
}
public MessageListResponse(final long accountId, final long maxId, final long sinceId,
final List<DirectMessage> list, final boolean truncated) {
this(accountId, maxId, sinceId, list, truncated, null);
}
MessageListResponse(final long accountId, final long maxId, final long sinceId,
final List<DirectMessage> list, final boolean truncated, final Exception exception) {
super(accountId, maxId, sinceId, list, exception);
this.truncated = truncated;
}
}
public static final class StatusListResponse extends TwitterListResponse<Status> {
public final boolean truncated;
public StatusListResponse(final long accountId, final Exception exception) {
this(accountId, -1, -1, null, false, exception);
}
public StatusListResponse(final long accountId, final List<Status> list) {
this(accountId, -1, -1, list, false, null);
}
public StatusListResponse(final long accountId, final long maxId, final long sinceId,
final List<Status> list, final boolean truncated) {
this(accountId, maxId, sinceId, list, truncated, null);
}
StatusListResponse(final long accountId, final long maxId, final long sinceId, final List<Status> list,
final boolean truncated, final Exception exception) {
super(accountId, maxId, sinceId, list, exception);
this.truncated = truncated;
}
}
public static class TwitterListResponse<Data> extends ListResponse<Data> {
public final long accountId, maxId, sinceId;
public TwitterListResponse(final long accountId, final Exception exception) {
this(accountId, -1, -1, null, exception);
}
public TwitterListResponse(final long accountId, final long maxId, final long sinceId, final List<Data> list) {
this(accountId, maxId, sinceId, list, null);
}
TwitterListResponse(final long accountId, final long maxId, final long sinceId, final List<Data> list,
final Exception exception) {
super(list, exception);
this.accountId = accountId;
this.maxId = maxId;
this.sinceId = sinceId;
}
}
}