From 83d80340e5976381b181fe249d8bea51c417b3e2 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 17 Feb 2017 17:23:24 +1030 Subject: [PATCH 1/6] Add a file upload/read into memory control --- index.html | 7 +++++++ js/site.js | 23 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index a31b36a..24e73d4 100644 --- a/index.html +++ b/index.html @@ -36,6 +36,13 @@

On OpenStreetMap

+
+
+ + +
+
+
Start by telling us where your business is located. diff --git a/js/site.js b/js/site.js index 50d9188..15b767e 100644 --- a/js/site.js +++ b/js/site.js @@ -74,9 +74,8 @@ $(window).on('hashchange', function() { findme_map.invalidateSize(); }); -$("#collect-data-done").click(function() { - location.hash = '#done'; - +/** @todo Params */ +function submit_note() { var note_body = "onosm.org submitted note from a business:\n" + "name: " + $("#name").val() + "\n" + "phone: " + $("#phone").val() + "\n" + @@ -92,5 +91,21 @@ $("#collect-data-done").click(function() { text: note_body }; - $.post('https://api.openstreetmap.org/api/0.6/notes.json', qwarg); + $.post('https://api.openstreetmap.org/api/0.6/notes.json', qwarg); +} +$("#collect-data-done").click(function() { + location.hash = '#done'; + + submit_note(); }); + +var locations = []; + +function read_local_file(file) { + var reader = new FileReader(); + reader.onload = function () { + locations.concat(reader.result.split("\n")); + }; + reader.readAsBinaryString(file); +} + From 8a810477705479c4f30bf509b91d3f41b6b87d92 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 17 Feb 2017 17:42:08 +1030 Subject: [PATCH 2/6] Add https://github.com/mholt/PapaParse at 229af7049775aaf5830ecd2f160d65275b953624 --- index.html | 1 + js/papaparse.min.js | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 js/papaparse.min.js diff --git a/index.html b/index.html index 24e73d4..740ebdf 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,7 @@ +
diff --git a/js/papaparse.min.js b/js/papaparse.min.js new file mode 100644 index 0000000..3dd6f69 --- /dev/null +++ b/js/papaparse.min.js @@ -0,0 +1,6 @@ +/*! + Papa Parse + v4.1.4 + https://github.com/mholt/PapaParse +*/ +!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof module&&module.exports?module.exports=b():a.Papa=b()}(this,function(){"use strict";function a(a,b){if(b=b||{},b.dynamicTyping=b.dynamicTyping||!1,b.worker&&y.WORKERS_SUPPORTED){var c=j();return c.userStep=b.step,c.userChunk=b.chunk,c.userComplete=b.complete,c.userError=b.error,b.step=q(b.step),b.chunk=q(b.chunk),b.complete=q(b.complete),b.error=q(b.error),delete b.worker,void c.postMessage({input:a,config:b,workerId:c.id})}var g=null;return"string"==typeof a?g=b.download?new d(b):new f(b):(s.File&&a instanceof File||a instanceof Object)&&(g=new e(b)),g.stream(a)}function b(a,b){function c(){"object"==typeof b&&("string"==typeof b.delimiter&&1===b.delimiter.length&&y.BAD_DELIMITERS.indexOf(b.delimiter)===-1&&(j=b.delimiter),("boolean"==typeof b.quotes||b.quotes instanceof Array)&&(h=b.quotes),"string"==typeof b.newline&&(k=b.newline),"string"==typeof b.quoteChar&&(l=b.quoteChar),"boolean"==typeof b.header&&(i=b.header))}function d(a){if("object"!=typeof a)return[];var b=[];for(var c in a)b.push(c);return b}function e(a,b){var c="";"string"==typeof a&&(a=JSON.parse(a)),"string"==typeof b&&(b=JSON.parse(b));var d=a instanceof Array&&a.length>0,e=!(b[0]instanceof Array);if(d&&i){for(var g=0;g0&&(c+=j),c+=f(a[g],g);b.length>0&&(c+=k)}for(var h=0;h0&&(c+=j);var n=d&&e?a[m]:m;c+=f(b[h][n],m)}h-1||" "===a.charAt(0)||" "===a.charAt(a.length-1);return c?l+a+l:a}function g(a,b){for(var c=0;c-1)return!0;return!1}var h=!1,i=!0,j=",",k="\r\n",l='"';c();var m=new RegExp(l,"g");if("string"==typeof a&&(a=JSON.parse(a)),a instanceof Array){if(!a.length||a[0]instanceof Array)return e(null,a);if("object"==typeof a[0])return e(d(a[0]),a)}else if("object"==typeof a)return"string"==typeof a.data&&(a.data=JSON.parse(a.data)),a.data instanceof Array&&(a.fields||(a.fields=a.meta&&a.meta.fields),a.fields||(a.fields=a.data[0]instanceof Array?a.fields:d(a.data[0])),a.data[0]instanceof Array||"object"==typeof a.data[0]||(a.data=[a.data])),e(a.fields||[],a.data||[]);throw"exception: Unable to serialize unrecognized input"}function c(a){function b(a){var b=o(a);b.chunkSize=parseInt(b.chunkSize),a.step||a.chunk||(b.chunkSize=null),this._handle=new g(b),this._handle.streamer=this,this._config=b}this._handle=null,this._paused=!1,this._finished=!1,this._input=null,this._baseIndex=0,this._partialLine="",this._rowCount=0,this._start=0,this._nextChunk=null,this.isFirstChunk=!0,this._completeResults={data:[],errors:[],meta:{}},b.call(this,a),this.parseChunk=function(a){if(this.isFirstChunk&&q(this._config.beforeFirstChunk)){var b=this._config.beforeFirstChunk(a);void 0!==b&&(a=b)}this.isFirstChunk=!1;var c=this._partialLine+a;this._partialLine="";var d=this._handle.parse(c,this._baseIndex,!this._finished);if(!this._handle.paused()&&!this._handle.aborted()){var e=d.meta.cursor;this._finished||(this._partialLine=c.substring(e-this._baseIndex),this._baseIndex=e),d&&d.data&&(this._rowCount+=d.data.length);var f=this._finished||this._config.preview&&this._rowCount>=this._config.preview;if(u)s.postMessage({results:d,workerId:y.WORKER_ID,finished:f});else if(q(this._config.chunk)){if(this._config.chunk(d,this._handle),this._paused)return;d=void 0,this._completeResults=void 0}return this._config.step||this._config.chunk||(this._completeResults.data=this._completeResults.data.concat(d.data),this._completeResults.errors=this._completeResults.errors.concat(d.errors),this._completeResults.meta=d.meta),!f||!q(this._config.complete)||d&&d.meta.aborted||this._config.complete(this._completeResults,this._input),f||d&&d.meta.paused||this._nextChunk(),d}},this._sendError=function(a){q(this._config.error)?this._config.error(a):u&&this._config.error&&s.postMessage({workerId:y.WORKER_ID,error:a,finished:!1})}}function d(a){function b(a){var b=a.getResponseHeader("Content-Range");return null===b?-1:parseInt(b.substr(b.lastIndexOf("/")+1))}a=a||{},a.chunkSize||(a.chunkSize=y.RemoteChunkSize),c.call(this,a);var d;t?this._nextChunk=function(){this._readChunk(),this._chunkLoaded()}:this._nextChunk=function(){this._readChunk()},this.stream=function(a){this._input=a,this._nextChunk()},this._readChunk=function(){if(this._finished)return void this._chunkLoaded();if(d=new XMLHttpRequest,this._config.withCredentials&&(d.withCredentials=this._config.withCredentials),t||(d.onload=p(this._chunkLoaded,this),d.onerror=p(this._chunkError,this)),d.open("GET",this._input,!t),this._config.chunkSize){var a=this._start+this._config.chunkSize-1;d.setRequestHeader("Range","bytes="+this._start+"-"+a),d.setRequestHeader("If-None-Match","webkit-no-cache")}try{d.send()}catch(a){this._chunkError(a.message)}t&&0===d.status?this._chunkError():this._start+=this._config.chunkSize},this._chunkLoaded=function(){if(4==d.readyState){if(d.status<200||d.status>=400)return void this._chunkError();this._finished=!this._config.chunkSize||this._start>b(d),this.parseChunk(d.responseText)}},this._chunkError=function(a){var b=d.statusText||a;this._sendError(b)}}function e(a){a=a||{},a.chunkSize||(a.chunkSize=y.LocalChunkSize),c.call(this,a);var b,d,e="undefined"!=typeof FileReader;this.stream=function(a){this._input=a,d=a.slice||a.webkitSlice||a.mozSlice,e?(b=new FileReader,b.onload=p(this._chunkLoaded,this),b.onerror=p(this._chunkError,this)):b=new FileReaderSync,this._nextChunk()},this._nextChunk=function(){this._finished||this._config.preview&&!(this._rowCount=this._input.size,this.parseChunk(a.target.result)},this._chunkError=function(){this._sendError(b.error)}}function f(a){a=a||{},c.call(this,a);var b,d;this.stream=function(a){return b=a,d=a,this._nextChunk()},this._nextChunk=function(){if(!this._finished){var a=this._config.chunkSize,b=a?d.substr(0,a):d;return d=a?d.substr(a):"",this._finished=!d,this.parseChunk(b)}}}function g(a){function b(){if(w&&n&&(k("Delimiter","UndetectableDelimiter","Unable to auto-detect delimiting character; defaulted to '"+y.DefaultDelimiter+"'"),n=!1),a.skipEmptyLines)for(var b=0;b=v.length?"__parsed_extra":v[d]),g=e(f,g),"__parsed_extra"===f?(c[f]=c[f]||[],c[f].push(g)):c[f]=g}w.data[b]=c,a.header&&(d>v.length?k("FieldMismatch","TooManyFields","Too many fields: expected "+v.length+" fields but parsed "+d,b):d1&&(k+=Math.abs(o-f),f=o):f=o}m.data.length>0&&(l/=m.data.length),("undefined"==typeof e||k1.99&&(e=k,d=j)}return a.delimiter=d,{successful:!!d,bestDelimiter:d}}function i(a){a=a.substr(0,1048576);var b=a.split("\r"),c=a.split("\n"),d=c.length>1&&c[0].length=b.length/2?"\r\n":"\r"}function j(a){var b=p.test(a);return b?parseFloat(a):a}function k(a,b,c,d){w.errors.push({type:a,code:b,message:c,row:d})}var l,m,n,p=/^\s*-?(\d*\.?\d+|\d+\.?\d*)(e[-+]?\d+)?\s*$/i,r=this,s=0,t=!1,u=!1,v=[],w={data:[],errors:[],meta:{}};if(q(a.step)){var x=a.step;a.step=function(d){if(w=d,c())b();else{if(b(),0===w.data.length)return;s+=d.data.length,a.preview&&s>a.preview?m.abort():x(w,r)}}}this.parse=function(c,d,e){if(a.newline||(a.newline=i(c)),n=!1,a.delimiter)"function"==typeof a.delimiter&&(a.delimiter=a.delimiter(c),w.meta.delimiter=a.delimiter);else{var f=g(c,a.newline);f.successful?a.delimiter=f.bestDelimiter:(n=!0,a.delimiter=y.DefaultDelimiter),w.meta.delimiter=a.delimiter}var j=o(a);return a.preview&&a.header&&j.preview++,l=c,m=new h(j),w=m.parse(l,d,e),b(),t?{meta:{paused:!0}}:w||{meta:{paused:!1}}},this.paused=function(){return t},this.pause=function(){t=!0,m.abort(),l=l.substr(m.getCharIndex())},this.resume=function(){t=!1,r.streamer.parseChunk(l)},this.aborted=function(){return u},this.abort=function(){u=!0,m.abort(),w.meta.aborted=!0,q(a.complete)&&a.complete(w),l=""}}function h(a){a=a||{};var b=a.delimiter,c=a.newline,d=a.comments,e=a.step,f=a.preview,g=a.fastMode,h=a.quoteChar||'"';if(("string"!=typeof b||y.BAD_DELIMITERS.indexOf(b)>-1)&&(b=","),d===b)throw"Comment character same as delimiter";d===!0?d="#":("string"!=typeof d||y.BAD_DELIMITERS.indexOf(d)>-1)&&(d=!1),"\n"!=c&&"\r"!=c&&"\r\n"!=c&&(c="\n");var i=0,j=!1;this.parse=function(a,k,l){function m(a){w.push(a),z=i}function n(b){return l?p():("undefined"==typeof b&&(b=a.substr(i)),y.push(b),i=r,m(y),v&&q(),p())}function o(b){i=b,m(y),y=[],D=a.indexOf(c,i)}function p(a){return{data:w,errors:x,meta:{delimiter:b,linebreak:c,aborted:j,truncated:!!a,cursor:z+(k||0)}}}function q(){e(p()),w=[],x=[]}if("string"!=typeof a)throw"Input must be a string";var r=a.length,s=b.length,t=c.length,u=d.length,v="function"==typeof e;i=0;var w=[],x=[],y=[],z=0;if(!a)return p();if(g||g!==!1&&a.indexOf(h)===-1){for(var A=a.split(c),B=0;B=f)return w=w.slice(0,f),p(!0)}}return p()}for(var C=a.indexOf(b,i),D=a.indexOf(c,i),E=new RegExp(h+h,"g");;)if(a[i]!==h)if(d&&0===y.length&&a.substr(i,u)===d){if(D===-1)return p();i=D+t,D=a.indexOf(c,i),C=a.indexOf(b,i)}else if(C!==-1&&(C=f)return p(!0)}else{var F=i;for(i++;;){var F=a.indexOf(h,F+1);if(F===-1)return l||x.push({type:"Quotes",code:"MissingQuotes",message:"Quoted field unterminated",row:w.length,index:i}),n();if(F===r-1){var G=a.substring(i,F).replace(E,h);return n(G)}if(a[F+1]!==h){if(a[F+1]===b){y.push(a.substring(i,F).replace(E,h)),i=F+1+s,C=a.indexOf(b,i),D=a.indexOf(c,i);break}if(a.substr(F+1,t)===c){if(y.push(a.substring(i,F).replace(E,h)),o(F+1+t),C=a.indexOf(b,i),v&&(q(),j))return p();if(f&&w.length>=f)return p(!0);break}}else F++}}return n()},this.abort=function(){j=!0},this.getCharIndex=function(){return i}}function i(){var a=document.getElementsByTagName("script");return a.length?a[a.length-1].src:""}function j(){if(!y.WORKERS_SUPPORTED)return!1;if(!v&&null===y.SCRIPT_PATH)throw new Error("Script path cannot be determined automatically when Papa Parse is loaded asynchronously. You need to set Papa.SCRIPT_PATH manually.");var a=y.SCRIPT_PATH||r;a+=(a.indexOf("?")!==-1?"&":"?")+"papaworker";var b=new s.Worker(a);return b.onmessage=k,b.id=x++,w[b.id]=b,b}function k(a){var b=a.data,c=w[b.workerId],d=!1;if(b.error)c.userError(b.error,b.file);else if(b.results&&b.results.data){var e=function(){d=!0,l(b.workerId,{data:[],errors:[],meta:{aborted:!0}})},f={abort:e,pause:m,resume:m};if(q(c.userStep)){for(var g=0;g Date: Fri, 17 Feb 2017 18:01:20 +1030 Subject: [PATCH 3/6] Parse the CSV into a location collection; and populate the various forms --- js/site.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/js/site.js b/js/site.js index 15b767e..bc9b28c 100644 --- a/js/site.js +++ b/js/site.js @@ -57,17 +57,20 @@ $(window).on('hashchange', function() { $('#collect-data-step').removeClass('hide'); $('#address-step').addClass('hide'); $('#confirm-step').addClass('hide'); + $('#upload-step').addClass('hide'); $('.steps').addClass('on-2'); $('.steps').removeClass('on-3'); } else if (location.hash == '#done') { $('#confirm-step').removeClass('hide'); $('#collect-data-step').addClass('hide'); $('#address-step').addClass('hide'); + $('#upload-step').addClass('hide'); $('.steps').addClass('on-3'); } else { $('#address-step').removeClass('hide'); $('#collect-data-step').addClass('hide'); $('#confirm-step').addClass('hide'); + $('#upload-step').addClass('hide'); $('.steps').removeClass('on-2'); $('.steps').removeClass('on-3'); } @@ -97,15 +100,61 @@ $("#collect-data-done").click(function() { location.hash = '#done'; submit_note(); + + if (locations.length > 0) { + read_next_location(); + } }); var locations = []; -function read_local_file(file) { - var reader = new FileReader(); - reader.onload = function () { - locations.concat(reader.result.split("\n")); - }; - reader.readAsBinaryString(file); +function read_next_location() { + location.hash = ''; + + var business_location = locations.pop(); + + console.log("Reading", business_location); + + $("#address").val(business_location["Address"]); + + $("#name").val(business_location["Location Name"]); + $("#phone").val(business_location["Phone"]); + $("#opening_hours").val(business_location["Opening Hours (“Monday to Friday 10am-5pm”)"]); + $("#website").val(business_location["Website"]); + $("#twitter").val(business_location["Twitter"]); + $("#category").val(business_location["Category"]); + + + $('#find').submit(); } +function read_local_file(file) { + locations = Papa.parse(file, { + delimiter: "", // auto-detect + newline: "", // auto-detect + quoteChar: '"', + header: true, + dynamicTyping: false, + preview: 0, + encoding: "", + worker: false, + comments: false, + step: undefined, + complete: function (csv) { + locations = csv.data; + + console.log("Read data", locations); + + read_next_location(); + }, + error: undefined, + download: false, + skipEmptyLines: true, + chunk: undefined, + fastMode: undefined, + beforeFirstChunk: undefined, + withCredentials: undefined + }); + + +} From 7ccbd06376f93acf8dc0808e6ad81124986c7df9 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 17 Feb 2017 18:07:04 +1030 Subject: [PATCH 4/6] Add test data --- template-test-data.csv | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 template-test-data.csv diff --git a/template-test-data.csv b/template-test-data.csv new file mode 100644 index 0000000..d341ca9 --- /dev/null +++ b/template-test-data.csv @@ -0,0 +1,3 @@ +Address,Category,Location Name,Phone Number,Website,Twitter,Opening Hours (“Monday to Friday 10am-5pm”) +"97 Pirie Street, Adelaide",Accountant,Test location,1300 600 300,http://google.com/,CloCkWeRX,24 7 +"98 Pirie Street, Adelaide",American Restaurant,Test location 2,1300 600 300,http://openstreetmap.org/,OpenStreetMap,Hello world From 9ce33d792375441419eba7ad1bc4af8d9f9a6c6f Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 17 Feb 2017 18:07:10 +1030 Subject: [PATCH 5/6] Fix mapping --- js/site.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/site.js b/js/site.js index bc9b28c..f214b61 100644 --- a/js/site.js +++ b/js/site.js @@ -118,7 +118,7 @@ function read_next_location() { $("#address").val(business_location["Address"]); $("#name").val(business_location["Location Name"]); - $("#phone").val(business_location["Phone"]); + $("#phone").val(business_location["Phone Number"]); $("#opening_hours").val(business_location["Opening Hours (“Monday to Friday 10am-5pm”)"]); $("#website").val(business_location["Website"]); $("#twitter").val(business_location["Twitter"]); From 82809fdb99a42e934632e4da594aa0829dff28fa Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 17 Feb 2017 18:15:20 +1030 Subject: [PATCH 6/6] Add ability to process through multiple locations --- index.html | 19 +++++++++++++------ js/site.js | 1 + template.csv | 1 + 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 template.csv diff --git a/index.html b/index.html index 740ebdf..8455cb8 100644 --- a/index.html +++ b/index.html @@ -37,12 +37,7 @@

On OpenStreetMap

-
-
- - -
-
+
@@ -64,6 +59,18 @@

On OpenStreetMap

+
+
+
+
+

Bulk Upload

+

Need to upload multiple locations? Download and complete the template.

+
+ + +
+
+

We found your location. Now tell us about your business.

diff --git a/js/site.js b/js/site.js index f214b61..1f66731 100644 --- a/js/site.js +++ b/js/site.js @@ -110,6 +110,7 @@ var locations = []; function read_next_location() { location.hash = ''; + $('#bulk-upload-count').text(locations.length + " location(s) remaining to process"); var business_location = locations.pop(); diff --git a/template.csv b/template.csv new file mode 100644 index 0000000..3510300 --- /dev/null +++ b/template.csv @@ -0,0 +1 @@ +Address,Category,Location Name,Phone Number,Website,Twitter,Opening Hours (“Monday to Friday 10am-5pm”)