package com.piusvelte.sonet.social;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.piusvelte.sonet.BuildConfig;
import com.piusvelte.sonet.R;
import com.piusvelte.sonet.Sonet;
import com.piusvelte.sonet.SonetCrypto;
import com.piusvelte.sonet.SonetHttpClient;
import com.piusvelte.sonet.provider.Entity;
import com.piusvelte.sonet.provider.Notifications;
import com.piusvelte.sonet.provider.Statuses;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import static com.piusvelte.sonet.Sonet.Sauthor;
import static com.piusvelte.sonet.Sonet.Sbody;
import static com.piusvelte.sonet.Sonet.ScommentId;
import static com.piusvelte.sonet.Sonet.SdisplayName;
import static com.piusvelte.sonet.Sonet.Sentry;
import static com.piusvelte.sonet.Sonet.Sid;
import static com.piusvelte.sonet.Sonet.SmoodStatusLastUpdated;
import static com.piusvelte.sonet.Sonet.SpostedDate;
import static com.piusvelte.sonet.Sonet.SrecentComments;
import static com.piusvelte.sonet.Sonet.Sstatus;
import static com.piusvelte.sonet.Sonet.SstatusId;
import static com.piusvelte.sonet.Sonet.SthumbnailUrl;
import static com.piusvelte.sonet.Sonet.SuserId;
/**
* Created by bemmanuel on 2/15/15.
*/
public class MySpace extends Client {
private static final String MYSPACE_BASE_URL = "http://api.myspace.com/1.0/";
private static final String MYSPACE_URL_REQUEST = "http://api.myspace.com/request_token";
private static final String MYSPACE_URL_AUTHORIZE = "http://api.myspace.com/authorize";
private static final String MYSPACE_URL_ACCESS = "http://api.myspace.com/access_token";
private static final String MYSPACE_URL_ME = "%speople/@me/@self";
private static final String MYSPACE_HISTORY = "%sstatusmood/@me/@friends/history?includeself=true&fields=author,source,recentComments";
private static final String MYSPACE_URL_STATUSMOOD = "%sstatusmood/@me/@self";
private static final String MYSPACE_URL_STATUSMOODCOMMENTS = "%sstatusmoodcomments/%s/@self/%s?format=json&includeself=true&fields=author";
private static final String MYSPACE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
private static final String MYSPACE_STATUSMOOD_BODY = "{\"status\":\"%s\"}";
private static final String MYSPACE_STATUSMOODCOMMENTS_BODY = "{\"body\":\"%s\"}";
private static final String MYSPACE_USER = "%speople/%s/@self";
public MySpace(Context context, String token, String secret, String accountEsid, int network) {
super(context, token, secret, accountEsid, network);
}
@Nullable
@Override
public String getProfileUrl(@NonNull String esid) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_USER, MYSPACE_BASE_URL, esid))
.build();
String response = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(response)) {
try {
return new JSONObject(response).getJSONObject("person").getString("profileUrl");
} catch (JSONException e) {
if (BuildConfig.DEBUG) {
Log.e(mTag, "Error parsing: " + response, e);
}
}
}
return null;
}
@Nullable
@Override
public String getProfilePhotoUrl() {
return getProfilePhotoUrl(mAccountEsid);
}
@Nullable
@Override
public String getProfilePhotoUrl(String esid) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_ME, MYSPACE_BASE_URL))
.build();
String httpResponse = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(httpResponse)) {
try {
JSONObject jobj = new JSONObject(httpResponse);
JSONObject person = jobj.getJSONObject("person");
return person.getString(SthumbnailUrl);
} catch (JSONException e) {
if (BuildConfig.DEBUG) {
Log.d(mTag, "error parsing me response: " + httpResponse, e);
}
}
}
return null;
}
@Nullable
@Override
public Uri getCallback() {
return Uri.parse("sonet://myspace");
}
@Override
String getRequestUrl() {
return MYSPACE_URL_REQUEST;
}
@Override
String getAccessUrl() {
return MYSPACE_URL_ACCESS;
}
@Override
String getAuthorizeUrl() {
return MYSPACE_URL_AUTHORIZE;
}
@Override
public String getCallbackUrl() {
return getCallback().toString();
}
@Override
public MemberAuthentication getMemberAuthentication(@NonNull String authenticatedUrl) {
if (getOAuth10Helper().getAccessToken(SonetHttpClient.getOkHttpClientInstance(), authenticatedUrl)) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_ME, MYSPACE_BASE_URL))
.build();
String httpResponse = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(httpResponse)) {
try {
JSONObject jobj = new JSONObject(httpResponse);
JSONObject person = jobj.getJSONObject("person");
if (person.has(SdisplayName) && person.has(Sid)) {
MemberAuthentication memberAuthentication = new MemberAuthentication();
memberAuthentication.username = person.getString(SdisplayName);
memberAuthentication.token = getOAuth10Helper().getToken();
memberAuthentication.secret = getOAuth10Helper().getSecret();
memberAuthentication.expiry = 0;
memberAuthentication.network = mNetwork;
memberAuthentication.id = person.getString(Sid);
return memberAuthentication;
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) {
Log.d(mTag, "error parsing me response: " + httpResponse, e);
}
}
}
}
return null;
}
@Nullable
@Override
public Set<String> getNotificationStatusIds(long account, String[] notificationMessage) {
Set<String> notificationSids = new HashSet<>();
Cursor currentNotifications = getContentResolver().query(Notifications.getContentUri(mContext),
new String[] { Notifications._ID, Notifications.SID, Notifications.UPDATED, Notifications.CLEARED, Notifications.ESID },
Notifications.ACCOUNT + "=?", new String[] { Long.toString(account) }, null);
// loop over notifications
if (currentNotifications.moveToFirst()) {
while (!currentNotifications.isAfterLast()) {
long notificationId = currentNotifications.getLong(0);
String sid = SonetCrypto.getInstance(mContext).Decrypt(currentNotifications.getString(1));
long updated = currentNotifications.getLong(2);
boolean cleared = currentNotifications.getInt(3) == 1;
String esid = SonetCrypto.getInstance(mContext).Decrypt(currentNotifications.getString(4));
// store sids, to avoid duplicates when requesting the latest feed
notificationSids.add(sid);
// get comments for current notifications
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_STATUSMOODCOMMENTS, MYSPACE_BASE_URL, esid, sid))
.build();
String response = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(response)) {
// check for a newer post, if it's the user's own, then set CLEARED=0
try {
JSONArray commentsArray = new JSONObject(response).getJSONArray(Sentry);
final int i2 = commentsArray.length();
if (i2 > 0) {
for (int i = 0; i < i2; i++) {
JSONObject commentObj = commentsArray.getJSONObject(i);
long created_time = parseDate(commentObj.getString(SpostedDate), MYSPACE_DATE_FORMAT);
if (created_time > updated) {
JSONObject friendObj = commentObj.getJSONObject(Sauthor);
updateNotificationMessage(notificationMessage,
updateNotification(notificationId, created_time, mAccountEsid, friendObj.getString(Sid),
friendObj.getString(SdisplayName), cleared));
}
}
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.d(mTag, "error parsing: " + response, e);
}
}
currentNotifications.moveToNext();
}
}
currentNotifications.close();
return notificationSids;
}
@Nullable
@Override
public String getFeedResponse(int status_count) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_HISTORY, MYSPACE_BASE_URL))
.build();
return SonetHttpClient.getResponse(request);
}
@Nullable
@Override
public JSONArray parseFeed(@NonNull String response) throws JSONException {
return new JSONObject(response).getJSONArray(Sentry);
}
@Nullable
@Override
public void addFeedItem(@NonNull JSONObject item,
boolean display_profile,
boolean time24hr,
int appWidgetId,
long account,
Set<String> notificationSids,
String[] notificationMessage,
boolean doNotify) throws JSONException {
JSONObject friendObj = item.getJSONObject(Sauthor);
long date = parseDate(item.getString(SmoodStatusLastUpdated), MYSPACE_DATE_FORMAT);
String esid = item.getString(SuserId);
int commentCount = 0;
String sid = item.getString(SstatusId);
String friend = friendObj.getString(SdisplayName);
String statusValue = item.getString(Sstatus);
String notification = null;
if (item.has(SrecentComments)) {
JSONArray commentsArray = item.getJSONArray(SrecentComments);
commentCount = commentsArray.length();
// notifications
if ((sid != null) && !notificationSids.contains(sid) && (commentCount > 0)) {
// default hasCommented to whether or not these comments are for the own user's status
boolean hasCommented = notification != null || esid.equals(mAccountEsid);
for (int c2 = 0; c2 < commentCount; c2++) {
JSONObject commentObj = commentsArray.getJSONObject(c2);
if (commentObj.has(Sauthor)) {
JSONObject c4 = commentObj.getJSONObject(Sauthor);
if (c4.getString(Sid).equals(mAccountEsid)) {
if (!hasCommented) {
// the user has commented on this thread, notify any updates
hasCommented = true;
}
// clear any notifications, as the user is already aware
if (notification != null) {
notification = null;
}
} else if (hasCommented) {
// don't notify about user's own comments
// send the parent comment sid
notification = String.format(getString(R.string.friendcommented), c4.getString(SdisplayName));
}
}
}
}
}
if (doNotify && notification != null) {
// new notification
addNotification(sid, esid, friend, statusValue, date, account, notification);
updateNotificationMessage(notificationMessage, notification);
}
addStatusItem(date,
friend,
display_profile ? friendObj.getString(SthumbnailUrl) : null,
String.format(getString(R.string.messageWithCommentCount), statusValue, commentCount),
time24hr,
appWidgetId,
account,
sid,
esid,
new ArrayList<String[]>()
);
}
@Nullable
@Override
public void getNotificationMessage(long account, String[] notificationMessage) {
}
@Override
public void getNotifications(long account, String[] notificationMessage) {
Cursor currentNotifications = getContentResolver().query(Notifications.getContentUri(mContext),
new String[] { Notifications._ID, Notifications.SID, Notifications.UPDATED, Notifications.CLEARED, Notifications.ESID },
Notifications.ACCOUNT + "=?", new String[] { Long.toString(account) }, null);
if (currentNotifications.moveToFirst()) {
Set<String> notificationSids = new HashSet<>();
// loop over notifications
while (!currentNotifications.isAfterLast()) {
long notificationId = currentNotifications.getLong(0);
String sid = SonetCrypto.getInstance(mContext).Decrypt(currentNotifications.getString(1));
long updated = currentNotifications.getLong(2);
boolean cleared = currentNotifications.getInt(3) == 1;
String esid = SonetCrypto.getInstance(mContext).Decrypt(currentNotifications.getString(4));
// store sids, to avoid duplicates when requesting the latest feed
notificationSids.add(sid);
// get comments for current notifications
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_STATUSMOODCOMMENTS, MYSPACE_BASE_URL, esid, sid))
.build();
String response = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(response)) {
// check for a newer post, if it's the user's own, then set CLEARED=0
try {
JSONArray comments = new JSONObject(response).getJSONArray(Sentry);
int i2 = comments.length();
if (i2 > 0) {
for (int i = 0; i < i2; i++) {
JSONObject comment = comments.getJSONObject(i);
long created_time = parseDate(comment.getString(SpostedDate), MYSPACE_DATE_FORMAT);
if (created_time > updated) {
// new comment
ContentValues values = new ContentValues();
values.put(Notifications.UPDATED, created_time);
JSONObject author = comment.getJSONObject(Sauthor);
if (mAccountEsid.equals(author.getString(Sid))) {
// user's own comment, clear the notification
values.put(Notifications.CLEARED, 1);
} else if (cleared) {
values.put(Notifications.NOTIFICATION,
String.format(getString(R.string.friendcommented), comment.getString(SdisplayName)));
values.put(Notifications.CLEARED, 0);
} else {
values.put(Notifications.NOTIFICATION,
String.format(getString(R.string.friendcommented), comment.getString(SdisplayName) + " and others"));
}
getContentResolver().update(Notifications.getContentUri(mContext), values, Notifications._ID + "=?",
new String[] { Long.toString(notificationId) });
}
}
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.e(mTag, e.toString());
}
}
currentNotifications.moveToNext();
}
// check the latest feed
String response = getFeedResponse(0);
if (!TextUtils.isEmpty(response)) {
try {
JSONArray jarr = new JSONObject(response).getJSONArray(Sentry);
// if there are updates, clear the cache
int d2 = jarr.length();
if (d2 > 0) {
for (int d = 0; d < d2; d++) {
JSONObject o = jarr.getJSONObject(d);
String sid = o.getString(SstatusId);
// if already notified, ignore
if (!notificationSids.contains(sid)) {
if (o.has(Sauthor) && o.has(SrecentComments)) {
JSONObject f = o.getJSONObject(Sauthor);
if (f.has(SdisplayName) && f.has(Sid)) {
String notification = null;
String esid = f.getString(Sid);
String friend = f.getString(SdisplayName);
JSONArray comments = o.getJSONArray(SrecentComments);
int commentCount = comments.length();
// notifications
if ((sid != null) && (commentCount > 0)) {
// default hasCommented to whether or not these comments are for the own user's status
boolean hasCommented = notification != null || esid.equals(mAccountEsid);
for (int c2 = 0; c2 < commentCount; c2++) {
JSONObject c3 = comments.getJSONObject(c2);
if (c3.has(Sauthor)) {
JSONObject c4 = c3.getJSONObject(Sauthor);
if (c4.getString(Sid).equals(mAccountEsid)) {
if (!hasCommented) {
// the user has commented on this thread, notify any updates
hasCommented = true;
}
// clear any notifications, as the user is already aware
if (notification != null) {
notification = null;
}
} else if (hasCommented) {
// don't notify about user's own comments
// send the parent comment sid
notification = String.format(getString(R.string.friendcommented), c4.getString(SdisplayName));
}
}
}
}
if (notification != null) {
// new notification
addNotification(sid, esid, friend, o.getString(Sstatus),
parseDate(o.getString("moodStatusLastUpdated"), MYSPACE_DATE_FORMAT), account, notification);
}
}
}
}
}
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.e(mTag, e.toString());
}
}
}
currentNotifications.close();
}
@Override
public boolean createPost(String message, String placeId, String latitude, String longitude, String photoPath, String[] tags) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_STATUSMOOD, MYSPACE_BASE_URL))
.put(RequestBody.create(MediaType.parse("application/json"), String.format(MYSPACE_STATUSMOOD_BODY, message)))
.build();
return SonetHttpClient.request(request);
}
@Override
public boolean isLikeable(String statusId) {
return false;
}
@Override
public boolean isLiked(String statusId, String accountId) {
return false;
}
@Override
public boolean likeStatus(String statusId, String accountId, boolean doLike) {
return false;
}
@Override
public String getLikeText(boolean isLiked) {
return null;
}
@Override
public boolean isCommentable(String statusId) {
return true;
}
@Override
public String getCommentPretext(String accountId) {
return null;
}
@Override
public void onDelete() {
}
@Nullable
@Override
public String getCommentsResponse(String statusId) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_STATUSMOODCOMMENTS, MYSPACE_BASE_URL, mAccountEsid, statusId))
.build();
return SonetHttpClient.getResponse(request);
}
@Nullable
@Override
public JSONArray parseComments(@NonNull String response) throws JSONException {
return new JSONObject(response).getJSONArray(Sentry);
}
@Nullable
@Override
public HashMap<String, String> parseComment(@NonNull String statusId, @NonNull JSONObject jsonComment, boolean time24hr) throws JSONException {
HashMap<String, String> commentMap = new HashMap<String, String>();
commentMap.put(Statuses.SID, jsonComment.getString(ScommentId));
commentMap.put(Entity.FRIEND, jsonComment.getJSONObject(Sauthor).getString(SdisplayName));
commentMap.put(Statuses.MESSAGE, jsonComment.getString(Sbody));
commentMap.put(Statuses.CREATEDTEXT, Sonet.getCreatedText(parseDate(jsonComment.getString(SpostedDate), MYSPACE_DATE_FORMAT), time24hr));
commentMap.put(getString(R.string.like), "");
return commentMap;
}
@Override
public LinkedHashMap<String, String> getLocations(String latitude, String longitude) {
return null;
}
@Override
public boolean sendComment(@NonNull String statusId, @NonNull String message) {
Request request = getOAuth10Helper().getBuilder()
.url(String.format(MYSPACE_URL_STATUSMOODCOMMENTS, MYSPACE_BASE_URL, mAccountEsid, statusId))
.post(RequestBody.create(MediaType.parse("application/json"), String.format(MYSPACE_STATUSMOODCOMMENTS_BODY, message)))
.build();
return SonetHttpClient.request(request);
}
@Override
public List<HashMap<String, String>> getFriends() {
return null;
}
@Override
String getApiKey() {
return BuildConfig.MYSPACE_KEY;
}
@Override
String getApiSecret() {
return BuildConfig.MYSPACE_SECRET;
}
}