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)=>aremovetask(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{ 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{ if(err) return cb(err); var i; for(i=0;i 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{ 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!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(allidsMath.random()-0.5).slice(0,5); } else { selectedids=new Set(); while(selectedids.sizesqldb.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.lengthundercount(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); };