Skip to main content

Topic: JScript Panel (Read 49385 times) previous topic - next topic

carp (+ 1 Hidden) and 3 Guests are viewing this topic.
  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #325
This component provides the bare metal required to do it yourself!! You can read the tags from each handle as you loop through and build a new handle list if it contains tags that aren't on your "good" list.

Consider using the difference function built in to the lodash library that I use and is already bundled with the component..

Code: [Select]
// ==PREPROCESSOR==
// @import "%fb2k_component_path%samples\complete\js\lodash.min.js"
// ==/PREPROCESSOR==

https://lodash.com/docs/3.10.1#difference



Re: JScript Panel
Reply #326
Hi marc
I've come up with this to remove any unwanted tags from the list of files;

Code: [Select]
    var toKeepArray=["band", "album","artist","composer","date","genre","title","tracknumber", 
    "totaltracks", "disctype", "disctitle", "discnumber", "totaldiscs", "album artist", "musicbrainz_artistid", "musicbrainz_albumid"];
   
// Loop thru all metadb fields in this file to see which ones to keep/delete
// Firstly forms an array of all unwanted unique tag names
    var foundArray=[];
    for (var trk = 0; trk < l_handles.Count; trk++) {
        var track_metadb = l_handles.Item(trk);
        var track_fileinfo = track_metadb.GetFileInfo();

        for (flds = 0; flds < track_fileinfo.MetaCount; flds++) {
            foundArray.push(track_fileinfo.MetaName(flds));
        }
    }
// Only want one of each
    var uniqArray=_.uniq(foundArray, false);
// Now get the names of tags to remove   
    var difArray=_.difference(uniqArray, toKeepArray);
// Loop through unwanted array to form object with properties
    if (difArray.length > 0) {
        var tagobj = {};
        for (itm = 0; itm < difArray.length; itm++) {
            tagobj[difArray[itm]] = "";
        }
        var str = JSON.stringify(tagobj);
        l_handles.UpdateFileInfoFromJSON(str);
    }

However it doesn't seem to work. Any ideas would be greatfully received.

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #327
You'll want to use toLowerCase() here...

Code: [Select]
foundArray.push(track_fileinfo.MetaName(flds).toLowerCase());

MetaName seems to return differently cased strings depending on tagging format.



Re: JScript Panel
Reply #328
I've tried hard-coding the exact tag names to be removed (both in lower and upper cases) and still I can't get it to remove the tags. I've checked the resultant str variable and it contains both upper and lower case versions - sill doesn't work.

PS these are mp3 files using ID3v2.3 formatted tags if that makes any difference.

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #329
The case doesn't matter when constructing your object - it matters when using the difference function because uppercase/lowercase values are different in javascript..

Code: [Select]
var a = ["test"];
var b = ["TEST"];

var c = _.difference(a, b);

fb.trace(c); //test

c would be an empty array if the cases were the same which is what you want. I used toLowerCase to match your hardcoded values.

I tested the code and it works for me...

Before:


After:


Code:
Code: [Select]
// ==PREPROCESSOR==
// @import "%fb2k_component_path%samples\complete\js\lodash.min.js"
// ==/PREPROCESSOR==

function on_mouse_lbtn_dblclk() {
    var l_handles = plman.GetPlaylistItems(plman.ActivePlaylist);
   
     var toKeepArray=["band", "album","artist","composer","date","genre","title","tracknumber",
    "totaltracks", "disctype", "disctitle", "discnumber", "totaldiscs", "album artist", "musicbrainz_artistid", "musicbrainz_albumid"];
  
// Loop thru all metadb fields in this file to see which ones to keep/delete
// Firstly forms an array of all unwanted unique tag names
    var foundArray=[];
    for (var trk = 0; trk < l_handles.Count; trk++) {
        var track_metadb = l_handles.Item(trk);
        var track_fileinfo = track_metadb.GetFileInfo();

        for (flds = 0; flds < track_fileinfo.MetaCount; flds++) {
            foundArray.push(track_fileinfo.MetaName(flds).toLowerCase());
        }
    }
// Only want one of each
    var uniqArray=_.uniq(foundArray, false);
// Now get the names of tags to remove  
    var difArray=_.difference(uniqArray, toKeepArray);
// Loop through unwanted array to form object with properties
    if (difArray.length > 0) {
        var tagobj = {};
        for (itm = 0; itm < difArray.length; itm++) {
            tagobj[difArray[itm]] = "";
        }
        var str = JSON.stringify(tagobj);
        l_handles.UpdateFileInfoFromJSON(str);
    }
}

Blank white panel, double click to process all tracks in active playlist.

Re: JScript Panel
Reply #330
Hi marc
Thanks for your help on this.

I think I may have mis-understood the meaning of 'clearing existing tags'. I had thought that the tags with the unwanted names would not appear in the properties list. Your code leaves them behind but sets them to null or "" (not sure).

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #331
No, those tags appear in my properties dialog because they are configured in my advanced preferences. They really don't exist in the file.

Look at "comment" and "album artist". Both are empty before and after.
  • Last Edit: 01 November, 2017, 10:49:15 AM by marc2003

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #332
Just to expand on my previous post (I was out earlier on mobile so couldn't link/do screenshots), the tags appearing in my Properties dialog are defined here...



And the C++ code in the component always deletes all fields sent before attempting to add anything..

https://github.com/19379/foo-jscript-panel/blob/4d36208d172df751773ca353e41c8b62d152e3b1/src/script_interface_impl.cpp#L778

It's only on these following lines when it's determined that the values aren't empty that tags are written...

https://github.com/19379/foo-jscript-panel/blob/4d36208d172df751773ca353e41c8b62d152e3b1/src/script_interface_impl.cpp#L785L786
https://github.com/19379/foo-jscript-panel/blob/4d36208d172df751773ca353e41c8b62d152e3b1/src/script_interface_impl.cpp#L792L793
  • Last Edit: 01 November, 2017, 02:57:20 PM by marc2003

Re: JScript Panel
Reply #333
Hi marc
I understand the tags in advanced properties - thanks for the clarification.

I can't get the object method to work so what I did was to generate the object containing tags to be removed and then used _.assign to 'add' it to each object in the array solution and it works fine.

Not sure what I was doing wrong but thanks to you I now have a working solution.

  • TheQwertiest
  • [*][*]
Re: JScript Panel
Reply #334
Hey @marc2003 !
I'm trying to change value of the metadata via following code:
Code: [Select]
var file_info = metadb.GetFileInfo();
var rating_meta_idx = file_info.MetaFind('RATING');
if (rating_meta_idx === (-1 >>> 0)){
  file_info.MetaAdd('RATING',new_rating );
}
else {
  file_info.MetaSet(rating_meta_idx,new_rating );
}
But it seems, that this code does not actually modify the file, i.e. it only saves to FileInfo structure and does not save the changes to the file itself.

The following code works properly though:
Code: [Select]
var handle = fb.CreateHandleList();
handle.Add(metadb);
  handle.UpdateFileInfoFromJSON(
  JSON.stringify({
    'RATING': new_rating
  })
);

Am I missing something?

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #335
Funnily enough, I figured those methods were pointless and removed them several days ago.

https://github.com/19379/foo-jscript-panel/commit/4d36208d172df751773ca353e41c8b62d152e3b1

They were obviously part of WSH panel mod but I've never seen them used before.

edit: I suspect they could be used if I added additional methods which do the "writing" part but you know I'm what like... I don't like having multiple ways of doing the same thing and I'm incredibly lazy and incompetent.
  • Last Edit: 11 November, 2017, 12:13:08 PM by marc2003

  • TheQwertiest
  • [*][*]
Re: JScript Panel
Reply #336
Funnily enough, I figured those methods were pointless and removed them several days ago.
They were obviously part of WSH panel mod but I've never seen them used before.
I see, thanks! As long as I have a way to view and edit tags, I don't really care how I achieve that.

Quote
edit: I suspect they could be used if I added additional methods which do the "writing" part but you know I'm what like... I don't like having multiple ways of doing the same thing and I'm incredibly lazy and incompetent.
I'm glad though that we have someone that lazy and incompetent to develop this component :D

  • MojoBass
  • [*]
Re: JScript Panel
Reply #337
I am trying to use this https://pastebin.com/uJ5fjXW7  code from ExtremeHunter in a JS Panel to show the current Playlist. It is doing what is expected, however crashes eg when jumping to next title ("getPlaylistInfo" is undefined).
Can anyone help how to get this running properly (or suggest an alternative)?
Thanks, MojoBass

Re: JScript Panel
Reply #338
however crashes eg when jumping to next title ("getPlaylistInfo" is undefined).
(function getPlaylistInfo() {
...
})();
==Try the following.==
function getPlaylistInfo() {
...
};
getPlaylistInfo();

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #339
^Yep, that is exactly it. Enforcing the use of the chakra javascript engine in IE9 or above breaks those types of functions.

  • MojoBass
  • [*]
Re: JScript Panel
Reply #340
Great, works perfect!
Thanks to you, always.beta and marc2003 !! Great community here!

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #341
Quick heads up about the next release (no idea when it's coming out as I haven't added anything yet!!)

I''ve removed the gdi.CreateStyleTextRender method. Anything based on the glow text sample.txt script will no longer work.

Code: [Select]
		gdi.CreateStyleTextRender([pngmode]); (IStyleTextRender)
// pngmode: boolean, default false.
// see samples\basic\Glow Text Sample.txt

interface IStyleTextRender {
Methods:
// ---- outline mode ----
OutLineText(text_color, outline_color, outline_width);
DoubleOutLineText(text_color, outline_color1, outline_color2, outline_width1, outline_width2);
GlowText(text_color, glow_color, glow_width);

// ---- shadow ----
EnableShadow(enable);
ResetShadow();
// it's recommended to call ResetShadow() directly after EnableShadow()
Shadow(color, thickness, offset_x, offset_y);
// default shadow, used in solid shadow colour
DiffusedShadow(colour, thickness, offset_x, offset_y);
// soft shadow

// while using DiffusedShadow(), these two methods below are useful
SetShadowBackgroundColor(colour, width, height);
SetShadowBackgroundImage(img);

// ---- Render ----
// Not recommended if the flags contains something like "center". it won't
// work properly because of the lack of width and height information.
RenderStringPoint(g, str, font, x, y[, flags]);
RenderStringRect(g, str, font, x, y, w, h[, flags]);
SetPngImage(IGdiBitmap);
// Only in pngmode, the image should be a transparent image created by gdi.CreateImage().
}

  • TheQwertiest
  • [*][*]
Re: JScript Panel
Reply #342
Hey again @marc2003 !
I've found an inconsistency in the interface description and it's implementation:
In interfaces.txt plman.IsPlaylistItemSelected is described to have boolean return type, but actually it has a UINT return type.
Code: [Select]
fb.trace(typeof plman.IsPlaylistItemSelected(plman.ActivePlaylist, 0) === "boolean");
// false
This causes some checks to fail, when strong comparison is used with other bool values (i.e. '===', instead of '==').

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #343
Well spotted. It was added before my time but it should be fixed now.

  • TheQwertiest
  • [*][*]
Re: JScript Panel
Reply #344
Thanks =)

To anyone using IntelliJ WebStorm or IDEA to create\edit scripts:
I've made a JSDoc'd version of JScript's interface.txt (with param and return types specified), which can be used as plugin in IDEA/WebStorm.
This will remove all the undefined symbol warnings and will also provide some type checks, when using JScript interface.

Instructions:
  • Download and extract the archive. >>Mediafire Link<<
  • File > Settings > Languages > JavaScript > Libraries > Add... > + > Attach Directories... > Choose extracted folder
  • Last Edit: 15 November, 2017, 09:30:00 AM by TheQwertiest

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #345
Do you really need the Ultimate edition for Javascript support??

  • TheQwertiest
  • [*][*]
Re: JScript Panel
Reply #346
Do you really need the Ultimate edition for Javascript support??
Regretfully, yeah.

There is WebStorm IDE from the same dev ( https://www.jetbrains.com/webstorm ), which contains only JavaScript features from IDEA Ultimate, but has price that is much more humane ( https://www.jetbrains.com/webstorm/buy/#edition=personal ).

PS: There is a very simple way to activate Ultimate IDEA semi-permanently though (which I can't discuss here, but PM me if interested).
  • Last Edit: 15 November, 2017, 09:34:05 AM by TheQwertiest

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #347
Thanks but I'll pass. I'll continue slumming it with Notepad++ for now.  :P

  • TheQwertiest
  • [*][*]
Re: JScript Panel
Reply #348
@marc2003 :
Btw, what about interface methods that can return -1? Shouldn't their return type be INT instead of UINT? Otherwise the return value of -1 will be equal to UINT_MAX and thus will require workarounds for strong comparisons with -1:
Code: [Select]
// Example

fb.trace(file_info.MetaFind('AZAZA') === -1, file_info.MetaFind('AZAZA') === (-1 >>> 0));
// false true
  • Last Edit: 15 November, 2017, 10:54:14 AM by TheQwertiest

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: JScript Panel
Reply #349
MetaFind and InfoFind don't return -1. This is directly from the foobar2000 SDK...

https://github.com/19379/foo-jscript-panel/blob/133af6edb43598179cc7dd60ea4f4135a2a92457/foobar2000/SDK/file_info.h#L99L100

I did clarify the docs the other day when I realised it wasn't clear...

Quote
InfoFind(name);
// returns idx. if found the value will be lower than InfoCount

MetaFind(name);
// returns idx. if found the value will lower than MetaCount