UNPKG

lemmy-bot

Version:

A bot API for Lemmy, the fediverse link aggregator.

170 lines (169 loc) 6.35 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.setupDB = exports.useDatabaseFunctions = void 0; const fs_1 = require("fs"); const promises_1 = require("fs/promises"); const path_1 = __importDefault(require("path")); const tableTypes = [ 'comments', 'posts', 'messages', 'registrations', 'mentions', 'replies', 'comments', 'commentReports', 'postReports', 'messageReports', 'removedPosts', 'lockedPosts', 'featuredPosts', 'removedComments', 'removedCommunities', 'communityBans', 'modsAddedToCommunities', 'modsTransferredToCommunities', 'adminsAdded', 'siteBans' ]; const getRow = (db, id, table) => new Promise((resolve, reject) => { db.get(`SELECT id, reprocessTime FROM ${table} WHERE id=?;`, id, (err, row) => { if (err) { reject(err); } else { resolve({ exists: !!row, reprocessTime: row && row.reprocessTime ? new Date(row.reprocessTime) : null }); } }); }); const upsert = (db, id, table, minutesUntilReprocess) => new Promise((resolve, reject) => { db.run(`INSERT INTO ${table} (id, reprocessTime) VALUES ($id, $reprocessTime) ON CONFLICT (id) DO UPDATE SET reprocessTime=$reprocessTime;`, { $id: id, $reprocessTime: minutesUntilReprocess && minutesUntilReprocess > 0 ? Date.now() + 1000 * 60 * minutesUntilReprocess : null }, (err) => { if (err) { reject(err); } else { resolve(); } }); }); const tableFuncMap = new Map(tableTypes.map((tt) => [ tt, { get: (db, id) => getRow(db, id, tt), upsert: (db, id, minutesUntilReprocess) => upsert(db, id, tt, minutesUntilReprocess) } ])); let sqlite = undefined; const useDatabase = (doStuffWithDB, dbPath) => __awaiter(void 0, void 0, void 0, function* () { if (sqlite === null) { return; } if (!sqlite) { try { const sqliteImport = yield Promise.resolve().then(() => __importStar(require('sqlite3'))); sqlite = sqliteImport.verbose(); } catch (_a) { console.warn('sqlite3 optional dependency is not available. This can cause your bot to respond to the same event more than once (e.g. replying multiple times to the same post). If you have intentionally chosen to omit the use of sqlite, ignore this message.'); return; } } let db; if (!dbPath) { db = new sqlite.Database(':memory:'); } else { db = new sqlite.Database(dbPath); } yield doStuffWithDB(db); if (dbPath) { db.close(); } }); const useDatabaseFunctions = (table, doStuff, dbPath) => useDatabase((db) => __awaiter(void 0, void 0, void 0, function* () { const { get, upsert } = tableFuncMap.get(table); yield doStuff({ get: (id) => get(db, id), upsert: (id, minutesUntilReprocess) => upsert(db, id, minutesUntilReprocess) }); }), dbPath); exports.useDatabaseFunctions = useDatabaseFunctions; const createTable = (db, table) => { db.run(`CREATE TABLE IF NOT EXISTS ${table} (id INTEGER PRIMARY KEY, reprocessTime INTEGER) WITHOUT ROWID;`); db.run(`CREATE UNIQUE INDEX IF NOT EXISTS idx_${table}_id ON ${table} (id);`); }; const setupDB = (log, dbPath) => __awaiter(void 0, void 0, void 0, function* () { if (dbPath && !(0, fs_1.existsSync)(dbPath)) { log('Creating database file'); try { yield (0, promises_1.mkdir)(path_1.default.dirname(dbPath), { recursive: true }); yield (0, promises_1.writeFile)(dbPath, ''); } catch (error) { console.log('Error making database file: ' + error); process.exit(1); } } yield useDatabase((db) => __awaiter(void 0, void 0, void 0, function* () { db.serialize(() => { log('Initializing DB'); for (const table of tableTypes) { createTable(db, table); } }); }), dbPath); }); exports.setupDB = setupDB;