Removing keywords from server and client
This commit is contained in:
parent
eece4dd876
commit
4f4713ec46
@ -18,10 +18,6 @@
|
||||
<div class="col-md-7">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-xs btn-danger" id="forget">Forget</button>
|
||||
<button class="btn btn-xs btn-default" id="learn">Learn</button>
|
||||
</div>
|
||||
<big>Visualizer</big>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
@ -37,10 +33,6 @@
|
||||
<big>Query</big>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="form-group">
|
||||
<label for="searchKeyword">Keyword <span class="label label-warning" id="customized" style="display: none;">Cutomized</span></label>
|
||||
<select id="searchKeyword" class="form-control"></select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="walkingDist">Walking distance (km)</label>
|
||||
<input class="form-control" type="number" step="0.1" min="0.1" value="1.0" id="walkingDist">
|
||||
|
@ -1,28 +1,23 @@
|
||||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Alex Yatskov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
* Copyright (c) 2015 Alex Yatskov <alex@foosoft.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
(function(hscd) {
|
||||
'use strict';
|
||||
@ -34,7 +29,6 @@
|
||||
$.getJSON('/search', _ctx.query, function(results) {
|
||||
saveSnapshot(results);
|
||||
outputSnapshot(results, true);
|
||||
setCustomized(true);
|
||||
});
|
||||
}
|
||||
|
||||
@ -60,84 +54,17 @@
|
||||
|
||||
$.getJSON('/get_parameters', function(parameters) {
|
||||
_ctx.parameters = parameters;
|
||||
for (var keyword in parameters.keywords) {
|
||||
$('#searchKeyword').append($('<option></option>', { value: keyword, text: keyword }));
|
||||
}
|
||||
|
||||
onSearch();
|
||||
|
||||
$('#searchKeyword').change(function() { onSearch(); });
|
||||
$('#minScore,#hintSteps,#walkingDist,#maxResults').change(function() { onSearch(getFeaturesGrapher); });
|
||||
$('#historyIndex').on('slideStop', onSelectSnapshot);
|
||||
$('#learn').click(onLearn);
|
||||
$('#forget').click(onForget);
|
||||
$('#customized').click(onReset);
|
||||
});
|
||||
}
|
||||
|
||||
function onReset() {
|
||||
if (confirm('Reset customizations?')) {
|
||||
onSearch();
|
||||
}
|
||||
}
|
||||
|
||||
function onLearn() {
|
||||
var keyword = prompt('Learn keyword as');
|
||||
if (keyword === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var query = {
|
||||
keyword: keyword,
|
||||
features: _ctx.query.features
|
||||
};
|
||||
|
||||
$.getJSON('/add_keyword', query, function(results) {
|
||||
if (results.success) {
|
||||
_ctx.parameters.keywords[keyword] = _.clone(query.features);
|
||||
$('#searchKeyword').append($('<option></option>', { value: keyword, text: keyword }));
|
||||
$('#searchKeyword').val(keyword);
|
||||
setCustomized(false);
|
||||
}
|
||||
else {
|
||||
alert('Failed to learn keyword');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onForget() {
|
||||
var keyword = $('#searchKeyword').val();
|
||||
if (!confirm('Are you sure you want to delete keyword "' + keyword + '"?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var query = {
|
||||
keyword: keyword
|
||||
};
|
||||
|
||||
$.getJSON('/remove_keyword', query, function(results) {
|
||||
if (results.success) {
|
||||
$('#searchKeyword option:selected').remove();
|
||||
onSearch();
|
||||
}
|
||||
else {
|
||||
alert('Failed to forget keyword');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getFeaturesKeyword() {
|
||||
var keyword = $('#searchKeyword').val();
|
||||
return _.clone(_ctx.parameters.keywords[keyword]);
|
||||
}
|
||||
|
||||
function getFeaturesGrapher() {
|
||||
return _.clone(_ctx.query.features);
|
||||
}
|
||||
|
||||
function onSearch(provider) {
|
||||
_ctx.query = {
|
||||
features: (provider || getFeaturesKeyword)(),
|
||||
features: _clone(_ctx.query.features),
|
||||
range: { min: -1.0, max: 1.0 },
|
||||
walkingDist: parseFloat($('#walkingDist').val()),
|
||||
minScore: parseFloat($('#minScore').val()),
|
||||
@ -185,14 +112,12 @@
|
||||
$.getJSON('/search', _ctx.query, function(results) {
|
||||
saveSnapshot(results);
|
||||
outputSnapshot(results, false);
|
||||
setCustomized(false);
|
||||
});
|
||||
}
|
||||
|
||||
function onSelectSnapshot() {
|
||||
var index = $('#historyIndex').slider('getValue');
|
||||
outputSnapshot(_ctx.log[index], false);
|
||||
setCustomized(true);
|
||||
}
|
||||
|
||||
function saveSnapshot(results) {
|
||||
@ -208,17 +133,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setCustomized(customized) {
|
||||
if (customized) {
|
||||
$('#customized').show();
|
||||
$('#forget').hide();
|
||||
}
|
||||
else {
|
||||
$('#customized').hide();
|
||||
$('#forget').show();
|
||||
}
|
||||
}
|
||||
|
||||
function outputSnapshot(results, omitValues) {
|
||||
var columns = {};
|
||||
for (var name in results.columns) {
|
||||
|
@ -1,28 +1,23 @@
|
||||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Alex Yatskov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
* Copyright (c) 2015 Alex Yatskov <alex@foosoft.net>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
(function(grapher) {
|
||||
'use strict';
|
||||
|
@ -133,67 +133,6 @@ function loadDb(params) {
|
||||
pool = mysql.createPool(params);
|
||||
}
|
||||
|
||||
function addKeyword(query, callback) {
|
||||
if (!/^[a-zA-Z0-9\s\-]+$/.test(query.keyword)) {
|
||||
callback({
|
||||
keyword: query.keyword,
|
||||
success: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
getKeywords(function(keywords) {
|
||||
var values = [
|
||||
query.keyword,
|
||||
query.features.delicious,
|
||||
query.features.accomodating,
|
||||
query.features.affordable,
|
||||
query.features.atmospheric,
|
||||
query.features.nearby,
|
||||
query.features.accessible
|
||||
];
|
||||
|
||||
pool.query('INSERT INTO keywords VALUES(?, ?, ?, ?, ?, ?, ?)', values, function(err) {
|
||||
callback({
|
||||
keyword: query.keyword,
|
||||
success: err === null
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeKeyword(query, callback) {
|
||||
pool.query('DELETE FROM keywords WHERE name=? AND name NOT IN (SELECT name FROM presets)', [query.keyword], function(err, fields) {
|
||||
callback({
|
||||
keyword: query.keyword,
|
||||
success: err === null && fields.affectedRows > 0
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getKeywords(callback) {
|
||||
pool.query('SELECT * FROM keywords', function(err, rows) {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
var keywords = {};
|
||||
for (var i = 0, count = rows.length; i < count; ++i) {
|
||||
var row = rows[i];
|
||||
keywords[row.name] = {
|
||||
delicious: row.delicious,
|
||||
accomodating: row.accomodating,
|
||||
affordable: row.affordable,
|
||||
atmospheric: row.atmospheric,
|
||||
nearby: row.nearby,
|
||||
accessible: row.access
|
||||
};
|
||||
}
|
||||
|
||||
callback(keywords);
|
||||
});
|
||||
}
|
||||
|
||||
function getRecords(context, callback) {
|
||||
pool.query('SELECT * FROM reviews', function(err, rows) {
|
||||
if (err) {
|
||||
@ -250,30 +189,13 @@ function computeRecordGeo(records, context) {
|
||||
});
|
||||
}
|
||||
|
||||
function getData(context, callback) {
|
||||
getKeywords(function(keywords) {
|
||||
getRecords(context, function(records) {
|
||||
callback({
|
||||
keywords: keywords,
|
||||
records: records
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getParameters(callback) {
|
||||
getKeywords(function(keywords) {
|
||||
callback({keywords: keywords});
|
||||
});
|
||||
}
|
||||
|
||||
function execQuery(query, callback) {
|
||||
var context = {
|
||||
geo: query.geo,
|
||||
walkingDist: query.walkingDist * 1000.0
|
||||
};
|
||||
|
||||
getData(context, function(data) {
|
||||
getRecords(context, function(data) {
|
||||
var searchResults = findRecords(
|
||||
data,
|
||||
query.features,
|
||||
@ -308,8 +230,5 @@ function execQuery(query, callback) {
|
||||
|
||||
module.exports = {
|
||||
loadDb: loadDb,
|
||||
addKeyword: addKeyword,
|
||||
removeKeyword: removeKeyword,
|
||||
getParameters: getParameters,
|
||||
execQuery: execQuery
|
||||
};
|
||||
|
@ -39,24 +39,6 @@ function main(staticFiles, port) {
|
||||
user: 'hscd'
|
||||
});
|
||||
|
||||
app.use('/get_parameters', function(req, res) {
|
||||
search.getParameters(function(parameters) {
|
||||
res.json(parameters);
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/add_keyword', function(req, res) {
|
||||
search.addKeyword(req.query, function(results) {
|
||||
res.json(results);
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/remove_keyword', function(req, res) {
|
||||
search.removeKeyword(req.query, function(results) {
|
||||
res.json(results);
|
||||
});
|
||||
});
|
||||
|
||||
app.use('/search', function(req, res) {
|
||||
search.execQuery(req.query, function(results) {
|
||||
res.json(results);
|
||||
|
Loading…
Reference in New Issue
Block a user