Thanks! I appreciate the replies.
Is there a way to quickly edit the code to use "track.getTopTags" instead of "track.getInfo"?
Also, how do we set it to automatically overwrite %LASTFMTOPTAGS% each time?
Tags are living things and changes from time to time.
I would love to do the coding myself, but I don't know how to code. So I hope this isn't asking too much.
Here you go.
+ Uses track.getTopTags.
+ Added option to overwrite. (right-click panel and in properties set to "on" or "off"
You should modify LargeFieldsConfig.txt (located in foobar2000 directory) and change defaultMetaMax to a higher value eg 5000.
# Size limit for meta fields that do not appear in either list
defaultMetaMax=5000
// ==PREPROCESSOR==
// @name "Lastfm track.getTopTags LASTFMTOPTAGS Tag (11-08-2015)"
// @author "zeremy"
// @feature "v1.4"
// @feature "watch-metadb"
// ==/PREPROCESSOR==
// In WSH panel properties (right-click panel) add your lastfm api key.
// Auto mode "ON" gets and writes LASTFMTOPTAGS on playback start.
// Overwrite mode "ON" will overwrite existing LASTFMTOPTAGS with new.
var api_key = window.GetProperty("LastFM api key", "");
var auto = window.GetProperty("Auto Mode [on/off]", "on");
var overwrite = window.GetProperty("Overwrite Tags [on/off]", "on");
var maxitems = window.GetProperty("Max Items", "100");
var text = "";
var top_tags_values = [];
var mediafile = new RegExp("file://", "i");
var playlist_call;
function RGB(r, g, b) {
return (0xff000000 | (r << 16) | (g << 8) | (b));
}
ButtonStates = {
normal: 0,
hover: 1,
down: 2,
hide: 3
}
var DT_TOP = 0x00000000;
var DT_CENTER = 0x00000001;
var DT_VCENTER = 0x00000004;
var DT_WORDBREAK = 0x00000010;
var DT_CALCRECT = 0x00000400;
var DT_NOPREFIX = 0x00000800;
var MF_STRING = 0x00000000;
var g_theme = window.CreateThemeManager("Button");
var g_font = gdi.Font("Tahoma", 12);
var ww = window.Width;
var wh = window.Height;
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);
gr.GdiDrawText(this.text, g_font, RGB(0, 0, 0), this.x, this.y, this.w, this.h, DT_WORDBREAK | 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 = {
FindTags: new SimpleButton(5, 5, ww / 2 - 5, 30, "Get TopTags from Last.fm for FOCUSED ITEM", function () {
g_metadb = fb.GetFocusItem();
getTags();
}),
WriteTags: new SimpleButton(ww / 2, 5, ww / 2 - 5, 30, "Add TopTags from Last.fm to FOCUSED ITEM", function () {
g_metadb = fb.GetFocusItem();
writeTags();
}),
WriteTagsPlaylist: new SimpleButton(5, 35, ww / 2 - 5, 30, "Add TopTags from Last.fm to SELECTED FILES in playlist", function () {
writetagsplaylistselected();
}),
RemoveTags: new SimpleButton(ww / 2, 35, ww / 2 - 5, 30, "Remove LASTFMTOPTAGS from SELECTED ITEM(s)", function () {
g_metadb = fb.GetSelections();
removeTagsSelection();
}),
Clearoutput: new SimpleButton(5, 65, ww / 2 - 5, 30, "Clear Output", function () {
text = "";
window.Repaint();
})
}
var cur_btn = null;
var g_down = false;
function on_paint(gr) {
myfont = gdi.Font("Segoe UI", 12, 0)
col = utils.GetSysColor(1);
col2 = utils.GetSysColor(0);
gr.FillSolidRect(0, 0, ww, wh, col);
gr.GdiDrawText(text, myfont, col2, 0, 100, ww, wh, DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
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();
}
}
function getTags() {
fb.trace("-----------Get Tags---------");
artist = fb.TitleFormat("%artist%").EvalWithMetadb(g_metadb);
title = fb.TitleFormat("%title%").EvalWithMetadb(g_metadb);
file = fb.TitleFormat("%path%").EvalWithMetadb(g_metadb);
if (artist == "" || artist == "?" || title == "" || title == "?") return;
var url = "https://ws.audioscrobbler.com/2.0/?method=track.getTopTags&api_key=" + api_key + "&artist=" + encodeURIComponent(artist) + "&track=" + encodeURIComponent(title) + "&format=json";
fb.trace(url);
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET", url, true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
try {
data = xmlhttp.ResponseText;
fb.trace(data);
xmlhttp.Close;
json_data = JSON.parse(data);
top_tags = json_data.toptags.tag;
top_tags_values = [];
items = top_tags.length;
if (top_tags.length > 0) {
for (i = 0; i < items; i++) {
name = json_data.toptags.tag[i].name.replace(/&/g, " \& ");
top_tags_values.push(name);
}
}
fb.trace("Tags From Last.fm:" + top_tags_values);
text = "\n-----------Get Tags---------\nFile Name: " + file + "\n" + "Tags From Last.fm: " + top_tags_values;
window.Repaint();
if (auto == "on" || playlist_call == "yes" || overwrite == "on") writeTags();
} catch (err) {
fb.trace(xmlhttp.responsetext || "HTTP error: " + xmlhttp.status);
fb.trace(err);
text = "No data availiable";
fb.trace(text);
window.Repaint();
xmlhttp.Close;
}
}
}
}
xmlhttp.send();
}
function writeTags() {
//no data exit
if (!top_tags_values) {
text2 = "\n-----------Write Tags---------\nNothing to Write";
text = text.concat(text2);
fb.trace(text2);
window.Repaint();
return;
}
fileinfo = g_metadb.GetFileInfo();
lastfmtoptags = fb.TitleFormat("%lastfmtoptags%").EvalWithMetadb(g_metadb);
//fb.trace("Tags in file:" + lastfmtoptags);
//no tags in file write lastfmtoptags
if (lastfmtoptags == "?") {
//tags
tags = top_tags_values.toString();
tags = tags.replace(/,/g, ";");
//write tags
g_metadb.UpdateFileInfoSimple("LASTFMTOPTAGS", tags, "LASTFMTOPTAGS");
text2 = "\n-----------Write Tags---------\nTags LASTFMTOPTAGS: " + tags + "\nWritten to File \n" + file;
text = text.concat(text2);
fb.trace(text2);
fileinfo.Dispose();
window.Repaint();
} else {
text2 = "\n-----------Write Tags---------\nTags Exist";
fb.trace(text2);
if (overwrite == "on") {
removeTags();
tags = top_tags_values.toString();
tags = tags.replace(/,/g, ";");
//write tags
g_metadb.UpdateFileInfoSimple("LASTFMTOPTAGS", tags, "LASTFMTOPTAGS");
text2 = "\n-----------Write Tags---------\nOverwrite ON\nTags LASTFMTOPTAGS: " + tags + "\nWritten to File \n" + file;
text = text.concat(text2);
fb.trace(text2);
fileinfo.Dispose();
}
window.Repaint();
}
}
function removeTags() {
fb.trace("\n-----------Remove Tags---------");
fileinfo = g_metadb.GetFileInfo();
lastfmtoptags = fb.TitleFormat("%lastfmtoptags%").EvalWithMetadb(g_metadb);
//no tags in file write lastfmtoptags
if (lastfmtoptags == "?") {
text2 = "\n-----------Remove Tags---------\nNothing to do.";
text = text.concat(text2);
window.Repaint();
return;
window.Repaint();
} else {
fb.trace("Tags in file Removed:" + lastfmtoptags);
g_metadb.UpdateFileInfoSimple("LASTFMTOPTAGS", "");
text2 = "\n-----------Remove Tags---------\nTags Removed.";
text = text.concat(text2);
window.Repaint();
}
}
function removeTagsSelection() {
var items = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
var count = items.Count;
if (count > maxitems) {
fb.ShowPopupMessage("With WSH Panel Mod a separate update process is spawned for each affected file. This can lead to locking up your computer in case of too many threads with some corrupted files as a result.\n\nYour selection is larger than " + maxitems + "entries.\nReduce playlist to 100 entries.");
return;
}
for (var i = 0; i < count; i++) {
g_metadb = items.item(i);
removeTags();
}
items.Dispose();
text = "Finished.";
window.Repaint();
}
//playlist SELECTED items get - write tags
function writetagsplaylistselected() {
playlist_call = "yes";
var items = plman.GetPlaylistSelectedItems(plman.ActivePlaylist);
var count = items.Count;
if (count > 100) {
fb.ShowPopupMessage("With WSH Panel Mod a separate update process is spawned for each affected file. From my own experience this can lead to locking up your computer in case of too many threads with some corrupted files as a result.\n\nYour selection is larger than " + maxitems + " entries.\nReduce playlist to " + maxitems + " entries.");
return;
}
for (var i = 0; i < count; i++) {
g_metadb = items.item(i);
getTags();
top_tags_values = [];
}
items.Dispose();
playlist_call = "no";
text = "Finished.";
window.Repaint();
}
function on_playback_new_track() {
if (fb.TitleFormat("%_path_raw%").Eval(true).match(mediafile) && (auto == "on")) {
g_metadb = fb.GetNowPlaying();
getTags();
}
}
function on_playback_stop() {
text = "";
tags = "";
top_tags_values = [];
g_metadb = "";
window.Repaint();
}