Commit 924077e9 authored by Sascha Pfeiffer's avatar Sascha Pfeiffer

some more progress to fileupload

Signed-off-by: default avatarSascha Pfeiffer <sascha.pfeiffer@psono.com>
parent 2af00f1c
......@@ -346,6 +346,7 @@
<script src="js/service/manager-secret-link.js" type="application/javascript"></script>
<script src="js/service/manager-share-link.js" type="application/javascript"></script>
<script src="js/service/manager-export.js" type="application/javascript"></script>
<script src="js/service/manager-file-transfer.js" type="application/javascript"></script>
<script src="js/service/manager-hosts.js" type="application/javascript"></script>
<script src="js/service/manager-import.js" type="application/javascript"></script>
<script src="js/service/manager-security-report.js" type="application/javascript"></script>
......
......@@ -2470,6 +2470,44 @@
return call(connection_type, endpoint, data, headers, session_secret_key);
};
/**
* @ngdoc
* @name psonocli.apiClient#create_file
* @methodOf psonocli.apiClient
*
* @description
* Ajax PUT request to create a file with the token as authentication
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {string} shard_id The id of the target shard
* @param {int} size The size of the complete file in bytes
* @param {int} chunk_count The amount of chunks that this file is split into
* @param {string} link_id the local id of the file in the datastructure
* @param {string|undefined} [parent_datastore_id] (optional) id of the parent datastore, may be left empty if the share resides in a share
* @param {string|undefined} [parent_share_id] (optional) id of the parent share, may be left empty if the share resides in the datastore
*
* @returns {promise} Returns a promise with the new file_id
*/
var create_file = function (token, session_secret_key, shard_id, size, chunk_count, link_id, parent_datastore_id, parent_share_id) {
var endpoint = '/file/';
var connection_type = "PUT";
var data = {
shard_id: shard_id,
size: size,
chunk_count: chunk_count,
link_id: link_id,
parent_datastore_id: parent_datastore_id,
parent_share_id: parent_share_id
};
var headers = {
"Authorization": "Token " + token
};
return call(connection_type, endpoint, data, headers, session_secret_key);
};
/**
* @ngdoc
* @name psonocli.apiClient#delete_account
......@@ -2575,6 +2613,7 @@
delete_membership: delete_membership,
accept_membership: accept_membership,
decline_membership: decline_membership,
create_file: create_file,
delete_account: delete_account
};
};
......
......@@ -16,7 +16,7 @@
* Service to talk to the psono REST api
*/
var apiFileserver = function($http, $q, $rootScope, storage, cryptoLibrary, device) {
var apiFileserver = function($http, $q, $rootScope, storage, cryptoLibrary, device, offlineCache) {
var decrypt_data = function(session_secret_key, data, req) {
if (session_secret_key && data !== null
......@@ -69,20 +69,22 @@
* @description
* Ajax POST request to upload a file chunk
*
* @param {Uint8Array} file_chunk The content of the file chunk to upload
* @param {uuid} shard_id The target shard ID
* @param {string} hash_blake2b The blake2b hash
* @param {string} token The token of the user
* @param {Blob} chunk The content of the chunk to upload
* @param {string} ticket The ticket to authenticate the upload
* @param {string} ticket_nonce The nonce of the ticket
*
* @returns {promise} promise
*/
var upload = function (file_chunk, shard_id, hash_blake2b) {
var upload = function (token, chunk, ticket, ticket_nonce) {
var endpoint = '/upload/';
var connection_type = "POST";
var data = new FormData();
data.append('file', file_chunk);
data.append('shard_id', shard_id);
data.append('hash_blake2b', hash_blake2b);
data.append('token', token);
data.append('chunk', chunk);
data.append('ticket', ticket);
data.append('ticket_nonce', ticket_nonce);
var headers = {
'Content-Type': undefined
};
......
......@@ -11,7 +11,7 @@
* @requires psonocli.helper
* @requires psonocli.cryptoLibrary
* @requires psonocli.storage
* @requires psonocli.apiFileserver
* @requires psonocli.managerFileTransfer
*
* @description
* Service that provides the possible item blueprints e.g.:
......@@ -22,7 +22,7 @@
*/
var itemBlueprint = function($q, $rootScope, $window, $uibModal, helper, cryptoLibrary, storage, apiFileserver) {
var itemBlueprint = function($q, $rootScope, $window, $uibModal, helper, cryptoLibrary, storage, managerFileTransfer) {
var _default = "website_password";
......@@ -205,7 +205,8 @@
alternativeSave: function(selected, parent, path, modalClose){
var file_secret_key = cryptoLibrary.generate_secret_key();
var file_id = cryptoLibrary.generate_uuid();
var file_chunk_size = 128*1024*1024; //128*1024*1024; // in bytes. e.g. 128*1024*1024 Bytes = 128 MB
var link_id = cryptoLibrary.generate_uuid();
var shard_id = 'd7054d0a-060f-46f9-abc8-31b206f8171d';
......@@ -216,7 +217,7 @@
* @param file_id
* @param file_secret_key
*/
function upload_file(file, file_id, file_secret_key) {
function multi_chunk_upload(file, file_id, file_secret_key) {
var defer = $q.defer();
......@@ -236,7 +237,7 @@
console.log("blake2b " + chunk_position + " " + (new Date().getTime() - time_start)/1000);
time_start = new Date().getTime();
apiFileserver.upload(new Blob([encrypted_bytes], {type: 'application/octet-stream'}), shard_id, hash).then(function() {
managerFileTransfer.upload(new Blob([encrypted_bytes], {type: 'application/octet-stream'}), file_id, chunk_position, shard_id, hash).then(function() {
console.log("upload " + chunk_position + " " + (new Date().getTime() - time_start)/1000);
time_start = new Date().getTime();
resolve()
......@@ -263,8 +264,6 @@
var is_last = false;
var is_first = true;
var file_slice_start = 0;
var file_chunk_size = 128*1024*1024; //128*1024*1024; // in bytes. e.g. 128*1024*1024 Bytes = 128 MB
var file_chunk_count = Math.ceil(file.size / file_chunk_size);
while (file_slice_start <= file.size) {
var bytes_to_go = Math.min(file_chunk_size, file.size-file_slice_start);
......@@ -318,9 +317,31 @@
if (!file) {
return;
}
upload_file(file, file_id, file_secret_key).then(function() {
console.log("upload_file resolved");
})
var chunk_count = Math.ceil(file.size / file_chunk_size);
var size = file.size;
var parent_datastore_id = undefined;
var parent_share_id = undefined;
if (parent.hasOwnProperty("share_id")) {
parent_share_id = parent.share_id;
} else if(parent.hasOwnProperty("datastore_id")) {
parent_datastore_id = parent.datastore_id;
}
var onSuccess = function(file_id){
multi_chunk_upload(file, file_id, file_secret_key).then(function() {
console.log("multi_chunk_upload resolved");
})
};
var onError = function() {
//pass
};
managerFileTransfer.create_file(shard_id, size + chunk_count * 40, chunk_count, link_id, parent_datastore_id, parent_share_id)
.then(onSuccess, onError);
}
selected.skipRegularCreate = true;
......@@ -941,7 +962,7 @@
* @returns {boolean} returns whether the server supports files or not
*/
function server_supports_files() {
return storage.find_key('config', 'server_info').value && storage.find_key('config', 'server_info').value.hasOwnProperty('files') && storage.find_key('config', 'server_info').value['files']
return storage.find_key('config', 'server_info') && storage.find_key('config', 'server_info').value && storage.find_key('config', 'server_info').value.hasOwnProperty('files') && storage.find_key('config', 'server_info').value['files']
}
/**
......@@ -1132,6 +1153,6 @@
};
var app = angular.module('psonocli');
app.factory("itemBlueprint", ['$q', '$rootScope', '$window', '$uibModal', 'helper', 'cryptoLibrary', 'storage', 'apiFileserver', itemBlueprint]);
app.factory("itemBlueprint", ['$q', '$rootScope', '$window', '$uibModal', 'helper', 'cryptoLibrary', 'storage', 'managerFileTransfer', itemBlueprint]);
}(angular));
......@@ -5,16 +5,51 @@
* @ngdoc service
* @name psonocli.managerFileTransfer
* @requires $q
* @requires $window
* @requires $timeout
* @requires psonocli.managerSecret
* @requires psonocli.managerDatastorePassword
* @requires psonocli.managerBase
* @requires psonocli.cryptoLibrary
* @requires psonocli.apiClient
* @requires psonocli.apiFileserver
*
* @description
* Service to manage the export of datastores
* Service to manage everything around file transfer
*/
var managerFileTransfer = function($q, $window, $timeout, managerSecret, managerDatastorePassword) {
var managerFileTransfer = function($q, managerBase, cryptoLibrary , apiClient, apiFileserver) {
/**
* @ngdoc
* @name psonocli.managerFileTransfer#create_file
* @methodOf psonocli.managerFileTransfer
*
* @description
* Triggered once someone wants to create a file object
*
* @param shard_id The id of the shard this upload goes to
* @param size The file size in bytes
* @param chunk_count The amount of chunks to upload
* @param link_id The id of the link
* @param parent_datastore_id The id of the parent datastore (can be undefined if the parent is a share)
* @param parent_share_id The id of the parent share (can be undefined if the parent is a datastore)
*
* @returns {promise} promise
*/
var create_file = function (shard_id, size, chunk_count, link_id, parent_datastore_id, parent_share_id) {
var onError = function(result) {
return $q.reject(result.data)
};
var onSuccess = function(result) {
return result.data.file_id;
};
return apiClient.create_file(managerBase.get_token(),
managerBase.get_session_secret_key(), shard_id, size, chunk_count, link_id, parent_datastore_id, parent_share_id)
.then(onSuccess, onError);
};
/**
......@@ -23,20 +58,48 @@
* @methodOf psonocli.managerFileTransfer
*
* @description
* Triggered once someone wants to upload a file
* Triggered once someone wants to actually upload the file
*
* @param {Blob} chunk The content of the chunk to upload
* @param {uuid} file_id The target id of the file this chunk belongs to
* @param {int} chunk_position The sequence number of the chunk to determine the order
* @param {uuid} shard_id The target shard ID
* @param {string} hash_blake2b The blake2b hash
*
* @returns {promise} promise
*/
var upload = function () {
console.log("managerFileTransfer:upload")
var upload = function (chunk, file_id, chunk_position, shard_id, hash_blake2b) {
var ticket = {
'file_id': file_id,
'chunk_position': chunk_position,
'shard_id': shard_id,
'hash_blake2b': hash_blake2b
};
var ticket_enc = cryptoLibrary.encrypt_data(JSON.stringify(ticket), managerBase.get_session_secret_key());
var onError = function(result) {
return $q.reject(result.data)
};
var onSuccess = function(result) {
return result.data;
};
return apiFileserver.upload(managerBase.get_token(), chunk, ticket_enc.text, ticket_enc.nonce)
.then(onSuccess, onError);
};
return {
create_file: create_file,
upload: upload
};
};
var app = angular.module('psonocli');
app.factory("managerFileTransfer", ['$q', '$window', '$timeout', 'managerSecret', 'managerDatastorePassword', managerFileTransfer]);
app.factory("managerFileTransfer", ['$q', 'managerBase', 'cryptoLibrary', 'apiClient', 'apiFileserver', managerFileTransfer]);
}(angular));
\ No newline at end of file
......@@ -129,6 +129,11 @@
* @param {string} size The size of the modal
*/
var open_new_item = function (datastore, parent, path, size) {
if (typeof parent === 'undefined') {
parent = datastore;
}
var modalInstance = $uibModal.open({
templateUrl: 'view/modal-new-entry.html',
controller: 'ModalDatastoreNewEntryCtrl',
......@@ -152,10 +157,6 @@
return;
}
if (typeof parent === 'undefined') {
parent = datastore;
}
if (typeof parent.items === 'undefined') {
parent.items = [];
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment