From c464409d4362183c5e89d1607c23dfb955e595ed Mon Sep 17 00:00:00 2001 From: "Tim.willis" Date: Fri, 15 Jan 2016 16:33:47 -0500 Subject: [PATCH 1/3] Recommit from previous repository. --- db3.js | 81 ++++++ models/time.js | 17 ++ notes.txt | 15 + public/components_riot/layout/layout.js | 7 + public/components_riot/layout/layout.tag | 35 +++ public/components_riot/time_form/time_form.js | 111 +++++++ .../components_riot/time_form/time_form.tag | 259 +++++++++++++++++ .../times_added/times_added.js | 156 ++++++++++ .../times_added/times_added.tag | 274 ++++++++++++++++++ public/index.html | 18 ++ public/lib/riot.min.js | 2 + public/lib/riotcontrol.js | 17 ++ public/scripts/main.js | 5 + public/styles/layout.css | 3 + public/styles/layout.scss | 3 + routes/routes.js | 10 + routes/times.js | 257 ++++++++++++++++ server.js | 88 ++++++ 18 files changed, 1358 insertions(+) create mode 100644 db3.js create mode 100644 models/time.js create mode 100644 notes.txt create mode 100644 public/components_riot/layout/layout.js create mode 100644 public/components_riot/layout/layout.tag create mode 100644 public/components_riot/time_form/time_form.js create mode 100644 public/components_riot/time_form/time_form.tag create mode 100644 public/components_riot/times_added/times_added.js create mode 100644 public/components_riot/times_added/times_added.tag create mode 100644 public/index.html create mode 100644 public/lib/riot.min.js create mode 100644 public/lib/riotcontrol.js create mode 100644 public/scripts/main.js create mode 100644 public/styles/layout.css create mode 100644 public/styles/layout.scss create mode 100644 routes/routes.js create mode 100644 routes/times.js create mode 100644 server.js diff --git a/db3.js b/db3.js new file mode 100644 index 0000000..106879c --- /dev/null +++ b/db3.js @@ -0,0 +1,81 @@ +"use strict"; + +//var mongodb = require('mongodb'), ObjectId = require('mongodb').ObjectID, server = new mongodb.Server('localhost', 27017, {auto_reconnect: true}), +// db = new mongodb.Db('gstv', server, {wtimeout: 2000}); + +var MongoClient = require('mongodb').MongoClient; +var ObjectId = require('mongodb').ObjectID; +var assert = require('assert'); +var url = 'mongodb://localhost:27017/gstv'; +var db; +MongoClient.connect(url, function(err, my_db) { + assert.equal(null, err); + //console.log("Connected correctly to server."); + //db.close(); + db = my_db; +}); + +var db_module = (function() { + //var query = JSON.parse(query_string); + function db_module() { + this.process_query = function(query, callback) { + db.collection(query.collection, function (error, objects) { + if (error) { + console.error(error); + return; + } + if (query.object._id && typeof query.object._id != "object") { + query.object._id = new ObjectId(query.object._id); + } + if (query.object.foreignId && typeof query.object.foreignId != "object") { + query.object.foreignId = new ObjectId(query.object.foreignId); + } + if (query.verb == "post") { + objects.save(query.object, {safe: true}, function (error, result) { + if (error) { + //console.log(error); + } + ////console.log("result"); + ////console.log(result); + var data = result, response = {data: data}; + //observer.onNext(response); + callback(null, response); + }); + } + else if (query.verb == "get") { + //console.log(query.verb); + objects.find(query.object, function (error, result) { + if (error) { + console.error(error); + return; + } + result.toArray(function (error, results) { + //console.log(results); + var data = results, response = {data: data}; + //return response; + //callback.resolve({ times: response }); + callback(null, response); + }); + }); + } + else if (query.verb == "put") { + //console.log(query.verb); + objects.save(query.object, {safe: true}, function (error, result) { + if (error) { + console.error(error); + } + ////console.log("result"); + ////console.log(result); + var data = result, response = {data: data}; + //return response; + callback(null, response); + }); + } + }); + } + } + + return db_module; +})(); + +module.exports = db_module; \ No newline at end of file diff --git a/models/time.js b/models/time.js new file mode 100644 index 0000000..8d633b6 --- /dev/null +++ b/models/time.js @@ -0,0 +1,17 @@ +var time = (function () { + //timezone + //daylight savings time + function time(value_start, value_end, day, time_start, time_end, is_24, owner_id, deleted, _id) { + this.value_start = value_start; + this.value_end = value_end; + this.day = day; + this.time_start = time_start; + this.time_end = time_end; + this.is_24 = is_24; + this.owner_id = owner_id.toString(); + this.deleted = deleted ? deleted : null; + this._id = _id; + } + return time; +})(); +exports.time = time; diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..96f7900 --- /dev/null +++ b/notes.txt @@ -0,0 +1,15 @@ + + + +cd C:\Users\Tim\websitesWorking\GSTV\node-coding-exercise +node server + +if on another pc, move mongodb install to this location, copy paste. +C:\mongodb\Server\3.2\bin\mongod + + + + + + + diff --git a/public/components_riot/layout/layout.js b/public/components_riot/layout/layout.js new file mode 100644 index 0000000..9a55b2b --- /dev/null +++ b/public/components_riot/layout/layout.js @@ -0,0 +1,7 @@ +riot.tag2('layout', '

Time Schedule

', 'layout h1,[riot-tag="layout"] h1{ margin: 10px 0 0 0; }', '', function(opts) { +"use strict"; + +var owner_id = 1; + +this.on('mount', function () {}); +}, '{ }'); \ No newline at end of file diff --git a/public/components_riot/layout/layout.tag b/public/components_riot/layout/layout.tag new file mode 100644 index 0000000..14a6794 --- /dev/null +++ b/public/components_riot/layout/layout.tag @@ -0,0 +1,35 @@ + + +

Time Schedule

+ + + + + +
\ No newline at end of file diff --git a/public/components_riot/time_form/time_form.js b/public/components_riot/time_form/time_form.js new file mode 100644 index 0000000..c800ec5 --- /dev/null +++ b/public/components_riot/time_form/time_form.js @@ -0,0 +1,111 @@ +riot.tag2('time_form', '
Open 24hrs!
', 'time_form .hidden,[riot-tag="time_form"] .hidden{ display: none; }', '', function(opts) { +"use strict"; + +var _this = this; + +var time_start = undefined; +var time_end = undefined; + +var is_24_elem = undefined; +this.is_24 = this.opts.is_24 ? true : false; + +function validate_form(time_start_value, time_end_value) { + var message = undefined; + if (time_start_value >= time_end_value) { + message = 'Unable to Create/Update: The start time must be before the end time. '; + } + if (time_start_value === 0) { + message += 'Unable to Create/Update: start time is required. '; + } + if (time_end_value === 0) { + message += 'Unable to Create/Update: end time is required. '; + } + + return message ? message : true; +} + +this.submit_form = function (event) { + var is_valid = undefined; + event.preventDefault(); + is_valid = validate_form(parseInt(time_start.value), parseInt(time_end.value)); + if (is_valid === true) { + _this.error_message.style.display = 'none'; + _this.opts.submit_callback(_this.calculate_time_value({ time_start: time_start.options[time_start.selectedIndex].value, + time_end: time_end.options[time_end.selectedIndex].value, + day: _this.opts.day, + is_24: _this.is_24, + _id: _this.opts._id })); + } else { + _this.error_message.style.display = 'block'; + _this.error_message.innerText = is_valid; + } +}; +this.checked_changed = function (event) { + _this.is_24 = is_24_elem.checked; + _this.update(); +}; +this.delete_time = function (event) { + _this.opts.delete_callback({ time_start: time_start.selectedIndex != -1 ? time_start.options[time_start.selectedIndex].value : 0, + time_end: time_end.selectedIndex != -1 ? time_end.options[time_end.selectedIndex].value : 0, + day: _this.opts.day, + is_24: _this.is_24, + _id: _this.opts._id }); +}; +this.on('mount', function () { + setTimeout(function () { + if (_this.opts._id) { + time_start = document.getElementById('time_start' + _this.opts._id); + time_end = document.getElementById('time_end' + _this.opts._id); + + is_24_elem = document.getElementById('is_24_check' + _this.opts._id); + time_start.value = _this.opts.time_start; + time_end.value = _this.opts.time_end; + } else { + time_start = _this.time_start; + time_end = _this.time_end; + } + }, 1); +}); + +this.calculate_time_value = function (time_to_add) { + var value = 0, + value_start = 0, + value_end = 0; + switch (time_to_add.day) { + case "1": + value = 0; + break; + case "2": + value = 48; + break; + case "3": + value = 96; + break; + case "4": + value = 144; + break; + case "5": + value = 192; + break; + case "6": + value = 240; + break; + default: + value = 288; + } + if (time_to_add.day === "7") { + value_start = value + parseInt(time_to_add.time_start); + if (parseInt(time_to_add.time_end) > 48) { + value_end = parseInt(time_to_add.time_end); + } else { + value_end = value + parseInt(time_to_add.time_end); + } + } else { + value_start = value + parseInt(time_to_add.time_start); + value_end = value + parseInt(time_to_add.time_end); + } + time_to_add.value_start = value_start; + time_to_add.value_end = value_end; + return time_to_add; +}; +}, '{ }'); \ No newline at end of file diff --git a/public/components_riot/time_form/time_form.tag b/public/components_riot/time_form/time_form.tag new file mode 100644 index 0000000..c5c5686 --- /dev/null +++ b/public/components_riot/time_form/time_form.tag @@ -0,0 +1,259 @@ + + + +
+ + + + + + + + + + + + + + + + + + + Open 24hrs! + + + + +
+ + + + +
\ No newline at end of file diff --git a/public/components_riot/times_added/times_added.js b/public/components_riot/times_added/times_added.js new file mode 100644 index 0000000..f6ed1c2 --- /dev/null +++ b/public/components_riot/times_added/times_added.js @@ -0,0 +1,156 @@ +riot.tag2('times_added', '

Sunday

Monday

Tuesday

Wednesday

Thursday

Friday

Saturday

', 'times_added h2,[riot-tag="times_added"] h2{ margin-bottom:0; } times_added .hidden,[riot-tag="times_added"] .hidden{ display: none; }', '', function(opts) { +"use strict"; + +var _this = this; + +var self = this; +var owner_id = 1; +this.times = []; + +this.expand = function (event) { + var container = event.target.parentNode.querySelector('.container'); + event.target.classList.add('hidden'); + container.classList.remove('hidden'); +}; +this.close = function (event) { + var container = event.target.parentNode; + container.classList.add('hidden'); + event.target.parentNode.parentNode.querySelector('input.hidden').classList.remove('hidden'); +}; + +function validate_day(day, times, value_start, value_end) { + var my_array = times.find(function (time) { + if (time.day !== day && (time.value_start > value_end && time.value_start < value_start || time.value_end > value_end && time.value_end < value_start)) return time.day !== day && (time.value_start > value_end && time.value_start < value_start || time.value_end > value_end && time.value_end < value_start) ? true : false; + }); + return !my_array || my_array.length == 0 ? true : false; +} + +this.process_response = function (event) { + if (event.target.readyState == 4 && event.target.status == 200) { + var response = JSON.parse(event.target.responseText); + if (response.error) { + alert('Cannot add/update time: ' + response.error); + } else { + _this.get_times(owner_id); + } + } +}; + +this.time_added_24 = function (event) { + var xmlHttp = new XMLHttpRequest(); + var day = event.target.dataset.day; + var value = undefined, + is_valid = undefined, + day_name = undefined; + switch (day) { + case "1": + value = 0;day_name = 'sunday'; + break; + case "2": + value = 48;day_name = 'monday'; + break; + case "3": + value = 96;day_name = 'tuesday'; + break; + case "4": + value = 144;day_name = 'wednesday'; + break; + case "5": + value = 192;day_name = 'thursday'; + break; + case "6": + value = 240;day_name = 'friday'; + break; + default: + value = 288;day_name = 'saturday'; + } + if (validate_day(day, _this.times, value, value + 48)) { + _this[day_name].forEach(function (time) { + _this.time_deleted(time); + }); + + setTimeout(function () { + xmlHttp.onreadystatechange = _this.process_response; + xmlHttp.open("POST", "/owners/" + owner_id + "/times/"); + xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + xmlHttp.send(JSON.stringify({ time_start: null, + time_end: null, + day: day, + is_24: true, + value_start: value, + value_end: value + 48, + _id: null })); + }, 500); + } else { + alert('Unable to Create/Update: there is at least one overlapping time slot'); + } +}; +this.time_added = function (form) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = _this.process_response; + xmlHttp.open("POST", "/owners/" + owner_id + "/times/"); + xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + xmlHttp.send(JSON.stringify(form)); +}; +this.time_edited = function (form) { + form.owner_id = owner_id; + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = _this.process_response; + xmlHttp.open("PUT", "/times/" + form._id); + xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + xmlHttp.send(JSON.stringify(form)); +}; +this.time_deleted = function (form) { + form.owner_id = owner_id; + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = _this.process_response; + + xmlHttp.open("DELETE", "/times/" + form._id); + xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); + xmlHttp.send(JSON.stringify(form)); +}; + +this.seperate_days = function (times) { + _this.sunday = _this.times.filter(function (time) { + return time.day === "1" ? true : false; + }); + _this.monday = _this.times.filter(function (time) { + return time.day === "2" ? true : false; + }); + _this.tuesday = _this.times.filter(function (time) { + return time.day === "3" ? true : false; + }); + _this.wednesday = _this.times.filter(function (time) { + return time.day === "4" ? true : false; + }); + _this.thursday = _this.times.filter(function (time) { + return time.day === "5" ? true : false; + }); + _this.friday = _this.times.filter(function (time) { + return time.day === "6" ? true : false; + }); + _this.saturday = _this.times.filter(function (time) { + return time.day === "7" ? true : false; + }); +}; + +this.get_times = function (owner_id) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.onreadystatechange = function () { + if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { + if (xmlHttp.responseText) { + _this.times = JSON.parse(xmlHttp.responseText).times; + _this.seperate_days(_this.times); + } else { + _this.times = []; + } + _this.update(); + } + }; + xmlHttp.open("GET", "/owners/" + owner_id + "/times/", true); + xmlHttp.send(); +}; +self.on('mount', function () { + this.get_times(owner_id); +}); +}, '{ }'); \ No newline at end of file diff --git a/public/components_riot/times_added/times_added.tag b/public/components_riot/times_added/times_added.tag new file mode 100644 index 0000000..34e7a95 --- /dev/null +++ b/public/components_riot/times_added/times_added.tag @@ -0,0 +1,274 @@ + + +
+

Sunday

+ + +
+
+

Monday

+ + +
+
+

Tuesday

+ + +
+
+

Wednesday

+ + +
+
+

Thursday

+ + +
+
+

Friday

+ + +
+
+

Saturday

+ + +
+ + + +
\ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..4700d4c --- /dev/null +++ b/public/index.html @@ -0,0 +1,18 @@ + + + + + GSTV Coding Exercise + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/lib/riot.min.js b/public/lib/riot.min.js new file mode 100644 index 0000000..e688e06 --- /dev/null +++ b/public/lib/riot.min.js @@ -0,0 +1,2 @@ +/* Riot v2.3.1, @license MIT, (c) 2015 Muut Inc. + contributors */ +(function(e,t){"use strict";var n={version:"v2.3.1",settings:{}},r=0,i=[],o={},f="riot-",u=f+"tag",a="string",s="object",c="undefined",l="function",p=/^(?:opt(ion|group)|tbody|col|t[rhd])$/,d=["_item","_id","_parent","update","root","mount","unmount","mixin","isMounted","isLoop","tags","parent","opts","trigger","on","off","one"],g=(e&&e.document||{}).documentMode|0;n.observable=function(e){e=e||{};var t={},n=function(e,t){e.replace(/\S+/g,t)},r=function(t,n){Object.defineProperty(e,t,{value:n,enumerable:false,writable:false,configurable:false})};r("on",function(r,i){if(typeof i!="function")return e;n(r,function(e,n){(t[e]=t[e]||[]).push(i);i.typed=n>0});return e});r("off",function(r,i){if(r=="*")t={};else{n(r,function(e){if(i){var n=t[e];for(var r=0,o;o=n&&n[r];++r){if(o==i)n.splice(r--,1)}}else delete t[e]})}return e});r("one",function(t,n){function r(){e.off(t,r);n.apply(e,arguments)}return e.on(t,r)});r("trigger",function(r){var i=arguments.length-1,o=new Array(i);for(var f=0;fa-zA-Z0-9'",;\\]/.test(e)){throw new Error('Unsupported brackets "'+e+'"')}c=n.concat(e.replace(/(?=[[\]()*+?.^$|])/g,"\\").split(" "));s=d}c[4]=s(c[1].length>1?/(?:^|[^\\]){[\S\s]*?}/:/(?:^|[^\\]){[^}]*}/);c[5]=s(/\\({|})/g);c[6]=s(/(\\?)({)/g);c[7]=l("(\\\\?)(?:([[({])|("+c[3]+"))|"+o,t);c[9]=l(/^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S+)\s*}/);c[8]=e}v.settings.brackets=a=e}function h(e){if(a!==e){g(e)}}function v(e){h(v.settings.brackets);return e instanceof RegExp?s(e):c[e]}v.split=function m(e,t){var n=[],r,i,o,f,a=v(6);i=o=a.lastIndex=0;while(r=a.exec(e)){f=r.index;if(i){if(r[2]){a.lastIndex=l(r[2],a.lastIndex);continue}if(!r[3])continue}if(!r[1]){s(e.slice(o,f));o=a.lastIndex;a=c[6+(i^=1)];a.lastIndex=o}}if(e&&o2||r[0]){var i,o,f=[];for(i=o=0;i2&&!t?""+(n.push(e)-1)+"~":e}).replace(/\s+/g," ").trim().replace(/\ ?([[\({},?\.:])\ ?/g,"$1");if(e){var r=[],i=0,o;while(e&&(o=e.match(s))&&!o.index){var u,a,c=/,|([[{(])|$/g;e=RegExp.rightContext;u=o[2]?n[o[2]].slice(1,-1).trim().replace(/\s+/g," "):o[1];while(a=(o=c.exec(e))[1])l(a,c);a=e.slice(0,o.index);e=RegExp.rightContext;r[i++]=g(a,1,u)}e=!i?g(e,t):i>1?"["+r.join(",")+'].join(" ").trim()':r[0]}return e;function l(t,n){var r,i=1,o=t==="("?/[()]/g:t==="["?/[[\]]/g:/[{}]/g;o.lastIndex=n.lastIndex;while(r=o.exec(e)){if(r[0]===t)++i;else if(!--i)break}n.lastIndex=i?e.length:o.lastIndex}}var p='"in this?this:'+(typeof e!=="object"?"global":"window")+").";var d=/[,{][$\w]+:|(^ *|[^$\w\.])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g;function g(e,n,r){var i=t;e=e.replace(d,function(e,t,n,r,o){if(n){r=i?0:r+e.length;if(n!=="this"&&n!=="global"&&n!=="window"){e=t+'("'+n+p+n;if(r)i=(o=o[r])==="."||o==="("||o==="["}else if(r)i=!/^(?=(\.[$\w]+))\1(?:[^.[(]|$)/.test(o.slice(r))}return e});if(i){e="try{return "+e+"}catch(e){E(e,this)}"}if(r){e=(i?"function(){"+e+"}.call(this)":"("+e+")")+'?"'+r+'":""'}else if(n){e="function(v){"+(i?e.replace("return ","v="):"v=("+e+")")+';return v||v===0?v:""}.call(this)'}return e}r.parse=function(e){return e};return r}();var m=function(e){var t={tr:"tbody",th:"tr",td:"tr",tbody:"table",col:"colgroup"},n="div";e=e&&e<10;function r(r){var o=r&&r.match(/^\s*<([-\w]+)/),f=o&&o[1].toLowerCase(),u=t[f]||n,a=W(u);a.stub=true;if(e&&f&&(o=f.match(p)))i(a,r,f,!!o[1]);else a.innerHTML=r;return a}function i(e,t,r,i){var o=W(n),f=i?"select>":"table>",u;o.innerHTML="<"+f+t+"r){var i=t[--n];t.splice(n,1);i.unmount()}}function w(e,t){Object.keys(e.tags).forEach(function(n){var r=e.tags[n];if(q(r))$(r,function(e){B(e,n,t)});else B(r,n,t)})}function x(e,t,n){var r=e._root;e._virts=[];while(r){var i=r.nextSibling;if(n)t.insertBefore(r,n._root);else t.appendChild(r);e._virts.push(r);r=i}}function _(e,t,n,r){var i=e._root;for(var o=0;o(<\/\1>)?/gi,t||"")}function Y(e,t){return(t||document).querySelectorAll(e)}function ee(e,t){return(t||document).querySelector(e)}function te(e){function t(){}t.prototype=e;return new t}function ne(e){return H(e,"id")||H(e,"name")}function re(e,t,n){var r=ne(e),i=function(i){if(V(n,r))return;var o=q(i);if(!i)t[r]=e;else if(!o||o&&!V(i,e)){if(o)i.push(e);else t[r]=[i,e]}};if(!r)return;if(v.hasExpr(r))t.one("updated",function(){r=ne(e);i(t[r])});else i(t[r])}function ie(e,t){return e.slice(0,t.length)===t}var oe=function(){if(!e)return;var t=W("style"),n=ee("style[type=riot]");j(t,"type","text/css");if(n){n.parentNode.replaceChild(t,n);n=null}else document.getElementsByTagName("head")[0].appendChild(t);return t.styleSheet?function(e){t.styleSheet.cssText+=e}:function(e){t.innerHTML+=e}}();function fe(e,t,n){var r=o[t],f=e._innerHTML=e._innerHTML||e.innerHTML;e.innerHTML="";if(r&&e)r=new M(r,{root:e,opts:n},f);if(r&&r.mount){r.mount();if(!V(i,r))i.push(r)}return r}n.util={brackets:h,tmpl:v};n.mixin=function(){var e={};return function(t,n){if(!n)return e[t];e[t]=n}}();n.tag=function(e,t,n,r,i){if(k(r)){i=r;if(/^[\w\-]+\s?=/.test(n)){r=n;n=""}else r=""}if(n){if(k(n))i=n;else if(oe)oe(n)}o[e]={name:e,tmpl:t,attrs:r,fn:i};return e};n.tag2=function(e,t,n,r,i,f){if(n&&oe)oe(n);o[e]={name:e,tmpl:t,attrs:r,fn:i};return e};n.mount=function(e,t,n){var r,i,f=[];function c(e){var t="";$(e,function(e){t+=", *["+u+'="'+e.trim()+'"]'});return t}function l(){var e=Object.keys(o);return e+c(e)}function p(e){var r;if(e.tagName){if(t&&(!(r=H(e,u))||r!=t))j(e,u,t);var i=fe(e,t||e.getAttribute(u)||e.tagName.toLowerCase(),n);if(i)f.push(i)}else if(e.length)$(e,p)}if(typeof t===s){n=t;t=0}if(typeof e===a){if(e==="*")e=i=l();else e+=c(e.split(","));r=e?Y(e):[]}else r=e;if(t==="*"){t=i||l();if(r.tagName)r=Y(t,r);else{var d=[];$(r,function(e){d.push(Y(t,e))});r=d}t=0}if(r.tagName)p(r);else $(r,p);return f};n.update=function(){return $(i,function(e){e.update()})};n.Tag=M;if(typeof exports===s)module.exports=n;else if(typeof define==="function"&&define.amd)define(function(){return e.riot=n});else e.riot=n})(typeof window!="undefined"?window:void 0); diff --git a/public/lib/riotcontrol.js b/public/lib/riotcontrol.js new file mode 100644 index 0000000..405a505 --- /dev/null +++ b/public/lib/riotcontrol.js @@ -0,0 +1,17 @@ +var RiotControl = { + _stores: [], + addStore: function(store) { + this._stores.push(store); + } +}; + +['on','one','off','trigger'].forEach(function(api){ + RiotControl[api] = function() { + var args = [].slice.call(arguments); + this._stores.forEach(function(el){ + el[api].apply(null, args); + }); + }; +}); + +if (typeof(module) !== 'undefined') module.exports = RiotControl; diff --git a/public/scripts/main.js b/public/scripts/main.js new file mode 100644 index 0000000..4c591b7 --- /dev/null +++ b/public/scripts/main.js @@ -0,0 +1,5 @@ +/** + * Created by Tim on 1/14/2016. + */ +"use strict"; +riot.mount('layout'); \ No newline at end of file diff --git a/public/styles/layout.css b/public/styles/layout.css new file mode 100644 index 0000000..84c978f --- /dev/null +++ b/public/styles/layout.css @@ -0,0 +1,3 @@ + + +/*# sourceMappingURL=layout.css.map */ diff --git a/public/styles/layout.scss b/public/styles/layout.scss new file mode 100644 index 0000000..e7b71e1 --- /dev/null +++ b/public/styles/layout.scss @@ -0,0 +1,3 @@ +body{ + +} \ No newline at end of file diff --git a/routes/routes.js b/routes/routes.js new file mode 100644 index 0000000..8283c81 --- /dev/null +++ b/routes/routes.js @@ -0,0 +1,10 @@ +var modTimes = require("./times"); + +var routes = (function () { + function routes() { + this.times = new modTimes(); + } + return routes; +})(); + +module.exports = routes; diff --git a/routes/times.js b/routes/times.js new file mode 100644 index 0000000..aa049c7 --- /dev/null +++ b/routes/times.js @@ -0,0 +1,257 @@ +"use strict"; +var dbMod = require("../db3") + , db = new dbMod() + , ObjectId = require('mongodb').ObjectID + , times_model = require("../models/time") + , validate = require("validate.js") + , Q = require('q'); + +var timesRoute = (function () { + function timesRoute() { + + + + let validation_constraints = { + creditCardNumber: { + presence: true, + format: { + pattern: /^(34|37|4|5[1-5]).*$/, + message: function(value, attribute, validatorOptions, attributes, globalOptions) { + return validate.format("^%{num} is not a valid credit card number", { + num: value + }); + } + }, + length: function(value, attributes, attributeName, options, constraints) { + if (value) { + // Amex + if ((/^(34|37).*$/).test(value)) return {is: 15}; + // Visa, Mastercard + if ((/^(4|5[1-5]).*$/).test(value)) return {is: 16}; + } + // Unknown card, don't validate length + return false; + } + }, + creditCardZip: function(value, attributes, attributeName, options, constraints) { + if (!(/^(34|37).*$/).test(attributes.creditCardNumber)) return null; + return { + presence: {message: "is required when using AMEX"}, + length: {is: 5} + }; + } + } + + + + + let equal = ( x, y ) => { + if ( x === y ) return true; + // if both x and y are null or undefined and exactly the same + + if ( ! ( x instanceof Object ) || ! ( y instanceof Object ) ) return false; + // if they are not strictly equal, they both need to be Objects + + if ( x.constructor !== y.constructor ) return false; + // they must have the exact same prototype chain, the closest we can do is + // test there constructor. + + for ( var p in x ) { + if ( ! x.hasOwnProperty( p ) ) continue; + // other properties were tested using x.constructor === y.constructor + + if ( ! y.hasOwnProperty( p ) ) return false; + // allows to compare x[ p ] and y[ p ] when set to undefined + + if ( x[ p ] === y[ p ] ) continue; + // if they have the same strict value or identity then they are equal + + if ( typeof( x[ p ] ) !== "object" ) return false; + // Numbers, Strings, Functions, Booleans must be strictly equal + + if ( ! Object.equals( x[ p ], y[ p ] ) ) return false; + // Objects and Arrays must be tested recursively + } + + for ( p in y ) { + if ( y.hasOwnProperty( p ) && ! x.hasOwnProperty( p ) ) return false; + // allows x[ p ] to be set to undefined + } + return true; + } + this.checkTime = function (time) { + //validate times + let message, time_start = parseInt(time.time_start), time_end = parseInt(time.time_end); + console.log(time_start); + console.log(time_end); + console.log(time); + function getTime(query) { + return qGetTime(query).then(function (times) { + //console.log(time) + //console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') + console.log(times); + if (times.data.length) { + console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') + //console.log(time); + if(times.data.length === 1 && times.data[0]._id.toString() === time._id){ + times.data[0]._id = times.data[0]._id.toString(); + // got the current record + // check if current record is the same + console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') + console.log(time); + console.log(times.data[0]); + var time_test = new times_model.time(times.data[0].value_start, times.data[0].value_end, times.data[0].day, + times.data[0].time_start, times.data[0].time_end, times.data[0].is_24, times.data[0].owner_id, + times.data[0].deleted, times.data[0]._id); + //time_test = times.data[0]; + if(equal(time, time_test)){ + return {error: 'Unable to Create/Update: the time slot has not been changed'}; + }else{ + return true; + } + }else{ + return {error: 'Unable to Create/Update: there is at least one overlapping time slot'}; + } + //return 'Unable to Create/Update: there is at least one overlapping time slot'; + } else { + return true; + } + }); + } + if(!time.is_24){ + if (time_start >= time_end) { + message = 'Unable to Create/Update: The start time must be before the end time. ' + } + if (time_start < 0 || time_start > 61) { + message += 'Unable to Create/Update: time slot, start time does not match the expected format. ' + } + if (time_end < 0 || time_end > 61) { + console.log('test') + message += 'Unable to Create/Update: time slot, end time does not match the expected format. ' + } + if (message) { + return {error: message} + } + } + + try { + var qGetTime = Q.nbind(db.process_query, db); + + var query = { + object: { + owner_id: time.owner_id, deleted: {$ne: true}//,_id: {$ne: ObjectId(time._id)} + , $or: [{value_start: {$lt: time.value_end, $gt: time.value_start}}, {value_end: {$gt: time.value_end, $lt: time.value_start}} + , {_id: {$eq: ObjectId(time._id)}}] + }, + verb: 'get', + collection: 'times' + }; + //console.log(time.value_start) + //console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') + //console.log(query.object) + return getTime(query); + } catch (e) { + //console.log("test2"); + return ({error: e.message}); + } + + }; + + + this.update_create = function *(time, verb) { + //console.log('asdfasdf'); + const myTime = new times_model.time(time.value_start, time.value_end, time.day, time.time_start, time.time_end, time.is_24, time.owner_id, time.deleted, time._id), + isTimeOk = yield this.checkTime(myTime), + qTimeUpdate = Q.nbind(db.process_query, db), + query = { + collection: 'times', + verb: verb, + object: myTime + }; + //console.log(query); + function timesUpdate(query) { + return qTimeUpdate(query).then(function (result) { + //console.log('inside q promise') + return ({message: "Time updated/created successful."}); + }); + } + + ////console.log(myTime); + if (isTimeOk != true) { + //console.log(isTimeOk); + return ({error: isTimeOk}); + } + + return timesUpdate(query); + }; + this.get = function (query_object) { + function getTime(query) { + return qGetTime(query).then(function (times) { + //console.log('inside promise') + //console.log(times); + return {times: times.data}; + }); + } + + try { + var qGetTime = Q.nbind(db.process_query, db); + var query = { + object: query_object, + verb: 'get', + collection: 'times' + }; + return getTime(query); + } catch (e) { + //console.log("test2"); + return ({error: e.message}); + } + }; + this.delete = function (query_object) { + function getTime(query) { + return qGetTime(query).then(function (times) { + //console.log('inside promise') + //console.log(times); + return {times: times.data}; + }); + } + + try { + var qGetTime = Q.nbind(db.process_query, db); + var query = { + object: query_object, + verb: 'get', + collection: 'times' + }; + return getTime(query); + } catch (e) { + //console.log("test2"); + return ({error: e.message}); + } + }; + //this.get_by_owner_or_id = function (koaThis, is_owner) { + // try { + // var qGetTime = Q.nbind(db.process_db_query, db); + // var query = { + // object: is_owner ? { owner_id: koaThis.request.query._id, deleted: { $ne: false } } : { _id: koaThis.request.query._id, deleted: { $ne: false } }, + // verb: 'get', + // collection: 'times' + // }; + // function getTime(query) { + // return qGetTime(query).then(function (times) { + // //console.log(times); + // return { times: times }; + // }); + // } + // return getTime(query); + // } catch (e) { + // //console.log("test2"); + // return ({ error: e.message }); + // } + //}; + + } + + return timesRoute; +})(); + +module.exports = timesRoute; diff --git a/server.js b/server.js new file mode 100644 index 0000000..ebc4a55 --- /dev/null +++ b/server.js @@ -0,0 +1,88 @@ + +"use strict"; +let send = require('koa-send'), + app = require('koa')(), + path = require('path'), + routesMod = require("./routes/routes"), + routes = new routesMod(), + //json = require('koa-json'), + router = require('koa-router')(), + parse = require('co-body'), + appPath = path.dirname(require.main.filename).replace(/\\/g,"/").replace('C', 'c') + '/public'; + + + +router + .get('/index', function *(next) { + //console.log(this.path); + yield send(this, '/index.html', { root: appPath, maxage: 10 * 24 * 60 * 60 }); + }) + .get('/times/:time_id', function *(next) { + //console.log('asdf'); + var response = yield routes.times.get({ _id: this.params.time_id, deleted: { $ne: false } }); + if(response.error){ + this.body = response.error; + }else{ + this.body = response; + } + }) + .get('/owners/:owner_id/times/', function *(next) { + //console.log('asdf'); + var response = yield routes.times.get({ owner_id: this.params.owner_id, deleted: { $ne: true } }); + //console.log('asdf'); + //console.log(response); + if(response.error){ + this.body = response.error; + }else{ + this.body = response; + } + }) + .post('/owners/:owner_id/times', function *(next) { + var time = yield parse.json(this, { limit: '1kb' }); + time.owner_id = this.params.owner_id; + //console.log(time); + var response = yield routes.times.update_create(time, 'post'); + //console.log('everything is good'); + if(response.error){ + this.body = response.error; + }else{ + this.body = response; + } + }) + .put('/times/:time_id', function *(next) { + var time = yield parse.json(this, { limit: '1kb' }); + //console.log(time); + var response = yield routes.times.update_create(time, 'put'); + //console.log('everything is good'); + if(response.error){ + this.body = response.error; + }else{ + this.body = response; + } + }) + .del('/times/:time_id', function *(next) { + var time = yield parse.json(this, { limit: '1kb' }); + time.deleted = true; + //console.log(time); + var response = yield routes.times.update_create(time, 'put'); + //console.log('everything is good'); + if(response.error){ + this.body = response.error; + }else{ + this.body = response; + } + }) + .redirect('/', 'index'); + +app + .use(router.routes()) + .use(router.allowedMethods()); +app.use(function *(){ + //console.log(this.path); + //console.log('I went here?????????????????????????????????'); + //yield send(this, this.path, { root: __dirname + '/public' });//this should be fixed later, try to reinstall later + yield send(this, this.path, { root: appPath, maxage: 10 * 24 * 60 * 60 }); +}) + +app.listen(4567); +//console.log('listening on port 8080'); From 250493b12bb9b1dea4ecbee94d8077490fb44681 Mon Sep 17 00:00:00 2001 From: "Tim.willis" Date: Fri, 15 Jan 2016 20:48:57 -0500 Subject: [PATCH 2/3] Add in server validation and fix mongo query. --- public/components_riot/time_form/time_form.js | 4 +- .../components_riot/time_form/time_form.tag | 4 +- .../times_added/times_added.js | 4 +- .../times_added/times_added.tag | 4 +- routes/times.js | 185 ++++++++++++------ 5 files changed, 131 insertions(+), 70 deletions(-) diff --git a/public/components_riot/time_form/time_form.js b/public/components_riot/time_form/time_form.js index c800ec5..fe04942 100644 --- a/public/components_riot/time_form/time_form.js +++ b/public/components_riot/time_form/time_form.js @@ -45,8 +45,8 @@ this.checked_changed = function (event) { _this.update(); }; this.delete_time = function (event) { - _this.opts.delete_callback({ time_start: time_start.selectedIndex != -1 ? time_start.options[time_start.selectedIndex].value : 0, - time_end: time_end.selectedIndex != -1 ? time_end.options[time_end.selectedIndex].value : 0, + _this.opts.delete_callback({ time_start: time_start.selectedIndex != -1 ? time_start.options[time_start.selectedIndex].value : 1, + time_end: time_end.selectedIndex != -1 ? time_end.options[time_end.selectedIndex].value : 1, day: _this.opts.day, is_24: _this.is_24, _id: _this.opts._id }); diff --git a/public/components_riot/time_form/time_form.tag b/public/components_riot/time_form/time_form.tag index c5c5686..9f90bdc 100644 --- a/public/components_riot/time_form/time_form.tag +++ b/public/components_riot/time_form/time_form.tag @@ -190,8 +190,8 @@ this.update(); } this.delete_time = (event) =>{ - this.opts.delete_callback({time_start: time_start.selectedIndex != -1 ? time_start.options[time_start.selectedIndex].value : 0 - , time_end: time_end.selectedIndex != -1 ? time_end.options[time_end.selectedIndex].value : 0 + this.opts.delete_callback({time_start: time_start.selectedIndex != -1 ? time_start.options[time_start.selectedIndex].value : 1 + , time_end: time_end.selectedIndex != -1 ? time_end.options[time_end.selectedIndex].value : 1 , day: this.opts.day , is_24: this.is_24 , _id: this.opts._id}); diff --git a/public/components_riot/times_added/times_added.js b/public/components_riot/times_added/times_added.js index f6ed1c2..ffcb2a6 100644 --- a/public/components_riot/times_added/times_added.js +++ b/public/components_riot/times_added/times_added.js @@ -73,8 +73,8 @@ this.time_added_24 = function (event) { xmlHttp.onreadystatechange = _this.process_response; xmlHttp.open("POST", "/owners/" + owner_id + "/times/"); xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); - xmlHttp.send(JSON.stringify({ time_start: null, - time_end: null, + xmlHttp.send(JSON.stringify({ time_start: 1, + time_end: 1, day: day, is_24: true, value_start: value, diff --git a/public/components_riot/times_added/times_added.tag b/public/components_riot/times_added/times_added.tag index 34e7a95..2142eeb 100644 --- a/public/components_riot/times_added/times_added.tag +++ b/public/components_riot/times_added/times_added.tag @@ -184,8 +184,8 @@ xmlHttp.onreadystatechange = this.process_response xmlHttp.open("POST", "/owners/" + owner_id + "/times/"); xmlHttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); - xmlHttp.send(JSON.stringify({time_start: null - , time_end: null + xmlHttp.send(JSON.stringify({time_start: 1 + , time_end: 1 , day: day , is_24: true , value_start: value diff --git a/routes/times.js b/routes/times.js index aa049c7..9795606 100644 --- a/routes/times.js +++ b/routes/times.js @@ -10,71 +10,113 @@ var timesRoute = (function () { function timesRoute() { - + //(value_start, value_end, day, time_start, time_end, is_24, owner_id, deleted, _id) let validation_constraints = { - creditCardNumber: { - presence: true, - format: { - pattern: /^(34|37|4|5[1-5]).*$/, - message: function(value, attribute, validatorOptions, attributes, globalOptions) { - return validate.format("^%{num} is not a valid credit card number", { - num: value - }); - } - }, - length: function(value, attributes, attributeName, options, constraints) { - if (value) { - // Amex - if ((/^(34|37).*$/).test(value)) return {is: 15}; - // Visa, Mastercard - if ((/^(4|5[1-5]).*$/).test(value)) return {is: 16}; - } - // Unknown card, don't validate length - return false; + + value_start: { + numericality: { + onlyInteger: true, + greaterThan: 0, + lessThanOrEqualTo: 288, + //even: true, + message: "Unable to Create/Update: time slot, end value does not match the expected format." } - }, - creditCardZip: function(value, attributes, attributeName, options, constraints) { - if (!(/^(34|37).*$/).test(attributes.creditCardNumber)) return null; - return { - presence: {message: "is required when using AMEX"}, - length: {is: 5} - }; } - } - - + , value_end: { + numericality: { + onlyInteger: true, + greaterThan: 0, + lessThanOrEqualTo: 349, + //even: true, + message: "Unable to Create/Update: time slot, start value does not match the expected format." + } + } + , time_start: { + numericality: { + greaterThan: 0, + lessThanOrEqualTo: 61, + //even: true, + message: "Unable to Create/Update: time slot, start time does not match the expected format." + } + } + , time_end: { + numericality: { + //onlyInteger: true, + greaterThan: 0, + lessThanOrEqualTo: 61, + //even: true, + message: "Unable to Create/Update: time slot, end time does not match the expected format." + } + } + , day: { + numericality: { + //onlyInteger: true, + greaterThan: 0, + lessThanOrEqualTo: 7, + //even: true, + message: "Unable to Create/Update: time slot, day does not match the expected format." + } + } + , is_24: { + inclusion: { + within: [true, false], + message: "Unable to Create/Update: time slot, is_24 does not match the expected format." + } + } + , owner_id: { + numericality: { + //onlyInteger: true, + greaterThan: 0, + lessThanOrEqualTo: 1000000, + //even: true, + message: "Unable to Create/Update: time slot, owner_id does not match the expected format." + } + } + , deleted: { + inclusion: { + within: [true, false, null], + message: "Unable to Create/Update: time slot, deleted does not match the expected format." + } + } + , _id: { + length: { + maximum: 100, + message: "Unable to Create/Update: time slot, message does not match the expected format." + } + } + }; - let equal = ( x, y ) => { - if ( x === y ) return true; + let equal = (x, y) => { + if (x === y) return true; // if both x and y are null or undefined and exactly the same - if ( ! ( x instanceof Object ) || ! ( y instanceof Object ) ) return false; + if (!( x instanceof Object ) || !( y instanceof Object )) return false; // if they are not strictly equal, they both need to be Objects - if ( x.constructor !== y.constructor ) return false; + if (x.constructor !== y.constructor) return false; // they must have the exact same prototype chain, the closest we can do is // test there constructor. - for ( var p in x ) { - if ( ! x.hasOwnProperty( p ) ) continue; + for (var p in x) { + if (!x.hasOwnProperty(p)) continue; // other properties were tested using x.constructor === y.constructor - if ( ! y.hasOwnProperty( p ) ) return false; + if (!y.hasOwnProperty(p)) return false; // allows to compare x[ p ] and y[ p ] when set to undefined - if ( x[ p ] === y[ p ] ) continue; + if (x[p] === y[p]) continue; // if they have the same strict value or identity then they are equal - if ( typeof( x[ p ] ) !== "object" ) return false; + if (typeof( x[p] ) !== "object") return false; // Numbers, Strings, Functions, Booleans must be strictly equal - if ( ! Object.equals( x[ p ], y[ p ] ) ) return false; + if (!Object.equals(x[p], y[p])) return false; // Objects and Arrays must be tested recursively } - for ( p in y ) { - if ( y.hasOwnProperty( p ) && ! x.hasOwnProperty( p ) ) return false; + for (p in y) { + if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) return false; // allows x[ p ] to be set to undefined } return true; @@ -88,28 +130,28 @@ var timesRoute = (function () { function getTime(query) { return qGetTime(query).then(function (times) { //console.log(time) - //console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') + console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') console.log(times); if (times.data.length) { console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') //console.log(time); - if(times.data.length === 1 && times.data[0]._id.toString() === time._id){ + if (times.data.length === 1 && times.data[0]._id.toString() === time._id) { times.data[0]._id = times.data[0]._id.toString(); // got the current record // check if current record is the same console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') - console.log(time); + //console.log(time); console.log(times.data[0]); var time_test = new times_model.time(times.data[0].value_start, times.data[0].value_end, times.data[0].day, times.data[0].time_start, times.data[0].time_end, times.data[0].is_24, times.data[0].owner_id, times.data[0].deleted, times.data[0]._id); //time_test = times.data[0]; - if(equal(time, time_test)){ + if (equal(time, time_test)) { return {error: 'Unable to Create/Update: the time slot has not been changed'}; - }else{ + } else { return true; } - }else{ + } else { return {error: 'Unable to Create/Update: there is at least one overlapping time slot'}; } //return 'Unable to Create/Update: there is at least one overlapping time slot'; @@ -118,29 +160,49 @@ var timesRoute = (function () { } }); } - if(!time.is_24){ + message = validate(time, validation_constraints); + + if (!time.is_24) { if (time_start >= time_end) { - message = 'Unable to Create/Update: The start time must be before the end time. ' - } - if (time_start < 0 || time_start > 61) { - message += 'Unable to Create/Update: time slot, start time does not match the expected format. ' - } - if (time_end < 0 || time_end > 61) { - console.log('test') - message += 'Unable to Create/Update: time slot, end time does not match the expected format. ' - } - if (message) { - return {error: message} + message += 'Unable to Create/Update: The start time must be before the end time. ' } + //if (time_start < 0 || time_start > 61) { + // message += 'Unable to Create/Update: time slot, start time does not match the expected format. ' + //} + //if (time_end < 0 || time_end > 61) { + // console.log('test') + // message += 'Unable to Create/Update: time slot, end time does not match the expected format. ' + //} + } + if (message) { + console.log(message); + return {error: message} } try { var qGetTime = Q.nbind(db.process_query, db); + var query2 = { + object: { + owner_id: time.owner_id, deleted: {$ne: true}//,_id: {$ne: ObjectId(time._id)} + //, $or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}} + , $or: [{$or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}}]} + , {$and: [{value_start: {$lte: time.value_start}}, {value_end: {$gte: time.value_start}}]} + //, $or: [{$and: [{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]} + // ,{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]}]} + , {_id: {$eq: ObjectId(time._id)}}] + }, + verb: 'get', + collection: 'times' + }; var query = { object: { owner_id: time.owner_id, deleted: {$ne: true}//,_id: {$ne: ObjectId(time._id)} - , $or: [{value_start: {$lt: time.value_end, $gt: time.value_start}}, {value_end: {$gt: time.value_end, $lt: time.value_start}} + //, $or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}} + , $or: [{$or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}}]} + , {$and: [{value_start: {$lte: time.value_start}}, {value_end: {$gt: time.value_start}}]} + //, $or: [{$and: [{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]} + // ,{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]}]} , {_id: {$eq: ObjectId(time._id)}}] }, verb: 'get', @@ -159,7 +221,6 @@ var timesRoute = (function () { this.update_create = function *(time, verb) { - //console.log('asdfasdf'); const myTime = new times_model.time(time.value_start, time.value_end, time.day, time.time_start, time.time_end, time.is_24, time.owner_id, time.deleted, time._id), isTimeOk = yield this.checkTime(myTime), qTimeUpdate = Q.nbind(db.process_query, db), From 1d245d634f81d09cb078c3bf2e353cfb6f96b711 Mon Sep 17 00:00:00 2001 From: "Tim.willis" Date: Fri, 15 Jan 2016 21:37:23 -0500 Subject: [PATCH 3/3] Final(I think) commit with notes.txt. --- db3.js | 19 +-------------- notes.txt | 9 ++++++- package.json | 12 +++++++++- routes/times.js | 62 ++----------------------------------------------- server.js | 20 +--------------- 5 files changed, 23 insertions(+), 99 deletions(-) diff --git a/db3.js b/db3.js index 106879c..3fec2aa 100644 --- a/db3.js +++ b/db3.js @@ -1,8 +1,5 @@ "use strict"; -//var mongodb = require('mongodb'), ObjectId = require('mongodb').ObjectID, server = new mongodb.Server('localhost', 27017, {auto_reconnect: true}), -// db = new mongodb.Db('gstv', server, {wtimeout: 2000}); - var MongoClient = require('mongodb').MongoClient; var ObjectId = require('mongodb').ObjectID; var assert = require('assert'); @@ -10,13 +7,10 @@ var url = 'mongodb://localhost:27017/gstv'; var db; MongoClient.connect(url, function(err, my_db) { assert.equal(null, err); - //console.log("Connected correctly to server."); - //db.close(); db = my_db; }); var db_module = (function() { - //var query = JSON.parse(query_string); function db_module() { this.process_query = function(query, callback) { db.collection(query.collection, function (error, objects) { @@ -33,41 +27,30 @@ var db_module = (function() { if (query.verb == "post") { objects.save(query.object, {safe: true}, function (error, result) { if (error) { - //console.log(error); + console.log(error); } - ////console.log("result"); - ////console.log(result); var data = result, response = {data: data}; - //observer.onNext(response); callback(null, response); }); } else if (query.verb == "get") { - //console.log(query.verb); objects.find(query.object, function (error, result) { if (error) { console.error(error); return; } result.toArray(function (error, results) { - //console.log(results); var data = results, response = {data: data}; - //return response; - //callback.resolve({ times: response }); callback(null, response); }); }); } else if (query.verb == "put") { - //console.log(query.verb); objects.save(query.object, {safe: true}, function (error, result) { if (error) { console.error(error); } - ////console.log("result"); - ////console.log(result); var data = result, response = {data: data}; - //return response; callback(null, response); }); } diff --git a/notes.txt b/notes.txt index 96f7900..35f9650 100644 --- a/notes.txt +++ b/notes.txt @@ -1,4 +1,11 @@ - +Notes: + +This took me a bit longer than I expected. I had not used Mongodb since discovering firebase(really awesome, check it out) over a year ago +and had to update mongodb, how I connected to it and my node version as well. The last time I was using mongodb was with socket io and redis +trying to make something similar to firebase, I had it mostly working but shortly after found firebase. If you wish I can walk you through that +project as well. I tried to stay focused on the backend, but the frontend needed a lot of functionality. Some is copy and paste from previous projects +so not all is es6 perfect. Obviously there is a lot that could be done, optimizations, unit testing, better ui, bring in mongoose, etc, but I hope +this demonstrates some of my abilities. Everything is working on my end, so please let me know if you have any issues. cd C:\Users\Tim\websitesWorking\GSTV\node-coding-exercise diff --git a/package.json b/package.json index 74d77ee..f9054f9 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,15 @@ "bugs": { "url": "https://github.com/GasStationTV/node-coding-exercise/issues" }, - "homepage": "https://github.com/GasStationTV/node-coding-exercise#readme" + "homepage": "https://github.com/GasStationTV/node-coding-exercise#readme", + "dependencies": { + "assert": "^1.3.0", + "co-body": "^4.0.0", + "koa": "^1.1.2", + "koa-router": "^5.3.0", + "koa-send": "^3.1.0", + "mongod": "^1.3.0", + "path": "^0.12.7", + "validate.js": "^0.9.0" + } } diff --git a/routes/times.js b/routes/times.js index 9795606..ce2f74a 100644 --- a/routes/times.js +++ b/routes/times.js @@ -9,8 +9,6 @@ var dbMod = require("../db3") var timesRoute = (function () { function timesRoute() { - - //(value_start, value_end, day, time_start, time_end, is_24, owner_id, deleted, _id) let validation_constraints = { value_start: { @@ -129,23 +127,15 @@ var timesRoute = (function () { console.log(time); function getTime(query) { return qGetTime(query).then(function (times) { - //console.log(time) - console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') - console.log(times); if (times.data.length) { - console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') - //console.log(time); if (times.data.length === 1 && times.data[0]._id.toString() === time._id) { times.data[0]._id = times.data[0]._id.toString(); // got the current record // check if current record is the same - console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') - //console.log(time); console.log(times.data[0]); var time_test = new times_model.time(times.data[0].value_start, times.data[0].value_end, times.data[0].day, times.data[0].time_start, times.data[0].time_end, times.data[0].is_24, times.data[0].owner_id, times.data[0].deleted, times.data[0]._id); - //time_test = times.data[0]; if (equal(time, time_test)) { return {error: 'Unable to Create/Update: the time slot has not been changed'}; } else { @@ -154,7 +144,6 @@ var timesRoute = (function () { } else { return {error: 'Unable to Create/Update: there is at least one overlapping time slot'}; } - //return 'Unable to Create/Update: there is at least one overlapping time slot'; } else { return true; } @@ -166,13 +155,6 @@ var timesRoute = (function () { if (time_start >= time_end) { message += 'Unable to Create/Update: The start time must be before the end time. ' } - //if (time_start < 0 || time_start > 61) { - // message += 'Unable to Create/Update: time slot, start time does not match the expected format. ' - //} - //if (time_end < 0 || time_end > 61) { - // console.log('test') - // message += 'Unable to Create/Update: time slot, end time does not match the expected format. ' - //} } if (message) { console.log(message); @@ -184,12 +166,9 @@ var timesRoute = (function () { var query2 = { object: { - owner_id: time.owner_id, deleted: {$ne: true}//,_id: {$ne: ObjectId(time._id)} - //, $or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}} + owner_id: time.owner_id, deleted: {$ne: true} , $or: [{$or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}}]} , {$and: [{value_start: {$lte: time.value_start}}, {value_end: {$gte: time.value_start}}]} - //, $or: [{$and: [{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]} - // ,{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]}]} , {_id: {$eq: ObjectId(time._id)}}] }, verb: 'get', @@ -197,23 +176,16 @@ var timesRoute = (function () { }; var query = { object: { - owner_id: time.owner_id, deleted: {$ne: true}//,_id: {$ne: ObjectId(time._id)} - //, $or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}} + owner_id: time.owner_id, deleted: {$ne: true} , $or: [{$or: [{value_start: {$gte: time.value_start, $lt: time.value_end }}, {value_end: {$gt: time.value_start, $lte: time.value_end}}]} , {$and: [{value_start: {$lte: time.value_start}}, {value_end: {$gt: time.value_start}}]} - //, $or: [{$and: [{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]} - // ,{$or: [{value_start: {$lt: time.value_end}}, {value_start: {$lt: time.value_start}}]}]} , {_id: {$eq: ObjectId(time._id)}}] }, verb: 'get', collection: 'times' }; - //console.log(time.value_start) - //console.log('aaaaaaaaaaaaaaaaaaaaaa-----check----------aaaaaaaaaaaaa') - //console.log(query.object) return getTime(query); } catch (e) { - //console.log("test2"); return ({error: e.message}); } @@ -229,17 +201,13 @@ var timesRoute = (function () { verb: verb, object: myTime }; - //console.log(query); function timesUpdate(query) { return qTimeUpdate(query).then(function (result) { - //console.log('inside q promise') return ({message: "Time updated/created successful."}); }); } - ////console.log(myTime); if (isTimeOk != true) { - //console.log(isTimeOk); return ({error: isTimeOk}); } @@ -248,8 +216,6 @@ var timesRoute = (function () { this.get = function (query_object) { function getTime(query) { return qGetTime(query).then(function (times) { - //console.log('inside promise') - //console.log(times); return {times: times.data}; }); } @@ -263,15 +229,12 @@ var timesRoute = (function () { }; return getTime(query); } catch (e) { - //console.log("test2"); return ({error: e.message}); } }; this.delete = function (query_object) { function getTime(query) { return qGetTime(query).then(function (times) { - //console.log('inside promise') - //console.log(times); return {times: times.data}; }); } @@ -285,30 +248,9 @@ var timesRoute = (function () { }; return getTime(query); } catch (e) { - //console.log("test2"); return ({error: e.message}); } }; - //this.get_by_owner_or_id = function (koaThis, is_owner) { - // try { - // var qGetTime = Q.nbind(db.process_db_query, db); - // var query = { - // object: is_owner ? { owner_id: koaThis.request.query._id, deleted: { $ne: false } } : { _id: koaThis.request.query._id, deleted: { $ne: false } }, - // verb: 'get', - // collection: 'times' - // }; - // function getTime(query) { - // return qGetTime(query).then(function (times) { - // //console.log(times); - // return { times: times }; - // }); - // } - // return getTime(query); - // } catch (e) { - // //console.log("test2"); - // return ({ error: e.message }); - // } - //}; } diff --git a/server.js b/server.js index ebc4a55..a8d2373 100644 --- a/server.js +++ b/server.js @@ -1,24 +1,18 @@ - "use strict"; let send = require('koa-send'), app = require('koa')(), path = require('path'), routesMod = require("./routes/routes"), routes = new routesMod(), - //json = require('koa-json'), router = require('koa-router')(), parse = require('co-body'), appPath = path.dirname(require.main.filename).replace(/\\/g,"/").replace('C', 'c') + '/public'; - - router .get('/index', function *(next) { - //console.log(this.path); yield send(this, '/index.html', { root: appPath, maxage: 10 * 24 * 60 * 60 }); }) .get('/times/:time_id', function *(next) { - //console.log('asdf'); var response = yield routes.times.get({ _id: this.params.time_id, deleted: { $ne: false } }); if(response.error){ this.body = response.error; @@ -27,10 +21,7 @@ router } }) .get('/owners/:owner_id/times/', function *(next) { - //console.log('asdf'); var response = yield routes.times.get({ owner_id: this.params.owner_id, deleted: { $ne: true } }); - //console.log('asdf'); - //console.log(response); if(response.error){ this.body = response.error; }else{ @@ -40,9 +31,7 @@ router .post('/owners/:owner_id/times', function *(next) { var time = yield parse.json(this, { limit: '1kb' }); time.owner_id = this.params.owner_id; - //console.log(time); var response = yield routes.times.update_create(time, 'post'); - //console.log('everything is good'); if(response.error){ this.body = response.error; }else{ @@ -51,9 +40,7 @@ router }) .put('/times/:time_id', function *(next) { var time = yield parse.json(this, { limit: '1kb' }); - //console.log(time); var response = yield routes.times.update_create(time, 'put'); - //console.log('everything is good'); if(response.error){ this.body = response.error; }else{ @@ -63,9 +50,7 @@ router .del('/times/:time_id', function *(next) { var time = yield parse.json(this, { limit: '1kb' }); time.deleted = true; - //console.log(time); var response = yield routes.times.update_create(time, 'put'); - //console.log('everything is good'); if(response.error){ this.body = response.error; }else{ @@ -78,11 +63,8 @@ app .use(router.routes()) .use(router.allowedMethods()); app.use(function *(){ - //console.log(this.path); - //console.log('I went here?????????????????????????????????'); - //yield send(this, this.path, { root: __dirname + '/public' });//this should be fixed later, try to reinstall later yield send(this, this.path, { root: appPath, maxage: 10 * 24 * 60 * 60 }); }) app.listen(4567); -//console.log('listening on port 8080'); +console.log('listening on port 4567');