package com.uwflow.flow_android.network; import android.content.Context; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.ImageView; import com.crashlytics.android.Crashlytics; import com.facebook.HttpMethod; import com.facebook.Request; import com.facebook.Response; import com.facebook.Session; import com.facebook.model.GraphObject; import com.loopj.android.http.JsonHttpResponseHandler; import com.loopj.android.http.RequestParams; import com.uwflow.flow_android.constant.Constants; import com.uwflow.flow_android.db_object.*; import com.uwflow.flow_android.util.JsonToDbUtil; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; import org.json.JSONException; import org.json.JSONObject; public class FlowApiRequests { private static final String TAG = "FlowApiRequests"; public static void login(String facebookId, String facebookAccessToken, final FlowApiRequestCallback callback) { RequestParams params = new RequestParams(); params.put(Constants.FBID, facebookId); params.put(Constants.FACEBOOK_ACCESS_TOKEN, facebookAccessToken); FlowAsyncClient.post(Constants.API_LOGIN, params, new JsonHttpResponseHandler() { @Override public void onSuccess(JSONObject response) { Log.d(TAG, "Login success"); callback.onSuccess(response); } @Override public void onFailure(String responseBody, Throwable error) { Log.d(TAG, "Login failed"); callback.onFailure(responseBody); } }); } public static void addCourseToShortlist(final String courseId, final FlowApiRequestCallback callback) { String url = String.format(Constants.API_USER_SHORTLIST_COURSE, courseId); FlowAsyncClient.put(url, null, new JsonHttpResponseHandler() { @Override public void onSuccess(JSONObject response) { Log.d(TAG, "Add course " + courseId + " to shortlist success."); callback.onSuccess(response); } @Override public void onFailure(String responseBody, Throwable error) { Log.d(TAG, "Add course " + courseId + " to shortlist failed."); callback.onFailure(responseBody); } @Override public void onFailure(Throwable e, JSONObject errorResponse) { Log.d(TAG, "Add course " + courseId + " to shortlist failed."); String errorMessage = ""; try { errorMessage = errorResponse.getString("error"); } catch (JSONException e1) { // Ignore could not parse error message } callback.onFailure(errorMessage); } }); } public static void searchCourses(String keywords, String sortMode, Boolean excludeTakenCourses, Integer count, Integer offset, final FlowApiRequestCallback callback) { // Build the search query string Uri.Builder uriBuilder = new Uri.Builder(); if (StringUtils.isNotBlank(keywords)) { uriBuilder.appendQueryParameter("keywords", keywords); } if (StringUtils.isNotEmpty(sortMode)) { uriBuilder.appendQueryParameter("sort_mode", sortMode); } if (excludeTakenCourses) { uriBuilder.appendQueryParameter("exclude_taken_courses", "yes"); } if (count != null && count >= 0) { uriBuilder.appendQueryParameter("count", String.valueOf(count)); } if (offset != null && offset >= 0) { uriBuilder.appendQueryParameter("offset", String.valueOf(offset)); } final String encodedQuery = uriBuilder.build().getEncodedQuery(); final String uri = String.format(Constants.API_SEARCH_COURSES, encodedQuery); getDetails(Constants.API_REQUEST_CALL_ID.API_SEARCH_COURSES, uri, callback); } public static void getUser(final FlowApiRequestCallback callback) { final String uri = Constants.API_USER; getDetails(uri, callback); } public static void getUserSchedule(final FlowApiRequestCallback callback) { final String uri = Constants.API_USER_SCHEDULE; getDetails(uri, callback); } public static void getUserExams(final FlowApiRequestCallback callback) { final String uri = Constants.API_USER_EXAMS; getDetails(uri, callback); } public static void getUserCourses(final FlowApiRequestCallback callback) { final String uri = Constants.API_USER_COURSES; getDetails(uri, callback); } public static void getUserFriends(final FlowApiRequestCallback callback) { final String uri = Constants.API_USER_FRIENDS; getDetails(uri, callback); } public static void getUser(String userId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_USERS, userId); getDetails(Constants.API_REQUEST_CALL_ID.API_USER, uri, callback); } public static void getUserSchedule(String userId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_USERS_SCHEDULE, userId); getDetails(Constants.API_REQUEST_CALL_ID.API_USER_SCHEDULE, uri, callback); } public static void getUserExams(String userId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_USERS_EXAMS, userId); getDetails(Constants.API_REQUEST_CALL_ID.API_USER_EXAMS, uri, callback); } public static void getUserCourses(String userId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_USERS_COURSES, userId); getDetails(Constants.API_REQUEST_CALL_ID.API_USER_COURSE, uri, callback); } public static void getUserFriends(String userId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_USERS_FRIENDS, userId); getDetails(Constants.API_REQUEST_CALL_ID.API_USER_FRIENDS, uri, callback); } public static void getCourse(String courseId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_COURSE, courseId); getDetails(Constants.API_REQUEST_CALL_ID.API_COURSE, uri, callback); } public static void getCourseProfessors(String courseId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_COURSE_PROFESSORS, courseId); getDetails(Constants.API_REQUEST_CALL_ID.API_COURSE_PROFESSORS, uri, callback); } public static void getCourseExams(String courseId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_COURSE_EXAMS, courseId); getDetails(Constants.API_REQUEST_CALL_ID.API_COURSE_EXAMS, uri, callback); } public static void getCourseSections(String courseId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_COURSE_SECTIONS, courseId); getDetails(Constants.API_REQUEST_CALL_ID.API_COURSE_SECTIONS, uri, callback); } public static void getCourseUsers(String courseId, final FlowApiRequestCallback callback) { final String uri = String.format(Constants.API_COURSE_USERS, courseId); getDetails(Constants.API_REQUEST_CALL_ID.API_COURSE_USERS, uri, callback); } public static void getUserCoverImage(final Context context, final String fbid, final ImageView imageView, final FlowImageLoaderCallback callback){ Bundle params = new Bundle(); params.putString("fields", "cover"); new Request( Session.getActiveSession(), "/" + fbid, params, HttpMethod.GET, new Request.Callback() { public void onCompleted(Response response) { GraphObject graphObject = response.getGraphObject(); if (graphObject != null && graphObject.getProperty("cover") != null) { if (graphObject != null && graphObject.getProperty("cover") != null) { try { JSONObject json = graphObject.getInnerJSONObject(); String url = json.getJSONObject("cover").getString("source"); FlowImageLoader loader = new FlowImageLoader(context); loader.loadImage(url, imageView, callback); } catch (Exception e) { Crashlytics.logException(e); } } } } } ).executeAsync(); } private static void getDetails(final int id, String uri, final FlowApiRequestCallback callback) { FlowAsyncClient.get(uri, null, new JsonHttpResponseHandler() { @Override public void onSuccess(org.json.JSONObject response) { FlowNetworkAsyncParser parser = new FlowNetworkAsyncParser(callback, id); parser.execute(response); } @Override public void onFailure(String responseBody, Throwable error) { callback.onFailure(responseBody); } }); } private static void getDetails(String uri, final FlowApiRequestCallback callback) { FlowAsyncClient.get(uri, null, new JsonHttpResponseHandler() { @Override public void onSuccess(org.json.JSONObject response) { // Successfully got a response callback.onSuccess(response); } @Override public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable e) { callback.onFailure(responseBody); } }); } protected static class FlowNetworkAsyncParser extends AsyncTask<JSONObject, Void, Object> { protected int callId; protected FlowApiRequestCallback callback; public FlowNetworkAsyncParser(FlowApiRequestCallback callback, int callId) { this.callback = callback; this.callId = callId; } @Override protected Object doInBackground(JSONObject... jsonObjects) { JSONObject jsonObject = jsonObjects[0]; switch (callId) { case Constants.API_REQUEST_CALL_ID.API_COURSE: return JsonToDbUtil.getCourseDetail(jsonObject); case Constants.API_REQUEST_CALL_ID.API_COURSE_EXAMS: return JsonToDbUtil.getCourseExams(jsonObject); case Constants.API_REQUEST_CALL_ID.API_COURSE_PROFESSORS: return JsonToDbUtil.getCourseProfessors(jsonObject); case Constants.API_REQUEST_CALL_ID.API_COURSE_USERS: return JsonToDbUtil.getCourseUserDetail(jsonObject); case Constants.API_REQUEST_CALL_ID.API_COURSE_SECTIONS: return JsonToDbUtil.getCourseSections(jsonObject); case Constants.API_REQUEST_CALL_ID.API_USER: return JsonToDbUtil.getUser(jsonObject); case Constants.API_REQUEST_CALL_ID.API_USER_COURSE: return JsonToDbUtil.getUserCourseDetail(jsonObject); case Constants.API_REQUEST_CALL_ID.API_USER_EXAMS: return JsonToDbUtil.getUserExams(jsonObject); case Constants.API_REQUEST_CALL_ID.API_USER_FRIENDS: return JsonToDbUtil.getUserFriends(jsonObject); case Constants.API_REQUEST_CALL_ID.API_USER_SCHEDULE: return JsonToDbUtil.getUserSchedule(jsonObject); case Constants.API_REQUEST_CALL_ID.API_SEARCH_COURSES: return JsonToDbUtil.getSearchResults(jsonObject); // TODO(david): Handle default case which throws an exception } return jsonObject; } @Override protected void onPostExecute(Object result) { try { switch (callId) { case Constants.API_REQUEST_CALL_ID.API_COURSE: callback.getCourseCallback((CourseDetail) result); break; case Constants.API_REQUEST_CALL_ID.API_COURSE_EXAMS: callback.getCourseExamsCallback((Exams) result); break; case Constants.API_REQUEST_CALL_ID.API_COURSE_PROFESSORS: callback.getCourseProfessorCallback((Professors) result); break; case Constants.API_REQUEST_CALL_ID.API_COURSE_USERS: callback.getCourseUsersCallback((CourseUserDetail) result); break; case Constants.API_REQUEST_CALL_ID.API_COURSE_SECTIONS: callback.getCourseSectionsCallback((Sections) result); break; case Constants.API_REQUEST_CALL_ID.API_USER: callback.getUserCallback((User) result); break; case Constants.API_REQUEST_CALL_ID.API_USER_FRIENDS: callback.getUserFriendsCallback((UserFriends) result); break; case Constants.API_REQUEST_CALL_ID.API_USER_SCHEDULE: callback.getUserScheduleCallback((ScheduleCourses) result); break; case Constants.API_REQUEST_CALL_ID.API_USER_EXAMS: callback.getUserExamsCallback((Exams) result); break; case Constants.API_REQUEST_CALL_ID.API_USER_COURSE: callback.getUserCoursesCallback((UserCourseDetail) result); break; case Constants.API_REQUEST_CALL_ID.API_SEARCH_COURSES: callback.searchCoursesCallback((SearchResults) result); break; default: callback.onSuccess((JSONObject) result); } } catch (Exception e) { callback.onFailure("Failed to parse"); Crashlytics.logException(e); } } } }