mirror of https://github.com/FreeTubeApp/FreeTube
Move local API player cache internals into the main process (#5068)
This commit is contained in:
parent
71b7c60b68
commit
7685d75e79
|
@ -4,8 +4,6 @@ const IpcChannels = {
|
|||
DISABLE_PROXY: 'disable-proxy',
|
||||
OPEN_EXTERNAL_LINK: 'open-external-link',
|
||||
GET_SYSTEM_LOCALE: 'get-system-locale',
|
||||
GET_USER_DATA_PATH: 'get-user-data-path',
|
||||
GET_USER_DATA_PATH_SYNC: 'get-user-data-path-sync',
|
||||
GET_PICTURES_PATH: 'get-pictures-path',
|
||||
SHOW_OPEN_DIALOG: 'show-open-dialog',
|
||||
SHOW_SAVE_DIALOG: 'show-save-dialog',
|
||||
|
@ -26,7 +24,10 @@ const IpcChannels = {
|
|||
SYNC_PLAYLISTS: 'sync-playlists',
|
||||
|
||||
GET_REPLACE_HTTP_CACHE: 'get-replace-http-cache',
|
||||
TOGGLE_REPLACE_HTTP_CACHE: 'toggle-replace-http-cache'
|
||||
TOGGLE_REPLACE_HTTP_CACHE: 'toggle-replace-http-cache',
|
||||
|
||||
PLAYER_CACHE_GET: 'player-cache-get',
|
||||
PLAYER_CACHE_SET: 'player-cache-set'
|
||||
}
|
||||
|
||||
const DBActions = {
|
||||
|
|
|
@ -199,10 +199,12 @@ function runApp() {
|
|||
app.commandLine.appendSwitch('enable-features', 'VaapiVideoDecodeLinuxGL')
|
||||
}
|
||||
|
||||
const userDataPath = app.getPath('userData')
|
||||
|
||||
// command line switches need to be added before the app ready event first
|
||||
// that means we can't use the normal settings system as that is asynchronous,
|
||||
// doing it synchronously ensures that we add it before the event fires
|
||||
const REPLACE_HTTP_CACHE_PATH = `${app.getPath('userData')}/experiment-replace-http-cache`
|
||||
const REPLACE_HTTP_CACHE_PATH = `${userDataPath}/experiment-replace-http-cache`
|
||||
const replaceHttpCache = existsSync(REPLACE_HTTP_CACHE_PATH)
|
||||
if (replaceHttpCache) {
|
||||
// the http cache causes excessive disk usage during video playback
|
||||
|
@ -211,6 +213,8 @@ function runApp() {
|
|||
app.commandLine.appendSwitch('disable-http-cache')
|
||||
}
|
||||
|
||||
const PLAYER_CACHE_PATH = `${userDataPath}/player_cache`
|
||||
|
||||
// See: https://stackoverflow.com/questions/45570589/electron-protocol-handler-not-working-on-windows
|
||||
// remove so we can register each time as we run the app.
|
||||
app.removeAsDefaultProtocolClient('freetube')
|
||||
|
@ -866,14 +870,6 @@ function runApp() {
|
|||
return app.getSystemLocale()
|
||||
})
|
||||
|
||||
ipcMain.handle(IpcChannels.GET_USER_DATA_PATH, () => {
|
||||
return app.getPath('userData')
|
||||
})
|
||||
|
||||
ipcMain.on(IpcChannels.GET_USER_DATA_PATH_SYNC, (event) => {
|
||||
event.returnValue = app.getPath('userData')
|
||||
})
|
||||
|
||||
ipcMain.handle(IpcChannels.GET_PICTURES_PATH, () => {
|
||||
return app.getPath('pictures')
|
||||
})
|
||||
|
@ -938,6 +934,35 @@ function runApp() {
|
|||
relaunch()
|
||||
})
|
||||
|
||||
function playerCachePathForKey(key) {
|
||||
// Remove path separators and period characters,
|
||||
// to prevent any files outside of the player_cache directory,
|
||||
// from being read or written
|
||||
const sanitizedKey = `${key}`.replaceAll(/[./\\]/g, '__')
|
||||
|
||||
return path.join(PLAYER_CACHE_PATH, sanitizedKey)
|
||||
}
|
||||
|
||||
ipcMain.handle(IpcChannels.PLAYER_CACHE_GET, async (_, key) => {
|
||||
const filePath = playerCachePathForKey(key)
|
||||
|
||||
try {
|
||||
const contents = await asyncFs.readFile(filePath)
|
||||
return contents.buffer
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return undefined
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.handle(IpcChannels.PLAYER_CACHE_SET, async (_, key, value) => {
|
||||
const filePath = playerCachePathForKey(key)
|
||||
|
||||
await asyncFs.mkdir(PLAYER_CACHE_PATH, { recursive: true })
|
||||
|
||||
await asyncFs.writeFile(filePath, new Uint8Array(value))
|
||||
})
|
||||
|
||||
// ************************************************* //
|
||||
// DB related IPC calls
|
||||
// *********** //
|
||||
|
|
|
@ -1,43 +1,21 @@
|
|||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
import { IpcChannels } from '../../../constants'
|
||||
|
||||
import { pathExists } from '../filesystem'
|
||||
|
||||
// based off https://github.com/LuanRT/YouTube.js/blob/6caa679df6ddc77d25be02dcb7355b722ab268aa/src/utils/Cache.ts
|
||||
// avoids errors caused by the fully dynamic `fs` and `path` module imports that youtubei.js's UniversalCache does
|
||||
export class PlayerCache {
|
||||
constructor(cacheDirectory) {
|
||||
this.cacheDirectory = cacheDirectory
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
const filePath = path.resolve(this.cacheDirectory, key)
|
||||
|
||||
try {
|
||||
const contents = await fs.readFile(filePath)
|
||||
return contents.buffer
|
||||
} catch (e) {
|
||||
if (e?.code === 'ENOENT') {
|
||||
return undefined
|
||||
}
|
||||
throw e
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
return await ipcRenderer.invoke(IpcChannels.PLAYER_CACHE_GET, key)
|
||||
}
|
||||
}
|
||||
|
||||
async set(key, value) {
|
||||
await fs.mkdir(this.cacheDirectory, { recursive: true })
|
||||
|
||||
const filePath = path.resolve(this.cacheDirectory, key)
|
||||
await fs.writeFile(filePath, new Uint8Array(value))
|
||||
}
|
||||
|
||||
async remove(key) {
|
||||
const filePath = path.resolve(this.cacheDirectory, key)
|
||||
|
||||
if (await pathExists(filePath)) {
|
||||
try {
|
||||
await fs.unlink(filePath)
|
||||
} catch { }
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
await ipcRenderer.invoke(IpcChannels.PLAYER_CACHE_SET, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
async remove(_key) {
|
||||
// no-op; YouTube.js only uses remove for the OAuth credentials, but we don't use that in FreeTube
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ClientType, Endpoints, Innertube, Misc, UniversalCache, Utils, YT } from 'youtubei.js'
|
||||
import Autolinker from 'autolinker'
|
||||
import { join } from 'path'
|
||||
import { SEARCH_CHAR_LIMIT } from '../../../constants'
|
||||
|
||||
import { PlayerCache } from './PlayerCache'
|
||||
|
@ -9,7 +8,6 @@ import {
|
|||
calculatePublishedDate,
|
||||
escapeHTML,
|
||||
extractNumberFromString,
|
||||
getUserDataPath,
|
||||
toLocalePublicationString
|
||||
} from '../utils'
|
||||
|
||||
|
@ -41,8 +39,7 @@ async function createInnertube({ withPlayer = false, location = undefined, safet
|
|||
let cache
|
||||
if (withPlayer) {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const userData = await getUserDataPath()
|
||||
cache = new PlayerCache(join(userData, 'player_cache'))
|
||||
cache = new PlayerCache()
|
||||
} else {
|
||||
cache = new UniversalCache(false)
|
||||
}
|
||||
|
|
|
@ -611,16 +611,6 @@ export async function getSystemLocale() {
|
|||
return locale || 'en-US'
|
||||
}
|
||||
|
||||
export async function getUserDataPath() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
return await ipcRenderer.invoke(IpcChannels.GET_USER_DATA_PATH)
|
||||
} else {
|
||||
// TODO: implement getUserDataPath web compatible callback
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export async function getPicturesPath() {
|
||||
if (process.env.IS_ELECTRON) {
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
|
Loading…
Reference in New Issue