diff --git a/app/listen/[collectionid]/page.tsx b/app/listen/[collectionid]/page.tsx
index b234b09..151abb7 100644
--- a/app/listen/[collectionid]/page.tsx
+++ b/app/listen/[collectionid]/page.tsx
@@ -1,6 +1,37 @@
-import InProgress from "@/components/InProgress";
+import NotFound from "@/components/NotFound";
+import MusicController from "@/server/controllers/music.controller";
+import { MusicStreamingEntry } from "@/server/db/schema";
+import { S3Service } from "@/server/s3";
+import { Suspense } from "react";
-export default async function ListenByCollectionID() {
+export default async function ListenByCollectionID({ params }: { params: { collectionid?: string }}) {
+ const id = params.collectionid ? Number(params.collectionid) : undefined;
+ if (!id) return
- return
+ const controller = new MusicController();
+ const result = await controller.getByID(id);
+ if (!result) return
+
+ console.log(result);
+ const entries = await S3Service.getURLs(result.pathToEntry);
+
+ return (
+
+
Loading...}>
+
+
+ {result.longDescription}
+
+
+ { entries
+ ? entries.map((entry: string, idx: number) => {entry}
)
+ : No entries found
+ }
+
+
+
+ )
}
diff --git a/components/NotFound.tsx b/components/NotFound.tsx
new file mode 100644
index 0000000..9b5b4b6
--- /dev/null
+++ b/components/NotFound.tsx
@@ -0,0 +1,8 @@
+export default function NotFound() {
+ return (
+
+
404
+ Page not found
+
+ )
+}
diff --git a/package.json b/package.json
index 0e8b5f8..09a638d 100644
--- a/package.json
+++ b/package.json
@@ -12,11 +12,12 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.367.0",
+ "@smithy/node-http-handler": "^2.1.8",
"@t3-oss/env-nextjs": "^0.7.0",
"@vercel/style-guide": "^5.0.1",
"autoprefixer": "10.4.14",
"ioredis": "^5.3.2",
- "next": "^13.4.12",
+ "next": "^14.0.1",
"pg": "^8.11.3",
"react": "18.2.0",
"react-dom": "18.2.0",
diff --git a/postcss.config.js b/postcss.config.cjs
similarity index 100%
rename from postcss.config.js
rename to postcss.config.cjs
diff --git a/server/controllers/base.controller.ts b/server/controllers/base.controller.ts
index 8942789..e8ece0e 100644
--- a/server/controllers/base.controller.ts
+++ b/server/controllers/base.controller.ts
@@ -1,5 +1,5 @@
import { S3Client } from '@aws-sdk/client-s3';
-import Redis from 'ioredis';
+// import Redis from 'ioredis';
import pg from 'pg';
import { createDBClient } from '../db';
import { Maybe, must } from '@/util/helpers';
@@ -16,40 +16,47 @@ type ControllerOptions = {
export default abstract class BaseController {
#db: pg.Client
- #bucket: S3Client
- #cache: Redis
+ // #bucket: S3Client
+ // #cache: Redis
tableName: string
parser?: FullParserType
constructor(options: ControllerOptions) {
this.#db = must(createDBClient);
- this.#bucket = must(createS3Client);
- this.#cache = must(createRedisClient);
+ // this.#bucket = must(createS3Client);
+ // this.#cache = must(createRedisClient);
this.tableName = options.tableName;
this.parser = options.parser;
}
async getAll(projection?: string): Promise> {
+ 'use server';
try {
// we'll enable cache here later
+ await this.#db.connect();
const result = await this.#db.query("SELECT $1 FROM $2", [projection ?? "*", this.tableName]);
return result.rows;
} catch (error) {
console.log({ error });
return null;
+ } finally {
+ await this.#db.end();
}
}
async getByID(id: number, projection?: string): Promise> {
try {
- const result = await this.#db.query("SELECT $1 FROM $2 WHERE id = $3", [projection ?? "*", this.tableName, id]);
+ await this.#db.connect();
+ const result = await this.#db.query(`SELECT ${projection ?? "*"} FROM ${this.tableName} WHERE id = ${id}`);
return result.rows[0];
} catch (error) {
console.log({ error });
return null;
+ } finally {
+ await this.#db.end();
}
}
}
diff --git a/server/db/schema.ts b/server/db/schema.ts
index a434c35..ff41a26 100644
--- a/server/db/schema.ts
+++ b/server/db/schema.ts
@@ -8,8 +8,8 @@ export const ZMusicStreamingEntry = z.object({
name: z.string().max(100),
shortDescription: z.string().max(100),
longDescription: z.string().max(1000),
+ pathToEntry: z.string(),
tags: z.array(z.string().max(100)).optional(),
- pathToEntry: z.string().optional(),
});
export type MusicStreamingEntry = z.infer;
diff --git a/server/s3/createClient.ts b/server/s3/createClient.ts
index 5692421..f7e82fd 100644
--- a/server/s3/createClient.ts
+++ b/server/s3/createClient.ts
@@ -1,5 +1,7 @@
import { env } from "@/env.mjs";
import { S3Client, S3ClientConfig } from "@aws-sdk/client-s3";
+import { NodeHttpHandler } from "@smithy/node-http-handler";
+import https from "https";
export default function createS3Client() {
if (typeof process.env.S3_ACCESS_KEY !== "string") {
@@ -11,7 +13,17 @@ export default function createS3Client() {
}
const config: S3ClientConfig = {
- endpoint: env.S3_ENDPOINT
+ endpoint: env.S3_ENDPOINT,
+ region: "us-east-1",
+
+ requestHandler: new NodeHttpHandler({
+ httpsAgent: new https.Agent({
+ rejectUnauthorized: false,
+ ciphers: "ALL",
+ }),
+ }),
+
+ forcePathStyle: true,
}
if (env.S3_SECRET) {
diff --git a/server/s3/service.ts b/server/s3/service.ts
index b790671..70109e4 100644
--- a/server/s3/service.ts
+++ b/server/s3/service.ts
@@ -2,8 +2,6 @@ import { ListObjectsV2Command, PutObjectCommand, PutObjectCommandOutput, S3Clien
import { env } from "@/env.mjs";
import createS3Client from "./createClient";
import { Maybe, must } from "@/util/helpers";
-import { readFile } from "fs/promises";
-import { readFileSync, readdir } from "fs";
export default class S3Service {
static async getFiles(key: string): Promise> {
@@ -34,71 +32,4 @@ export default class S3Service {
return null;
}
}
-
- static async upload(filePath: string, key: string) {
- if (env.NODE_ENV != "development") {
- throw new Error("Cannot upload files in production");
- }
-
- try {
- const client = must(createS3Client);
- const Body = await readFile(filePath);
-
- const cmd = new PutObjectCommand({
- Bucket: env.S3_BUCKET,
- Key: key,
- Body,
- });
-
- const result = await client.send(cmd);
- return result.$metadata.httpStatusCode == 200;
- } catch (error) {
- console.log({ error });
- return null;
- }
- }
-
- static async uploadAllInDirectory(dirPath: string, prefix: string): Promise {
- if (env.NODE_ENV != "development") {
- throw new Error("Cannot upload files in production");
- }
-
- try {
- const client = must(createS3Client);
- const promises = new Array>();
- const results = new Array();
-
- readdir(dirPath, (err, files) => {
- if (err) {
- console.log({ err });
- return null;
- }
-
- files.forEach(file => {
- const Key = `${prefix}/${file}`
- const Body = readFileSync(Key);
-
- const cmd = new PutObjectCommand({
- Bucket: env.S3_BUCKET,
- Key,
- Body,
- })
-
- promises.push(client.send(cmd));
- })
- })
-
- promises.forEach(p => {
- setTimeout(async() => {
- const output = await Promise.resolve(p);
- results.push(output.$metadata.httpStatusCode == 200);
- }, 1000)
- })
-
- return results.every(r => true);
- } catch (error) {
- console.log({ error });
- return false;
- }
- }
}
diff --git a/server/sql/create_tables.sql b/server/sql/create_tables.sql
new file mode 100644
index 0000000..07cf172
--- /dev/null
+++ b/server/sql/create_tables.sql
@@ -0,0 +1,20 @@
+CREATE TABLE IF NOT EXISTS music (
+ id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ name varchar(100),
+ shortDescription varchar(100),
+ longDescription varchar(1000),
+ pathToEntry varchar
+);
+
+CREATE TABLE IF NOT EXISTS tags (
+ id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ name varchar(100)
+);
+
+CREATE TABLE IF NOT EXISTS music_tags (
+ id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
+ music_id INTEGER,
+ tag_id INTEGER,
+ FOREIGN KEY(music_id) REFERENCES music(id),
+ FOREIGN KEY(tag_id) REFERENCES tags(id)
+);
diff --git a/server/sql/seed.sql b/server/sql/seed.sql
new file mode 100644
index 0000000..a8e9ddc
--- /dev/null
+++ b/server/sql/seed.sql
@@ -0,0 +1,26 @@
+INSERT INTO music (name, shortDescription, longDescription, pathToEntry) VALUES (
+ 'Jisei',
+ 'My first major undertaking as a singer-songwriter',
+ 'Released in October 2020',
+ 'Jisei'
+);
+
+INSERT INTO tags (name) VALUES
+(
+ 'indie-rock'
+),
+(
+ 'alternative'
+),
+(
+ 'guitar'
+),
+(
+ 'cello'
+);
+
+INSERT INTO music_tags (music_id, tag_id) VALUES
+(1, 1),
+(1, 2),
+(1, 3),
+(1, 4);
diff --git a/tailwind.config.js b/tailwind.config.js
index 58b5f09..300dd22 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,5 +1,5 @@
/** @type {import('tailwindcss').Config} */
-module.exports = {
+export default {
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',