+ pub fn add_file_note<F>(&self, collection_id: i32, path: &Path, callback: F)
+ where F: FnOnce(Result<note::Model, DbErr>) + Send + 'static {
+ let bhandle = self.clone();
+ let pathbuf = path.to_path_buf();
+ let cmd = Box::pin(async move {
+ let name = pathbuf.as_path().file_name();
+ // check file and get the file name
+ let result: Result<&OsStr, Error> = async {
+ let metadata = fs::metadata(pathbuf.as_path()).await?;
+ if !metadata.is_file() {
+ let msg = format!("{} is not a valid file", pathbuf.display());
+ return Err(Error::new(ErrorKind::NotFound, msg));
+ }
+ let name = pathbuf.file_name();
+ if let Some(name) = name {
+ Ok(name)
+ } else {
+ // this shouldn't happen because the path points to a file
+ Err(Error::new(ErrorKind::NotFound, "no file name".to_string()))
+ }
+ }.await;
+
+ let name = match result {
+ Ok(name) => {
+ let name = name.to_string_lossy().to_string();
+ if name.len() > 0 {
+ name
+ } else {
+ // in case to_string_lossy removes everything
+ "new_file".to_string()
+ }
+ },
+ Err(e) => {
+ callback(Err(DbErr::Custom(e.to_string())));
+ return;
+ }
+ };
+
+ let result: Result<note::Model, DbErr> = async {
+ // prepare db insert
+ let nodename = generate_nodename_in_collection(&bhandle.backend.db, collection_id, name.as_str()).await?;
+ let title = nodename.clone(); // TODO
+ let contenttype = "image/png".to_string(); // TODO
+ let insert = note::ActiveModel {
+ collection_id: Set(collection_id),
+ nodename: Set(nodename),
+ kind: Set(NoteType::File),
+ title: Set(title),
+ content_type: Set(contenttype),
+ lastmodified: Set(Utc::now().into()),
+ created: Set(Utc::now().into()),
+ fixed_title: Set(true),
+ version: Set(0),
+
+ ..Default::default()
+ };
+ // do insert
+ let model = insert.insert(&bhandle.backend.db).await?;
+
+ // if local storage is enabled, copy the note to the note path
+ let note_local_path = get_note_storage_path(&bhandle.backend.db, model.note_id).await?;
+ if let Some(note_path) = note_local_path {
+ // copy file to new note path
+ let to_path = Path::new(¬e_path);
+ let copy_result = fs::copy(pathbuf.as_path(), to_path).await;
+ if let Err(e) = copy_result {
+ return Err(DbErr::Custom(e.to_string()))
+ }
+ } else {
+ // copy note content to the database
+ // TODO
+ }
+
+ Ok(model)
+ }.await;
+ callback(result);
+ });
+ let _ = self.tx.send(cmd);
+ }
+