diff options
author | Patiga <dev@patiga.eu> | 2022-06-28 12:11:17 +0200 |
---|---|---|
committer | fiaxh <git@lightrise.org> | 2024-11-14 10:20:12 -0600 |
commit | aaf4542e6208460c305db4be36b15dc832ddc95a (patch) | |
tree | ec7b60b0f0ea74e21403788e8345336bd0f3939b /libdino/src/entity/file_transfer.vala | |
parent | 909f569318835d11703c49fba7dbe49996759f38 (diff) | |
download | dino-aaf4542e6208460c305db4be36b15dc832ddc95a.tar.gz dino-aaf4542e6208460c305db4be36b15dc832ddc95a.zip |
Implement XEP-0447: Stateless file sharing
Diffstat (limited to 'libdino/src/entity/file_transfer.vala')
-rw-r--r-- | libdino/src/entity/file_transfer.vala | 158 |
1 files changed, 151 insertions, 7 deletions
diff --git a/libdino/src/entity/file_transfer.vala b/libdino/src/entity/file_transfer.vala index 20bc1a7a..c9c7916e 100644 --- a/libdino/src/entity/file_transfer.vala +++ b/libdino/src/entity/file_transfer.vala @@ -14,6 +14,22 @@ public class FileTransfer : Object { FAILED } + public class SerializedSfsSource: Object { + public string type; + public string data; + + public SerializedSfsSource.from_sfs_source(Xep.StatelessFileSharing.SfsSource source) { + this.type = source.type(); + this.data = source.serialize(); + } + + public async Xep.StatelessFileSharing.SfsSource to_sfs_source() { + assert(this.type == Xep.StatelessFileSharing.HttpSource.SOURCE_TYPE); + Xep.StatelessFileSharing.HttpSource http_source = yield Xep.StatelessFileSharing.HttpSource.deserialize(this.data); + return http_source; + } + } + public int id { get; set; default=-1; } public Account account { get; set; } public Jid counterpart { get; set; } @@ -64,13 +80,19 @@ public class FileTransfer : Object { } public string path { get; set; } public string? mime_type { get; set; } - // TODO(hrxi): expand to 64 bit - public int size { get; set; default=-1; } - + public int64 size { get; set; } public State state { get; set; default=State.NOT_STARTED; } public int provider { get; set; } public string info { get; set; } public Cancellable cancellable { get; default=new Cancellable(); } + public string? desc { get; set; } + public DateTime? modification_date { get; set; } + public int width { get; set; default=-1; } + public int height { get; set; default=-1; } + public int64 length { get; set; default=-1; } + public Xep.CryptographicHashes.Hashes hashes { get; set; default=new Xep.CryptographicHashes.Hashes();} + public ListStore sfs_sources { get; set; default=new ListStore(typeof(SerializedSfsSource)); } + public Gee.List<Xep.JingleContentThumbnails.Thumbnail> thumbnails = new Gee.ArrayList<Xep.JingleContentThumbnails.Thumbnail>(); private Database? db; private string storage_dir; @@ -99,10 +121,37 @@ public class FileTransfer : Object { file_name = row[db.file_transfer.file_name]; path = row[db.file_transfer.path]; mime_type = row[db.file_transfer.mime_type]; - size = row[db.file_transfer.size]; + size = (int64) row[db.file_transfer.size]; state = (State) row[db.file_transfer.state]; provider = row[db.file_transfer.provider]; info = row[db.file_transfer.info]; + modification_date = new DateTime.from_unix_utc(row[db.file_transfer.modification_date]); + width = row[db.file_transfer.width]; + height = row[db.file_transfer.height]; + length = (int64) row[db.file_transfer.length]; + + foreach(var hash_row in db.file_hashes.select().with(db.file_hashes.id, "=", id)) { + Xep.CryptographicHashes.Hash hash = new Xep.CryptographicHashes.Hash(); + hash.algo = hash_row[db.file_hashes.algo]; + hash.val = hash_row[db.file_hashes.value]; + hashes.hashes.add(hash); + } + + foreach(var thumbnail_row in db.file_thumbnails.select().with(db.file_thumbnails.id, "=", id)) { + Xep.JingleContentThumbnails.Thumbnail thumbnail = new Xep.JingleContentThumbnails.Thumbnail(); + thumbnail.uri = thumbnail_row[db.file_thumbnails.uri]; + thumbnail.media_type = thumbnail_row[db.file_thumbnails.mime_type]; + thumbnail.width = thumbnail_row[db.file_thumbnails.width]; + thumbnail.height = thumbnail_row[db.file_thumbnails.height]; + thumbnails.add(thumbnail); + } + + foreach(Qlite.Row source_row in db.sfs_sources.select().with(db.sfs_sources.id, "=", id)) { + SerializedSfsSource source = new SerializedSfsSource(); + source.type = source_row[db.sfs_sources.type]; + source.data = source_row[db.sfs_sources.data]; + sfs_sources.append(source as Object); + } notify.connect(on_update); } @@ -121,17 +170,52 @@ public class FileTransfer : Object { .value(db.file_transfer.local_time, (long) local_time.to_unix()) .value(db.file_transfer.encryption, encryption) .value(db.file_transfer.file_name, file_name) - .value(db.file_transfer.size, size) + .value(db.file_transfer.size, (long) size) .value(db.file_transfer.state, state) .value(db.file_transfer.provider, provider) .value(db.file_transfer.info, info); - if (file_name != null) builder.value(db.file_transfer.file_name, file_name); if (path != null) builder.value(db.file_transfer.path, path); if (mime_type != null) builder.value(db.file_transfer.mime_type, mime_type); + if (path != null) builder.value(db.file_transfer.path, path); + if (modification_date != null) builder.value(db.file_transfer.modification_date, (long) modification_date.to_unix()); + if (width != -1) builder.value(db.file_transfer.width, width); + if (height != -1) builder.value(db.file_transfer.height, height); + if (length != -1) builder.value(db.file_transfer.length, (long) length); id = (int) builder.perform(); + + foreach (Xep.CryptographicHashes.Hash hash in hashes.hashes) { + db.file_hashes.insert() + .value(db.file_hashes.id, id) + .value(db.file_hashes.algo, hash.algo) + .value(db.file_hashes.value, hash.val) + .perform(); + } + foreach (Xep.JingleContentThumbnails.Thumbnail thumbnail in thumbnails) { + db.file_thumbnails.insert() + .value(db.file_thumbnails.id, id) + .value(db.file_thumbnails.uri, thumbnail.uri) + .value(db.file_thumbnails.mime_type, thumbnail.media_type) + .value(db.file_thumbnails.width, thumbnail.width) + .value(db.file_thumbnails.height, thumbnail.height) + .perform(); + } + + for(int i = 0; i < sfs_sources.get_n_items(); i++) { + Object source_object = sfs_sources.get_item(i); + SerializedSfsSource source = source_object as SerializedSfsSource; + db.sfs_sources.insert() + .value(db.sfs_sources.id, id) + .value(db.sfs_sources.type, source.type) + .value(db.sfs_sources.data, source.data) + .perform(); + } + notify.connect(on_update); + sfs_sources.items_changed.connect((position, removed, added) => { + on_update_sources_items(this, position, removed, added); + }); } public File get_file() { @@ -161,7 +245,7 @@ public class FileTransfer : Object { case "mime-type": update_builder.set(db.file_transfer.mime_type, mime_type); break; case "size": - update_builder.set(db.file_transfer.size, size); break; + update_builder.set(db.file_transfer.size, (long) size); break; case "state": if (state == State.IN_PROGRESS) return; update_builder.set(db.file_transfer.state, state); break; @@ -169,9 +253,69 @@ public class FileTransfer : Object { update_builder.set(db.file_transfer.provider, provider); break; case "info": update_builder.set(db.file_transfer.info, info); break; + case "modification-date": + update_builder.set(db.file_transfer.modification_date, (long) modification_date.to_unix()); break; + case "width": + update_builder.set(db.file_transfer.width, width); break; + case "height": + update_builder.set(db.file_transfer.height, height); break; + case "length": + update_builder.set(db.file_transfer.length, (long) length); break; } update_builder.perform(); } + + private void on_update_sources_items(FileTransfer file_transfer, uint position, uint removed, uint added) { + for(uint i = position; i < position + added; i++) { + Object source_object = file_transfer.sfs_sources.get_item(i); + SerializedSfsSource source = source_object as SerializedSfsSource; + db.sfs_sources.insert() + .value(db.sfs_sources.id, id) + .value(db.sfs_sources.type, source.type) + .value(db.sfs_sources.data, source.data) + .perform(); + } + } + + public Xep.FileMetadataElement.FileMetadata to_metadata_element() { + Xep.FileMetadataElement.FileMetadata metadata = new Xep.FileMetadataElement.FileMetadata(); + metadata.name = this.file_name; + metadata.mime_type = this.mime_type; + metadata.size = this.size; + metadata.desc = this.desc; + metadata.date = this.modification_date; + metadata.width = this.width; + metadata.height = this.height; + metadata.length = this.length; + metadata.hashes = this.hashes; + metadata.thumbnails = this.thumbnails; + return metadata; + } + + public async Xep.StatelessFileSharing.SfsElement to_sfs_element() { + Xep.StatelessFileSharing.SfsElement sfs_element = new Xep.StatelessFileSharing.SfsElement(); + sfs_element.metadata = this.to_metadata_element(); + for(int i = 0; i < sfs_sources.get_n_items(); i++) { + Object source_object = sfs_sources.get_item(i); + SerializedSfsSource source = source_object as SerializedSfsSource; + sfs_element.sources.add(yield source.to_sfs_source()); + } + + return sfs_element; + } + + public void with_metadata_element(Xep.FileMetadataElement.FileMetadata metadata) { + this.file_name = metadata.name; + this.mime_type = metadata.mime_type; + this.size = metadata.size; + this.desc = metadata.desc; + this.modification_date = metadata.date; + this.width = metadata.width; + this.height = metadata.height; + this.length = metadata.length; + this.hashes = metadata.hashes; + this.thumbnails = metadata.thumbnails; + } } } |