From 1e08e9cd41ff07bd19659e0e81cfe8ad00095c60 Mon Sep 17 00:00:00 2001 From: leiyiz Date: Thu, 13 Jun 2019 13:10:16 -0700 Subject: [PATCH] ability to sync reduced-size image attachments from server and redownload all reduced-size images if wanted. --- .../opendatakit/services/MainActivity.java | 8 ++++ .../services/sync/actions/SyncActions.java | 2 +- .../sync/actions/fragments/SyncFragment.java | 42 +++++++++++++++++++ .../service/logic/AggregateSynchronizer.java | 8 +++- .../sync/service/logic/HttpSynchronizer.java | 14 +++++++ .../ProcessManifestContentAndFileChanges.java | 18 +++++--- .../logic/ProcessRowDataSyncAttachments.java | 14 +++++-- services_app/src/main/res/menu/main.xml | 7 ++++ .../src/main/res/values-es/arrays.xml | 2 + .../src/main/res/values-es/strings.xml | 2 + services_app/src/main/res/values/arrays.xml | 2 + services_app/src/main/res/values/strings.xml | 2 + 12 files changed, 110 insertions(+), 11 deletions(-) diff --git a/services_app/src/main/java/org/opendatakit/services/MainActivity.java b/services_app/src/main/java/org/opendatakit/services/MainActivity.java index e02f8adb1..240e8d6f4 100644 --- a/services_app/src/main/java/org/opendatakit/services/MainActivity.java +++ b/services_app/src/main/java/org/opendatakit/services/MainActivity.java @@ -140,6 +140,14 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; } + if (id == R.id.action_redownload) { + Intent i = new Intent(this, SyncActivity.class); + i.putExtra(IntentConsts.INTENT_KEY_APP_NAME, getAppName()); + i.putExtra(IntentConsts.INTENT_KEY_REDOWNLOAD_ATTACHMENT, "true"); + startActivityForResult(i, SYNC_ACTIVITY_RESULT_CODE); + return true; + } + if (id == R.id.action_about) { FragmentManager mgr = getSupportFragmentManager(); diff --git a/services_app/src/main/java/org/opendatakit/services/sync/actions/SyncActions.java b/services_app/src/main/java/org/opendatakit/services/sync/actions/SyncActions.java index 854ddb31b..c52e6f05a 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/actions/SyncActions.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/actions/SyncActions.java @@ -4,5 +4,5 @@ * @author mitchellsundt@gmail.com */ public enum SyncActions { - IDLE, MONITOR_SYNCING, SYNC, RESET_SERVER + IDLE, MONITOR_SYNCING, SYNC, RESET_SERVER, RE_DOWNLOAD } diff --git a/services_app/src/main/java/org/opendatakit/services/sync/actions/fragments/SyncFragment.java b/services_app/src/main/java/org/opendatakit/services/sync/actions/fragments/SyncFragment.java index daeb3e384..9dd684aab 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/actions/fragments/SyncFragment.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/actions/fragments/SyncFragment.java @@ -148,6 +148,14 @@ public SyncFragment() { } } + String re_download = getActivity().getIntent().getStringExtra(IntentConsts.INTENT_KEY_REDOWNLOAD_ATTACHMENT); + WebLogger.getLogger(getAppName()) + .w(TAG, "re_download is :" + re_download); + + if (re_download != null) { + reDownload(); + } + ArrayAdapter instanceAttachmentsAdapter = ArrayAdapter .createFromResource(getActivity(), R.array.sync_attachment_option_names, android.R.layout.select_dialog_item); syncInstanceAttachmentsSpinner.setAdapter(instanceAttachmentsAdapter); @@ -309,6 +317,17 @@ void postTaskToAccessSyncService() { } }); break; + case RE_DOWNLOAD: + syncServiceInterface.synchronizeWithServer(getAppName(), SyncAttachmentState.RE_DOWNLOAD); + syncAction = SyncActions.MONITOR_SYNCING; + + handler.post(new Runnable() { + @Override public void run() { + showProgressDialog(SyncStatus.NONE, null, getString(R.string.sync_starting), -1, + 0); + } + }); + break; case RESET_SERVER: syncServiceInterface.resetServer(getAppName(), syncAttachmentState); syncAction = SyncActions.MONITOR_SYNCING; @@ -479,6 +498,29 @@ public void onClickChangeUser(View v) { return; } + private void reDownload() { + WebLogger.getLogger(getAppName()).d(TAG, "[" + getId() + "] [onClickReDownload] timestamp: " + System.currentTimeMillis()); + if (areCredentialsConfigured(false)) { + // show warning message + //TODO: make some error message here + AlertDialog.Builder msg = buildOkMessage("confirm re-download attachments", + "re-download will result in high data usage"); + + msg.setPositiveButton(getString(R.string.sync_reset), new DialogInterface.OnClickListener() { + @Override public void onClick(DialogInterface dialog, int which) { + WebLogger.getLogger(getAppName()).d(TAG, + "[" + getId() + "] [onClickReDownload] timestamp: " + System.currentTimeMillis()); + disableButtons(); + syncAction = SyncActions.RE_DOWNLOAD; + prepareForSyncAction(); + } + }); + + msg.setNegativeButton(getString(R.string.cancel), null); + msg.show(); + } + } + private void showProgressDialog(SyncStatus status, SyncProgressState progress, String message, int progressStep, int maxStep) { if (getActivity() == null) { diff --git a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java index e5a82d415..50c452fd2 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/AggregateSynchronizer.java @@ -1053,14 +1053,20 @@ public void uploadInstanceFileBatch(List batch, @Override public void downloadInstanceFileBatch(List filesToDownload, String serverInstanceFileUri, String instanceId, String tableId) throws HttpClientWebException, IOException { - // boolean downloadedAllFiles = true; + downloadInstanceFileBatch(filesToDownload, serverInstanceFileUri, instanceId, tableId, false); + } + @Override + public void downloadInstanceFileBatch(List filesToDownload, + String serverInstanceFileUri, String instanceId, String tableId, boolean reduce) throws HttpClientWebException, IOException { + // boolean downloadedAllFiles = true; URI instanceFilesDownloadUri = wrapper.constructInstanceFileBulkDownloadUri(serverInstanceFileUri, instanceId); ArrayList entries = new ArrayList(); for (CommonFileAttachmentTerms cat : filesToDownload) { OdkTablesFileManifestEntry entry = new OdkTablesFileManifestEntry(); entry.filename = cat.rowPathUri; + entry.reduceFileSize = reduce ? "t" : "f"; entries.add(entry); } diff --git a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/HttpSynchronizer.java b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/HttpSynchronizer.java index 362bf6720..80a33caba 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/HttpSynchronizer.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/HttpSynchronizer.java @@ -371,6 +371,20 @@ void downloadInstanceFileBatch(List filesToDownload, String serverInstanceFileUri, String instanceId, String tableId) throws HttpClientWebException, IOException; + + /** + * @param filesToDownload + * @param serverInstanceFileUri + * @param instanceId + * @param tableId + * @param reduce + * @throws HttpClientWebException + * @throws IOException + */ + void downloadInstanceFileBatch(List filesToDownload, + String serverInstanceFileUri, String instanceId, String tableId, boolean reduce) + throws HttpClientWebException, IOException; + /** * Report the sync status for this device to the server * @param tableResource diff --git a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java index 37dd388ef..f4a580e31 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessManifestContentAndFileChanges.java @@ -868,7 +868,9 @@ public boolean syncRowLevelFileAttachments(String serverInstanceFileUri, String log.i(LOGTAG, "syncRowLevelFileAttachments no files to send to server -- they are all synced"); fullySyncedUploads = true; } else if (attachmentState.equals(SyncAttachmentState.SYNC) || - attachmentState.equals(SyncAttachmentState.UPLOAD)) { + attachmentState.equals(SyncAttachmentState.UPLOAD) || + attachmentState.equals(SyncAttachmentState.REDUCED_SYNC) || + attachmentState.equals(SyncAttachmentState.RE_DOWNLOAD)) { long batchSize = 0; List batch = new LinkedList(); for (CommonFileAttachmentTerms fileAttachment : filesToUpload) { @@ -903,10 +905,14 @@ public boolean syncRowLevelFileAttachments(String serverInstanceFileUri, String log.i(LOGTAG, "syncRowLevelFileAttachments no files to fetch from server -- they are all synced"); fullySyncedDownloads = !impossibleToFullySyncDownloadsServerMissingFileToDownload; } else if (attachmentState.equals(SyncAttachmentState.SYNC) || - attachmentState.equals(SyncAttachmentState.DOWNLOAD)) { + attachmentState.equals(SyncAttachmentState.UPLOAD) || + attachmentState.equals(SyncAttachmentState.REDUCED_SYNC) || + attachmentState.equals(SyncAttachmentState.RE_DOWNLOAD)) { long batchSize = 0; List batch = new LinkedList(); + boolean reduce = attachmentState.equals(SyncAttachmentState.REDUCED_SYNC); + for (CommonFileAttachmentTerms fileAttachment : filesToDownloadSizes.keySet()) { // Check if adding the file exceeds the batch limit. If so, download the current batch @@ -916,8 +922,8 @@ public boolean syncRowLevelFileAttachments(String serverInstanceFileUri, String if (batchSize + filesToDownloadSizes.get(fileAttachment) > MAX_BATCH_SIZE && !batch.isEmpty()) { log.i(LOGTAG, "syncRowLevelFileAttachments downloading batch for " + instanceId); - sc.getSynchronizer().downloadInstanceFileBatch(batch, - serverInstanceFileUri, instanceId, tableId); + HttpSynchronizer httpSynchronizer = (HttpSynchronizer) sc.getSynchronizer(); + httpSynchronizer.downloadInstanceFileBatch(batch, serverInstanceFileUri, instanceId, tableId, reduce); batch.clear(); batchSize = 0; } @@ -929,8 +935,8 @@ public boolean syncRowLevelFileAttachments(String serverInstanceFileUri, String if ( !batch.isEmpty() ) { // download the final batch log.i(LOGTAG, "syncRowLevelFileAttachments downloading batch for " + instanceId); - sc.getSynchronizer().downloadInstanceFileBatch(batch, serverInstanceFileUri, - instanceId, tableId); + HttpSynchronizer httpSynchronizer = (HttpSynchronizer) sc.getSynchronizer(); + httpSynchronizer.downloadInstanceFileBatch(batch, serverInstanceFileUri, instanceId, tableId, reduce); } fullySyncedDownloads = !impossibleToFullySyncDownloadsServerMissingFileToDownload; diff --git a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessRowDataSyncAttachments.java b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessRowDataSyncAttachments.java index f629e4903..1a8254803 100644 --- a/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessRowDataSyncAttachments.java +++ b/services_app/src/main/java/org/opendatakit/services/sync/service/logic/ProcessRowDataSyncAttachments.java @@ -138,8 +138,14 @@ public void syncAttachments(TableResource tableResource, String sqlCommand; - BindArgs bindArgs = new BindArgs(new Object[]{ SyncState.in_conflict.name(), - SyncState.synced_pending_files.name() }); + BindArgs bindArgs; + if (attachmentState.equals(SyncAttachmentState.RE_DOWNLOAD)) { + bindArgs = new BindArgs(new Object[]{SyncState.synced.name(), + SyncState.synced_pending_files.name()}); + } else { + bindArgs = new BindArgs(new Object[]{ SyncState.in_conflict.name(), + SyncState.synced_pending_files.name() }); + } { StringBuilder sqlCommandBuilder = new StringBuilder(); @@ -239,7 +245,8 @@ public void syncAttachments(TableResource tableResource, boolean syncAttachments = false; // the local row wasn't impacted by a server change // see if this local row should be pushed to the server. - if (state == SyncState.in_conflict) { + if (state == SyncState.in_conflict || + (state == SyncState.synced && attachmentState.equals(SyncAttachmentState.RE_DOWNLOAD))) { if (!fileAttachmentColumns.isEmpty()) { // fetch the file attachments for an in_conflict row but don't delete // anything and never update the state to synced (it must stay in in_conflict) @@ -299,6 +306,7 @@ public void syncAttachments(TableResource tableResource, idString = R.string.sync_skipping_attachments_server_row; break; case SYNC: + case REDUCED_SYNC: idString = R.string.sync_syncing_attachments_server_row; break; case UPLOAD: diff --git a/services_app/src/main/res/menu/main.xml b/services_app/src/main/res/menu/main.xml index 0e0944a0b..7b19d5f36 100644 --- a/services_app/src/main/res/menu/main.xml +++ b/services_app/src/main/res/menu/main.xml @@ -38,6 +38,13 @@ android:title="@string/action_change_user" app:showAsAction="ifRoom" /> + + UPLOAD DOWNLOAD NONE + REDUCED_SYNC Sincronizar Todos Solo enviar archivos (imágenes, audio, video) al servidor Solo recibir archivos (imágenes, audio, video) del servidor No sincronizar archivos + diff --git a/services_app/src/main/res/values-es/strings.xml b/services_app/src/main/res/values-es/strings.xml index d2ea0f3c8..e0c09dbab 100644 --- a/services_app/src/main/res/values-es/strings.xml +++ b/services_app/src/main/res/values-es/strings.xml @@ -9,6 +9,7 @@ Sincronización Cambiar usuario/Cerrar sesión + Resolver Conflictos Actualizar permisos de usuario @@ -165,6 +166,7 @@ Sincronizar archivos adjuntos de la instancia más tarde Sincronizar Ahora Reinicializar servidor + Confirmar cambios de configuración Si cambia su configuración, tablas que han sincronizado ahora pueden ya no ser capaces de sincronizar en el futuro. Guardar diff --git a/services_app/src/main/res/values/arrays.xml b/services_app/src/main/res/values/arrays.xml index 31021db5c..1d598456c 100644 --- a/services_app/src/main/res/values/arrays.xml +++ b/services_app/src/main/res/values/arrays.xml @@ -15,11 +15,13 @@ UPLOAD DOWNLOAD NONE + REDUCED_SYNC Fully Sync Attachments Upload Attachments Only Download Attachments Only Do Not Sync Attachments + Sync Reduced-size Attachments \ No newline at end of file diff --git a/services_app/src/main/res/values/strings.xml b/services_app/src/main/res/values/strings.xml index a47208579..b1b988aed 100644 --- a/services_app/src/main/res/values/strings.xml +++ b/services_app/src/main/res/values/strings.xml @@ -9,6 +9,7 @@ Sync Change User/Logout + re-Download attachments Resolve Conflicts Update User Permissions @@ -195,6 +196,7 @@ Defer Instance Attachments Sync now Reset App Server + Re-download Attachments Confirm Change Settings If you change your settings, tables you have sync\'d now may no longer be able to be sync\'d.