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: * 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 `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 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 ### 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` * 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/'` * 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/'` * 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 * `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 * `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|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)/ {` * `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 #### Developers important notes

View File

@ -2,7 +2,7 @@ import { timeToInt, timecodeRegexString } from '../common/date.js'
const timecodeRegex = new RegExp(`^(${timecodeRegexString})\\s`) const timecodeRegex = new RegExp(`^(${timecodeRegexString})\\s`)
export function parseChapters (text: string, maxTitleLength: number) { export function parseChapters (text: string) {
if (!text) return [] if (!text) return []
const lines = text.split(/\r?\n|\r|\n/g) 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 timecode = timeToInt(timecodeText)
const title = line.replace(matched[0], '') 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 return chapters
if (chapters.length > 1) return chapters
return []
} }

View File

@ -178,13 +178,13 @@ describe('Test video chapters', function () {
checkChapters(chapters) 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) await waitJobs(servers)
for (const server of servers) { for (const server of servers) {
const { chapters } = await server.chapters.list({ videoId: video.uuid }) 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' } }) 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') 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 () { after(async function () {
await cleanupTests([ server ]) await cleanupTests([ server ])
}) })

View File

@ -221,38 +221,25 @@ describe('Parse semantic version string', function () {
describe('Extract chapters', function () { describe('Extract chapters', function () {
it('Should not extract chapters', function () { it('Should not extract chapters', function () {
expect(parseChapters('my super description\nno?', 100)).to.deep.equal([]) expect(parseChapters('my super description\nno?')).to.deep.equal([])
expect(parseChapters('m00:00 super description\nno?', 100)).to.deep.equal([]) expect(parseChapters('m00:00 super description\nno?')).to.deep.equal([])
expect(parseChapters('00:00super description\nno?', 100)).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', 100)).to.deep.equal([]) expect(parseChapters('my super description\n'.repeat(10) + ' * list1\n * list 2\n * list 3')).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 () { it('Should extract chapters', function () {
expect(parseChapters('00:00 coucou\n00:05 hello', 100)).to.deep.equal([ expect(parseChapters('00:00 coucou')).to.deep.equal([ { timecode: 0, title: 'coucou' } ])
{ timecode: 0, title: 'coucou' }, expect(parseChapters('my super description\n\n00:01:30 chapter 1\n00:01:35 chapter 2')).to.deep.equal([
{ 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: 90, title: 'chapter 1' },
{ timecode: 95, title: 'chapter 2' } { 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: 90, title: 'chapter 1' },
{ timecode: 95, title: 'chapter 2' } { 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: 90, title: 'chapter 1' },
{ timecode: 95, title: 'chapter 2' } { 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 # 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) let user = await UserModel.loadByEmail(bypassLogin.user.email)
if (!user) { if (!user) user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user)
user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user) else user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
} else if (user.pluginAuth === bypassLogin.pluginName) {
user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
}
// Cannot create a user // Cannot create a user
if (!user) throw new AccessDeniedError('Cannot create such user: an actor with that name already exists.') 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) { 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) 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 { MVideoImmutable } from '@server/types/models/index.js'
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { InternalEventEmitter } from './internal-event-emitter.js' import { InternalEventEmitter } from './internal-event-emitter.js'
import { CONSTRAINTS_FIELDS } from '@server/initializers/constants.js'
const lTags = loggerTagsFactory('video', 'chapters') const lTags = loggerTagsFactory('video', 'chapters')
@ -45,7 +44,7 @@ export async function replaceChaptersFromDescriptionIfNeeded (options: {
}) { }) {
const { transaction, video, newDescription, oldDescription = '' } = 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) const existingChapters = await VideoChapterModel.listChaptersOfVideo(video.id, transaction)
logger.debug( logger.debug(
@ -55,7 +54,7 @@ export async function replaceChaptersFromDescriptionIfNeeded (options: {
// Then we can update chapters from the new description // Then we can update chapters from the new description
if (areSameChapters(chaptersFromOldDescription, existingChapters)) { 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 if (chaptersFromOldDescription.length === 0 && chaptersFromNewDescription.length === 0) return false
await replaceChapters({ video, chapters: chaptersFromNewDescription, transaction }) await replaceChapters({ video, chapters: chaptersFromNewDescription, transaction })

View File

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

View File

@ -9766,10 +9766,10 @@ components:
description: P2P peers connected (doesn't include WebSeed peers) description: P2P peers connected (doesn't include WebSeed peers)
resolutionChanges: resolutionChanges:
type: number 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: errors:
type: number type: number
description: How many errors occurred since the last metric creation description: How many errors occured since the last metric creation
downloadedBytesP2P: downloadedBytesP2P:
type: number type: number
description: How many bytes were downloaded with P2P since the last metric creation 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 ### Publishing

View File

@ -185,7 +185,7 @@ peertube-runner list-registered
## Server tools ## 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. They must be run on the server, in `peertube-latest` directory.
### Parse logs ### Parse logs