Compare commits

..

No commits in common. "develop" and "master" have entirely different histories.

13 changed files with 26 additions and 71 deletions

View File

@ -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 value: directory on filesystem must be renamed from `videos/` to `web-videos/` to represent the value of `storage.web_videos`
* Ensure your directory name on filesystem is the same as `storage.web_videos` configuration
### Bug fixes
@ -43,7 +43,7 @@ We have many important notes in this release. We know it's a pain for sysadmin,
* Directory on filesystem must be **renamed** from `videos/` to `web-videos/` to represent the value of `storage.web_videos`
* Classic installation: `sudo -u peertube mv '/var/www/peertube/storage/videos/' '/var/www/peertube/storage/web-videos/'`
* Docker installation: `mv '/path-to-docker-installation/docker-volume/data/videos/' '/path-to-docker-installation/docker-volume/data/web-videos/'`
* `transcoding.webtorrent` must be **renamed** to `transcoding.web_videos`: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L532
* `transcoding.webtorrent` must be **renamed** to `transcoding.web_videos`: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L522
* `object_storage.videos` must be **renamed** to `object_storage.web_videos`. The value of `object_storage.web_videos.bucket_name` doesn't need to be changed: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L223
* `storage.storyboards` must be **added**: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L157
@ -61,7 +61,7 @@ We have many important notes in this release. We know it's a pain for sysadmin,
* `location ~ ^(/static/(webseed|streaming-playlists)/private/)|^/download {` must be updated to `location ~ ^(/static/(webseed|web-videos|streaming-playlists)/private/)|^/download {`
* `location ~ ^/static/(webseed|redundancy|streaming-playlists)/ {` must be updated to `location ~ ^/static/(webseed|web-videos|redundancy|streaming-playlists)/ {`
* Tracing requires `--experimental-loader=@opentelemetry/instrumentation/hook.mjs` node option: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L264
* Tracing requires `--experimental-loader=@opentelemetry/instrumentation/hook.mjs` node option: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L263
#### Developers important notes

View File

@ -2,7 +2,7 @@ import { timeToInt, timecodeRegexString } from '../common/date.js'
const timecodeRegex = new RegExp(`^(${timecodeRegexString})\\s`)
export function parseChapters (text: string, maxTitleLength: number) {
export function parseChapters (text: string) {
if (!text) return []
const lines = text.split(/\r?\n|\r|\n/g)
@ -25,11 +25,8 @@ export function parseChapters (text: string, maxTitleLength: number) {
const timecode = timeToInt(timecodeText)
const title = line.replace(matched[0], '')
chapters.push({ timecode, title: title.slice(0, maxTitleLength) })
chapters.push({ timecode, title })
}
// Only consider chapters if there are more than one
if (chapters.length > 1) return chapters
return []
return chapters
}

View File

@ -178,13 +178,13 @@ describe('Test video chapters', function () {
checkChapters(chapters)
}
await servers[0].videos.update({ id: video.uuid, attributes: { description: '00:01 chapter 1\n00:03 chapter 2' } })
await servers[0].videos.update({ id: video.uuid, attributes: { description: '00:01 chapter 1' } })
await waitJobs(servers)
for (const server of servers) {
const { chapters } = await server.chapters.list({ videoId: video.uuid })
expect(chapters).to.deep.equal([ { timecode: 1, title: 'chapter 1' }, { timecode: 3, title: 'chapter 2' } ])
expect(chapters).to.deep.equal([ { timecode: 1, title: 'chapter 1' } ])
}
await servers[0].videos.update({ id: video.uuid, attributes: { description: 'null description' } })

View File

@ -242,29 +242,6 @@ describe('Test id and pass auth plugins', function () {
expect(laguna.pluginAuth).to.equal('peertube-plugin-test-id-pass-auth-two')
})
it('Should not update a user if not owned by the plugin auth', async function () {
{
await server.users.update({ userId: lagunaId, videoQuota: 43000, password: 'coucou', pluginAuth: null })
const body = await server.users.get({ userId: lagunaId })
expect(body.videoQuota).to.equal(43000)
expect(body.pluginAuth).to.be.null
}
{
await server.login.login({
user: { username: 'laguna', password: 'laguna password' },
expectedStatus: HttpStatusCode.BAD_REQUEST_400
})
}
{
const body = await server.users.get({ userId: lagunaId })
expect(body.videoQuota).to.equal(43000)
expect(body.pluginAuth).to.be.null
}
})
after(async function () {
await cleanupTests([ server ])
})

View File

@ -221,38 +221,25 @@ describe('Parse semantic version string', function () {
describe('Extract chapters', function () {
it('Should not extract chapters', function () {
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([])
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([])
})
it('Should extract chapters', function () {
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([
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([
{ 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', 100)).to.deep.equal([
expect(parseChapters('hi\n\n00:01:30 chapter 1\n00:01:35 chapter 2\nhi')).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', 100)).to.deep.equal([
expect(parseChapters('hi\n\n00:01:30 chapter 1\n00:01:35 chapter 2\nhi\n00:01:40 chapter 3')).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' }
])
})
})

View File

@ -4,4 +4,4 @@ set -eu
# Backward path compatibility now upgrade.sh is in dist/scripts since v6
/bin/sh ../dist/scripts/upgrade.sh $1
/bin/sh ../dist/scripts/upgrade.sh

View File

@ -89,11 +89,8 @@ async function getUser (usernameOrEmail?: string, password?: string, bypassLogin
let user = await UserModel.loadByEmail(bypassLogin.user.email)
if (!user) {
user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user)
} else if (user.pluginAuth === bypassLogin.pluginName) {
user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
}
if (!user) user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user)
else user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
// Cannot create a user
if (!user) throw new AccessDeniedError('Cannot create such user: an actor with that name already exists.')

View File

@ -38,7 +38,7 @@ export async function moveToJob (options: {
}
if (video.VideoStreamingPlaylists) {
logger.debug('Moving HLS playlist of %s.', video.uuid, lTags)
logger.debug('Moving HLS playlist of %s.', video.uuid)
await moveHLSFiles(video)
}

View File

@ -5,7 +5,6 @@ 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')
@ -45,7 +44,7 @@ export async function replaceChaptersFromDescriptionIfNeeded (options: {
}) {
const { transaction, video, newDescription, oldDescription = '' } = options
const chaptersFromOldDescription = sortBy(parseChapters(oldDescription, CONSTRAINTS_FIELDS.VIDEO_CHAPTERS.TITLE.max), 'timecode')
const chaptersFromOldDescription = sortBy(parseChapters(oldDescription), 'timecode')
const existingChapters = await VideoChapterModel.listChaptersOfVideo(video.id, transaction)
logger.debug(
@ -55,7 +54,7 @@ export async function replaceChaptersFromDescriptionIfNeeded (options: {
// Then we can update chapters from the new description
if (areSameChapters(chaptersFromOldDescription, existingChapters)) {
const chaptersFromNewDescription = sortBy(parseChapters(newDescription, CONSTRAINTS_FIELDS.VIDEO_CHAPTERS.TITLE.max), 'timecode')
const chaptersFromNewDescription = sortBy(parseChapters(newDescription), 'timecode')
if (chaptersFromOldDescription.length === 0 && chaptersFromNewDescription.length === 0) return false
await replaceChapters({ video, chapters: chaptersFromNewDescription, transaction })

View File

@ -873,8 +873,6 @@ export class UserModel extends Model<Partial<AttributesOnly<UserModel>>> {
}
isPasswordMatch (password: string) {
if (!password || !this.password) return false
return comparePassword(password, this.password)
}

View File

@ -9766,10 +9766,10 @@ components:
description: P2P peers connected (doesn't include WebSeed peers)
resolutionChanges:
type: number
description: How many resolution changes occurred since the last metric creation
description: How many resolution changes occured since the last metric creation
errors:
type: number
description: How many errors occurred since the last metric creation
description: How many errors occured since the last metric creation
downloadedBytesP2P:
type: number
description: How many bytes were downloaded with P2P since the last metric creation

View File

@ -870,7 +870,7 @@ function register ({ registerClientRoute }) {
}
```
You can then access the page on `/p/my-super/route` (please note the additional `/p/` in the path).
You can then access the page on `/p/my-super/route` (please note the additionnal `/p/` in the path).
### Publishing

View File

@ -185,7 +185,7 @@ peertube-runner list-registered
## Server tools
Server tools are scripts that interact directly with the code of your PeerTube instance.
Server tools are scripts that interect directly with the code of your PeerTube instance.
They must be run on the server, in `peertube-latest` directory.
### Parse logs