mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Merge branch 'campaigns'
Conflicts: commons/res/values/strings.xml commons/src/main/java/org/wikimedia/commons/Media.java Change-Id: Ib8c74cbf88630f11b3fbfee903800e7acf7b2fd4
This commit is contained in:
commit
064dbb0df6
32 changed files with 1374 additions and 462 deletions
|
|
@ -82,6 +82,15 @@
|
|||
android:label="@string/title_activity_settings"
|
||||
/>
|
||||
<activity android:name=".AboutActivity" android:label="@string/title_activity_about"/>
|
||||
<activity android:name=".campaigns.CampaignActivity" android:label="Campaigns"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".upload.UploadService" >
|
||||
</service>
|
||||
<service
|
||||
|
|
@ -96,6 +105,17 @@
|
|||
android:name="android.accounts.AccountAuthenticator"
|
||||
android:resource="@xml/authenticator" />
|
||||
</service>
|
||||
<service
|
||||
android:name=".campaigns.CampaignsSyncService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action
|
||||
android:name="android.content.SyncAdapter" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.content.SyncAdapter"
|
||||
android:resource="@xml/campaigns_sync_adapter" />
|
||||
</service>
|
||||
<service
|
||||
android:name=".contributions.ContributionsSyncService"
|
||||
android:exported="true">
|
||||
|
|
@ -127,6 +147,13 @@
|
|||
android:authorities="org.wikimedia.commons.contributions.contentprovider"
|
||||
android:exported="false">
|
||||
</provider>
|
||||
<provider
|
||||
android:name=".campaigns.CampaignsContentProvider"
|
||||
android:label="@string/provider_campaigns"
|
||||
android:syncable="true"
|
||||
android:authorities="org.wikimedia.commons.campaigns.contentprovider"
|
||||
android:exported="false">
|
||||
</provider>
|
||||
<provider
|
||||
android:name=".modifications.ModificationsContentProvider"
|
||||
android:label="@string/provider_modifications"
|
||||
|
|
|
|||
|
|
@ -24,14 +24,8 @@
|
|||
<dependency>
|
||||
<groupId>com.actionbarsherlock</groupId>
|
||||
<artifactId>actionbarsherlock</artifactId>
|
||||
<version>4.2.0</version>
|
||||
<version>4.4.0</version>
|
||||
<type>apklib</type>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>support-v4</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>android</groupId>
|
||||
|
|
|
|||
13
commons/res/layout/activity_campaigns.xml
Normal file
13
commons/res/layout/activity_campaigns.xml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/campaignsList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
</FrameLayout>
|
||||
18
commons/res/layout/fragment_campaigns.xml
Normal file
18
commons/res/layout/fragment_campaigns.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<GridView android:id="@+id/campaignsList"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent"
|
||||
android:stretchMode="columnWidth"
|
||||
android:columnWidth="240dp"
|
||||
android:numColumns="auto_fit"
|
||||
android:listSelector="@null"
|
||||
android:fadingEdge="none"
|
||||
android:fastScrollEnabled="false"
|
||||
/>
|
||||
</LinearLayout>
|
||||
12
commons/res/layout/layout_campaign_item.xml
Normal file
12
commons/res/layout/layout_campaign_item.xml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:id="@+id/campaignItemName"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
|
@ -138,4 +138,5 @@
|
|||
<string name="detail_panel_cats_label">Categories</string>
|
||||
<string name="detail_panel_cats_loading">Loading...</string>
|
||||
<string name="detail_panel_cats_none">None selected</string>
|
||||
<string name="provider_campaigns">Campaigns</string>
|
||||
</resources>
|
||||
|
|
|
|||
9
commons/res/xml/campaigns_sync_adapter.xml
Normal file
9
commons/res/xml/campaigns_sync_adapter.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:contentAuthority="org.wikimedia.commons.campaigns.contentprovider"
|
||||
android:accountType="org.wikimedia.commons"
|
||||
android:supportsUploading="false"
|
||||
android:userVisible="true"
|
||||
android:isAlwaysSyncable="true"
|
||||
/>
|
||||
|
|
@ -59,6 +59,9 @@ public class Media implements Parcelable {
|
|||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
if(imageUrl == null) {
|
||||
imageUrl = Utils.makeThumbBaseUrl(this.getFilename());
|
||||
}
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +106,7 @@ public class Media implements Parcelable {
|
|||
}
|
||||
|
||||
public String getThumbnailUrl(int width) {
|
||||
return Utils.makeThumbUrl(imageUrl, filename, width);
|
||||
return Utils.makeThumbUrl(getImageUrl(), getFilename(), width);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
|
|
@ -182,6 +185,10 @@ public class Media implements Parcelable {
|
|||
}
|
||||
}
|
||||
|
||||
public Media(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public Media(Uri localUri, String imageUrl, String filename, String description, long dataLength, Date dateCreated, Date dateUploaded, String creator) {
|
||||
this();
|
||||
this.localUri = localUri;
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ public class MediaWikiImageView extends ImageView {
|
|||
|
||||
if (response.getBitmap() != null) {
|
||||
setImageBitmap(response.getBitmap());
|
||||
if(tryOriginal && mMedia instanceof Contribution && response.getBitmap().getWidth() > mMedia.getWidth() || response.getBitmap().getHeight() > mMedia.getHeight()) {
|
||||
if(tryOriginal && mMedia instanceof Contribution && (response.getBitmap().getWidth() > mMedia.getWidth() || response.getBitmap().getHeight() > mMedia.getHeight())) {
|
||||
// If there is no width information for this image, save it. This speeds up image loading massively for smaller images
|
||||
mMedia.setHeight(response.getBitmap().getHeight());
|
||||
mMedia.setWidth(response.getBitmap().getWidth());
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package org.wikimedia.commons;
|
|||
|
||||
import android.net.Uri;
|
||||
import android.os.*;
|
||||
import android.util.Log;
|
||||
import com.nostra13.universalimageloader.core.*;
|
||||
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
|
||||
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import android.support.v4.app.NavUtils;
|
|||
|
||||
import org.wikimedia.commons.*;
|
||||
import org.wikimedia.commons.EventLog;
|
||||
import org.wikimedia.commons.campaigns.CampaignsContentProvider;
|
||||
import org.wikimedia.commons.contributions.*;
|
||||
import org.wikimedia.commons.modifications.ModificationsContentProvider;
|
||||
|
||||
|
|
@ -67,6 +68,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
|||
// FIXME: If the user turns it off, it shouldn't be auto turned back on
|
||||
ContentResolver.setSyncAutomatically(account, ContributionsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(account, ModificationsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
ContentResolver.setSyncAutomatically(account, CampaignsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
context.finish();
|
||||
} else {
|
||||
int response;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,190 @@
|
|||
package org.wikimedia.commons.campaigns;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
// FIXME: Implement Parcelable
|
||||
public class Campaign implements Serializable {
|
||||
private boolean enabled;
|
||||
|
||||
private String autoAddWikitext;
|
||||
private ArrayList<String> autoAddCategories;
|
||||
|
||||
private String name;
|
||||
private String ownWorkLicenseDefault;
|
||||
|
||||
private String defaultDescription;
|
||||
|
||||
private JSONObject config;
|
||||
private String body;
|
||||
private boolean isParsed;
|
||||
private String trackingCategory;
|
||||
private String description;
|
||||
private String title;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public String getAutoAddWikitext() {
|
||||
if(!this.isParsed) {
|
||||
this.parseConfig();
|
||||
}
|
||||
return autoAddWikitext;
|
||||
}
|
||||
|
||||
public ArrayList<String> getAutoAddCategories() {
|
||||
if(!this.isParsed) {
|
||||
this.parseConfig();
|
||||
}
|
||||
return autoAddCategories;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getOwnWorkLicenseDefault() {
|
||||
if(!this.isParsed) {
|
||||
this.parseConfig();
|
||||
}
|
||||
return ownWorkLicenseDefault;
|
||||
}
|
||||
|
||||
public String getDefaultDescription() {
|
||||
if(!this.isParsed) {
|
||||
this.parseConfig();
|
||||
}
|
||||
return defaultDescription;
|
||||
}
|
||||
|
||||
public JSONObject getConfig() {
|
||||
if(!this.isParsed) {
|
||||
this.parseConfig();
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
private void parseConfig() {
|
||||
try {
|
||||
this.config = new JSONObject(body);
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e); // because what else are you gonna do?
|
||||
}
|
||||
if(config.has("autoAdd")) {
|
||||
this.autoAddWikitext = config.optJSONObject("autoAdd").optString("wikitext", null);
|
||||
if(config.optJSONObject("autoAdd").has("categories")) {
|
||||
this.autoAddCategories = new ArrayList<String>();
|
||||
JSONArray catsArray = config.optJSONObject("autoAdd").optJSONArray("categories");
|
||||
for(int i=0; i < catsArray.length(); i++) {
|
||||
autoAddCategories.add(catsArray.optString(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
this.title = config.optString("title", name);
|
||||
this.description = config.optString("description", "");
|
||||
this.isParsed = true;
|
||||
}
|
||||
private Campaign(String name, String body, String trackingCategory) {
|
||||
this.name = name;
|
||||
this.body = body;
|
||||
this.trackingCategory = trackingCategory;
|
||||
}
|
||||
|
||||
public ContentValues toContentValues() {
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(Table.COLUMN_NAME, this.getName());
|
||||
cv.put(Table.COLUMN_ENABLED, this.isEnabled() ? 1 : 0);
|
||||
cv.put(Table.COLUMN_TITLE, this.getTitle());
|
||||
cv.put(Table.COLUMN_DESCRIPTION, this.getDescription());
|
||||
cv.put(Table.COLUMN_TRACKING_CATEGORY, this.getTrackingCategory());
|
||||
cv.put(Table.COLUMN_BODY, this.body);
|
||||
return cv;
|
||||
}
|
||||
|
||||
public static Campaign parse(String name, String body, String trackingCategory) {
|
||||
Campaign c = new Campaign(name, body, trackingCategory);
|
||||
c.parseConfig();
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Campaign fromCursor(Cursor cursor) {
|
||||
String name = cursor.getString(1);
|
||||
Boolean enabled = cursor.getInt(2) == 1;
|
||||
String title = cursor.getString(3);
|
||||
String description = cursor.getString(4);
|
||||
String trackingCategory = cursor.getString(5);
|
||||
String body = cursor.getString(6);
|
||||
Campaign c = new Campaign(name, body, trackingCategory);
|
||||
c.title = title;
|
||||
c.description = description;
|
||||
c.enabled = enabled;
|
||||
return c;
|
||||
}
|
||||
|
||||
public String getTrackingCategory() {
|
||||
return trackingCategory;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public static class Table {
|
||||
public static final String TABLE_NAME = "campaigns";
|
||||
|
||||
public static final String COLUMN_ID = "_id";
|
||||
public static final String COLUMN_NAME = "name";
|
||||
public static final String COLUMN_ENABLED = "enabled";
|
||||
public static final String COLUMN_TITLE = "title";
|
||||
public static final String COLUMN_DESCRIPTION = "description";
|
||||
public static final String COLUMN_TRACKING_CATEGORY = "tracking_category";
|
||||
public static final String COLUMN_BODY = "body";
|
||||
|
||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||
public static final String[] ALL_FIELDS = {
|
||||
COLUMN_ID,
|
||||
COLUMN_NAME,
|
||||
COLUMN_ENABLED,
|
||||
COLUMN_TITLE,
|
||||
COLUMN_DESCRIPTION,
|
||||
COLUMN_TRACKING_CATEGORY,
|
||||
COLUMN_BODY
|
||||
};
|
||||
|
||||
|
||||
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||
+ "_id INTEGER PRIMARY KEY,"
|
||||
+ "name STRING,"
|
||||
+ "enabled INTEGER,"
|
||||
+ "title STRING,"
|
||||
+ "description STRING,"
|
||||
+ "tracking_category STRING,"
|
||||
+ "body STRING"
|
||||
+ ");";
|
||||
|
||||
|
||||
public static void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
||||
}
|
||||
|
||||
public static void onUpdate(SQLiteDatabase db, int from, int to) {
|
||||
if(to <= 6) {
|
||||
onCreate(db);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package org.wikimedia.commons.campaigns;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.R;
|
||||
import org.wikimedia.commons.contributions.ContributionsActivity;
|
||||
|
||||
public class CampaignActivity
|
||||
extends SherlockFragmentActivity
|
||||
implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private ListView campaignsListView;
|
||||
private CampaignsListAdapter campaignsListAdapter;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_campaigns);
|
||||
|
||||
ContentResolver.setSyncAutomatically(((CommonsApplication)getApplicationContext()).getCurrentAccount(), CampaignsContentProvider.AUTHORITY, true); // Enable sync by default!
|
||||
campaignsListView = (ListView) findViewById(R.id.campaignsList);
|
||||
|
||||
campaignsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
Campaign c = Campaign.fromCursor((Cursor) adapterView.getItemAtPosition(i));
|
||||
Intent intent = new Intent(CampaignActivity.this, ContributionsActivity.class);
|
||||
intent.putExtra("campaign", c);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
getSupportLoaderManager().initLoader(0, null, this);
|
||||
}
|
||||
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
return new CursorLoader(this, CampaignsContentProvider.BASE_URI, Campaign.Table.ALL_FIELDS, "", null, "");
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
if(campaignsListAdapter == null) {
|
||||
campaignsListAdapter = new CampaignsListAdapter(this, cursor, 0);
|
||||
campaignsListView.setAdapter(campaignsListAdapter);
|
||||
} else {
|
||||
campaignsListAdapter.swapCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoaderReset(Loader<Cursor> cursorLoader) {
|
||||
campaignsListAdapter.swapCursor(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
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<String> 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;
|
||||
}
|
||||
|
||||
public void setCampaign(Campaign campaign) {
|
||||
this.campaign = campaign;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTrackingTemplates() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
if(campaign.getAutoAddWikitext() != null) {
|
||||
buffer.append(campaign.getAutoAddWikitext()).append("\n");
|
||||
}
|
||||
if(campaign.getAutoAddCategories() != null && campaign.getAutoAddCategories().size() != 0) {
|
||||
for(String cat : campaign.getAutoAddCategories()) {
|
||||
buffer.append("[[Category:").append(cat).append("]]").append("\n");
|
||||
}
|
||||
} else {
|
||||
buffer.append("{{subst:unc}}\n");
|
||||
}
|
||||
buffer.append("[[Category:").append(campaign.getTrackingCategory()).append("\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return super.getDescription();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
package org.wikimedia.commons.campaigns;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteQueryBuilder;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.data.DBOpenHelper;
|
||||
|
||||
public class CampaignsContentProvider extends ContentProvider{
|
||||
|
||||
private static final int CAMPAIGNS = 1;
|
||||
private static final int CAMPAIGNS_ID = 2;
|
||||
|
||||
public static final String AUTHORITY = "org.wikimedia.commons.campaigns.contentprovider";
|
||||
private static final String BASE_PATH = "campiagns";
|
||||
|
||||
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
|
||||
|
||||
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
static {
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH, CAMPAIGNS);
|
||||
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CAMPAIGNS_ID);
|
||||
}
|
||||
|
||||
|
||||
public static Uri uriForId(int id) {
|
||||
return Uri.parse(BASE_URI.toString() + "/" + id);
|
||||
}
|
||||
|
||||
private DBOpenHelper dbOpenHelper;
|
||||
@Override
|
||||
public boolean onCreate() {
|
||||
dbOpenHelper = ((CommonsApplication)this.getContext().getApplicationContext()).getDbOpenHelper();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
|
||||
queryBuilder.setTables(Campaign.Table.TABLE_NAME);
|
||||
|
||||
int uriType = uriMatcher.match(uri);
|
||||
|
||||
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
|
||||
Cursor cursor;
|
||||
|
||||
switch(uriType) {
|
||||
case CAMPAIGNS:
|
||||
cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
|
||||
break;
|
||||
case CAMPAIGNS_ID:
|
||||
cursor = queryBuilder.query(db,
|
||||
Campaign.Table.ALL_FIELDS,
|
||||
"_id = ?",
|
||||
new String[] { uri.getLastPathSegment() },
|
||||
null,
|
||||
null,
|
||||
sortOrder
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI" + uri);
|
||||
}
|
||||
|
||||
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uri insert(Uri uri, ContentValues contentValues) {
|
||||
int uriType = uriMatcher.match(uri);
|
||||
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
||||
long id = 0;
|
||||
switch (uriType) {
|
||||
case CAMPAIGNS:
|
||||
sqlDB.beginTransaction();
|
||||
// if the campaign already exists, rip it out and then re-insert
|
||||
if(campaignExists(sqlDB, contentValues)) {
|
||||
sqlDB.delete(
|
||||
Campaign.Table.TABLE_NAME,
|
||||
Campaign.Table.COLUMN_NAME + " = ?",
|
||||
new String[]{contentValues.getAsString(Campaign.Table.COLUMN_NAME)}
|
||||
);
|
||||
}
|
||||
id = sqlDB.insert(Campaign.Table.TABLE_NAME, null, contentValues);
|
||||
sqlDB.endTransaction();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI: " + uri);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return Uri.parse(BASE_URI + "/" + id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int delete(Uri uri, String s, String[] strings) {
|
||||
int rows = 0;
|
||||
int uriType = uriMatcher.match(uri);
|
||||
|
||||
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
|
||||
|
||||
switch(uriType) {
|
||||
case CAMPAIGNS_ID:
|
||||
rows = db.delete(Campaign.Table.TABLE_NAME,
|
||||
"_id = ?",
|
||||
new String[] { uri.getLastPathSegment() }
|
||||
);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI" + uri);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return rows;
|
||||
}
|
||||
|
||||
private boolean campaignExists(SQLiteDatabase db, ContentValues campaign) {
|
||||
Cursor cr = db.query(
|
||||
Campaign.Table.TABLE_NAME,
|
||||
new String[]{Campaign.Table.COLUMN_NAME},
|
||||
Campaign.Table.COLUMN_NAME + " = ?",
|
||||
new String[]{campaign.getAsString(Campaign.Table.COLUMN_NAME)},
|
||||
"", "", ""
|
||||
);
|
||||
return cr != null && cr.getCount() != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int bulkInsert(Uri uri, ContentValues[] values) {
|
||||
Log.d("Commons", "Hello, bulk insert!");
|
||||
int uriType = uriMatcher.match(uri);
|
||||
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
||||
sqlDB.beginTransaction();
|
||||
switch (uriType) {
|
||||
case CAMPAIGNS:
|
||||
for(ContentValues value: values) {
|
||||
Log.d("Commons", "Inserting! " + value.toString());
|
||||
// if the campaign already exists, rip it out and then re-insert
|
||||
if(campaignExists(sqlDB, value)) {
|
||||
sqlDB.delete(
|
||||
Campaign.Table.TABLE_NAME,
|
||||
Campaign.Table.COLUMN_NAME + " = ?",
|
||||
new String[]{value.getAsString(Campaign.Table.COLUMN_NAME)}
|
||||
);
|
||||
}
|
||||
sqlDB.insert(Campaign.Table.TABLE_NAME, null, value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI: " + uri);
|
||||
}
|
||||
sqlDB.setTransactionSuccessful();
|
||||
sqlDB.endTransaction();
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return values.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
|
||||
/*
|
||||
SQL Injection warnings: First, note that we're not exposing this to the outside world (exported="false")
|
||||
Even then, we should make sure to sanitize all user input appropriately. Input that passes through ContentValues
|
||||
should be fine. So only issues are those that pass in via concating.
|
||||
|
||||
In here, the only concat created argument is for id. It is cast to an int, and will error out otherwise.
|
||||
*/
|
||||
int uriType = uriMatcher.match(uri);
|
||||
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
||||
int rowsUpdated = 0;
|
||||
switch (uriType) {
|
||||
case CAMPAIGNS:
|
||||
rowsUpdated = sqlDB.update(Campaign.Table.TABLE_NAME,
|
||||
contentValues,
|
||||
selection,
|
||||
selectionArgs);
|
||||
break;
|
||||
case CAMPAIGNS_ID:
|
||||
int id = Integer.valueOf(uri.getLastPathSegment());
|
||||
|
||||
if (TextUtils.isEmpty(selection)) {
|
||||
rowsUpdated = sqlDB.update(Campaign.Table.TABLE_NAME,
|
||||
contentValues,
|
||||
Campaign.Table.COLUMN_ID + " = ?",
|
||||
new String[] { String.valueOf(id) } );
|
||||
} else {
|
||||
throw new IllegalArgumentException("Parameter `selection` should be empty when updating an ID");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown URI: " + uri + " with type " + uriType);
|
||||
}
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
return rowsUpdated;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package org.wikimedia.commons.campaigns;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import com.actionbarsherlock.app.SherlockFragment;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.MediaWikiImageView;
|
||||
import org.wikimedia.commons.R;
|
||||
import org.wikimedia.commons.Utils;
|
||||
import org.wikimedia.commons.campaigns.Campaign;
|
||||
|
||||
class CampaignsListAdapter extends CursorAdapter {
|
||||
|
||||
private DisplayImageOptions contributionDisplayOptions = Utils.getGenericDisplayOptions().build();;
|
||||
private Activity activity;
|
||||
|
||||
public CampaignsListAdapter(Activity activity, Cursor c, int flags) {
|
||||
super(activity, c, flags);
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
|
||||
View parent = activity.getLayoutInflater().inflate(android.R.layout.simple_list_item_1, viewGroup, false);
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
TextView campaignName = (TextView)view.findViewById(android.R.id.text1);
|
||||
|
||||
Campaign campaign = Campaign.fromCursor(cursor);
|
||||
|
||||
campaignName.setText(campaign.getTitle());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package org.wikimedia.commons.campaigns;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.*;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import org.mediawiki.api.ApiResult;
|
||||
import org.mediawiki.api.MWApi;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.Utils;
|
||||
import org.wikimedia.commons.contributions.Contribution;
|
||||
import org.wikimedia.commons.contributions.ContributionsContentProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class CampaignsSyncAdapter extends AbstractThreadedSyncAdapter {
|
||||
private static int COMMIT_THRESHOLD = 10;
|
||||
public CampaignsSyncAdapter(Context context, boolean autoInitialize) {
|
||||
super(context, autoInitialize);
|
||||
}
|
||||
|
||||
private int getLimit() {
|
||||
return 500; // FIXME: Parameterize!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPerformSync(Account account, Bundle bundle, String s, ContentProviderClient contentProviderClient, SyncResult syncResult) {
|
||||
// This code is fraught with possibilities of race conditions, but lalalalala I can't hear you!
|
||||
String user = account.name;
|
||||
MWApi api = CommonsApplication.createMWApi();
|
||||
ApiResult result;
|
||||
Boolean done = false;
|
||||
String queryContinue = null;
|
||||
while(!done) {
|
||||
|
||||
try {
|
||||
MWApi.RequestBuilder builder = api.action("query")
|
||||
.param("list", "allcampaigns")
|
||||
// Disabled, since we want to modify local state if the campaign was disabled
|
||||
// FIXME: To be more effecient, delete the disabled campaigns locally
|
||||
//.param("ucenabledonly", "true")
|
||||
.param("uclimit", getLimit());
|
||||
if(!TextUtils.isEmpty(queryContinue)) {
|
||||
builder.param("uccontinue", queryContinue);
|
||||
}
|
||||
result = builder.get();
|
||||
} catch (IOException e) {
|
||||
// There isn't really much we can do, eh?
|
||||
// FIXME: Perhaps add EventLogging?
|
||||
syncResult.stats.numIoExceptions += 1; // Not sure if this does anything. Shitty docs
|
||||
Log.d("Commons", "Syncing failed due to " + e.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<ApiResult> campaigns = result.getNodes("/api/query/allcampaigns/campaign");
|
||||
Log.d("Commons", campaigns.size() + " results!");
|
||||
ArrayList<ContentValues> campaignValues = new ArrayList<ContentValues>();
|
||||
for(ApiResult campaignItem: campaigns) {
|
||||
String name = campaignItem.getString("@name");
|
||||
String body = campaignItem.getString(".");
|
||||
Log.d("Commons", "Campaign body is " + body);
|
||||
String trackingCat = campaignItem.getString("@trackingCategory");
|
||||
Campaign campaign = Campaign.parse(name, body, trackingCat);
|
||||
campaignValues.add(campaign.toContentValues());
|
||||
|
||||
if(campaignValues.size() % COMMIT_THRESHOLD == 0) {
|
||||
try {
|
||||
contentProviderClient.bulkInsert(CampaignsContentProvider.BASE_URI, campaignValues.toArray(new ContentValues[]{}));
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
campaignValues.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if(campaignValues.size() != 0) {
|
||||
try {
|
||||
contentProviderClient.bulkInsert(CampaignsContentProvider.BASE_URI, campaignValues.toArray(new ContentValues[]{}));
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
queryContinue = result.getString("/api/query-continue/allcampaigns/@uccontinue");
|
||||
if(TextUtils.isEmpty(queryContinue)) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package org.wikimedia.commons.campaigns;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import org.wikimedia.commons.contributions.ContributionsSyncAdapter;
|
||||
|
||||
public class CampaignsSyncService extends Service {
|
||||
|
||||
private static final Object sSyncAdapterLock = new Object();
|
||||
|
||||
private static CampaignsSyncAdapter sSyncAdapter = null;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
synchronized (sSyncAdapterLock) {
|
||||
if (sSyncAdapter == null) {
|
||||
sSyncAdapter = new CampaignsSyncAdapter(getApplicationContext(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return sSyncAdapter.getSyncAdapterBinder();
|
||||
}
|
||||
}
|
||||
|
|
@ -117,13 +117,17 @@ public class Contribution extends Media {
|
|||
this.dateUploaded = date;
|
||||
}
|
||||
|
||||
public String getTrackingTemplates() {
|
||||
return "{{subst:unc}}"; // Remove when we have categorization
|
||||
}
|
||||
|
||||
public String getPageContents() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
buffer
|
||||
.append("== {{int:filedesc}} ==\n")
|
||||
.append("{{Information\n")
|
||||
.append("|description=").append(description).append("\n")
|
||||
.append("|description=").append(getDescription()).append("\n")
|
||||
.append("|source=").append("{{own}}\n")
|
||||
.append("|author=[[User:").append(creator).append("|").append(creator).append("]]\n");
|
||||
if(dateCreated != null) {
|
||||
|
|
@ -133,9 +137,9 @@ public class Contribution extends Media {
|
|||
buffer
|
||||
.append("}}").append("\n")
|
||||
.append("== {{int:license-header}} ==\n")
|
||||
.append(Utils.licenseTemplateFor(license)).append("\n\n")
|
||||
.append(Utils.licenseTemplateFor(getLicense())).append("\n\n")
|
||||
.append("{{Uploaded from Mobile|platform=Android|version=").append(CommonsApplication.APPLICATION_VERSION).append("}}\n")
|
||||
.append("{{subst:unc}}"); // Remove when we have categorization
|
||||
.append(getTrackingTemplates());
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
package org.wikimedia.commons.contributions;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.Log;
|
||||
import com.actionbarsherlock.app.SherlockFragment;
|
||||
import org.wikimedia.commons.upload.ShareActivity;
|
||||
import org.wikimedia.commons.upload.UploadService;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
public class ContributionController {
|
||||
private SherlockFragment fragment;
|
||||
private Activity activity;
|
||||
|
||||
private final static int SELECT_FROM_GALLERY = 1;
|
||||
private final static int SELECT_FROM_CAMERA = 2;
|
||||
|
||||
public ContributionController(SherlockFragment fragment) {
|
||||
this.fragment = fragment;
|
||||
this.activity = fragment.getActivity();
|
||||
}
|
||||
|
||||
// See http://stackoverflow.com/a/5054673/17865 for why this is done
|
||||
private Uri lastGeneratedCaptureURI;
|
||||
|
||||
private Uri reGenerateImageCaptureURI() {
|
||||
String storageState = Environment.getExternalStorageState();
|
||||
if(storageState.equals(Environment.MEDIA_MOUNTED)) {
|
||||
|
||||
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Commons/images/" + new Date().getTime() + ".jpg";
|
||||
File _photoFile = new File(path);
|
||||
try {
|
||||
if(_photoFile.exists() == false) {
|
||||
_photoFile.getParentFile().mkdirs();
|
||||
_photoFile.createNewFile();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e("Commons", "Could not create file: " + path, e);
|
||||
}
|
||||
|
||||
return Uri.fromFile(_photoFile);
|
||||
} else {
|
||||
throw new RuntimeException("No external storage found!");
|
||||
}
|
||||
}
|
||||
|
||||
public void startCameraCapture() {
|
||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
lastGeneratedCaptureURI = reGenerateImageCaptureURI();
|
||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, lastGeneratedCaptureURI);
|
||||
fragment.startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA);
|
||||
}
|
||||
|
||||
public void startGalleryPick() {
|
||||
Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
pickImageIntent.setType("image/*");
|
||||
fragment.startActivityForResult(pickImageIntent, SELECT_FROM_GALLERY);
|
||||
}
|
||||
|
||||
public void handleImagePicked(int requestCode, Intent data) {
|
||||
Intent shareIntent = new Intent(activity, ShareActivity.class);
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
switch(requestCode) {
|
||||
case SELECT_FROM_GALLERY:
|
||||
shareIntent.setType(activity.getContentResolver().getType(data.getData()));
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, data.getData());
|
||||
shareIntent.putExtra(UploadService.EXTRA_SOURCE, Contribution.SOURCE_GALLERY);
|
||||
break;
|
||||
case SELECT_FROM_CAMERA:
|
||||
shareIntent.setType("image/jpeg"); //FIXME: Find out appropriate mime type
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, lastGeneratedCaptureURI);
|
||||
shareIntent.putExtra(UploadService.EXTRA_SOURCE, Contribution.SOURCE_CAMERA);
|
||||
break;
|
||||
}
|
||||
activity.startActivity(shareIntent);
|
||||
}
|
||||
|
||||
public void saveState(Bundle outState) {
|
||||
outState.putParcelable("lastGeneratedCaptureURI", lastGeneratedCaptureURI);
|
||||
}
|
||||
|
||||
public void loadState(Bundle savedInstanceState) {
|
||||
if(savedInstanceState != null) {
|
||||
lastGeneratedCaptureURI = (Uri) savedInstanceState.getParcelable("lastGeneratedCaptureURI");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package org.wikimedia.commons.contributions;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import org.wikimedia.commons.MediaWikiImageView;
|
||||
import org.wikimedia.commons.R;
|
||||
|
||||
class ContributionViewHolder {
|
||||
final MediaWikiImageView imageView;
|
||||
final TextView titleView;
|
||||
final TextView stateView;
|
||||
final TextView seqNumView;
|
||||
final ProgressBar progressView;
|
||||
|
||||
String url;
|
||||
|
||||
ContributionViewHolder(View parent) {
|
||||
imageView = (MediaWikiImageView) parent.findViewById(R.id.contributionImage);
|
||||
titleView = (TextView)parent.findViewById(R.id.contributionTitle);
|
||||
stateView = (TextView)parent.findViewById(R.id.contributionState);
|
||||
seqNumView = (TextView)parent.findViewById(R.id.contributionSequenceNumber);
|
||||
progressView = (ProgressBar)parent.findViewById(R.id.contributionProgress);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import android.support.v4.content.Loader;
|
|||
import android.content.*;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
|
|
@ -16,12 +17,15 @@ import com.actionbarsherlock.view.MenuItem;
|
|||
|
||||
import org.wikimedia.commons.*;
|
||||
import org.wikimedia.commons.auth.*;
|
||||
import org.wikimedia.commons.campaigns.Campaign;
|
||||
import org.wikimedia.commons.media.*;
|
||||
import org.wikimedia.commons.upload.UploadService;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ContributionsActivity
|
||||
extends AuthenticatedActivity
|
||||
implements LoaderManager.LoaderCallbacks<Cursor>,
|
||||
implements LoaderManager.LoaderCallbacks<Object>,
|
||||
AdapterView.OnItemClickListener,
|
||||
MediaDetailPagerFragment.MediaDetailProvider,
|
||||
FragmentManager.OnBackStackChangedListener {
|
||||
|
|
@ -31,6 +35,8 @@ public class ContributionsActivity
|
|||
private ContributionsListFragment contributionsList;
|
||||
private MediaDetailPagerFragment mediaDetails;
|
||||
|
||||
private Campaign campaign;
|
||||
|
||||
public ContributionsActivity() {
|
||||
super(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE);
|
||||
}
|
||||
|
|
@ -101,6 +107,10 @@ public class ContributionsActivity
|
|||
setTitle(R.string.title_activity_contributions);
|
||||
setContentView(R.layout.activity_contributions);
|
||||
|
||||
if(getIntent().hasExtra("campaign")) {
|
||||
this.campaign = (Campaign) getIntent().getSerializableExtra("campaign");
|
||||
}
|
||||
|
||||
contributionsList = (ContributionsListFragment)getSupportFragmentManager().findFragmentById(R.id.contributionsListFragment);
|
||||
|
||||
getSupportFragmentManager().addOnBackStackChangedListener(this);
|
||||
|
|
@ -180,13 +190,7 @@ public class ContributionsActivity
|
|||
|
||||
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int position, long item) {
|
||||
Cursor cursor = (Cursor)adapterView.getItemAtPosition(position);
|
||||
Contribution c = Contribution.fromCursor(cursor);
|
||||
|
||||
Log.d("Commons", "Clicking for " + c.toContentValues());
|
||||
showDetail(position);
|
||||
|
||||
Log.d("Commons", "You clicked on:" + c.toContentValues().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -194,31 +198,51 @@ public class ContributionsActivity
|
|||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
|
||||
public Loader onCreateLoader(int i, Bundle bundle) {
|
||||
if(campaign == null) {
|
||||
return new CursorLoader(this, ContributionsContentProvider.BASE_URI, Contribution.Table.ALL_FIELDS, CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
|
||||
} else {
|
||||
return new CategoryImagesLoader(this, campaign.getTrackingCategory());
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
|
||||
allContributions = cursor;
|
||||
contributionsList.setCursor(cursor);
|
||||
public void onLoadFinished(Loader cursorLoader, Object result) {
|
||||
if(campaign == null) {
|
||||
Cursor cursor = (Cursor) result;
|
||||
if(contributionsList.getAdapter() == null) {
|
||||
contributionsList.setAdapter(new ContributionsListAdapter(this, cursor, 0));
|
||||
} else {
|
||||
((CursorAdapter)contributionsList.getAdapter()).swapCursor(cursor);
|
||||
}
|
||||
|
||||
getSupportActionBar().setSubtitle(getResources().getQuantityString(R.plurals.contributions_subtitle, cursor.getCount(), cursor.getCount()));
|
||||
} else {
|
||||
contributionsList.setAdapter(new MediaListAdapter(this, (ArrayList<Media>) result));
|
||||
}
|
||||
}
|
||||
|
||||
public void onLoaderReset(Loader<Cursor> cursorLoader) {
|
||||
contributionsList.setCursor(null);
|
||||
public void onLoaderReset(Loader cursorLoader) {
|
||||
if(campaign == null) {
|
||||
((CursorAdapter) contributionsList.getAdapter()).swapCursor(null);
|
||||
} else {
|
||||
//((MediaListAdapter) contributionsList.getAdapter()).
|
||||
// DO SOMETHING!
|
||||
}
|
||||
}
|
||||
|
||||
public Media getMediaAtPosition(int i) {
|
||||
allContributions.moveToPosition(i);
|
||||
return Contribution.fromCursor(allContributions);
|
||||
if(campaign == null) {
|
||||
return Contribution.fromCursor((Cursor) contributionsList.getAdapter().getItem(i));
|
||||
} else {
|
||||
return (Media) contributionsList.getAdapter().getItem(i);
|
||||
}
|
||||
}
|
||||
|
||||
public int getTotalMediaCount() {
|
||||
if(allContributions == null) {
|
||||
if(contributionsList.getAdapter() == null) {
|
||||
return 0;
|
||||
}
|
||||
return allContributions.getCount();
|
||||
return contributionsList.getAdapter().getCount();
|
||||
}
|
||||
|
||||
public void notifyDatasetChanged() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
package org.wikimedia.commons.contributions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import com.actionbarsherlock.app.SherlockFragment;
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.MediaWikiImageView;
|
||||
import org.wikimedia.commons.R;
|
||||
import org.wikimedia.commons.Utils;
|
||||
|
||||
class ContributionsListAdapter extends CursorAdapter {
|
||||
|
||||
private DisplayImageOptions contributionDisplayOptions = Utils.getGenericDisplayOptions().build();;
|
||||
private Activity activity;
|
||||
|
||||
public ContributionsListAdapter(Activity activity, Cursor c, int flags) {
|
||||
super(activity, c, flags);
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
|
||||
View parent = activity.getLayoutInflater().inflate(R.layout.layout_contribution, viewGroup, false);
|
||||
parent.setTag(new ContributionViewHolder(parent));
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
final ContributionViewHolder views = (ContributionViewHolder)view.getTag();
|
||||
Contribution contribution = Contribution.fromCursor(cursor);
|
||||
|
||||
String actualUrl = (contribution.getLocalUri() != null && TextUtils.isEmpty(contribution.getLocalUri().toString())) ? contribution.getLocalUri().toString() : contribution.getThumbnailUrl(640);
|
||||
|
||||
if(views.url == null || !views.url.equals(actualUrl)) {
|
||||
if(actualUrl.startsWith("http")) {
|
||||
MediaWikiImageView mwImageView = (MediaWikiImageView)views.imageView;
|
||||
mwImageView.setMedia(contribution, ((CommonsApplication) activity.getApplicationContext()).getImageLoader());
|
||||
// FIXME: For transparent images
|
||||
} else {
|
||||
com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(actualUrl, views.imageView, contributionDisplayOptions, new SimpleImageLoadingListener() {
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
if(loadedImage.hasAlpha()) {
|
||||
views.imageView.setBackgroundResource(android.R.color.white);
|
||||
}
|
||||
views.seqNumView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
views.url = actualUrl;
|
||||
}
|
||||
|
||||
BitmapDrawable actualImageDrawable = (BitmapDrawable)views.imageView.getDrawable();
|
||||
if(actualImageDrawable != null && actualImageDrawable.getBitmap() != null && actualImageDrawable.getBitmap().hasAlpha()) {
|
||||
views.imageView.setBackgroundResource(android.R.color.white);
|
||||
} else {
|
||||
views.imageView.setBackgroundDrawable(null);
|
||||
}
|
||||
|
||||
views.titleView.setText(contribution.getDisplayTitle());
|
||||
|
||||
views.seqNumView.setText(String.valueOf(cursor.getPosition() + 1));
|
||||
views.seqNumView.setVisibility(View.VISIBLE);
|
||||
|
||||
switch(contribution.getState()) {
|
||||
case Contribution.STATE_COMPLETED:
|
||||
views.stateView.setVisibility(View.GONE);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.stateView.setText("");
|
||||
break;
|
||||
case Contribution.STATE_QUEUED:
|
||||
views.stateView.setVisibility(View.VISIBLE);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.stateView.setText(R.string.contribution_state_queued);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
views.stateView.setVisibility(View.GONE);
|
||||
views.progressView.setVisibility(View.VISIBLE);
|
||||
long total = contribution.getDataLength();
|
||||
long transferred = contribution.getTransferred();
|
||||
if(transferred == 0 || transferred >= total) {
|
||||
views.progressView.setIndeterminate(true);
|
||||
} else {
|
||||
views.progressView.setProgress((int)(((double)transferred / (double)total) * 100));
|
||||
}
|
||||
break;
|
||||
case Contribution.STATE_FAILED:
|
||||
views.stateView.setVisibility(View.VISIBLE);
|
||||
views.stateView.setText(R.string.contribution_state_failed);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -5,14 +5,7 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
|
@ -23,226 +16,55 @@ import com.actionbarsherlock.view.Menu;
|
|||
import com.actionbarsherlock.view.MenuInflater;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
|
||||
import com.nostra13.universalimageloader.core.DisplayImageOptions;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
|
||||
import org.wikimedia.commons.*;
|
||||
import org.wikimedia.commons.R;
|
||||
import org.wikimedia.commons.upload.ShareActivity;
|
||||
import org.wikimedia.commons.upload.UploadService;
|
||||
|
||||
public class ContributionsListFragment extends SherlockFragment {
|
||||
|
||||
private final static int SELECT_FROM_GALLERY = 1;
|
||||
private final static int SELECT_FROM_CAMERA = 2;
|
||||
|
||||
private GridView contributionsList;
|
||||
private TextView waitingMessage;
|
||||
private TextView emptyMessage;
|
||||
|
||||
private ContributionsListAdapter contributionsAdapter;
|
||||
|
||||
private DisplayImageOptions contributionDisplayOptions;
|
||||
private Cursor allContributions;
|
||||
|
||||
private static class ContributionViewHolder {
|
||||
final ImageView imageView;
|
||||
final TextView titleView;
|
||||
final TextView stateView;
|
||||
final TextView seqNumView;
|
||||
final ProgressBar progressView;
|
||||
|
||||
String url;
|
||||
|
||||
ContributionViewHolder(View parent) {
|
||||
imageView = (ImageView)parent.findViewById(R.id.contributionImage);
|
||||
titleView = (TextView)parent.findViewById(R.id.contributionTitle);
|
||||
stateView = (TextView)parent.findViewById(R.id.contributionState);
|
||||
seqNumView = (TextView)parent.findViewById(R.id.contributionSequenceNumber);
|
||||
progressView = (ProgressBar)parent.findViewById(R.id.contributionProgress);
|
||||
}
|
||||
}
|
||||
|
||||
private class ContributionsListAdapter extends CursorAdapter {
|
||||
|
||||
public ContributionsListAdapter(Context context, Cursor c, int flags) {
|
||||
super(context, c, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
|
||||
View parent = getActivity().getLayoutInflater().inflate(R.layout.layout_contribution, viewGroup, false);
|
||||
parent.setTag(new ContributionViewHolder(parent));
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindView(View view, Context context, Cursor cursor) {
|
||||
// hack: hide the 'first sync' message once we've loaded a cell
|
||||
clearSyncMessage();
|
||||
|
||||
final ContributionViewHolder views = (ContributionViewHolder)view.getTag();
|
||||
Contribution contribution = Contribution.fromCursor(cursor);
|
||||
|
||||
String actualUrl = TextUtils.isEmpty(contribution.getImageUrl()) ? contribution.getLocalUri().toString() : contribution.getThumbnailUrl(320);
|
||||
|
||||
if(views.url == null || !views.url.equals(actualUrl)) {
|
||||
if(actualUrl.startsWith("http")) {
|
||||
MediaWikiImageView mwImageView = (MediaWikiImageView)views.imageView;
|
||||
mwImageView.setMedia(contribution, ((CommonsApplication) getActivity().getApplicationContext()).getImageLoader());
|
||||
// FIXME: For transparent images
|
||||
} else {
|
||||
com.nostra13.universalimageloader.core.ImageLoader.getInstance().displayImage(actualUrl, views.imageView, contributionDisplayOptions, new SimpleImageLoadingListener() {
|
||||
|
||||
@Override
|
||||
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
|
||||
if(loadedImage.hasAlpha()) {
|
||||
views.imageView.setBackgroundResource(android.R.color.white);
|
||||
}
|
||||
views.seqNumView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
views.url = actualUrl;
|
||||
}
|
||||
|
||||
BitmapDrawable actualImageDrawable = (BitmapDrawable)views.imageView.getDrawable();
|
||||
if(actualImageDrawable != null && actualImageDrawable.getBitmap() != null && actualImageDrawable.getBitmap().hasAlpha()) {
|
||||
views.imageView.setBackgroundResource(android.R.color.white);
|
||||
} else {
|
||||
views.imageView.setBackgroundDrawable(null);
|
||||
}
|
||||
|
||||
views.titleView.setText(contribution.getDisplayTitle());
|
||||
|
||||
views.seqNumView.setText(String.valueOf(cursor.getPosition() + 1));
|
||||
views.seqNumView.setVisibility(View.VISIBLE);
|
||||
|
||||
switch(contribution.getState()) {
|
||||
case Contribution.STATE_COMPLETED:
|
||||
views.stateView.setVisibility(View.GONE);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.stateView.setText("");
|
||||
break;
|
||||
case Contribution.STATE_QUEUED:
|
||||
views.stateView.setVisibility(View.VISIBLE);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.stateView.setText(R.string.contribution_state_queued);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
views.stateView.setVisibility(View.GONE);
|
||||
views.progressView.setVisibility(View.VISIBLE);
|
||||
long total = contribution.getDataLength();
|
||||
long transferred = contribution.getTransferred();
|
||||
if(transferred == 0 || transferred >= total) {
|
||||
views.progressView.setIndeterminate(true);
|
||||
} else {
|
||||
views.progressView.setProgress((int)(((double)transferred / (double)total) * 100));
|
||||
}
|
||||
break;
|
||||
case Contribution.STATE_FAILED:
|
||||
views.stateView.setVisibility(View.VISIBLE);
|
||||
views.stateView.setText(R.string.contribution_state_failed);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
private ContributionController controller;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_contributions, container, false);
|
||||
}
|
||||
|
||||
public void setCursor(Cursor cursor) {
|
||||
if(allContributions == null) {
|
||||
contributionsAdapter = new ContributionsListAdapter(this.getActivity(), cursor, 0);
|
||||
contributionsList.setAdapter(contributionsAdapter);
|
||||
public ListAdapter getAdapter() {
|
||||
return contributionsList.getAdapter();
|
||||
}
|
||||
allContributions = cursor;
|
||||
contributionsAdapter.swapCursor(cursor);
|
||||
|
||||
public void setAdapter(ListAdapter adapter) {
|
||||
this.contributionsList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
controller.saveState(outState);
|
||||
outState.putInt("grid-position", contributionsList.getFirstVisiblePosition());
|
||||
outState.putParcelable("lastGeneratedCaptureURI", lastGeneratedCaptureURI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch(requestCode) {
|
||||
case SELECT_FROM_GALLERY:
|
||||
if(resultCode == Activity.RESULT_OK) {
|
||||
Intent shareIntent = new Intent(getActivity(), ShareActivity.class);
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
|
||||
shareIntent.setType(getActivity().getContentResolver().getType(data.getData()));
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, data.getData());
|
||||
shareIntent.putExtra(UploadService.EXTRA_SOURCE, Contribution.SOURCE_GALLERY);
|
||||
startActivity(shareIntent);
|
||||
}
|
||||
break;
|
||||
case SELECT_FROM_CAMERA:
|
||||
if(resultCode == Activity.RESULT_OK) {
|
||||
Intent shareIntent = new Intent(getActivity(), ShareActivity.class);
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
Log.d("Commons", "Uri is " + lastGeneratedCaptureURI);
|
||||
shareIntent.setType("image/jpeg"); //FIXME: Find out appropriate mime type
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, lastGeneratedCaptureURI);
|
||||
shareIntent.putExtra(UploadService.EXTRA_SOURCE, Contribution.SOURCE_CAMERA);
|
||||
startActivity(shareIntent);
|
||||
}
|
||||
break;
|
||||
controller.handleImagePicked(requestCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
// See http://stackoverflow.com/a/5054673/17865 for why this is done
|
||||
private Uri lastGeneratedCaptureURI;
|
||||
|
||||
private void reGenerateImageCaptureURI() {
|
||||
String storageState = Environment.getExternalStorageState();
|
||||
if(storageState.equals(Environment.MEDIA_MOUNTED)) {
|
||||
|
||||
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Commons/images/" + new Date().getTime() + ".jpg";
|
||||
File _photoFile = new File(path);
|
||||
try {
|
||||
if(_photoFile.exists() == false) {
|
||||
_photoFile.getParentFile().mkdirs();
|
||||
_photoFile.createNewFile();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
Log.e("Commons", "Could not create file: " + path, e);
|
||||
}
|
||||
|
||||
lastGeneratedCaptureURI = Uri.fromFile(_photoFile);
|
||||
} else {
|
||||
throw new RuntimeException("No external storage found!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch(item.getItemId()) {
|
||||
case R.id.menu_from_gallery:
|
||||
Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
pickImageIntent.setType("image/*");
|
||||
startActivityForResult(pickImageIntent, SELECT_FROM_GALLERY);
|
||||
controller.startGalleryPick();
|
||||
return true;
|
||||
case R.id.menu_from_camera:
|
||||
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
reGenerateImageCaptureURI();
|
||||
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, lastGeneratedCaptureURI);
|
||||
startActivityForResult(takePictureIntent, SELECT_FROM_CAMERA);
|
||||
controller.startCameraCapture();
|
||||
return true;
|
||||
case R.id.menu_settings:
|
||||
Intent settingsIntent = new Intent(getActivity(), SettingsActivity.class);
|
||||
|
|
@ -282,19 +104,25 @@ public class ContributionsListFragment extends SherlockFragment {
|
|||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
controller = new ContributionController(this);
|
||||
controller.loadState(savedInstanceState);
|
||||
|
||||
contributionsList = (GridView)getView().findViewById(R.id.contributionsList);
|
||||
waitingMessage = (TextView)getView().findViewById(R.id.waitingMessage);
|
||||
emptyMessage = (TextView)getView().findViewById(R.id.waitingMessage);
|
||||
contributionDisplayOptions = Utils.getGenericDisplayOptions().build();
|
||||
|
||||
contributionsList.setOnItemClickListener((AdapterView.OnItemClickListener)getActivity());
|
||||
if(savedInstanceState != null) {
|
||||
Log.d("Commons", "Scrolling to " + savedInstanceState.getInt("grid-position"));
|
||||
lastGeneratedCaptureURI = (Uri) savedInstanceState.getParcelable("lastGeneratedCaptureURI");
|
||||
contributionsList.setSelection(savedInstanceState.getInt("grid-position"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package org.wikimedia.commons.contributions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import com.android.volley.toolbox.ImageLoader;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.Media;
|
||||
import org.wikimedia.commons.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MediaListAdapter extends BaseAdapter {
|
||||
private ArrayList<Media> mediaList;
|
||||
private Activity activity;
|
||||
|
||||
public MediaListAdapter(Activity activity, ArrayList<Media> mediaList) {
|
||||
this.mediaList = mediaList;
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mediaList.size();
|
||||
}
|
||||
|
||||
public Object getItem(int i) {
|
||||
return mediaList.get(i);
|
||||
}
|
||||
|
||||
public long getItemId(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||
if(view == null) {
|
||||
view = activity.getLayoutInflater().inflate(R.layout.layout_contribution, null, false);
|
||||
view.setTag(new ContributionViewHolder(view));
|
||||
}
|
||||
|
||||
Media m = (Media) getItem(i);
|
||||
ContributionViewHolder holder = (ContributionViewHolder) view.getTag();
|
||||
holder.imageView.setMedia(m, ((CommonsApplication)activity.getApplicationContext()).getImageLoader());
|
||||
holder.titleView.setText(m.getDisplayTitle());
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package org.wikimedia.commons.data;
|
|||
import android.content.*;
|
||||
import android.database.sqlite.*;
|
||||
|
||||
import org.wikimedia.commons.campaigns.Campaign;
|
||||
import org.wikimedia.commons.category.Category;
|
||||
import org.wikimedia.commons.contributions.*;
|
||||
import org.wikimedia.commons.modifications.ModifierSequence;
|
||||
|
|
@ -21,6 +22,7 @@ public class DBOpenHelper extends SQLiteOpenHelper{
|
|||
Contribution.Table.onCreate(sqLiteDatabase);
|
||||
ModifierSequence.Table.onCreate(sqLiteDatabase);
|
||||
Category.Table.onCreate(sqLiteDatabase);
|
||||
Campaign.Table.onCreate(sqLiteDatabase);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -28,5 +30,6 @@ public class DBOpenHelper extends SQLiteOpenHelper{
|
|||
Contribution.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
ModifierSequence.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
Category.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
Campaign.Table.onUpdate(sqLiteDatabase, from, to);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
package org.wikimedia.commons.media;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.util.Log;
|
||||
import org.mediawiki.api.ApiResult;
|
||||
import org.wikimedia.commons.CommonsApplication;
|
||||
import org.wikimedia.commons.Media;
|
||||
import org.wikimedia.commons.Utils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CategoryImagesLoader extends AsyncTaskLoader<List<Media>>{
|
||||
private final CommonsApplication app;
|
||||
private final String category;
|
||||
|
||||
public CategoryImagesLoader(Context context, String category) {
|
||||
super(context);
|
||||
this.app = (CommonsApplication) context.getApplicationContext();
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
super.onStartLoading();
|
||||
super.forceLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Media> loadInBackground() {
|
||||
ArrayList<Media> mediaList = new ArrayList<Media>();
|
||||
ApiResult result;
|
||||
try {
|
||||
result = app.getApi().action("query")
|
||||
.param("list", "categorymembers")
|
||||
.param("cmtitle", "Category:" + category)
|
||||
.param("cmprop", "title|timestamp")
|
||||
.param("cmtype", "file")
|
||||
.param("cmsort", "timestamp")
|
||||
.param("cmdir", "descending")
|
||||
.param("cmlimit", 50)
|
||||
.get();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Log.d("Commons", Utils.getStringFromDOM(result.getDocument()));
|
||||
|
||||
List<ApiResult> members = result.getNodes("/api/query/categorymembers/cm");
|
||||
for(ApiResult member : members) {
|
||||
mediaList.add(new Media(member.getString("@title")));
|
||||
}
|
||||
return mediaList;
|
||||
}
|
||||
}
|
||||
|
|
@ -148,7 +148,7 @@ public class MediaDetailFragment extends SherlockFragment {
|
|||
*/
|
||||
|
||||
|
||||
String actualUrl = TextUtils.isEmpty(media.getImageUrl()) ? media.getLocalUri().toString() : media.getThumbnailUrl(640);
|
||||
String actualUrl = (media.getLocalUri() != null && TextUtils.isEmpty(media.getLocalUri().toString())) ? media.getLocalUri().toString() : media.getThumbnailUrl(640);
|
||||
if(actualUrl.startsWith("http")) {
|
||||
ImageLoader loader = ((CommonsApplication)getActivity().getApplicationContext()).getImageLoader();
|
||||
MediaWikiImageView mwImage = (MediaWikiImageView)image;
|
||||
|
|
|
|||
|
|
@ -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,29 @@ 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();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
uploadsList.setImageOnlyMode(true);
|
||||
|
||||
categorizationFragment = (CategorizationFragment) this.getSupportFragmentManager().findFragmentByTag("categorization");
|
||||
|
|
@ -112,75 +134,6 @@ public class MultipleShareActivity
|
|||
finish();
|
||||
}
|
||||
|
||||
private class StartMultipleUploadTask extends AsyncTask<Void, Integer, Void> {
|
||||
|
||||
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 +149,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 +167,7 @@ public class MultipleShareActivity
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(isUploadServiceConnected) {
|
||||
unbindService(uploadServiceConnection);
|
||||
}
|
||||
uploadController.cleanup();
|
||||
}
|
||||
|
||||
private void showDetail(int i) {
|
||||
|
|
@ -267,11 +219,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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,23 +44,17 @@ 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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showPostUpload() {
|
||||
|
|
@ -96,26 +90,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 +135,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 +149,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 +181,7 @@ public class ShareActivity
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(isUploadServiceConnected) {
|
||||
unbindService(uploadServiceConnection);
|
||||
}
|
||||
uploadController.cleanup();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -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<Void, Void, Contribution> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
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;
|
||||
private Campaign campaign;
|
||||
final CommonsApplication app;
|
||||
|
||||
public interface ContributionUploadProgress {
|
||||
void onUploadStarted(Contribution contribution);
|
||||
}
|
||||
|
||||
public UploadController(Activity activity) {
|
||||
this.activity = activity;
|
||||
app = (CommonsApplication)activity.getApplicationContext();
|
||||
}
|
||||
|
||||
public UploadController(Activity activity, Campaign campaign) {
|
||||
this(activity);
|
||||
this.campaign = campaign;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public void startUpload(String rawTitle, Uri mediaUri, String description, String mimeType, String source, 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<Void, Void, Contribution>() {
|
||||
|
||||
// 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);
|
||||
onComplete.onUploadStarted(contribution);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue