From e7a4672b82c02beb0d22a11eddaa6ab48fe6b8e1 Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Tue, 30 Jul 2013 14:22:57 +0530 Subject: [PATCH] Add UploadController, move upload related functionality to it - Removes StartUploadActivity and children - All 'filling in' of missing contribution data is now done in one place - Campaigns are theoretically supported Change-Id: I18bac1b672e4a0f95cdcdc467dd137177feaf8e6 --- .../campaigns/CampaignContribution.java | 8 + .../commons/upload/MultipleShareActivity.java | 110 ++++-------- .../commons/upload/ShareActivity.java | 60 ++----- .../commons/upload/StartUploadTask.java | 115 ------------- .../commons/upload/UploadController.java | 162 ++++++++++++++++++ 5 files changed, 217 insertions(+), 238 deletions(-) delete mode 100644 commons/src/main/java/org/wikimedia/commons/upload/StartUploadTask.java create mode 100644 commons/src/main/java/org/wikimedia/commons/upload/UploadController.java diff --git a/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignContribution.java b/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignContribution.java index 1566c1430..111a2f910 100644 --- a/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignContribution.java +++ b/commons/src/main/java/org/wikimedia/commons/campaigns/CampaignContribution.java @@ -1,14 +1,22 @@ package org.wikimedia.commons.campaigns; +import android.net.Uri; import org.wikimedia.commons.contributions.Contribution; import java.util.ArrayList; +import java.util.Date; public class CampaignContribution extends Contribution { private Campaign campaign; private ArrayList fieldValues; + + public CampaignContribution(Uri localUri, String remoteUri, String filename, String description, long dataLength, Date dateCreated, Date dateUploaded, String creator, String editSummary, Campaign campaign) { + super(localUri, remoteUri, filename, description, dataLength, dateCreated, dateUploaded, creator, editSummary); + this.campaign = campaign; + } + public Campaign getCampaign() { return campaign; } diff --git a/commons/src/main/java/org/wikimedia/commons/upload/MultipleShareActivity.java b/commons/src/main/java/org/wikimedia/commons/upload/MultipleShareActivity.java index 62b37482d..44e6a783a 100644 --- a/commons/src/main/java/org/wikimedia/commons/upload/MultipleShareActivity.java +++ b/commons/src/main/java/org/wikimedia/commons/upload/MultipleShareActivity.java @@ -38,6 +38,7 @@ public class MultipleShareActivity private MediaDetailPagerFragment mediaDetails; private CategorizationFragment categorizationFragment; + private UploadController uploadController; public MultipleShareActivity() { super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE); @@ -67,8 +68,33 @@ public class MultipleShareActivity } public void OnMultipleUploadInitiated() { - StartMultipleUploadTask startUploads = new StartMultipleUploadTask(); - Utils.executeAsyncTask(startUploads); + final ProgressDialog dialog = new ProgressDialog(MultipleShareActivity.this); + dialog.setIndeterminate(false); + dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + dialog.setMax(photosList.size()); + dialog.setTitle(getResources().getQuantityString(R.plurals.starting_multiple_uploads, photosList.size(), photosList.size())); + dialog.show(); + + for(int i = 0; i < photosList.size(); i++) { + Contribution up = photosList.get(i); + final int uploadCount = i + 1; // Goddamn Java + + uploadController.startUpload(up, new UploadController.ContributionUploadProgress() { + public void onUploadStarted(Contribution contribution) { + dialog.setProgress(uploadCount); + if(uploadCount == photosList.size()) { + dialog.dismiss(); + Toast startingToast = Toast.makeText(getApplicationContext(), R.string.uploading_started, Toast.LENGTH_LONG); + startingToast.show(); + } + } + + public boolean isJavaAPieceOfShit() { + return true; + } + }); + } + uploadsList.setImageOnlyMode(true); categorizationFragment = (CategorizationFragment) this.getSupportFragmentManager().findFragmentByTag("categorization"); @@ -112,75 +138,6 @@ public class MultipleShareActivity finish(); } - private class StartMultipleUploadTask extends AsyncTask { - - ProgressDialog dialog; - - @Override - protected Void doInBackground(Void... voids) { - for(int i = 0; i < photosList.size(); i++) { - Contribution up = photosList.get(i); - String curMimetype = (String)up.getTag("mimeType"); - if(curMimetype == null || TextUtils.isEmpty(curMimetype) || curMimetype.endsWith("*")) { - String mimeType = getContentResolver().getType(up.getLocalUri()); - if(mimeType != null) { - up.setTag("mimeType", mimeType); - } - } - - StartUploadTask startUploadTask = new StartUploadTask(MultipleShareActivity.this, uploadService, up); - try { - Utils.executeAsyncTask(startUploadTask); - startUploadTask.get(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } catch (ExecutionException e) { - throw new RuntimeException(e); - } - this.publishProgress(i); - - } - return null; - } - - @Override - protected void onPreExecute() { - super.onPreExecute(); - dialog = new ProgressDialog(MultipleShareActivity.this); - dialog.setIndeterminate(false); - dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - dialog.setMax(photosList.size()); - dialog.setTitle(getResources().getQuantityString(R.plurals.starting_multiple_uploads, photosList.size(), photosList.size())); - dialog.show(); - } - - @Override - protected void onProgressUpdate(Integer... values) { - dialog.setProgress(values[0]); - } - - @Override - protected void onPostExecute(Void aVoid) { - dialog.dismiss(); - Toast startingToast = Toast.makeText(getApplicationContext(), R.string.uploading_started, Toast.LENGTH_LONG); - startingToast.show(); - } - } - - private UploadService uploadService; - private boolean isUploadServiceConnected; - private ServiceConnection uploadServiceConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName componentName, IBinder binder) { - uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService(); - isUploadServiceConnected = true; - } - - public void onServiceDisconnected(ComponentName componentName) { - // this should never happen - throw new RuntimeException("UploadService died but the rest of the process did not!"); - } - }; - @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { @@ -196,6 +153,7 @@ public class MultipleShareActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + uploadController = new UploadController(this); setContentView(R.layout.activity_multiple_uploads); app = (CommonsApplication)this.getApplicationContext(); @@ -213,9 +171,7 @@ public class MultipleShareActivity @Override protected void onDestroy() { super.onDestroy(); - if(isUploadServiceConnected) { - unbindService(uploadServiceConnection); - } + uploadController.cleanup(); } private void showDetail(int i) { @@ -267,11 +223,7 @@ public class MultipleShareActivity .commit(); } setTitle(getResources().getQuantityString(R.plurals.multiple_uploads_title, photosList.size(), photosList.size())); - - Intent uploadServiceIntent = new Intent(getApplicationContext(), UploadService.class); - uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); - startService(uploadServiceIntent); - bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); + uploadController.prepareService(); } } diff --git a/commons/src/main/java/org/wikimedia/commons/upload/ShareActivity.java b/commons/src/main/java/org/wikimedia/commons/upload/ShareActivity.java index 0fc955a4c..4010ad3cf 100644 --- a/commons/src/main/java/org/wikimedia/commons/upload/ShareActivity.java +++ b/commons/src/main/java/org/wikimedia/commons/upload/ShareActivity.java @@ -44,23 +44,21 @@ public class ShareActivity private ImageView backgroundImageView; - private UploadService uploadService; - private boolean isUploadServiceConnected; - private ServiceConnection uploadServiceConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName componentName, IBinder binder) { - uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService(); - isUploadServiceConnected = true; - } - - public void onServiceDisconnected(ComponentName componentName) { - // this should never happen - throw new RuntimeException("UploadService died but the rest of the process did not!"); - } - }; + private UploadController uploadController; public void uploadActionInitiated(String title, String description) { - StartUploadTask task = new SingleStartUploadTask(ShareActivity.this, uploadService, title, mediaUri, description, mimeType, source); - task.execute(); + Toast startingToast = Toast.makeText(getApplicationContext(), R.string.uploading_started, Toast.LENGTH_LONG); + startingToast.show(); + uploadController.startUpload(title, mediaUri, description, mimeType, source, new UploadController.ContributionUploadProgress() { + public void onUploadStarted(Contribution contribution) { + ShareActivity.this.contribution = contribution; + showPostUpload(); + } + + public boolean isJavaAPieceOfShit() { + return true; + } + }); } private void showPostUpload() { @@ -96,26 +94,6 @@ public class ShareActivity finish(); } - private class SingleStartUploadTask extends StartUploadTask { - - private SingleStartUploadTask(Activity context, UploadService uploadService, String rawTitle, Uri mediaUri, String description, String mimeType, String source) { - super(context, uploadService, rawTitle, mediaUri, description, mimeType, source); - } - - @Override - protected void onPreExecute() { - Toast startingToast = Toast.makeText(getApplicationContext(), R.string.uploading_started, Toast.LENGTH_LONG); - startingToast.show(); - } - - @Override - protected void onPostExecute(Contribution contribution) { - super.onPostExecute(contribution); - ShareActivity.this.contribution = contribution; - showPostUpload(); - } - } - @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -161,11 +139,7 @@ public class ShareActivity .commit(); } - - Intent uploadServiceIntent = new Intent(getApplicationContext(), UploadService.class); - uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); - startService(uploadServiceIntent); - bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); + uploadController.prepareService(); } @Override @@ -179,7 +153,7 @@ public class ShareActivity @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + uploadController = new UploadController(this); setContentView(R.layout.activity_share); app = (CommonsApplication)this.getApplicationContext(); @@ -211,9 +185,7 @@ public class ShareActivity @Override protected void onDestroy() { super.onDestroy(); - if(isUploadServiceConnected) { - unbindService(uploadServiceConnection); - } + uploadController.cleanup(); } @Override diff --git a/commons/src/main/java/org/wikimedia/commons/upload/StartUploadTask.java b/commons/src/main/java/org/wikimedia/commons/upload/StartUploadTask.java deleted file mode 100644 index 113eec975..000000000 --- a/commons/src/main/java/org/wikimedia/commons/upload/StartUploadTask.java +++ /dev/null @@ -1,115 +0,0 @@ -package org.wikimedia.commons.upload; - -import android.app.*; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.net.*; -import android.os.*; -import android.preference.PreferenceManager; -import android.provider.*; -import android.text.TextUtils; -import android.webkit.MimeTypeMap; - -import java.io.*; -import java.util.*; - -import org.wikimedia.commons.CommonsApplication; -import org.wikimedia.commons.Prefs; -import org.wikimedia.commons.Utils; -import org.wikimedia.commons.contributions.*; - -public class StartUploadTask extends AsyncTask { - - private Activity context; - private UploadService uploadService; - - private Contribution contribution; - - private CommonsApplication app; - - public StartUploadTask(Activity context, UploadService uploadService, String rawTitle, Uri mediaUri, String description, String mimeType, String source) { - - this.context = context; - this.uploadService = uploadService; - - app = (CommonsApplication)context.getApplicationContext(); - - String title = rawTitle; - String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); - // People are used to ".jpg" more than ".jpeg" which the system gives us. - if (extension != null && extension.toLowerCase().equals("jpeg")) { - extension = "jpg"; - } - if(extension != null && !title.toLowerCase().endsWith(extension.toLowerCase())) { - title += "." + extension; - } - - contribution = new Contribution(mediaUri, null, title, description, -1, null, null, app.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY); - contribution.setTag("mimeType", mimeType); - contribution.setSource(source); - - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - String license = prefs.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA); - contribution.setLicense(license); - } - - public StartUploadTask(Activity context, UploadService uploadService, Contribution contribution) { - this.context = context; - this.uploadService = uploadService; - this.contribution = contribution; - - // Set things that have not been set! - if(contribution.getLicense() == null) { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - String license = prefs.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA); - contribution.setLicense(license); - } - - app = (CommonsApplication)context.getApplicationContext(); - } - - - @Override - protected Contribution doInBackground(Void... voids) { - String title = contribution.getFilename(); - - long length; - try { - if(contribution.getDataLength() <= 0) { - length = context.getContentResolver().openAssetFileDescriptor(contribution.getLocalUri(), "r").getLength(); - if(length == -1) { - // Let us find out the long way! - length = Utils.countBytes(context.getContentResolver().openInputStream(contribution.getLocalUri())); - } - contribution.setDataLength(length); - } - } catch(IOException e) { - throw new RuntimeException(e); - } - - if(TextUtils.isEmpty(contribution.getCreator())) { - contribution.setCreator(app.getCurrentAccount().name); - } - - if(contribution.getDescription() == null) { - contribution.setDescription(""); - } - - String mimeType = (String)contribution.getTag("mimeType"); - if(mimeType.startsWith("image/") && contribution.getDateCreated() == null) { - Cursor cursor = context.getContentResolver().query(contribution.getLocalUri(), - new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null); - if(cursor != null && cursor.getCount() != 0) { - cursor.moveToFirst(); - contribution.setDateCreated(new Date(cursor.getLong(0))); - } // FIXME: Alternate way of setting dateCreated if this data is not found - } - - return contribution; - } - - @Override - protected void onPostExecute(Contribution contribution) { - uploadService.queue(UploadService.ACTION_UPLOAD_FILE, contribution); - } -} \ No newline at end of file diff --git a/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java b/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java new file mode 100644 index 000000000..84f654951 --- /dev/null +++ b/commons/src/main/java/org/wikimedia/commons/upload/UploadController.java @@ -0,0 +1,162 @@ +package org.wikimedia.commons.upload; + +import android.app.Activity; +import android.content.*; +import android.database.Cursor; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.IBinder; +import android.preference.PreferenceManager; +import android.provider.MediaStore; +import android.text.TextUtils; +import android.webkit.MimeTypeMap; +import org.wikimedia.commons.CommonsApplication; +import org.wikimedia.commons.HandlerService; +import org.wikimedia.commons.Prefs; +import org.wikimedia.commons.Utils; +import org.wikimedia.commons.campaigns.Campaign; +import org.wikimedia.commons.campaigns.CampaignContribution; +import org.wikimedia.commons.contributions.Contribution; + +import java.io.IOException; +import java.util.Date; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; + +public class UploadController { + private UploadService uploadService; + + private final Activity activity; + final CommonsApplication app; + + public interface ContributionUploadProgress { + void onUploadStarted(Contribution contribution); + boolean isJavaAPieceOfShit(); + } + + public UploadController(Activity activity) { + this.activity = activity; + app = (CommonsApplication)activity.getApplicationContext(); + } + + private boolean isUploadServiceConnected; + private ServiceConnection uploadServiceConnection = new ServiceConnection() { + public void onServiceConnected(ComponentName componentName, IBinder binder) { + uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService(); + isUploadServiceConnected = true; + } + + public void onServiceDisconnected(ComponentName componentName) { + // this should never happen + throw new RuntimeException("UploadService died but the rest of the process did not!"); + } + }; + + public void prepareService() { + Intent uploadServiceIntent = new Intent(activity.getApplicationContext(), UploadService.class); + uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE); + activity.startService(uploadServiceIntent); + activity.bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE); + } + + public void cleanup() { + if(isUploadServiceConnected) { + activity.unbindService(uploadServiceConnection); + } + } + + /* The JavaScript is Leaking!*/ + public void startUpload(String rawTitle, Uri mediaUri, String description, String mimeType, String source, ContributionUploadProgress onComplete) { + startUpload(rawTitle, mediaUri, description, mimeType, source, null, onComplete); + } + + public void startUpload(String rawTitle, Uri mediaUri, String description, String mimeType, String source, Campaign campaign, ContributionUploadProgress onComplete) { + Contribution contribution; + + String title = rawTitle; + String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType); + // People are used to ".jpg" more than ".jpeg" which the system gives us. + if (extension != null && extension.toLowerCase().equals("jpeg")) { + extension = "jpg"; + } + if(extension != null && !title.toLowerCase().endsWith(extension.toLowerCase())) { + title += "." + extension; + } + + if(campaign == null) { + contribution = new Contribution(mediaUri, null, title, description, -1, null, null, app.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY); + } else { + contribution = new CampaignContribution(mediaUri, null, title, description, -1, null, null, app.getCurrentAccount().name, CommonsApplication.DEFAULT_EDIT_SUMMARY, campaign); + } + contribution.setTag("mimeType", mimeType); + contribution.setSource(source); + + startUpload(contribution, onComplete); + } + + public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); + + if(TextUtils.isEmpty(contribution.getCreator())) { + contribution.setCreator(app.getCurrentAccount().name); + } + + if(contribution.getDescription() == null) { + contribution.setDescription(""); + } + + String license = prefs.getString(Prefs.DEFAULT_LICENSE, Prefs.Licenses.CC_BY_SA); + contribution.setLicense(license); + + Utils.executeAsyncTask(new AsyncTask() { + + // Fills up missing information about Contributions + // Only does things that involve some form of IO + // Runs in background thread + @Override + protected Contribution doInBackground(Void... voids /* stare into you */) { + long length; + try { + if(contribution.getDataLength() <= 0) { + length = activity.getContentResolver().openAssetFileDescriptor(contribution.getLocalUri(), "r").getLength(); + if(length == -1) { + // Let us find out the long way! + length = Utils.countBytes(activity.getContentResolver().openInputStream(contribution.getLocalUri())); + } + contribution.setDataLength(length); + } + } catch(IOException e) { + throw new RuntimeException(e); + } + + String mimeType = (String)contribution.getTag("mimeType"); + if(mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) { + mimeType = activity.getContentResolver().getType(contribution.getLocalUri()); + if(mimeType != null) { + contribution.setTag("mimeType", mimeType); + } + } + + if(mimeType.startsWith("image/") && contribution.getDateCreated() == null) { + Cursor cursor = activity.getContentResolver().query(contribution.getLocalUri(), + new String[]{MediaStore.Images.ImageColumns.DATE_TAKEN}, null, null, null); + if(cursor != null && cursor.getCount() != 0) { + cursor.moveToFirst(); + contribution.setDateCreated(new Date(cursor.getLong(0))); + } // FIXME: Alternate way of setting dateCreated if this data is not found + } + + return contribution; + } + + @Override + protected void onPostExecute(Contribution contribution) { + super.onPostExecute(contribution); + uploadService.queue(UploadService.ACTION_UPLOAD_FILE, contribution); + assert onComplete.isJavaAPieceOfShit(); + onComplete.onUploadStarted(contribution); + } + }); + } + +}