Skip to content

Instantly share code, notes, and snippets.

@straup
Created September 22, 2014 13:21
Show Gist options
  • Select an option

  • Save straup/0ee19019afd88c6dbd2d to your computer and use it in GitHub Desktop.

Select an option

Save straup/0ee19019afd88c6dbd2d to your computer and use it in GitHub Desktop.

Revisions

  1. straup created this gist Sep 22, 2014.
    224 changes: 224 additions & 0 deletions upload.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,224 @@
    // See also: http://www.aaronland.info/weblog/2014/09/22/desire/#upload

    function upload_init(){

    $("#upload-form").submit(function(){

    try {

    var photos = $("#photo");
    var files = photos = photos[0].files;
    var file = files[0];

    var reader = new FileReader();

    reader.onload = function(evt){

    var data_uri = evt.target.result;

    var dt = new Date();
    var pending_id = window.btoa(dt.toISOString());

    var key = "upload_" + pending_id;

    localforage.setItem(key, data_uri, function(rsp){
    upload_process_pending(pending_id);
    });
    };

    reader.readAsDataURL(file)
    }

    catch(e){

    console.log("Hrm, there was a problem uploading your photo.", e);
    return false;
    }

    return false;
    });

    upload_clear_processing();

    setInterval(upload_process_pending, 30000);
    }

    function upload_clear_processing(){

    var re = /processing_(.*)/;

    localforage.keys(function(rsp){

    var count = rsp.length;

    for (var i=0; i < count; i++){

    var m = rsp[i].match(re);

    if (m){

    localforage.removeItem(m[0], function(){
    console.log("unset " + m[0]);
    });
    }
    }
    });
    }

    function upload_process_pending(){

    var re = /upload_(.*)/;

    localforage.keys(function(rsp){

    var count = rsp.length;

    for (var i=0; i < count; i++){

    var m = rsp[i].match(re);

    if (m){
    console.log("process pending id " + m[1]);
    upload_process_pending_id(m[1]);
    }
    }
    });

    }

    function upload_process_pending_id(pending_id){

    var processing_key = "processing_" + pending_id;
    var upload_key = "upload_" + pending_id;

    console.log("process id: " + processing_key);
    console.log("process id: " + upload_key);

    localforage.getItem(processing_key, function(rsp){

    if (rsp){
    console.log("got processing key, so skipping");
    return;
    }

    var dt = new Date();
    var ts = dt.getTime();

    localforage.setItem(processing_key, ts, function(rsp){

    console.log("set " + processing_key + ", to " + ts);

    localforage.getItem(upload_key, function(data_uri){

    console.log("got data uri for " + upload_key);

    try {
    var blob = upload_data_uri_to_blob(data_uri);
    }

    catch(e){
    console.log("failed to create a blob for " + upload_key + ", because " + e);
    return false;
    }

    upload_do_upload(blob, pending_id);
    });

    });

    });
    }

    function upload_do_upload(file, pending_id){

    console.log("do upload for " + pending_id);

    var data = new FormData();
    data.append('photo', file);

    var on_success = function(rsp){

    console.log(rsp);

    var processing_key = "upload_" + pending_id;
    var upload_key = "upload_" + pending_id;

    localforage.removeItem(upload_key, function(rsp){

    console.log("removed " + upload_key);

    localforage.removeItem(processing_key, function(rsp){
    console.log("removed " + processing_key);
    });

    });

    };

    var on_error = function(rsp){

    console.log(rsp);

    var processing_key = "processing_" + pending_id;

    localforage.removeItem(processing_key, function(rsp){
    console.log("removed " + processing_key);
    });

    var details = '';

    try {
    var rsp = JSON.parse(rsp['responseText']);
    details = rsp['error']['message'];

    console.log(details);
    }

    catch(e){
    console.log(e);
    }
    };

    $.ajax({
    url: 'https://upload.example.com/',
    type: "POST",
    data: data,
    cache: false,
    contentType: false,
    processData: false,
    dataType: "json",
    success: on_success,
    error: on_error,
    });

    return false;
    }

    // http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata

    function upload_data_uri_to_blob(data_uri){

    // convert base64/URLEncoded data component to raw binary data held in a string

    var byteString;

    if (data_uri.split(',')[0].indexOf('base64') >= 0){
    byteString = atob(data_uri.split(',')[1]);
    }

    else {
    byteString = unescape(data_uri.split(',')[1]);
    }

    // separate out the mime component
    var mimeString = data_uri.split(',')[0].split(':')[1].split(';')[0]

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);

    for (var i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
    }