Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cf843c3f12 | ||
![]() |
6966f37c4b | ||
![]() |
4fd8d34175 | ||
![]() |
c6047e1573 | ||
![]() |
f51bafb3fa | ||
![]() |
f9e710e7d4 | ||
![]() |
7a953a6b2f |
|
@ -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
|
||||
|
||||
|
@ -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#L522
|
||||
* `transcoding.webtorrent` must be **renamed** to `transcoding.web_videos`: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L532
|
||||
* `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#L263
|
||||
* Tracing requires `--experimental-loader=@opentelemetry/instrumentation/hook.mjs` node option: https://github.com/Chocobozzz/PeerTube/blob/develop/config/production.yaml.example#L264
|
||||
|
||||
#### Developers important notes
|
||||
|
||||
|
|
|
@ -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 []
|
||||
}
|
||||
|
|
|
@ -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' } })
|
||||
await servers[0].videos.update({ id: video.uuid, attributes: { description: '00:01 chapter 1\n00:03 chapter 2' } })
|
||||
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' } ])
|
||||
expect(chapters).to.deep.equal([ { timecode: 1, title: 'chapter 1' }, { timecode: 3, title: 'chapter 2' } ])
|
||||
}
|
||||
|
||||
await servers[0].videos.update({ id: video.uuid, attributes: { description: 'null description' } })
|
||||
|
|
|
@ -242,6 +242,29 @@ 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 ])
|
||||
})
|
||||
|
|
|
@ -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' }
|
||||
])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -4,4 +4,4 @@ set -eu
|
|||
|
||||
# Backward path compatibility now upgrade.sh is in dist/scripts since v6
|
||||
|
||||
/bin/sh ../dist/scripts/upgrade.sh
|
||||
/bin/sh ../dist/scripts/upgrade.sh $1
|
||||
|
|
|
@ -89,8 +89,11 @@ 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 user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
|
||||
if (!user) {
|
||||
user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user)
|
||||
} else if (user.pluginAuth === bypassLogin.pluginName) {
|
||||
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.')
|
||||
|
|
|
@ -38,7 +38,7 @@ export async function moveToJob (options: {
|
|||
}
|
||||
|
||||
if (video.VideoStreamingPlaylists) {
|
||||
logger.debug('Moving HLS playlist of %s.', video.uuid)
|
||||
logger.debug('Moving HLS playlist of %s.', video.uuid, lTags)
|
||||
|
||||
await moveHLSFiles(video)
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -873,6 +873,8 @@ export class UserModel extends Model<Partial<AttributesOnly<UserModel>>> {
|
|||
}
|
||||
|
||||
isPasswordMatch (password: string) {
|
||||
if (!password || !this.password) return false
|
||||
|
||||
return comparePassword(password, this.password)
|
||||
}
|
||||
|
||||
|
|
|
@ -9766,10 +9766,10 @@ components:
|
|||
description: P2P peers connected (doesn't include WebSeed peers)
|
||||
resolutionChanges:
|
||||
type: number
|
||||
description: How many resolution changes occured since the last metric creation
|
||||
description: How many resolution changes occurred since the last metric creation
|
||||
errors:
|
||||
type: number
|
||||
description: How many errors occured since the last metric creation
|
||||
description: How many errors occurred since the last metric creation
|
||||
downloadedBytesP2P:
|
||||
type: number
|
||||
description: How many bytes were downloaded with P2P since the last metric creation
|
||||
|
|
|
@ -870,7 +870,7 @@ function register ({ registerClientRoute }) {
|
|||
}
|
||||
```
|
||||
|
||||
You can then access the page on `/p/my-super/route` (please note the additionnal `/p/` in the path).
|
||||
You can then access the page on `/p/my-super/route` (please note the additional `/p/` in the path).
|
||||
|
||||
### Publishing
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ peertube-runner list-registered
|
|||
|
||||
## Server tools
|
||||
|
||||
Server tools are scripts that interect directly with the code of your PeerTube instance.
|
||||
Server tools are scripts that interact directly with the code of your PeerTube instance.
|
||||
They must be run on the server, in `peertube-latest` directory.
|
||||
|
||||
### Parse logs
|
||||
|
|
Loading…
Reference in New Issue
Block a user