From 101fd385236ef30906afead1bcaa818bd9b55e0f Mon Sep 17 00:00:00 2001 From: Candid Dauth Date: Thu, 19 Jun 2014 02:37:30 +0200 Subject: [PATCH] Added function to copy pad --- frontend/js/ng.js | 15 ++++ frontend/js/pad.js | 11 +++ frontend/pad.css | 4 + frontend/pad.html | 20 ++++- server/lib/database.js | 125 ++++++++++++++++++++++----- server/lib/databaseBackendMongodb.js | 34 +++++++- server/lib/server.js | 4 + 7 files changed, 187 insertions(+), 26 deletions(-) diff --git a/frontend/js/ng.js b/frontend/js/ng.js index c9f909e2..ffbe028e 100644 --- a/frontend/js/ng.js +++ b/frontend/js/ng.js @@ -171,6 +171,7 @@ $scope.layers = fp.getLayerInfo(); $scope.colours = fp.COLOURS; $scope.readonly = null; + $scope.copyPadId = fp.generateRandomPadId(); socket.emit("setPadId", FacilPad.padId); @@ -494,6 +495,20 @@ }); }; + $scope.copyPad = function() { + socket.emit("copyPad", { toId: $scope.copyPadId }, function(err) { + if(err) { + $scope.dialogError = err; + return; + } + + $scope.closeDialog(); + var url = $scope.urlPrefix + $scope.copyPadId; + $scope.showMessage("success", "The pad has been copied to", [ { label: url, url: url } ]); + $scope.copyPadId = fp.generateRandomPadId(); + }); + }; + $scope.openDialog = function(id) { var el = $("#"+id); diff --git a/frontend/js/pad.js b/frontend/js/pad.js index 00642ebe..fc1a20dd 100644 --- a/frontend/js/pad.js +++ b/frontend/js/pad.js @@ -367,6 +367,17 @@ var FacilPad = { } }; + var LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + var LENGTH = 12; + + fp.generateRandomPadId = function() { + var randomPadId = ""; + for(var i=0; i -
  • Pad settings
  • +
  • Tools
  • {{message.message}} -  {{button.label}} +  {{button.label}} ×

    @@ -172,6 +175,19 @@ +
    +
    +

    {{dialogError}}

    +
    +
    Copy to
    +
    {{urlPrefix}}
    +
    +
    + +
    +
    +
    + diff --git a/server/lib/database.js b/server/lib/database.js index f8acfd30..a7a1bbec 100644 --- a/server/lib/database.js +++ b/server/lib/database.js @@ -113,19 +113,13 @@ function createLine(padId, data, callback) { _calculateRouting(data, function(err, actualPoints) { // Also sets data.distance and data.time if(err) return callback(err); - backend.createLine(padId, data, function(err, data) { + + _createLine(padId, data, function(err, data) { if(err) return callback(err); - backend.setLinePoints(data.id, actualPoints, function(err) { - if(err) - return callback(err); - - listeners.notifyPadListeners(data._pad, "line", data); - listeners.notifyPadListeners(data._pad, "linePoints", function(bboxWithZoom) { - return { reset: true, id: data.id, points : routing.prepareForBoundingBox(actualPoints, bboxWithZoom) }; - }); - callback(null, data); + _setLinePoints(padId, data.id, actualPoints, function(err) { + callback(err, data); }); }); }); @@ -147,27 +141,49 @@ function updateLine(lineId, data, callback) { _calculateRouting(data, next); // Also sets data.distance and data.time } ], updateLine : [ "calculateRouting", function(next) { - backend.updateLine(lineId, data, next); + _updateLine(lineId, data, next); } ], - setLinePoints : [ "calculateRouting", function(next, res) { + setLinePoints : [ "originalLine", "calculateRouting", function(next, res) { if(!res.calculateRouting) return next(); - backend.setLinePoints(lineId, res.calculateRouting, next); + _setLinePoints(res.originalLine._pad, lineId, res.calculateRouting, next); } ] }, function(err, res) { + callback(err, res.updateLine); + }); +} + +function _createLine(padId, data, callback) { + backend.createLine(padId, data, function(err, data) { if(err) return callback(err); - listeners.notifyPadListeners(res.updateLine._pad, "line", res.updateLine); + listeners.notifyPadListeners(data._pad, "line", data); + callback(null, data); + }); +} - if(res.calculateRouting) { - listeners.notifyPadListeners(res.updateLine._pad, "linePoints", function(bboxWithZoom) { - return { reset: true, id: data.id, points : routing.prepareForBoundingBox(res.calculateRouting, bboxWithZoom) }; - }); - } +function _updateLine(lineId, data, callback) { + backend.updateLine(lineId, data, function(err, data) { + if(err) + return callback(err); - callback(null, res.updateLine); + listeners.notifyPadListeners(data._pad, "line", data); + callback(null, data); + }); +} + +function _setLinePoints(padId, lineId, points, callback) { + backend.setLinePoints(lineId, points, function(err) { + if(err) + return callback(err); + + listeners.notifyPadListeners(padId, "linePoints", function(bboxWithZoom) { + return { reset: true, id: lineId, points : routing.prepareForBoundingBox(points, bboxWithZoom) }; + }); + + callback(null); }); } @@ -200,6 +216,72 @@ function getLinePoints(padId, bboxWithZoom) { }); } +function copyPad(fromPadId, toPadId, callback) { + function _handleStream(stream, next, cb) { + stream.on("data", function(data) { + stream.pause(); + cb(data, function() { + stream.resume(); + }); + }); + + stream.on("error", next); + stream.on("end", next); + } + + async.auto({ + fromPadData : function(next) { + backend.getPadData(fromPadId, next); + }, + toPadData : function(next) { + getPadData(toPadId, next); + }, + padsExist : [ "fromPadData", "toPadData", function(next, r) { + if(!r.fromPadData) + return next(new Error("Pad "+fromPadId+" does not exist.")); + if(!r.toPadData.writable) + return next(new Error("Destination pad is read-only.")); + + toPadId = r.toPadData.id; + + next(); + }], + copyMarkers : [ "padsExist", function(next) { + _handleStream(getPadMarkers(fromPadId, null), next, function(marker, cb) { + createMarker(toPadId, marker, cb); + }); + }], + copyLines : [ "padsExist", function(next) { + _handleStream(getPadLines(fromPadId), next, function(line, cb) { + async.auto({ + createLine : function(next) { + _createLine(toPadId, line, next); + }, + getLinePoints : function(next) { + backend.getLinePoints(line.id, next); + }, + setLinePoints : [ "createLine", "getLinePoints", function(next, r) { + _setLinePoints(toPadId, r.createLine.id, r.getLinePoints, next); + } ] + }, cb); + }); + }], + copyViews : [ "padsExist", function(next, r) { + _handleStream(getViews(fromPadId), next, function(view, cb) { + createView(toPadId, view, function(err, newView) { + if(err) + return cb(err); + + if(r.fromPadData.defaultView && r.fromPadData.defaultView.id == view.id && r.toPadData.defaultView == null) + updatePadData(toPadId, { defaultView: newView.id }, cb); + else + cb(); + }); + }); + }] + }, callback); +} + function _calculateRouting(line, callback) { if(line.points && line.points.length >= 2 && line.mode) { routing.calculateRouting(line.points, line.mode, function(err, routeData) { @@ -273,5 +355,6 @@ module.exports = { createLine : createLine, updateLine : updateLine, deleteLine : deleteLine, - getLinePoints : getLinePoints + getLinePoints : getLinePoints, + copyPad : copyPad }; \ No newline at end of file diff --git a/server/lib/databaseBackendMongodb.js b/server/lib/databaseBackendMongodb.js index 0c3e347b..2c590f83 100644 --- a/server/lib/databaseBackendMongodb.js +++ b/server/lib/databaseBackendMongodb.js @@ -144,7 +144,7 @@ function getLine(lineId, callback) { } function createLine(padId, data, callback) { - data._pad = padId; + data = utils.extend({ }, data, { _pad: padId }); Line.create(data, _fixIdCallback(callback)); } @@ -156,17 +156,21 @@ function deleteLine(lineId, callback) { Line.findByIdAndRemove(lineId, _fixIdCallback(callback)); } +function getLinePoints(lineId, callback) { + LinePoints.find({ _line: lineId }).sort("idx").exec(_linePointsCallback(callback)); +} + function getLinePointsByBbox(lineId, bboxWithZoom, callback) { var condition = { $and: [ _makeBboxCondition(bboxWithZoom), { "_line" : lineId, "zoom" : { $lte: bboxWithZoom.zoom } } ] }; - LinePoints.find(condition, "idx zoom", { sort: "idx" }).exec(callback); + LinePoints.find(condition, "idx zoom", { sort: "idx" }).exec(_linePointsCallback(callback)); } function getLinePointsByIdx(lineId, indexes, callback) { - LinePoints.find({ _line: lineId, idx: { $in: indexes } }).select("lon lat idx").sort("idx").exec(callback); + LinePoints.find({ _line: lineId, idx: { $in: indexes } }).select("lon lat idx").sort("idx").exec(_linePointsCallback(callback)); } function setLinePoints(lineId, points, callback) { @@ -199,6 +203,11 @@ function _fixId(data) { data.defaultView.id = data.defaultView._id; delete data.defaultView._id; } + + if(data.points) { + for(var i=0; i