From 56782fc2d32c41b9d48363a87c5ea7709043171a Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Tue, 6 Aug 2024 22:11:21 +0200 Subject: [PATCH] Added init --- admin/package.json | 3 +- admin/src/App.tsx | 23 +++++------ admin/src/components/DatetimeInput.tsx | 22 +++++++++++ admin/src/main.tsx | 2 + admin/src/pages/AuthorCleanupScreen.tsx | 52 +++++++++++++++++++++++++ pnpm-lock.yaml | 18 +++++++++ src/node/db/AuthorManager.ts | 5 +++ src/node/hooks/express/adminsettings.ts | 29 +++++++++++++- 8 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 admin/src/components/DatetimeInput.tsx create mode 100644 admin/src/pages/AuthorCleanupScreen.tsx diff --git a/admin/package.json b/admin/package.json index ffa62adad..8aca4e3cb 100644 --- a/admin/package.json +++ b/admin/package.json @@ -11,7 +11,8 @@ "preview": "vite preview" }, "dependencies": { - "@radix-ui/react-switch": "^1.1.0" + "@radix-ui/react-switch": "^1.1.0", + "react-day-picker": "^9.0.7" }, "devDependencies": { "@radix-ui/react-dialog": "^1.1.1", diff --git a/admin/src/App.tsx b/admin/src/App.tsx index b3238ef9a..4bf430ff3 100644 --- a/admin/src/App.tsx +++ b/admin/src/App.tsx @@ -6,7 +6,7 @@ import {NavLink, Outlet, useNavigate} from "react-router-dom"; import {useStore} from "./store/store.ts"; import {LoadingScreen} from "./utils/LoadingScreen.tsx"; import {Trans, useTranslation} from "react-i18next"; -import {Cable, Construction, Crown, NotepadText, Wrench, PhoneCall} from "lucide-react"; +import {Cable, Construction, Crown, NotepadText, Wrench, PhoneCall,Paintbrush } from "lucide-react"; const WS_URL = import.meta.env.DEV? 'http://localhost:9001' : '' export const App = ()=> { @@ -93,18 +93,19 @@ export const App = ()=> {

Etherpad

- + -
- +
+
} diff --git a/admin/src/components/DatetimeInput.tsx b/admin/src/components/DatetimeInput.tsx new file mode 100644 index 000000000..db638d083 --- /dev/null +++ b/admin/src/components/DatetimeInput.tsx @@ -0,0 +1,22 @@ +import { DayPicker } from "react-day-picker"; +import "react-day-picker/style.css"; +import {FC} from "react"; + +type DatetimeInputProps = { + value: Date, + onChange: (value: Date) => void +} + +export const DatetimeInput:FC = ({ + onChange,value + })=>{ + + return ( + + ); +} diff --git a/admin/src/main.tsx b/admin/src/main.tsx index 5efc26de6..47f058d08 100644 --- a/admin/src/main.tsx +++ b/admin/src/main.tsx @@ -13,6 +13,7 @@ import i18n from "./localization/i18n.ts"; import {PadPage} from "./pages/PadPage.tsx"; import {ToastDialog} from "./utils/Toast.tsx"; import {ShoutPage} from "./pages/ShoutPage.tsx"; +import {AuthorCleanupScreen} from "./pages/AuthorCleanupScreen.tsx"; const router = createBrowserRouter(createRoutesFromElements( <>}> @@ -22,6 +23,7 @@ const router = createBrowserRouter(createRoutesFromElements( }/> }/> }/> + }/> }/> diff --git a/admin/src/pages/AuthorCleanupScreen.tsx b/admin/src/pages/AuthorCleanupScreen.tsx new file mode 100644 index 000000000..a68546952 --- /dev/null +++ b/admin/src/pages/AuthorCleanupScreen.tsx @@ -0,0 +1,52 @@ +import {useState} from "react"; +import {DatetimeInput} from "../components/DatetimeInput.tsx"; +import {IconButton} from "../components/IconButton.tsx"; +import {PaintRoller} from "lucide-react"; +import * as Dialog from "@radix-ui/react-dialog"; +import {useStore} from "../store/store.ts"; + +export const AuthorCleanupScreen = ()=>{ + const [cleanUpBefore, setCleanUpBefore] = useState() + const [openDialog, setOpenDialog] = useState(false) + const settingsSocket = useStore(state=>state.settingsSocket) + + + const deleteAuthorsBefore = (date: Date)=>{ + settingsSocket?.emit('deleteAuthorsBefore', date.getTime()) + } + + return
+ + + +
+
+
+ Delete all authors before {cleanUpBefore?.toLocaleString()}? +
+
+ + +
+
+
+
+
+

Author cleanup

+ +
+ setCleanUpBefore(c)} value={cleanUpBefore!}/> + + {cleanUpBefore&&

All authors before {cleanUpBefore.toLocaleString()} will be deleted

} + + } title="Delete authors?" onClick={()=>{ + setOpenDialog(true) + }}/> +
+
+} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1b4b8865a..243432091 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,6 +27,9 @@ importers: '@radix-ui/react-switch': specifier: ^1.1.0 version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-day-picker: + specifier: ^9.0.7 + version: 9.0.7(react@18.3.1) devDependencies: '@radix-ui/react-dialog': specifier: ^1.1.1 @@ -2185,6 +2188,9 @@ packages: resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} engines: {node: '>= 0.4'} + date-fns@3.6.0: + resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + date-format@4.0.14: resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} engines: {node: '>=4.0'} @@ -3712,6 +3718,11 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + react-day-picker@9.0.7: + resolution: {integrity: sha512-JTa9vhhfxWSVfhzTFG5rEXynsDb6zi3NG+0EHbs5JBZuGFlNbg8qyagh9YtIR1ccGThwY339CAqFOH6op55omw==} + peerDependencies: + react: '>=16.8.0' + react-dom@18.3.1: resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: @@ -6333,6 +6344,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.1 + date-fns@3.6.0: {} + date-format@4.0.14: {} debug@2.6.9: @@ -8157,6 +8170,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + react-day-picker@9.0.7(react@18.3.1): + dependencies: + date-fns: 3.6.0 + react: 18.3.1 + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 diff --git a/src/node/db/AuthorManager.ts b/src/node/db/AuthorManager.ts index 2f4e7d751..dd8f848b6 100644 --- a/src/node/db/AuthorManager.ts +++ b/src/node/db/AuthorManager.ts @@ -297,6 +297,11 @@ exports.addPad = async (authorID: string, padID: string) => { await db.set(`globalAuthor:${authorID}`, author); }; + +exports.listAllAuthorsKeys = async () => { + return await db.findKeys('globalAuthor:*'); +} + /** * Removes a pad from the list of contributions * @param {String} authorID The id of the author diff --git a/src/node/hooks/express/adminsettings.ts b/src/node/hooks/express/adminsettings.ts index 63d901f21..f5f6738c6 100644 --- a/src/node/hooks/express/adminsettings.ts +++ b/src/node/hooks/express/adminsettings.ts @@ -13,7 +13,7 @@ const settings = require('../../utils/Settings'); const UpdateCheck = require('../../utils/UpdateCheck'); const padManager = require('../../db/PadManager'); const api = require('../../db/API'); - +const authorManager = require('../../db/AuthorManager'); const queryPadLimit = 12; const logger = log4js.getLogger('adminSettings'); @@ -252,6 +252,33 @@ exports.socketio = (hookName: string, {io}: any) => { } }) + socket.on('deleteAuthorsBefore', async (time: number) => { + const allGlobalAuthors = await authorManager.listAllAuthorsKeys() + const authorId = authorManager.createAuthor("inactive_user") + const {padIDs} = await padManager.listAllPads() + + for (const authorKey of allGlobalAuthors) { + const authorId = authorKey.split(":")[1] + console.log("global Authors are",allGlobalAuthors) + const author = await authorManager.getAuthor(authorId) + console.log("Author is", author) + if (author.timestamp < time) { + if ("padIDs" in author) { + for (const padId of Object.keys(author.padIDs)) { + const pad = padManager.getPad(padId) as PadType + console.log("Pad is", pad) + const headRevision = pad.head + for (let i = 0; i < headRevision; i++) { + const rev = await pad.getRevision(i) + console.log("Revision is", rev) + } + } + } + } + } + }) + + socket.on('restartServer', async () => { logger.info('Admin request to restart server through a socket on /admin/settings'); settings.reloadSettings();