/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.talk.demo.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.http.HttpStatus; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.accounts.Account; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.text.TextUtils; import android.util.Log; import com.talk.demo.parser.CandidateParser; import com.talk.demo.parser.DialogParser; import com.talk.demo.parser.FriendParser; import com.talk.demo.parser.GroupParser; import com.talk.demo.parser.NewsParser; import com.talk.demo.parser.RecordParser; import com.talk.demo.parser.ResParser; import com.talk.demo.parser.ResponseParser; import com.talk.demo.types.Candidate; import com.talk.demo.types.PrvDialog; import com.talk.demo.types.Friend; import com.talk.demo.types.Group; import com.talk.demo.types.News; import com.talk.demo.types.Record; import com.talk.demo.types.Response; import com.talk.demo.types.TalkType; import com.talk.demo.util.HttpRequest.HttpRequestException; /** * Provides utility methods for communicating with the server. */ final public class NetworkUtilities { /** The tag used to log to adb console. */ private static final String TAG = "NetworkUtilities"; /** POST parameter name for the user's account name */ public static final String PARAM_USERNAME = "username"; /** POST parameter name for the user's password */ public static final String PARAM_PASSWORD = "password"; /** POST parameter name for the user's authentication token */ public static final String PARAM_AUTH_TOKEN = "authtoken"; /** POST parameter name for the crsf token */ public static final String PARAM_CSRF_TOKEN = "csrftoken"; /** POST parameter name for the client's last-known sync state */ public static final String PARAM_SYNC_STATE = "syncstate"; /** POST parameter name for the sending client-edited contact info */ public static final String PARAM_RECORDS_DATA = "records"; public static final String PARAM_FRIENDS_DATA = "friends"; /** Base URL for the v2 Sample Sync Service */ //public static final String BASE_URL = "http://10.4.65.41/"; public static final String BASE_URL = "http://192.168.1.106/"; /** URI for authentication service */ public static final String AUTH_URI = BASE_URL + "users/login/"; public static final String SIGNUP_URI = BASE_URL + "users/signup/"; public static final String SEARCH_PEOPLE_URI = BASE_URL + "users/search_people/"; /** URI for friend service */ public static final String RECOMMEND_FRIENDS_URI = BASE_URL + "friends/recommend/"; public static final String SYNC_FRIENDS_URI = BASE_URL + "friends/sync_friend/"; public static final String ADD_FRIENDS_URI = BASE_URL + "friends/add_friend/"; public static final String ACCEPT_FRIENDS_URI = BASE_URL + "friends/accept_friend/"; public static final String UPDATE_FRIENDS_URI = BASE_URL + "friends/update_friend/"; /** URI for sync service */ public static final String SYNC_RECORDS_URI = BASE_URL + "times/sync/"; public static final String VISIT_RECORDS_URI = BASE_URL + "times/visit/"; /** URI for dialog share */ public static final String SHARE_RECORDS_URI = BASE_URL + "dialogs/share/"; public static final String GET_DIALOGS_URI = BASE_URL + "dialogs/getdialog/"; /** URI for news service */ public static final String SYNC_NEWS_URI = BASE_URL + "news/today/"; public static final String UPLOAD_PHOTO_URI = BASE_URL + "times/photo/"; public static final String DOWNLOAD_PHOTO_URI = BASE_URL + "times/photoView/"; public static final String ADD_AVATAR_URI = BASE_URL + "users/add_avatar/"; public static final String GET_AVATAR_URI = BASE_URL + "users/get_avatar/"; private NetworkUtilities() { } public static HttpRequest createGet(String url) { HttpRequest request = HttpRequest.get(url); request.followRedirects(false); return request; } public static HttpRequest createPost(String url, Map<String, String> formData) { HttpRequest request = HttpRequest.post(url); Map<String, String> headers = new HashMap<String, String>(); headers.put("Content-Type", "text/html"); request.headers(headers); Log.d(TAG, "request: "+formData.toString()); request.form(formData); return request; } public static TalkType doHttpRequest(HttpRequest request, ResParser<? extends TalkType> parser) throws JSONException { try { int statusCode = request.code(); switch (statusCode) { case 200: String response = request.body(); Log.d(TAG, "respone: " + response.toString()); return consume(parser, response); case 400: Log.d(TAG, "HTTP Code: 400"); break; case 401: Log.d(TAG, "HTTP Code: 400"); break; case 404: Log.d(TAG, "HTTP Code: 404"); break; case 500: Log.d(TAG, "HTTP Code: 500"); break; default: Log.d(TAG, "Default case"); break; } } catch (HttpRequestException ex) { Log.d(TAG, "http request error: "+ex.getMessage()); } return null; } public static TalkType consume(ResParser<? extends TalkType> parser, String content) throws JSONException { try { JSONObject json = new JSONObject(content); Log.d(TAG, "response json : "+json.toString()); Iterator<String> it = (Iterator<String>)json.keys(); if(it.hasNext()) { String key = (String)it.next(); if(key.equals("error")) { Log.d(TAG, "error is: "+json.getString(key)); } else { Object obj = json.get(key); if(obj instanceof JSONArray) { return parser.parse((JSONArray)obj); } else { return parser.parse(json); } } } else { throw new JSONException("Error parsing JSON response, object had no single child key."); } } catch (JSONException ex) { throw new JSONException("Error parsing JSON response: "+ ex.getMessage()); } return null; } public static Response addFriend(String username, String friend) throws HttpRequestException, JSONException { HttpRequest request = createPost(ADD_FRIENDS_URI, PackedFormData.addFriend(username, friend)); return (Response)doHttpRequest(request,new ResponseParser()); } public static Response acceptFriend(String username, boolean response, String friend) throws HttpRequestException, JSONException { HttpRequest request = createPost(ACCEPT_FRIENDS_URI, PackedFormData.acceptFriend(username, response, friend)); return (Response)doHttpRequest(request,new ResponseParser()); } public static Friend updateFriend(String username, String comment, String description, String friend) throws HttpRequestException, JSONException { HttpRequest request = createPost(UPDATE_FRIENDS_URI, PackedFormData.updateFriend(username, comment, description, friend)); return (Friend)doHttpRequest(request,new FriendParser()); } public static String signup(String username, String email, String password) { try { HttpRequest request = HttpRequest.post(SIGNUP_URI); // X-CSRFToken Map<String, String> headers = new HashMap<String, String>(); headers.put("Content-Type", "text/html"); //headers.put("Cookie", csrfToken); //Log.d(TAG, "our cookie: " + csrfToken); request.headers(headers); //request.followRedirects(false); HttpRequest conn4Session = request.form(PackedFormData.signup(username, email, password)); conn4Session.code(); HttpURLConnection sessionConnection = conn4Session.getConnection(); try { int result = sessionConnection.getResponseCode(); Log.e(TAG, "get response code : "+result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (HttpRequestException exception) { Log.d(TAG, "exception : " + exception.toString()); return null; } finally { Log.v(TAG, "signup completing"); } return "ok"; } public static String authenticate(String username, String password) { try { HttpRequest request = HttpRequest.post(AUTH_URI); Map<String, String> headers = new HashMap<String, String>(); headers.put("Content-Type", "text/html"); request.headers(headers); request.followRedirects(false); HttpRequest conn4Session = request.form(PackedFormData.login(username, password)); conn4Session.code(); HttpURLConnection sessionConnection = conn4Session.getConnection(); try { int result = sessionConnection.getResponseCode(); Log.e(TAG, "get response code : "+result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (HttpRequestException exception) { Log.d(TAG, "exception : " + exception.toString()); return null; } finally { Log.v(TAG, "getAuthtoken completing"); } return "ok"; } @SuppressWarnings("unchecked") public static Group<News> todayNews() throws JSONException, HttpRequestException { HttpRequest request = createGet(SYNC_NEWS_URI); return (Group<News>)doHttpRequest(request,new GroupParser(new NewsParser())); } @SuppressWarnings("unchecked") public static Group<Candidate> newFriends() throws JSONException, HttpRequestException { HttpRequest request = createGet(RECOMMEND_FRIENDS_URI); return (Group<Candidate>)doHttpRequest(request,new GroupParser(new CandidateParser())); } public static void shareRecord(PrvDialog raw, String oring, String target) { try { HttpRequest request = HttpRequest.post(SHARE_RECORDS_URI); request.followRedirects(false); request.form(PackedFormData.shareRecord(raw, oring, target)); request.getConnection(); int code = request.code(); if(code == HttpStatus.SC_OK) { Log.d(TAG, "finish!!"); } } catch (HttpRequestException exception) { Log.d(TAG, "exception : "+ exception.toString()); } } public static PrvDialog getDialog_v2(String username, int id) throws HttpRequestException, JSONException { HttpRequest request = createPost(GET_DIALOGS_URI, PackedFormData.getDialog(username, id)); return (PrvDialog)doHttpRequest(request,new DialogParser()); } @SuppressWarnings("unchecked") public static Group<Record> updateChannel_v2(String friend, String last_date) throws JSONException, HttpRequestException { HttpRequest request = createPost(VISIT_RECORDS_URI, PackedFormData.packedUpdateChannel(friend, last_date)); return (Group<Record>)doHttpRequest(request,new GroupParser(new RecordParser())); } /** * Perform 2-way sync with the server-side contacts. We send a request that * includes all the locally-dirty contacts so that the server can process * those changes, and we receive (and return) a list of contacts that were * updated on the server-side that need to be updated locally. * * @param account The account being synced * @param authtoken The authtoken stored in the AccountManager for this * account * @param serverSyncState A token returned from the server on the last sync * @param dirtyContacts A list of the contacts to send to the server * @return A list of contacts that we need to update locally */ @SuppressWarnings("unchecked") public static Group<Record> syncRecords_v2( Account account, String authtoken, long serverSyncState, List<Record> dirtyRecords) throws JSONException, HttpRequestException { HttpRequest request = createPost(SYNC_RECORDS_URI, PackedFormData.syncRecords(account, authtoken, serverSyncState, dirtyRecords)); return (Group<Record>)doHttpRequest(request,new GroupParser(new RecordParser())); } @SuppressWarnings("unchecked") public static Group<Friend> syncFriends_v2( Account account, String authtoken, long serverSyncState, List<Friend> dirtyFriends) throws JSONException, HttpRequestException { HttpRequest request = createPost(SYNC_FRIENDS_URI, PackedFormData.syncFriends(account, authtoken, serverSyncState, dirtyFriends)); return (Group<Friend>)doHttpRequest(request,new GroupParser(new FriendParser())); } public static void addAvatar(String imagePath, String userName) { Log.d(TAG,"add photo to Server :"+imagePath); HttpRequest request = HttpRequest.post(ADD_AVATAR_URI); request.part("image", userName, new File(imagePath)); request.part("username", userName); if (request.ok()) System.out.println("Status was updated"); } public static void uploadPhoto(String imagePath) { Log.d(TAG,"Sync photo to Server :"+imagePath); HttpRequest request = HttpRequest.post(UPLOAD_PHOTO_URI); request.part("image", new File(imagePath)); if (request.ok()) System.out.println("Status was updated"); } public static String downloadPhoto(final String photoName) { String photoPath = null; // If there is no photo, we're done if (TextUtils.isEmpty(photoName)) { return null; } try { Log.i(TAG, "Downloading photo: " + DOWNLOAD_PHOTO_URI); // Request the photo from the server, and create a bitmap // object from the stream we get back. URL url = new URL(DOWNLOAD_PHOTO_URI+photoName+"/"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); try { final BitmapFactory.Options options = new BitmapFactory.Options(); final Bitmap photo = BitmapFactory.decodeStream(connection.getInputStream(), null, options); Log.d(TAG, "file name : "+photoName); photoPath = TalkUtil.createDirAndSaveFile(photo, photoName); } finally { connection.disconnect(); } } catch (MalformedURLException muex) { // A bad URL - nothing we can really do about it here... Log.e(TAG, "Malformed avatar URL: " + DOWNLOAD_PHOTO_URI); } catch (IOException ioex) { // If we're unable to download the avatar, it's a bummer but not the // end of the world. We'll try to get it next time we sync. Log.e(TAG, "Failed to download user avatar: " + DOWNLOAD_PHOTO_URI); } return photoPath; } /** * Download the avatar image from the server. * * @param avatarUrl the URL pointing to the avatar image * @return a byte array with the raw JPEG avatar image */ public static byte[] downloadAvatar(final String avatarUrl) { // If there is no avatar, we're done if (TextUtils.isEmpty(avatarUrl)) { return null; } try { Log.i(TAG, "Downloading avatar: " + avatarUrl); // Request the avatar image from the server, and create a bitmap // object from the stream we get back. URL url = new URL(avatarUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.connect(); try { final BitmapFactory.Options options = new BitmapFactory.Options(); final Bitmap avatar = BitmapFactory.decodeStream(connection.getInputStream(), null, options); // Take the image we received from the server, whatever format it // happens to be in, and convert it to a JPEG image. Note: we're // not resizing the avatar - we assume that the image we get from // the server is a reasonable size... Log.i(TAG, "Converting avatar to JPEG"); ByteArrayOutputStream convertStream = new ByteArrayOutputStream( avatar.getWidth() * avatar.getHeight() * 4); avatar.compress(Bitmap.CompressFormat.JPEG, 95, convertStream); convertStream.flush(); convertStream.close(); // On pre-Honeycomb systems, it's important to call recycle on bitmaps avatar.recycle(); return convertStream.toByteArray(); } finally { connection.disconnect(); } } catch (MalformedURLException muex) { // A bad URL - nothing we can really do about it here... Log.e(TAG, "Malformed avatar URL: " + avatarUrl); } catch (IOException ioex) { // If we're unable to download the avatar, it's a bummer but not the // end of the world. We'll try to get it next time we sync. Log.e(TAG, "Failed to download user avatar: " + avatarUrl); } return null; } }