/**
* galaxy inc.
* meetup client for android
*/
package com.galaxy.meetup.client.android.iu;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.BufferedHttpEntity;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Build;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
import android.util.Xml;
import com.android.gallery3d.common.Fingerprint;
import com.galaxy.meetup.client.util.EsLog;
import com.galaxy.picasa.HttpUtils;
import com.galaxy.picasa.store.MetricsUtils;
/**
*
* @author sihai
*
*/
public class GDataUploader implements Uploader {
private static final Pattern RE_RANGE_HEADER = Pattern.compile("bytes=(\\d+)-(\\d+)");
private static String sUserAgent;
private Authorizer mAuthorizer;
private Context mContext;
private HttpClient mHttpClient;
private Uploader.UploadProgressListener mListener;
private UploadTaskEntry mUploadTask;
private final UploadsDatabaseHelper mUploadsDbHelper;
GDataUploader(Context context)
{
mContext = context;
mHttpClient = HttpUtils.createHttpClient(getUserAgent(context));
mUploadsDbHelper = UploadsDatabaseHelper.getInstance(context);
mAuthorizer = new Authorizer(context);
}
private HttpResponse executeWithAuthRetry(HttpUriRequest httpurirequest, String s, String s1)
throws ClientProtocolException, IOException, Uploader.UnauthorizedException
{
long l = SystemClock.elapsedRealtime();
HttpResponse httpresponse = mHttpClient.execute(httpurirequest);
MetricsUtils.incrementNetworkOpDuration(SystemClock.elapsedRealtime() - l);
int i = httpresponse.getStatusLine().getStatusCode();
if(i == 401 || i == 403)
{
String s2;
try
{
s2 = mAuthorizer.getFreshAuthToken(s, "lh2", s1);
if(s2 == null)
throw new Uploader.UnauthorizedException("null auth token");
}
catch(OperationCanceledException operationcanceledexception)
{
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", "authentication canceled", operationcanceledexception);
throw new Uploader.UnauthorizedException(operationcanceledexception);
}
catch(IOException ioexception)
{
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", "authentication failed", ioexception);
throw ioexception;
}
catch(AuthenticatorException authenticatorexception)
{
if(EsLog.isLoggable("iu.UploadsManager", 5))
Log.w("iu.UploadsManager", authenticatorexception);
throw new Uploader.UnauthorizedException(authenticatorexception);
}
httpurirequest.setHeader("Authorization", (new StringBuilder("GoogleLogin auth=")).append(s2).toString());
if(EsLog.isLoggable("iu.UploadsManager", 3))
Log.d("iu.UploadsManager", "executeWithAuthRetry: attempt #2");
long l1 = SystemClock.elapsedRealtime();
httpresponse = mHttpClient.execute(httpurirequest);
MetricsUtils.incrementNetworkOpDuration(SystemClock.elapsedRealtime() - l1);
}
return httpresponse;
}
private String getAuthToken(String s)
throws IOException, Uploader.UnauthorizedException
{
String s1;
try
{
s1 = mAuthorizer.getAuthToken(s, "lh2");
}
catch(OperationCanceledException operationcanceledexception)
{
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", "authentication canceled", operationcanceledexception);
throw new Uploader.UnauthorizedException(operationcanceledexception);
}
catch(IOException ioexception)
{
if(EsLog.isLoggable("iu.UploadsManager", 4))
Log.i("iu.UploadsManager", "authentication failed", ioexception);
throw ioexception;
}
catch(AuthenticatorException authenticatorexception)
{
if(EsLog.isLoggable("iu.UploadsManager", 5))
Log.w("iu.UploadsManager", authenticatorexception);
throw new Uploader.UnauthorizedException(authenticatorexception);
}
return s1;
}
private static HttpEntity getEntity(HttpResponse httpresponse)
throws IOException
{
BufferedHttpEntity bufferedhttpentity = new BufferedHttpEntity(httpresponse.getEntity());
if(bufferedhttpentity.getContentLength() == 0L)
{
safeConsumeContent(bufferedhttpentity);
bufferedhttpentity = null;
}
return bufferedhttpentity;
}
private MediaRecordEntry getMediaRecordEntry(UploadTaskEntry uploadtaskentry, GDataResponse gdataresponse)
throws Uploader.UploadException
{
MediaRecordEntry mediarecordentry = MediaRecordEntry.fromId(mUploadsDbHelper.getReadableDatabase(), uploadtaskentry.getMediaRecordId());
if(mediarecordentry == null)
{
throw new Uploader.UploadException((new StringBuilder("could not find the media record for the uploaded task; ")).append(uploadtaskentry).toString());
} else
{
mediarecordentry.setUploadId(gdataresponse.photoId).setUploadUrl(gdataresponse.photoUrl).setUploadTime(gdataresponse.timestamp).setBytesUploaded(uploadtaskentry.getBytesUploaded()).setState(300);
return mediarecordentry;
}
}
private static String getUserAgent(Context context)
{
if(sUserAgent == null)
{
PackageInfo packageinfo;
Object aobj[];
try
{
packageinfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
}
catch(android.content.pm.PackageManager.NameNotFoundException namenotfoundexception)
{
throw new IllegalStateException("getPackageInfo failed");
}
aobj = new Object[10];
aobj[0] = packageinfo.packageName;
aobj[1] = packageinfo.versionName;
aobj[2] = Build.BRAND;
aobj[3] = Build.DEVICE;
aobj[4] = Build.MODEL;
aobj[5] = Build.ID;
aobj[6] = android.os.Build.VERSION.SDK;
aobj[7] = android.os.Build.VERSION.RELEASE;
aobj[8] = android.os.Build.VERSION.INCREMENTAL;
aobj[9] = Integer.valueOf(1);
sUserAgent = String.format("%s/%s; %s/%s/%s/%s; %s/%s/%s/%d", aobj);
}
return sUserAgent;
}
private static boolean isIncompeteStatusCode(int i)
{
boolean flag;
if(i == 308)
flag = true;
else
flag = false;
return flag;
}
private static boolean isSuccessStatusCode(int i)
{
boolean flag;
if(i == 200 || i == 201)
flag = true;
else
flag = false;
return flag;
}
private static HashMap parseHeaders(String s)
{
HashMap hashmap = new HashMap();
String as[] = s.split("\r\n");
int i = as.length;
for(int j = 0; j < i; j++)
{
String as1[] = as[j].split(":");
if(as1.length == 2)
hashmap.put(as1[0], as1[1]);
}
return hashmap;
}
private static GDataQuota parseQuotaResponse(HttpEntity httpentity) {
// TODO
return null;
}
private static long parseRangeHeaderEndByte(String s) {
if(s == null) {
return -1;
} else {
Matcher matcher = RE_RANGE_HEADER.matcher(s);
if(matcher.find()) {
return 1L + Long.parseLong(matcher.group(2));
}
return -1L;
}
}
private static GDataResponse parseResult(HttpEntity httpentity) throws SAXException, IOException, Uploader.UploadException {
InputStream inputstream = null;
if(httpentity == null)
throw new Uploader.UploadException("null HttpEntity in response");
GDataResponse gdataresponse = new GDataResponse();
try {
inputstream = httpentity.getContent();
Xml.parse(inputstream, android.util.Xml.Encoding.UTF_8, gdataresponse);
gdataresponse.validateResult();
return gdataresponse;
} finally {
if(null != inputstream) {
inputstream.close();
}
}
}
private void resetUpload() {
mUploadTask.setUploadUrl(null);
mUploadTask.setBytesUploaded(0L);
}
private MediaRecordEntry resume(InputStream inputstream, String s, String s1)
throws ClientProtocolException, IOException, Uploader.PicasaQuotaException, SAXException, Uploader.UploadException, Uploader.LocalIoException, Uploader.MediaFileChangedException, Uploader.RestartException, Uploader.UnauthorizedException
{
// TODO
return null;
}
private static void safeConsumeContent(HttpEntity httpentity) {
if(httpentity == null)
return;
try {
httpentity.consumeContent();
} catch (IOException e) {
//
}
}
private MediaRecordEntry start(InputStream inputstream, Uri uri, String s, String s1, String s2)
throws ClientProtocolException, IOException, Uploader.PicasaQuotaException, SAXException, Uploader.UploadException, Uploader.MediaFileChangedException, Uploader.UnauthorizedException, Uploader.RestartException, Uploader.LocalIoException
{
// TODO
return null;
}
private static void throwIfQuotaError(GDataResponse gdataresponse)
throws Uploader.PicasaQuotaException
{
if(gdataresponse != null && "LimitQuota".equals(gdataresponse.errorCode))
throw new Uploader.PicasaQuotaException(gdataresponse.errorCode);
else
return;
}
private MediaRecordEntry uploadChunks(InputStream inputstream, String s, String s1)
throws ClientProtocolException, IOException, Uploader.PicasaQuotaException, SAXException, Uploader.UploadException, Uploader.MediaFileChangedException, Uploader.RestartException, Uploader.LocalIoException, Uploader.UnauthorizedException
{
// TODO
return null;
}
public final void close()
{
mHttpClient = null;
mAuthorizer = null;
}
final GDataQuota getQuota(String s)
{
// TODO
return null;
}
public final MediaRecordEntry upload(UploadTaskEntry uploadtaskentry, Uploader.UploadProgressListener uploadprogresslistener)
throws IOException, Uploader.UploadException, Uploader.RestartException, Uploader.LocalIoException, Uploader.MediaFileChangedException, Uploader.MediaFileUnavailableException, Uploader.UnauthorizedException, Uploader.PicasaQuotaException
{
// TODO
return null;
}
public static final class GDataQuota {
public final String toString() {
return (new StringBuilder("[GDataIUStats; limit: "))
.append(quotaLimit).append(", used: ").append(quotaUsed)
.append(", low quota? ").append(disableFullRes).append("]")
.toString();
}
boolean disableFullRes;
long quotaLimit;
long quotaUsed;
public GDataQuota() {
quotaLimit = -1L;
quotaUsed = -1L;
disableFullRes = false;
}
}
private static final class GDataResponse extends DefaultHandler {
String errorCode;
Fingerprint fingerprint;
GDataQuota iuStats;
private HashMap mMap;
private List<String> mStreamIdList;
private StringBuilder mText;
long photoId;
String photoUrl;
long timestamp;
GDataResponse()
{
mMap = new HashMap();
mStreamIdList = new ArrayList<String>();
}
private static GDataQuota getIUStatsAttrs(Attributes attributes)
{
GDataQuota gdataquota = new GDataQuota();
int i = attributes.getLength();
int j = 0;
while(j < i)
{
String s = attributes.getQName(j);
if("quotaLimitMB".contentEquals(s))
try
{
gdataquota.quotaLimit = Long.parseLong(attributes.getValue(j));
}
catch(NumberFormatException numberformatexception1) { }
else
if("quotaUsedMB".contentEquals(s))
try
{
gdataquota.quotaUsed = Long.parseLong(attributes.getValue(j));
}
catch(NumberFormatException numberformatexception) { }
else
if("disableFullRes".contentEquals(s))
gdataquota.disableFullRes = Boolean.parseBoolean(attributes.getValue(j));
j++;
}
return gdataquota;
}
public final void characters(char ac[], int i, int j)
{
if(mText != null)
mText.append(ac, i, j);
}
public final void endElement(String s, String s1, String s2)
{
if("gphoto:streamId".contentEquals(s2) && mText.length() > 0)
mStreamIdList.add(mText.toString());
mText = null;
}
public final void startDocument()
{
mMap.clear();
mMap.put("code", new StringBuilder());
mMap.put("gphoto:id", new StringBuilder());
mMap.put("gphoto:size", new StringBuilder());
mMap.put("gphoto:streamId", new StringBuilder());
mMap.put("gphoto:timestamp", new StringBuilder());
photoUrl = "";
mStreamIdList.clear();
}
public final void startElement(String s, String s1, String s2, Attributes attributes) {
mText = (StringBuilder)mMap.get(s2);
if(mText != null)
return;
if(!"media:content".contentEquals(s2)) {
if("gphoto:iuStats".contentEquals(s2))
iuStats = getIUStatsAttrs(attributes);
} else {
// TODO
}
}
public final void validateResult() throws Uploader.UploadException {
errorCode = ((StringBuilder)mMap.get("code")).toString();
try
{
photoId = Long.parseLong(((StringBuilder)mMap.get("gphoto:id")).toString());
}
catch(NumberFormatException numberformatexception)
{
throw new Uploader.UploadException((new StringBuilder("error parsing photo ID: ")).append(mMap.get("gphoto:id")).toString());
}
try
{
timestamp = Long.parseLong(((StringBuilder)mMap.get("gphoto:timestamp")).toString());
}
catch(NumberFormatException numberformatexception1)
{
throw new Uploader.UploadException((new StringBuilder("error parsing timestamp: ")).append(mMap.get("gphoto:timestamp")).toString());
}
if(TextUtils.isEmpty(photoUrl))
throw new Uploader.UploadException("photo URL missing");
fingerprint = Fingerprint.extractFingerprint(mStreamIdList);
if(fingerprint == null)
throw new Uploader.UploadException((new StringBuilder("fingerprint missing: ")).append(mStreamIdList).toString());
else
return;
}
}
}