Skip to content

Commit

Permalink
Change vault instance data structure
Browse files Browse the repository at this point in the history
  • Loading branch information
Lendruk committed Jun 10, 2024
1 parent c221c77 commit 735079c
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 75 deletions.
7 changes: 2 additions & 5 deletions backend/src/db/VaultController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import * as vaultSchema from './vault/schema';

export type VaultDb = BetterSQLite3Database<typeof vaultSchema>;

export type VaultInstance = {
vault: Vault;
db: VaultDb;
}
export type VaultInstance = Vault & { db: VaultDb };

export class VaultController {
public static vaults: Map<string, VaultInstance> = new Map();
Expand All @@ -19,7 +16,7 @@ export class VaultController {
const newDb = new Database(`${vault.path}/vault.sqlite`);
const db = drizzle(newDb, { schema: vaultSchema });
await migrate(db, { migrationsFolder: 'migrations/vault' });
this.vaults.set(vault.id, { vault, db });
this.vaults.set(vault.id, { ...vault, db });
}

public static getVault(vaultId: string) {
Expand Down
15 changes: 8 additions & 7 deletions backend/src/db/master/schema.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { InferSelectModel } from "drizzle-orm";
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
import type { InferSelectModel } from 'drizzle-orm';
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core';

export const vaults = sqliteTable("vaults", {
id: text("id").primaryKey(),
name: text("name"),
path: text("path").notNull(),
createdAt: integer("createdAt").notNull().default(Date.now()),
export const vaults = sqliteTable('vaults', {
id: text('id').primaryKey(),
name: text('name'),
path: text('path').notNull(),
createdAt: integer('createdAt').notNull().default(Date.now()),
hasInstalledSD: integer('has_installed_sd').notNull().default(0)
});

export type Vault = InferSelectModel<typeof vaults>;
6 changes: 3 additions & 3 deletions backend/src/db/vault/db.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Database from 'better-sqlite3';
import { drizzle } from 'drizzle-orm/better-sqlite3';
import * as schema from './schema'
const sqlite = new Database("vault.sqlite");
import * as schema from './schema';
const sqlite = new Database('vault.sqlite');
export const db = drizzle(sqlite, { schema });

console.log("db init");
console.log('db init');
58 changes: 28 additions & 30 deletions backend/src/routes/images/createImage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { FastifyReply, RouteOptions } from 'fastify';
import { Request } from '../../types/Request';
import { db } from '../../db/vault/db';
import { TagTableSchema, mediaItems, tags as tagsTable, tagsToMediaItems } from '../../db/vault/schema';
import { randomUUID } from 'crypto';
import path from 'path';
Expand All @@ -9,39 +8,38 @@ import { eq } from 'drizzle-orm';
import { checkVault } from '../../hooks/checkVault';

const createImage = async (request: Request, reply: FastifyReply) => {
const vaultInstance = request.vault;

if(!vaultInstance) {
return reply.status(400).send('No vault provided');
}

const { vault } = vaultInstance;

const body = request.body as { image: string, tags: TagTableSchema[] };
const imageBase64 = body.image;
const tags: TagTableSchema[] = body.tags;

const id = randomUUID();
const imageBuffer = Buffer.from(imageBase64.replace(/^data:image\/\w+;base64,/, ""), 'base64');
await fs.writeFile(path.join(vault.path, "media", 'images', `${id}.png`), imageBuffer);
// TODO - Use fs.stat instead
const fileSize = imageBuffer.byteLength;
console.log(id);
const mediaItem = await db.insert(mediaItems).values({ fileName: id, extension: "png", type: "image", fileSize, createdAt: Date.now() }).returning();

if(tags && tags.length > 0) {
await db.insert(tagsToMediaItems).values(tags.map(tag => ({ tagId: tag.id, mediaItemId: mediaItem[0].id }))).returning();
for(const tag of tags) {
await db.update(tagsTable).set({ mediaCount: tag.mediaCount + 1 }).where(eq(tagsTable.id, tag.id));
}
}

return reply.send({ message: "Image registered", id });
const vault = request.vault;

if(!vault) {
return reply.status(400).send('No vault provided');
}

const { db } = vault;
const body = request.body as { image: string, tags: TagTableSchema[] };
const imageBase64 = body.image;
const tags: TagTableSchema[] = body.tags;

const id = randomUUID();
const imageBuffer = Buffer.from(imageBase64.replace(/^data:image\/\w+;base64,/, ''), 'base64');
await fs.writeFile(path.join(vault.path, 'media', 'images', `${id}.png`), imageBuffer);
// TODO - Use fs.stat instead
const fileSize = imageBuffer.byteLength;
console.log(id);
const mediaItem = await db.insert(mediaItems).values({ fileName: id, extension: 'png', type: 'image', fileSize, createdAt: Date.now() }).returning();

if(tags && tags.length > 0) {
await db.insert(tagsToMediaItems).values(tags.map(tag => ({ tagId: tag.id, mediaItemId: mediaItem[0].id }))).returning();
for(const tag of tags) {
await db.update(tagsTable).set({ mediaCount: tag.mediaCount + 1 }).where(eq(tagsTable.id, tag.id));
}
}

return reply.send({ message: 'Image registered', id });
};

export default {
method: 'POST',
url: '/images',
handler: createImage,
onRequest: checkVault,
onRequest: checkVault,
} as RouteOptions;
20 changes: 10 additions & 10 deletions backend/src/routes/images/getImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@ import * as fs from 'fs/promises';
import { VaultController } from '../../db/VaultController';

const getImageThumbnail = async (request: FastifyRequest, reply: FastifyReply) => {
const params = request.params as { fileName: string; vaultId: string };
const params = request.params as { fileName: string; vaultId: string };

const vaultId = params.vaultId;
if(!vaultId) {
return reply.status(400).send("Vault ID is required");
}
const vaultId = params.vaultId;
if(!vaultId) {
return reply.status(400).send('Vault ID is required');
}

const fileName = params.fileName;
const { vault } = VaultController.getVault(vaultId);
const imagePath = path.join(vault.path, "media", 'images', `${fileName}`);
const image = await fs.readFile(imagePath);
const fileName = params.fileName;
const vault = VaultController.getVault(vaultId);
const imagePath = path.join(vault.path, 'media', 'images', `${fileName}`);
const image = await fs.readFile(imagePath);

return reply.header('Content-Type', 'image/jpg').send(image);
return reply.header('Content-Type', 'image/jpg').send(image);
};

export default {
Expand Down
20 changes: 10 additions & 10 deletions backend/src/routes/images/getImageThumbnail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ import * as fs from 'fs/promises';
import { VaultController } from '../../db/VaultController';

const getImageThumbnail = async (request: FastifyRequest, reply: FastifyReply) => {
const params = request.params as { fileName: string; vaultId: string };
const params = request.params as { fileName: string; vaultId: string };

const vaultId = params.vaultId;
if(!vaultId) {
return reply.status(400).send("Vault ID is required");
}
const vaultId = params.vaultId;
if(!vaultId) {
return reply.status(400).send('Vault ID is required');
}

const fileName = params.fileName;
const { vault } = VaultController.getVault(vaultId);
const fileName = params.fileName;
const vault = VaultController.getVault(vaultId);

const imagePath = path.join(vault.path, 'media', 'images', '.thumb', `${fileName}`);
const image = await fs.readFile(imagePath);
const imagePath = path.join(vault.path, 'media', 'images', '.thumb', `${fileName}`);
const image = await fs.readFile(imagePath);

return reply.header('Content-Type', 'image/jpg').send(image);
return reply.header('Content-Type', 'image/jpg').send(image);
};

export default {
Expand Down
6 changes: 3 additions & 3 deletions backend/src/routes/images/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import createImage from "./createImage";
import getImage from "./getImage";
import getImageThumbnail from "./getImageThumbnail";
import createImage from './createImage';
import getImage from './getImage';
import getImageThumbnail from './getImageThumbnail';

export default [createImage, getImage, getImageThumbnail];
6 changes: 3 additions & 3 deletions backend/src/routes/media/createMediaItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ const { pipeline } = require('node:stream');
const pump = util.promisify(pipeline);

const createMediaItems = async (request: Request, reply: FastifyReply) => {
const vaultInstance = request.vault;
const vault = request.vault;

if(!vaultInstance) {
if(!vault) {
return reply.status(400).send('No vault provided');
}
const { db, vault } = vaultInstance;

const { db } = vault;
const parts = request.parts();
for await (const part of parts) {
if (part.type === 'file') {
Expand Down
6 changes: 3 additions & 3 deletions backend/src/routes/media/deleteMediaItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import * as fs from 'fs/promises';
import { checkVault } from '../../hooks/checkVault';

const deleteMediaItem = async (request: Request, reply: FastifyReply) => {
const vaultInstance = request.vault;
if(!vaultInstance) {
const vault = request.vault;
if(!vault) {
return reply.status(400).send('No vault provided');
}

const { ids } = request.params as { ids: string };
const parsedIdArray: string[] = JSON.parse(ids);
const { vault, db } = vaultInstance;
const { db } = vault;
try {
for (const rawId of parsedIdArray) {
const parsedId = Number.parseInt(rawId ?? '');
Expand Down
2 changes: 1 addition & 1 deletion backend/src/routes/videos/getVideo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const getVideo = async (request: FastifyRequest, reply: FastifyReply) => {
}

const fileName = params.fileName;
const { vault } = VaultController.getVault(vaultId);
const vault = VaultController.getVault(vaultId);
const videoPath = path.join(vault.path, 'media', 'videos', fileName!);
const videoStream = createReadStream(videoPath);

Expand Down

0 comments on commit 735079c

Please sign in to comment.