]> git.proxmox.com Git - proxmox-backup.git/blob - www/Utils.js
ui: utils: eslint format fixes
[proxmox-backup.git] / www / Utils.js
1 Ext.ns('PBS');
2
3 console.log("Starting Backup Server GUI");
4
5 Ext.define('PBS.Utils', {
6 singleton: true,
7
8 updateLoginData: function(data) {
9 Proxmox.Utils.setAuthData(data);
10 },
11
12 dataStorePrefix: 'DataStore-',
13
14 cryptmap: [
15 'none',
16 'mixed',
17 'sign-only',
18 'encrypt',
19 ],
20
21 cryptText: [
22 Proxmox.Utils.noText,
23 gettext('Mixed'),
24 gettext('Signed'),
25 gettext('Encrypted'),
26 ],
27
28 cryptIconCls: [
29 '',
30 '',
31 'lock faded',
32 'lock good',
33 ],
34
35 calculateCryptMode: function(data) {
36 let mixed = data.mixed;
37 let encrypted = data.encrypt;
38 let signed = data['sign-only'];
39 let files = data.count;
40 if (mixed > 0) {
41 return PBS.Utils.cryptmap.indexOf('mixed');
42 } else if (files === encrypted && encrypted > 0) {
43 return PBS.Utils.cryptmap.indexOf('encrypt');
44 } else if (files === signed && signed > 0) {
45 return PBS.Utils.cryptmap.indexOf('sign-only');
46 } else if ((signed+encrypted) === 0) {
47 return PBS.Utils.cryptmap.indexOf('none');
48 } else {
49 return PBS.Utils.cryptmap.indexOf('mixed');
50 }
51 },
52
53 noSubKeyHtml: 'You do not have a valid subscription for this server. Please visit <a target="_blank" href="https://www.proxmox.com/proxmox-backup-server/pricing">www.proxmox.com</a> to get a list of available options.',
54
55 getDataStoreFromPath: function(path) {
56 return path.slice(PBS.Utils.dataStorePrefix.length);
57 },
58
59 isDataStorePath: function(path) {
60 return path.indexOf(PBS.Utils.dataStorePrefix) === 0;
61 },
62
63 parsePropertyString: function(value, defaultKey) {
64 var res = {},
65 error;
66
67 if (typeof value !== 'string' || value === '') {
68 return res;
69 }
70
71 Ext.Array.each(value.split(','), function(p) {
72 var kv = p.split('=', 2);
73 if (Ext.isDefined(kv[1])) {
74 res[kv[0]] = kv[1];
75 } else if (Ext.isDefined(defaultKey)) {
76 if (Ext.isDefined(res[defaultKey])) {
77 error = 'defaultKey may be only defined once in propertyString';
78 return false; // break
79 }
80 res[defaultKey] = kv[0];
81 } else {
82 error = 'invalid propertyString, not a key=value pair and no defaultKey defined';
83 return false; // break
84 }
85 return true;
86 });
87
88 if (error !== undefined) {
89 console.error(error);
90 return null;
91 }
92
93 return res;
94 },
95
96 printPropertyString: function(data, defaultKey) {
97 var stringparts = [],
98 gotDefaultKeyVal = false,
99 defaultKeyVal;
100
101 Ext.Object.each(data, function(key, value) {
102 if (defaultKey !== undefined && key === defaultKey) {
103 gotDefaultKeyVal = true;
104 defaultKeyVal = value;
105 } else if (value !== '' && value !== undefined) {
106 stringparts.push(key + '=' + value);
107 }
108 });
109
110 stringparts = stringparts.sort();
111 if (gotDefaultKeyVal) {
112 stringparts.unshift(defaultKeyVal);
113 }
114
115 return stringparts.join(',');
116 },
117
118 // helper for deleting field which are set to there default values
119 delete_if_default: function(values, fieldname, default_val, create) {
120 if (values[fieldname] === '' || values[fieldname] === default_val) {
121 if (!create) {
122 if (values.delete) {
123 if (Ext.isArray(values.delete)) {
124 values.delete.push(fieldname);
125 } else {
126 values.delete += ',' + fieldname;
127 }
128 } else {
129 values.delete = [fieldname];
130 }
131 }
132
133 delete values[fieldname];
134 }
135 },
136
137
138 render_datetime_utc: function(datetime) {
139 let pad = (number) => number < 10 ? '0' + number : number;
140 return datetime.getUTCFullYear() +
141 '-' + pad(datetime.getUTCMonth() + 1) +
142 '-' + pad(datetime.getUTCDate()) +
143 'T' + pad(datetime.getUTCHours()) +
144 ':' + pad(datetime.getUTCMinutes()) +
145 ':' + pad(datetime.getUTCSeconds()) +
146 'Z';
147 },
148
149 render_datastore_worker_id: function(id, what) {
150 const res = id.match(/^(\S+?)_(\S+?)_(\S+?)(_(.+))?$/);
151 if (res) {
152 let datastore = res[1], backupGroup = `${res[2]}/${res[3]}`;
153 if (res[4] !== undefined) {
154 let datetime = Ext.Date.parse(parseInt(res[5], 16), 'U');
155 let utctime = PBS.Utils.render_datetime_utc(datetime);
156 return `Datastore ${datastore} ${what} ${backupGroup}/${utctime}`;
157 } else {
158 return `Datastore ${datastore} ${what} ${backupGroup}`;
159 }
160 }
161 return `Datastore ${what} ${id}`;
162 },
163
164 parse_datastore_worker_id: function(type, id) {
165 let result;
166 let res;
167 if (type.startsWith('verif')) {
168 res = PBS.Utils.VERIFICATION_JOB_ID_RE.exec(id);
169 if (res) {
170 result = res[1];
171 }
172 } else if (type.startsWith('sync')) {
173 res = PBS.Utils.SYNC_JOB_ID_RE.exec(id);
174 if (res) {
175 result = res[3];
176 }
177 } else if (type === 'backup') {
178 res = PBS.Utils.BACKUP_JOB_ID_RE.exec(id);
179 if (res) {
180 result = res[1];
181 }
182 } else if (type === 'garbage_collection') {
183 return id;
184 } else if (type === 'prune') {
185 return id;
186 }
187
188
189 return result;
190 },
191
192 extractTokenUser: function(tokenid) {
193 return tokenid.match(/^(.+)!([^!]+)$/)[1];
194 },
195
196 extractTokenName: function(tokenid) {
197 return tokenid.match(/^(.+)!([^!]+)$/)[2];
198 },
199
200 render_estimate: function(value) {
201 if (!value) {
202 return gettext('Not enough data');
203 }
204
205 let now = new Date();
206 let estimate = new Date(value*1000);
207
208 let timespan = (estimate - now)/1000;
209
210 if (Number(estimate) <= Number(now) || isNaN(timespan)) {
211 return gettext('Never');
212 }
213
214 let duration = Proxmox.Utils.format_duration_human(timespan);
215 return Ext.String.format(gettext("in {0}"), duration);
216 },
217
218 render_size_usage: function(val, max) {
219 if (max === 0) {
220 return gettext('N/A');
221 }
222 return (val*100/max).toFixed(2) + '% (' +
223 Ext.String.format(gettext('{0} of {1}'),
224 Proxmox.Utils.format_size(val), Proxmox.Utils.format_size(max)) + ')';
225 },
226
227 get_help_tool: function(blockid) {
228 let info = Proxmox.Utils.get_help_info(blockid);
229 if (info === undefined) {
230 info = Proxmox.Utils.get_help_info('pbs_documentation_index');
231 }
232 if (info === undefined) {
233 throw "get_help_info failed"; // should not happen
234 }
235
236 let docsURI = window.location.origin + info.link;
237 let title = info.title;
238 if (info.subtitle) {
239 title += ' - ' + info.subtitle;
240 }
241 return {
242 type: 'help',
243 tooltip: title,
244 handler: function() {
245 window.open(docsURI);
246 },
247 };
248 },
249
250 constructor: function() {
251 var me = this;
252
253 let PROXMOX_SAFE_ID_REGEX = "([A-Za-z0-9_][A-Za-z0-9._-]*)";
254 // only anchored at beginning
255 // only parses datastore for now
256 me.VERIFICATION_JOB_ID_RE = new RegExp("^" + PROXMOX_SAFE_ID_REGEX + ':?');
257 me.SYNC_JOB_ID_RE = new RegExp("^" + PROXMOX_SAFE_ID_REGEX + ':' +
258 PROXMOX_SAFE_ID_REGEX + ':' + PROXMOX_SAFE_ID_REGEX + ':');
259 me.BACKUP_JOB_ID_RE = new RegExp("^" + PROXMOX_SAFE_ID_REGEX + ':');
260
261 // do whatever you want here
262 Proxmox.Utils.override_task_descriptions({
263 backup: (type, id) => PBS.Utils.render_datastore_worker_id(id, gettext('Backup')),
264 dircreate: [gettext('Directory Storage'), gettext('Create')],
265 dirremove: [gettext('Directory'), gettext('Remove')],
266 garbage_collection: ['Datastore', gettext('Garbage collect')],
267 logrotate: [null, gettext('Log Rotation')],
268 prune: (type, id) => PBS.Utils.render_datastore_worker_id(id, gettext('Prune')),
269 reader: (type, id) => PBS.Utils.render_datastore_worker_id(id, gettext('Read objects')),
270 sync: ['Datastore', gettext('Remote Sync')],
271 syncjob: [gettext('Sync Job'), gettext('Remote Sync')],
272 verify: ['Datastore', gettext('Verification')],
273 verify_group: ['Group', gettext('Verification')],
274 verify_snapshot: ['Snapshot', gettext('Verification')],
275 verificationjob: [gettext('Verify Job'), gettext('Scheduled Verification')],
276 zfscreate: [gettext('ZFS Storage'), gettext('Create')],
277 });
278 },
279 });