Skip to content

Commit

Permalink
Implement update time code
Browse files Browse the repository at this point in the history
  • Loading branch information
VovaStelmashchuk committed Sep 1, 2024
1 parent 78ac596 commit d5a5d16
Show file tree
Hide file tree
Showing 20 changed files with 211 additions and 93 deletions.
35 changes: 23 additions & 12 deletions src/core/episodeRepo.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Database } from "./client.js";

export function getPublicPosts() {
export function getPublicPosts(showSlug) {
return Database.collection('posts').find(
{
'visibility': 'public'
'visibility': 'public',
'showSlug': showSlug
},
{
sort: {
Expand All @@ -27,9 +28,11 @@ export function getPodcastForRss() {
).toArray();
}

export function getAllPosts() {
export function getAllPosts(showSlug) {
return Database.collection('posts').find(
{},
{
'showSlug': showSlug
},
{
sort: {
'publish_date': -1
Expand All @@ -38,14 +41,22 @@ export function getAllPosts() {
).toArray();
}

export function updatePodcastNameBySlug(slug, podcastName) {
return Database.collection('posts').updateOne({ slug: slug }, { $set: { title: podcastName } });
export function updatePodcastNameBySlug(showSlug, episodeSlug, podcastName) {
return Database.collection('posts').updateOne({
showSlug: showSlug,
slug: episodeSlug
}, {
$set: { title: podcastName }
});
}

export function updateTimeCodeBySlug(slug, index, time, description, isPublicValue) {
export function updateTimeCodeBySlug(showSlug, episodeSlug, index, time, description, isPublicValue) {
const timeInSeconds = time.split(':').reduce((acc, time) => (60 * acc) + +time, 0);
return Database.collection('posts').updateOne(
{ slug: slug },
{
showSlug: showSlug,
slug: episodeSlug
},
{
$set: {
[`charters.${index}.time`]: time,
Expand All @@ -69,16 +80,16 @@ export function updateLinkBySlug(slug, index, link, title) {
);
}

export function getPostBySlug(slug) {
return Database.collection('posts').findOne({ slug: slug });
export function getPostBySlug(showSlug, episodeSlug) {
return Database.collection('posts').findOne({ slug: episodeSlug, showSlug: showSlug });
}

export function updateMontageStatusBySlug(slug, status) {
return Database.collection('posts').updateOne({ slug: slug }, { $set: { montage_status: status } });
}

export function updateMontageStatusToSuccessBySlug(slug, audioFileKey) {
return Database.collection('posts').updateOne({ slug: slug }, { $set: { montage_status: 'success', audio_file_key: audioFileKey } });
export function updateMontageStatusToSuccessBySlug(slug, publicAudioFile) {
return Database.collection('posts').updateOne({ slug: slug }, { $set: { montage_status: 'success', publicAudioFile: publicAudioFile } });
}

export function publishPodcast(slug) {
Expand Down
22 changes: 12 additions & 10 deletions src/core/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,35 @@ import { Podcast } from 'podcast';

import { getPodcastForRss } from './episodeRepo.js';
import { buildObjectURL, getFileSizeInByte, uploadFile } from '../minio/utils.js';
import { getShowInfo } from '../core/podcastRepo.js';

import dotenv from 'dotenv';

dotenv.config();

const host = process.env.BASE_URL;

export async function updateRss() {
export async function updateRss(showSlug) {
const podcasts = await getPodcastForRss();
const logoUrl = buildObjectURL('logo.jpg')
const logoUrl = buildObjectURL(showSlug + '/logo.jpg')

const description = 'Два андроїдщики, два Вови і деколи дві різні думки. Кожний подкаст ми обговорюємо нові релізи в світі android розробки, кращі і не дуже практики. Ділимося своїми думками, досвідом і деколи пробуємо не смішно жартувати. Також тут ви знайдете рекомендації початківцям, а хто давно в розробці мають тут просто гарно провести час. Якщо вам тут сподобалося то заходьте в наш telegram chat https://t.me/androidstory_chat Якщо прям сильно сподобалося закиньте там трішки грошей. https://www.patreon.com/androidstory'
const showInfo = await getShowInfo(showSlug);
const description = showInfo.about;

const author = 'Vova and Vova';
const author = showInfo.authors;

const pubDate = new Date().toUTCString();

const feed = new Podcast({
title: 'Android story',
title: showInfo.showName,
description: description,
feedUrl: buildObjectURL('rss.xml'),
feedUrl: buildObjectURL(showSlug + '/rss.xml'),
siteUrl: host,
webMaster: host,
generator: 'Android story',
imageUrl: logoUrl,
author: author,
copyright: 2022 Android story',
copyright: 20220-2024' + showInfo.showName,
language: 'ua',
categories: ['Technology'],
pubDate: pubDate,
Expand All @@ -50,11 +52,11 @@ export async function updateRss() {
});

const fileSizes = await Promise.all(podcasts.map(post =>
getFileSizeInByte('episodes/' + post.audio_file_key)
getFileSizeInByte(post.publicAudioFile)
));

const podcastsUrl = await Promise.all(podcasts.map(post =>
buildObjectURL('episodes/' + post.audio_file_key)
buildObjectURL(post.publicAudioFile)
));

const podcastCount = podcasts.length;
Expand Down Expand Up @@ -94,7 +96,7 @@ export async function updateRss() {

const xml = feed.buildXml();

await uploadFile('rss.xml', xml);
await uploadFile(showSlug + '/rss.xml', xml);
}

export function buildPublicChapters(chapters) {
Expand Down
3 changes: 1 addition & 2 deletions src/core/podcastRepo.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Database } from "./client.js";

export async function getShowInfo(podcastDomain) {
return Database.collection('shows').findOne({ domains: podcastDomain });
return Database.collection('shows').findOne({ domains: podcastDomain });
}


14 changes: 14 additions & 0 deletions src/core/showRepo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Database } from "./client.js";

export async function getAllShows() {
return Database.collection('shows').find().toArray();
}

export async function getShowBySlug(slug) {
return Database.collection('shows').findOne({ slug });
}

export async function getShowInfo(podcastDomain) {
return Database.collection('shows').findOne({ domains: podcastDomain });
}

2 changes: 1 addition & 1 deletion src/minio/ffmpegApply.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Fs from 'fs'
* The method downoald file from minio and apply ffmpeg to it and upload to minio
*/
export async function applyFFmpegToFileInMinio(inputKey, outputKey, ffmpegCommand) {
console.log('Applying ffmpeg to file in minio');
console.log('Applying ffmpeg to file in minio, start download');
const folder = `.tmp/test-key/`;
Fs.rmSync(folder, { recursive: true, force: true });

Expand Down
5 changes: 3 additions & 2 deletions src/montage/publicAudioGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ async function createPublicAudioJob(podcast) {

complexFilterString += `concat=n=${publicIndex - 1}:v=0:a=1`;

await applyFFmpegToFileInMinio(podcast.origin_file, `episodes/${podcast.slug}.mp3`, complexFilterString)
await applyFFmpegToFileInMinio(podcast.originFilePath, podcast.publicAudioFile, complexFilterString)
}

export async function createPublicAudio(podcast) {
await modifyPodcastStatus(podcast.slug, 'in_progress');

createPublicAudioJob(podcast)
.then(async () => {
await updateMontageStatusToSuccessBySlug(podcast.slug, `episodes/${podcast.slug}.mp3`);
const publicAudioPath = `${podcast.showSlug}/episodes/${podcast.slug}`;
await updateMontageStatusToSuccessBySlug(podcast.slug, publicAudioPath);
console.log('Public audio creation successful.');
})
.catch(async (error) => {
Expand Down
37 changes: 30 additions & 7 deletions src/routers/admin/dashboard.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,47 @@
import { getAllPosts } from "../../core/episodeRepo.js";
import { getAllShows, getShowBySlug } from "../../core/showRepo.js";

async function dashboardView(request, h) {
return h.view('admin/dashboard', {}, { layout: 'admin', })
const shows = await getAllShows();
const showsUiModel = shows.map(show => ({
url: `/admin/show/${show.slug}`,
showName: show.showName,
}));

return h.view(
'admin/dashboard',
{
pageTitle: 'Dashboard',
shows: showsUiModel,
},
{
layout: 'admin'
}
)
}

async function adminPodcastList(request, h) {
const posts = await getAllPosts()
const showSlug = request.params.showSlug;

const show = await getShowBySlug(showSlug);
const posts = await getAllPosts(showSlug);

const uiPosts = posts.map(post => ({
...post,
detailUrl: `/admin/podcast/${post.slug}`,
detailUrl: `/admin/show/${show.slug}/episode/${post.slug}`,
}));

const pageTitle = 'Dashboard ' + show.showName;

return h.view(
'admin/admin_podcast_list',
{
pageTitle: pageTitle,
posts: uiPosts,
}, {
layout: false,
}
},
{
layout: 'admin'
}
)
}

Expand All @@ -34,7 +57,7 @@ export function adminDashboard(server) {

server.route({
method: 'GET',
path: '/admin/podcast',
path: '/admin/show/{showSlug}',
handler: adminPodcastList,
options: {
auth: 'adminSession',
Expand Down
23 changes: 14 additions & 9 deletions src/routers/admin/detail/edit_meta.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { getPostBySlug, updateTimeCodeBySlug, updateLinkBySlug } from "../../../core/episodeRepo.js";

async function updateTimeCode(request, h) {
const showSlug = request.params.showSlug;
const episodeSlug = request.params.episodeSlug;

const { hours, minutes, seconds, text, isPublic } = request.payload;
const isPublicValue = isPublic === 'on' ? true : false;

const slug = request.params.slug;
const index = request.params.index;

const time = `${hours}:${minutes}:${seconds}`;

await updateTimeCodeBySlug(slug, index, time, text, isPublicValue);
await updateTimeCodeBySlug(showSlug, episodeSlug, index, time, text, isPublicValue);

return h.response().code(200).header('HX-Trigger', 'update-preview');
}
Expand All @@ -25,15 +27,18 @@ async function updateLink(request, h) {
}

async function addTimeCode(request, h) {
const slug = request.params.slug;
const podcast = await getPostBySlug(slug);
const showSlug = request.params.showSlug;
const episodeSlug = request.params.episodeSlug;

const podcast = await getPostBySlug(showSlug, episodeSlug);

const index = podcast.charters.length;

return h.view(
'edit_podcast_time_code_wrapper',
'editable_time_code',
{
slug: slug,
showSlug: showSlug,
episodeSlug: episodeSlug,
index: index,
},
{
Expand All @@ -49,7 +54,7 @@ async function addLink(request, h) {
const index = podcast.links.length;

return h.view(
'editable_link_wrapper',
'editable_link',
{
slug: slug,
index: index,
Expand All @@ -63,7 +68,7 @@ async function addLink(request, h) {
export function editPodcastMetaInfo(server) {
server.route({
method: 'PUT',
path: '/admin/podcast/{slug}/timecodes/{index}',
path: '/admin/show/{showSlug}/episode/{episodeSlug}/timecodes/{index}',
handler: updateTimeCode,
options: {
auth: 'adminSession',
Expand All @@ -72,7 +77,7 @@ export function editPodcastMetaInfo(server) {

server.route({
method: 'POST',
path: '/admin/podcast/{slug}/add-timecode',
path: '/admin/show/{showSlug}/episode/{episodeSlug}/add-timecode',
handler: addTimeCode,
options: {
auth: 'adminSession',
Expand Down
25 changes: 14 additions & 11 deletions src/routers/admin/detail/getDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import { getPostBySlug } from "../../../core/episodeRepo.js";
import { buildObjectURL } from "../../../minio/utils.js";
import { buildYoutubePublicDescription, buildYoutubePatreonDescription } from "../../../core/generator.js";

async function podcastDetailsHandler(request, h) {
const slug = request.params.slug;
async function getPodcastDetails(request, h) {
const showSlug = request.params.showSlug;
const episodeSlug = request.params.episodeSlug;

const podcast = await getPostBySlug(slug);
const podcast = await getPostBySlug(showSlug, episodeSlug);

return h.view(
'admin/admin_podcast_detail',
{
title: podcast.title,
slug: podcast.slug,
audioUrl: buildObjectURL(podcast.origin_file),
showSlug: showSlug,
episodeSlug: podcast.slug,
audioUrl: buildObjectURL(podcast.originFilePath),
timecodes: podcast.charters.map((chapter, index) => {
const splitTime = chapter.time.split(':');
const hour = splitTime[0];
Expand All @@ -38,23 +41,23 @@ async function podcastDetailsHandler(request, h) {
}),
isAudioBuildInProgress: podcast.montage_status === 'in_progress',
publish_button_text: podcast.visibility === 'private' ? 'Publish' : 'Unpublish',
url: podcast.visibility === 'private' ? `/admin/podcast/${slug}/publish` : `/admin/podcast/${slug}/unpublish`,
url: podcast.visibility === 'private' ? `/admin/podcast/${episodeSlug}/publish` : `/admin/podcast/${episodeSlug}/unpublish`,
},
{ layout: 'admin' }
)
}

async function youtbeTextComponent(request, h) {
const slug = request.params.slug;
const showSlug = request.params.showSlug;
const episodeSlug = request.params.episodeSlug;

const podcast = await getPostBySlug(slug);
const podcast = await getPostBySlug(showSlug, episodeSlug);
const publicDescription = buildYoutubePublicDescription(podcast);
const patreonDescription = buildYoutubePatreonDescription(podcast);

return h.view(
'admin/youtube_text',
{
slug: slug,
public_text: publicDescription,
patreon_text: patreonDescription,
},
Expand All @@ -67,16 +70,16 @@ async function youtbeTextComponent(request, h) {
export function adminPodcastGetInfoController(server) {
server.route({
method: 'GET',
path: '/admin/podcast/{slug}',
handler: podcastDetailsHandler,
path: '/admin/show/{showSlug}/episode/{episodeSlug}',
handler: getPodcastDetails,
options: {
auth: 'adminSession',
}
});

server.route({
method: 'GET',
path: '/admin/podcast/{slug}/youtube-description',
path: '/admin/show/{showSlug}/episode/{episodeSlug}/youtube-description',
handler: youtbeTextComponent,
options: {
auth: 'adminSession',
Expand Down
Loading

0 comments on commit d5a5d16

Please sign in to comment.