Synced branch with master

This commit is contained in:
Vishan Seru 2018-02-18 00:32:25 +05:30
commit 4fc3040d52
479 changed files with 11666 additions and 3806 deletions

View file

@ -1,13 +1,8 @@
package fr.free.nrw.commons.contributions;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Parcel;
import android.os.RemoteException;
import android.text.TextUtils;
import android.support.annotation.NonNull;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -16,7 +11,6 @@ import java.util.Locale;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.settings.Prefs;
public class Contribution extends Media {
@ -43,7 +37,6 @@ public class Contribution extends Media {
public static final String SOURCE_GALLERY = "gallery";
public static final String SOURCE_EXTERNAL = "external";
private ContentProviderClient client;
private Uri contentUri;
private String source;
private String editSummary;
@ -51,24 +44,42 @@ public class Contribution extends Media {
private int state;
private long transferred;
private String decimalCoords;
private boolean isMultiple;
public boolean getMultiple() {
return isMultiple;
public Contribution(Uri contentUri, String filename, Uri localUri, String imageUrl, Date timestamp,
int state, long dataLength, Date dateUploaded, long transferred,
String source, String description, String creator, boolean isMultiple,
int width, int height, String license) {
super(localUri, imageUrl, filename, description, dataLength, timestamp, dateUploaded, creator);
this.contentUri = contentUri;
this.state = state;
this.timestamp = timestamp;
this.transferred = transferred;
this.source = source;
this.isMultiple = isMultiple;
this.width = width;
this.height = height;
this.license = license;
}
public void setMultiple(boolean multiple) {
isMultiple = multiple;
}
public Contribution(Uri localUri, String remoteUri, String filename, String description, long dataLength, Date dateCreated, Date dateUploaded, String creator, String editSummary, String decimalCoords) {
super(localUri, remoteUri, filename, description, dataLength, dateCreated, dateUploaded, creator);
public Contribution(Uri localUri, String imageUrl, String filename, String description, long dataLength,
Date dateCreated, Date dateUploaded, String creator, String editSummary, String decimalCoords) {
super(localUri, imageUrl, filename, description, dataLength, dateCreated, dateUploaded, creator);
this.decimalCoords = decimalCoords;
this.editSummary = editSummary;
timestamp = new Date(System.currentTimeMillis());
}
public Contribution(Parcel in) {
super(in);
contentUri = in.readParcelable(Uri.class.getClassLoader());
source = in.readString();
timestamp = (Date) in.readSerializable();
state = in.readInt();
transferred = in.readLong();
isMultiple = in.readInt() == 1;
}
@Override
public void writeToParcel(Parcel parcel, int flags) {
super.writeToParcel(parcel, flags);
@ -80,14 +91,12 @@ public class Contribution extends Media {
parcel.writeInt(isMultiple ? 1 : 0);
}
public Contribution(Parcel in) {
super(in);
contentUri = in.readParcelable(Uri.class.getClassLoader());
source = in.readString();
timestamp = (Date) in.readSerializable();
state = in.readInt();
transferred = in.readLong();
isMultiple = in.readInt() == 1;
public boolean getMultiple() {
return isMultiple;
}
public void setMultiple(boolean multiple) {
isMultiple = multiple;
}
public long getTransferred() {
@ -106,10 +115,18 @@ public class Contribution extends Media {
return contentUri;
}
public void setContentUri(Uri contentUri) {
this.contentUri = contentUri;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public int getState() {
return state;
}
@ -149,68 +166,12 @@ public class Contribution extends Media {
}
buffer.append("== {{int:license-header}} ==\n")
.append(Utils.licenseTemplateFor(getLicense())).append("\n\n")
.append(licenseTemplateFor(getLicense())).append("\n\n")
.append("{{Uploaded from Mobile|platform=Android|version=").append(BuildConfig.VERSION_NAME).append("}}\n")
.append(getTrackingTemplates());
return buffer.toString();
}
public void setContentProviderClient(ContentProviderClient client) {
this.client = client;
}
public void save() {
try {
if (contentUri == null) {
contentUri = client.insert(ContributionsContentProvider.BASE_URI, this.toContentValues());
} else {
client.update(contentUri, toContentValues(), null, null);
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
public void delete() {
try {
if (contentUri == null) {
// noooo
throw new RuntimeException("tried to delete item with no content URI");
} else {
client.delete(contentUri, null, null);
}
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
public ContentValues toContentValues() {
ContentValues cv = new ContentValues();
cv.put(Table.COLUMN_FILENAME, getFilename());
if (getLocalUri() != null) {
cv.put(Table.COLUMN_LOCAL_URI, getLocalUri().toString());
}
if (getImageUrl() != null) {
cv.put(Table.COLUMN_IMAGE_URL, getImageUrl());
}
if (getDateUploaded() != null) {
cv.put(Table.COLUMN_UPLOADED, getDateUploaded().getTime());
}
cv.put(Table.COLUMN_LENGTH, getDataLength());
cv.put(Table.COLUMN_TIMESTAMP, getTimestamp().getTime());
cv.put(Table.COLUMN_STATE, getState());
cv.put(Table.COLUMN_TRANSFERRED, transferred);
cv.put(Table.COLUMN_SOURCE, source);
cv.put(Table.COLUMN_DESCRIPTION, description);
cv.put(Table.COLUMN_CREATOR, creator);
cv.put(Table.COLUMN_MULTIPLE, isMultiple ? 1 : 0);
cv.put(Table.COLUMN_WIDTH, width);
cv.put(Table.COLUMN_HEIGHT, height);
cv.put(Table.COLUMN_LICENSE, license);
return cv;
}
@Override
public void setFilename(String filename) {
this.filename = filename;
@ -224,33 +185,6 @@ public class Contribution extends Media {
timestamp = new Date(System.currentTimeMillis());
}
public static Contribution fromCursor(Cursor cursor) {
// Hardcoding column positions!
Contribution c = new Contribution();
//Check that cursor has a value to avoid CursorIndexOutOfBoundsException
if (cursor.getCount() > 0) {
c.contentUri = ContributionsContentProvider.uriForId(cursor.getInt(0));
c.filename = cursor.getString(1);
c.localUri = TextUtils.isEmpty(cursor.getString(2)) ? null : Uri.parse(cursor.getString(2));
c.imageUrl = cursor.getString(3);
c.timestamp = cursor.getLong(4) == 0 ? null : new Date(cursor.getLong(4));
c.state = cursor.getInt(5);
c.dataLength = cursor.getLong(6);
c.dateUploaded = cursor.getLong(7) == 0 ? null : new Date(cursor.getLong(7));
c.transferred = cursor.getLong(8);
c.source = cursor.getString(9);
c.description = cursor.getString(10);
c.creator = cursor.getString(11);
c.isMultiple = cursor.getInt(12) == 1;
c.width = cursor.getInt(13);
c.height = cursor.getInt(14);
c.license = cursor.getString(15);
}
return c;
}
public String getSource() {
return source;
}
@ -267,118 +201,25 @@ public class Contribution extends Media {
this.decimalCoords = decimalCoords;
}
public static class Table {
public static final String TABLE_NAME = "contributions";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_FILENAME = "filename";
public static final String COLUMN_LOCAL_URI = "local_uri";
public static final String COLUMN_IMAGE_URL = "image_url";
public static final String COLUMN_TIMESTAMP = "timestamp";
public static final String COLUMN_STATE = "state";
public static final String COLUMN_LENGTH = "length";
public static final String COLUMN_UPLOADED = "uploaded";
public static final String COLUMN_TRANSFERRED = "transferred"; // Currently transferred number of bytes
public static final String COLUMN_SOURCE = "source";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_CREATOR = "creator"; // Initial uploader
public static final String COLUMN_MULTIPLE = "multiple";
public static final String COLUMN_WIDTH = "width";
public static final String COLUMN_HEIGHT = "height";
public static final String COLUMN_LICENSE = "license";
// 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_FILENAME,
COLUMN_LOCAL_URI,
COLUMN_IMAGE_URL,
COLUMN_TIMESTAMP,
COLUMN_STATE,
COLUMN_LENGTH,
COLUMN_UPLOADED,
COLUMN_TRANSFERRED,
COLUMN_SOURCE,
COLUMN_DESCRIPTION,
COLUMN_CREATOR,
COLUMN_MULTIPLE,
COLUMN_WIDTH,
COLUMN_HEIGHT,
COLUMN_LICENSE
};
private static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
+ "_id INTEGER PRIMARY KEY,"
+ "filename STRING,"
+ "local_uri STRING,"
+ "image_url STRING,"
+ "uploaded INTEGER,"
+ "timestamp INTEGER,"
+ "state INTEGER,"
+ "length INTEGER,"
+ "transferred INTEGER,"
+ "source STRING,"
+ "description STRING,"
+ "creator STRING,"
+ "multiple INTEGER,"
+ "width INTEGER,"
+ "height INTEGER,"
+ "LICENSE STRING"
+ ");";
public static void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_STATEMENT);
@NonNull
private String licenseTemplateFor(String license) {
switch (license) {
case Prefs.Licenses.CC_BY_3:
return "{{self|cc-by-3.0}}";
case Prefs.Licenses.CC_BY_4:
return "{{self|cc-by-4.0}}";
case Prefs.Licenses.CC_BY_SA_3:
return "{{self|cc-by-sa-3.0}}";
case Prefs.Licenses.CC_BY_SA_4:
return "{{self|cc-by-sa-4.0}}";
case Prefs.Licenses.CC0:
return "{{self|cc-zero}}";
case Prefs.Licenses.CC_BY:
return "{{self|cc-by-3.0}}";
case Prefs.Licenses.CC_BY_SA:
return "{{self|cc-by-sa-3.0}}";
}
public static void onDelete(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public static void onUpdate(SQLiteDatabase db, int from, int to) {
if (from == to) {
return;
}
if (from == 1) {
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN description STRING;");
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN creator STRING;");
from++;
onUpdate(db, from, to);
return;
}
if (from == 2) {
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN multiple INTEGER;");
db.execSQL("UPDATE " + TABLE_NAME + " SET multiple = 0");
from++;
onUpdate(db, from, to);
return;
}
if (from == 3) {
// Do nothing
from++;
onUpdate(db, from, to);
return;
}
if (from == 4) {
// Do nothing -- added Category
from++;
onUpdate(db, from, to);
return;
}
if (from == 5) {
// Added width and height fields
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN width INTEGER;");
db.execSQL("UPDATE " + TABLE_NAME + " SET width = 0");
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN height INTEGER;");
db.execSQL("UPDATE " + TABLE_NAME + " SET height = 0");
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN license STRING;");
db.execSQL("UPDATE " + TABLE_NAME + " SET license='" + Prefs.Licenses.CC_BY_SA_3 + "';");
from++;
onUpdate(db, from, to);
return;
}
}
throw new RuntimeException("Unrecognized license value: " + license);
}
}

View file

@ -93,10 +93,15 @@ class ContributionController {
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_GALLERY);
break;
case SELECT_FROM_CAMERA:
shareIntent.setType("image/jpeg"); //FIXME: Find out appropriate mime type
//FIXME: Find out appropriate mime type
// AFAIK this is the right type for a JPEG image
// https://developer.android.com/training/sharing/send.html#send-binary-content
shareIntent.setType("image/jpeg");
shareIntent.putExtra(EXTRA_STREAM, lastGeneratedCaptureUri);
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_CAMERA);
break;
default:
break;
}
Timber.i("Image selected");
try {

View file

@ -0,0 +1,281 @@
package fr.free.nrw.commons.contributions;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import java.util.Date;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import fr.free.nrw.commons.settings.Prefs;
import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS;
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI;
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.uriForId;
public class ContributionDao {
/*
This sorts in the following order:
Currently Uploading
Failed (Sorted in ascending order of time added - FIFO)
Queued to Upload (Sorted in ascending order of time added - FIFO)
Completed (Sorted in descending order of time added)
This is why Contribution.STATE_COMPLETED is -1.
*/
static final String CONTRIBUTION_SORT = Table.COLUMN_STATE + " DESC, "
+ Table.COLUMN_UPLOADED + " DESC , ("
+ Table.COLUMN_TIMESTAMP + " * "
+ Table.COLUMN_STATE + ")";
private final Provider<ContentProviderClient> clientProvider;
@Inject
public ContributionDao(@Named("contribution") Provider<ContentProviderClient> clientProvider) {
this.clientProvider = clientProvider;
}
Cursor loadAllContributions() {
ContentProviderClient db = clientProvider.get();
try {
return db.query(BASE_URI, ALL_FIELDS, "", null, CONTRIBUTION_SORT);
} catch (RemoteException e) {
return null;
} finally {
db.release();
}
}
public void save(Contribution contribution) {
ContentProviderClient db = clientProvider.get();
try {
if (contribution.getContentUri() == null) {
contribution.setContentUri(db.insert(BASE_URI, toContentValues(contribution)));
} else {
db.update(contribution.getContentUri(), toContentValues(contribution), null, null);
}
} catch (RemoteException e) {
throw new RuntimeException(e);
} finally {
db.release();
}
}
public void delete(Contribution contribution) {
ContentProviderClient db = clientProvider.get();
try {
if (contribution.getContentUri() == null) {
// noooo
throw new RuntimeException("tried to delete item with no content URI");
} else {
db.delete(contribution.getContentUri(), null, null);
}
} catch (RemoteException e) {
throw new RuntimeException(e);
} finally {
db.release();
}
}
ContentValues toContentValues(Contribution contribution) {
ContentValues cv = new ContentValues();
cv.put(Table.COLUMN_FILENAME, contribution.getFilename());
if (contribution.getLocalUri() != null) {
cv.put(Table.COLUMN_LOCAL_URI, contribution.getLocalUri().toString());
}
if (contribution.getImageUrl() != null) {
cv.put(Table.COLUMN_IMAGE_URL, contribution.getImageUrl());
}
if (contribution.getDateUploaded() != null) {
cv.put(Table.COLUMN_UPLOADED, contribution.getDateUploaded().getTime());
}
cv.put(Table.COLUMN_LENGTH, contribution.getDataLength());
cv.put(Table.COLUMN_TIMESTAMP, contribution.getTimestamp().getTime());
cv.put(Table.COLUMN_STATE, contribution.getState());
cv.put(Table.COLUMN_TRANSFERRED, contribution.getTransferred());
cv.put(Table.COLUMN_SOURCE, contribution.getSource());
cv.put(Table.COLUMN_DESCRIPTION, contribution.getDescription());
cv.put(Table.COLUMN_CREATOR, contribution.getCreator());
cv.put(Table.COLUMN_MULTIPLE, contribution.getMultiple() ? 1 : 0);
cv.put(Table.COLUMN_WIDTH, contribution.getWidth());
cv.put(Table.COLUMN_HEIGHT, contribution.getHeight());
cv.put(Table.COLUMN_LICENSE, contribution.getLicense());
return cv;
}
public Contribution fromCursor(Cursor cursor) {
// Hardcoding column positions!
//Check that cursor has a value to avoid CursorIndexOutOfBoundsException
if (cursor.getCount() > 0) {
return new Contribution(
uriForId(cursor.getInt(0)),
cursor.getString(1),
parseUri(cursor.getString(2)),
cursor.getString(3),
parseTimestamp(cursor.getLong(4)),
cursor.getInt(5),
cursor.getLong(6),
parseTimestamp(cursor.getLong(7)),
cursor.getLong(8),
cursor.getString(9),
cursor.getString(10),
cursor.getString(11),
cursor.getInt(12) == 1,
cursor.getInt(13),
cursor.getInt(14),
cursor.getString(15));
}
return null;
}
@Nullable
private static Date parseTimestamp(long timestamp) {
return timestamp == 0 ? null : new Date(timestamp);
}
@Nullable
private static Uri parseUri(String uriString) {
return TextUtils.isEmpty(uriString) ? null : Uri.parse(uriString);
}
public static class Table {
public static final String TABLE_NAME = "contributions";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_FILENAME = "filename";
public static final String COLUMN_LOCAL_URI = "local_uri";
public static final String COLUMN_IMAGE_URL = "image_url";
public static final String COLUMN_TIMESTAMP = "timestamp";
public static final String COLUMN_STATE = "state";
public static final String COLUMN_LENGTH = "length";
public static final String COLUMN_UPLOADED = "uploaded";
public static final String COLUMN_TRANSFERRED = "transferred"; // Currently transferred number of bytes
public static final String COLUMN_SOURCE = "source";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_CREATOR = "creator"; // Initial uploader
public static final String COLUMN_MULTIPLE = "multiple";
public static final String COLUMN_WIDTH = "width";
public static final String COLUMN_HEIGHT = "height";
public static final String COLUMN_LICENSE = "license";
// 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_FILENAME,
COLUMN_LOCAL_URI,
COLUMN_IMAGE_URL,
COLUMN_TIMESTAMP,
COLUMN_STATE,
COLUMN_LENGTH,
COLUMN_UPLOADED,
COLUMN_TRANSFERRED,
COLUMN_SOURCE,
COLUMN_DESCRIPTION,
COLUMN_CREATOR,
COLUMN_MULTIPLE,
COLUMN_WIDTH,
COLUMN_HEIGHT,
COLUMN_LICENSE
};
public static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
public static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
+ "_id INTEGER PRIMARY KEY,"
+ "filename STRING,"
+ "local_uri STRING,"
+ "image_url STRING,"
+ "uploaded INTEGER,"
+ "timestamp INTEGER,"
+ "state INTEGER,"
+ "length INTEGER,"
+ "transferred INTEGER,"
+ "source STRING,"
+ "description STRING,"
+ "creator STRING,"
+ "multiple INTEGER,"
+ "width INTEGER,"
+ "height INTEGER,"
+ "LICENSE STRING"
+ ");";
// Upgrade from version 1 ->
static final String ADD_CREATOR_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN creator STRING;";
static final String ADD_DESCRIPTION_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN description STRING;";
// Upgrade from version 2 ->
static final String ADD_MULTIPLE_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN multiple INTEGER;";
static final String SET_DEFAULT_MULTIPLE = "UPDATE " + TABLE_NAME + " SET multiple = 0";
// Upgrade from version 5 ->
static final String ADD_WIDTH_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN width INTEGER;";
static final String SET_DEFAULT_WIDTH = "UPDATE " + TABLE_NAME + " SET width = 0";
static final String ADD_HEIGHT_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN height INTEGER;";
static final String SET_DEFAULT_HEIGHT = "UPDATE " + TABLE_NAME + " SET height = 0";
static final String ADD_LICENSE_FIELD = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN license STRING;";
static final String SET_DEFAULT_LICENSE = "UPDATE " + TABLE_NAME + " SET license='" + Prefs.Licenses.CC_BY_SA_3 + "';";
public static void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_STATEMENT);
}
public static void onDelete(SQLiteDatabase db) {
db.execSQL(DROP_TABLE_STATEMENT);
onCreate(db);
}
public static void onUpdate(SQLiteDatabase db, int from, int to) {
if (from == to) {
return;
}
if (from == 1) {
db.execSQL(ADD_DESCRIPTION_FIELD);
db.execSQL(ADD_CREATOR_FIELD);
from++;
onUpdate(db, from, to);
return;
}
if (from == 2) {
db.execSQL(ADD_MULTIPLE_FIELD);
db.execSQL(SET_DEFAULT_MULTIPLE);
from++;
onUpdate(db, from, to);
return;
}
if (from == 3) {
// Do nothing
from++;
onUpdate(db, from, to);
return;
}
if (from == 4) {
// Do nothing -- added Category
from++;
onUpdate(db, from, to);
return;
}
if (from == 5) {
// Added width and height fields
db.execSQL(ADD_WIDTH_FIELD);
db.execSQL(SET_DEFAULT_WIDTH);
db.execSQL(ADD_HEIGHT_FIELD);
db.execSQL(SET_DEFAULT_HEIGHT);
db.execSQL(ADD_LICENSE_FIELD);
db.execSQL(SET_DEFAULT_LICENSE);
from++;
onUpdate(db, from, to);
return;
}
}
}
}

View file

@ -9,7 +9,6 @@ import android.database.Cursor;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
@ -23,13 +22,17 @@ import android.widget.AdapterView;
import java.util.ArrayList;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.ButterKnife;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.HandlerService;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.AuthenticatedActivity;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.settings.Prefs;
import fr.free.nrw.commons.upload.UploadService;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -39,15 +42,22 @@ import timber.log.Timber;
import static android.content.ContentResolver.requestSync;
import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED;
import static fr.free.nrw.commons.contributions.Contribution.Table.ALL_FIELDS;
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.AUTHORITY;
import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS;
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI;
import static fr.free.nrw.commons.settings.Prefs.UPLOADS_SHOWING;
public class ContributionsActivity extends AuthenticatedActivity
implements LoaderManager.LoaderCallbacks<Cursor>, AdapterView.OnItemClickListener,
MediaDetailPagerFragment.MediaDetailProvider, FragmentManager.OnBackStackChangedListener,
ContributionsListFragment.SourceRefresher {
public class ContributionsActivity
extends AuthenticatedActivity
implements LoaderManager.LoaderCallbacks<Cursor>,
AdapterView.OnItemClickListener,
MediaDetailPagerFragment.MediaDetailProvider,
FragmentManager.OnBackStackChangedListener,
ContributionsListFragment.SourceRefresher {
@Inject MediaWikiApi mediaWikiApi;
@Inject SessionManager sessionManager;
@Inject @Named("default_preferences") SharedPreferences prefs;
@Inject ContributionDao contributionDao;
private Cursor allContributions;
private ContributionsListFragment contributionsList;
@ -55,21 +65,6 @@ public class ContributionsActivity extends AuthenticatedActivity
private UploadService uploadService;
private boolean isUploadServiceConnected;
private ArrayList<DataSetObserver> observersWaitingForLoad = new ArrayList<>();
private String CONTRIBUTION_SELECTION = "";
/*
This sorts in the following order:
Currently Uploading
Failed (Sorted in ascending order of time added - FIFO)
Queued to Upload (Sorted in ascending order of time added - FIFO)
Completed (Sorted in descending order of time added)
This is why Contribution.STATE_COMPLETED is -1.
*/
private String CONTRIBUTION_SORT = Contribution.Table.COLUMN_STATE + " DESC, "
+ Contribution.Table.COLUMN_UPLOADED + " DESC , ("
+ Contribution.Table.COLUMN_TIMESTAMP + " * "
+ Contribution.Table.COLUMN_STATE + ")";
private CompositeDisposable compositeDisposable = new CompositeDisposable();
@ -84,7 +79,7 @@ public class ContributionsActivity extends AuthenticatedActivity
@Override
public void onServiceDisconnected(ComponentName componentName) {
// this should never happen
throw new RuntimeException("UploadService died but the rest of the process did not!");
Timber.e(new RuntimeException("UploadService died but the rest of the process did not!"));
}
};
@ -101,12 +96,8 @@ public class ContributionsActivity extends AuthenticatedActivity
@Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean isSettingsChanged =
sharedPreferences.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false);
editor.apply();
boolean isSettingsChanged = prefs.getBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false);
prefs.edit().putBoolean(Prefs.IS_CONTRIBUTION_COUNT_CHANGED, false).apply();
if (isSettingsChanged) {
refreshSource();
}
@ -114,16 +105,14 @@ public class ContributionsActivity extends AuthenticatedActivity
@Override
protected void onAuthCookieAcquired(String authCookie) {
// Do a sync every time we get here!
CommonsApplication app = ((CommonsApplication) getApplication());
requestSync(app.getCurrentAccount(), AUTHORITY, new Bundle());
// Do a sync everytime we get here!
requestSync(sessionManager.getCurrentAccount(), ContributionsContentProvider.CONTRIBUTION_AUTHORITY, new Bundle());
Intent uploadServiceIntent = new Intent(this, UploadService.class);
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
startService(uploadServiceIntent);
bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
allContributions = getContentResolver().query(BASE_URI, ALL_FIELDS,
CONTRIBUTION_SELECTION, null, CONTRIBUTION_SORT);
allContributions = contributionDao.loadAllContributions();
getSupportLoaderManager().initLoader(0, null, this);
}
@ -137,17 +126,20 @@ public class ContributionsActivity extends AuthenticatedActivity
// Activity can call methods in the fragment by acquiring a
// reference to the Fragment from FragmentManager, using findFragmentById()
FragmentManager supportFragmentManager = getSupportFragmentManager();
contributionsList = (ContributionsListFragment) supportFragmentManager
contributionsList = (ContributionsListFragment)supportFragmentManager
.findFragmentById(R.id.contributionsListFragment);
supportFragmentManager.addOnBackStackChangedListener(this);
if (savedInstanceState != null) {
mediaDetails = (MediaDetailPagerFragment) supportFragmentManager
mediaDetails = (MediaDetailPagerFragment)supportFragmentManager
.findFragmentById(R.id.contributionsFragmentContainer);
getSupportLoaderManager().initLoader(0, null, this);
}
requestAuthToken();
initDrawer();
setTitle(getString(R.string.title_activity_contributions));
setUploadCount();
}
@Override
@ -178,24 +170,23 @@ public class ContributionsActivity extends AuthenticatedActivity
public void retryUpload(int i) {
allContributions.moveToPosition(i);
Contribution c = Contribution.fromCursor(allContributions);
Contribution c = contributionDao.fromCursor(allContributions);
if (c.getState() == STATE_FAILED) {
uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c);
Timber.d("Restarting for %s", c.toContentValues());
Timber.d("Restarting for %s", c.toString());
} else {
Timber.d("Skipping re-upload for non-failed %s", c.toContentValues());
Timber.d("Skipping re-upload for non-failed %s", c.toString());
}
}
public void deleteUpload(int i) {
allContributions.moveToPosition(i);
Contribution c = Contribution.fromCursor(allContributions);
Contribution c = contributionDao.fromCursor(allContributions);
if (c.getState() == STATE_FAILED) {
Timber.d("Deleting failed contrib %s", c.toContentValues());
c.setContentProviderClient(getContentResolver().acquireContentProviderClient(AUTHORITY));
c.delete();
Timber.d("Deleting failed contrib %s", c.toString());
contributionDao.delete(c);
} else {
Timber.d("Skipping deletion for non-failed contrib %s", c.toContentValues());
Timber.d("Skipping deletion for non-failed contrib %s", c.toString());
}
}
@ -229,24 +220,23 @@ public class ContributionsActivity extends AuthenticatedActivity
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
int uploads = sharedPref.getInt(UPLOADS_SHOWING, 100);
int uploads = prefs.getInt(UPLOADS_SHOWING, 100);
return new CursorLoader(this, BASE_URI,
ALL_FIELDS, CONTRIBUTION_SELECTION, null,
CONTRIBUTION_SORT + "LIMIT " + uploads);
ALL_FIELDS, "", null,
ContributionDao.CONTRIBUTION_SORT + "LIMIT " + uploads);
}
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
contributionsList.changeProgressBarVisibility(false);
if (contributionsList.getAdapter() == null) {
contributionsList.setAdapter(new ContributionsListAdapter(getApplicationContext(),
cursor, 0));
cursor, 0, contributionDao));
} else {
((CursorAdapter) contributionsList.getAdapter()).swapCursor(cursor);
}
setUploadCount();
contributionsList.clearSyncMessage();
notifyAndMigrateDataSetObservers();
}
@ -263,7 +253,7 @@ public class ContributionsActivity extends AuthenticatedActivity
// not yet ready to return data
return null;
} else {
return Contribution.fromCursor((Cursor) contributionsList.getAdapter().getItem(i));
return contributionDao.fromCursor((Cursor) contributionsList.getAdapter().getItem(i));
}
}
@ -277,19 +267,16 @@ public class ContributionsActivity extends AuthenticatedActivity
@SuppressWarnings("ConstantConditions")
private void setUploadCount() {
CommonsApplication app = ((CommonsApplication) getApplication());
compositeDisposable.add(
app.getMWApi()
.getUploadCount(app.getCurrentAccount().name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
uploadCount -> getSupportActionBar().setSubtitle(getResources()
.getQuantityString(R.plurals.contributions_subtitle,
uploadCount, uploadCount)),
t -> Timber.e(t, "Fetching upload count failed")
)
);
compositeDisposable.add(mediaWikiApi
.getUploadCount(sessionManager.getCurrentAccount().name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
uploadCount -> getSupportActionBar().setSubtitle(getResources()
.getQuantityString(R.plurals.contributions_subtitle,
uploadCount, uploadCount)),
t -> Timber.e(t, "Fetching upload count failed")
));
}
@Override
@ -341,9 +328,4 @@ public class ContributionsActivity extends AuthenticatedActivity
public void refreshSource() {
getSupportLoaderManager().restartLoader(0, null, this);
}
public static void startYourself(Context context) {
context.startActivity(new Intent(context, ContributionsActivity.class));
}
}

View file

@ -1,6 +1,5 @@
package fr.free.nrw.commons.contributions;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
@ -10,36 +9,36 @@ import android.net.Uri;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import fr.free.nrw.commons.CommonsApplication;
import javax.inject.Inject;
import fr.free.nrw.commons.data.DBOpenHelper;
import fr.free.nrw.commons.di.CommonsDaggerContentProvider;
import timber.log.Timber;
import static android.content.UriMatcher.NO_MATCH;
import static fr.free.nrw.commons.contributions.Contribution.Table.ALL_FIELDS;
import static fr.free.nrw.commons.contributions.Contribution.Table.TABLE_NAME;
import static fr.free.nrw.commons.contributions.ContributionDao.Table.ALL_FIELDS;
import static fr.free.nrw.commons.contributions.ContributionDao.Table.TABLE_NAME;
public class ContributionsContentProvider extends ContentProvider {
public class ContributionsContentProvider extends CommonsDaggerContentProvider {
private static final int CONTRIBUTIONS = 1;
private static final int CONTRIBUTIONS_ID = 2;
private static final String BASE_PATH = "contributions";
private static final UriMatcher uriMatcher = new UriMatcher(NO_MATCH);
public static final String AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider";
public static final String CONTRIBUTION_AUTHORITY = "fr.free.nrw.commons.contributions.contentprovider";
public static final Uri BASE_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
public static final Uri BASE_URI = Uri.parse("content://" + CONTRIBUTION_AUTHORITY + "/" + BASE_PATH);
static {
uriMatcher.addURI(AUTHORITY, BASE_PATH, CONTRIBUTIONS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID);
uriMatcher.addURI(CONTRIBUTION_AUTHORITY, BASE_PATH, CONTRIBUTIONS);
uriMatcher.addURI(CONTRIBUTION_AUTHORITY, BASE_PATH + "/#", CONTRIBUTIONS_ID);
}
public static Uri uriForId(int id) {
return Uri.parse(BASE_URI.toString() + "/" + id);
}
@Override
public boolean onCreate() {
return false;
}
@Inject DBOpenHelper dbOpenHelper;
@SuppressWarnings("ConstantConditions")
@Override
@ -50,8 +49,7 @@ public class ContributionsContentProvider extends ContentProvider {
int uriType = uriMatcher.match(uri);
CommonsApplication app = (CommonsApplication) getContext().getApplicationContext();
SQLiteDatabase db = app.getDBOpenHelper().getReadableDatabase();
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor;
switch (uriType) {
@ -87,8 +85,7 @@ public class ContributionsContentProvider extends ContentProvider {
@Override
public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
int uriType = uriMatcher.match(uri);
CommonsApplication app = (CommonsApplication) getContext().getApplicationContext();
SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase();
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
long id;
switch (uriType) {
case CONTRIBUTIONS:
@ -107,13 +104,12 @@ public class ContributionsContentProvider extends ContentProvider {
int rows;
int uriType = uriMatcher.match(uri);
CommonsApplication app = (CommonsApplication) getContext().getApplicationContext();
SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase();
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (uriType) {
case CONTRIBUTIONS_ID:
Timber.d("Deleting contribution id %s", uri.getLastPathSegment());
rows = sqlDB.delete(TABLE_NAME,
rows = db.delete(TABLE_NAME,
"_id = ?",
new String[]{uri.getLastPathSegment()}
);
@ -130,8 +126,7 @@ public class ContributionsContentProvider extends ContentProvider {
public int bulkInsert(@NonNull Uri uri, @NonNull ContentValues[] values) {
Timber.d("Hello, bulk insert! (ContributionsContentProvider)");
int uriType = uriMatcher.match(uri);
CommonsApplication app = (CommonsApplication) getContext().getApplicationContext();
SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase();
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
sqlDB.beginTransaction();
switch (uriType) {
case CONTRIBUTIONS:
@ -162,8 +157,7 @@ public class ContributionsContentProvider extends ContentProvider {
error out otherwise.
*/
int uriType = uriMatcher.match(uri);
CommonsApplication app = (CommonsApplication) getContext().getApplicationContext();
SQLiteDatabase sqlDB = app.getDBOpenHelper().getWritableDatabase();
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
int rowsUpdated;
switch (uriType) {
case CONTRIBUTIONS:
@ -175,7 +169,7 @@ public class ContributionsContentProvider extends ContentProvider {
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqlDB.update(TABLE_NAME,
contentValues,
Contribution.Table.COLUMN_ID + " = ?",
ContributionDao.Table.COLUMN_ID + " = ?",
new String[]{String.valueOf(id)});
} else {
throw new IllegalArgumentException(

View file

@ -11,8 +11,11 @@ import fr.free.nrw.commons.R;
class ContributionsListAdapter extends CursorAdapter {
public ContributionsListAdapter(Context context, Cursor c, int flags) {
private final ContributionDao contributionDao;
public ContributionsListAdapter(Context context, Cursor c, int flags, ContributionDao contributionDao) {
super(context, c, flags);
this.contributionDao = contributionDao;
}
@Override
@ -26,7 +29,7 @@ class ContributionsListAdapter extends CursorAdapter {
@Override
public void bindView(View view, Context context, Cursor cursor) {
final ContributionViewHolder views = (ContributionViewHolder)view.getTag();
final Contribution contribution = Contribution.fromCursor(cursor);
final Contribution contribution = contributionDao.fromCursor(cursor);
views.imageView.setMedia(contribution);
views.titleView.setText(contribution.getDisplayTitle());
@ -34,7 +37,7 @@ class ContributionsListAdapter extends CursorAdapter {
views.seqNumView.setText(String.valueOf(cursor.getPosition() + 1));
views.seqNumView.setVisibility(View.VISIBLE);
switch(contribution.getState()) {
switch (contribution.getState()) {
case Contribution.STATE_COMPLETED:
views.stateView.setVisibility(View.GONE);
views.progressView.setVisibility(View.GONE);
@ -50,7 +53,7 @@ class ContributionsListAdapter extends CursorAdapter {
views.progressView.setVisibility(View.VISIBLE);
long total = contribution.getDataLength();
long transferred = contribution.getTransferred();
if(transferred == 0 || transferred >= total) {
if (transferred == 0 || transferred >= total) {
views.progressView.setIndeterminate(true);
} else {
views.progressView.setProgress((int)(((double)transferred / (double)total) * 100));

View file

@ -5,9 +5,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
@ -19,30 +17,43 @@ import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ListAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Named;
import butterknife.BindView;
import butterknife.ButterKnife;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.nearby.NearbyActivity;
import timber.log.Timber;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.app.Activity.RESULT_OK;
import static android.content.Context.MODE_PRIVATE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.View.GONE;
public class ContributionsListFragment extends Fragment {
public class ContributionsListFragment extends CommonsDaggerSupportFragment {
@BindView(R.id.contributionsList)
GridView contributionsList;
@BindView(R.id.waitingMessage)
TextView waitingMessage;
@BindView(R.id.emptyMessage)
TextView emptyMessage;
@BindView(R.id.loadingContributionsProgressBar)
ProgressBar progressBar;
@Inject
@Named("prefs")
SharedPreferences prefs;
@Inject
@Named("default_preferences")
SharedPreferences defaultPrefs;
private ContributionController controller;
@Override
@ -57,7 +68,6 @@ public class ContributionsListFragment extends Fragment {
}
//TODO: Should this be in onResume?
SharedPreferences prefs = getActivity().getSharedPreferences("prefs", MODE_PRIVATE);
String lastModified = prefs.getString("lastSyncTimestamp", "");
Timber.d("Last Sync Timestamp: %s", lastModified);
@ -67,6 +77,7 @@ public class ContributionsListFragment extends Fragment {
waitingMessage.setVisibility(GONE);
}
changeProgressBarVisibility(true);
return v;
}
@ -78,6 +89,10 @@ public class ContributionsListFragment extends Fragment {
this.contributionsList.setAdapter(adapter);
}
public void changeProgressBarVisibility(boolean isVisible) {
this.progressBar.setVisibility(isVisible ? View.VISIBLE : View.GONE);
}
@Override
public void onSaveInstanceState(Bundle outState) {
if (outState == null) {
@ -155,9 +170,7 @@ public class ContributionsListFragment extends Fragment {
return true;
case R.id.menu_from_camera:
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(CommonsApplication.getInstance());
boolean useExtStorage = sharedPref.getBoolean("useExternalStorage", true);
boolean useExtStorage = defaultPrefs.getBoolean("useExternalStorage", true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && useExtStorage) {
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(getActivity(), WRITE_EXTERNAL_STORAGE)
@ -201,7 +214,7 @@ public class ContributionsListFragment extends Fragment {
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult: req code = " + " perm = "
+ permissions + " grant =" + grantResults);
+ Arrays.toString(permissions) + " grant =" + Arrays.toString(grantResults));
switch (requestCode) {
// 1 = Storage allowed when gallery selected
@ -235,12 +248,17 @@ public class ContributionsListFragment extends Fragment {
menu.clear(); // See http://stackoverflow.com/a/8495697/17865
inflater.inflate(R.menu.fragment_contributions_list, menu);
CommonsApplication app = (CommonsApplication) getContext().getApplicationContext();
if (!app.deviceHasCamera()) {
if (!deviceHasCamera()) {
menu.findItem(R.id.menu_from_camera).setEnabled(false);
}
}
public boolean deviceHasCamera() {
PackageManager pm = getContext().getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) ||
pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View file

@ -13,21 +13,27 @@ import android.os.RemoteException;
import android.text.TextUtils;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import javax.inject.Inject;
import javax.inject.Named;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.mwapi.LogEventResult;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import timber.log.Timber;
import static android.content.Context.MODE_PRIVATE;
import static fr.free.nrw.commons.contributions.Contribution.STATE_COMPLETED;
import static fr.free.nrw.commons.contributions.Contribution.Table.COLUMN_FILENAME;
import static fr.free.nrw.commons.contributions.ContributionDao.Table.COLUMN_FILENAME;
import static fr.free.nrw.commons.contributions.ContributionsContentProvider.BASE_URI;
@SuppressWarnings("WeakerAccess")
public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
private static final String[] existsQuery = {COLUMN_FILENAME};
@ -35,6 +41,10 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
private static final ContentValues[] EMPTY = {};
private static int COMMIT_THRESHOLD = 10;
@SuppressWarnings("WeakerAccess")
@Inject MediaWikiApi mwApi;
@Inject @Named("prefs") SharedPreferences prefs;
public ContributionsSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
}
@ -47,6 +57,9 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
}
private boolean fileExists(ContentProviderClient client, String filename) {
if (filename == null) {
return false;
}
Cursor cursor = null;
try {
cursor = client.query(BASE_URI,
@ -68,19 +81,23 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
@Override
public void onPerformSync(Account account, Bundle bundle, String authority,
ContentProviderClient contentProviderClient, SyncResult syncResult) {
ApplicationlessInjection
.getInstance(getContext()
.getApplicationContext())
.getCommonsApplicationComponent()
.inject(this);
// This code is fraught with possibilities of race conditions, but lalalalala I can't hear you!
String user = account.name;
MediaWikiApi api = CommonsApplication.getInstance().getMWApi();
SharedPreferences prefs = getContext().getSharedPreferences("prefs", MODE_PRIVATE);
String lastModified = prefs.getString("lastSyncTimestamp", "");
Date curTime = new Date();
LogEventResult result;
Boolean done = false;
String queryContinue = null;
ContributionDao contributionDao = new ContributionDao(() -> contentProviderClient);
while (!done) {
try {
result = api.logEvents(user, lastModified, queryContinue, getLimit());
result = mwApi.logEvents(user, lastModified, queryContinue, getLimit());
} catch (IOException e) {
// There isn't really much we can do, eh?
// FIXME: Perhaps add EventLogging?
@ -109,7 +126,7 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
"", -1, dateUpdated, dateUpdated, user,
"", "");
contrib.setState(STATE_COMPLETED);
imageValues.add(contrib.toContentValues());
imageValues.add(contributionDao.toContentValues(contrib));
if (imageValues.size() % COMMIT_THRESHOLD == 0) {
try {
@ -134,8 +151,13 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
done = true;
}
}
prefs.edit().putString("lastSyncTimestamp", Utils.toMWDate(curTime)).apply();
prefs.edit().putString("lastSyncTimestamp", toMWDate(curTime)).apply();
Timber.d("Oh hai, everyone! Look, a kitty!");
}
private String toMWDate(Date date) {
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC
isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return isoFormat.format(date);
}
}