mirror of https://github.com/nextcloud/android
229 lines
9.3 KiB
Java
229 lines
9.3 KiB
Java
/*
|
|
* Nextcloud - Android Client
|
|
*
|
|
* SPDX-FileCopyrightText: 2017 Mario Danic <mario@lovelyhq.com>
|
|
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
package com.owncloud.android.datamodel;
|
|
|
|
import android.content.ContentResolver;
|
|
import android.content.ContentValues;
|
|
import android.database.Cursor;
|
|
import android.net.Uri;
|
|
|
|
import com.owncloud.android.db.ProviderMeta;
|
|
import com.owncloud.android.lib.common.utils.Log_OC;
|
|
import com.owncloud.android.utils.SyncedFolderUtils;
|
|
|
|
import java.io.BufferedInputStream;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
import java.util.zip.CRC32;
|
|
|
|
/**
|
|
* Provider for stored filesystem data.
|
|
*/
|
|
public class FilesystemDataProvider {
|
|
|
|
static private final String TAG = FilesystemDataProvider.class.getSimpleName();
|
|
|
|
private ContentResolver contentResolver;
|
|
|
|
public FilesystemDataProvider(ContentResolver contentResolver) {
|
|
if (contentResolver == null) {
|
|
throw new IllegalArgumentException("Cannot create an instance with a NULL contentResolver");
|
|
}
|
|
this.contentResolver = contentResolver;
|
|
}
|
|
|
|
public int deleteAllEntriesForSyncedFolder(String syncedFolderId) {
|
|
return contentResolver.delete(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
|
|
new String[]{syncedFolderId}
|
|
);
|
|
}
|
|
|
|
public void updateFilesystemFileAsSentForUpload(String path, String syncedFolderId) {
|
|
ContentValues cv = new ContentValues();
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, 1);
|
|
|
|
contentResolver.update(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
|
|
cv,
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
|
|
new String[]{path, syncedFolderId}
|
|
);
|
|
}
|
|
|
|
public Set<String> getFilesForUpload(String localPath, String syncedFolderId) {
|
|
Set<String> localPathsToUpload = new HashSet<>();
|
|
|
|
String likeParam = localPath + "%";
|
|
|
|
Cursor cursor = contentResolver.query(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
|
|
null,
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " LIKE ? and " +
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ? and " +
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD + " = ? and " +
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER + " = ?",
|
|
new String[]{likeParam, syncedFolderId, "0", "0"},
|
|
null);
|
|
|
|
if (cursor != null) {
|
|
if (cursor.moveToFirst()) {
|
|
do {
|
|
String value = cursor.getString(cursor.getColumnIndexOrThrow(
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
|
|
if (value == null) {
|
|
Log_OC.e(TAG, "Cannot get local path");
|
|
} else {
|
|
File file = new File(value);
|
|
if (!file.exists()) {
|
|
Log_OC.d(TAG, "Ignoring file for upload (doesn't exist): " + value);
|
|
} else if (!SyncedFolderUtils.isQualifiedFolder(file.getParent())) {
|
|
Log_OC.d(TAG, "Ignoring file for upload (unqualified folder): " + value);
|
|
} else if (!SyncedFolderUtils.isFileNameQualifiedForAutoUpload(file.getName())) {
|
|
Log_OC.d(TAG, "Ignoring file for upload (unqualified file): " + value);
|
|
} else {
|
|
localPathsToUpload.add(value);
|
|
}
|
|
}
|
|
} while (cursor.moveToNext());
|
|
}
|
|
|
|
cursor.close();
|
|
}
|
|
|
|
return localPathsToUpload;
|
|
}
|
|
|
|
public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean isFolder, SyncedFolder syncedFolder) {
|
|
|
|
FileSystemDataSet data = getFilesystemDataSet(localPath, syncedFolder);
|
|
|
|
int isFolderValue = 0;
|
|
if (isFolder) {
|
|
isFolderValue = 1;
|
|
}
|
|
|
|
ContentValues cv = new ContentValues();
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY, System.currentTimeMillis());
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED, modifiedAt);
|
|
|
|
if (data == null) {
|
|
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH, localPath);
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER, isFolderValue);
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, Boolean.FALSE);
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID, syncedFolder.getId());
|
|
|
|
long newCrc32 = getFileChecksum(localPath);
|
|
if (newCrc32 != -1) {
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_CRC32, Long.toString(newCrc32));
|
|
}
|
|
|
|
Uri result = contentResolver.insert(ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM, cv);
|
|
|
|
if (result == null) {
|
|
Log_OC.v(TAG, "Failed to insert filesystem data with local path: " + localPath);
|
|
}
|
|
} else {
|
|
|
|
if (data.getModifiedAt() != modifiedAt) {
|
|
long newCrc32 = getFileChecksum(localPath);
|
|
if (data.getCrc32() == null || (newCrc32 != -1 && !data.getCrc32().equals(Long.toString(newCrc32)))) {
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_CRC32, Long.toString(newCrc32));
|
|
cv.put(ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD, 0);
|
|
}
|
|
}
|
|
|
|
|
|
int result = contentResolver.update(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
|
|
cv,
|
|
ProviderMeta.ProviderTableMeta._ID + "=?",
|
|
new String[]{String.valueOf(data.getId())}
|
|
);
|
|
|
|
if (result == 0) {
|
|
Log_OC.v(TAG, "Failed to update filesystem data with local path: " + localPath);
|
|
}
|
|
}
|
|
}
|
|
|
|
private FileSystemDataSet getFilesystemDataSet(String localPathParam, SyncedFolder syncedFolder) {
|
|
|
|
Cursor cursor = contentResolver.query(
|
|
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
|
|
null,
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH + " = ? and " +
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_SYNCED_FOLDER_ID + " = ?",
|
|
new String[]{localPathParam, Long.toString(syncedFolder.getId())},
|
|
null
|
|
);
|
|
|
|
FileSystemDataSet dataSet = null;
|
|
if (cursor != null) {
|
|
if (cursor.moveToFirst()) {
|
|
int id = cursor.getInt(cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta._ID));
|
|
String localPath = cursor.getString(cursor.getColumnIndexOrThrow(
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_LOCAL_PATH));
|
|
long modifiedAt = cursor.getLong(cursor.getColumnIndexOrThrow(
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_MODIFIED));
|
|
boolean isFolder = false;
|
|
if (cursor.getInt(cursor.getColumnIndexOrThrow(
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_IS_FOLDER)) != 0) {
|
|
isFolder = true;
|
|
}
|
|
long foundAt = cursor.getLong(cursor.getColumnIndexOrThrow(ProviderMeta.
|
|
ProviderTableMeta.FILESYSTEM_FILE_FOUND_RECENTLY));
|
|
|
|
boolean isSentForUpload = false;
|
|
if (cursor.getInt(cursor.getColumnIndexOrThrow(
|
|
ProviderMeta.ProviderTableMeta.FILESYSTEM_FILE_SENT_FOR_UPLOAD)) != 0) {
|
|
isSentForUpload = true;
|
|
}
|
|
|
|
String crc32 = cursor.getString(cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.FILESYSTEM_CRC32));
|
|
|
|
if (id == -1) {
|
|
Log_OC.e(TAG, "Arbitrary value could not be created from cursor");
|
|
} else {
|
|
dataSet = new FileSystemDataSet(id, localPath, modifiedAt, isFolder, isSentForUpload, foundAt,
|
|
syncedFolder.getId(), crc32);
|
|
}
|
|
}
|
|
cursor.close();
|
|
} else {
|
|
Log_OC.e(TAG, "DB error restoring arbitrary values.");
|
|
}
|
|
|
|
return dataSet;
|
|
}
|
|
|
|
private long getFileChecksum(String filepath) {
|
|
|
|
try (InputStream inputStream = new BufferedInputStream(new FileInputStream(filepath))) {
|
|
CRC32 crc = new CRC32();
|
|
byte[] buf = new byte[1024 * 64];
|
|
int size;
|
|
while ((size = inputStream.read(buf)) > 0) {
|
|
crc.update(buf, 0, size);
|
|
}
|
|
|
|
return crc.getValue();
|
|
|
|
} catch (IOException e) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|