FilesSyncJob.java 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * Nextcloud Android client application
  3. *
  4. * @author Mario Danic
  5. * Copyright (C) 2017 Mario Danic
  6. * Copyright (C) 2017 Nextcloud
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. package com.owncloud.android.jobs;
  22. import android.accounts.Account;
  23. import android.content.ContentResolver;
  24. import android.content.Context;
  25. import android.os.PowerManager;
  26. import android.support.annotation.NonNull;
  27. import android.support.media.ExifInterface;
  28. import android.text.TextUtils;
  29. import com.evernote.android.job.Job;
  30. import com.evernote.android.job.util.support.PersistableBundleCompat;
  31. import com.owncloud.android.MainApp;
  32. import com.owncloud.android.authentication.AccountUtils;
  33. import com.owncloud.android.datamodel.FilesystemDataProvider;
  34. import com.owncloud.android.datamodel.MediaFolderType;
  35. import com.owncloud.android.datamodel.SyncedFolder;
  36. import com.owncloud.android.datamodel.SyncedFolderProvider;
  37. import com.owncloud.android.files.services.FileUploader;
  38. import com.owncloud.android.lib.common.utils.Log_OC;
  39. import com.owncloud.android.operations.UploadFileOperation;
  40. import com.owncloud.android.utils.FileStorageUtils;
  41. import com.owncloud.android.utils.FilesSyncHelper;
  42. import com.owncloud.android.utils.MimeTypeUtil;
  43. import java.io.File;
  44. import java.io.IOException;
  45. import java.text.ParsePosition;
  46. import java.text.SimpleDateFormat;
  47. import java.util.Date;
  48. import java.util.Locale;
  49. import java.util.TimeZone;
  50. /*
  51. Job that:
  52. - restarts existing jobs if required
  53. - finds new and modified files since we last run this
  54. - creates upload tasks
  55. */
  56. public class FilesSyncJob extends Job {
  57. public static final String TAG = "FilesSyncJob";
  58. public static final String SKIP_CUSTOM = "skipCustom";
  59. @NonNull
  60. @Override
  61. protected Result onRunJob(Params params) {
  62. final Context context = MainApp.getAppContext();
  63. final ContentResolver contentResolver = context.getContentResolver();
  64. PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
  65. FileUploader.UploadRequester requester = new FileUploader.UploadRequester();
  66. PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
  67. TAG);
  68. wakeLock.acquire();
  69. PersistableBundleCompat bundle = params.getExtras();
  70. final boolean skipCustom = bundle.getBoolean(SKIP_CUSTOM, false);
  71. FilesSyncHelper.restartJobsIfNeeded();
  72. FilesSyncHelper.insertAllDBEntries(skipCustom);
  73. // Create all the providers we'll need
  74. final FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
  75. SyncedFolderProvider syncedFolderProvider = new SyncedFolderProvider(contentResolver);
  76. for (SyncedFolder syncedFolder : syncedFolderProvider.getSyncedFolders()) {
  77. if ((syncedFolder.isEnabled()) && (!skipCustom || MediaFolderType.CUSTOM != syncedFolder.getType())) {
  78. for (String path : filesystemDataProvider.getFilesForUpload(syncedFolder.getLocalPath(),
  79. Long.toString(syncedFolder.getId()))) {
  80. File file = new File(path);
  81. Long lastModificationTime = file.lastModified();
  82. final Locale currentLocale = context.getResources().getConfiguration().locale;
  83. if (MediaFolderType.IMAGE == syncedFolder.getType()) {
  84. String mimetypeString = FileStorageUtils.getMimeTypeFromName(file.getAbsolutePath());
  85. if ("image/jpeg".equalsIgnoreCase(mimetypeString) || "image/tiff".
  86. equalsIgnoreCase(mimetypeString)) {
  87. try {
  88. ExifInterface exifInterface = new ExifInterface(file.getAbsolutePath());
  89. String exifDate = exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
  90. if (!TextUtils.isEmpty(exifDate)) {
  91. ParsePosition pos = new ParsePosition(0);
  92. SimpleDateFormat sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss",
  93. currentLocale);
  94. sFormatter.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID()));
  95. Date dateTime = sFormatter.parse(exifDate, pos);
  96. lastModificationTime = dateTime.getTime();
  97. }
  98. } catch (IOException e) {
  99. Log_OC.d(TAG, "Failed to get the proper time " + e.getLocalizedMessage());
  100. }
  101. }
  102. }
  103. boolean needsCharging = syncedFolder.getChargingOnly();
  104. boolean needsWifi = syncedFolder.getWifiOnly();
  105. String mimeType = MimeTypeUtil.getBestMimeTypeByFilename(file.getAbsolutePath());
  106. Account account = AccountUtils.getOwnCloudAccountByName(context, syncedFolder.getAccount());
  107. requester.uploadFileWithOverwrite(
  108. context,
  109. account,
  110. file.getAbsolutePath(),
  111. FileStorageUtils.getInstantUploadFilePath(
  112. currentLocale,
  113. syncedFolder.getRemotePath(), file.getName(),
  114. lastModificationTime,
  115. syncedFolder.getSubfolderByDate()),
  116. syncedFolder.getUploadAction(),
  117. mimeType,
  118. true, // create parent folder if not existent
  119. UploadFileOperation.CREATED_AS_INSTANT_PICTURE,
  120. needsWifi,
  121. needsCharging,
  122. true
  123. );
  124. filesystemDataProvider.updateFilesystemFileAsSentForUpload(path,
  125. Long.toString(syncedFolder.getId()));
  126. }
  127. }
  128. }
  129. wakeLock.release();
  130. return Result.SUCCESS;
  131. }
  132. }