diff --git a/_migrate/bands.ts b/_migrate/bands.ts new file mode 100644 index 0000000..9916704 --- /dev/null +++ b/_migrate/bands.ts @@ -0,0 +1,32 @@ +import { MongoClient } from "mongodb"; +import mongoose from "mongoose"; +import { uri, olduri } from "../lib/dbconfig"; + +import { Band } from "../models/band"; + +const cli = new MongoClient(olduri); +export default async function () { + try { + console.debug(olduri) + await cli.connect() + await mongoose.connect(uri).then(() => console.log("connect'd")); + + const db = cli.db("rockfic_old") + const col = db.collection("bands"); + const cursor = col.find({}); + for await(const s of cursor) { + // console.debug(s.name) + const nb = new Band({ + _id: s._id, + name: s.name, + locked: s.locked, + characters: s.characters + }) + await nb.save() + } + } catch(e) { + console.error(e) + } finally { + return 0 + } +} diff --git a/_migrate/challenge.ts b/_migrate/challenge.ts new file mode 100644 index 0000000..bfeeeb8 --- /dev/null +++ b/_migrate/challenge.ts @@ -0,0 +1,34 @@ +import { Challenge } from "../models/challenges/gen"; +import { MongoClient } from "mongodb"; +import mongoose from "mongoose"; +import { uri, olduri } from "../lib/dbconfig"; + +import { Band } from "../models/band"; + +const cli = new MongoClient(olduri); +export default async function () { + try { + await cli.connect() + + await mongoose.connect(uri).then(() => console.log("connect'd")); + + const db = cli.db("rockfic_old") + const col = db.collection("challenges"); + const cursor = col.find({}); + for await(const s of cursor) { + const nc = new Challenge({ + _id: s.chall_id, active: s.isActive, + color: s.color.toLowerCase(), + allowMultiple: s.allowMultiple, + name: s.name, + description: s.description, + deadline: s.deadline + }) + await nc.save() + } + } catch(e) { + console.error(e) + } finally { + return 0 + } +} diff --git a/_migrate/ficmas.ts b/_migrate/ficmas.ts new file mode 100644 index 0000000..16195f4 --- /dev/null +++ b/_migrate/ficmas.ts @@ -0,0 +1,36 @@ +import { Ficmas } from "../models/challenges/ficmas"; +import { MongoClient } from "mongodb"; +import mongoose from "mongoose"; +import { uri, olduri } from "../lib/dbconfig"; + +import { Band } from "../models/band"; + +const cli = new MongoClient(olduri); +export default async function () { + try { + await cli.connect() + + await mongoose.connect(uri).then(() => console.log("connect'd")); + + const db = cli.db("rockfic_old") + const col = db.collection("ficmas_wishes"); + const cursor = col.find({}); + for await(const s of cursor) { + const bandList = await Band.find({name: {$in: s.bands}}) + const f = new Ficmas({ + _id: s.wishid, + bands: bandList.map(a => a._id), + year: s.year, + kink: s.kink, + anniversary: s.isAnniversary, + wisher: s.wisher, + relationship: s.relationship + }) + await f.save(); + } + } catch(e) { + console.error(e) + } finally { + return 0 + } +} diff --git a/_migrate/index.ts b/_migrate/index.ts new file mode 100644 index 0000000..7807de4 --- /dev/null +++ b/_migrate/index.ts @@ -0,0 +1,23 @@ +import * as dotenv from "dotenv"; +dotenv.config({path: "../.env.local"}); + +import band from "./bands"; +import ficmas from "./ficmas"; +import challenge from "./challenge"; +import story from "./stories"; +import user from "./users" + +async function main() { + try { + console.debug(process.env.NODE_ENV) + await band() + await ficmas() + await challenge() + await story() + await user() + } finally { + process.exit() + } +} + +main().catch(e => console.error(e)) diff --git a/_migrate/stories.ts b/_migrate/stories.ts new file mode 100644 index 0000000..b1382ab --- /dev/null +++ b/_migrate/stories.ts @@ -0,0 +1,65 @@ +import { IStory, Story } from "../models/stories"; +import { MongoClient } from "mongodb"; +import mongoose from "mongoose"; +import { uri, olduri } from "../lib/dbconfig"; + +import { Band } from "../models/band"; + +const cli = new MongoClient(olduri); + +export default async function () { + try { + await cli.connect() + + await mongoose.connect(uri).then(() => console.log("connect'd")); + + const db = cli.db("rockfic_old") + const col = db.collection("stories"); + const cursor = col.find({}); + for await(const s of cursor) { + const feec = await db.collection("ficmas_wishes").findOne({_id: s.ficmas}) + const chall = await db.collection("challenges").findOne({_id: s.challenge}) + const nso: any & IStory = { + ...s, + chapters: [], + views: s.viewcount, + reviews: s.numreviews, + ficmas: feec?.wishid || null, + challenge: chall?.chall_id || null, + _id: s.id + } + delete nso.viewcount; + delete nso.numchapters; + delete nso.numreviews; + const ns = new Story(nso) + let idx = 1; + for (const c of s.chapters) { + const bandList = await Band.find({name: {$in: c.bands}}) + ns.chapters.push({ + title: c.chaptertitle, + index: idx, + id: c.chapterid, + words: isNaN(parseInt(c.words)) ? 0 : parseInt(c.words), + notes: c.notes, + summary: c.summary, + genre: c.genre, + bands: bandList.map(a => a._id), + characters: c.characters, + relationships: c.relationships.map(a => a.split("/")), + hidden: c.hidden, + posted: c.posted, + nsfw: c.rating.toLowerCase() == "adult", + loggedInOnly: c.loggedinOnly, + reviews: 0 + // TODO: correct this count in a later script :| + }) + idx++; + } + await ns.save() + } + } catch(e) { + console.error(e) + } finally { + return 0 + } +} diff --git a/_migrate/tsconfig.json b/_migrate/tsconfig.json new file mode 100644 index 0000000..d772867 --- /dev/null +++ b/_migrate/tsconfig.json @@ -0,0 +1,107 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": false /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */, + "paths": { + "~": [".."], + "~/*": ["../*"] + } + } +} diff --git a/_migrate/users.ts b/_migrate/users.ts new file mode 100644 index 0000000..33e0ac7 --- /dev/null +++ b/_migrate/users.ts @@ -0,0 +1,82 @@ +import { IStory, Story } from "../models/stories"; +import { MongoClient } from "mongodb"; +import mongoose from "mongoose"; +import { uri, olduri } from "../lib/dbconfig"; + +import { Band } from "../models/band"; +import { User } from "../models/user"; + +const cli = new MongoClient(olduri); + +async function meep() { + try { + await cli.connect() + await mongoose.connect(uri).then(() => console.log("connect'd")); + + const db = cli.db("rockfic_old") + const col = db.collection("users"); + const cursor = col.find({}); + for await (const s of cursor) { + const nu = new User({ + _id: s._id, + username: s.username, + email: s.email, + auth: { + emailVerified: s.emailIsVerified, + activationKey: s.activationkey, + passwordResetToken: s.passwordresettoken, + }, + password: s.password, + ts: { + created: s.createdAt, + updated: s.updatedAt + }, + ipLog: [{ + lastAccess: s.lastvisit, + ip: s.ip_address + }], + lastLogin: s.lastvisit, + lastvisit: s.lastvisit, + profile: { + avatar: s.profile_metadata.avatar, + isAdmin: s.isAdmin, + nightMode: s.profile_metadata.isNightMode, + bio: s.profile_metadata.bio, + location: s.profile_metadata.location, + occupation: s.profile_metadata.occupation, + website: s.profile_metadata.website, + blog: s.profile_metadata.blog, + views: s.profile_metadata.pageviews, + lastWhere: s.profile_metadata.isWhere, + hidden: s.profile_metadata.isStatusHidden + }, + biffno: { + years: s.biffnoYears, + wins: s.biffnoWins + }, + favs: { + authors: s.favs.favauthors, + stories: (await db.collection("stories").find({_id: {$in: s.favs.favstories}}).toArray()).map(a => a.id) + }, + subscriptions: { + authors: s.subscriptions.author_subscriptions, + band_subscriptions: (await Band.find({name: {$in: s.subscriptions.band_subscriptions}})).map(a => a._id), + stories: (await db.collection("stories").find({_id: {$in: s.subscriptions.story_subscriptions}}).toArray()).map(a => a.id) + }, + hiddenBands: (await Band.find({name: {$in: s.hidden_bands}})).map(a => a._id), + hiddenAuthors: s.hidden_authors, + blocked: s.blocklist, + sessionId: s.sessionId, + banned: s.banned, + quickMenuConfig: [] + }) + await nu.save() + } + } finally { + return 0 + } +} + +// meep().then(() => process.exit()) + +export default meep