Skip to content

Commit db236ca

Browse files
committed
v17.3.9b
- The cache system has been overhauled to allow better control of disk space usage for cache storage. - Added the option to limit disk space usage in Options > Advanced > Developer Options > Enable disk cache. - Improvements in the option to add the list by Mac address. We need testers.
1 parent 54f418e commit db236ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1249
-1200
lines changed

www/nodejs-project/assets/js/app/app.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ function initApp(){
268268
const element = data.tabindex == -1 ? document.querySelector('.explorer-location-icon i') : explorer.currentElements[data.tabindex]
269269
const isCover = element && !data.alpha && (config['stretch-logos'] || (entry && entry.class && entry.class.indexOf('entry-force-cover') != -1))
270270
const bg = 'url("' + data.url + '")' // keep quotes
271-
console.warn('THUMB',{isCover, data, entry})
272271
const m = () => {
273272
let d, g = document.createElement('img')
274273
if(isCover){

www/nodejs-project/assets/js/app/electron.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ const fs = require('fs'), path = require('path')
1818

1919
class FFmpegDownloader {
2020
constructor(){}
21-
dl(){
22-
return getElectronRemote().getGlobal('Download')
23-
}
2421
async download(target, osd, mask) {
25-
const Download = this.dl()
2622
const tmpZipFile = path.join(target, 'ffmpeg.zip')
2723
const arch = process.arch == 'x64' ? 64 : 32
2824
let osName
@@ -40,11 +36,11 @@ class FFmpegDownloader {
4036
const variant = osName + '-' + arch
4137
const url = await this.getVariantURL(variant)
4238
osd.show(mask.replace('{0}', '0%'), 'fas fa-circle-notch fa-spin', 'ffmpeg-dl', 'persistent')
43-
await Download.file({
39+
await process.download({
4440
url,
4541
file: tmpZipFile,
4642
progress: p => {
47-
osd.show(mask.replace('{0}', p + '%'), 'fas fa-circle-notch fa-spin', 'ffmpeg-dl', 'persistent')
43+
Manager.app.osd.show(mask.replace('{0}', p + '%'), 'fas fa-circle-notch fa-spin', 'ffmpeg-dl', 'persistent')
4844
}
4945
})
5046
const AdmZip = require('adm-zip')
@@ -80,10 +76,9 @@ class FFmpegDownloader {
8076
return false
8177
}
8278
async getVariantURL(variant){
83-
const Download = this.dl()
84-
const data = await Download.get({url: 'https://ffbinaries.com/api/v1/versions', responseType: 'json'})
79+
const data = await process.download({url: 'https://ffbinaries.com/api/v1/versions', responseType: 'json'})
8580
for(const version of Object.keys(data.versions).sort().reverse()){
86-
const versionInfo = await Download.get({url: data.versions[version], responseType: 'json'})
81+
const versionInfo = await process.download({url: data.versions[version], responseType: 'json'})
8782
if(versionInfo.bin && typeof(versionInfo.bin[variant]) != 'undefined'){
8883
return versionInfo.bin[variant].ffmpeg
8984
}
@@ -100,8 +95,12 @@ class FFMpeg extends FFmpegDownloader {
10095
this.executable += '.exe'
10196
}
10297
this.executableDir = process.resourcesPath || path.resolve('ffmpeg')
98+
this.executableDir = this.executableDir.replace(new RegExp('\\\\', 'g'), '/')
99+
if(this.executableDir.indexOf('resources/app') != -1) {
100+
this.executableDir = this.executableDir.split('resources/app').shift() +'resources'
101+
}
103102
this.executable = path.basename(this.executable)
104-
this.tmpdir = require('os').tmpdir()
103+
this.tmpdir = process.paths.temp
105104
}
106105
isMetadata(s){
107106
return s.indexOf('Stream mapping:') != -1

www/nodejs-project/bin-debug.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ findElectronExecutable().then(electronPath => {
6464
child.on('error', (error) => {
6565
console.error(error);
6666
});
67-
child.on('close', (code) => {
67+
child.once('close', (code) => {
6868
console.log('exitcode: '+ code)
6969
process.exit(code);
7070
});

www/nodejs-project/main.js

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ process.on('uncaughtException', (exception) => {
6262
return false
6363
})
6464

65-
global.storage = require('./modules/storage')({main: true})
66-
6765
global.onexit(() => {
6866
global.isExiting = true
6967
console.error('APP_EXIT='+ traceback())
@@ -106,7 +104,9 @@ global.uiReady = (f, done) => {
106104
return ready
107105
}
108106

109-
global.config = require('./modules/config')(global.paths['data'] + '/config.json')
107+
const Storage = require('./modules/storage')
108+
global.config = require('./modules/config')(global.paths.data + '/config.json')
109+
global.storage = new Storage({main: true})
110110
global.Download = require('./modules/download')
111111
global.jimp = null
112112

@@ -172,7 +172,7 @@ let playOnLoaded, tuningHintShown, showingSlowBroadcastDialog
172172
global.updateUserTasks = async app => {
173173
if(process.platform != 'win32') return
174174
if(app) { // set from cache, Electron won't set after window is opened
175-
const tasks = await global.storage.promises.get('user-tasks')
175+
const tasks = await global.storage.get('user-tasks')
176176
if(tasks && !app.setUserTasks(tasks)) {
177177
throw 'Failed to set user tasks. '+ JSON.stringify(tasks)
178178
}
@@ -207,7 +207,10 @@ global.updateUserTasks = async app => {
207207
iconIndex: 0
208208
}
209209
})
210-
await global.storage.promises.set('user-tasks', tasks, true)
210+
await global.storage.set('user-tasks', tasks, {
211+
expiration: true,
212+
permanent: true
213+
})
211214
}
212215

213216
const videoErrorTimeoutCallback = ret => {
@@ -283,11 +286,10 @@ const init = (language, timezone) => {
283286
global.options = new Options()
284287
global.watching = new Watching()
285288
global.bookmarks = new Bookmarks()
286-
global.icons = new IconServer({folder: global.paths['data'] + '/icons'})
289+
global.icons = new IconServer({folder: global.paths['data'] + '/icons'})
290+
global.explorer = new Explorer({})
287291

288292
global.rmdir(global.streamer.opts.workDir, false, true)
289-
290-
global.explorer = new Explorer({})
291293

292294
console.log('Initializing premium...')
293295
Premium = require('./modules/premium-helper')
@@ -534,7 +536,7 @@ const init = (language, timezone) => {
534536
group: []
535537
}
536538
}
537-
global.storage.raw.set('open-url', url, true)
539+
global.config.set('open-url', url)
538540
global.lists.manager.waitListsReady().then(() => {
539541
if(isStreamerReady){
540542
global.streamer.play(e)
@@ -852,6 +854,7 @@ if(global.cordova) {
852854
global.ui.on(k, (...args) => global.ui.emit('electron-window-'+ k, ...args))
853855
})
854856
window.on('resize', updateMetrics)
857+
window.on('closed', () => window.closed = true) // prevent bridge IPC error
855858
global.ui.setElectronWindow(window)
856859
}
857860

www/nodejs-project/modules/bookmarks/bookmarks.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const EntriesGroup = require('../entries-group')
44
class Bookmarks extends EntriesGroup {
55
constructor(){
66
super('bookmarks')
7+
this.storeInConfig = true
78
this.currentBookmarkAddingByName = {
89
name: '',
910
live: true,

www/nodejs-project/modules/bridge/bridge.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ class ElectronChannel extends BaseChannel {
5050
super()
5151
}
5252
customEmit(...args){
53-
this.window && this.window.webContents.send('message', this.prepareSerialization(args))
53+
this.window && !this.window.closed && this.window.webContents.send('message',
54+
this.prepareSerialization(args)
55+
)
5456
}
5557
}
5658

@@ -136,6 +138,8 @@ class BridgeServer extends Events {
136138
}
137139
})
138140
this.server.listen(0, this.opts.addr, err => {
141+
if(err) console.error(err)
142+
if(!this.server) return
139143
this.opts.port = this.server.address().port
140144
console.log('Bridge server started', err)
141145
this.uploadURL = 'http://' + this.opts.addr + ':' + this.opts.port + '/upload'

www/nodejs-project/modules/channels/channels.js

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,10 @@ class ChannelsList {
1212
if(this.type && this.type != 'lists') this.key += '-'+ this.type
1313
}
1414
async load() {
15-
let fine, data = await global.storage.raw.promises.get(this.key).catch(console.error)
15+
let fine, data = await global.storage.get(this.key).catch(console.error)
1616
if(data){
17-
try {
18-
let cs = global.parseJSON(data)
19-
if(!Object.keys(cs).length){
20-
throw 'Empty list'
21-
}
22-
this.categories = cs
23-
fine = true
24-
} catch(e) {
25-
console.error(e)
26-
}
17+
this.categories = data
18+
fine = true
2719
}
2820
if(!fine) {
2921
let err
@@ -47,7 +39,7 @@ class ChannelsList {
4739
}
4840
async reset() {
4941
delete this.categories
50-
await global.storage.raw.promises.delete(this.key).catch(console.error)
42+
await global.storage.delete(this.key).catch(console.error)
5143
global.config.set('channel-grid', '')
5244
await this.load()
5345
}
@@ -202,7 +194,10 @@ class ChannelsList {
202194
})
203195
this.categories = ordering
204196
this.updateChannelsIndex(true)
205-
await global.storage.raw.promises.set(this.key, JSON.stringify(this.categories, null, 3), true)
197+
await global.storage.set(this.key, this.categories, {
198+
permanent: true,
199+
expiration: true
200+
})
206201
}
207202
destroy() {
208203
this.destroyed = true
@@ -1607,7 +1602,7 @@ class Channels extends ChannelsKids {
16071602
type: 'select',
16081603
fa: 'fas fa-step-forward',
16091604
renderer: () => {
1610-
return new Promise((resolve, reject) => {
1605+
return new Promise(resolve => {
16111606
let def = global.config.get('watch-now-auto'), opts = [
16121607
{name: global.lang.AUTO, type: 'action', selected: (def == 'auto'), action: data => {
16131608
global.config.set('watch-now-auto', 'auto')
@@ -1664,7 +1659,6 @@ class Channels extends ChannelsKids {
16641659
return entries
16651660
}
16661661
const renderer = async group => {
1667-
console.error('GROUP='+ JSON.stringify(group))
16681662
let entries = await global.lists.group(group).catch(global.displayErr)
16691663
if(Array.isArray(entries)) {
16701664
let gentries = (group.entries || []).map(g => groupToEntry(g))
@@ -1675,7 +1669,7 @@ class Channels extends ChannelsKids {
16751669
} else if(typeof(entry.renderer) == 'function') {
16761670
entries = await entry.renderer(entry)
16771671
} else if(typeof(entry.renderer) == 'string') {
1678-
entries = await global.storage.temp.promises.get(entry.renderer)
1672+
entries = await global.storage.get(entry.renderer)
16791673
} else {
16801674
break
16811675
}

www/nodejs-project/modules/cloud/cloud.js

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -82,58 +82,67 @@ class CloudConfiguration {
8282
throw "cloud data \'"+ key +"\' not found"
8383
}
8484
const expiralKey = key.split('/')[0].split('.')[0]
85-
const store = raw === true ? global.storage.raw : global.storage
86-
let data = await store.promises.get(this.cachingDomain + key).catch(console.error)
85+
const permanent = ['configure'].includes(expiralKey)
86+
let data = await global.storage.get(this.cachingDomain + key).catch(console.error)
8787
if(data){
8888
if(this.debug){
8989
console.log('cloud: got cache', key)
9090
}
9191
return data
92-
} else {
92+
}
93+
if(this.debug){
94+
console.log('cloud: no cache fallback', key)
95+
}
96+
const url = this.url(key)
97+
let err, err2, body = await global.Download.get({
98+
url,
99+
retry: 10,
100+
timeout: 60,
101+
responseType: raw === true ? 'text' : 'json',
102+
cacheTTL: this.expires[expiralKey] || 300,
103+
encoding: 'utf8'
104+
}).catch(e => err = e)
105+
if(this.debug){
106+
console.log('cloud: got '+ JSON.stringify({key, err, body}))
107+
}
108+
// use validator here only for minor overhead, so we'll not cache any bad data
109+
const succeeded = !err && body && (typeof(validator) != 'function' || validator(body))
110+
if(this.debug){
111+
console.log('cloud: got '+ JSON.stringify({key, succeeded}))
112+
}
113+
if(succeeded){
93114
if(this.debug){
94-
console.log('cloud: no cache', key)
115+
console.log('cloud: got', key, body, this.expires[expiralKey])
95116
}
96-
if(this.debug){
97-
console.log('cloud: fallback', key)
117+
if(typeof(this.expires[expiralKey]) != 'undefined'){
118+
global.storage.set(this.cachingDomain + key, body, {ttl: this.expires[expiralKey], permanent})
119+
global.storage.set(this.cachingDomain + key + '-fallback', body, {expiration: true, permanent})
120+
} else {
121+
console.error('"'+ key +'" is not cacheable (no expires set)')
98122
}
99-
const url = this.url(key)
100-
let err, err2, body = await global.Download.get({
101-
url,
102-
retry: 10,
103-
timeout: 60,
104-
responseType: raw === true ? 'text' : 'json',
105-
cacheTTL: this.expires[expiralKey] || 300,
106-
encoding: 'utf8'
107-
}).catch(e => err = e)
108123
if(this.debug){
109-
console.log('cloud: got', key, err, body)
110-
}
111-
// use validator here only for minor overhead, so we'll not cache any bad data
112-
const succeeded = !err && body && (typeof(validator) != 'function' || validator(body))
113-
if(succeeded){
114-
if(this.debug){
115-
console.log('cloud: got', key, body, this.expires[expiralKey])
116-
}
117-
if(typeof(this.expires[expiralKey]) != 'undefined'){
118-
store.set(this.cachingDomain + key, body, this.expires[expiralKey])
119-
store.set(this.cachingDomain + key + '-fallback', body, true)
120-
} else {
121-
console.error('"'+ key +'" is not cacheable (no expires set)')
122-
}
123-
if(this.debug){
124-
console.log('cloud: got', key, body, this.expires[expiralKey])
125-
}
126-
return body
127-
} else {
128-
data = await store.promises.get(this.cachingDomain + key + '-fallback').catch(e => err2 = e)
129-
if(data && !err2){
130-
return data
131-
} else {
132-
if(err && String(err).endsWith('404')) this.notFound.push(key)
133-
throw err || 'empty response, no fallback for '+url
134-
}
124+
console.log('cloud: got', key, body, this.expires[expiralKey])
135125
}
126+
return body
127+
}
128+
if(this.debug){
129+
console.log('cloud: get fallback '+ JSON.stringify({key}))
130+
}
131+
data = await global.storage.get(this.cachingDomain + key + '-fallback').catch(e => err2 = e)
132+
if(this.debug){
133+
console.log('cloud: get fallback* '+ JSON.stringify({key, data, err2}))
134+
}
135+
if(data && !err2){
136+
return data
137+
}
138+
if(err && String(err).endsWith('404')) {
139+
this.notFound.push(key)
140+
}
141+
if(this.debug){
142+
console.log('cloud: get fallback** '+ JSON.stringify({key, err, url}))
136143
}
144+
if(!err) err = 'empty response, no fallback for '+ url
145+
throw err
137146
}
138147
async discovery(adder){
139148
const timeoutMs = 30000

www/nodejs-project/modules/config/defaults.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ module.exports = {
6363
'F11 Alt+Enter': 'FULLSCREEN',
6464
'F12 Ctrl+Shift+I': 'DEVTOOLS'
6565
},
66-
'in-disk-caching': true,
66+
'in-disk-caching-size': 1024,
6767
'kids-fun-titles': true,
6868
'lists': [],
6969
'live-window-time': 180,

www/nodejs-project/modules/discovery/discovery.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ class PublicIPTVListsDiscovery extends Events {
2828
})
2929
this.on('found', () => this.save().catch(console.error))
3030
this.saver = new Limiter(() => {
31-
global.storage.set(this.key, this.knownLists, true)
31+
global.storage.set(this.key, this.knownLists, {
32+
permanent: true,
33+
expiration: true
34+
})
3235
}, 10000)
3336
this.restore().catch(console.error)
3437
const iptv = new IPTVOrgProvider()
@@ -42,7 +45,7 @@ class PublicIPTVListsDiscovery extends Events {
4245
})
4346
}
4447
async restore(){
45-
const data = await global.storage.promises.get(this.key).catch(console.error)
48+
const data = await global.storage.get(this.key).catch(console.error)
4649
Array.isArray(data) && this.add(data)
4750
}
4851
async save(){

www/nodejs-project/modules/discovery/providers/iptv-org.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class IPTV extends Events {
2020
}
2121
}
2222
async ready(){
23-
return new Promise((resolve, reject) => {
23+
await new Promise((resolve, reject) => {
2424
if(this.isReady){
2525
resolve()
2626
} else {

0 commit comments

Comments
 (0)