diff --git a/.gitignore b/.gitignore index 516418d..e13362d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ node_modules .git .idea .tmp +.DS_Store diff --git a/src/app.js b/src/app.js index e4c6825..1b9e11a 100644 --- a/src/app.js +++ b/src/app.js @@ -10,6 +10,7 @@ import { admin } from './routers/admin/login.js'; import { adminAuth } from './routers/admin/auth.js'; import { editPodcastDetails } from './routers/admin/details.js' import { rss } from './routers/rss/rss.js'; +import { uploadVideoController } from './routers/admin/detail/file.js'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; @@ -22,7 +23,7 @@ const init = async () => { const server = _server({ port: 3000, host: '0.0.0.0', - debug: { request: ['error'] } + debug: { request: ['error'] }, }); await server.register(Inert); @@ -51,6 +52,7 @@ const init = async () => { admin(server); editPodcastDetails(server); rss(server); + uploadVideoController(server); await server.start(); console.log('Server running on %s', server.info.uri); diff --git a/src/minio/utils.js b/src/minio/utils.js index c706249..3b8cc3d 100644 --- a/src/minio/utils.js +++ b/src/minio/utils.js @@ -128,4 +128,3 @@ export async function getFileContent(key) { throw error; } } - diff --git a/src/routers/admin/detail/file.js b/src/routers/admin/detail/file.js new file mode 100644 index 0000000..ff28117 --- /dev/null +++ b/src/routers/admin/detail/file.js @@ -0,0 +1,69 @@ +import fs from 'fs' +import path from 'path' + +async function uploadVideo(request, h) { + try { + const data = request.payload; + + if (data.video) { + const file = data.video; + console.log(file); + const filename = 'test.mov'; + + const uploadDir = `uploads/`; + fs.mkdirSync(uploadDir, { recursive: true }); + + if (!fs.existsSync(uploadDir)) { + fs.mkdirSync(uploadDir); + } + + const filePath = path.join(uploadDir, filename); + const fileStream = fs.createWriteStream(filePath); + + // Pipe the file to the file system + await new Promise((resolve, reject) => { + file.on('error', (err) => reject(err)); + file.pipe(fileStream); + file.on('end', () => resolve()); + }); + + return h + .response({ + status: 'success', + message: 'File uploaded successfully', + data: { + filename: filename, + path: filePath, + }, + }) + .code(200); + } else { + return h + .response({ status: 'fail', message: 'No file received' }) + .code(400); + } + } catch (error) { + console.error('File upload failed:', error); + return h + .response({ status: 'error', message: 'Internal Server Error' }) + .code(500); + } +} + +export function uploadVideoController(server) { + server.route({ + method: 'POST', + path: '/upload-video', + handler: uploadVideo, + options: { + auth: 'adminSession', + payload: { + output: 'stream', + parse: true, + allow: 'multipart/form-data', + maxBytes: 16 * 1024 * 1024 * 1024, // 16 GB + multipart: true, + }, + } + }); +} diff --git a/src/routers/admin/detail/getDetails.js b/src/routers/admin/detail/getDetails.js index 66c361e..bfa93b5 100644 --- a/src/routers/admin/detail/getDetails.js +++ b/src/routers/admin/detail/getDetails.js @@ -15,7 +15,13 @@ async function getPodcastDetails(request, h) { slug: podcast.slug, showSlug: showSlug, episodeSlug: podcast.slug, - audioUrl: buildObjectURL(podcast.originFilePath), + media: { + showAudio: false, + showVideo: false, + showUploadVideoButton: true, + audioUrl: buildObjectURL(podcast.originFilePath), + uploadUrl: `/admin/show/${showSlug}/episode/${episodeSlug}/upload`, + }, timecodes: podcast.charters.map((chapter, index) => { const splitTime = chapter.time.split(':'); const hour = splitTime[0]; diff --git a/src/templates/pages/admin/admin_podcast_detail.html b/src/templates/pages/admin/admin_podcast_detail.html index ae9dd9c..e83aa75 100644 --- a/src/templates/pages/admin/admin_podcast_detail.html +++ b/src/templates/pages/admin/admin_podcast_detail.html @@ -9,14 +9,7 @@ hx-include="[name=episode_name]" hx-swap="none"> -