Compare commits
3 Commits
60ce765193
...
642cd67678
Author | SHA1 | Date |
---|---|---|
adueck | 642cd67678 | |
adueck | 25c17bb0bc | |
adueck | dd0ac0a27e |
|
@ -1,47 +1,104 @@
|
||||||
|
#!/usr/bin/env tsx
|
||||||
|
|
||||||
// a script for making edits to the couchdb records - run with tsnode
|
// a script for making edits to the couchdb records - run with tsnode
|
||||||
|
|
||||||
import Nano from "nano";
|
import Nano from "nano";
|
||||||
import { DocumentInsertResponse } from "nano";
|
import { DocumentInsertResponse } from "nano";
|
||||||
import env from "./src/lib/env-vars";
|
import env from "./src/lib/env-vars";
|
||||||
import * as T from "../website/src/types/account-types";
|
import * as T from "../website/src/types/account-types";
|
||||||
import { getAllLingdocsUsers, getLingdocsUser, insertLingdocsUser } from "./src/lib/couch-db";
|
import {
|
||||||
|
getAllLingdocsUsers,
|
||||||
|
getLingdocsUser,
|
||||||
|
insertLingdocsUser,
|
||||||
|
} from "./src/lib/couch-db";
|
||||||
|
|
||||||
const nano = Nano(env.couchDbURL);
|
const nano = Nano(env.couchDbURL);
|
||||||
const usersDb = nano.db.use("lingdocs-users");
|
// const usersDb = nano.db.use("lingdocs-users");
|
||||||
const userDbPrefix = "userdb-";
|
// const userDbPrefix = "userdb-";
|
||||||
|
|
||||||
function processAPIResponse(user: T.LingdocsUser, response: DocumentInsertResponse): T.LingdocsUser | undefined {
|
function processAPIResponse(
|
||||||
|
user: T.LingdocsUser,
|
||||||
|
response: DocumentInsertResponse
|
||||||
|
): T.LingdocsUser | undefined {
|
||||||
if (response.ok !== true) return undefined;
|
if (response.ok !== true) return undefined;
|
||||||
return {
|
return {
|
||||||
...user,
|
...user,
|
||||||
_id: response.id,
|
_id: response.id,
|
||||||
_rev: response.rev,
|
_rev: response.rev,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
const users = await getAllLingdocsUsers();
|
const users = await getAllLingdocsUsers();
|
||||||
users.forEach(async (user) => {
|
const usersWDbs = users.filter((x) => x.level !== "basic");
|
||||||
if (user.tests.length) {
|
const paidUsersEmails: string[] = [];
|
||||||
await insertLingdocsUser({
|
for (let user of usersWDbs) {
|
||||||
...user,
|
// if (!user.docs.length) return;
|
||||||
tests: removeRedundant(user.tests),
|
// const u = user.docs[0];
|
||||||
});
|
// await authUsers.destroy(u._id, u._rev);
|
||||||
|
if (user.level === "basic") {
|
||||||
|
throw new Error("");
|
||||||
}
|
}
|
||||||
})
|
process.stdout.write(`Checking for db for ${user.name} - ${user.email}...`);
|
||||||
|
const userDb = nano.db.use(user.wordlistDbName);
|
||||||
|
try {
|
||||||
|
// await userDb.insert(
|
||||||
|
// {
|
||||||
|
// admins: {
|
||||||
|
// names: [user.userId],
|
||||||
|
// roles: ["_admin"],
|
||||||
|
// },
|
||||||
|
// members: {
|
||||||
|
// names: [user.userId],
|
||||||
|
// roles: ["_admin"],
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// "_security"
|
||||||
|
// );
|
||||||
|
const { admins, members } = await userDb.get("_security");
|
||||||
|
if (
|
||||||
|
admins?.names?.[0] === user.userId &&
|
||||||
|
members?.names?.[0] === user.userId
|
||||||
|
) {
|
||||||
|
console.log("✅");
|
||||||
|
} else {
|
||||||
|
console.log("check", user.wordlistDbName);
|
||||||
|
console.log("uid", user.userId);
|
||||||
|
console.log("RR");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// console.log(e);
|
||||||
|
console.log("❌");
|
||||||
|
console.log(`needs ${user.wordlistDbName} - ${user.userId}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const allDbs = await nano.db.list();
|
||||||
|
const strayDbs = allDbs.reduce<string[]>((acc, curr) => {
|
||||||
|
if (!curr.startsWith("userdb-")) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!usersWDbs.some((x) => x.level !== "basic" && x.wordlistDbName === curr)
|
||||||
|
) {
|
||||||
|
return [...acc, curr];
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
console.log("STRAY USERDBS");
|
||||||
|
console.log(strayDbs);
|
||||||
return "done";
|
return "done";
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeRedundant(tests: T.TestResult[]): T.TestResult[] {
|
// function removeRedundant(tests: T.TestResult[]): T.TestResult[] {
|
||||||
if (tests.length === 0) return tests;
|
// if (tests.length === 0) return tests;
|
||||||
const first = tests[0];
|
// const first = tests[0];
|
||||||
const rest = tests.slice(1);
|
// const rest = tests.slice(1);
|
||||||
const redundancies = rest.filter(x => ((x.id === first.id)) && (x.done === first.done));
|
// const redundancies = rest.filter(x => ((x.id === first.id)) && (x.done === first.done));
|
||||||
return redundancies.length < 2
|
// return redundancies.length < 2
|
||||||
? [first, ...removeRedundant(rest)]
|
// ? [first, ...removeRedundant(rest)]
|
||||||
: removeRedundant(rest);
|
// : removeRedundant(rest);
|
||||||
}
|
// }
|
||||||
|
|
||||||
main().then(res => {
|
main().then((res) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
});
|
});
|
||||||
|
|
|
@ -183,6 +183,22 @@ export async function addCouchDbAuthUser(
|
||||||
password,
|
password,
|
||||||
};
|
};
|
||||||
await usersDb.insert(authUser);
|
await usersDb.insert(authUser);
|
||||||
|
await nano.db.create(userDbName);
|
||||||
|
const userDb = nano.db.use(userDbName);
|
||||||
|
await userDb.insert(
|
||||||
|
{
|
||||||
|
// @ts-ignore
|
||||||
|
admins: {
|
||||||
|
names: [uuid],
|
||||||
|
roles: ["_admin"],
|
||||||
|
},
|
||||||
|
members: {
|
||||||
|
names: [uuid],
|
||||||
|
roles: ["_admin"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"_security"
|
||||||
|
);
|
||||||
return { password, userDbName };
|
return { password, userDbName };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import {
|
import { getAudioAttachment } from "../lib/wordlist-database";
|
||||||
getAudioAttachment,
|
|
||||||
} from "../lib/wordlist-database";
|
|
||||||
import { WordlistWord } from "../types/dictionary-types";
|
import { WordlistWord } from "../types/dictionary-types";
|
||||||
|
|
||||||
export function AudioPlayButton({ word }: { word: WordlistWord }) {
|
export function AudioPlayButton({ word }: { word: WordlistWord }) {
|
||||||
const [src, setSrc] = useState<string | undefined>(undefined);
|
const [src, setSrc] = useState<string | undefined>(undefined);
|
||||||
const [type, setType] = useState<string | undefined>(undefined);
|
const [type, setType] = useState<string | undefined>(undefined);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getAudioAttachment(word).then((audio) => {
|
getAudioAttachment(word)
|
||||||
|
.then((audio) => {
|
||||||
if (!audio) return;
|
if (!audio) return;
|
||||||
// @ts-ignore // TODO: FIX THIS!
|
// @ts-ignore // TODO: FIX THIS!
|
||||||
const src = URL.createObjectURL(audio);
|
const src = URL.createObjectURL(audio);
|
||||||
|
@ -25,13 +24,12 @@ export function AudioPlayButton({ word }: { word: WordlistWord }) {
|
||||||
return () => {
|
return () => {
|
||||||
URL.revokeObjectURL(src);
|
URL.revokeObjectURL(src);
|
||||||
};
|
};
|
||||||
}).catch(console.error);
|
})
|
||||||
|
.catch(console.error);
|
||||||
}, [word]);
|
}, [word]);
|
||||||
return (
|
return (
|
||||||
<div className="text-center mb-3">
|
<div className="text-center mb-3">
|
||||||
<audio controls>
|
<audio controls>{src && <source src={src} type={type} />}</audio>
|
||||||
{src && <source src={src} type={type} />}
|
|
||||||
</audio>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue