use of org.mediawiki.api.ApiResult in project apps-android-commons by commons-app.
the class UploadService method uploadContribution.
private void uploadContribution(Contribution contribution) {
MWApi api = app.getMWApi();
ApiResult result;
InputStream file = null;
String notificationTag = contribution.getLocalUri().toString();
try {
//FIXME: Google Photos bug
file = this.getContentResolver().openInputStream(contribution.getLocalUri());
} catch (FileNotFoundException e) {
Timber.d("File not found");
Toast fileNotFound = Toast.makeText(this, R.string.upload_failed, Toast.LENGTH_LONG);
fileNotFound.show();
}
Timber.d("Before execution!");
curProgressNotification = new NotificationCompat.Builder(this).setAutoCancel(true).setSmallIcon(R.drawable.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)).setAutoCancel(true).setContentTitle(getString(R.string.upload_progress_notification_title_start, contribution.getDisplayTitle())).setContentText(getResources().getQuantityString(R.plurals.uploads_pending_notification_indicator, toUpload, toUpload)).setOngoing(true).setProgress(100, 0, true).setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, ContributionsActivity.class), 0)).setTicker(getString(R.string.upload_progress_notification_title_in_progress, contribution.getDisplayTitle()));
this.startForeground(NOTIFICATION_UPLOAD_IN_PROGRESS, curProgressNotification.build());
String filename = null;
try {
filename = Utils.fixExtension(contribution.getFilename(), MimeTypeMap.getSingleton().getExtensionFromMimeType((String) contribution.getTag("mimeType")));
synchronized (unfinishedUploads) {
Timber.d("making sure of uniqueness of name: %s", filename);
filename = findUniqueFilename(filename);
unfinishedUploads.add(filename);
}
if (!api.validateLogin()) {
// Need to revalidate!
if (app.revalidateAuthToken()) {
Timber.d("Successfully revalidated token!");
} else {
Timber.d("Unable to revalidate :(");
// TODO: Put up a new notification, ask them to re-login
stopForeground(true);
Toast failureToast = Toast.makeText(this, R.string.authentication_failed, Toast.LENGTH_LONG);
failureToast.show();
return;
}
}
NotificationUpdateProgressListener notificationUpdater = new NotificationUpdateProgressListener(notificationTag, getString(R.string.upload_progress_notification_title_in_progress, contribution.getDisplayTitle()), getString(R.string.upload_progress_notification_title_finishing, contribution.getDisplayTitle()), contribution);
result = api.upload(filename, file, contribution.getDataLength(), contribution.getPageContents(), contribution.getEditSummary(), notificationUpdater);
Timber.d("Response is %s", Utils.getStringFromDOM(result.getDocument()));
curProgressNotification = null;
String resultStatus = result.getString("/api/upload/@result");
if (!resultStatus.equals("Success")) {
String errorCode = result.getString("/api/error/@code");
showFailedNotification(contribution);
EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT).param("username", app.getCurrentAccount().name).param("source", contribution.getSource()).param("multiple", contribution.getMultiple()).param("result", errorCode).param("filename", contribution.getFilename()).log();
} else {
Date dateUploaded = null;
dateUploaded = Utils.parseMWDate(result.getString("/api/upload/imageinfo/@timestamp"));
// Title vs Filename
String canonicalFilename = "File:" + result.getString("/api/upload/@filename").replace("_", " ");
String imageUrl = result.getString("/api/upload/imageinfo/@url");
contribution.setFilename(canonicalFilename);
contribution.setImageUrl(imageUrl);
contribution.setState(Contribution.STATE_COMPLETED);
contribution.setDateUploaded(dateUploaded);
contribution.save();
EventLog.schema(CommonsApplication.EVENT_UPLOAD_ATTEMPT).param("username", app.getCurrentAccount().name).param("source", //FIXME
contribution.getSource()).param("filename", contribution.getFilename()).param("multiple", contribution.getMultiple()).param("result", "success").log();
}
} catch (IOException e) {
Timber.d("I have a network fuckup");
showFailedNotification(contribution);
return;
} finally {
if (filename != null) {
unfinishedUploads.remove(filename);
}
toUpload--;
if (toUpload == 0) {
// Sync modifications right after all uplaods are processed
ContentResolver.requestSync((CommonsApplication.getInstance()).getCurrentAccount(), ModificationsContentProvider.AUTHORITY, new Bundle());
stopForeground(true);
}
}
}
use of org.mediawiki.api.ApiResult in project apps-android-commons by commons-app.
the class ContributionsSyncAdapter method onPerformSync.
@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.getInstance().getMWApi();
SharedPreferences prefs = this.getContext().getSharedPreferences("prefs", Context.MODE_PRIVATE);
String lastModified = prefs.getString("lastSyncTimestamp", "");
Date curTime = new Date();
ApiResult result;
Boolean done = false;
String queryContinue = null;
while (!done) {
try {
MWApi.RequestBuilder builder = api.action("query").param("list", "logevents").param("letype", "upload").param("leprop", "title|timestamp|ids").param("leuser", user).param("lelimit", getLimit());
if (!TextUtils.isEmpty(lastModified)) {
builder.param("leend", lastModified);
}
if (!TextUtils.isEmpty(queryContinue)) {
builder.param("lestart", queryContinue);
}
result = builder.get();
} catch (IOException e) {
// There isn't really much we can do, eh?
// FIXME: Perhaps add EventLogging?
// Not sure if this does anything. Shitty docs
syncResult.stats.numIoExceptions += 1;
Timber.d("Syncing failed due to %s", e);
return;
}
Timber.d("Last modified at %s", lastModified);
ArrayList<ApiResult> uploads = result.getNodes("/api/query/logevents/item");
Timber.d("%d results!", uploads.size());
ArrayList<ContentValues> imageValues = new ArrayList<>();
for (ApiResult image : uploads) {
String pageId = image.getString("@pageid");
if (pageId.equals("0")) {
// means that this upload was deleted.
continue;
}
String filename = image.getString("@title");
if (fileExists(contentProviderClient, filename)) {
Timber.d("Skipping %s", filename);
continue;
}
String thumbUrl = Utils.makeThumbBaseUrl(filename);
Date dateUpdated = Utils.parseMWDate(image.getString("@timestamp"));
Contribution contrib = new Contribution(null, thumbUrl, filename, "", -1, dateUpdated, dateUpdated, user, "", "");
contrib.setState(Contribution.STATE_COMPLETED);
imageValues.add(contrib.toContentValues());
if (imageValues.size() % COMMIT_THRESHOLD == 0) {
try {
contentProviderClient.bulkInsert(ContributionsContentProvider.BASE_URI, imageValues.toArray(new ContentValues[] {}));
} catch (RemoteException e) {
throw new RuntimeException(e);
}
imageValues.clear();
}
}
if (imageValues.size() != 0) {
try {
contentProviderClient.bulkInsert(ContributionsContentProvider.BASE_URI, imageValues.toArray(new ContentValues[] {}));
} catch (RemoteException e) {
throw new RuntimeException(e);
}
}
queryContinue = result.getString("/api/query-continue/logevents/@lestart");
if (TextUtils.isEmpty(queryContinue)) {
done = true;
}
}
prefs.edit().putString("lastSyncTimestamp", Utils.toMWDate(curTime)).apply();
Timber.d("Oh hai, everyone! Look, a kitty!");
}
use of org.mediawiki.api.ApiResult in project apps-android-commons by commons-app.
the class UploadService method fileExistsWithName.
private static boolean fileExistsWithName(MWApi api, String fileName) throws IOException {
ApiResult result;
result = api.action("query").param("prop", "imageinfo").param("titles", "File:" + fileName).get();
return result.getNodes("/api/query/pages/page/imageinfo").size() > 0;
}
use of org.mediawiki.api.ApiResult in project apps-android-commons by commons-app.
the class ModificationsSyncAdapter method onPerformSync.
@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!
Cursor allModifications;
try {
allModifications = contentProviderClient.query(ModificationsContentProvider.BASE_URI, null, null, null, null);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
// Exit early if nothing to do
if (allModifications == null || allModifications.getCount() == 0) {
Timber.d("No modifications to perform");
return;
}
String authCookie;
try {
authCookie = AccountManager.get(getContext()).blockingGetAuthToken(account, "", false);
} catch (OperationCanceledException | AuthenticatorException e) {
throw new RuntimeException(e);
} catch (IOException e) {
Timber.d("Could not authenticate :(");
return;
}
if (Utils.isNullOrWhiteSpace(authCookie)) {
Timber.d("Could not authenticate :(");
return;
}
MWApi api = CommonsApplication.getInstance().getMWApi();
api.setAuthCookie(authCookie);
String editToken;
ApiResult requestResult, responseResult;
try {
editToken = api.getEditToken();
} catch (IOException e) {
Timber.d("Can not retreive edit token!");
return;
}
allModifications.moveToFirst();
Timber.d("Found %d modifications to execute", allModifications.getCount());
ContentProviderClient contributionsClient = null;
try {
contributionsClient = getContext().getContentResolver().acquireContentProviderClient(ContributionsContentProvider.AUTHORITY);
while (!allModifications.isAfterLast()) {
ModifierSequence sequence = ModifierSequence.fromCursor(allModifications);
sequence.setContentProviderClient(contentProviderClient);
Contribution contrib;
Cursor contributionCursor;
try {
contributionCursor = contributionsClient.query(sequence.getMediaUri(), null, null, null, null);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
contributionCursor.moveToFirst();
contrib = Contribution.fromCursor(contributionCursor);
if (contrib.getState() == Contribution.STATE_COMPLETED) {
try {
requestResult = api.action("query").param("prop", "revisions").param("rvprop", "timestamp|content").param("titles", contrib.getFilename()).get();
} catch (IOException e) {
Timber.d("Network fuckup on modifications sync!");
continue;
}
Timber.d("Page content is %s", Utils.getStringFromDOM(requestResult.getDocument()));
String pageContent = requestResult.getString("/api/query/pages/page/revisions/rev");
String processedPageContent = sequence.executeModifications(contrib.getFilename(), pageContent);
try {
responseResult = api.action("edit").param("title", contrib.getFilename()).param("token", editToken).param("text", processedPageContent).param("summary", sequence.getEditSummary()).post();
} catch (IOException e) {
Timber.d("Network fuckup on modifications sync!");
continue;
}
Timber.d("Response is %s", Utils.getStringFromDOM(responseResult.getDocument()));
String result = responseResult.getString("/api/edit/@result");
if (!result.equals("Success")) {
// FIXME: Log this somewhere else
Timber.d("Non success result! %s", result);
} else {
sequence.delete();
}
}
allModifications.moveToNext();
}
} finally {
if (contributionsClient != null) {
contributionsClient.release();
}
}
}
use of org.mediawiki.api.ApiResult in project apps-android-commons by commons-app.
the class ExistingFileAsync method doInBackground.
@Override
protected Boolean doInBackground(Void... voids) {
MWApi api = CommonsApplication.getInstance().getMWApi();
ApiResult result;
// https://commons.wikimedia.org/w/api.php?action=query&list=allimages&format=xml&aisha1=801957214aba50cb63bb6eb1b0effa50188900ba
try {
result = api.action("query").param("format", "xml").param("list", "allimages").param("aisha1", fileSHA1).get();
Timber.d("Searching Commons API for existing file: %s", result);
} catch (IOException e) {
Timber.e(e, "IO Exception: ");
return false;
}
ArrayList<ApiResult> resultNodes = result.getNodes("/api/query/allimages/img");
Timber.d("Result nodes: %s", resultNodes);
boolean fileExists = !resultNodes.isEmpty();
Timber.d("File already exists in Commons: %s", fileExists);
return fileExists;
}
Aggregations