(function () { 'use strict'; //service that handles uploading of files and images var serviceId = 'fileUpload'; angular.module('app').factory(serviceId, ['config', '$q', '$upload', 'user', fileUpload]); function fileUpload(config, $q, $upload, user) { var service = { uploadFile: uploadFile, uploadImage: uploadImage }; return service; //upload an image function uploadImage(obj, file, success, progress, error, uploadPath) { user.getProfile().then(function (theUser) { var data = { upload_preset: config.cloudinaryUploadPreset, tags: 'myimages,' + theUser.id }; //images are uploaded to Cloudinary $upload.upload({ url: config.cloudinaryApiBaseUrl + config.cloudinaryName + uploadPath, data: data, file: file }).progress(function (e) { var percent = Math.round((e.loaded * 100.0) / e.total); return progress(percent); }).success(function (data, status, headers, config) { return success(obj, data); }).error(function (data) { return error(); }); }); } //upload a (non-image) file function uploadFile(fileItem, file, success, progress, error, container) { user.getProfile().then(function (theUser) { //upload to azure blob storage return uploadToBlob(fileItem, file, success, progress, error, container); }); } //get the url of the Azure blob bucket to upload files to function getBucketUploadUrl(fileName, container) { fileName = fileName.replace("#", ""); fileName = fileName.replace(" ", ""); fileName = fileName.replace(")", ""); fileName = fileName.replace("(", ""); if (container) { return config.azureBlobUrl + container + '/' + fileName; } else { return config.azureBlobUrl + config.uploadBucketName + '/' + fileName; } } //we use Azure blob storage to upload files to - get the Azure Blob url for the file function getBlobUploadUrl(fileName, container) { //get the base url of blob storage var baseUrl = getBucketUploadUrl(fileName, container); //get the SAS (Secure Access Signature) token from cache (this signature allows us write access permissions to Azure Blob storage - so we can write the file there) var sas = user.getUploadBucketSasCached(); if (sas) { //check if the SAS token is still valid, if it is use the token - using moment.js for easy calculation of times var expiry = moment(sas.expiryTime).subtract('seconds', '30'); //30 seconds to allow for small differences in time calculations between machines if (expiry.isAfter(moment())) { var deferred = $q.defer(); deferred.resolve({ baseUrl: baseUrl, fullUrl: baseUrl + sas.sas }); return deferred.promise; } } if (config.appCode == 'OB' || config.appCode == 'CUPPA') { return user.getUploadBucketSasForContainerMyUsers(container).then(function (sas) { return { baseUrl: baseUrl, fullUrl: baseUrl + sas.sas }; }); } //we don't have a valid existing SAS so get the sas from the server if (container) { return user.getUploadBucketSasForContainer(container).then(function (sas) { return { baseUrl: baseUrl, fullUrl: baseUrl + sas.sas }; }); } else { return user.getUploadBucketSas().then(function (sas) { return { baseUrl: baseUrl, fullUrl: baseUrl + sas.sas }; }); } } //upload the file to blob storage (Azure) function uploadToBlob(fileItem, file, success, progress, error, container) { //first get the upload URL getBlobUploadUrl(fileItem.fileName, container).then(function (urls) { var fileReader = new FileReader(); fileItem.fileUrl = urls.baseUrl; fileItem.isDropBoxFile = false; fileReader.readAsArrayBuffer(file); //use the $upload service to write the file as part of an HTTP PUT request to Azure Blob storage fileReader.onload = function (e) { $upload.http({ url: urls.fullUrl, method: 'PUT', headers: { //azure needs these extra headers 'x-ms-blob-type': 'BlockBlob', 'Content-Type': file.type }, data: e.target.result }).progress(function (e) { //inform the user what progress we are making on the upload var percent = Math.round((e.loaded * 100.0) / e.total); return progress(percent); }).success(function (data, status, headers, config) { return success(fileItem, data); }).error(function (data) { return error(); }); } }); } } })();