Skip to content

Commit cb3d142

Browse files
committed
Add setting to keep chrome window open (closes #51)
1 parent 72d6ca0 commit cb3d142

File tree

5 files changed

+81
-32
lines changed

5 files changed

+81
-32
lines changed

preload.js

+40-15
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const SharedownAPI = (() => {
3737
const _logsFolderPath = _path.normalize(_sharedownAppDataPath+'/logs');
3838
const _logFilePath = _path.normalize(_logsFolderPath+'/sharedownLog.log');
3939
const _ytdlpLogFilePath = _path.normalize(_logsFolderPath+'/ytdlp.log');
40+
let _puppyBrowser = null;
4041
let _showDownlInfo = false;
4142
let _runningProcess = null;
4243
let _stoppingProcess = false;
@@ -609,6 +610,11 @@ const SharedownAPI = (() => {
609610
_fs.unlinkSync(path);
610611
}
611612

613+
function _browserDisconnectedEvt() {
614+
_puppyBrowser?.close();
615+
_puppyBrowser = null;
616+
}
617+
612618
function _sortURLsFromFolder(vURLsList, sortType) {
613619
const sorted = [];
614620
const ret = [];
@@ -707,21 +713,20 @@ const SharedownAPI = (() => {
707713
await kt.deletePassword('sharedown', 'loginmodule');
708714
}
709715

710-
api.runPuppeteerGetVideoData = async (video, loginData, tmout, enableUserdataFold, customChromePath, isDirect = false) => {
716+
api.runPuppeteerGetVideoData = async (video, loginData, tmout, enableUserdataFold, customChromePath, keepBrowserOpen, isDirect = false) => {
711717
const knownResponses = [
712718
'RenderListDataAsStream?@a1=', 'RenderListDataAsStream?@listUrl',
713719
'SP.List.GetListDataAsStream?listFullUrl'
714720
];
715721
const puppy = require('puppeteer');
716722
const puppyTimeout = tmout * 1000;
717-
let browser = null;
718723
let ret = null;
719724

720725
_startCatchResponse = false;
721726

722-
723727
try {
724-
browser = await puppy.launch(_getPuppeteerArgs(customChromePath, enableUserdataFold));
728+
if (_puppyBrowser === null)
729+
_puppyBrowser = await puppy.launch(_getPuppeteerArgs(customChromePath, enableUserdataFold));
725730

726731
const responseList = [];
727732
const catchResponse = function(resp) {
@@ -735,7 +740,7 @@ const SharedownAPI = (() => {
735740
if ((resType === 'fetch' || resType === 'xhr') && (method === 'post' || method === 'get'))
736741
responseList.push(resp);
737742
}
738-
const page = (await browser.pages())[0];
743+
const page = (await _puppyBrowser.pages())[0];
739744
let matchedResponse = null;
740745
let donorRespData = null;
741746
let videoUrl;
@@ -744,6 +749,11 @@ const SharedownAPI = (() => {
744749
let dlData;
745750
let vID;
746751

752+
if (keepBrowserOpen) {
753+
_puppyBrowser.off('disconnected', _browserDisconnectedEvt)
754+
_puppyBrowser.on('disconnected', _browserDisconnectedEvt);
755+
}
756+
747757
if (customChromePath)
748758
api.writeLog('WARNING: custom chrome executable, Sharedown may not work as expected!');
749759

@@ -813,13 +823,18 @@ const SharedownAPI = (() => {
813823
cookies = null;
814824
}
815825

816-
await browser.close();
826+
if (!keepBrowserOpen) {
827+
await _puppyBrowser.close();
828+
_puppyBrowser = null;
829+
}
817830

818831
ret = {m: videoUrl, t: title, c: cookies};
819832

820833
} catch (e) {
821-
if (browser)
822-
await browser.close();
834+
if (!keepBrowserOpen && _puppyBrowser) {
835+
await _puppyBrowser.close();
836+
_puppyBrowser = null;
837+
}
823838

824839
api.writeLog(`runPuppeteerGetVideoData: error\n${e.message}`);
825840
api.showMessage('error', e.message, 'Puppeteer Error');
@@ -828,19 +843,24 @@ const SharedownAPI = (() => {
828843
return ret;
829844
}
830845

831-
api.runPuppeteerGetURLListFromFolder = async (folderURLsList, includeSubFolds, sortType, loginData, tmout, enableUserdataFold) => {
846+
api.runPuppeteerGetURLListFromFolder = async (folderURLsList, includeSubFolds, sortType, loginData, tmout, keepBrowserOpen, enableUserdataFold) => {
832847
const puppy = require('puppeteer');
833848
const puppyTimeout = tmout * 1000;
834-
let browser = null;
835849

836850
try {
837-
browser = await puppy.launch(_getPuppeteerArgs('', enableUserdataFold));
851+
if (_puppyBrowser === null)
852+
_puppyBrowser = await puppy.launch(_getPuppeteerArgs('', enableUserdataFold));
838853

839-
const page = (await browser.pages())[0];
854+
const page = (await _puppyBrowser.pages())[0];
840855
const regex = new RegExp(/\/sites\/([^\/]+)/);
841856
const match = folderURLsList[0].match(regex);
842857
const ret = {list: []};
843858

859+
if (keepBrowserOpen) {
860+
_puppyBrowser.off('disconnected', _browserDisconnectedEvt)
861+
_puppyBrowser.on('disconnected', _browserDisconnectedEvt);
862+
}
863+
844864
api.writeLog("runPuppeteerGetURLListFromFolder: start");
845865
page.setDefaultTimeout(puppyTimeout);
846866
page.setDefaultNavigationTimeout(puppyTimeout);
@@ -860,13 +880,18 @@ const SharedownAPI = (() => {
860880
await _getVideoURLsInFold(ret, page, `${urlObj.origin}${urlObj.pathname}`, includeSubFolds);
861881
}
862882

863-
await browser.close();
883+
if (!keepBrowserOpen) {
884+
await _puppyBrowser.close();
885+
_puppyBrowser = null;
886+
}
864887

865888
return _sortURLsFromFolder(ret.list, sortType);
866889

867890
} catch (e) {
868-
if (browser)
869-
await browser.close();
891+
if (!keepBrowserOpen && _puppyBrowser) {
892+
await _puppyBrowser.close();
893+
_puppyBrowser = null;
894+
}
870895

871896
api.writeLog(`runPuppeteerGetURLListFromFolder: error\n${e.message}`);
872897
api.showMessage('error', e.message, 'Puppeteer Error');

sharedown/sharedown.html

+18
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,24 @@ <h5 class="modal-title">Sharedown settings</h5>
291291
</div>
292292
</div>
293293
<hr>
294+
<div class="row">
295+
<div class="col-12">
296+
<div class="form-check form-switch mb-3">
297+
<input class="form-check-input" type="checkbox" id="keepbrowopen">
298+
<label class="form-check-label" for="keepbrowopen">Keep Chrome window open</label>
299+
</div>
300+
</div>
301+
</div>
302+
<div class="row">
303+
<div class="col-12">
304+
<p class="form-text">
305+
Workaround for those cases where login session is lost on browser close event.<br><br>
306+
This will start Chrome once and never close its window.<br>
307+
It's up to the user to close the browser window once all donwloads are complete.
308+
</p>
309+
</div>
310+
</div>
311+
<hr>
294312
<div class="row">
295313
<div class="col-12">
296314
<div class="form-check form-switch mb-3">

sharedown/sharedown.js

+14-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
const sharedownApi = window.sharedown;
2020

2121
const globalSettings = {
22-
_version: 13, // internal
22+
_version: 14, // internal
2323
outputPath: '',
2424
downloader: 'yt-dlp',
2525
ytdlpTmpOut: '',
@@ -32,7 +32,8 @@ const globalSettings = {
3232
userdataFold: false,
3333
autoSaveState: true,
3434
logging: false,
35-
customChomePath: ''
35+
customChomePath: '',
36+
keepBrowserOpen: false
3637
};
3738

3839
const resources = {
@@ -167,8 +168,8 @@ async function importURLsFromFolder() {
167168
for (const inv of invalid)
168169
foldersList.splice(foldersList.indexOf(inv), 1);
169170

170-
urlList = await Utils.getFolderURLsList(resources.globalSetModal, foldersList, includeSubFolds,
171-
urlsSortType, globalSettings.timeout,
171+
urlList = await Utils.getFolderURLsList(resources.globalSetModal, foldersList, includeSubFolds, urlsSortType,
172+
globalSettings.timeout, globalSettings.keepBrowserOpen,
172173
globalSettings.userdataFold);
173174

174175
if (urlList === null || urlList.length === 0) {
@@ -342,9 +343,10 @@ async function loadGlobalSettings() {
342343
resources.globalSetModal.querySelector('#shlogs').value = globalSettings.logging ? '1':'0';
343344
resources.globalSetModal.querySelector('#retryonfail').checked = globalSettings.retryOnFail;
344345
resources.globalSetModal.querySelector('#cuschromep').value = globalSettings.customChomePath;
346+
resources.globalSetModal.querySelector('#keepbrowopen').checked = globalSettings.keepBrowserOpen;
345347

346-
if (globalSettings.userdataFold)
347-
UIUtils.chromeUsrDataChangeEvt(true, resources.globalSetModal);
348+
if (globalSettings.userdataFold || globalSettings.keepBrowserOpen)
349+
UIUtils.disableAutoLoginOptions(true, resources.globalSetModal);
348350
else if (globalSettings.useKeytar)
349351
await UIUtils.keytarCheckChangeEvt(true, resources.globalSetModal, globalSettings.loginModule);
350352

@@ -370,6 +372,7 @@ async function saveGlobalSettings() {
370372
globalSettings.timeout = isNaN(timeout) || timeout < 0 ? 30 : timeout;
371373
globalSettings.logging = shlogsInpt.value === '1' ? sharedownApi.enableLogs() : sharedownApi.disableLogs();
372374
globalSettings.customChomePath = resources.globalSetModal.querySelector('#cuschromep').value;
375+
globalSettings.keepBrowserOpen = resources.globalSetModal.querySelector('#keepbrowopen').checked;
373376

374377
shlogsInpt.value = globalSettings.logging ? '1' : '0';
375378

@@ -406,6 +409,7 @@ function importAppSettings() {
406409
globalSettings.timeout = data.timeout ?? 30;
407410
globalSettings.logging = data.logging ?? false;
408411
globalSettings.customChomePath = data.customChomePath ?? '';
412+
globalSettings.keepBrowserOpen = data.keepBrowserOpen ?? false;
409413

410414
if (data['_version'] < globalSettings['_version']) {
411415
sharedownApi.upgradeSett(data['_version']);
@@ -467,7 +471,8 @@ async function downloadVideo(videoElem) {
467471
toggleLoadingScr();
468472

469473
vdata = await Utils.getVideoData(resources.globalSetModal, resources.downloading, globalSettings.timeout,
470-
globalSettings.userdataFold, globalSettings.customChomePath, isDirectDownloader);
474+
globalSettings.userdataFold, globalSettings.customChomePath,
475+
globalSettings.keepBrowserOpen, isDirectDownloader);
471476
toggleLoadingScr();
472477

473478
sharedownApi.writeLog('downloadVideo: has vdata: ' + (vdata !== null));
@@ -598,7 +603,8 @@ window.addEventListener('DOMContentLoaded', async () => {
598603
resources.globalSetModal.querySelector('#ytdlptmpdir').addEventListener('click', e => Utils.showSelectOutputFolderDialog(e.currentTarget));
599604
resources.globalSetModal.querySelector('#cuschromepb').addEventListener('click', e => Utils.showSelectCustomChomeDialog(e.currentTarget));
600605
resources.globalSetModal.querySelector('#shddownloader').addEventListener('change', e => setDownloaderSettingsUI(e.currentTarget.value));
601-
resources.globalSetModal.querySelector('#chuserdata').addEventListener('change', e => UIUtils.chromeUsrDataChangeEvt(e.target.checked, resources.globalSetModal));
606+
resources.globalSetModal.querySelector('#chuserdata').addEventListener('change', e => UIUtils.disableAutoLoginOptions(e.target.checked, resources.globalSetModal));
607+
resources.globalSetModal.querySelector('#keepbrowopen').addEventListener('change', e => UIUtils.disableAutoLoginOptions(e.target.checked, resources.globalSetModal));
602608

603609
document.getElementById('loginmodlist').addEventListener('change', async (e) => {
604610
const keytarInpt = resources.globalSetModal.querySelector('#keytar');

sharedown/uiUtils.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ const UIUtils = (() => {
107107
globalSetModal.querySelector(`#loginModuleField${i}`).value = lmCreds[i];
108108
}
109109

110-
UIutil.chromeUsrDataChangeEvt = (isChecked, globalSetModal) => {
110+
UIutil.disableAutoLoginOptions = (isChecked, globalSetModal) => {
111111
const loginModuleInpt = globalSetModal.querySelector('#loginmodlist');
112112
const keytarInpt = globalSetModal.querySelector('#keytar');
113113
const msIDInpt = globalSetModal.querySelector('#username');

sharedown/utils.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -96,28 +96,28 @@ const Utils = (() => {
9696
await _sharedownApi.keytarRemoveLogin();
9797
}
9898

99-
util.getVideoData = async (globalSettingsModal, video, timeout, enableUserdataFold, customChromePath, isDirect) => {
100-
if (enableUserdataFold)
101-
return ( await _sharedownApi.runPuppeteerGetVideoData(video, null, timeout, true, customChromePath, isDirect) );
99+
util.getVideoData = async (globalSettingsModal, video, timeout, enableUserdataFold, customChromePath, keepBrowserOpen, isDirect) => {
100+
if (enableUserdataFold || keepBrowserOpen)
101+
return ( await _sharedownApi.runPuppeteerGetVideoData(video, null, timeout, enableUserdataFold, customChromePath, keepBrowserOpen, isDirect) );
102102

103103
const loginD = _getLoginData(globalSettingsModal);
104104

105105
if (!_isValidCustomLogin(loginD))
106106
return null;
107107

108-
return ( await _sharedownApi.runPuppeteerGetVideoData(video, loginD, timeout, false, customChromePath, isDirect) );
108+
return ( await _sharedownApi.runPuppeteerGetVideoData(video, loginD, timeout, enableUserdataFold, customChromePath, keepBrowserOpen, isDirect) );
109109
}
110110

111-
util.getFolderURLsList = async (globalSettingsModal, foldersList, includeSubFolds, urlsSortType, timeout, enableUserdataFold) => {
112-
if (enableUserdataFold)
113-
return ( await _sharedownApi.runPuppeteerGetURLListFromFolder(foldersList, includeSubFolds, urlsSortType, null, timeout, true) );
111+
util.getFolderURLsList = async (globalSettingsModal, foldersList, includeSubFolds, urlsSortType, timeout, keepBrowserOpen, enableUserdataFold) => {
112+
if (enableUserdataFold || keepBrowserOpen)
113+
return ( await _sharedownApi.runPuppeteerGetURLListFromFolder(foldersList, includeSubFolds, urlsSortType, null, timeout, keepBrowserOpen, enableUserdataFold) );
114114

115115
const loginD = _getLoginData(globalSettingsModal);
116116

117117
if (!_isValidCustomLogin(loginD))
118118
return null;
119119

120-
return ( await _sharedownApi.runPuppeteerGetURLListFromFolder(foldersList, includeSubFolds, urlsSortType, loginD, timeout, false) );
120+
return ( await _sharedownApi.runPuppeteerGetURLListFromFolder(foldersList, includeSubFolds, urlsSortType, loginD, timeout, keepBrowserOpen, enableUserdataFold) );
121121
}
122122

123123
util.getOutputFolder = (globalFolder, videoFolder) => {

0 commit comments

Comments
 (0)