219 lines
6.8 KiB
JavaScript
219 lines
6.8 KiB
JavaScript
/*Canopy - The next generation of stoner streaming software
|
|
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
|
|
|
|
//NPM Imports
|
|
const {mongoose} = require('mongoose');
|
|
|
|
//Local Imports
|
|
const config = require('./../../../config.json');
|
|
const loggerUtils = require('../../utils/loggerUtils');
|
|
|
|
/**
|
|
* DB Schema for single document for keeping track of a single toke
|
|
*/
|
|
const tokeSchema = new mongoose.Schema({
|
|
toke: {
|
|
type: mongoose.SchemaTypes.Map,
|
|
required: true,
|
|
default: new Map()
|
|
},
|
|
date: {
|
|
type: mongoose.SchemaTypes.Date,
|
|
required: true,
|
|
default: new Date()
|
|
}
|
|
});
|
|
|
|
//statics
|
|
/**
|
|
* Cached map containing counts of individual toke commands
|
|
*/
|
|
tokeSchema.statics.tokeMap = new Map();
|
|
|
|
/**
|
|
* Cached number of total tokes
|
|
*/
|
|
tokeSchema.statics.count = 0;
|
|
|
|
/**
|
|
* Cached number of times a user has successfully ran a '!toke' command
|
|
* Not to be confused with tokeSchema.statics.count, which counts total amount of tokes called out
|
|
*/
|
|
tokeSchema.statics.commandCount = 0;
|
|
|
|
/**
|
|
* Calculates cached toke map from existing
|
|
*/
|
|
tokeSchema.statics.calculateTokeMap = async function(){
|
|
//Pull full toke collection
|
|
const tokes = await this.find();
|
|
|
|
//Drop existing toke map
|
|
this.tokeMap = new Map();
|
|
|
|
//Iterate through DB of tokes
|
|
for(const toke of tokes){
|
|
//Increment toke count
|
|
this.count++;
|
|
|
|
//For each command callout
|
|
for(const command of toke.toke){
|
|
//Increment Command Count
|
|
this.commandCount++;
|
|
|
|
//Pull current count of respective toke command
|
|
let curCount = this.tokeMap.get(command[1]);
|
|
|
|
//If this is an unset toke command
|
|
if(curCount == null){
|
|
//Set it to one
|
|
this.tokeMap.set(command[1], 1);
|
|
//Otherwise
|
|
}else{
|
|
//Increment the existing count
|
|
this.tokeMap.set(command[1], ++curCount);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Display calculated toke sats for funsies
|
|
if(config.verbose){
|
|
console.log(`Processed ${this.commandCount} toke command callouts accross ${await this.estimatedDocumentCount()} tokes.`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tattoos toke into toke DB colleciton
|
|
*
|
|
* We use this instead of a pre-save function as we need to fuck w/ statics
|
|
*/
|
|
tokeSchema.statics.tattooToke = async function(toke){
|
|
//Write toke to DB
|
|
await this.create({toke});
|
|
|
|
//Increment RAM-backed toke count
|
|
this.count++;
|
|
|
|
//Iterate through tokers
|
|
for(const curToke of toke){
|
|
//Pull current toke count
|
|
let curCount = this.tokeMap.get(curToke[1]);
|
|
|
|
//If this command hasn't been counted
|
|
if(curCount == null){
|
|
//Set new command count to one
|
|
this.tokeMap.set(curToke[1], 1);
|
|
}else{
|
|
//Increment current toke count and commit it to the RAM-backed tokeMap
|
|
this.tokeMap.set(curToke[1], ++curCount);
|
|
}
|
|
|
|
//Increment RAM-Backed command count
|
|
this.commandCount++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Ingests legacy tokes handed over by the migration model
|
|
* @param {Array} rawLegacyTokes - List of strings containing contents of legacy cytube/fore.st toke logs
|
|
*/
|
|
tokeSchema.statics.ingestLegacyTokes = async function(rawLegacyTokes){
|
|
//If migration is disabled
|
|
if(!config.migrate){
|
|
//BAIL!
|
|
return;
|
|
}
|
|
|
|
try{
|
|
//For each toke log
|
|
for(const tokeLog of rawLegacyTokes){
|
|
//Split and iterate toke log by new line
|
|
for(const tokeLine of tokeLog.split('\n')){
|
|
//Ensure line is a valid toke log line (this will break if your tokes take place after 12:46:40PM on Nov 20th 2286... Or before 21:46:40 Sep 08 2001)
|
|
//You'll probably want to have migrated from cytube/fore.st to canopy by then :)
|
|
//Also splits tokers array off for easier processing
|
|
const splitToke = tokeLine.match(/^\[.+\]|,[0-9]{1,4},|[0-9]{13}$/g)
|
|
if(splitToke != null){
|
|
|
|
//Create empty tokers map
|
|
const toke = new Map();
|
|
|
|
//Add qoutes around strings in the tokers line
|
|
let tokersLine = splitToke[0].replaceAll('[', '["');
|
|
tokersLine = tokersLine.replaceAll(']','"]');
|
|
tokersLine = tokersLine.replaceAll(',','","');
|
|
|
|
//Force feed doctored line into the JSON parser, and iterate by the array it shits out
|
|
for(const toker of JSON.parse(tokersLine)){
|
|
toke.set(toker,"Legacy Tokes");
|
|
}
|
|
|
|
const date = new Date(Number(splitToke[2]));
|
|
|
|
//Push toke on to statDB
|
|
this.create({
|
|
toke,
|
|
date
|
|
});
|
|
|
|
console.log(`Adding legacy toke: ${tokersLine} from: ${date.toLocaleString()}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log("Legacy tokes commited to server-wide database statistics file!");
|
|
}catch(err){
|
|
return loggerUtils.localExceptionHandler(err);
|
|
}
|
|
}
|
|
|
|
tokeSchema.statics.dropLegacyTokes = async function(){
|
|
try{
|
|
//If legacy toke dropping is disabled or migration is enabled
|
|
if(!config.dropLegacyTokes || config.migrate){
|
|
//return
|
|
return;
|
|
}
|
|
//Pull tokes from DB
|
|
const oldTokes = await this.find();
|
|
|
|
//Create temporary toke array
|
|
const tokes = [];
|
|
|
|
//Nuke the toke collection
|
|
await this.deleteMany({});
|
|
|
|
//Iterate through server toke history
|
|
for(const toke of oldTokes){
|
|
//If it's not a legacy toke or a dupe
|
|
if(Array.from(toke.toke)[0][1] != "Legacy Tokes"){
|
|
//Re-add it to the database, scraping out the old ID
|
|
this.create({
|
|
toke: toke.toke,
|
|
date: toke.date
|
|
});
|
|
}
|
|
}
|
|
|
|
//Tell of our success
|
|
console.log("Removed migration tokes!");
|
|
}catch(err){
|
|
return loggerUtils.localExceptionHandler(err);
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = mongoose.model("toke", tokeSchema); |