+import { Observable, of, Subject } from 'rxjs'
import { first, map, share, shareReplay, switchMap, tap } from 'rxjs/operators'
import { HttpClient } from '@angular/common/http'
import { Inject, Injectable, LOCALE_ID } from '@angular/core'
-import { peertubeLocalStorage } from '@app/shared/misc/peertube-web-storage'
-import { Observable, of, Subject } from 'rxjs'
-import { getCompleteLocale, ServerConfig } from '../../../../../shared'
+import { getDevLocale, isOnDevLocale, sortBy } from '@app/helpers'
+import { logger } from '@root-helpers/logger'
+import { getCompleteLocale, isDefaultLocale, peertubeTranslate } from '@shared/core-utils/i18n'
+import { HTMLServerConfig, ServerConfig, ServerStats, VideoConstant } from '@shared/models'
import { environment } from '../../../environments/environment'
-import { VideoConstant } from '../../../../../shared/models/videos'
-import { isDefaultLocale, peertubeTranslate } from '../../../../../shared/models/i18n'
-import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
-import { sortBy } from '@app/shared/misc/utils'
@Injectable()
export class ServerService {
private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
private static BASE_VIDEO_PLAYLIST_URL = environment.apiUrl + '/api/v1/video-playlists/'
private static BASE_LOCALE_URL = environment.apiUrl + '/client/locales/'
- private static CONFIG_LOCAL_STORAGE_KEY = 'server-config'
+ private static BASE_STATS_URL = environment.apiUrl + '/api/v1/server/stats'
- configReloaded = new Subject<void>()
+ configReloaded = new Subject<ServerConfig>()
private localeObservable: Observable<any>
private videoLicensesObservable: Observable<VideoConstant<number>[]>
private configReset = false
private configLoaded = false
- private config: ServerConfig = {
- instance: {
- name: 'PeerTube',
- shortDescription: 'PeerTube, a federated (ActivityPub) video streaming platform ' +
- 'using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.',
- defaultClientRoute: '',
- isNSFW: false,
- defaultNSFWPolicy: 'do_not_list' as 'do_not_list',
- customizations: {
- javascript: '',
- css: ''
- }
- },
- plugin: {
- registered: []
- },
- theme: {
- registered: [],
- default: 'default'
- },
- email: {
- enabled: false
- },
- contactForm: {
- enabled: false
- },
- serverVersion: 'Unknown',
- signup: {
- allowed: false,
- allowedForCurrentIP: false,
- requiresEmailVerification: false
- },
- transcoding: {
- enabledResolutions: [],
- hls: {
- enabled: false
- },
- webtorrent: {
- enabled: true
- }
- },
- avatar: {
- file: {
- size: { max: 0 },
- extensions: []
- }
- },
- video: {
- image: {
- size: { max: 0 },
- extensions: []
- },
- file: {
- extensions: []
- }
- },
- videoCaption: {
- file: {
- size: { max: 0 },
- extensions: []
- }
- },
- user: {
- videoQuota: -1,
- videoQuotaDaily: -1
- },
- import: {
- videos: {
- http: {
- enabled: false
- },
- torrent: {
- enabled: false
- }
- }
- },
- trending: {
- videos: {
- intervalDays: 0
- }
- },
- autoBlacklist: {
- videos: {
- ofUsers: {
- enabled: false
- }
- }
- },
- tracker: {
- enabled: true
- },
- followings: {
- instance: {
- autoFollowIndex: {
- indexUrl: 'https://instances.joinpeertube.org'
- }
- }
- }
- }
+ private config: ServerConfig
+ private htmlConfig: HTMLServerConfig
constructor (
private http: HttpClient,
@Inject(LOCALE_ID) private localeId: string
) {
- this.loadConfigLocally()
+ }
+
+ loadHTMLConfig () {
+ try {
+ this.loadHTMLConfigLocally()
+ } catch (err) {
+ // Expected in dev mode since we can't inject the config in the HTML
+ if (environment.production !== false) {
+ logger.error('Cannot load config locally. Fallback to API.')
+ }
+
+ return this.getConfig()
+ }
}
getServerVersionAndCommit () {
resetConfig () {
this.configLoaded = false
this.configReset = true
+
+ // Notify config update
+ return this.getConfig()
}
getConfig () {
if (!this.configObservable) {
this.configObservable = this.http.get<ServerConfig>(ServerService.BASE_CONFIG_URL)
.pipe(
- tap(config => this.saveConfigLocally(config)),
tap(config => {
this.config = config
+ this.htmlConfig = config
this.configLoaded = true
}),
- tap(() => {
+ tap(config => {
if (this.configReset) {
- this.configReloaded.next()
+ this.configReloaded.next(config)
this.configReset = false
}
}),
return this.configObservable
}
- getTmpConfig () {
- return this.config
+ getHTMLConfig () {
+ return this.htmlConfig
}
getVideoCategories () {
return this.videoPlaylistPrivaciesObservable.pipe(first())
}
- getServerLocale () {
+ getServerLocale (): Observable<{ [ id: string ]: string }> {
if (!this.localeObservable) {
const completeLocale = isOnDevLocale() ? getDevLocale() : getCompleteLocale(this.localeId)
return this.localeObservable.pipe(first())
}
+ getServerStats () {
+ return this.http.get<ServerStats>(ServerService.BASE_STATS_URL)
+ }
+
private loadAttributeEnum <T extends string | number> (
baseUrl: string,
attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
.pipe(map(data => ({ data, translations })))
}),
map(({ data, translations }) => {
- const hashToPopulate: VideoConstant<T>[] = []
+ const hashToPopulate: VideoConstant<T>[] = Object.keys(data)
+ .map(dataKey => {
+ const label = data[dataKey]
- Object.keys(data)
- .forEach(dataKey => {
- const label = data[ dataKey ]
+ const id = attributeName === 'languages'
+ ? dataKey as T
+ : parseInt(dataKey, 10) as T
- hashToPopulate.push({
- id: (attributeName === 'languages' ? dataKey : parseInt(dataKey, 10)) as T,
- label: peertubeTranslate(label, translations)
- })
- })
+ return {
+ id,
+ label: peertubeTranslate(label, translations)
+ }
+ })
if (sort === true) sortBy(hashToPopulate, 'label')
)
}
- private saveConfigLocally (config: ServerConfig) {
- peertubeLocalStorage.setItem(ServerService.CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config))
- }
-
- private loadConfigLocally () {
- const configString = peertubeLocalStorage.getItem(ServerService.CONFIG_LOCAL_STORAGE_KEY)
-
- if (configString) {
- try {
- const parsed = JSON.parse(configString)
- Object.assign(this.config, parsed)
- } catch (err) {
- console.error('Cannot parse config saved in local storage.', err)
- }
+ private loadHTMLConfigLocally () {
+ // FIXME: typings
+ const configString = (window as any)['PeerTubeServerConfig']
+ if (!configString) {
+ throw new Error('Could not find PeerTubeServerConfig in HTML')
}
+
+ this.htmlConfig = JSON.parse(configString)
}
}