Skip to content

Commit

Permalink
Updated helpers.
Browse files Browse the repository at this point in the history
  • Loading branch information
regorxxx committed Dec 23, 2021
1 parent 9fcf49e commit 13e909b
Show file tree
Hide file tree
Showing 11 changed files with 238 additions and 51 deletions.
7 changes: 6 additions & 1 deletion _TIPS and INSTALLATION.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,19 @@ any problem with it.
(**) If you upgraded to >1.6 from an older portable version then it may be possible that the 'profile' folder does not exist.
In such case you have to create it and move all the config folders/files to it, where they should reside (instead of the root of the
foobar2000 installation path). Some native folders and files which must be moved include:
index-data, js_data, omponent-updates, configuration, crash reports, user-components, foo_spider_monkey_panel, library, playlists,
index-data, js_data, component-updates, configuration, crash reports, user-components, foo_spider_monkey_panel, library, playlists,
theme.fth, LargeFieldsConfig.txt, version.txt
Some extra folders from other components which must be moved include (non extensive list):
autobackup, dvda_metabase, foo_httpcontrol_data, foo_youtube, images, lastfm, python, sacd_metabase, vst-presets, yttm,
minibar.db, playlist-tree-0.pts, playlist-tree-1.pts,
If you don't move all the config folders/files then on startup default values will be used for things not found, probably "losing"
the theme or other config. You may "fix" it later moving the missing files which still reside in the root. May take some tries to do them all.

SMP 1.5.2 BUG:
-------------
After properly installing the files, if Foobar2000 SMP panels keep crashing due to 'missing files', check '_switchPaths.zip'.
Follow its instructions to fix it. Then report it at https://hydrogenaud.io/index.php?topic=116669.0 and hopefully it will be fixed.

PORTABLE TIP:
-------------
Some scripts have configurable paths to save json data, track playlists, etc. Those can be found on the properties panel.
Expand Down
81 changes: 79 additions & 2 deletions helpers/helpers_xxx.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict';
//08/10/21
//19/12/21
include(fb.ComponentPath + 'docs\\Codepages.js');
include(fb.ComponentPath + 'docs\\Flags.js');
include('helpers_xxx_basic_js.js');
include('helpers_xxx_console.js');
include('helpers_xxx_foobar.js');

/*
Global Variables
Expand All @@ -24,4 +25,80 @@ const iDelaySBDCache = 15; // ms per step for playlist processing: playlist mana

// Console log file
conLog = fb.ProfilePath + 'console.log'; // Edit here to change logging file. Replace with '' or null to disable logging
conLogMaxSize = 5000000; // File size, in bytes. Setting to zero or null disables logging too
conLogMaxSize = 5000000; // File size, in bytes. Setting to zero or null disables logging too

// Linux features
const soFeat = getSoFeatures();
// CheckSoFeatures(soFeat);

function getSoFeatures() {
const soFeat = {gecko: true, clipboard: true, dpi: true, recycle: true, gdiplus: true, segoe: true, bio: true}
const WshShell = new ActiveXObject('WScript.Shell');
const app = new ActiveXObject('Shell.Application');
let doc;
// Internals
try {doc = new ActiveXObject('htmlfile');} catch (e) {soFeat.gecko = false;}
if (typeof doc !== 'undefined' && soFeat.gecko) {
let clText = 'test';
try {doc.parentWindow.clipboardData.setData('Text', clText); clText = doc.parentWindow.clipboardData.getData('Text');} catch (e) {soFeat.clipboard = false;}
if (clText !== 'test') {soFeat.clipboard = false;}
} else {soFeat.clipboard = false;}
// File system
if (typeof app !== 'undefined') {
try {app.NameSpace(10).MoveHere(null);} catch (e) {soFeat.recycle = false;}
} else {soFeat.recycle = false;}
// Scripting
if (utils.IsFile && utils.IsFile(fb.ProfilePath + 'yttm\\foo_lastfm_img.vbs')) {
try {
new ActiveXObject("Scripting.FileSystemObject");
new ActiveXObject("MSXML2.XMLHTTP");
new ActiveXObject("ADODB.Stream");
} catch (e) {soFeat.bio = false;}
}
// UI
if (typeof WshShell !== 'undefined') {
try {WshShell.RegRead('HKCU\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI');} catch (e) {soFeat.dpi = false;}
} else {soFeat.dpi = false;}
if (!utils.CheckFont('Arial')) {
soFeat.gdiplus = false;
}
if (!utils.CheckFont('Segoe UI')) {
soFeat.segoe = false;
}
return soFeat;
}

function CheckSoFeatures(soFeat) {
let bPass = true;
// Internals
if (!soFeat.gecko) {
fb.ShowPopupMessage('Found an issue on current installation:\nActiveXObject_Constructor failed:\nFailed to create ActiveXObject object via CLSID: htmlfile.\n\nFix: install \'Gecko\' package.\n' + 'https://wiki.winehq.org/Gecko', 'SO features');
bPass = false;
} else if (!soFeat.clipboard) {
fb.ShowPopupMessage('Found an issue on current installation:\nclipboardData failed.\n\nFix: Install IE8 with Winetricks.\n' + 'https://wiki.winehq.org/Winetricks' + '\n' + 'https://askubuntu.com/questions/1194126/problem-in-installing-internet-explorer-8' + '\n\nWARNING:\nApplying this fix will break internet connection on current profile.\ni.e. Bio Script config popup will work but image downloading will be broken. It\'s therefore recommended to don\'t apply this fix on online systems.', 'SO features');
bPass = false;
}
// File system
if (!soFeat.recycle) {
// Not sure if there is an alternative (?)
bPass = false;
}
// Scripting
if (!soFeat.bio) {
fb.ShowPopupMessage('Found an issue on current installation:\nMissing scripting components for vbs integration (BIO panel).\n\nFix: Install \'wsh57\' and \'mdac28\' with Winetricks.\n' + 'https://wiki.winehq.org/Winetricks' + '\n\nTerminal command:\n' + 'sh winetricks wsh57 mdac28' + '\n\nFix: Also msado15 needs to be aded to the dll overrides in Winecfg:\n' + 'https://hydrogenaud.io/index.php?topic=121786.msg1005447#msg1005447' +'\n' + 'https://itectec.com/ubuntu/ubuntu-how-to-override-a-dll-without-using-the-winecfg-gui-in-wine/' + '\n' + 'https://wiki.winehq.org/Wine_User%27s_Guide#WINEDLLOVERRIDES.3DDLL_Overrides', 'SO features');
bPass = false;
}
// UI
if (!soFeat.dpi) {
fb.ShowPopupMessage('Found an issue on current installation:\nRegistry entry not found:\nHKCU\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI\n\nFix: add entry to registry.\n' + 'HKCU\\Control Panel\\Desktop\\WindowMetrics\\AppliedDPI ---> 96\n\nCMD command:\n' + 'reg.exe ADD "HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics" /v AppliedDPI /t REG_DWORD /d 96', 'SO features');
bPass = false;
}
if (!soFeat.gdiplus) {
fb.ShowPopupMessage('Found an issue on current installation:\nFonts are not found via utils.CheckFont() and gdi.Font().\n\nFix: install install \'gdiplus\' package with winetricks.\n' + 'https://wiki.winehq.org/Winetricks' + '\n\nTerminal command:\n' + 'sh winetricks gdiplus', 'SO features');
bPass = false;
} else if (!soFeat.segoe) {
fb.ShowPopupMessage('Found an issue on current installation:\nSegoe UI font is missing.\n\nFix: install missing font.\n' + 'https://github.com/mrbvrz/segoe-ui-linux', 'SO features');
bPass = false;
}
return bPass;
}
13 changes: 8 additions & 5 deletions helpers/helpers_xxx_UI.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
//14/11/21
//16/12/21

include(fb.ComponentPath + 'docs\\Flags.js');
include('helpers_xxx_UI_chars.js');
Expand All @@ -9,16 +9,16 @@ include('helpers_xxx_UI_chars.js');
*/

// Callbacks: append to any previously existing callback
function onScriptUnload() {
function onScriptUnloadUI() {
window.Tooltip.Deactivate();
}
if (on_script_unload) {
const oldFunc = on_script_unload;
on_script_unload = function() {
oldFunc();
onScriptUnload();
onScriptUnloadUI();
};
} else {var on_script_unload = onScriptUnload;}
} else {var on_script_unload = onScriptUnloadUI;}

const WshShellUI = new ActiveXObject('WScript.Shell');
const _bmp = gdi.CreateImage(1, 1);
Expand Down Expand Up @@ -187,8 +187,9 @@ function _tt(value, font = 'Segoe UI', fontsize = _scale(10), width = 600) {
this.tooltip.SetFont(font, fontsize);
this.width = width;
this.tooltip.SetMaxWidth(width);
this.text = this.tooltip.text = value;
this.text = this.tooltip.Text = value;
this.oldDelay = this.tooltip.GetDelayTime(3); //TTDT_INITIAL
this.bActive = false;

this.SetValue = function (value, bForceActivate = false) {
if (value === null) {
Expand All @@ -213,10 +214,12 @@ function _tt(value, font = 'Segoe UI', fontsize = _scale(10), width = 600) {

this.Activate = function () {
this.tooltip.Activate();
this.bActive = true;
};

this.Deactivate = function () {
this.tooltip.Deactivate();
this.bActive = false;
};

this.SetDelayTime = function (type, time) {
Expand Down
21 changes: 20 additions & 1 deletion helpers/helpers_xxx_basic_js.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
//07/10/21
//13/12/21

// https://github.com/angus-c/just
/*
Expand Down Expand Up @@ -172,4 +172,23 @@ function convertObjectToString(object, separator = ',') {
}
return output;
}
}

function SetReplacer(key, value) {
if (typeof value === 'object' && value instanceof Set) {return [...value];}
return value;
}

/*
Script including
*/
let module = {}, exports = {};
module.exports = null;

function require(script) {
let newScript = script;
['helpers-external', 'main', 'examples', 'buttons'].forEach((folder) => {newScript.replace(new RegExp('^\.\\\\' + folder + '\\\\', 'i'), '..\\' + folder + '\\');});
['helpers'].forEach((folder) => {newScript.replace(new RegExp('^\.\\\\' + folder + '\\\\', 'i'), '');});
include(newScript + '.js') ;
return module.exports;
}
12 changes: 10 additions & 2 deletions helpers/helpers_xxx_console.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
//08/10/21
//02/12/21

include(fb.ComponentPath + 'docs\\Codepages.js');

Expand Down Expand Up @@ -61,4 +61,12 @@ if (conLog && conLog.length && conLogMaxSize && console.log) {
utils.WriteTextFile(conLog, '', false);
console.log('helpers_xxx: console log file size exceeds ' + (conLogMaxSize / 10000000) + ' MB, creating new file: ' + conLog);
}
}
}

// Send to popup and console
console.popup = (arg, popupName) => {
fb.ShowPopupMessage(arg, popupName);
arg.split('\n').forEach((line) => {
if (line && line.length) {console.log(line);}
;});
}
65 changes: 57 additions & 8 deletions helpers/helpers_xxx_file.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';
//13/10/21
//21/12/21

include(fb.ComponentPath + 'docs\\Codepages.js');
include('helpers_xxx_foobar.js');
include('helpers_xxx.js');
include('helpers_xxx_prototypes.js');

/*
Expand Down Expand Up @@ -128,8 +128,11 @@ function _restoreFile(file) {
if (file.startsWith('.\\')) {file = fb.FoobarPath + file.replace('.\\','');}
const arr = isCompatible('1.4.0') ? utils.SplitFilePath(file) : utils.FileTest(file, 'split'); //TODO: Deprecated
const OriginalFileName = (arr[1].endsWith(arr[2])) ? arr[1] : arr[1] + arr[2]; // <1.4.0 Bug: [directory, filename + filename_extension, filename_extension]
const items = app.NameSpace(10).Items();
const numItems = items.Count;
let numItems, items;
try {
items = app.NameSpace(10).Items();
numItems = items.Count;
} catch (e) {return false;}
for (let i = 0; i < numItems; i++) {
if (items.Item(i).Name === OriginalFileName) {
_renameFile(items.Item(i).Path, file);
Expand Down Expand Up @@ -165,6 +168,26 @@ function _save(file, value, bBOM = false) {
return false;
}

function _saveSplitJson(file, value, replacer = void(0), space = void(0), splitBy = 50000, bBOM = false) {
if (file.startsWith('.\\')) {file = fb.FoobarPath + file.replace('.\\','');}
const filePath = isCompatible('1.4.0') ? utils.SplitFilePath(file)[0] : utils.FileTest(file, 'split')[0]; //TODO: Deprecated
if (!_isFolder(filePath)) {_createFolder(filePath);}
if (_isFolder(filePath)) {
const fileName = utils.SplitFilePath(file)[1];
const len = value.length;
const add = len > splitBy ? splitBy : len;
const count = Math.ceil(len / splitBy);
let bDone = true;
for (let i = 0; i < count; i++) {
const newFilename = file.replace(fileName, fileName + i);
bDone = bDone && _save(newFilename, JSON.stringify(value.slice(i * add, ((i + 1) * add < len ? (i + 1) * add : len)), replacer, space), bBOM);
}
return bDone;
}
console.log('Error saving to ' + file);
return false;
}

function _jsonParse(value) {
try {
let data = JSON.parse(value);
Expand All @@ -178,12 +201,24 @@ function _jsonParseFile(file, codePage = 0) {
return _jsonParse(_open(file, codePage));
}

function _jsonParseFileSplit(filePath, reportName = 'Json', popupName = window.Name, codePage = 0) {
const [path, fileName, extension] = utils.SplitFilePath(filePath);
const files = utils.Glob(path + '\\' + fileName + '*' + extension);
let result = [];
for (let file of files) {
const data = _jsonParseFile(file, codePage);
if (data) {result = result.concat(data);}
else {return null;}
}
return result;
}

function _jsonParseFileCheck(file, fileName = 'Json', popupName = window.Name, codePage = 0) {
let data = null;
if (_isFile(file)) {
data = _jsonParseFile(file, codePage);
if (!data && utils.GetFileSize(file)) {
console.log(fileName + ' file is corrupt:\n', file);
console.log(fileName + ' file is corrupt:', file);
fb.ShowPopupMessage(fileName + ' file is corrupt:\n' + file, popupName);
}
} else {
Expand Down Expand Up @@ -222,11 +257,20 @@ function _run() {
}
}

function _runHidden() {
try {
WshShell.Run([...arguments].map((arg) => {return _q(arg);}).join(' '), 0, true);
return true;
} catch (e) {
return false;
}
}

function _runCmd(command, wait) {
try {
WshShell.Run(command, 0, wait);
} catch (e) {
console.log('_runCmd(): failed to run command ' + command);
console.log('_runCmd(): failed to run command ' + command + '(' + e + ')');
}
}

Expand Down Expand Up @@ -272,8 +316,8 @@ function checkCodePage(originalText, extension, bAdvancedCheck = false) {
else if (extension === '.m3u' && plsText.length >= 2 && plsText[1].startsWith('#EXTENC:')) {
const codepageName = plsText[1].split(':').pop();
if (codepageName) {codepage = convertCharsetToCodepage(codepageName);}
} else if ((extension === '.xspf' || extension === '.asx') && plsText.length >= 2 && plsText[0].indexOf('encoding=') !== -1) {
const codepageName = plsText[0].match(/"[\S]*"/g).pop().replace(/"/g,'');
} else if ((extension === '.xspf' || extension === '.asx' || extension === '.xsp') && plsText.length >= 2 && plsText[0].indexOf('encoding=') !== -1) {
const codepageName = plsText[0].match(/encoding="([\S]*)"/).pop();
if (codepageName) {codepage = convertCharsetToCodepage(codepageName);}
} else if (bAdvancedCheck) {
if (plsText.length && plsText.some((line) => {
Expand Down Expand Up @@ -351,4 +395,9 @@ function UUID() {
const rnd = Math.random() * 16 | 0, v = c === 'x' ? rnd : (rnd&0x3|0x8) ;
return v.toString(16);
});
}

function lastModified(file, bParse = false) {
if (!_isFile(file)) {return -1;}
return bParse ? Date.parse(fso.GetFile(file).DateLastModified) : fso.GetFile(file).DateLastModified;
}
Loading

0 comments on commit 13e909b

Please sign in to comment.