show quota in stats, display quota on the about page, fixes #405 (#421)
[oweals/peertube.git] / client / src / app / core / server / server.service.ts
1 import { HttpClient } from '@angular/common/http'
2 import { Injectable } from '@angular/core'
3 import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
4 import 'rxjs/add/operator/do'
5 import { ReplaySubject } from 'rxjs/ReplaySubject'
6 import { ServerConfig } from '../../../../../shared'
7 import { About } from '../../../../../shared/models/server/about.model'
8 import { ServerStats } from '../../../../../shared/models/server/server-stats.model'
9 import { environment } from '../../../environments/environment'
10
11 @Injectable()
12 export class ServerService {
13   private static BASE_CONFIG_URL = environment.apiUrl + '/api/v1/config/'
14   private static BASE_VIDEO_URL = environment.apiUrl + '/api/v1/videos/'
15   private static CONFIG_LOCAL_STORAGE_KEY = 'server-config'
16
17   configLoaded = new ReplaySubject<boolean>(1)
18   videoPrivaciesLoaded = new ReplaySubject<boolean>(1)
19   videoCategoriesLoaded = new ReplaySubject<boolean>(1)
20   videoLicencesLoaded = new ReplaySubject<boolean>(1)
21   videoLanguagesLoaded = new ReplaySubject<boolean>(1)
22
23   private config: ServerConfig = {
24     instance: {
25       name: 'PeerTube',
26       shortDescription: 'PeerTube, a federated (ActivityPub) video streaming platform  ' +
27                         'using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.',
28       defaultClientRoute: '',
29       customizations: {
30         javascript: '',
31         css: ''
32       }
33     },
34     serverVersion: 'Unknown',
35     signup: {
36       allowed: false
37     },
38     transcoding: {
39       enabledResolutions: []
40     },
41     avatar: {
42       file: {
43         size: { max: 0 },
44         extensions: []
45       }
46     },
47     video: {
48       image: {
49         size: { max: 0 },
50         extensions: []
51       },
52       file: {
53         extensions: []
54       }
55     },
56     user: {
57       videoQuota: -1
58     }
59   }
60   private videoCategories: Array<{ id: number, label: string }> = []
61   private videoLicences: Array<{ id: number, label: string }> = []
62   private videoLanguages: Array<{ id: number, label: string }> = []
63   private videoPrivacies: Array<{ id: number, label: string }> = []
64
65   constructor (private http: HttpClient) {
66     this.loadConfigLocally()
67   }
68
69   loadConfig () {
70     this.http.get<ServerConfig>(ServerService.BASE_CONFIG_URL)
71       .do(this.saveConfigLocally)
72       .subscribe(data => {
73         this.config = data
74
75         this.configLoaded.next(true)
76       })
77   }
78
79   loadVideoCategories () {
80     return this.loadVideoAttributeEnum('categories', this.videoCategories, this.videoCategoriesLoaded, true)
81   }
82
83   loadVideoLicences () {
84     return this.loadVideoAttributeEnum('licences', this.videoLicences, this.videoLicencesLoaded)
85   }
86
87   loadVideoLanguages () {
88     return this.loadVideoAttributeEnum('languages', this.videoLanguages, this.videoLanguagesLoaded, true)
89   }
90
91   loadVideoPrivacies () {
92     return this.loadVideoAttributeEnum('privacies', this.videoPrivacies, this.videoPrivaciesLoaded)
93   }
94
95   getConfig () {
96     return this.config
97   }
98
99   getVideoCategories () {
100     return this.videoCategories
101   }
102
103   getVideoLicences () {
104     return this.videoLicences
105   }
106
107   getVideoLanguages () {
108     return this.videoLanguages
109   }
110
111   getVideoPrivacies () {
112     return this.videoPrivacies
113   }
114
115   getAbout () {
116     return this.http.get<About>(ServerService.BASE_CONFIG_URL + '/about')
117   }
118
119   private loadVideoAttributeEnum (
120     attributeName: 'categories' | 'licences' | 'languages' | 'privacies',
121     hashToPopulate: { id: number, label: string }[],
122     notifier: ReplaySubject<boolean>,
123     sort = false
124   ) {
125     return this.http.get(ServerService.BASE_VIDEO_URL + attributeName)
126        .subscribe(data => {
127          Object.keys(data)
128                .forEach(dataKey => {
129                  hashToPopulate.push({
130                    id: parseInt(dataKey, 10),
131                    label: data[dataKey]
132                  })
133                })
134
135          if (sort === true) {
136            hashToPopulate.sort((a, b) => {
137              if (a.label < b.label) return -1
138              if (a.label === b.label) return 0
139              return 1
140            })
141          }
142
143          notifier.next(true)
144        })
145   }
146
147   private saveConfigLocally (config: ServerConfig) {
148     peertubeLocalStorage.setItem(ServerService.CONFIG_LOCAL_STORAGE_KEY, JSON.stringify(config))
149   }
150
151   private loadConfigLocally () {
152     const configString = peertubeLocalStorage.getItem(ServerService.CONFIG_LOCAL_STORAGE_KEY)
153
154     if (configString) {
155       try {
156         const parsed = JSON.parse(configString)
157         Object.assign(this.config, parsed)
158       } catch (err) {
159         console.error('Cannot parse config saved in local storage.', err)
160       }
161     }
162   }
163 }