Added files
This commit is contained in:
commit
f8bd82f33d
|
@ -0,0 +1,92 @@
|
||||||
|
var exports = module.exports;
|
||||||
|
//var {Database} = require('sqlite3');
|
||||||
|
//var sqldb = new Database(_data+'/data.db');
|
||||||
|
var {Client} = require('cassandra-driver');
|
||||||
|
const cass = new Client({
|
||||||
|
cloud: {secureConnectBundle:'secure-connect-todo.zip'},
|
||||||
|
credentials: {
|
||||||
|
username:'',
|
||||||
|
password:''
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
async function startcass() {
|
||||||
|
await cass.connect();
|
||||||
|
cass.execute('use todo');
|
||||||
|
}
|
||||||
|
startcass();
|
||||||
|
|
||||||
|
(()=>{
|
||||||
|
var rankCache = new Map();
|
||||||
|
var rankReadTimeouts = new Map();
|
||||||
|
var rankWriteTimeouts = new Map();
|
||||||
|
var rankReadBounce = 1000*60*5;
|
||||||
|
var rankWriteBounce = 1000*15;
|
||||||
|
function rawgetrank(user,cb) {
|
||||||
|
cass.execute('Select json from rank where user=?',[user]).then(result=>{
|
||||||
|
if(!result || !result.rows || !result.rows.length) return cb(null,{});
|
||||||
|
cb(null,JSON.parse(result.rows[0].json));
|
||||||
|
}).catch(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updaterankreadtimeout(user) {
|
||||||
|
if(rankReadTimeouts.has(user)) clearTimeout(rankReadTimeouts.get(user));
|
||||||
|
rankReadTimeouts.set(user,setTimeout(()=>rankCache.delete(user),rankReadBounce));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getrank(user,cb) {
|
||||||
|
updaterankreadtimeout(user);
|
||||||
|
if(rankCache.has(user)) return cb(null,rankCache.get(user));
|
||||||
|
rawgetrank(user,(err,obj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
rankCache.set(user,obj);
|
||||||
|
return cb(null,obj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function rawwriterank(user,obj) {
|
||||||
|
cass.execute('Insert into rank (user,json) values (?,?)',[user,JSON.stringify(obj)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function writerank(user,obj) {
|
||||||
|
if(rankWriteTimeouts.has(user)) clearTimeout(rankWriteTimeouts.get(user));
|
||||||
|
rankWriteTimeouts.set(user,setTimeout(()=>rawwriterank(user,obj),rankWriteBounce));
|
||||||
|
}
|
||||||
|
exports.getrank=getrank;
|
||||||
|
exports.writerank=writerank;
|
||||||
|
})();
|
||||||
|
|
||||||
|
(()=>{
|
||||||
|
function rawgettitle(user,id,cb) {
|
||||||
|
cass.execute('Select title from titles where user=? and id=?',[user,id]).then(result=>{
|
||||||
|
if(!result || !result.rows || !result.rows.length) return cb('title not found');
|
||||||
|
cb(null,result.rows[0]);
|
||||||
|
}).catch(cb);
|
||||||
|
}
|
||||||
|
function rawwritetitle(user,id,title) {
|
||||||
|
cass.execute('Insert into titles (user,id,title) values (?,?,?)',[user.id,title]);
|
||||||
|
}
|
||||||
|
exports.gettitle=rawgettitle;
|
||||||
|
exports.writetitle=rawwritetitle;
|
||||||
|
})();
|
||||||
|
|
||||||
|
(()=>{
|
||||||
|
function rawgetday(user,day,cb) {
|
||||||
|
cass.execute('Select json from day where user=? and day=?',[user,day]).then(result=>{
|
||||||
|
if(!result || !result.rows || !result.rows.length) return cb(null,[]);
|
||||||
|
cb(null,JSON.parse(result.rows[0].json));
|
||||||
|
}).catch(cb);
|
||||||
|
}
|
||||||
|
function rawwriteday(user,day,list) {
|
||||||
|
cass.execute('Insert into day (user,day,json) values (?,?,?)',[user,day,JSON.stringify(list)]);
|
||||||
|
}
|
||||||
|
exports.getday=rawgetday;
|
||||||
|
exports.writeday=rawwriteday;
|
||||||
|
})();
|
||||||
|
|
||||||
|
(()=>{
|
||||||
|
function rawaddlog(user,title,id) {
|
||||||
|
cass.execute('Insert into addjournal (user,time,title,id) values (?,?,?,?)',[user,Date.now(),title,id]);
|
||||||
|
}
|
||||||
|
exports.addlogwrite=rawaddlog;
|
||||||
|
})();
|
|
@ -0,0 +1,93 @@
|
||||||
|
|
||||||
|
var readwritecache2 = require('../readwritecache2');
|
||||||
|
var fs=require('fs');
|
||||||
|
var _data = __dirname+'/data';
|
||||||
|
var sqlitedb = require('./sqlitedb');
|
||||||
|
var sqldb = sqlitedb;
|
||||||
|
|
||||||
|
//var {Client} = require('cassandra-driver');
|
||||||
|
//const cass = new Client({
|
||||||
|
// cloud: {secureConnectBundle:'secure-connect-todo.zip'},
|
||||||
|
// credentials: {
|
||||||
|
// username:'jvonmitchell@gmail.com',
|
||||||
|
// password:'6e9hDX8$$'
|
||||||
|
// },
|
||||||
|
//});
|
||||||
|
//
|
||||||
|
//async function startcass() {
|
||||||
|
// await cass.connect();
|
||||||
|
// cass.execute('use todo');
|
||||||
|
//}
|
||||||
|
//startcass();
|
||||||
|
|
||||||
|
module.exports.ranks=readwritecache2({
|
||||||
|
default:{},
|
||||||
|
writefreq:1000*30,
|
||||||
|
readfreq:1000*60*5,
|
||||||
|
delayclearonread:true,
|
||||||
|
delaywriteonwrite:true,
|
||||||
|
get:(key,cb)=>{
|
||||||
|
console.log('Reading ranks for',key);
|
||||||
|
sqlitedb.get("SELECT json FROM rank WHERE user=?",key,(err,json)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
if(!json) return cb();
|
||||||
|
try {
|
||||||
|
cb(null,JSON.parse(json.json));
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
cb(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
write:(key,obj,notindb,cb)=>{
|
||||||
|
//console.log('Writing ranks for',key);
|
||||||
|
if(notindb) return sqlitedb.run('INSERT INTO rank (user,json) VALUES (?,?)',key,JSON.stringify(obj),cb);
|
||||||
|
sqlitedb.run('UPDATE rank SET json=? WHERE user=?',JSON.stringify(obj),key,cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports.journals=readwritecache2({
|
||||||
|
default:{},
|
||||||
|
get:(key,cb)=>{
|
||||||
|
var user = key.split('.')[0];
|
||||||
|
var date=key.split('.day.')[1].replace('.json','');
|
||||||
|
//var date=key.toString();
|
||||||
|
sqldb.get('Select json from day where user=? and day=?',user,date,(err,result)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
if(result) return cb(null,JSON.parse(result.json));
|
||||||
|
//cass.execute('Select json from day where user=? and day=?',[user,date]).then(result=>{
|
||||||
|
//if(result && result.rows && result.rows.length) {
|
||||||
|
// //console.log({result});
|
||||||
|
// return cb(null,JSON.parse(result.rows[0].json));
|
||||||
|
//}
|
||||||
|
fs.readFile(_data+'/'+key+'.json',(err,buff)=>{
|
||||||
|
if(err) return cb();
|
||||||
|
try {
|
||||||
|
cb(null,JSON.parse(buff));
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
console.log({key,buff:buff.toString(),err:e,cb});
|
||||||
|
cb(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
write:(key,obj,notindb,cb)=>{
|
||||||
|
var user = key.split('.')[0];
|
||||||
|
var day = key.split('.day.')[1];
|
||||||
|
var stringified=JSON.stringify(obj);
|
||||||
|
//cass.execute('Insert into day (user,day,json) values (?,?,?)',[user,day,stringified]);
|
||||||
|
fs.writeFile(_data+'/'+key+'.json',stringified,cb);
|
||||||
|
if(notindb) {
|
||||||
|
sqldb.run('INSERT into day (user,day,json) values (?,?,?)',user,day,stringified);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sqldb.run('UPDATE day SET json=? WHERE user=? AND day=?',stringified,user,day);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
writefreq:1000*30,
|
||||||
|
readfreq:1000*60*5,
|
||||||
|
delayclearonread:true,
|
||||||
|
delaywriteonwrite:true
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var repl = require('repl');
|
||||||
|
var user = process.argv[2]||'me';
|
||||||
|
var todo=require('./nice')(user);
|
||||||
|
var context=repl.start(user+'> ').context;
|
||||||
|
|
||||||
|
context.todo=todo;
|
||||||
|
Object.keys(todo).forEach(k=>context[k]=todo[k]);
|
|
@ -0,0 +1,330 @@
|
||||||
|
module.exports=exports;
|
||||||
|
var todo=require('./todo');
|
||||||
|
var {pullexposedtasks,randomtasks,edittitle,searchtasks,pullmirrorsuper,pullmirrortask,getjournal,decayranks,completetask,pulltasks,addtask,removetask,ranktasks,removetasks,addmany}=todo;
|
||||||
|
Object.keys(todo).forEach(k=>exports[k]=todo[k]);
|
||||||
|
var prompt=require('prompt-sync')();
|
||||||
|
var fs=require('fs');
|
||||||
|
var async=require('async');
|
||||||
|
|
||||||
|
function noop() {}
|
||||||
|
|
||||||
|
function exports(user) {
|
||||||
|
var retr={};
|
||||||
|
retr.exports=exports;
|
||||||
|
retr.random=random;
|
||||||
|
retr.rand=random;
|
||||||
|
function random(count=5) {
|
||||||
|
randomtasks(user,count,(err,res)=>{
|
||||||
|
console.log();
|
||||||
|
res.forEach(i=>console.log(i.id,i.title));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.add=add;
|
||||||
|
function add() {
|
||||||
|
if(arguments.length==0) {
|
||||||
|
var list=[];
|
||||||
|
function ask() {
|
||||||
|
var line=prompt(':');
|
||||||
|
if(line) {
|
||||||
|
list.push(line);
|
||||||
|
ask();
|
||||||
|
}
|
||||||
|
else { //Add list
|
||||||
|
addmany(user,list,console.log);
|
||||||
|
}
|
||||||
|
//if(line) addtask(user,line,ask);
|
||||||
|
}
|
||||||
|
return ask();
|
||||||
|
}
|
||||||
|
Array.prototype.forEach.bind(arguments)(item=>{
|
||||||
|
if(typeof(item)==='string') addtask(user,item,noop);
|
||||||
|
else { //Asuming list
|
||||||
|
item.forEach(item=>addtask(user,item,noop));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.remove=remove;
|
||||||
|
function remove() {
|
||||||
|
Array.prototype.forEach.bind(arguments)(item=>{
|
||||||
|
if(typeof(item)==='number') {
|
||||||
|
if(item<=4) {
|
||||||
|
var verify = prompt('Verify: Y/n');
|
||||||
|
if(verify[0]=='n'||verify[0]=='N') return;
|
||||||
|
}
|
||||||
|
removetask(user,item,noop);
|
||||||
|
}
|
||||||
|
else { //Asuming list
|
||||||
|
item.forEach(item=>removetask(user,item,noop));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function printtasks(tasks,stream) {
|
||||||
|
pastpull=tasks;
|
||||||
|
try {
|
||||||
|
tasks.sort(()=>Math.random()-0.5);
|
||||||
|
stream.write('\n');
|
||||||
|
//console.log({tasks});
|
||||||
|
tasks.forEach((t,i)=>{
|
||||||
|
//console.log(t.id+':',i,t.title);
|
||||||
|
stream.write(t.id+': '+i+' '+t.title+'\n');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
console.log({user,tasks});
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retr.pullexposed = pullexposed;
|
||||||
|
function pullexposed(count=4,stream=process.stdout) {
|
||||||
|
pullexposedtasks(user,count,(err,tasks)=>{
|
||||||
|
if(err) return console.log(err,tasks);
|
||||||
|
printtasks(tasks,stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var pastpull=[];
|
||||||
|
retr.pull=pull;
|
||||||
|
retr.p = pull;
|
||||||
|
function pull(count=4,stream=process.stdout) {
|
||||||
|
pulltasks(user,count,(err,tasks)=>{
|
||||||
|
if(err) return console.log(err,tasks);
|
||||||
|
printtasks(tasks,stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.r=r;
|
||||||
|
var pulllog=fs.createWriteStream(__dirname+'/data/logs/pull.log',{flags:'a'});
|
||||||
|
//function r() {
|
||||||
|
// if(arguments.length===1 && typeof(arguments[0])==='string') {
|
||||||
|
// return retr.done(arguments[0]);
|
||||||
|
// }
|
||||||
|
// var expanded=[];
|
||||||
|
// Array.prototype.forEach.bind(arguments)(item=>{
|
||||||
|
// if(typeof(item)==='number') expanded.push(item);
|
||||||
|
// else { //Asuming list
|
||||||
|
// expanded=expanded.concat(item);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// var toptitle = pastpull[expanded[0]].title;
|
||||||
|
// expanded=expanded.map(i=>pastpull[i].id);
|
||||||
|
// //console.log(expanded)
|
||||||
|
// ranktasks(user,expanded,noop);
|
||||||
|
// pulllog.write(toptitle+'\n');
|
||||||
|
// pastrank=expanded;
|
||||||
|
//}
|
||||||
|
function r() {
|
||||||
|
if (arguments.length === 1 && typeof(arguments[0]) === 'string') {
|
||||||
|
return retr.done(arguments[0]);
|
||||||
|
}
|
||||||
|
var expanded = [];
|
||||||
|
Array.prototype.forEach.call(arguments, item => {
|
||||||
|
if (typeof(item) === 'number') {
|
||||||
|
expanded.push([item]); // Wrap single numbers in an array
|
||||||
|
} else if (Array.isArray(item)) {
|
||||||
|
expanded.push(item); // Use array as is
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var toptitle = pastpull[expanded[0][0]].title; // Use the first element of the first array to get the title
|
||||||
|
expanded = expanded.map(group => group.map(i => pastpull[i].id)); // Replace temp ids with longhand ids
|
||||||
|
ranktasks(user, expanded, noop);
|
||||||
|
pulllog.write(toptitle + '\n');
|
||||||
|
pastrank = expanded.flat();
|
||||||
|
}
|
||||||
|
retr.addfromfile=addfromfile;
|
||||||
|
function addfromfile(path='insert') {
|
||||||
|
fs.readFile(path,(err,buff)=>{
|
||||||
|
if(err) return console.log(err);
|
||||||
|
addmany(user,buff.toString().split('\n').filter(i=>i.length),console.log);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.done=done;
|
||||||
|
function done(taskid) {
|
||||||
|
if(taskid<=4) {
|
||||||
|
var verify = prompt('Verify: Y/n');
|
||||||
|
if(verify[0]=='n'||verify[0]=='N') return;
|
||||||
|
}
|
||||||
|
completetask(user,taskid,err=>{
|
||||||
|
if(err) return console.log(err);
|
||||||
|
decayranks(user,1-5/300,noop);
|
||||||
|
//if(typeof(taskid)=='number') setTimeout(pm,100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.d=d;
|
||||||
|
function d() {
|
||||||
|
done(pastrank[0]);
|
||||||
|
}
|
||||||
|
var pastrank=[];
|
||||||
|
retr.rank=rank;
|
||||||
|
//function rank() {
|
||||||
|
// var expanded=[];
|
||||||
|
// Array.prototype.forEach.bind(arguments)(item=>{
|
||||||
|
// if(typeof(item)==='number') expanded.push(item);
|
||||||
|
// else { //Asuming list
|
||||||
|
// expanded=expanded.concat(item);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// pastrank=expanded;
|
||||||
|
// ranktasks(user,expanded,noop);
|
||||||
|
//}
|
||||||
|
function rank() {
|
||||||
|
var expanded = [];
|
||||||
|
if (arguments.length === 1 && Array.isArray(arguments[0])) {
|
||||||
|
expanded = arguments[0]; // Treat single array argument as the complete taskGroups
|
||||||
|
} else {
|
||||||
|
// Treat each argument as an element to be passed to ranktasks
|
||||||
|
Array.prototype.forEach.call(arguments, item => {
|
||||||
|
if (typeof(item) === 'number') {
|
||||||
|
expanded.push([item]); // Wrap single numbers in an array
|
||||||
|
} else {
|
||||||
|
expanded.push(item); // Already an array, use as is
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pastrank = expanded.flat();
|
||||||
|
ranktasks(user, expanded, noop);
|
||||||
|
}
|
||||||
|
retr.pullmirror=pullmirror;
|
||||||
|
retr.pm=pullmirror;
|
||||||
|
retr.pullmirrormonth=pullmirrormonth;
|
||||||
|
retr.pullmirrorweek=pullmirrorweek;
|
||||||
|
retr.pullmirrorday=pullmirrorday;
|
||||||
|
function pullmirror() {
|
||||||
|
//async.parallel([pullmirrormonth,pullmirrorweek,pullmirrorday],(err,res)=>{
|
||||||
|
async.map([doublepullmirrormonth,pullmirrormonth,doublepullmirrorweek,pullmirrorweek,doublepullmirrorday,pullmirrorday],(func,cb)=>{
|
||||||
|
func((err,res)=>{
|
||||||
|
if(err == 'Journal missing - skiplimit reached') return cb();
|
||||||
|
cb(err,res);
|
||||||
|
});
|
||||||
|
},(err,res)=>{
|
||||||
|
if(err) return console.log(err);
|
||||||
|
res=res.filter(r=>r);
|
||||||
|
res.forEach(item=>{
|
||||||
|
if(!item) return console.log('missing');
|
||||||
|
console.log((new Date(item.time)).toLocaleString(),item.title,item.id||'');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function pullmirrorday(cb) {
|
||||||
|
pullmirrortask(user,cb);
|
||||||
|
}
|
||||||
|
function doublepullmirrorday(cb) {
|
||||||
|
getjournal(user,0,(err,journal)=>{
|
||||||
|
if(err) return console.log(err);
|
||||||
|
if(!journal.list) return cb();
|
||||||
|
pullmirrorsuper(user,1,journal.list.length*2,5,cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.lookback=lookback;
|
||||||
|
function lookback(days) {
|
||||||
|
getjournal(user,days,(err,journal)=>{
|
||||||
|
if(err) return console.log(err);
|
||||||
|
if(!journal.list) return console.log('Journal missing');
|
||||||
|
journal.list.forEach(item=>{
|
||||||
|
console.log((new Date(item.time)).toLocaleString(),item.title,item.id||'');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.pullmirrorweek=pullmirrorweek;
|
||||||
|
function pullmirrorweek(cb) {
|
||||||
|
var day=(new Date()).getDay()||7;
|
||||||
|
var pending=day;
|
||||||
|
var lookcount=0;
|
||||||
|
for(var i=0;i<day;++i) {
|
||||||
|
getjournal(user,i,(err,journal)=>{
|
||||||
|
--pending;
|
||||||
|
if(journal && journal.list) lookcount+=journal.list.length;
|
||||||
|
if(!pending) {
|
||||||
|
pullmirrorsuper(user,day,lookcount,5,cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retr.doublepullmirrorweek=doublepullmirrorweek;
|
||||||
|
function doublepullmirrorweek(cb) {
|
||||||
|
var day=(new Date()).getDay()||7;
|
||||||
|
var pending=day;
|
||||||
|
var lookcount=0;
|
||||||
|
for(var i=0;i<day;++i) {
|
||||||
|
getjournal(user,i,(err,journal)=>{
|
||||||
|
--pending;
|
||||||
|
if(journal && journal.list) lookcount+=journal.list.length;
|
||||||
|
if(!pending) {
|
||||||
|
pullmirrorsuper(user,day,lookcount*2,5,cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retr.pullmirrormonth=pullmirrormonth;
|
||||||
|
function pullmirrormonth(cb) {
|
||||||
|
var day=(new Date()).getDate()||30;
|
||||||
|
var pending=day;
|
||||||
|
var lookcount=0;
|
||||||
|
for(var i=0;i<day;++i) {
|
||||||
|
getjournal(user,i,(err,journal)=>{
|
||||||
|
--pending;
|
||||||
|
if(journal && journal.list) lookcount+=journal.list.length;
|
||||||
|
if(!pending) {
|
||||||
|
pullmirrorsuper(user,day,lookcount,15,cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retr.doublepullmirrormonth=doublepullmirrormonth;
|
||||||
|
function doublepullmirrormonth(cb) {
|
||||||
|
var day=(new Date()).getDate()||30;
|
||||||
|
var pending=day;
|
||||||
|
var lookcount=0;
|
||||||
|
for(var i=0;i<day;++i) {
|
||||||
|
getjournal(user,i,(err,journal)=>{
|
||||||
|
--pending;
|
||||||
|
if(journal && journal.list) lookcount+=journal.list.length;
|
||||||
|
if(!pending) {
|
||||||
|
pullmirrorsuper(user,day,lookcount*2,15,cb);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function lookup(ref) {
|
||||||
|
if(!ref) return;
|
||||||
|
if(typeof(ref)=='number') return lookupid(ref);
|
||||||
|
else return lookupname(ref);
|
||||||
|
}
|
||||||
|
retr.search=search;
|
||||||
|
function search(titlefrag) {
|
||||||
|
var args=[];
|
||||||
|
for(var i=0;arguments[i];++i) {
|
||||||
|
args=args.concat(arguments[i]);
|
||||||
|
}
|
||||||
|
searchtasks(user,args,console.log);
|
||||||
|
}
|
||||||
|
retr.searchres=searchres;
|
||||||
|
function searchres(titlefrag) {
|
||||||
|
var args=[];
|
||||||
|
for(var i=0;arguments[i];++i) {
|
||||||
|
args=args.concat(arguments[i]);
|
||||||
|
}
|
||||||
|
return new Promise((resolve,reject)=>{
|
||||||
|
searchtasks(user,args,(err,results)=>{
|
||||||
|
if(err) return reject(err);
|
||||||
|
resolve(results);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
retr.edit = edit;
|
||||||
|
function edit(id,title) {
|
||||||
|
edittitle(user,id,title);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
http.createServer((req,res)=>{
|
||||||
|
if(req.url=='/pull') {
|
||||||
|
res.writeHead(200,{'Content-type':'text/plain'});
|
||||||
|
pulltasks(user,5,(err,tasks)=>{
|
||||||
|
tasks.forEach((t,i)=>{
|
||||||
|
//console.log(t.id+':',i,t.title);
|
||||||
|
res.write(t.id+': '+i+' '+t.title+'\n');
|
||||||
|
});
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).listen(7000);
|
||||||
|
*/
|
||||||
|
return retr;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "todo2",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": ".eslintrc.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"start": "node server.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"prompt-sync": "^4.2.0",
|
||||||
|
"sqlite3": "^5.1.4"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
var async = require('async');
|
||||||
|
var UrlResolver = require('urlresolver');
|
||||||
|
var p = new UrlResolver();
|
||||||
|
var user = 'me';
|
||||||
|
exports.p = p;
|
||||||
|
|
||||||
|
var todo=require('./todo');
|
||||||
|
var {pulltasks,addtask,removetask,ranktasks,removetasks}=todo;
|
||||||
|
Object.keys(todo).forEach(k=>exports[k]=todo[k]);
|
||||||
|
|
||||||
|
exports.de=de;
|
||||||
|
function de(res,err,code) {
|
||||||
|
res.writeHead(code||400,{"Content-Type":'text/plain'});
|
||||||
|
res.end(err.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.simpcb=simpcb;
|
||||||
|
function simpcb(res) {
|
||||||
|
return (err,data)=>{
|
||||||
|
if(err) return de(res,err);
|
||||||
|
if(data) return res.end(data.toString());
|
||||||
|
res.end('success');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
p.add('/pull',(req,res)=>{
|
||||||
|
pulltasks(user,5,(err,tasks)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
res.writeHead(200,{"Content-Type":'text/plain'});
|
||||||
|
res.end(tasks.map((i,ind)=>`${i.id}: ${ind} ${i.title}`).join('\n'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
p.add('/api/pull',(req,res)=>{
|
||||||
|
//Replace with req.user
|
||||||
|
pulltasks(user,5,(err,tasks)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
res.writeHead(200,{"Content-Type":'application/json'});
|
||||||
|
res.end(JSON.stringify(tasks));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
p.add('/add/task/',(req,res)=>{
|
||||||
|
addtask(req.user,req.post.string,simpcb(res));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
p.add('/remove/task',(req,res)=>{
|
||||||
|
var taskid=parseInt(req.post.string);
|
||||||
|
if(isNaN(taskid)) return de(res,"Not a number");
|
||||||
|
removetask(req.user,taskid,simpcb(res));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
p.add('/rank/tasks',(req,res)=>{
|
||||||
|
var tasks=req.post.string.split(',').map(i=>parseInt(i)).filter(i=>!isNaN(i));
|
||||||
|
ranktasks(req.user,tasks,simpcb(res));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
p.add('/rank/and/remove/tasks',(req,res)=>{
|
||||||
|
var [rank,remove]=req.post.string.split('|').map(list=>list.split(',').map(i=>parseInt(i)).filter(i=>!isNaN(i)));
|
||||||
|
async.parallel([
|
||||||
|
cb=>ranktasks(req.user,rank,cb),
|
||||||
|
cb=>removetasks(req.user,remove,cb)
|
||||||
|
],simpcb(res));
|
||||||
|
});
|
||||||
|
|
||||||
|
function exports(req,res) {
|
||||||
|
p.get(req.url)(req,res);
|
||||||
|
}
|
||||||
|
|
||||||
|
require('http').createServer(exports).listen(8092);
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/*
|
||||||
|
sqlitedb.get("SELECT json FROM rank WHERE user=?",key,(err,json)=>{
|
||||||
|
if(notindb) return sqlitedb.run('INSERT INTO rank (user,json) VALUES (?,?)',key,JSON.stringify(obj),cb);
|
||||||
|
sqlitedb.run('UPDATE rank SET json=? WHERE user=?',JSON.stringify(obj),key,cb);
|
||||||
|
*/
|
||||||
|
|
||||||
|
var db = require('./sqlitedb');
|
||||||
|
|
||||||
|
db.run('CREATE TABLE rank (user text primary key,json text)',console.log);
|
||||||
|
|
||||||
|
/*
|
||||||
|
todo.js: async.map(ids,(id,cb)=>sqldb.get('Select id,title from titles where user=? and id=?',user,id,cb),cb);
|
||||||
|
todo.js: sqldb.run('Insert into titles values (?,?,?)',user,i,tasktext,noop);
|
||||||
|
todo.js: sqldb.run('Insert into titles values (?,?,?)',user,i,tasktext,noop);
|
||||||
|
todo.js: sqldb.get('Select title from titles where user=? and id=?',user,taskid,(err,result)=>{
|
||||||
|
todo.js: sqldb.run('Delete from titles where user=? and id=?',user,taskid,err=>{
|
||||||
|
todo.js: sqldb.get('Select title from titles where user=? and id=?',user,taskid,(err,titleobj)=>{
|
||||||
|
todo.js: sqldb.all(`Select id,title from titles where user=? and ${titlefrags}`,user,cb);
|
||||||
|
todo.js: sqldb.run('Update titles Set title=? Where user=? and id=?',title,user,id,cb);
|
||||||
|
todo.js: async.map(selectedids,(id,cb)=>sqldb.get('Select id,title from titles where user=? and id=?',user,id,cb),cb);
|
||||||
|
*/
|
||||||
|
|
||||||
|
db.run('CREATE TABLE titles (user text,id integer,title text)');
|
||||||
|
db.run('CREATE INDEX titles_idx ON titles(user,id)');
|
||||||
|
|
||||||
|
/*
|
||||||
|
data2.js: sqldb.get('Select json from day where user=? and day=?',user,date,(err,result)=>{
|
||||||
|
data2.js: sqldb.run('INSERT into day (user,day,json) values (?,?,?)',user,day,stringified);
|
||||||
|
data2.js: sqldb.run('UPDATE day SET json=? WHERE user=? AND day=?',stringified,user,day);
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE TABLE day (user text not null,day text not null,json text not null);
|
||||||
|
CREATE UNIQUE INDEX day_idx ON day(user,day);
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
var sqlite3 = require('sqlite3');
|
||||||
|
module.exports = new sqlite3.Database(__dirname+'/data/data.db');
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
function test1() {
|
||||||
|
var a = require('./data');
|
||||||
|
setTimeout(()=>{
|
||||||
|
a.getrank('test',console.log);
|
||||||
|
},1000);
|
||||||
|
}
|
||||||
|
test1();
|
|
@ -0,0 +1,6 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
|
||||||
|
var a = require('./server');
|
||||||
|
|
||||||
|
a.pulltasks('test',5,console.log);
|
|
@ -0,0 +1,475 @@
|
||||||
|
var exports=module.exports;
|
||||||
|
var _data = __dirname+'/data';
|
||||||
|
exports._data=_data;
|
||||||
|
|
||||||
|
var fs=require('fs');
|
||||||
|
var {shuffle} = require('lodash');
|
||||||
|
var async = require('async');
|
||||||
|
var df = require('../df');
|
||||||
|
var {ranks,journals} = require('./data2');
|
||||||
|
|
||||||
|
df((err,kb)=>{
|
||||||
|
if(err) return console.log('df err',err);
|
||||||
|
if(kb<1000) process.exit(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
var db = require('../readwritecache')(dbwrite,dbwrite,dbread,{},1000,1);
|
||||||
|
//var {Database} = require('sqlite3');
|
||||||
|
var sqldb = require('./sqlitedb');
|
||||||
|
//var {Client} = require('cassandra-driver');
|
||||||
|
//const cass = new Client({
|
||||||
|
// cloud: {secureConnectBundle:'secure-connect-todo.zip'},
|
||||||
|
// credentials: {
|
||||||
|
// username:'jvonmitchell@gmail.com',
|
||||||
|
// password:'6e9hDX8$$'
|
||||||
|
// },
|
||||||
|
//});
|
||||||
|
|
||||||
|
//async function startcass() {
|
||||||
|
// await cass.connect();
|
||||||
|
// cass.execute('use todo');
|
||||||
|
//}
|
||||||
|
//startcass();
|
||||||
|
|
||||||
|
|
||||||
|
exports.db=db;
|
||||||
|
|
||||||
|
exports.dbwrite=dbwrite;
|
||||||
|
function dbwrite(key,obj,cb) {
|
||||||
|
//console.log("Writing",key);
|
||||||
|
var stringified=JSON.stringify(obj);
|
||||||
|
var user = key.split('.')[0];
|
||||||
|
if(key.endsWith('.rank')) {
|
||||||
|
sqldb.run('Update rank set json=? where user=?',stringified,user,noop);
|
||||||
|
cass.execute('Insert into rank (user,json) values (?,?)',[user,stringified]);
|
||||||
|
}
|
||||||
|
if(key.indexOf('.day.')!=-1) {
|
||||||
|
var day = key.split('.day.')[1];
|
||||||
|
cass.execute('Insert into day (user,day,json) values (?,?,?)',[user,day,stringified]);
|
||||||
|
}
|
||||||
|
fs.writeFile(_data+'/'+key+'.json',stringified,cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rankCache = new Map();
|
||||||
|
var rankCacheTimeouts = new Map();
|
||||||
|
exports.dbread=dbread;
|
||||||
|
function dbread(key,cb) {
|
||||||
|
var user = key.split('.')[0];
|
||||||
|
if(key.endsWith('.rank')) {
|
||||||
|
if(rankCache.has(user)) {
|
||||||
|
clearTimeout(rankCacheTimeouts.get(user));
|
||||||
|
rankCacheTimeouts.set(user,setTimeout(()=>rankCache.delete(user)));
|
||||||
|
return cb(null,rankCache.get(user));
|
||||||
|
}
|
||||||
|
return sqldb.get('Select json from rank where user=?',user,(err,json)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
//if(!json) return cb('User not found in rank');
|
||||||
|
if(!json) return cb();
|
||||||
|
json=JSON.parse(json.json);
|
||||||
|
rankCache.set(user,json);
|
||||||
|
rankCacheTimeouts.set(user,setTimeout(()=>rankCache.delete(user)));
|
||||||
|
cb(null,json);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(key.indexOf('.day.')!=-1) {
|
||||||
|
//var indexOf = key.indexOf('.day.');
|
||||||
|
//console.log({key,indexOf});
|
||||||
|
var date=key.split('.day.')[1].replace('.json','');
|
||||||
|
return cass.execute('Select json from day where user=? and day=?',[user,date]).then(result=>{
|
||||||
|
if(result && result.rows && result.rows.length) {
|
||||||
|
//console.log({result});
|
||||||
|
return cb(null,JSON.parse(result.rows[0].json));
|
||||||
|
}
|
||||||
|
fs.readFile(_data+'/'+key+'.json',(err,buff)=>{
|
||||||
|
if(err) return cb();
|
||||||
|
try {
|
||||||
|
cb(null,JSON.parse(buff));
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
console.log({key,buff:buff.toString(),err:e,cb});
|
||||||
|
cb(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fs.readFile(_data+'/'+key+'.json',(err,buff)=>{
|
||||||
|
if(err) return cb();
|
||||||
|
try {
|
||||||
|
cb(null,JSON.parse(buff));
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
console.log({key,buff:buff.toString(),err:e,cb});
|
||||||
|
cb(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.minindexes=minindexes;
|
||||||
|
function minindexes(list) {
|
||||||
|
if(!list.length) return [];
|
||||||
|
var minvalue=list.reduce((a,b)=>a<b?a:b);
|
||||||
|
var retr=[];
|
||||||
|
for(var i=0;i<list.length;++i) {
|
||||||
|
if(list[i]==minvalue) retr.push(i);
|
||||||
|
}
|
||||||
|
//console.log({minvalue,idexes:retr});
|
||||||
|
return retr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
exports.removetasks=removetasks;
|
||||||
|
function removetasks(user,tasks,cb) {
|
||||||
|
async.map(tasks,(task,cb)=>removetask(user,cb),cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
function noop () {}
|
||||||
|
|
||||||
|
exports.addtask=addtask;
|
||||||
|
function addtask(user,tasktext,cb) {
|
||||||
|
//var rankkey=user+'.rank';
|
||||||
|
var addhistkey=user+'.addhist';
|
||||||
|
//async.map([rankkey,addhistkey],db.get,(err,objs)=>{
|
||||||
|
async.parallel([
|
||||||
|
cb=>ranks.get(user,cb),
|
||||||
|
cb=>db.get(addhistkey,cb)
|
||||||
|
],(err,objs)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
var [rankobj,addhistobj]=objs;
|
||||||
|
var i=0;
|
||||||
|
while(rankobj[i]) ++i;
|
||||||
|
sqldb.run('Insert into titles values (?,?,?)',user,i,tasktext,noop);
|
||||||
|
rankobj[i]={};
|
||||||
|
if(!addhistobj.hist) addhistobj.hist=[];
|
||||||
|
addhistobj.hist.push(tasktext);
|
||||||
|
//console.log({rankkey,rankobj,i,tasktext});
|
||||||
|
//db.markWrite(rankkey);
|
||||||
|
ranks.markWrite(user);
|
||||||
|
db.markWrite(addhistkey);
|
||||||
|
cb(null,i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.addmany=addmany;
|
||||||
|
function addmany(user,tasktexts,cb) {
|
||||||
|
//var rankkey=user+'.rank';
|
||||||
|
//db.get(rankkey,(err,rankobj)=>{
|
||||||
|
ranks.get(user,(err,rankobj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
var retr=[];
|
||||||
|
var i=0;
|
||||||
|
tasktexts.forEach(tasktext=>{
|
||||||
|
if(!tasktext) return;
|
||||||
|
while(rankobj[i]) ++i;
|
||||||
|
retr.push(i);
|
||||||
|
//sqldb.run('BEGIN TRANSACTION',noop);
|
||||||
|
sqldb.run('Insert into titles values (?,?,?)',user,i,tasktext,noop);
|
||||||
|
//sqldb.run('COMMIT',noop);
|
||||||
|
rankobj[i]={};
|
||||||
|
});
|
||||||
|
//db.markWrite(rankkey);
|
||||||
|
ranks.markWrite(user);
|
||||||
|
cb(null,retr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.removetask=removetask;
|
||||||
|
function removetask(user,taskid,cb) {
|
||||||
|
//var rankkey=user+'.rank';
|
||||||
|
//db.get(rankkey,(err,rankobj)=>{
|
||||||
|
ranks.get(user,(err,rankobj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
sqldb.get('Select title from titles where user=? and id=?',user,taskid,(err,result)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
if(result) console.log('Removed:',result.title);
|
||||||
|
sqldb.run('Delete from titles where user=? and id=?',user,taskid,err=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
console.log('removing',taskid);
|
||||||
|
delete rankobj[taskid];
|
||||||
|
Object.values(rankobj).forEach(peerobj=>{
|
||||||
|
delete peerobj[taskid];
|
||||||
|
});
|
||||||
|
//db.markWrite(rankkey);
|
||||||
|
ranks.markWrite(user);
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.completetask=completetask;
|
||||||
|
function completetask(user,taskid,cb) {
|
||||||
|
var now=Date.now();
|
||||||
|
var journalkey=user+'.day.'+(new Date()).toLocaleDateString().replace(/\//g,'.');
|
||||||
|
//db.get(journalkey,(err,journalobj)=>{
|
||||||
|
journals.get(journalkey,(err,journalobj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
var title;
|
||||||
|
journalobj.list=journalobj.list||[];
|
||||||
|
if(typeof(taskid)==='string') {
|
||||||
|
title=taskid;
|
||||||
|
journalobj.list.push({time:now,title});
|
||||||
|
journals.markWrite(journalkey);
|
||||||
|
//db.markWrite(journalkey);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sqldb.get('Select title from titles where user=? and id=?',user,taskid,(err,titleobj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
title=titleobj.title;
|
||||||
|
journalobj.list.push({time:now,title,id:taskid});
|
||||||
|
removetask(user,taskid,cb);
|
||||||
|
journals.markWrite(journalkey);
|
||||||
|
//db.markWrite(journalkey);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.undercount=undercount;
|
||||||
|
function undercount(id,obj,blockset) {
|
||||||
|
if(blockset.has(id)) return 1000;
|
||||||
|
var count=0;
|
||||||
|
var keys=Object.keys(obj);
|
||||||
|
if(!keys.length) return 0;
|
||||||
|
for(var i=0;i<keys.length;++i) {
|
||||||
|
if(blockset.has(keys[i])) continue;
|
||||||
|
if(obj[keys[i]]<0) count-=obj[keys[i]];
|
||||||
|
}
|
||||||
|
//console.log({id,count});
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.decayranks=decayranks;
|
||||||
|
const DECAY=5/300;
|
||||||
|
function decayranks(user,decay,cb) {
|
||||||
|
//var key=user+'.rank';
|
||||||
|
decay=decay||DECAY;
|
||||||
|
//db.get(key,(err,obj)=>{
|
||||||
|
ranks.get(user,(err,obj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
Object.values(obj).forEach(subobj=>{
|
||||||
|
Object.keys(subobj).forEach(subkey=>{
|
||||||
|
if(subkey=='block') return;
|
||||||
|
subobj[subkey]*=decay;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//db.markWrite(key);
|
||||||
|
ranks.markWrite(user);
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.getjournal=getjournal;
|
||||||
|
function getjournal(user,days,cb) {
|
||||||
|
days=days||0;
|
||||||
|
days=Math.abs(days);
|
||||||
|
var journalkey=user+'.day.'+(new Date(Date.now()-1000*60*60*24*days)).toLocaleDateString().replace(/\//g,'.');
|
||||||
|
//db.get(journalkey,cb);
|
||||||
|
journals.get(journalkey,cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
//exports.ranktasks=ranktasks;
|
||||||
|
//function ranktasks(user,tasklist,cb) {
|
||||||
|
// //var key=user+'.rank';
|
||||||
|
// //db.get(key,(err,obj)=>{
|
||||||
|
// ranks.get(user,(err,obj)=>{
|
||||||
|
// if(err) return cb(err);
|
||||||
|
// var i;
|
||||||
|
// for(i=0;i<tasklist.length;++i) {
|
||||||
|
// for(var j=i+1;j<tasklist.length;++j) {
|
||||||
|
// obj[tasklist[i]][tasklist[j]]=1;
|
||||||
|
// obj[tasklist[j]][tasklist[i]]=-1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// for(i=1;i<tasklist.length;++i) {
|
||||||
|
// obj[tasklist[i]].block=i; //We don't want to see it for a bit, add a block that will count down
|
||||||
|
// //console.log("Block",tasklist[i],i);
|
||||||
|
// }
|
||||||
|
// //db.markWrite(key);
|
||||||
|
// ranks.markWrite(user);
|
||||||
|
// cb();
|
||||||
|
// });
|
||||||
|
//}
|
||||||
|
|
||||||
|
exports.ranktasks=ranktasks;
|
||||||
|
function ranktasks(user,taskGroups,cb) {
|
||||||
|
ranks.get(user,(err,obj)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
var i;
|
||||||
|
for(i=0;i<taskGroups.length;++i) {
|
||||||
|
for(var j=i+1;j<taskGroups.length;++j) {
|
||||||
|
for(var taskA of [].concat(taskGroups[i])) {
|
||||||
|
for(var taskB of [].concat(taskGroups[j])) {
|
||||||
|
obj[taskA][taskB]=1;
|
||||||
|
obj[taskB][taskA]=-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 1; i < taskGroups.length; ++i) {
|
||||||
|
[].concat(taskGroups[i]).forEach(task => obj[task].block = i);
|
||||||
|
}
|
||||||
|
ranks.markWrite(user);
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.searchtasks=searchtasks;
|
||||||
|
function searchtasks(user,titlefrags,cb) {
|
||||||
|
//This is not safe
|
||||||
|
if(typeof(titlefrags)=='string') titlefrags = [titlefrags];
|
||||||
|
titlefrags = titlefrags.map(i=>i.toLowerCase());
|
||||||
|
titlefrags = titlefrags.map(i=>`title like '%${i}%'`);
|
||||||
|
titlefrags = titlefrags.join(' and ');
|
||||||
|
sqldb.all(`Select id,title from titles where user=? and ${titlefrags}`,user,cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.edittitle=edittitle;
|
||||||
|
function edittitle(user,id,title,cb) {
|
||||||
|
sqldb.run('Update titles Set title=? Where user=? and id=?',title,user,id,cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.pullmirrorsuper=pullmirrorsuper;
|
||||||
|
function pullmirrorsuper(user,daysback,donecount,skiplimit,cb) {
|
||||||
|
getjournal(user,daysback,(err,backjournal)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
if(!backjournal.list) {
|
||||||
|
if(skiplimit) pullmirrorsuper(user,daysback+1,donecount,skiplimit-1,cb);
|
||||||
|
else return cb("Journal missing - skiplimit reached");
|
||||||
|
}
|
||||||
|
else if(backjournal.list.length<donecount) pullmirrorsuper(user,daysback+1,donecount-=backjournal.list.length,skiplimit,cb);
|
||||||
|
else cb(null,backjournal.list[backjournal.list.length-donecount]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.pullmirrortask=pullmirrortask;
|
||||||
|
function pullmirrortask(user,cb) {
|
||||||
|
var skiplimit=5;
|
||||||
|
getjournal(user,0,(err,journal0)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
if(!journal0.list) return cb("Journal missing");
|
||||||
|
var donecount=journal0.list.length;
|
||||||
|
var daysback=1;
|
||||||
|
function getone() {
|
||||||
|
getjournal(user,daysback,(err,backjournal)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
if(!backjournal.list) {
|
||||||
|
if(skiplimit) {
|
||||||
|
--skiplimit;
|
||||||
|
++daysback;
|
||||||
|
//console.log('One journal missing');
|
||||||
|
return getone();
|
||||||
|
}
|
||||||
|
return cb("Journal missing");
|
||||||
|
}
|
||||||
|
if(backjournal.list.length<donecount) {
|
||||||
|
donecount-=backjournal.list.length;
|
||||||
|
++daysback;
|
||||||
|
return getone();
|
||||||
|
}
|
||||||
|
cb(null,backjournal.list[backjournal.list.length-donecount]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getone(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function filter(list,filterSet,maxcount) {
|
||||||
|
maxcount = maxcount || Infinity;
|
||||||
|
return list.filter(i=>!filterSet.has(i)).slice(0,maxcount);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.randomtasks=randomtasks;
|
||||||
|
function randomtasks(user,count,cb) {
|
||||||
|
ranks.get(user,(err,rank)=>{
|
||||||
|
var allids = Object.keys(rank);
|
||||||
|
var selectedids;
|
||||||
|
if(allids<count*count) {
|
||||||
|
selectedids=allids.sort(()=>Math.random()-0.5).slice(0,5);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selectedids=new Set();
|
||||||
|
while(selectedids.size<count) {
|
||||||
|
selectedids.add(allids[Math.floor(allids.length*Math.random())]);
|
||||||
|
}
|
||||||
|
selectedids=Array.from(selectedids);
|
||||||
|
}
|
||||||
|
async.map(selectedids,(id,cb)=>sqldb.get('Select id,title from titles where user=? and id=?',user,id,cb),cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRanksButOnlyExposed(user,cb) {
|
||||||
|
ranks.get(user,(err,rank)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
var out={};
|
||||||
|
var ids=Object.keys(rank);
|
||||||
|
var validids = ids.filter(id=>Object.keys(rank[id]).length>0);
|
||||||
|
validids.forEach(id=>out[id]=rank[id]);
|
||||||
|
cb(null,out);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exports.pulltaskids=pulltaskids;
|
||||||
|
function pulltaskids(user,count,cb,getter=ranks.get) {
|
||||||
|
//var key=user+'.rank';
|
||||||
|
var pulledids=[];
|
||||||
|
var pulledidsSet=new Set();
|
||||||
|
var filterSet=new Set();
|
||||||
|
//db.get(key,(err,rank)=>{
|
||||||
|
getter(user,(err,rank)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
var rankkeys=Object.keys(rank);
|
||||||
|
var topcohort;
|
||||||
|
//console.log({rank,rankkeys});
|
||||||
|
//For blocking items with temp block.
|
||||||
|
rankkeys.forEach(i=>{ //If it currently has a block don't display it
|
||||||
|
//console.log('Block level',i,rank[i].block);
|
||||||
|
if(rank[i].block>0) {
|
||||||
|
//console.log('Blocking',i,rank[i].block);
|
||||||
|
rank[i].block=Math.floor(rank[i].block-1);
|
||||||
|
//console.log('Blocking',i,rank[i].block);
|
||||||
|
if(rank[i].block<=0) {
|
||||||
|
delete rank[i].block;
|
||||||
|
//console.log('Delete rank',i);
|
||||||
|
}
|
||||||
|
filterSet.add(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//db.markWrite(key);
|
||||||
|
ranks.markWrite(user);
|
||||||
|
while(pulledids.length<count) {
|
||||||
|
topcohort=minindexes(rankkeys.map(id=>undercount(id,rank[id],pulledidsSet))).map(i=>rankkeys[i]);
|
||||||
|
//console.log({rankkeys,topcohort});
|
||||||
|
if(topcohort.length==0) return cb(null,pulledids); //No more items to add. Return.
|
||||||
|
topcohort.forEach(id=>pulledidsSet.add(id));
|
||||||
|
topcohort=filter(shuffle(topcohort),filterSet,count-pulledids.length);
|
||||||
|
pulledids=pulledids.concat(topcohort);
|
||||||
|
if(pulledids.length==count) return cb(null,pulledids);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.pulltasks=pulltasks;
|
||||||
|
function pulltasks(user,count,cb) {
|
||||||
|
pulltaskids(user,count,(err,ids)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
console.log({ids});
|
||||||
|
async.map(ids,(id,cb)=>sqldb.get('Select id,title from titles where user=? and id=?',user,id,cb),cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.pullexposedtasks=pullexposedtasks;
|
||||||
|
function pullexposedtasks(user,count,cb) {
|
||||||
|
pulltaskids(user,count,(err,ids)=>{
|
||||||
|
if(err) return cb(err);
|
||||||
|
console.log({ids});
|
||||||
|
async.map(ids,(id,cb)=>sqldb.get('Select id,title from titles where user=? and id=?',user,id,cb),cb);
|
||||||
|
},getRanksButOnlyExposed);
|
||||||
|
};
|
Loading…
Reference in New Issue