11package fr .free .nrw .commons .contributions ;
22
33import android .accounts .Account ;
4+ import android .annotation .SuppressLint ;
45import android .content .AbstractThreadedSyncAdapter ;
56import android .content .ContentProviderClient ;
67import android .content .ContentValues ;
1112import android .os .RemoteException ;
1213import android .text .TextUtils ;
1314
15+ import org .wikipedia .dataclient .mwapi .MwQueryLogEvent ;
16+ import org .wikipedia .dataclient .mwapi .MwQueryResult ;
1417import org .wikipedia .util .DateUtil ;
1518
1619import java .io .IOException ;
2629import fr .free .nrw .commons .kvstore .JsonKvStore ;
2730import fr .free .nrw .commons .mwapi .LogEventResult ;
2831import fr .free .nrw .commons .mwapi .MediaWikiApi ;
32+ import fr .free .nrw .commons .mwapi .UserClient ;
2933import timber .log .Timber ;
3034
3135import static fr .free .nrw .commons .contributions .Contribution .STATE_COMPLETED ;
@@ -44,8 +48,8 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
4448 // into the app, rather than the user's setting. Also see Github issue #52.
4549 public static final int ABSOLUTE_CONTRIBUTIONS_LOAD_LIMIT = 500 ;
4650
47- @ SuppressWarnings ( "WeakerAccess" )
48- @ Inject MediaWikiApi mwApi ;
51+ @ Inject
52+ UserClient userClient ;
4953 @ Inject
5054 @ Named ("default_preferences" )
5155 JsonKvStore defaultKvStore ;
@@ -58,24 +62,19 @@ private boolean fileExists(ContentProviderClient client, String filename) {
5862 if (filename == null ) {
5963 return false ;
6064 }
61- Cursor cursor = null ;
62- try {
63- cursor = client .query (BASE_URI ,
64- existsQuery ,
65- existsSelection ,
66- new String []{filename },
67- ""
68- );
65+ try (Cursor cursor = client .query (BASE_URI ,
66+ existsQuery ,
67+ existsSelection ,
68+ new String []{filename },
69+ ""
70+ )) {
6971 return cursor != null && cursor .getCount () != 0 ;
7072 } catch (RemoteException e ) {
7173 throw new RuntimeException (e );
72- } finally {
73- if (cursor != null ) {
74- cursor .close ();
75- }
7674 }
7775 }
7876
77+ @ SuppressLint ("CheckResult" )
7978 @ Override
8079 public void onPerformSync (Account account , Bundle bundle , String authority ,
8180 ContentProviderClient contentProviderClient , SyncResult syncResult ) {
@@ -84,71 +83,20 @@ public void onPerformSync(Account account, Bundle bundle, String authority,
8483 .getApplicationContext ())
8584 .getCommonsApplicationComponent ()
8685 .inject (this );
87- // This code is fraught with possibilities of race conditions, but lalalalala I can't hear you!
86+ // This code is(was?) fraught with possibilities of race conditions, but lalalalala I can't hear you!
8887 String user = account .name ;
89- String lastModified = defaultKvStore .getString ("lastSyncTimestamp" , "" );
90- Date curTime = new Date ();
91- LogEventResult result ;
92- Boolean done = false ;
93- String queryContinue = null ;
9488 ContributionDao contributionDao = new ContributionDao (() -> contentProviderClient );
95- while (!done ) {
96-
97- try {
98- result = mwApi .logEvents (user , lastModified , queryContinue , ABSOLUTE_CONTRIBUTIONS_LOAD_LIMIT );
99- } catch (IOException e ) {
100- // There isn't really much we can do, eh?
101- // FIXME: Perhaps add EventLogging?
102- syncResult .stats .numIoExceptions += 1 ; // Not sure if this does anything. Shitty docs
103- Timber .d ("Syncing failed due to %s" , e );
104- return ;
105- }
106- Timber .d ("Last modified at %s" , lastModified );
107-
108- List <LogEventResult .LogEvent > logEvents = result .getLogEvents ();
109- Timber .d ("%d results!" , logEvents .size ());
110- ArrayList <ContentValues > imageValues = new ArrayList <>();
111- for (LogEventResult .LogEvent image : logEvents ) {
112- if (image .isDeleted ()) {
113- // means that this upload was deleted.
114- continue ;
115- }
116- String filename = image .getFilename ();
117- if (fileExists (contentProviderClient , filename )) {
118- Timber .d ("Skipping %s" , filename );
119- continue ;
120- }
121- Date dateUpdated = image .getDateUpdated ();
122- Contribution contrib = new Contribution (null , null , filename ,
123- "" , -1 , dateUpdated , dateUpdated , user ,
124- "" , "" );
125- contrib .setState (STATE_COMPLETED );
126- imageValues .add (contributionDao .toContentValues (contrib ));
127-
128- if (imageValues .size () % COMMIT_THRESHOLD == 0 ) {
129- try {
130- contentProviderClient .bulkInsert (BASE_URI , imageValues .toArray (EMPTY ));
131- } catch (RemoteException e ) {
132- throw new RuntimeException (e );
133- }
134- imageValues .clear ();
135- }
136- }
137-
138- if (imageValues .size () != 0 ) {
139- try {
140- contentProviderClient .bulkInsert (BASE_URI , imageValues .toArray (EMPTY ));
141- } catch (RemoteException e ) {
142- throw new RuntimeException (e );
143- }
144- }
145-
146- queryContinue = result .getQueryContinue ();
147- if (TextUtils .isEmpty (queryContinue )) {
148- done = true ;
149- }
150- }
151- defaultKvStore .putString ("lastSyncTimestamp" , DateUtil .iso8601DateFormat (curTime ));
89+ userClient .logEvents (user )
90+ .doOnNext (mwQueryLogEvent ->Timber .d ("Received image %s" , mwQueryLogEvent .title () ))
91+ .filter (mwQueryLogEvent -> !mwQueryLogEvent .isDeleted ())
92+ .filter (mwQueryLogEvent -> !fileExists (contentProviderClient , mwQueryLogEvent .title ()))
93+ .doOnNext (mwQueryLogEvent ->Timber .d ("Image %s passed filters" , mwQueryLogEvent .title () ))
94+ .map (image -> new Contribution (null , null , image .title (),
95+ "" , -1 , image .date (), image .date (), user ,
96+ "" , "" , STATE_COMPLETED ))
97+ .map (contributionDao ::toContentValues )
98+ .buffer (10 )
99+ .subscribe (imageValues ->contentProviderClient .bulkInsert (BASE_URI , imageValues .toArray (EMPTY )));
152100 Timber .d ("Oh hai, everyone! Look, a kitty!" );
153101 }
154102}
0 commit comments