Skip to main content

Topic: Filter ALL tags with title formatting (Read 475 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
Filter ALL tags with title formatting
Just as an example I want to search all fields that have a white space first char.

This works for artist
Code: [Select]
"$left(%artist%,1)" IS " "

How would something like that work for all fields?
Mp3tag beatport WSS creator (◣_◢)     https://goo.gl/YsJF8w

  • jazzthieve
  • [*][*][*][*]
Re: Filter ALL tags with title formatting
Reply #1
I don't think you can do that. not straight out of foobar anyway. You'll have to check each individual field.

If your goal is to remove leading white space best thing to do perhaps is make a bunch of format actions on the fields you want processed in a masstager script and run that script against your entire library. Use $trim(x).

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #2
You can highlight all files>right click>Properties>highlight all fields>right click>Clean up. This will remove all leading and trailing spaces from all tags.

  • Porcus
  • [*][*][*][*][*]
Re: Filter ALL tags with title formatting
Reply #3
"Clean up" also replaces underscores by spaces, so one should first filter down to NOT * HAS  _ and consider the ones with underscores separately. What more does the "Clean up" do?

I had issues with Clean up, by the way - it would hang overnight. Maybe there were too many files with too many fields. But it did not cause any harm, as it never got as far as to saving.

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #4
Must admit, I didn't know about the underscore replacement. I could write a script to do exactly what the OP wants but I'm far too tired to do it now. I'll try it out tomorrow.

Re: Filter ALL tags with title formatting
Reply #5
Thanks for the inputs guys. Good to know about that bug.

It also doesn't trim the UNSYNCED LYRICS tag.

Basically just wanted to know if there was a way to use title formatting on all tags.
I've tried this, thought it might work searching the ARTIST OR TITLE:
Code: [Select]
"$left($or(%artist%,%title%),1)" IS " "

If only regexp was supported for replacements. But from what I can see that's been suggested heaps of times. I know the trim can do this but this is as simple as it gets.

Replace
Code: [Select]
^\s+|\s+$
With:
Code: [Select]
BLANK

PS: Is there a roadmap laid out for foobar2000? (like future plans written somewhere on the webs)
  • Last Edit: 09 August, 2017, 07:20:34 PM by stevehero
Mp3tag beatport WSS creator (◣_◢)     https://goo.gl/YsJF8w

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #6
Here's a script which iterates all files/tags and then joins them together to create a query.

Requires foo_jscript_panel: https://github.com/19379/foo-jscript-panel/wiki/Requirements-&-Installation

Paste this code snippet in to a new panel.

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

var items = fb.GetLibraryItems();
var tags = [];
for (var i = 0; i < items.Count; i++) {
var f = items.Item(i).GetFileInfo();
for (var j = 0; j < f.MetaCount; j++) {
var tag = f.MetaName(j).toLowerCase();
if (!_.includes(tags, tag))
tags.push(tag);
}
f.Dispose();
}
items.Dispose();

var query = _.map(tags, function (item) {
return '"$left(%' + item + '%,1)" IS " "';
}).join(" OR ");

fb.ShowLibrarySearchUI(query);

It's blank with no UI - the usual library search window should appear populated with the query.
  • Last Edit: 09 August, 2017, 07:40:57 PM by marc2003

Re: Filter ALL tags with title formatting
Reply #7
Here's a script which iterates all files/tags and then joins them together to create a query.
It's blank with no UI - the usual library search window should appear populated with the query.
Very cool, thank you, thank you..

How hard would it be to add text to the button? The examples are way over my head.

I'll try get it to work with trailing spaces myself to learn. Will get at that over the wkd.

Edit:
Well this opens two search panels (one for left and right. Probably Ok that way)

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

var items = fb.GetLibraryItems();
var tags = [];
for (var i = 0; i < items.Count; i++) {
var f = items.Item(i).GetFileInfo();
for (var j = 0; j < f.MetaCount; j++) {
var tag = f.MetaName(j).toLowerCase();
if (!_.includes(tags, tag))
tags.push(tag);
}
f.Dispose();
}
items.Dispose();

var queryleft = _.map(tags, function (item) {
return '"$left(%' + item + '%,1)" IS " "';
}).join(" OR ");

fb.ShowLibrarySearchUI(queryleft);

var queryright = _.map(tags, function (item) {
return '"$right(%' + item + '%,1)" IS " "';
}).join(" OR ");

fb.ShowLibrarySearchUI(queryright);

  • Last Edit: 10 August, 2017, 07:18:50 PM by stevehero
Mp3tag beatport WSS creator (◣_◢)     https://goo.gl/YsJF8w

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #8
Here's one with actual buttons...

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

function get_tag_list() {
var items = fb.GetLibraryItems();
var tags = [];
for (var i = 0; i < items.Count; i++) {
var f = items.Item(i).GetFileInfo();
for (var j = 0; j < f.MetaCount; j++) {
var tag = f.MetaName(j).toLowerCase();
if (!_.includes(tags, tag))
tags.push(tag);
}
f.Dispose();
}
items.Dispose();
return tags;
}

ButtonStates = {
normal: 0,
hover: 1,
down: 2,
hide: 3
}

var g_theme = window.CreateThemeManager("Button");
var g_font = gdi.Font("Segoe UI", 12);

function SimpleButton(x, y, w, h, text, fonClick, state) {
this.state = state ? state : ButtonStates.normal;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.text = text;
this.fonClick = fonClick;

this.containXY = function (x, y) {
return (this.x <= x) && (x <= this.x + this.w) && (this.y <= y) && (y <= this.y + this.h);
}

this.changeState = function (state) {
var old = this.state;
this.state = state;
return old;
}

this.draw = function (gr) {
if (this.state == ButtonStates.hide) return;

switch (this.state)
{
case ButtonStates.normal:
g_theme.SetPartAndStateId(1, 1);
break;

case ButtonStates.hover:
g_theme.SetPartAndStateId(1, 2);
break;

case ButtonStates.down:
g_theme.SetPartAndStateId(1, 3);
break;

case ButtonStates.hide:
return;
}

g_theme.DrawThemeBackground(gr, this.x, this.y, this.w, this.h);
// RGB function is defined in docs\helpers.txt
// DT_* are defined in docs\flags.txt
gr.GdiDrawText(this.text, g_font, RGB(0,0,0), this.x, this.y, this.w, this.h, DT_CENTER| DT_VCENTER | DT_CALCRECT | DT_NOPREFIX);
}

this.onClick = function () {
this.fonClick && this.fonClick();
}
}

function drawAllButtons(gr) {
for (var i in $buttons) {
$buttons[i].draw(gr);
}
}

function chooseButton(x, y) {
for (var i in $buttons) {
if ($buttons[i].containXY(x, y) && $buttons[i].state != ButtonStates.hide) return $buttons[i];
}

return null;
}

$buttons = {
left: new SimpleButton(5, 5, 150, 26, "Find leading space", function () {
var query = _.map(get_tag_list(), function (item) {
return '"$left(%' + item + '%,1)" IS " "';
}).join(" OR ");
fb.ShowLibrarySearchUI(query);
}),
right: new SimpleButton(160, 5, 150, 26, "Find trailing space", function () {
var query = _.map(get_tag_list(), function (item) {
return '"$right(%' + item + '%,1)" IS " "';
}).join(" OR ");
fb.ShowLibrarySearchUI(query);
})
}

var cur_btn = null;
var g_down = false;

function on_paint(gr) {
gr.FillSolidRect(0, 0, window.Width, window.Height, utils.GetSysColor(15));
drawAllButtons(gr);
}

function on_mouse_move(x, y) {
var old = cur_btn;
cur_btn = chooseButton(x, y);

if (old == cur_btn) {
if (g_down) return;
} else if (g_down && cur_btn && cur_btn.state != ButtonStates.down) {
cur_btn.changeState(ButtonStates.down);
window.Repaint();
return;
}

old && old.changeState(ButtonStates.normal);
cur_btn && cur_btn.changeState(ButtonStates.hover);
window.Repaint();
}

function on_mouse_leave() {
g_down = false;

if (cur_btn) {
cur_btn.changeState(ButtonStates.normal);
window.Repaint();
}
}

function on_mouse_lbtn_down(x, y) {
g_down = true;

if (cur_btn) {
cur_btn.changeState(ButtonStates.down);
window.Repaint();
}
}

function on_mouse_lbtn_up(x, y) {
g_down = false;

if (cur_btn) {
cur_btn.onClick();
cur_btn.changeState(ButtonStates.hover);
window.Repaint();
}
}

Re: Filter ALL tags with title formatting
Reply #9
I've combined them buttons to 1 and to run the two fns for separate left and right searches. Less clicking/UI space :)

Thanks for your help. Another thing to learn.
Code: [Select]
// ==PREPROCESSOR==
// @import "%fb2k_component_path%samples\complete\js\lodash.min.js"
// @import "%fb2k_component_path%docs\flags.txt"
// @import "%fb2k_component_path%docs\helpers.txt"
// ==/PREPROCESSOR==

function get_tag_list() {
var items = fb.GetLibraryItems();
var tags = [];
for (var i = 0; i < items.Count; i++) {
var f = items.Item(i).GetFileInfo();
for (var j = 0; j < f.MetaCount; j++) {
var tag = f.MetaName(j).toLowerCase();
if (!_.includes(tags, tag))
tags.push(tag);
}
f.Dispose();
}
items.Dispose();
return tags;
}

ButtonStates = {
normal: 0,
hover: 1,
down: 2,
hide: 3
}

var g_theme = window.CreateThemeManager("Button");
var g_font = gdi.Font("Segoe UI", 12);

function SimpleButton(x, y, w, h, text, fonClick, state) {
this.state = state ? state : ButtonStates.normal;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.text = text;
this.fonClick = fonClick;

this.containXY = function (x, y) {
return (this.x <= x) && (x <= this.x + this.w) && (this.y <= y) && (y <= this.y + this.h);
}

this.changeState = function (state) {
var old = this.state;
this.state = state;
return old;
}

this.draw = function (gr) {
if (this.state == ButtonStates.hide) return;

switch (this.state)
{
case ButtonStates.normal:
g_theme.SetPartAndStateId(1, 1);
break;

case ButtonStates.hover:
g_theme.SetPartAndStateId(1, 2);
break;

case ButtonStates.down:
g_theme.SetPartAndStateId(1, 3);
break;

case ButtonStates.hide:
return;
}

g_theme.DrawThemeBackground(gr, this.x, this.y, this.w, this.h);
// RGB function is defined in docs\helpers.txt
// DT_* are defined in docs\flags.txt
gr.GdiDrawText(this.text, g_font, RGB(0,0,0), this.x, this.y, this.w, this.h, DT_CENTER| DT_VCENTER | DT_CALCRECT | DT_NOPREFIX);
}

this.onClick = function () {
this.fonClick && this.fonClick();
}
}

function drawAllButtons(gr) {
for (var i in $buttons) {
$buttons[i].draw(gr);
}
}

function chooseButton(x, y) {
for (var i in $buttons) {
if ($buttons[i].containXY(x, y) && $buttons[i].state != ButtonStates.hide) return $buttons[i];
}

return null;
}

$buttons = {
first_btn: new SimpleButton(5, 5, 150, 26, "Find tag whitespaces", function () {
var leftquery = _.map(get_tag_list(), function (item) {
return '"$left(%' + item + '%,1)" IS " "';
}).join(" OR ");
fb.ShowLibrarySearchUI(leftquery);
        var rightquery = _.map(get_tag_list(), function (item) {
return '"$right(%' + item + '%,1)" IS " "';
}).join(" OR ");
fb.ShowLibrarySearchUI(rightquery);
})
}

var cur_btn = null;
var g_down = false;

function on_paint(gr) {
gr.FillSolidRect(0, 0, window.Width, window.Height, utils.GetSysColor(15));
drawAllButtons(gr);
}

function on_mouse_move(x, y) {
var old = cur_btn;
cur_btn = chooseButton(x, y);

if (old == cur_btn) {
if (g_down) return;
} else if (g_down && cur_btn && cur_btn.state != ButtonStates.down) {
cur_btn.changeState(ButtonStates.down);
window.Repaint();
return;
}

old && old.changeState(ButtonStates.normal);
cur_btn && cur_btn.changeState(ButtonStates.hover);
window.Repaint();
}

function on_mouse_leave() {
g_down = false;

if (cur_btn) {
cur_btn.changeState(ButtonStates.normal);
window.Repaint();
}
}

function on_mouse_lbtn_down(x, y) {
g_down = true;

if (cur_btn) {
cur_btn.changeState(ButtonStates.down);
window.Repaint();
}
}

function on_mouse_lbtn_up(x, y) {
g_down = false;

if (cur_btn) {
cur_btn.onClick();
cur_btn.changeState(ButtonStates.hover);
window.Repaint();
}
}
Mp3tag beatport WSS creator (◣_◢)     https://goo.gl/YsJF8w

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #10
You could combine them in to a single query,,,

Code: [Select]
var query = _.map(get_tag_list(), function (item) {
return '"$left(%' + item + '%,1)" IS " " OR "$right(%' + item + '%,1)" IS " "';
}).join(" OR ");

On the other hand, you might find having different windows for left/right useful??

Re: Filter ALL tags with title formatting
Reply #11
..you might find having different windows for left/right useful??
Yeah, I like it that way. Pin points the errors easier. It's one of those fns I might run once a year, but still, this is definitely an eye opener to the power of this tool.
Thank you.
Mp3tag beatport WSS creator (◣_◢)     https://goo.gl/YsJF8w

  • Porcus
  • [*][*][*][*][*]
Re: Filter ALL tags with title formatting
Reply #12
A potential warning: It seems that some iTunes comment fields do start with a space. No idea if any harm is done by cleaning those up - anyone who knows?


An example:

COMMENT:
 00000000 00000210 00000978 000000000041D678 00000000 003BA14F 00000000 00000000 00000000 00000000 00000000 00000000

Mp3Tag reports in addition the following, which fb2k hides. The latter has a leading space.
COMMENT ITUNES_CDDB_IDS:
12+4CAC44E805C0684028199D7A50B4D974+6932911
COMMENT ITUNNORM:
 00002456 0000297F 00007A64 000079B6 0000E58B 0000E58B 00008000 00008000 000072E8 000072D1

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #13
Personally, I'd be zapping all those tags completely as they serve no purpose to me. One of the first steps I perform upon downloading new files is using the properties dialog to copy all "visible" tags to the clipboard, using tools>remove tags to wipe everything that foobar can't even see and then paste the "visible" fields back.

If I were keeping them, I wouldn't edit them. I mean why would you? It makes sense for useful metadata but no sense for "internal" tags used by itunes or whatever.
  • Last Edit: 11 August, 2017, 07:11:51 AM by marc2003

  • Porcus
  • [*][*][*][*][*]
Re: Filter ALL tags with title formatting
Reply #14
One of the first steps I perform upon downloading new files is using the properties dialog to copy all "visible" tags to the clipboard, using tools>remove tags to wipe everything that foobar can't even see and then paste the "visible" fields back.

At risk at removing gapless information, I think? Cf. the discussion on the Tag Sanitizer component.

Edit: And, I would be cautious to use fb2k for removing those COMMENT 00000000 00000210 etc. tags, as fb2k shows multiple COMMENT fields concatenated (and, IME, with other human-readable COMMENT fields to the far right, often out of sight and at the risk of obliterating them in the same operation). Mp3tag shows them separately, so you can remove such a COMMENT field without altering a human-readable one.

If I were keeping them, I wouldn't edit them.

Agree. Hence "warning". Using the cleanup will remove leading spaces that should not be trimmed unless the entire field is to be removed.


  • Last Edit: 11 August, 2017, 09:34:25 AM by Porcus

  • marc2003
  • [*][*][*][*][*]
  • Developer
Re: Filter ALL tags with title formatting
Reply #15
At risk at removing gapless information, I think? Cf. the discussion on the Tag Sanitizer component.

Well I don't really understand what happened in the last few posts of that thread. You said the files had itunes/quicktime mentioned as the "tool" but somehow had "nero" gapless info?? Although I had posted in that thread, I didn't comment further because I didn't have the knowledge/anything constructive to say.  :P

All my AAC files are exclusively from the itunes store and have ITUNSMPB tags containing gapless info (which your files didn't have). Using the "properties dialog>tools>remove tags" removes all tags except ITUNSMPB. This does requires foobar2000 v1.3.11 or later. There were issues with a beta of 1.3.11 which I reported here....

https://hydrogenaud.io/index.php/topic,112295.msg925427.html

I know the gapless tags definitely work because my most recent purchase is an album where many tracks flow in to each other seamlessly and I have no problems playing them with foobar2000 or gonemad (a music player for android).
  • Last Edit: 11 August, 2017, 11:45:28 AM by marc2003