Hello everyone, I modified Mar2003's similar artist script to display top artist tracks instead. I'm not familiar with scripting but I took a look at the script's code and last.fm api and figured it out.
This is the code in the modified lines:
Line 102
filename = folder + "\\toptracks.json";
Line 110
else if (typeof parsed_data.toptracks.track == "object") artists = parsed_data.toptracks.track;
Line 120
lastfm("&method=artist.gettoptracks&artist=" + encodeURIComponent(artist), "foo_wsh_lastfm_toptracks", function() { save(xmlhttp.responsetext, fn); load(); });
Line 9
var script_name = "Top Tracks";
I've been using this for almost 2 weeks with no issues other than the last.fm/spotify search links not working, I'm not familiar with regular expressions...
If I may ask, some questions regarding excellent Marc's scripts:
1- how can I use a complex titleformatting string for defining the path and name of the stored scripts data; json files for both biography view and similar artist?
2- how can I display the number of listeners before the artist name.
I also noted that while playing mp4 files the last.fm panels crashed, and when setting a very long string in the remapping artist field option of the bio script, it gets trimmed. I worked-around it by adding the setting directly in the properties panel dialog.
Similar to Motorhorst, I thought if it was possible to add a search button for the displayed artist to run a query in the media library search component, is it possible or not tooo tricky? I've used the similar artist panel to discover new music as well though unlucky for me, it always reports that is unable to open the default browser, which means that I have to type everytime the search url /name of the artist in last.fm for each artist. If is not too much to ask perhaps just like in the biography panel, there could be an option to copy the artist names to clipboard, which would save me some steps
Also I modified this script, I removed the button spotify, last.fm, auto playlist
// ==PREPROCESSOR==
// @import "%fb2k_profile_path%marc2003\common4.js"
// @name "Top Tracks"
// @author "marc2003"
// @feature "v1.0"
// @feature "watch-metadb"
// ==/PREPROCESSOR==
var script_name = "Top Tracks";
var username_file = settings_path + "username";
var username = read(username_file);
var api_key_file = settings_path + "api_key";
var api_key = read(api_key_file);
var lfm_img = gdi.Image(images_path + "lastfm_red_small.gif");
var spotify_img = gdi.Image(images_path + "spotify.png");
var lastfm_play_img = gdi.Image(images_path + "lastfm_play.png");
var auto_img = gdi.Image(images_path + "search_small.png");
var lastfm_small_img = gdi.Image(images_path + "lastfm small.png");
var up_img = gdi.Image(images_path + "up.png");
var down_img = gdi.Image(images_path + "down.png");
var but_x = 0;
var offset = 0;
var rows = 0;
var artist = "";
var folder = "";
var g_text = "";
var artists = [];
var g_tooltip = window.CreateTooltip();
var link = window.GetProperty("link", "spotify");
var show_artist = window.GetProperty("show_artist", true);
var pause = window.GetProperty("pause", true);
on_item_focus_change();
function on_notify_data(name, data) {
if (name == "lastfm_update" && data == 1) {
username = read(username_file);
api_key = read(api_key_file);
artist = Date();
on_item_focus_change();
}
}
function on_size() {
ww = window.Width;
wh = window.Height;
but_x = Math.round((ww - 15) / 2);
offset = 0;
rows = Math.floor((wh - 58) / 20);
up_btn = new sb(but_x, 32, 15, 15, up_img, "offset > 0", function () { on_mouse_wheel(1); });
down_btn = new sb(but_x, wh - 15, 15, 15, down_img, "offset < artists.length - rows", function () { on_mouse_wheel(-1); });
}
function on_paint(gr) {
gr.FillSolidRect(0, 0, ww, wh, g_backcolor);
switch(true) {
case username.length == 0:
case api_key.length != 32:
gr.GdiDrawText("Please use the context menu to set your Last.fm username and API KEY.", normal_font, g_textcolor, 10, 0, ww - 20, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
break;
case !g_metadb:
gr.GdiDrawText("[no selection]", normal_font, g_textcolor, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
break;
default:
gr.GdiDrawText(script_name + (show_artist ? " to " + artist : ""), title_font, g_textcolor_hl, 6, 6, ww - 77, 24, DT_VCENTER | DT_END_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX);
gr.DrawImage(lfm_img, ww - 60, 8, 50, 18, 0, 0, 50, 18);
gr.DrawLine(5, 29, ww - 10, 29, 1, g_textcolor_hl);
if (artists.length == 0) {
gr.GdiDrawText("[no data]", normal_font, g_textcolor, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
} else {
for (l = 0; l < Math.min(rows, artists.length); l++) {
gr.DrawImage(lastfm_small_img, 5, 45 + (l * 20), 20, 20, 0, 0, 20, 20);
gr.GdiDrawText(artists[l + offset].name, list_font, g_textcolor, 30, 46 + (l * 20), ww - 66, 18, DT_VCENTER | DT_END_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX);
}
up_btn.draw(gr);
down_btn.draw(gr);
}
}
}
function on_playback_new_track() {
on_item_focus_change();
}
function on_playback_dynamic_info_track() {
on_item_focus_change();
}
function on_playback_stop() {
on_item_focus_change();
}
function on_metadb_changed() {
if (!g_metadb) return;
my_metadb_changed("%artist%", function() { load(); });
}
function load() {
artists = [];
offset = 0;
if (!fso.FolderExists(folder)) fso.CreateFolder(folder);
filename = folder + "\\toptracks.json";
if (fso.fileExists(filename)) {
file = fso.Getfile(filename);
ts = fso.OpenTextFile(filename, 1, false, -1);
g_text = ts.ReadAll();
ts.close();
parsed_data = JSON.parse(g_text);
if (parsed_data.error > 0) fb.trace(script_name + ": " + g_text);
else if (typeof parsed_data.toptracks.track == "object") artists = parsed_data.toptracks.track;
if (Date.parse(Date()) - Date.parse(file.DateLastModified) > 86400000) get();
} else {
get();
}
window.Repaint();
}
function get() {
var fn = filename;
lastfm("&method=artist.gettoptracks&artist=" + encodeURIComponent(artist), "foo_wsh_lastfm_toptracks", function() { save(xmlhttp.responsetext, fn); load(); });
}
function on_mouse_wheel(delta) {
if (artists.length < rows) return;
offset -= delta * 3;
if (offset < 0) offset = 0;
if (rows + offset > artists.length) offset = artists.length - rows;
window.Repaint();
}
function on_mouse_move(x, y) {
index = Math.floor((y - 45 ) / 20) + offset;
in_range = index >= offset && index < Math.min(offset + rows, artists.length);
switch(true) {
case !g_metadb:
case username.length == 0:
case api_key.length != 32:
return;
case in_range && x > 5 && x < 25:
var url = (artists[index].url.indexOf("www.") == 0 ? "http://" : "") + artists[index].url;
tt(url);
window.SetCursor(IDC_HAND);
break;
case up_btn.trace(x, y):
case down_btn.trace(x, y):
window.SetCursor(IDC_HAND);
break;
default:
window.SetCursor(IDC_ARROW);
g_tooltip.Text = "";
g_tooltip.Deactivate();
break;
}
}
function on_mouse_lbtn_up(x, y) {
switch(true) {
case !g_metadb:
case username.length == 0:
case api_key.length != 32:
return;
case in_range && x > 5 && x < 25:
try { WshShell.run(artists[index].url); } catch(e) { MsgBox("Unable to launch your default browser.", 0, script_name); }
break;
case up_btn.trace(x, y):
up_btn.click(x, y);
break;
case down_btn.trace(x, y):
down_btn.click(x, y);
break;
}
}
function on_mouse_rbtn_up(x, y) {
var _menu = window.CreatePopupMenu();
var _links = window.CreatePopupMenu();
var _selection = window.CreatePopupMenu();
var idx;
_menu.AppendMenuItem(username.length > 0 && api_key.length == 32 && g_metadb ? MF_STRING : MF_GRAYED, 1, "Update");
_menu.AppendMenuSeparator();
_menu.AppendMenuItem(MF_STRING, 11, "Show artist name in heading");
_menu.CheckMenuItem(11, show_artist);
_menu.AppendMenuSeparator();
_menu.AppendMenuItem(link == "spotify" ? MF_STRING : MF_GRAYED, 7, "Pause playback when launching Spotify");
_menu.CheckMenuItem(7, pause);
_menu.AppendMenuSeparator();
_links.AppendMenuItem(MF_STRING, 4, "Spotify");
_links.AppendMenuItem(MF_STRING, 5, "Last.fm radio");
_links.AppendMenuItem(MF_STRING, 6, "Autoplaylist");
_links.CheckMenuRadioItem(4, 6, link == "spotify" ? 4 : link == "lastfm" ? 5 : 6);
_links.AppendTo(_menu, MF_STRING, "Links");
_menu.AppendMenuSeparator();
_selection.AppendMenuItem(MF_STRING, 900, "Use display preferences");
_selection.AppendMenuItem(MF_STRING, 901, "Prefer now playing");
_selection.AppendMenuItem(MF_STRING, 902, "Follow selected track");
_selection.CheckMenuRadioItem(900, 903, selection_mode + 900);
_selection.AppendTo(_menu, MF_STRING, "Selection mode");
_menu.AppendMenuSeparator();
_menu.AppendMenuItem(MF_STRING, 2, "Set your Last.fm username...");
_menu.AppendMenuItem(MF_STRING, 3, "Set your API KEY...");
_menu.AppendMenuSeparator();
if (utils.IsKeyPressed(0x10)) _menu.AppendMenuItem(MF_STRING, 9, "Properties");
_menu.AppendMenuItem(MF_STRING, 10, "Configure...");
idx = _menu.TrackPopupMenu(x, y);
switch(idx) {
case 1:
get();
break;
case 2:
set_username();
artist = Date();
on_item_focus_change();
break;
case 3:
set_api_key();
artist = Date();
on_item_focus_change();
break;
case 4:
case 5:
case 6:
link = idx == 4 ? "spotify" : idx == 5 ? "lastfm" : "auto";
window.SetProperty("link", link);
window.Repaint();
break;
case 11:
show_artist = !show_artist;
window.SetProperty("show_artist", show_artist);
window.Repaint();
break;
case 7:
pause = !pause;
window.SetProperty("pause", pause);
break;
case 9:
window.ShowProperties();
break;
case 10:
window.ShowConfigure();
break;
case 900:
case 901:
case 902:
selection_mode = idx - 900;
window.SetProperty("selection_mode", selection_mode);
on_item_focus_change();
break;
}
_selection.Dispose();
_menu.Dispose();
_links.Dispose();
return true;
}