mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 07:42:23 +02:00
YT: store and load decipher actions from Clapper cache dir
This commit is contained in:
@@ -4,6 +4,8 @@ imports.gi.versions.Gtk = '4.0';
|
|||||||
const { Gio, Gst } = imports.gi;
|
const { Gio, Gst } = imports.gi;
|
||||||
|
|
||||||
Gst.init(null);
|
Gst.init(null);
|
||||||
|
Gio._promisify(Gio._LocalFilePrototype, 'load_bytes_async', 'load_bytes_finish');
|
||||||
|
Gio._promisify(Gio._LocalFilePrototype, 'make_directory_async', 'make_directory_finish');
|
||||||
Gio._promisify(Gio._LocalFilePrototype, 'replace_contents_bytes_async', 'replace_contents_finish');
|
Gio._promisify(Gio._LocalFilePrototype, 'replace_contents_bytes_async', 'replace_contents_finish');
|
||||||
|
|
||||||
const { App } = imports.src.app;
|
const { App } = imports.src.app;
|
||||||
|
@@ -91,7 +91,10 @@ var YouTubeClient = GObject.registerClass({
|
|||||||
/* Decipher actions do not change too often, so try
|
/* Decipher actions do not change too often, so try
|
||||||
* to reuse without triggering too many requests ban */
|
* to reuse without triggering too many requests ban */
|
||||||
let actions = this.cachedSig.actions;
|
let actions = this.cachedSig.actions;
|
||||||
if(!actions) {
|
|
||||||
|
if(actions)
|
||||||
|
debug('using remembered decipher actions');
|
||||||
|
else {
|
||||||
const embedUri = `https://www.youtube.com/embed/${videoId}`;
|
const embedUri = `https://www.youtube.com/embed/${videoId}`;
|
||||||
const [body, isAbortedBody] =
|
const [body, isAbortedBody] =
|
||||||
await this._downloadDataPromise(embedUri).catch(debug);
|
await this._downloadDataPromise(embedUri).catch(debug);
|
||||||
@@ -118,8 +121,7 @@ var YouTubeClient = GObject.registerClass({
|
|||||||
debug(`found player URI: ${ytUri}`);
|
debug(`found player URI: ${ytUri}`);
|
||||||
|
|
||||||
const ytId = ytPath.split('/').find(el => Misc.isHex(el));
|
const ytId = ytPath.split('/').find(el => Misc.isHex(el));
|
||||||
|
actions = await this._getCacheFileActionsPromise(ytId).catch(debug);
|
||||||
/* TODO: load cache from file */
|
|
||||||
|
|
||||||
if(!actions) {
|
if(!actions) {
|
||||||
const [pBody, isAbortedPlayer] =
|
const [pBody, isAbortedPlayer] =
|
||||||
@@ -138,14 +140,12 @@ var YouTubeClient = GObject.registerClass({
|
|||||||
debug(new Error('could not extract decipher actions'));
|
debug(new Error('could not extract decipher actions'));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
debug('successfully obtained decipher actions');
|
|
||||||
|
|
||||||
if(this.cachedSig.id !== ytId) {
|
if(this.cachedSig.id !== ytId) {
|
||||||
this.cachedSig.id = ytId;
|
this.cachedSig.id = ytId;
|
||||||
this.cachedSig.actions = actions;
|
this.cachedSig.actions = actions;
|
||||||
debug('remembered current decipher actions for reuse');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug(`successfully obtained decipher actions: ${actions}`);
|
||||||
|
|
||||||
const isDeciphered = this._decipherStreamingData(
|
const isDeciphered = this._decipherStreamingData(
|
||||||
info.streamingData, actions
|
info.streamingData, actions
|
||||||
@@ -416,13 +416,32 @@ var YouTubeClient = GObject.registerClass({
|
|||||||
return `${url}&${sig}=${key}`;
|
return `${url}&${sig}=${key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createCacheFileAsync(ytId, actions)
|
async _createCacheFileAsync(ytId, actions)
|
||||||
{
|
{
|
||||||
const cachePath = GLib.get_user_cache_dir() + '/' + ytId;
|
|
||||||
const cacheFile = Gio.File.new_for_path(cachePath);
|
|
||||||
|
|
||||||
debug('saving cipher actions to cache file');
|
debug('saving cipher actions to cache file');
|
||||||
|
|
||||||
|
const ytCacheDir = Gio.File.new_for_path([
|
||||||
|
GLib.get_user_cache_dir(),
|
||||||
|
Misc.appId,
|
||||||
|
'yt-sig'
|
||||||
|
].join('/'));
|
||||||
|
|
||||||
|
for(let dir of [ytCacheDir.get_parent(), ytCacheDir]) {
|
||||||
|
if(dir.query_exists(null))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const dirCreated = await dir.make_directory_async(
|
||||||
|
GLib.PRIORITY_DEFAULT,
|
||||||
|
null,
|
||||||
|
).catch(debug);
|
||||||
|
|
||||||
|
if(!dirCreated) {
|
||||||
|
debug(new Error(`could not create dir: ${dir.get_path()}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cacheFile = ytCacheDir.get_child(ytId);
|
||||||
cacheFile.replace_contents_bytes_async(
|
cacheFile.replace_contents_bytes_async(
|
||||||
GLib.Bytes.new_take(actions),
|
GLib.Bytes.new_take(actions),
|
||||||
null,
|
null,
|
||||||
@@ -433,6 +452,38 @@ var YouTubeClient = GObject.registerClass({
|
|||||||
.then(() => debug('saved cache file'))
|
.then(() => debug('saved cache file'))
|
||||||
.catch(debug);
|
.catch(debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getCacheFileActionsPromise(ytId)
|
||||||
|
{
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
debug('checking decipher actions from cache file');
|
||||||
|
|
||||||
|
const ytActionsFile = Gio.File.new_for_path([
|
||||||
|
GLib.get_user_cache_dir(),
|
||||||
|
Misc.appId,
|
||||||
|
'yt-sig',
|
||||||
|
ytId
|
||||||
|
].join('/'));
|
||||||
|
|
||||||
|
if(!ytActionsFile.query_exists(null)) {
|
||||||
|
debug(`no such cache file: ${ytId}`);
|
||||||
|
return resolve(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
ytActionsFile.load_bytes_async(null)
|
||||||
|
.then(result => {
|
||||||
|
const data = result[0].get_data();
|
||||||
|
if(!data || !data.length)
|
||||||
|
return reject(new Error('actions cache file is empty'));
|
||||||
|
|
||||||
|
if(data instanceof Uint8Array)
|
||||||
|
resolve(ByteArray.toString(data));
|
||||||
|
else
|
||||||
|
resolve(data);
|
||||||
|
})
|
||||||
|
.catch(err => reject(err));
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function checkYouTubeUri(uri)
|
function checkYouTubeUri(uri)
|
||||||
|
Reference in New Issue
Block a user