From f9e710e7d49205d670dece683501b0e7df5c8a19 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 29 Nov 2023 14:11:57 +0100 Subject: [PATCH] Fix chapters import --- CHANGELOG.md | 2 +- packages/core-utils/src/string/chapters.ts | 9 ++++-- .../tests/src/server-helpers/core-utils.ts | 29 ++++++++++++++----- server/core/lib/video-chapters.ts | 5 ++-- 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e1738b17..e06384eae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * We've made some modifications in v6.0.0 IMPORTANT NOTES, so if you upgrade from PeerTube v6.0.0: * Ensure `location = /api/v1/videos/upload-resumable {` has been replaced by `location ~ ^/api/v1/videos/(upload-resumable|([^/]+/source/replace-resumable))$ {` in your nginx configuration * Ensure you updated `storage.web_videos` configuration value to use `web-videos/` directory name - * Ensure your directory name on filesystem is the same as `storage.web_videos` configuration + * Ensure your directory name on filesystem is the same as `storage.web_videos` configuration value: directory on filesystem must be renamed from `videos/` to `web-videos/` to represent the value of `storage.web_videos` ### Bug fixes diff --git a/packages/core-utils/src/string/chapters.ts b/packages/core-utils/src/string/chapters.ts index d7643665c..2f8105f3d 100644 --- a/packages/core-utils/src/string/chapters.ts +++ b/packages/core-utils/src/string/chapters.ts @@ -2,7 +2,7 @@ import { timeToInt, timecodeRegexString } from '../common/date.js' const timecodeRegex = new RegExp(`^(${timecodeRegexString})\\s`) -export function parseChapters (text: string) { +export function parseChapters (text: string, maxTitleLength: number) { if (!text) return [] const lines = text.split(/\r?\n|\r|\n/g) @@ -25,8 +25,11 @@ export function parseChapters (text: string) { const timecode = timeToInt(timecodeText) const title = line.replace(matched[0], '') - chapters.push({ timecode, title }) + chapters.push({ timecode, title: title.slice(0, maxTitleLength) }) } - return chapters + // Only consider chapters if there are more than one + if (chapters.length > 1) return chapters + + return [] } diff --git a/packages/tests/src/server-helpers/core-utils.ts b/packages/tests/src/server-helpers/core-utils.ts index d2b5b0512..43afab39a 100644 --- a/packages/tests/src/server-helpers/core-utils.ts +++ b/packages/tests/src/server-helpers/core-utils.ts @@ -221,25 +221,38 @@ describe('Parse semantic version string', function () { describe('Extract chapters', function () { it('Should not extract chapters', function () { - expect(parseChapters('my super description\nno?')).to.deep.equal([]) - expect(parseChapters('m00:00 super description\nno?')).to.deep.equal([]) - expect(parseChapters('00:00super description\nno?')).to.deep.equal([]) - expect(parseChapters('my super description\n'.repeat(10) + ' * list1\n * list 2\n * list 3')).to.deep.equal([]) + expect(parseChapters('my super description\nno?', 100)).to.deep.equal([]) + expect(parseChapters('m00:00 super description\nno?', 100)).to.deep.equal([]) + expect(parseChapters('00:00super description\nno?', 100)).to.deep.equal([]) + expect(parseChapters('my super description\n'.repeat(10) + ' * list1\n * list 2\n * list 3', 100)).to.deep.equal([]) + expect(parseChapters('3 Hello coucou', 100)).to.deep.equal([]) + expect(parseChapters('00:00 coucou', 100)).to.deep.equal([]) }) it('Should extract chapters', function () { - expect(parseChapters('00:00 coucou')).to.deep.equal([ { timecode: 0, title: 'coucou' } ]) - expect(parseChapters('my super description\n\n00:01:30 chapter 1\n00:01:35 chapter 2')).to.deep.equal([ + expect(parseChapters('00:00 coucou\n00:05 hello', 100)).to.deep.equal([ + { timecode: 0, title: 'coucou' }, + { timecode: 5, title: 'hello' } + ]) + + expect(parseChapters('my super description\n\n00:01:30 chapter 1\n00:01:35 chapter 2', 100)).to.deep.equal([ { timecode: 90, title: 'chapter 1' }, { timecode: 95, title: 'chapter 2' } ]) - expect(parseChapters('hi\n\n00:01:30 chapter 1\n00:01:35 chapter 2\nhi')).to.deep.equal([ + expect(parseChapters('hi\n\n00:01:30 chapter 1\n00:01:35 chapter 2\nhi', 100)).to.deep.equal([ { timecode: 90, title: 'chapter 1' }, { timecode: 95, title: 'chapter 2' } ]) - expect(parseChapters('hi\n\n00:01:30 chapter 1\n00:01:35 chapter 2\nhi\n00:01:40 chapter 3')).to.deep.equal([ + expect(parseChapters('hi\n\n00:01:30 chapter 1\n00:01:35 chapter 2\nhi\n00:01:40 chapter 3', 100)).to.deep.equal([ { timecode: 90, title: 'chapter 1' }, { timecode: 95, title: 'chapter 2' } ]) }) + + it('Should respect the max length option', function () { + expect(parseChapters('my super description\n\n00:01:30 chapter 1\n00:01:35 chapter 2', 3)).to.deep.equal([ + { timecode: 90, title: 'cha' }, + { timecode: 95, title: 'cha' } + ]) + }) }) diff --git a/server/core/lib/video-chapters.ts b/server/core/lib/video-chapters.ts index c2b091356..71e2a7cf4 100644 --- a/server/core/lib/video-chapters.ts +++ b/server/core/lib/video-chapters.ts @@ -5,6 +5,7 @@ import { VideoChapterModel } from '@server/models/video/video-chapter.js' import { MVideoImmutable } from '@server/types/models/index.js' import { Transaction } from 'sequelize' import { InternalEventEmitter } from './internal-event-emitter.js' +import { CONSTRAINTS_FIELDS } from '@server/initializers/constants.js' const lTags = loggerTagsFactory('video', 'chapters') @@ -44,7 +45,7 @@ export async function replaceChaptersFromDescriptionIfNeeded (options: { }) { const { transaction, video, newDescription, oldDescription = '' } = options - const chaptersFromOldDescription = sortBy(parseChapters(oldDescription), 'timecode') + const chaptersFromOldDescription = sortBy(parseChapters(oldDescription, CONSTRAINTS_FIELDS.VIDEO_CHAPTERS.TITLE.max), 'timecode') const existingChapters = await VideoChapterModel.listChaptersOfVideo(video.id, transaction) logger.debug( @@ -54,7 +55,7 @@ export async function replaceChaptersFromDescriptionIfNeeded (options: { // Then we can update chapters from the new description if (areSameChapters(chaptersFromOldDescription, existingChapters)) { - const chaptersFromNewDescription = sortBy(parseChapters(newDescription), 'timecode') + const chaptersFromNewDescription = sortBy(parseChapters(newDescription, CONSTRAINTS_FIELDS.VIDEO_CHAPTERS.TITLE.max), 'timecode') if (chaptersFromOldDescription.length === 0 && chaptersFromNewDescription.length === 0) return false await replaceChapters({ video, chapters: chaptersFromNewDescription, transaction })