/* * Created by Itzik Braun on 12/3/2015. * Copyright (c) 2015 deluge. All rights reserved. * * Last Modification at: 3/12/15 4:27 PM */ package com.braunster.chatsdk.network; import android.content.Context; import android.os.Handler; import android.os.Message; import com.braunster.chatsdk.R; import com.braunster.chatsdk.Utils.Debug; import com.braunster.chatsdk.object.BError; import org.apache.commons.lang3.StringUtils; import org.jdeferred.Deferred; import org.jdeferred.DoneCallback; import org.jdeferred.FailCallback; import org.jdeferred.impl.DeferredObject; import org.json.JSONException; import org.json.JSONObject; import org.scribe.builder.ServiceBuilder; import org.scribe.builder.api.TwitterApi; import org.scribe.model.OAuthRequest; import org.scribe.model.Response; import org.scribe.model.Token; import org.scribe.model.Verb; import org.scribe.model.Verifier; import org.scribe.oauth.OAuthService; import java.util.HashMap; import java.util.Map; import timber.log.Timber; import static com.braunster.chatsdk.network.BDefines.BAccountType.Twitter; import static com.braunster.chatsdk.network.BDefines.Prefs.LoginTypeKey; /** * Created by braunster on 04/08/14. */ public class TwitterManager { private static final String TAG = TwitterManager.class.getSimpleName(); private static final boolean DEBUG = Debug.TwitterManager; public static final int ERROR = 10, SUCCESS = 20; public static String userId = "-1L"; public static String profileImageUrl = ""; // Twitter Urls. private static final String PROTECTED_RESOURCE_URL = "https://api.twitter.com/1.1/account/verify_credentials.json"; private static OAuthService service; private static Token requestToken; public static Token accessToken; public static Thread getAuthorizationURLThread(final Context context, final Handler handler){ return new Thread(new Runnable() { @Override public void run() { // If you choose to use a callback, "oauth_verifier" will be the return value by Twitter (request param) if (service == null) service = createService(context); try { requestToken = service.getRequestToken(); } catch (Exception ex){ ex.printStackTrace(); Message message = new Message(); message.what = ERROR; message.obj = BError.getError(BError.Code.BAD_RESPONSE, "Cant get request token."); handler.sendMessage(message); return; } String authrizationURL = service.getAuthorizationUrl(requestToken); Message message = new Message(); message.obj = authrizationURL; message.what = SUCCESS; handler.sendMessage(message); } }); } public static Thread getVerifierThread(final Context context, final String ver, final Deferred<Object, BError, Void> deferred){ return new Thread(new Runnable() { @Override public void run() { accessToken = verify(ver); if (accessToken == null) { handler.sendMessage(MessageObj.getErrorMessage(deferred, BError.getError(BError.Code.ACCESS_TOKEN_REFUSED, "Access token is null"))); return; } Response response = getResponse(context, PROTECTED_RESOURCE_URL); if (!response.isSuccessful()) { handler.sendMessage(MessageObj.getErrorMessage(deferred, BError.getError(BError.Code.BAD_RESPONSE, response.getBody()))); return; } try { JSONObject json = new JSONObject(response.getBody()); if (DEBUG) Timber.d("Twitter Response: %s", json.toString()); userId = json.getString("id"); profileImageUrl = json.getString(BDefines.Keys.ThirdPartyData.ImageURL); if (DEBUG) Timber.i("profileImageUrl: %s", profileImageUrl); BNetworkManager.sharedManager().getNetworkAdapter().authenticateWithMap( AbstractNetworkAdapter.getMap(new String[]{BDefines.Keys.UserId, LoginTypeKey}, json.get("id"), Twitter)) .done(new DoneCallback<Object>() { @Override public void onDone(Object o) { deferred.resolve(o); } }) .fail(new FailCallback<BError>() { @Override public void onFail(BError bError) { deferred.reject(bError); } }); } catch (JSONException e) { e.printStackTrace(); } } } ); } /** Must be called from inside a thread.*/ private static Response getResponse(Context context, String url){ if (service == null) service = createService(context); OAuthRequest request = new OAuthRequest(Verb.GET, url); if (accessToken == null) { accessToken = new Token(context.getString(R.string.twitter_access_token), context.getString(R.string.twitter_access_token_secret)); } service.signRequest(accessToken, request); return request.send(); } private static Token verify(String ver){ if (StringUtils.isEmpty(ver)) return null; Verifier verifier = new Verifier(ver); try { return service.getAccessToken(requestToken, verifier); } catch (Exception e) { e.printStackTrace(); return null; } } private static OAuthService createService(Context context){ // If you choose to use a callback, "oauth_verifier" will be the return value by Twitter (request param) return service = new ServiceBuilder() .provider(TwitterApi.class) .apiKey(context.getString(R.string.twitter_consumer_key)) .apiSecret(context.getString(R.string.twitter_consumer_secret)) .callback(context.getString(R.string.twitter_callback_url)) .debug() .build(); } private static class MessageObj{ public Object listener; public Object data; private MessageObj(Object listener, Object data) { this.listener = listener; this.data = data; } private static Message getErrorMessage(Object listener, Object data){ Message msg = new Message(); msg.what = 1; msg.arg1 = ERROR; msg.obj = new MessageObj(listener, data); return msg; } private static Message getSuccessMessage(Object listener, Object data){ Message msg = new Message(); msg.what = 1; msg.arg1 = SUCCESS; msg.obj = new MessageObj(listener, data); return msg; } } private static TwitterHandler handler = new TwitterHandler(); private static class TwitterHandler extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case 1: MessageObj obj = (MessageObj) msg.obj; if (obj.listener instanceof Deferred) { Deferred<Object, BError, Void> deferred= ((DeferredObject) obj.listener); if (msg.arg1 == ERROR) deferred.reject((BError) obj.data); else deferred.resolve(obj.data); } } } } public static Map<String, Object> getMap(String[] keys, Object...values){ Map<String, Object> map = new HashMap<String, Object>(); for (int i = 0 ; i < keys.length; i++){ // More values then keys entered. if (i == values.length) break; map.put(keys[i], values[i]); } return map; } }