Removed and updated all references to FileMetadata to use new TaskAttachment

pull/14/head
Sam Bosley 13 years ago
parent abc741b293
commit 2f98b8d308

@ -113,6 +113,43 @@ public final class TaskAttachment extends RemoteModel {
return defaultValues; return defaultValues;
} }
// -- Constants
/** default directory for files on external storage */
public static final String FILES_DIRECTORY_DEFAULT = "attachments"; //$NON-NLS-1$
/** preference key for some other download directory */
public static final String FILES_DIRECTORY_PREF = "custom_files_dir"; //$NON-NLS-1$
/** Constants for file types */
public static final String FILE_TYPE_AUDIO = "audio/"; //$NON-NLS-1$
public static final String FILE_TYPE_IMAGE = "image/"; //$NON-NLS-1$
public static final String FILE_TYPE_PDF = "application/pdf"; //$NON-NLS-1$
public static final String FILE_TYPE_DOC = "application/msword"; //$NON-NLS-1$
public static final String FILE_TYPE_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; //$NON-NLS-1$
public static final String FILE_TYPE_PPT = "application/vnd.ms-powerpoint"; //$NON-NLS-1$
public static final String FILE_TYPE_PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; //$NON-NLS-1$
public static final String FILE_TYPE_XLS = "application/vnd.ms-excel"; //$NON-NLS-1$
public static final String FILE_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //$NON-NLS-1$
public static final String[] MS_FILETYPES = {
FILE_TYPE_DOC, FILE_TYPE_DOCX,
FILE_TYPE_XLS, FILE_TYPE_XLSX,
FILE_TYPE_PPT, FILE_TYPE_PPTX,
};
public static final String FILE_TYPE_OTHER = "application/octet-stream"; //$NON-NLS-1$
public static TaskAttachment createNewAttachment(String taskUuid, String filePath, String fileName, String fileType) {
TaskAttachment attachment = new TaskAttachment();
attachment.setValue(TaskAttachment.TASK_UUID, taskUuid);
attachment.setValue(NAME, fileName);
attachment.setValue(FILE_PATH, filePath);
attachment.setValue(CONTENT_TYPE, fileType);
attachment.setValue(DELETED_AT, 0L);
return attachment;
}
// --- data access boilerplate // --- data access boilerplate
public TaskAttachment() { public TaskAttachment() {

@ -5,18 +5,13 @@
*/ */
package com.todoroo.astrid.actfm.sync; package com.todoroo.astrid.actfm.sync;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -26,11 +21,8 @@ import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.timsu.astrid.GCMIntentService; import com.timsu.astrid.GCMIntentService;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.AndroidUtilities; import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.billing.BillingConstants; import com.todoroo.astrid.billing.BillingConstants;
@ -38,13 +30,9 @@ import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TagDataDao;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.dao.UserDao; import com.todoroo.astrid.dao.UserDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.MetadataApiDao.MetadataCriteria;
import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.User; import com.todoroo.astrid.data.User;
import com.todoroo.astrid.files.FileMetadata;
import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.service.MetadataService; import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.TagDataService; import com.todoroo.astrid.service.TagDataService;
@ -290,99 +278,99 @@ public final class ActFmSyncService {
handleException("fetch-tag-order-io", e); handleException("fetch-tag-order-io", e);
} }
} }
//
public void pushAttachmentInBackground(final Metadata fileMetadata) { // public void pushAttachmentInBackground(final Metadata fileMetadata) {
if (!ActFmPreferenceService.isPremiumUser()) // if (!ActFmPreferenceService.isPremiumUser())
return; // return;
new Thread(new Runnable() { // new Thread(new Runnable() {
@Override // @Override
public void run() { // public void run() {
waitUntilEmpty.close(); // waitUntilEmpty.close();
taskPushThreads.incrementAndGet(); // taskPushThreads.incrementAndGet();
try { // try {
Task t = taskDao.fetch(fileMetadata.getValue(Metadata.TASK), Task.UUID); // Task t = taskDao.fetch(fileMetadata.getValue(Metadata.TASK), Task.UUID);
if (t == null || !RemoteModel.isValidUuid(t.getUuid())) // if (t == null || !RemoteModel.isValidUuid(t.getUuid()))
return; // return;
if (fileMetadata.getValue(FileMetadata.DELETION_DATE) > 0) // if (fileMetadata.getValue(FileMetadata.DELETION_DATE) > 0)
deleteAttachment(fileMetadata); // deleteAttachment(fileMetadata);
else // else
pushAttachment(t.getValue(Task.UUID), fileMetadata); // pushAttachment(t.getValue(Task.UUID), fileMetadata);
} finally { // } finally {
if (taskPushThreads.decrementAndGet() == 0) { // if (taskPushThreads.decrementAndGet() == 0) {
waitUntilEmpty.open(); // waitUntilEmpty.open();
} // }
} // }
} // }
}).start(); // }).start();
} // }
//
/** // /**
* Push a file attachment to the server // * Push a file attachment to the server
* @param remoteTaskId // * @param remoteTaskId
* @param fileMetadata // * @param fileMetadata
*/ // */
public void pushAttachment(String remoteTaskId, Metadata fileMetadata) { // public void pushAttachment(String remoteTaskId, Metadata fileMetadata) {
if (!ActFmPreferenceService.isPremiumUser()) // if (!ActFmPreferenceService.isPremiumUser())
return; // return;
//
if (!fileMetadata.containsNonNullValue(FileMetadata.FILE_PATH) || !RemoteModel.isValidUuid(remoteTaskId)) // if (!fileMetadata.containsNonNullValue(FileMetadata.FILE_PATH) || !RemoteModel.isValidUuid(remoteTaskId))
return; // return;
//
File f = new File(fileMetadata.getValue(FileMetadata.FILE_PATH)); // File f = new File(fileMetadata.getValue(FileMetadata.FILE_PATH));
if (!f.exists()) // if (!f.exists())
return; // return;
//
if (!checkForToken()) // if (!checkForToken())
return; // return;
//
ArrayList<Object> params = new ArrayList<Object>(); // ArrayList<Object> params = new ArrayList<Object>();
params.add("task_id"); params.add(remoteTaskId); // params.add("task_id"); params.add(remoteTaskId);
params.add("token"); params.add(token); // params.add("token"); params.add(token);
//
try { // try {
MultipartEntity entity = new MultipartEntity(); // MultipartEntity entity = new MultipartEntity();
FileBody body = new FileBody(f, fileMetadata.getValue(FileMetadata.FILE_TYPE)); // FileBody body = new FileBody(f, fileMetadata.getValue(FileMetadata.FILE_TYPE));
entity.addPart("file", body); // entity.addPart("file", body);
//
JSONObject result = actFmInvoker.post("task_attachment_create", entity, // JSONObject result = actFmInvoker.post("task_attachment_create", entity,
params.toArray(new Object[params.size()])); // params.toArray(new Object[params.size()]));
//
fileMetadata.setValue(FileMetadata.REMOTE_ID, result.optLong("id")); // fileMetadata.setValue(FileMetadata.REMOTE_ID, result.optLong("id"));
fileMetadata.setValue(FileMetadata.URL, result.optString("url")); // fileMetadata.setValue(FileMetadata.URL, result.optString("url"));
metadataService.save(fileMetadata); // metadataService.save(fileMetadata);
} catch (ActFmServiceException e) { // } catch (ActFmServiceException e) {
handleException("push-attachment-error", e); // handleException("push-attachment-error", e);
} catch (IOException e) { // } catch (IOException e) {
handleException("push-attachment-error", e); // handleException("push-attachment-error", e);
} // }
} // }
//
public void deleteAttachment(Metadata fileMetadata) { // public void deleteAttachment(Metadata fileMetadata) {
long attachmentId = fileMetadata.getValue(FileMetadata.REMOTE_ID); // long attachmentId = fileMetadata.getValue(FileMetadata.REMOTE_ID);
if (attachmentId <= 0) // if (attachmentId <= 0)
return; // return;
//
if (!checkForToken()) // if (!checkForToken())
return; // return;
//
ArrayList<Object> params = new ArrayList<Object>(); // ArrayList<Object> params = new ArrayList<Object>();
params.add("id"); params.add(attachmentId); // params.add("id"); params.add(attachmentId);
params.add("token"); params.add(token); // params.add("token"); params.add(token);
//
try { // try {
JSONObject result = actFmInvoker.post("task_attachment_remove", null, params.toArray(new Object[params.size()])); // JSONObject result = actFmInvoker.post("task_attachment_remove", null, params.toArray(new Object[params.size()]));
if (result.optString("status").equals("success")) { // if (result.optString("status").equals("success")) {
metadataService.delete(fileMetadata); // metadataService.delete(fileMetadata);
} // }
} catch (ActFmServiceException e) { // } catch (ActFmServiceException e) {
if (e.result != null && e.result.optString("code").equals("not_found")) // if (e.result != null && e.result.optString("code").equals("not_found"))
metadataService.delete(fileMetadata); // metadataService.delete(fileMetadata);
else // else
handleException("push-attachment-error", e); // handleException("push-attachment-error", e);
} catch (IOException e) { // } catch (IOException e) {
handleException("push-attachment-error", e); // handleException("push-attachment-error", e);
} // }
} // }
// --- data fetch methods // --- data fetch methods
public int fetchFeaturedLists(int serverTime) throws JSONException, IOException { public int fetchFeaturedLists(int serverTime) throws JSONException, IOException {
@ -477,64 +465,64 @@ public final class ActFmSyncService {
parameters[i+2] = getParameters[i]; parameters[i+2] = getParameters[i];
return actFmInvoker.invoke(method, parameters); return actFmInvoker.invoke(method, parameters);
} }
//
// --- helpers // // --- helpers
private void synchronizeAttachments(JSONObject item, Task model) { // private void synchronizeAttachments(JSONObject item, Task model) {
TodorooCursor<Metadata> attachments = metadataService.query(Query.select(Metadata.PROPERTIES) // TodorooCursor<Metadata> attachments = metadataService.query(Query.select(Metadata.PROPERTIES)
.where(Criterion.and(MetadataCriteria.byTaskAndwithKey(model.getId(), // .where(Criterion.and(MetadataCriteria.byTaskAndwithKey(model.getId(),
FileMetadata.METADATA_KEY), FileMetadata.REMOTE_ID.gt(0)))); // FileMetadata.METADATA_KEY), FileMetadata.REMOTE_ID.gt(0))));
try { // try {
HashMap<Long, Metadata> currentFiles = new HashMap<Long, Metadata>(); // HashMap<Long, Metadata> currentFiles = new HashMap<Long, Metadata>();
for (attachments.moveToFirst(); !attachments.isAfterLast(); attachments.moveToNext()) { // for (attachments.moveToFirst(); !attachments.isAfterLast(); attachments.moveToNext()) {
Metadata m = new Metadata(attachments); // Metadata m = new Metadata(attachments);
currentFiles.put(m.getValue(FileMetadata.REMOTE_ID), m); // currentFiles.put(m.getValue(FileMetadata.REMOTE_ID), m);
} // }
//
JSONArray remoteFiles = item.getJSONArray("attachments"); // JSONArray remoteFiles = item.getJSONArray("attachments");
for (int i = 0; i < remoteFiles.length(); i++) { // for (int i = 0; i < remoteFiles.length(); i++) {
JSONObject file = remoteFiles.getJSONObject(i); // JSONObject file = remoteFiles.getJSONObject(i);
//
long id = file.optLong("id"); // long id = file.optLong("id");
if (currentFiles.containsKey(id)) { // if (currentFiles.containsKey(id)) {
// Match, make sure name and url are up to date, then remove from map // // Match, make sure name and url are up to date, then remove from map
Metadata fileMetadata = currentFiles.get(id); // Metadata fileMetadata = currentFiles.get(id);
fileMetadata.setValue(FileMetadata.URL, file.getString("url")); // fileMetadata.setValue(FileMetadata.URL, file.getString("url"));
fileMetadata.setValue(FileMetadata.NAME, file.getString("name")); // fileMetadata.setValue(FileMetadata.NAME, file.getString("name"));
metadataService.save(fileMetadata); // metadataService.save(fileMetadata);
currentFiles.remove(id); // currentFiles.remove(id);
} else { // } else {
// Create new file attachment // // Create new file attachment
Metadata newAttachment = FileMetadata.createNewFileMetadata(model.getId(), "", // Metadata newAttachment = FileMetadata.createNewFileMetadata(model.getId(), "",
file.getString("name"), file.getString("content_type")); // file.getString("name"), file.getString("content_type"));
String url = file.getString("url"); // String url = file.getString("url");
newAttachment.setValue(FileMetadata.URL, url); // newAttachment.setValue(FileMetadata.URL, url);
newAttachment.setValue(FileMetadata.REMOTE_ID, id); // newAttachment.setValue(FileMetadata.REMOTE_ID, id);
metadataService.save(newAttachment); // metadataService.save(newAttachment);
} // }
} // }
//
// Remove all the leftovers // // Remove all the leftovers
Set<Long> attachmentsToDelete = currentFiles.keySet(); // Set<Long> attachmentsToDelete = currentFiles.keySet();
for (Long remoteId : attachmentsToDelete) { // for (Long remoteId : attachmentsToDelete) {
Metadata toDelete = currentFiles.get(remoteId); // Metadata toDelete = currentFiles.get(remoteId);
String path = toDelete.getValue(FileMetadata.FILE_PATH); // String path = toDelete.getValue(FileMetadata.FILE_PATH);
if (TextUtils.isEmpty(path)) // if (TextUtils.isEmpty(path))
metadataService.delete(toDelete); // metadataService.delete(toDelete);
else { // else {
File f = new File(toDelete.getValue(FileMetadata.FILE_PATH)); // File f = new File(toDelete.getValue(FileMetadata.FILE_PATH));
if (!f.exists() || f.delete()) { // if (!f.exists() || f.delete()) {
metadataService.delete(toDelete); // metadataService.delete(toDelete);
} // }
//
} // }
} // }
//
} catch (JSONException e) { // } catch (JSONException e) {
e.printStackTrace(); // e.printStackTrace();
} finally { // } finally {
attachments.close(); // attachments.close();
} // }
} // }
protected void handleException(String message, Exception exception) { protected void handleException(String message, Exception exception) {

@ -5,87 +5,79 @@
*/ */
package com.todoroo.astrid.files; package com.todoroo.astrid.files;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.data.Metadata;
public class FileMetadata { //public class FileMetadata {
//
/** metadata key */ // /** metadata key */
public static final String METADATA_KEY = "file"; //$NON-NLS-1$ // public static final String METADATA_KEY = "file"; //$NON-NLS-1$
//
/** default directory for files on external storage */ // /** default directory for files on external storage */
public static final String FILES_DIRECTORY_DEFAULT = "attachments"; //$NON-NLS-1$ // public static final String FILES_DIRECTORY_DEFAULT = "attachments"; //$NON-NLS-1$
//
/** preference key for some other download directory */ // /** preference key for some other download directory */
public static final String FILES_DIRECTORY_PREF = "custom_files_dir"; //$NON-NLS-1$ // public static final String FILES_DIRECTORY_PREF = "custom_files_dir"; //$NON-NLS-1$
//
/** Constants for file types */ // /** Constants for file types */
public static final String FILE_TYPE_AUDIO = "audio/"; //$NON-NLS-1$ // public static final String FILE_TYPE_AUDIO = "audio/"; //$NON-NLS-1$
public static final String FILE_TYPE_IMAGE = "image/"; //$NON-NLS-1$ // public static final String FILE_TYPE_IMAGE = "image/"; //$NON-NLS-1$
public static final String FILE_TYPE_PDF = "application/pdf"; //$NON-NLS-1$ // public static final String FILE_TYPE_PDF = "application/pdf"; //$NON-NLS-1$
//
public static final String FILE_TYPE_DOC = "application/msword"; //$NON-NLS-1$ // public static final String FILE_TYPE_DOC = "application/msword"; //$NON-NLS-1$
public static final String FILE_TYPE_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; //$NON-NLS-1$ // public static final String FILE_TYPE_DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; //$NON-NLS-1$
public static final String FILE_TYPE_PPT = "application/vnd.ms-powerpoint"; //$NON-NLS-1$ // public static final String FILE_TYPE_PPT = "application/vnd.ms-powerpoint"; //$NON-NLS-1$
public static final String FILE_TYPE_PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; //$NON-NLS-1$ // public static final String FILE_TYPE_PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; //$NON-NLS-1$
public static final String FILE_TYPE_XLS = "application/vnd.ms-excel"; //$NON-NLS-1$ // public static final String FILE_TYPE_XLS = "application/vnd.ms-excel"; //$NON-NLS-1$
public static final String FILE_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //$NON-NLS-1$ // public static final String FILE_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //$NON-NLS-1$
//
public static final String[] MS_FILETYPES = { // public static final String[] MS_FILETYPES = {
FILE_TYPE_DOC, FILE_TYPE_DOCX, // FILE_TYPE_DOC, FILE_TYPE_DOCX,
FILE_TYPE_XLS, FILE_TYPE_XLSX, // FILE_TYPE_XLS, FILE_TYPE_XLSX,
FILE_TYPE_PPT, FILE_TYPE_PPTX, // FILE_TYPE_PPT, FILE_TYPE_PPTX,
}; // };
//
public static final String FILE_TYPE_OTHER = "application/octet-stream"; //$NON-NLS-1$ // public static final String FILE_TYPE_OTHER = "application/octet-stream"; //$NON-NLS-1$
//
public static final StringProperty FILE_PATH = new StringProperty(Metadata.TABLE, // public static final StringProperty FILE_PATH = new StringProperty(Metadata.TABLE,
Metadata.VALUE1.name); // Metadata.VALUE1.name);
//
public static final StringProperty FILE_TYPE = new StringProperty(Metadata.TABLE, // public static final StringProperty FILE_TYPE = new StringProperty(Metadata.TABLE,
Metadata.VALUE2.name); // Metadata.VALUE2.name);
//
public static final LongProperty DELETION_DATE = new LongProperty(Metadata.TABLE, // public static final LongProperty DELETION_DATE = new LongProperty(Metadata.TABLE,
Metadata.VALUE3.name); // Metadata.VALUE3.name);
//
public static final LongProperty REMOTE_ID = new LongProperty(Metadata.TABLE, // public static final LongProperty REMOTE_ID = new LongProperty(Metadata.TABLE,
Metadata.VALUE4.name); // Metadata.VALUE4.name);
//
public static final StringProperty URL = new StringProperty(Metadata.TABLE, // public static final StringProperty URL = new StringProperty(Metadata.TABLE,
Metadata.VALUE5.name); // Metadata.VALUE5.name);
//
public static final StringProperty NAME = new StringProperty(Metadata.TABLE, // public static final StringProperty NAME = new StringProperty(Metadata.TABLE,
Metadata.VALUE6.name); // Metadata.VALUE6.name);
//
//
public static Metadata createNewFileMetadata(long taskId, String filePath, String fileName, String fileType) { // public static Metadata createNewFileMetadata(long taskId, String filePath, String fileName, String fileType) {
Metadata metadata = new Metadata(); // Metadata metadata = new Metadata();
metadata.setValue(Metadata.KEY, METADATA_KEY); // metadata.setValue(Metadata.KEY, METADATA_KEY);
metadata.setValue(Metadata.TASK, taskId); // metadata.setValue(Metadata.TASK, taskId);
metadata.setValue(NAME, fileName); // metadata.setValue(NAME, fileName);
metadata.setValue(FILE_PATH, filePath); // metadata.setValue(FILE_PATH, filePath);
metadata.setValue(FILE_TYPE, fileType); // metadata.setValue(FILE_TYPE, fileType);
metadata.setValue(REMOTE_ID, 0L); // metadata.setValue(REMOTE_ID, 0L);
metadata.setValue(DELETION_DATE, 0L); // metadata.setValue(DELETION_DATE, 0L);
return metadata; // return metadata;
} // }
//
public static boolean taskHasAttachments(long taskId) { // public static boolean taskHasAttachments(long taskId) {
TodorooCursor<Metadata> files = PluginServices.getMetadataService() // TodorooCursor<Metadata> files = PluginServices.getMetadataService()
.query(Query.select(Metadata.TASK).where( // .query(Query.select(Metadata.TASK).where(
Criterion.and(MetadataCriteria.byTaskAndwithKey(taskId, METADATA_KEY), // Criterion.and(MetadataCriteria.byTaskAndwithKey(taskId, METADATA_KEY),
DELETION_DATE.eq(0))).limit(1)); // DELETION_DATE.eq(0))).limit(1));
try { // try {
return files.getCount() > 0; // return files.getCount() > 0;
} finally { // } finally {
files.close(); // files.close();
} // }
} // }
//
} //}

@ -16,6 +16,7 @@ import android.text.TextUtils;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences; import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.data.TaskAttachment;
public class FileUtilities { public class FileUtilities {
@ -68,12 +69,12 @@ public class FileUtilities {
public static File getAttachmentsDirectory(Context context) { public static File getAttachmentsDirectory(Context context) {
File directory = null; File directory = null;
String customDir = Preferences.getStringValue(FileMetadata.FILES_DIRECTORY_PREF); String customDir = Preferences.getStringValue(TaskAttachment.FILES_DIRECTORY_PREF);
if (!TextUtils.isEmpty(customDir)) if (!TextUtils.isEmpty(customDir))
directory = new File(customDir); directory = new File(customDir);
if (directory == null || !directory.exists()) if (directory == null || !directory.exists())
directory = context.getExternalFilesDir(FileMetadata.FILES_DIRECTORY_DEFAULT); directory = context.getExternalFilesDir(TaskAttachment.FILES_DIRECTORY_DEFAULT);
return directory; return directory;
} }

@ -44,23 +44,19 @@ import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.DialogUtilities; import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.actfm.sync.ActFmSyncService; import com.todoroo.astrid.dao.TaskAttachmentDao;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.MetadataService; import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.ui.PopupControlSet; import com.todoroo.astrid.ui.PopupControlSet;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
public class FilesControlSet extends PopupControlSet { public class FilesControlSet extends PopupControlSet {
@Autowired @Autowired
private MetadataService metadataService; private TaskAttachmentDao taskAttachmentDao;
@Autowired private final ArrayList<TaskAttachment> files = new ArrayList<TaskAttachment>();
private ActFmSyncService actFmSyncService;
private final ArrayList<Metadata> files = new ArrayList<Metadata>();
private final LinearLayout fileDisplayList; private final LinearLayout fileDisplayList;
private LinearLayout fileList; private LinearLayout fileList;
private final LayoutInflater inflater; private final LayoutInflater inflater;
@ -77,7 +73,7 @@ public class FilesControlSet extends PopupControlSet {
@Override @Override
protected void refreshDisplayView() { protected void refreshDisplayView() {
fileDisplayList.removeAllViews(); fileDisplayList.removeAllViews();
for (final Metadata m : files) { for (final TaskAttachment m : files) {
View fileRow = inflater.inflate(R.layout.file_display_row, null); View fileRow = inflater.inflate(R.layout.file_display_row, null);
LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.RIGHT; lp.gravity = Gravity.RIGHT;
@ -95,16 +91,16 @@ public class FilesControlSet extends PopupControlSet {
public void refreshMetadata() { public void refreshMetadata() {
if (model != null) { if (model != null) {
TodorooCursor<Metadata> cursor = metadataService.query( TodorooCursor<TaskAttachment> cursor = taskAttachmentDao.query(
Query.select(Metadata.PROPERTIES) Query.select(TaskAttachment.PROPERTIES)
.where(Criterion.and(MetadataCriteria.byTaskAndwithKey(model.getId(), FileMetadata.METADATA_KEY), .where(Criterion.and(TaskAttachment.TASK_UUID.eq(model.getUuid()),
FileMetadata.DELETION_DATE.eq(0)))); TaskAttachment.DELETED_AT.eq(0))));
try { try {
files.clear(); files.clear();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Metadata metadata = new Metadata(); TaskAttachment attachment = new TaskAttachment();
metadata.readFromCursor(cursor); attachment.readFromCursor(cursor);
files.add(metadata); files.add(attachment);
} }
} finally { } finally {
cursor.close(); cursor.close();
@ -117,15 +113,15 @@ public class FilesControlSet extends PopupControlSet {
private void validateFiles() { private void validateFiles() {
for (int i = 0; i < files.size(); i++) { for (int i = 0; i < files.size(); i++) {
Metadata m = files.get(i); TaskAttachment m = files.get(i);
if (m.containsNonNullValue(FileMetadata.FILE_PATH)) { if (m.containsNonNullValue(TaskAttachment.FILE_PATH)) {
File f = new File(m.getValue(FileMetadata.FILE_PATH)); File f = new File(m.getValue(TaskAttachment.FILE_PATH));
if (!f.exists()) { if (!f.exists()) {
m.setValue(FileMetadata.FILE_PATH, ""); //$NON-NLS-1$ m.setValue(TaskAttachment.FILE_PATH, ""); //$NON-NLS-1$
if (m.containsNonNullValue(FileMetadata.URL)) { // We're ok, just the local file was deleted if (m.containsNonNullValue(TaskAttachment.URL)) { // We're ok, just the local file was deleted
metadataService.save(m); taskAttachmentDao.saveExisting(m);
} else { // No local file and no url -- delete the metadata } else { // No local file and no url -- delete the metadata
metadataService.delete(m); taskAttachmentDao.delete(m.getId());
files.remove(i); files.remove(i);
i--; i--;
} }
@ -152,7 +148,7 @@ public class FilesControlSet extends PopupControlSet {
final LinearLayout finalList = fileList; final LinearLayout finalList = fileList;
fileList.removeAllViews(); fileList.removeAllViews();
LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
for (final Metadata m : files) { for (final TaskAttachment m : files) {
final View fileRow = inflater.inflate(R.layout.file_row, null); final View fileRow = inflater.inflate(R.layout.file_row, null);
setUpFileRow(m, fileRow, fileList, lp); setUpFileRow(m, fileRow, fileList, lp);
@ -170,16 +166,15 @@ public class FilesControlSet extends PopupControlSet {
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface d, int which) { public void onClick(DialogInterface d, int which) {
if (m.getValue(FileMetadata.REMOTE_ID) > 0) { if (RemoteModel.isValidUuid(m.getValue(TaskAttachment.UUID))) {
m.setValue(FileMetadata.DELETION_DATE, DateUtilities.now()); m.setValue(TaskAttachment.DELETED_AT, DateUtilities.now());
metadataService.save(m); taskAttachmentDao.saveExisting(m);
actFmSyncService.pushAttachmentInBackground(m);
} else { } else {
metadataService.delete(m); taskAttachmentDao.delete(m.getId());
} }
if (m.containsNonNullValue(FileMetadata.FILE_PATH)) { if (m.containsNonNullValue(TaskAttachment.FILE_PATH)) {
File f = new File(m.getValue(FileMetadata.FILE_PATH)); File f = new File(m.getValue(TaskAttachment.FILE_PATH));
f.delete(); f.delete();
} }
files.remove(m); files.remove(m);
@ -193,8 +188,8 @@ public class FilesControlSet extends PopupControlSet {
} }
} }
private void setupFileClickListener(View view, final Metadata m) { private void setupFileClickListener(View view, final TaskAttachment m) {
final String filePath = m.containsNonNullValue(FileMetadata.FILE_PATH) ? m.getValue(FileMetadata.FILE_PATH) : null; final String filePath = m.containsNonNullValue(TaskAttachment.FILE_PATH) ? m.getValue(TaskAttachment.FILE_PATH) : null;
if (TextUtils.isEmpty(filePath)) { if (TextUtils.isEmpty(filePath)) {
view.setOnClickListener(new OnClickListener() { view.setOnClickListener(new OnClickListener() {
@Override @Override
@ -218,18 +213,18 @@ public class FilesControlSet extends PopupControlSet {
} }
} }
private void showFile(final Metadata m) { private void showFile(final TaskAttachment m) {
final String fileType = m.containsNonNullValue(FileMetadata.FILE_TYPE) ? m.getValue(FileMetadata.FILE_TYPE) : FileMetadata.FILE_TYPE_OTHER; final String fileType = m.containsNonNullValue(TaskAttachment.CONTENT_TYPE) ? m.getValue(TaskAttachment.CONTENT_TYPE) : TaskAttachment.FILE_TYPE_OTHER;
final String filePath = m.getValue(FileMetadata.FILE_PATH); final String filePath = m.getValue(TaskAttachment.FILE_PATH);
if (fileType.startsWith(FileMetadata.FILE_TYPE_AUDIO)) { if (fileType.startsWith(TaskAttachment.FILE_TYPE_AUDIO)) {
RecognizerApi.play(activity, m.getValue(FileMetadata.FILE_PATH), new PlaybackExceptionHandler() { RecognizerApi.play(activity, m.getValue(TaskAttachment.FILE_PATH), new PlaybackExceptionHandler() {
@Override @Override
public void playbackFailed(String file) { public void playbackFailed(String file) {
showFromIntent(filePath, fileType); showFromIntent(filePath, fileType);
} }
}); });
} else if (fileType.startsWith(FileMetadata.FILE_TYPE_IMAGE)) { } else if (fileType.startsWith(TaskAttachment.FILE_TYPE_IMAGE)) {
AlertDialog image = new AlertDialog.Builder(activity).create(); AlertDialog image = new AlertDialog.Builder(activity).create();
ImageView imageView = new ImageView(activity); ImageView imageView = new ImageView(activity);
imageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); imageView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
@ -252,7 +247,7 @@ public class FilesControlSet extends PopupControlSet {
image.show(); image.show();
} else { } else {
String useType = fileType; String useType = fileType;
if (fileType.equals(FileMetadata.FILE_TYPE_OTHER)) { if (fileType.equals(TaskAttachment.FILE_TYPE_OTHER)) {
String extension = AndroidUtilities.getFileExtension(filePath); String extension = AndroidUtilities.getFileExtension(filePath);
MimeTypeMap map = MimeTypeMap.getSingleton(); MimeTypeMap map = MimeTypeMap.getSingleton();
@ -260,8 +255,8 @@ public class FilesControlSet extends PopupControlSet {
if (!TextUtils.isEmpty(guessedType)) if (!TextUtils.isEmpty(guessedType))
useType = guessedType; useType = guessedType;
if (useType != guessedType) { if (useType != guessedType) {
m.setValue(FileMetadata.FILE_TYPE, useType); m.setValue(TaskAttachment.CONTENT_TYPE, useType);
metadataService.save(m); taskAttachmentDao.saveExisting(m);
} }
} }
showFromIntent(filePath, useType); showFromIntent(filePath, useType);
@ -279,11 +274,11 @@ public class FilesControlSet extends PopupControlSet {
} }
private void handleActivityNotFound(String fileType) { private void handleActivityNotFound(String fileType) {
if (fileType.startsWith(FileMetadata.FILE_TYPE_AUDIO)) { if (fileType.startsWith(TaskAttachment.FILE_TYPE_AUDIO)) {
searchMarket("com.clov4r.android.nil", R.string.search_market_audio_title, R.string.search_market_audio); //$NON-NLS-1$ searchMarket("com.clov4r.android.nil", R.string.search_market_audio_title, R.string.search_market_audio); //$NON-NLS-1$
} else if (fileType.equals(FileMetadata.FILE_TYPE_PDF)) { } else if (fileType.equals(TaskAttachment.FILE_TYPE_PDF)) {
searchMarket("com.adobe.reader", R.string.search_market_pdf_title, R.string.search_market_pdf); //$NON-NLS-1$ searchMarket("com.adobe.reader", R.string.search_market_pdf_title, R.string.search_market_pdf); //$NON-NLS-1$
} else if (AndroidUtilities.indexOf(FileMetadata.MS_FILETYPES, fileType) >= 0) { } else if (AndroidUtilities.indexOf(TaskAttachment.MS_FILETYPES, fileType) >= 0) {
searchMarket("com.dataviz.docstogo", R.string.search_market_ms_title, R.string.search_market_ms); //$NON-NLS-1$ searchMarket("com.dataviz.docstogo", R.string.search_market_ms_title, R.string.search_market_ms); //$NON-NLS-1$
} else { } else {
DialogUtilities.okDialog(activity, activity.getString(R.string.file_type_unhandled_title), DialogUtilities.okDialog(activity, activity.getString(R.string.file_type_unhandled_title),
@ -311,7 +306,7 @@ public class FilesControlSet extends PopupControlSet {
} }
@SuppressWarnings("nls") @SuppressWarnings("nls")
private void downloadFile(final Metadata m) { private void downloadFile(final TaskAttachment m) {
final ProgressDialog pd = new ProgressDialog(activity); final ProgressDialog pd = new ProgressDialog(activity);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage(activity.getString(R.string.file_download_progress)); pd.setMessage(activity.getString(R.string.file_download_progress));
@ -320,9 +315,9 @@ public class FilesControlSet extends PopupControlSet {
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
String urlString = m.getValue(FileMetadata.URL); String urlString = m.getValue(TaskAttachment.URL);
urlString = urlString.replace(" ", "%20"); urlString = urlString.replace(" ", "%20");
String name = m.getValue(FileMetadata.NAME); String name = m.getValue(TaskAttachment.NAME);
StringBuilder filePathBuilder = new StringBuilder(); StringBuilder filePathBuilder = new StringBuilder();
File directory = FileUtilities.getAttachmentsDirectory(activity); File directory = FileUtilities.getAttachmentsDirectory(activity);
@ -378,8 +373,8 @@ public class FilesControlSet extends PopupControlSet {
fileOutput.flush(); fileOutput.flush();
fileOutput.close(); fileOutput.close();
m.setValue(FileMetadata.FILE_PATH, file.getAbsolutePath()); m.setValue(TaskAttachment.FILE_PATH, file.getAbsolutePath());
metadataService.save(m); taskAttachmentDao.saveExisting(m);
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -404,11 +399,11 @@ public class FilesControlSet extends PopupControlSet {
pd.show(); pd.show();
} }
private void setUpFileRow(Metadata m, View row, LinearLayout parent, LayoutParams lp) { private void setUpFileRow(TaskAttachment m, View row, LinearLayout parent, LayoutParams lp) {
TextView nameView = (TextView) row.findViewById(R.id.file_text); TextView nameView = (TextView) row.findViewById(R.id.file_text);
TextView typeView = (TextView) row.findViewById(R.id.file_type); TextView typeView = (TextView) row.findViewById(R.id.file_type);
String name = getNameString(m); String name = getNameString(m);
String type = getTypeString(m.getValue(FileMetadata.NAME)); String type = getTypeString(m.getValue(TaskAttachment.NAME));
nameView.setText(name); nameView.setText(name);
if (TextUtils.isEmpty(type)) if (TextUtils.isEmpty(type))
@ -419,8 +414,8 @@ public class FilesControlSet extends PopupControlSet {
parent.addView(row, lp); parent.addView(row, lp);
} }
private String getNameString(Metadata metadata) { private String getNameString(TaskAttachment metadata) {
String name = metadata.getValue(FileMetadata.NAME); String name = metadata.getValue(TaskAttachment.NAME);
int extension = name.lastIndexOf('.'); int extension = name.lastIndexOf('.');
if (extension < 0) if (extension < 0)
return name; return name;

@ -50,8 +50,8 @@ import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.Database; import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.files.FileExplore; import com.todoroo.astrid.files.FileExplore;
import com.todoroo.astrid.files.FileMetadata;
import com.todoroo.astrid.gcal.CalendarStartupReceiver; import com.todoroo.astrid.gcal.CalendarStartupReceiver;
import com.todoroo.astrid.gtasks.GtasksPreferences; import com.todoroo.astrid.gtasks.GtasksPreferences;
import com.todoroo.astrid.helper.MetadataHelper; import com.todoroo.astrid.helper.MetadataHelper;
@ -575,7 +575,7 @@ public class EditPreferences extends TodorooPreferenceActivity {
// pp preferences // pp preferences
else if (r.getString(R.string.p_files_dir).equals(preference.getKey())) { else if (r.getString(R.string.p_files_dir).equals(preference.getKey())) {
String dir = Preferences.getStringValue(FileMetadata.FILES_DIRECTORY_PREF); String dir = Preferences.getStringValue(TaskAttachment.FILES_DIRECTORY_PREF);
if (TextUtils.isEmpty(dir)) { if (TextUtils.isEmpty(dir)) {
dir = r.getString(R.string.p_files_dir_desc_default); dir = r.getString(R.string.p_files_dir_desc_default);
@ -665,7 +665,7 @@ public class EditPreferences extends TodorooPreferenceActivity {
} else if (requestCode == REQUEST_CODE_FILES_DIR && resultCode == RESULT_OK) { } else if (requestCode == REQUEST_CODE_FILES_DIR && resultCode == RESULT_OK) {
if (data != null) { if (data != null) {
String dir = data.getStringExtra(FileExplore.RESULT_DIR_SELECTED); String dir = data.getStringExtra(FileExplore.RESULT_DIR_SELECTED);
Preferences.setString(FileMetadata.FILES_DIRECTORY_PREF, dir); Preferences.setString(TaskAttachment.FILES_DIRECTORY_PREF, dir);
} }
return; return;
} }

@ -70,12 +70,12 @@ import com.todoroo.astrid.actfm.TaskCommentsFragment;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.actfm.sync.ActFmSyncService; import com.todoroo.astrid.actfm.sync.ActFmSyncService;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.dao.TaskAttachmentDao;
import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.files.AACRecordingActivity; import com.todoroo.astrid.files.AACRecordingActivity;
import com.todoroo.astrid.files.FileExplore; import com.todoroo.astrid.files.FileExplore;
import com.todoroo.astrid.files.FileMetadata;
import com.todoroo.astrid.files.FileUtilities; import com.todoroo.astrid.files.FileUtilities;
import com.todoroo.astrid.files.FilesControlSet; import com.todoroo.astrid.files.FilesControlSet;
import com.todoroo.astrid.gcal.GCalControlSet; import com.todoroo.astrid.gcal.GCalControlSet;
@ -212,6 +212,9 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
@Autowired @Autowired
private MetadataService metadataService; private MetadataService metadataService;
@Autowired
private TaskAttachmentDao taskAttachmentDao;
@Autowired @Autowired
private AddOnService addOnService; private AddOnService addOnService;
@ -870,7 +873,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
loadItem(intent); loadItem(intent);
synchronized (controls) { synchronized (controls) {
if (!FileMetadata.taskHasAttachments(model.getId())) { if (!taskAttachmentDao.taskHasAttachments(model.getUuid())) {
filesControlSet.getDisplayView().setVisibility(View.GONE); filesControlSet.getDisplayView().setVisibility(View.GONE);
} }
for (TaskEditControlSet controlSet : controls) for (TaskEditControlSet controlSet : controls)
@ -1140,7 +1143,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
String name = dst.getName(); String name = dst.getName();
String extension = AndroidUtilities.getFileExtension(name); String extension = AndroidUtilities.getFileExtension(name);
String type = FileMetadata.FILE_TYPE_OTHER; String type = TaskAttachment.FILE_TYPE_OTHER;
if (!TextUtils.isEmpty(extension)) { if (!TextUtils.isEmpty(extension)) {
MimeTypeMap map = MimeTypeMap.getSingleton(); MimeTypeMap map = MimeTypeMap.getSingleton();
String guessedType = map.getMimeTypeFromExtension(extension); String guessedType = map.getMimeTypeFromExtension(extension);
@ -1163,16 +1166,15 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
fos.flush(); fos.flush();
fos.close(); fos.close();
createNewFileAttachment(path, nameRef.get(), FileMetadata.FILE_TYPE_IMAGE + "png"); createNewFileAttachment(path, nameRef.get(), TaskAttachment.FILE_TYPE_IMAGE + "png");
} catch (Exception e) { } catch (Exception e) {
Toast.makeText(getActivity(), R.string.file_err_copy, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), R.string.file_err_copy, Toast.LENGTH_LONG).show();
} }
} }
private void createNewFileAttachment(String path, String fileName, String fileType) { private void createNewFileAttachment(String path, String fileName, String fileType) {
Metadata fileMetadata = FileMetadata.createNewFileMetadata(model.getId(), path, fileName, fileType); TaskAttachment attachment = TaskAttachment.createNewAttachment(model.getUuid(), path, fileName, fileType);
metadataService.save(fileMetadata); taskAttachmentDao.createNew(attachment);
actFmSyncService.pushAttachmentInBackground(fileMetadata);
filesControlSet.refreshMetadata(); filesControlSet.refreshMetadata();
filesControlSet.getDisplayView().setVisibility(View.VISIBLE); filesControlSet.getDisplayView().setVisibility(View.VISIBLE);
} }
@ -1291,7 +1293,7 @@ ViewPager.OnPageChangeListener, EditNoteActivity.UpdatesChangedListener {
} else if (requestCode == REQUEST_CODE_RECORD && resultCode == Activity.RESULT_OK) { } else if (requestCode == REQUEST_CODE_RECORD && resultCode == Activity.RESULT_OK) {
String recordedAudioPath = data.getStringExtra(AACRecordingActivity.RESULT_OUTFILE); String recordedAudioPath = data.getStringExtra(AACRecordingActivity.RESULT_OUTFILE);
String recordedAudioName = data.getStringExtra(AACRecordingActivity.RESULT_FILENAME); String recordedAudioName = data.getStringExtra(AACRecordingActivity.RESULT_FILENAME);
createNewFileAttachment(recordedAudioPath, recordedAudioName, FileMetadata.FILE_TYPE_AUDIO + "m4a"); //$NON-NLS-1$ createNewFileAttachment(recordedAudioPath, recordedAudioName, TaskAttachment.FILE_TYPE_AUDIO + "m4a"); //$NON-NLS-1$
} else if (requestCode == REQUEST_CODE_ATTACH_FILE && resultCode == Activity.RESULT_OK) { } else if (requestCode == REQUEST_CODE_ATTACH_FILE && resultCode == Activity.RESULT_OK) {
attachFile(data.getStringExtra(FileExplore.RESULT_FILE_SELECTED)); attachFile(data.getStringExtra(FileExplore.RESULT_FILE_SELECTED));
} else if (requestCode == REQUEST_CODE_BEAST_MODE) { } else if (requestCode == REQUEST_CODE_BEAST_MODE) {

@ -87,8 +87,8 @@ import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.data.User; import com.todoroo.astrid.data.User;
import com.todoroo.astrid.files.FileMetadata;
import com.todoroo.astrid.helper.SyncActionHelper; import com.todoroo.astrid.helper.SyncActionHelper;
import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader; import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader;
import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader.ContextMenuItem; import com.todoroo.astrid.helper.TaskListContextMenuExtensionLoader.ContextMenuItem;
@ -981,9 +981,7 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
tagsJoinCriterion).toString() //$NON-NLS-1$ tagsJoinCriterion).toString() //$NON-NLS-1$
+ Join.left(User.TABLE.as(USER_IMAGE_JOIN), + Join.left(User.TABLE.as(USER_IMAGE_JOIN),
Task.USER_ID.eq(Field.field(USER_IMAGE_JOIN + "." + User.UUID.name))).toString() Task.USER_ID.eq(Field.field(USER_IMAGE_JOIN + "." + User.UUID.name))).toString()
+ Join.left(Metadata.TABLE.as(FILE_METADATA_JOIN), + Join.left(TaskAttachment.TABLE.as(FILE_METADATA_JOIN), Task.UUID.eq(Field.field(FILE_METADATA_JOIN) + "." + TaskAttachment.UUID.name))
Criterion.and(Field.field(FILE_METADATA_JOIN + "." + Metadata.KEY.name).eq(FileMetadata.METADATA_KEY),
Task.ID.eq(Field.field(FILE_METADATA_JOIN + "." + Metadata.TASK.name))))
+ filter.getSqlQuery(); + filter.getSqlQuery();
sqlQueryTemplate.set(SortHelper.adjustQueryForFlagsAndSort( sqlQueryTemplate.set(SortHelper.adjustQueryForFlagsAndSort(

@ -77,6 +77,7 @@ import com.todoroo.astrid.core.LinkActionExposer;
import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.data.User; import com.todoroo.astrid.data.User;
import com.todoroo.astrid.files.FilesAction; import com.todoroo.astrid.files.FilesAction;
import com.todoroo.astrid.files.FilesControlSet; import com.todoroo.astrid.files.FilesControlSet;
@ -113,7 +114,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
@SuppressWarnings("nls") @SuppressWarnings("nls")
private static final StringProperty TAGS = new StringProperty(null, "group_concat(" + TaskListFragment.TAGS_METADATA_JOIN + "." + TaskToTagMetadata.TAG_NAME.name + ", ' | ')").as("tags"); private static final StringProperty TAGS = new StringProperty(null, "group_concat(" + TaskListFragment.TAGS_METADATA_JOIN + "." + TaskToTagMetadata.TAG_NAME.name + ", ' | ')").as("tags");
@SuppressWarnings("nls") @SuppressWarnings("nls")
private static final LongProperty FILE_ID_PROPERTY = Metadata.ID.cloneAs(TaskListFragment.FILE_METADATA_JOIN, "fileId"); private static final LongProperty FILE_ID_PROPERTY = TaskAttachment.ID.cloneAs(TaskListFragment.FILE_METADATA_JOIN, "fileId");
@SuppressWarnings("nls") @SuppressWarnings("nls")
private static final IntegerProperty HAS_NOTES_PROPERTY = new IntegerProperty(null, "length(" + Task.NOTES + ") > 0").as("hasNotes"); private static final IntegerProperty HAS_NOTES_PROPERTY = new IntegerProperty(null, "length(" + Task.NOTES + ") > 0").as("hasNotes");

@ -5,9 +5,11 @@
*/ */
package com.todoroo.astrid.dao; package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.actfm.sync.messages.NameMaps; import com.todoroo.astrid.actfm.sync.messages.NameMaps;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.TaskAttachment; import com.todoroo.astrid.data.TaskAttachment;
@ -34,6 +36,17 @@ public class TaskAttachmentDao extends RemoteModelDao<TaskAttachment> {
return NameMaps.shouldRecordOutstandingColumnForTable(NameMaps.TABLE_ID_ATTACHMENTS, columnName); return NameMaps.shouldRecordOutstandingColumnForTable(NameMaps.TABLE_ID_ATTACHMENTS, columnName);
} }
public boolean taskHasAttachments(String taskUuid) {
TodorooCursor<TaskAttachment> files = query(Query.select(TaskAttachment.TASK_UUID).where(
Criterion.and(TaskAttachment.TASK_UUID.eq(taskUuid),
TaskAttachment.DELETED_AT.eq(0))).limit(1));
try {
return files.getCount() > 0;
} finally {
files.close();
}
}
// --- SQL clause generators // --- SQL clause generators
/** /**

@ -46,12 +46,12 @@ import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.activity.TaskListFragment.OnTaskListItemClickedListener; import com.todoroo.astrid.activity.TaskListFragment.OnTaskListItemClickedListener;
import com.todoroo.astrid.core.PluginServices; import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.dao.TaskAttachmentDao;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.files.FileMetadata; import com.todoroo.astrid.data.TaskAttachment;
import com.todoroo.astrid.files.FileUtilities; import com.todoroo.astrid.files.FileUtilities;
import com.todoroo.astrid.gcal.GCalControlSet; import com.todoroo.astrid.gcal.GCalControlSet;
import com.todoroo.astrid.gcal.GCalHelper; import com.todoroo.astrid.gcal.GCalHelper;
@ -90,6 +90,8 @@ public class QuickAddBar extends LinearLayout {
@Autowired ExceptionService exceptionService; @Autowired ExceptionService exceptionService;
@Autowired MetadataService metadataService; @Autowired MetadataService metadataService;
@Autowired ActFmPreferenceService actFmPreferenceService; @Autowired ActFmPreferenceService actFmPreferenceService;
@Autowired
private TaskAttachmentDao taskAttachmentDao;
private VoiceRecognizer voiceRecognizer; private VoiceRecognizer voiceRecognizer;
@ -361,8 +363,8 @@ public class QuickAddBar extends LinearLayout {
voiceRecognizer.convert(path); voiceRecognizer.convert(path);
currentVoiceFile = null; currentVoiceFile = null;
Metadata fileMetadata = FileMetadata.createNewFileMetadata(task.getId(), path, nameRef.get(), FileMetadata.FILE_TYPE_AUDIO + "m4a"); TaskAttachment attachment = TaskAttachment.createNewAttachment(task.getUuid(), path, nameRef.get(), TaskAttachment.FILE_TYPE_AUDIO + "m4a");
metadataService.save(fileMetadata); taskAttachmentDao.createNew(attachment);
} }
fragment.onTaskCreated(task); fragment.onTaskCreated(task);

Loading…
Cancel
Save