File Upload to safeMutable Issue

mutabledata

#1

@Krishna @WhiteOutMashups
Hi, It looks like the browser does not allow me to upload files to safeMutable. Its not that only my code. The code which was working previously that was done by someone else also not working. Can you guide me what should I do?? I have tested with old version and very latest version too.

For your reference have a look on this below code.

var auth;
var Container = "apps/ronald";
var file = document.getElementById("file");
var filepath = document.getElementById("filepath");

//Finds and adds EventListener on buttons
window.document.getElementById("authorise").addEventListener("click", function () {
  'use strict';
  authorise();
});

window.document.getElementById("istokenvalid").addEventListener("click", function () {
  'use strict';
  istokenvalid();
});

window.document.getElementById("freetoken").addEventListener("click", function () {
  'use strict';
  freetoken();
});

window.document.getElementById("uploadfile").addEventListener("click", function () {
  'use strict';
  uploadfile();
});

window.document.getElementById("showfile").addEventListener("click", function () {
  'use strict';
  viewFiles();
});

//initialises and authorises with the network
function authorise() {
  'use strict';

  var app = {
    name: "BabbySAFEapi",
    id: "ronald",
    version: "1.0",
    vendor: "ronald.apps",
  }

  var permissions = {
    '_public': [
      'Read',
      'Insert',
      'Delete',
      'ManagePermissions'
    ],
    '_publicNames': [
      'Read',
      'Insert',
      'Update'
    ]
  };

  var owncontainer = {
    own_container: true
  };

  // Initialise applications
  window.safeApp.initialise(app)
    .then(appToken => {
      window.safeApp.authorise(appToken, permissions, owncontainer)
        .then(auth => {
          // Connect app to the network
          window.safeApp.connectAuthorised(appToken, auth)
            .then(authorisedAppToken => {
              window.auth = authorisedAppToken;
              $('#authorise-status').html('Authorised');
            });
        })
    })
    .catch(err => {
      $('#authorise-status').html('Not Authorised');
      console.error('Error from webapp: ', err);
    });
}

//checks network and token status
function istokenvalid() {
  window.safeApp.isRegistered(auth)
    .then((registered) => {
      if (registered == true) {
        $('#authorise-status').html('Already Authorised');
      } else {
        $('#authorise-status').html('Not Authorised');
      }
    });
}

//frees safe instance from memory
function freetoken() {
  window.safeApp.free(auth);
  auth = null;
  appToken = null;
  $('#authorise-status').html('Authorised Was Removed');
  location.reload();
}

//upload files into network
function uploadfile() {
  var file = document.getElementById("file");
  var reader = new FileReader();
  var content = null;

  reader.readAsArrayBuffer(new Blob([file.files[0]]));

  reader.onload = function (event) {
    var arrayBuffer = reader.result;
    content = new Uint8Array(arrayBuffer);
    return content;
  };

  window.safeApp.getContainer(auth, Container)
    .then((mdHandle) => window.safeMutableData.newMutation(auth)
      .then((mutationHandle) =>
        window.safeMutableDataMutation.insert(mutationHandle, file.files[0].name, content)
          .then(() =>
            window.safeMutableData.applyEntriesMutation(mdHandle, mutationHandle))
          .then(() => {
            console.log('New entry was inserted in the MutableData and committed to the network');
            $('#fileshow').empty();
            viewFiles();
          })
      )
    )
    .catch((err) => {
      console.error(err);
    });
}

function saveTextAsFile() {

  var textToSave = document.getElementById("inputTextToSave").value;
  var textReader = new FileReader();
  var fileNameToSaveAs = document.getElementById("inputFileNameToSaveAs").value;
  var textContent = null;

  textReader.readAsArrayBuffer(new Blob([textToSave], { type: "text/plain" }));

  textReader.onload = function (event) {
    var arrayBuffer = textReader.result;
    textContent = new Uint8Array(arrayBuffer);
    return textContent;
  };

  window.safeApp.getContainer(auth, Container)
    .then(mdHandle => window.safeMutableData.newMutation(auth)
      .then((mutationHandle) =>
        window.safeMutableDataMutation.insert(mutationHandle, fileNameToSaveAs, textContent)
          .then(_ => window.safeMutableData.applyEntriesMutation(mdHandle, mutationHandle))
          .then(_ => {
            console.log('Hore');
            $('#fileshow').empty();
            viewFiles();
            inputTextToSave.value = '';
            inputFileNameToSaveAs.value = '';
          })
      )
    )
    .then(_ => {

    })
    .catch((err) => {
      console.error(err);
    });
}

// upload text into network
function uploadtext() {
  var keytime = new Date().getTime().toString();
  window.safeApp.getContainer(auth, Container)
    .then(mdHandle => window.safeMutableData.newMutation(auth)
      .then((mutationHandle) =>
        window.safeMutableDataMutation.insert(mutationHandle, keytime, text.value)
          .then(_ => window.safeMutableData.applyEntriesMutation(mdHandle, mutationHandle))
          .then(_ => {
            console.log('New entry was inserted in the MutableData and committed to the network');
            $('#fileshow').empty();
            viewFiles();
          })
      )
    )
    .then(_ => {
      text.value = '';
    })
    .catch((err) => {
      console.error(err);
    });
}

function viewFiles() {
  var inc = 0;
  window.safeApp.getContainer(auth, Container)
    .then((mdHandle) => window.safeMutableData.getEntries(mdHandle)
      .then((entriesHandle) => window.safeMutableDataEntries.forEach(entriesHandle, (key, value) => {

        var htmlContent = "";

        switch ((new TextDecoder("utf-8").decode(key)).split('.').pop()) {
          //Text Format
          case "txt":
            htmlContent = "<textarea class='tarControl'>" + (uintToString(value.buf)) + "</textarea>";
            break;

          case "html":
          case "htm":
          case "css":
          case "js":
          case "json":
          case "md":
          case "odt":
          case "rtf":
          case "csv":
            htmlContent = "<textarea class='tarControl'>" + (new TextDecoder("utf-8").decode(value.buf)) + "</textarea>";
            break;

          //Image Format
          case "jpg":
          case "jpeg":
          case "png":
          case "gif":
          case "tiff":
          case "tif":
          case "ico":
          case "webp":
          case "svg":
          case "bmp":
            htmlContent = "<img class='img-fluid img-thumbnail imgControl' src='data:image/" + (new TextDecoder("utf-8").decode(key)).split('.').pop() + ";base64," + arrayBufferToBase64(value.buf) + "'/>";
            break;

          //Audio Format
          case "mp3":
          case "oga":
          case "wav":
            htmlContent = "<audio controls src='data:audio/" + (new TextDecoder("utf-8").decode(key)).split('.').pop() + ";base64," + arrayBufferToBase64(value.buf) + "' type='audio/" + (new TextDecoder("utf-8").decode(key)).split('.').pop() + "'></audio>";
            break;

          //Video Format
          case "mp4":
          case "ogv":
          case "ogg":
          case "webm":
            htmlContent = "<video class='video-js' controls> <source src='data:video/" + (new TextDecoder("utf-8").decode(key)).split('.').pop() + ";base64," + arrayBufferToBase64(value.buf) + "' type='video/" + (new TextDecoder("utf-8").decode(key)).split('.').pop() + "'></video>";
            break;
        }
        inc++;

        var fileNo = '<div class="file-no">' + inc + '</div>';
        var fileContent = '<div class="file-content">' + htmlContent + '</div>';
        var fileName = '<div class="file-name">' + (new TextDecoder("utf-8").decode(key)) + '</div>';
        var fileThird = '<div class="file-name">' + (new TextDecoder("utf-8").decode(key)).split('.').pop() + '</div>';
        var fileAction = '<div class="file-action"><button id="delete-' + inc + '" class="btn btn-warning">x</button></div>';

        $('#fileshow').append('<div class="col-md-4">' + fileNo + fileContent + fileName + fileAction + '</div>');
      })
      )
    )
    .catch((err) => {
      console.err(err);
    });
}

function arrayBufferToBase64(buffer) {
  var binary = '';
  var bytes = new Uint8Array(buffer);
  var len = bytes.byteLength;
  for (var inc = 0; inc < len; inc++) {
    binary += String.fromCharCode(bytes[inc]);
  }
  return window.btoa(binary);
}

function base64ToArrayBuffer(base64) {
  var binary_string = window.atob(base64);
  var len = binary_string.length;
  var bytes = new Uint8Array(len);
  for (var inc = 0; inc < len; inc++) {
    bytes[inc] = binary_string.charCodeAt[inc];
  }
  return bytes.buffer;
}

function uintToString(uintArray) {
  return new TextDecoder("utf-8").decode(uintArray);
}

function getMessages() {
  textarea.value = '';
  document.getElementById('messages').innerHTML = '';
  window.safeApp.getContainer(auth, '_public')
    .then(mdHandle => {
      window.safeMutableData.getEntries(mdHandle)
        .then(entriesHandle => {
          window.safeMutableDataEntries.forEach(entriesHandle, (key, value) => {
            var el = document.getElementById('messages');
            var elChild = document.createElement('li');
            elChild.innerHTML = value.buf.toString();
            el.appendChild(elChild);
          });
          window.safeMutableDataEntries.free(entriesHandle);
          window.safeMutableData.free(mdHandle);
        }, err => {
          console.error(err);
        });
    });
}

function sendMessage() {
  var time = new Date().getTime().toString();
  window.safeApp.getContainer(auth, '_public')
    .then((mdHandle) => {
      window.safeMutableData.newMutation(auth)
        .then((mutationHandle) =>
          window.safeMutableDataMutation.insert(mutationHandle, time, textarea.value)
            .then(_ => window.safeMutableData.applyEntriesMutation(mdHandle, mutationHandle))
            .then(_ => {
              console.log('masuk: ', textarea.value, time);
              window.safeMutableDataMutation.free(mutationHandle);
              window.safeMutableData.free(mdHandle);
              getMessages();
            })
        );
    }
    )
    .catch((err) => {
      console.error(err);
    });
}

function delMessage() {
  window.safeApp.getContainer(auth, '_public')
    .then((mdHandle) => {
      window.safeMutableData.newMutation(auth)
        .then((mutationHandle) =>
          window.safeMutableDataMutation.remove(mutationHandle, 'key1', value.version + 1)
            .then(_ => {
              console.log('Registers a remove operation with mutation handle, later to be applied.');
              window.safeMutableData.applyEntriesMutation(mdHandle, mutationHandle);
            })
            .then(_ => {
              console.log('masuk: ', textarea.value, time);
              window.safeMutableDataMutation.free(mutationHandle);
              window.safeMutableData.free(mdHandle);
              getMessages();
            })
        )
    }
    )
    .catch((err) => {
      console.error(err);
    });
}

The error from browser is as below

DevTools failed to parse SourceMap: safe://babysafeapi.websafeapps/webview-preload.build.js.map
DevTools failed to parse SourceMap: safe://babysafeapi.websafeapps/bootstrap.min.css.map
C:\safe\SAFE\safe-browser\resources\app\webview-preload.build.js:40 Uncaught TypeError: Cannot read property 'apply' of undefined
    at Readable.r.on.data (C:\safe\SAFE\safe-browser\resources\app\webview-preload.build.js:40)
    at emitOne (events.js:96)
    at Readable.emit (events.js:191)
    at readableAddChunk (_stream_readable.js:178)
    at Readable.push (_stream_readable.js:136)
    at EventEmitter.onIPCMessage (C:\safe\SAFE\safe-browser\resources\app\node_modules\pauls-electron-rpc\lib\import-api.js:159)
    at emitMany (events.js:127)
    at EventEmitter.emit (events.js:204)
r.on.data @ C:\safe\SAFE\safe-browser\resources\app\webview-preload.build.js:40
emitOne @ events.js:96
emit @ events.js:191
readableAddChunk @ _stream_readable.js:178
Readable.push @ _stream_readable.js:136
onIPCMessage @ C:\safe\SAFE\safe-browser\resources\app\node_modules\pauls-electron-rpc\lib\import-api.js:159
emitMany @ events.js:127
emit @ events.js:204
application.js:129 Error: Core error: CoreError::RequestTimeout
    at module.exports (C:\safe\SAFE\safe-browser\resources\app\node_modules\@maidsafe\safe-node-app\src\native\_error.js:19:10)
    at args.push.ffi.Callback.restArgs (C:\safe\SAFE\safe-browser\resources\app\node_modules\@maidsafe\safe-node-app\src\native\_base.js:89:27)
    at C:\safe\SAFE\safe-browser\resources\app\node_modules\ffi\lib\callback.js:66:25

#2

Just from a quick look I think you are missing a step.

You shouldn’t store content in a mutable data entry, but a pointer/value (because mutable data are limited in size to 1MB for the whole structure).

So you first create an immutable data (from the file content) and then insert the address of that into the mutable data value.

Hope that helps.


#3

I would also add that the error seems to be a timeout, I assume you are testing this with alpha-2 network, perhaps you can give it a try with the mock routing to confirm this is not just a timeout issue?
Also depending on the size of the file you are trying to upload onto a MD’s entry you need to consider what @happybeing was saying above as you won’t be able to store a file with >1MB in a MD.


#4

@happybeing @bochaco Any suggestion for going thru some examples for using immutable data?? Cause in breaker-plugin… I could see only plaintext… I would really appreciate your help. :slight_smile:


#5

Sounds like you need to fix the timeout issue as well.

For an example of uploading files, I have some code that works with the Beaker plugin API (before the update last week anyway). It is not pretty, but it does show a way to do this.

Here’s the code to store a new file _createFile():

See also _getMdHandle() and _updateFile() in the same file.

Hope it helps.


#6

This topic was automatically closed after 60 days. New replies are no longer allowed.