1
1
package fr .free .nrw .commons .contributions ;
2
2
3
3
import android .accounts .Account ;
4
+ import android .annotation .SuppressLint ;
4
5
import android .content .AbstractThreadedSyncAdapter ;
5
6
import android .content .ContentProviderClient ;
6
7
import android .content .ContentValues ;
11
12
import android .os .RemoteException ;
12
13
import android .text .TextUtils ;
13
14
15
+ import org .wikipedia .dataclient .mwapi .MwQueryLogEvent ;
16
+ import org .wikipedia .dataclient .mwapi .MwQueryResult ;
14
17
import org .wikipedia .util .DateUtil ;
15
18
16
19
import java .io .IOException ;
26
29
import fr .free .nrw .commons .kvstore .JsonKvStore ;
27
30
import fr .free .nrw .commons .mwapi .LogEventResult ;
28
31
import fr .free .nrw .commons .mwapi .MediaWikiApi ;
32
+ import fr .free .nrw .commons .mwapi .UserClient ;
29
33
import timber .log .Timber ;
30
34
31
35
import static fr .free .nrw .commons .contributions .Contribution .STATE_COMPLETED ;
@@ -44,8 +48,8 @@ public class ContributionsSyncAdapter extends AbstractThreadedSyncAdapter {
44
48
// into the app, rather than the user's setting. Also see Github issue #52.
45
49
public static final int ABSOLUTE_CONTRIBUTIONS_LOAD_LIMIT = 500 ;
46
50
47
- @ SuppressWarnings ( "WeakerAccess" )
48
- @ Inject MediaWikiApi mwApi ;
51
+ @ Inject
52
+ UserClient userClient ;
49
53
@ Inject
50
54
@ Named ("default_preferences" )
51
55
JsonKvStore defaultKvStore ;
@@ -58,24 +62,19 @@ private boolean fileExists(ContentProviderClient client, String filename) {
58
62
if (filename == null ) {
59
63
return false ;
60
64
}
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
+ )) {
69
71
return cursor != null && cursor .getCount () != 0 ;
70
72
} catch (RemoteException e ) {
71
73
throw new RuntimeException (e );
72
- } finally {
73
- if (cursor != null ) {
74
- cursor .close ();
75
- }
76
74
}
77
75
}
78
76
77
+ @ SuppressLint ("CheckResult" )
79
78
@ Override
80
79
public void onPerformSync (Account account , Bundle bundle , String authority ,
81
80
ContentProviderClient contentProviderClient , SyncResult syncResult ) {
@@ -84,71 +83,20 @@ public void onPerformSync(Account account, Bundle bundle, String authority,
84
83
.getApplicationContext ())
85
84
.getCommonsApplicationComponent ()
86
85
.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!
88
87
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 ;
94
88
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 )));
152
100
Timber .d ("Oh hai, everyone! Look, a kitty!" );
153
101
}
154
102
}
0 commit comments