Skip to content

docker and metadata improves #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 26 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3df6818
feat: openapi support plus more api validation
Huskydog9988 May 10, 2025
60d22ea
fix: back button link in admin dash
Huskydog9988 May 10, 2025
fc74738
feat: new unified data folder
Huskydog9988 May 10, 2025
1bbdf46
feat: better docker builds
Huskydog9988 May 10, 2025
a8ee27e
feat: pcgamgingwiki now provides a description
Huskydog9988 May 11, 2025
dad2161
feat: games now have tag support
Huskydog9988 May 11, 2025
a101ff0
fix: allow notification nonce reuse per user
Huskydog9988 May 14, 2025
b033496
feat: update checker based gh releases
Huskydog9988 May 14, 2025
ccdbbcf
fix: editing game image metadata in admin panel
Huskydog9988 May 14, 2025
b551788
fix: object fs backend not deleting metadata
Huskydog9988 May 14, 2025
2cc3f13
feat: fs object metadata cache and validation
Huskydog9988 May 14, 2025
898516b
chore: style
Huskydog9988 May 14, 2025
56e1ba6
fix: check update not using drop's correct version
Huskydog9988 May 14, 2025
6df2ef1
fix: igdb assuming certain values always exist
Huskydog9988 May 15, 2025
bea26a9
feat: game metadata rating support
Huskydog9988 May 15, 2025
9bf36c8
feat: pcgamgingwiki desc in searchstub
Huskydog9988 May 15, 2025
a34f10d
feat: igdb tag support
Huskydog9988 May 15, 2025
82b123a
fix: gamerating model
Huskydog9988 May 15, 2025
9d2aded
feat: add acl to notifications
Huskydog9988 May 15, 2025
1165d86
Merge remote-tracking branch 'origin/develop' into more-fixes
Huskydog9988 May 15, 2025
bee3b0c
fix: drop update notifications
Huskydog9988 May 15, 2025
59c3b9b
fix: don't send system notifications to all users
Huskydog9988 May 15, 2025
831b20d
fix: remove old requiredPerms field
Huskydog9988 May 15, 2025
a89c657
feat: very basic screenshot api
Huskydog9988 May 15, 2025
4fbc730
chore: style
Huskydog9988 May 15, 2025
21eec08
fix: missing user check in screenshot api endpoint
Huskydog9988 May 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dist

# Node dependencies
node_modules
.yarn

# Logs
logs
Expand All @@ -23,4 +24,8 @@ logs
.env.*
!.env.example

.data
# deploy template
deploy-template/

# generated prisma client
/prisma/client
42 changes: 26 additions & 16 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
# pull pre-configured and updated build environment
FROM debian:testing-20250317-slim AS build-system
# Unified deps builder
FROM node:lts-alpine AS deps
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --network-timeout 1000000 --ignore-scripts

# Build for app
FROM node:lts-alpine AS build-system
# setup workdir - has to be the same filepath as app because fuckin' Prisma
WORKDIR /app

# install dependencies and build
RUN apt-get update -y
RUN apt-get install node-corepack -y
RUN corepack enable
ENV NODE_ENV=production
ENV NUXT_TELEMETRY_DISABLED=1

# copy deps and rest of project files
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN NUXT_TELEMETRY_DISABLED=1 yarn install --network-timeout 1000000
RUN NUXT_TELEMETRY_DISABLED=1 yarn prisma generate
RUN NUXT_TELEMETRY_DISABLED=1 yarn build

# create run environment for Drop
FROM node:lts-slim AS run-system
# build
RUN yarn postinstall
RUN yarn build

# create run environment for Drop
FROM node:lts-alpine AS run-system
WORKDIR /app

ENV NODE_ENV=production
ENV NUXT_TELEMETRY_DISABLED=1

RUN yarn add --network-timeout 1000000 --no-lockfile [email protected]

COPY --from=build-system /app/package.json ./
COPY --from=build-system /app/.output ./app
COPY --from=build-system /app/prisma ./prisma
COPY --from=build-system /app/package.json ./
COPY --from=build-system /app/build ./startup

# OpenSSL as a dependency for Drop (TODO: seperate build environment)
RUN apt-get update -y && apt-get install -y openssl
RUN yarn global add [email protected]
ENV LIBRARY="/library"
ENV DATA="/data"

CMD ["/app/startup/launch.sh"]
CMD ["sh", "/app/startup/launch.sh"]
5 changes: 2 additions & 3 deletions build/launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

# This file starts up the Drop server by running migrations and then starting the executable
echo "[Drop] performing migrations..."
ls ./prisma/migrations/
prisma migrate deploy
yarn prisma migrate deploy

# Actually start the application
node /app/app/server/index.mjs
node /app/app/server/index.mjs
12 changes: 4 additions & 8 deletions deploy-template/compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
services:
postgres:
image: postgres:14-alpine
# using alpine image to reduce image size
image: postgres:alpine
ports:
- 5432:5432
healthcheck:
Expand All @@ -16,19 +17,14 @@ services:
- POSTGRES_USER=drop
- POSTGRES_DB=drop
drop:
image: registry.deepcore.dev/drop-oss/drop/main:latest
image: ghcr.io/drop-oss/drop
depends_on:
postgres:
condition: service_healthy
ports:
- 3000:3000
volumes:
- ./library:/library
- ./certs:/certs
- ./objects:/objects
- ./data:/data
environment:
- DATABASE_URL=postgres://drop:drop@postgres:5432/drop
- FS_BACKEND_PATH=/objects
- CLIENT_CERTIFICATES=/certs
- LIBRARY=/library
- GIANT_BOMB_API_KEY=REPLACE_WITH_YOUR_KEY
2 changes: 1 addition & 1 deletion layouts/admin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ const navigation: Array<NavigationItem & { icon: Component }> = [
},
{
label: "Back",
route: "/",
route: "/store",
prefix: ".",
icon: ArrowLeftIcon,
},
Expand Down
46 changes: 33 additions & 13 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import tailwindcss from "@tailwindcss/vite";

const dropVersion = "v0.3.0";

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
extends: ["./drop-base"],

// Module config from here down
modules: [
"vue3-carousel-nuxt",
"nuxt-security",
// "@nuxt/image",
"@nuxt/fonts",
"@nuxt/eslint",
],

// Nuxt-only config
telemetry: false,
compatibilityDate: "2024-04-03",
Expand All @@ -21,6 +34,10 @@ export default defineNuxtConfig({
viewTransition: true,
},

// future: {
// compatibilityVersion: 4,
// },

vite: {
plugins: [tailwindcss()],
},
Expand All @@ -31,24 +48,38 @@ export default defineNuxtConfig({
},
},

appConfig: {
dropVersion: dropVersion,
},

routeRules: {
"/api/**": { cors: true },
},

nitro: {
minify: true,
compressPublicAssets: true,

experimental: {
websocket: true,
tasks: true,
openAPI: true,
},

openAPI: {
// tracking for dynamic openapi schema https://github.com/nitrojs/nitro/issues/2974
meta: {
title: "Drop",
description:
"Drop is an open-source, self-hosted game distribution platform, creating a Steam-like experience for DRM-free games.",
version: dropVersion,
},
},

scheduledTasks: {
"0 * * * *": ["cleanup:invitations", "cleanup:sessions"],
},

compressPublicAssets: true,

storage: {
appCache: {
driver: "lru-cache",
Expand Down Expand Up @@ -76,17 +107,6 @@ export default defineNuxtConfig({
},
},

extends: ["./drop-base"],

// Module config from here down
modules: [
"vue3-carousel-nuxt",
"nuxt-security",
// "@nuxt/image",
"@nuxt/fonts",
"@nuxt/eslint",
],

carousel: {
prefix: "Vue",
},
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"arktype": "^2.1.10",
"axios": "^1.7.7",
"bcryptjs": "^3.0.2",
"cheerio": "^1.0.0",
"cookie-es": "^2.0.0",
"fast-fuzzy": "^1.12.0",
"file-type-mime": "^0.4.3",
Expand All @@ -36,7 +37,7 @@
"nuxt": "^3.16.2",
"nuxt-security": "2.2.0",
"prisma": "^6.7.0",
"sharp": "^0.33.5",
"semver": "^7.7.1",
"stream-mime-type": "^2.0.0",
"turndown": "^7.2.0",
"unstorage": "^1.15.0",
Expand All @@ -53,6 +54,7 @@
"@types/bcryptjs": "^3.0.0",
"@types/luxon": "^3.6.2",
"@types/node": "^22.13.16",
"@types/semver": "^7.7.0",
"@types/turndown": "^5.0.5",
"autoprefixer": "^10.4.20",
"eslint": "^9.24.0",
Expand Down
10 changes: 6 additions & 4 deletions pages/admin/metadata/games/[id]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
class="flex flex-col lg:flex-row lg:justify-between items-start lg:items-center gap-2"
>
<div class="inline-flex items-center gap-4">
<img :src="useObject(game.mIconObjectId)" class="size-20" />
<!-- cover image -->
<img :src="coreMetadataIconUrl" class="size-20" />
<div>
<h1 class="text-5xl font-bold font-display text-zinc-100">
{{ game.mName }}
Expand Down Expand Up @@ -625,7 +626,7 @@ async function updateBannerImage(id: string) {
method: "PATCH",
body: {
id: gameId,
mBannerId: id,
mBannerObjectId: id,
},
});
game.value.mBannerObjectId = mBannerObjectId;
Expand All @@ -652,10 +653,11 @@ async function updateCoverImage(id: string) {
method: "PATCH",
body: {
id: gameId,
mCoverId: id,
mCoverObjectId: id,
},
});
game.value.mCoverObjectId = mCoverObjectId;
coreMetadataIconUrl.value = useObject(mCoverObjectId);
} catch (e) {
createModal(
ModalType.Notification,
Expand Down Expand Up @@ -727,7 +729,7 @@ async function updateImageCarousel() {
method: "PATCH",
body: {
id: gameId,
mImageCarousel: game.value.mImageCarouselObjectIds,
mImageCarouselObjectIds: game.value.mImageCarouselObjectIds,
},
});
} catch (e) {
Expand Down
7 changes: 3 additions & 4 deletions pages/store/[id]/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,7 @@
'w-4 h-4',
]"
/>
<span class="text-zinc-600"
>({{ game.mReviewCount }} reviews)</span
>
<span class="text-zinc-600">({{ 0 }} reviews)</span>
</td>
</tr>
</tbody>
Expand Down Expand Up @@ -220,7 +218,8 @@ const platforms = game.versions
.flat()
.filter((e, i, u) => u.indexOf(e) === i);

const rating = Math.round(game.mReviewRating * 5);
// const rating = Math.round(game.mReviewRating * 5);
const rating = Math.round(0 * 5);
const ratingArray = Array(5)
.fill(null)
.map((_, i) => i + 1 <= rating);
Expand Down
16 changes: 16 additions & 0 deletions prisma/migrations/20250511154134_add_tags_to_games/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-- CreateTable
CREATE TABLE "_GameToTag" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL,

CONSTRAINT "_GameToTag_AB_pkey" PRIMARY KEY ("A","B")
);

-- CreateIndex
CREATE INDEX "_GameToTag_B_index" ON "_GameToTag"("B");

-- AddForeignKey
ALTER TABLE "_GameToTag" ADD CONSTRAINT "_GameToTag_A_fkey" FOREIGN KEY ("A") REFERENCES "Game"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_GameToTag" ADD CONSTRAINT "_GameToTag_B_fkey" FOREIGN KEY ("B") REFERENCES "Tag"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Warnings:

- A unique constraint covering the columns `[userId,nonce]` on the table `Notification` will be added. If there are existing duplicate values, this will fail.

*/
-- DropIndex
DROP INDEX "Notification_nonce_key";

-- CreateIndex
CREATE UNIQUE INDEX "Notification_userId_nonce_key" ON "Notification"("userId", "nonce");
41 changes: 41 additions & 0 deletions prisma/migrations/20250515021331_add_game_ratings/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Warnings:

- You are about to drop the column `mReviewCount` on the `Game` table. All the data in the column will be lost.
- You are about to drop the column `mReviewRating` on the `Game` table. All the data in the column will be lost.

*/
-- AlterEnum
-- This migration adds more than one value to an enum.
-- With PostgreSQL versions 11 and earlier, this is not possible
-- in a single migration. This can be worked around by creating
-- multiple migrations, each migration adding only one value to
-- the enum.


ALTER TYPE "MetadataSource" ADD VALUE 'Metacritic';
ALTER TYPE "MetadataSource" ADD VALUE 'OpenCritic';

-- AlterTable
ALTER TABLE "Game" DROP COLUMN "mReviewCount",
DROP COLUMN "mReviewRating";

-- CreateTable
CREATE TABLE "GameRating" (
"id" TEXT NOT NULL,
"metadataSource" "MetadataSource" NOT NULL,
"metadataId" TEXT NOT NULL,
"created" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"mReviewCount" INTEGER NOT NULL,
"mReviewRating" DOUBLE PRECISION NOT NULL,
"mReviewHref" TEXT,
"gameId" TEXT NOT NULL,

CONSTRAINT "GameRating_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "GameRating_metadataSource_metadataId_key" ON "GameRating"("metadataSource", "metadataId");

-- AddForeignKey
ALTER TABLE "GameRating" ADD CONSTRAINT "GameRating_gameId_fkey" FOREIGN KEY ("gameId") REFERENCES "Game"("id") ON DELETE CASCADE ON UPDATE CASCADE;
Loading