Advertisement
Guest User

Untitled

a guest
Dec 12th, 2010
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==PREPROCESSOR==
  2. // @import "%fb2k_profile_path%scripts\common.js"
  3. // @import "%fb2k_profile_path%scripts\md5.js"
  4. // @import "%fb2k_profile_path%scripts\utf8encode.js"
  5. // @name "Biography, Last.fm main panel"
  6. // Required for other Last.fm panels
  7. // ==/PREPROCESSOR==
  8.  
  9. var username = utils.ReadINI(inifile, "default", "username", "");
  10. var api_key = utils.ReadINI(inifile, "default", "api_key", "");
  11. var lfm_secret = utils.ReadINI(inifile, "default", "secret", "");
  12. var lfm_sk = utils.ReadINI(inifile, "default", "session_key", "");
  13. var cache_life = utils.ReadINI(inifile, "default", "cache_life", 0);
  14. var data_folder = utils.ReadINI(inifile, "default", "data_folder", "/");
  15. var proxy_file = script_path + "wget.ini";
  16. var languages = new Array("English", "日本語", "Deutsch", "Español", "Français", "Italiano", "Polski", "Português", "Руccкий", "Türkçe", "Svenska", "简体中文");
  17. var langs = new Array("en", "jp", "de", "es", "fr", "it", "pl", "pt", "ru", "tr", "sv", "zh");
  18. var lang = langs[window.GetProperty("language",100) - 100];
  19. var artist = alartist = album = title = lastfm_artist = lastfm_artist_url = p_title = '';
  20. var p_title_width = 0;
  21. var p_title_need_calc = true;
  22. var lfm_token = '';
  23. var g_text = '';
  24. var trackxml = '';
  25. var working = 0;
  26. var simartist_height = 0;
  27. var simartists_height = 0;
  28. var simartists = [];
  29. var simartist_widths = [];
  30. var simartist_urls = [];
  31. var simartist_urls_ori = [];
  32. var sc_cache = [];
  33. var scrobbling = lfm_np_updating = false;
  34. var sc_np_timer = null;
  35. var sc_cache_file = fb.ProfilePath + "wsh_lfm_scrobble_cache.txt";
  36. var need_calc_simartists_dim = true;
  37. var g_drag = false;
  38. var g_drag_y = 0;
  39. var g_need_calc = true;
  40. var g_offset = 0;
  41. var g_textheight = 0;
  42. var defoffset = 51;
  43. var start_y = 0;
  44. var dlartistart = false;
  45. var startplay = true;
  46. var token_timer = null;
  47. var pf = fb.CreateProfiler("");
  48. var pb_time = 0;
  49. var playing = pausing = false;
  50. var useragent = "thuan's foobar2000 lastfm wsh panels";
  51. var g_tooltip = window.CreateTooltip();
  52. var sc_hint_font = gdi.Font(font, 9, 0);
  53. var p_title_font = gdi.Font(font, 16, 1);
  54. g_tooltip.SetMaxWidth(600);
  55.  
  56. window.GetProperty("auto", true);
  57. window.GetProperty("artistartcacherefresh", true);
  58. window.GetProperty("offline", false);
  59.  
  60. window.GetProperty("scrobble", false);
  61. window.GetProperty("onlymlfile", false);
  62. window.GetProperty("walbum", true);
  63. window.GetProperty("walbumartist", true);
  64. window.GetProperty("wduration", true);
  65. window.GetProperty("wtracknumber", true);
  66.  
  67. var limit = window.GetProperty("limit", 305) - 300;
  68. var artistartsizes = ["Original", "Small", "Medium", "Large square", "Large", "Extra large"];
  69. var artistartsizetext = ["original", "small", "medium", "largesquare", "large", "extralarge"];
  70. var artistartsize = artistartsizetext[window.GetProperty("artistartsize",400) - 400];
  71.  
  72. var tf_artist = utils.ReadINI(inifile, "scrobbler", "tf_artist", "%artist%");
  73. var tf_title = utils.ReadINI(inifile, "scrobbler", "tf_title", "$meta(title)");
  74.  
  75. cache_life = (!cache_life.match(/^(\d+)$/)) ? 0 : (parseInt(cache_life) * 86400000);
  76.  
  77. if (window.GetProperty("scrobble")) sc_cache_restore();
  78.  
  79. function on_notify_data(name, data) {
  80.     if (name == "getplayinginfo" && !window.GetProperty("offline")) {
  81.         get_playing_track_info(data[0], data[1]);
  82.     }
  83.     if (name == "getlastfmchart") {
  84.         refreshlastfmchart = false;
  85.         get_lastfm_chart(data[0], data[1], data[2], data[3]);
  86.     }
  87.     if (name == "refreshlastfmchart") {
  88.         refreshlastfmchart = true;
  89.         get_lastfm_chart(data[0], data[1], data[2], data[3]);
  90.     }
  91.     if (name == "getrecenttracks") {
  92.         if (!window.GetProperty("offline"))
  93.         get_recent_tracks();
  94.         else
  95.         window.NotifyOthers("recenttracks", "offline");
  96.     }
  97.     if (name == "getartistart") {
  98.         dlartistart = true;
  99.         load();
  100.         dlartistart = false;
  101.     }
  102.     if (name == "altlastfmlovedstate") {
  103.         alt_lastfm_loved_state(data[0], data[1], data[2]);
  104.     }
  105. }
  106.  
  107. function on_timer(timer_id) {
  108.     if (token_timer && token_timer.ID == timer_id) {
  109.         window.KillTimer(token_timer) && token_timer.Dispose();
  110.         lfm_token = "";
  111.     }
  112.     if (sc_np_timer && sc_np_timer.ID == timer_id) {
  113.         window.KillTimer(sc_np_timer) && sc_np_timer.Dispose();
  114.         /*fb.trace("NP Total " + sc_cache.length + ":")
  115.         for (i in sc_cache) {
  116.             fb.trace(i + ":")
  117.             fb.trace(sc_cache[i].join("\n"));
  118.         }*/
  119.         if (fb.IsPlaying && !lfm_np_updating && !window.GetProperty("offline")) {
  120.             lfm_np_updating = true;
  121.             set_lfm_np(sc_cache.slice());
  122.         }
  123.     }
  124. }
  125.  
  126. function on_size() {
  127.     ww = window.Width;
  128.     wh = window.Height;
  129.     reset();
  130. }
  131.  
  132. function on_script_unload() {
  133.     if (window.GetProperty("scrobble")) sc_cache_save();
  134. }
  135.  
  136. function on_paint(gr) {
  137.     gr.FillSolidRect( 0, 0, ww, wh, g_backcolor);
  138.     if(username.length == 0 || api_key.length != 32) {
  139.         gr.GdiDrawText("Please use the context menu to set your Last.fm username and API KEY.", g_font, g_textcolor, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
  140.     } else if(fb.IsPlaying) {
  141.         if (g_need_calc) {
  142.             calc(g_text, g_font, 6, 40, ww-16, wh - defoffset);
  143.         }
  144.         if (need_calc_simartists_dim) calc_simartists_dim();
  145.         if (simartists_height > 0) {
  146.             start_y = 40 + g_textheight - simartists_height + g_offset;
  147.         }
  148.         gr.GdiDrawText(g_text, g_font, g_textcolor, 6, g_offset + 40, ww-16, wh - g_offset - defoffset, DT_WORDBREAK | DT_NOPREFIX);
  149.         gr.FillSolidRect(0, 0, ww, 40, g_backcolor);
  150.         gr.FillSolidRect(0, wh-11, ww, 11, g_backcolor);
  151.         if (g_textheight > wh - defoffset) {
  152.             if (g_offset == 0) {
  153.                 gr.GdiDrawText("▼", sc_hint_font, g_textcolor, 0, wh-12, ww, 12, DT_TOP | DT_CENTER | DT_NOPREFIX);
  154.             }
  155.             if (g_offset < 0 && g_offset > -g_textheight + wh - defoffset) {
  156.                 gr.GdiDrawText("▲", sc_hint_font, g_textcolor, 0, 28, ww, 12, DT_TOP | DT_CENTER);
  157.                 gr.GdiDrawText("▼", sc_hint_font, g_textcolor, 0, wh-12, ww, 12, DT_TOP | DT_CENTER);
  158.             }
  159.             if (g_offset == -g_textheight + wh - defoffset) {
  160.                 gr.GdiDrawText("▲", sc_hint_font, g_textcolor, 0, 28, ww, 12, DT_TOP | DT_CENTER);
  161.             }
  162.         }
  163.         if (p_title_need_calc) {
  164.             p_title_width = gr.CalcTextWidth(p_title, p_title_font);
  165.             p_title_width = (p_title_width > ww-12) ? ww-12 : p_title_width;
  166.             p_title_need_calc = false;
  167.         }
  168.         gr.GdiDrawText(p_title, p_title_font, g_textcolor_hl, 6, 6, ww-12, 24, DT_VCENTER  | DT_END_ELLIPSIS | DT_CALCRECT | DT_NOPREFIX);
  169.         gr.DrawLine(10, 29, ww-20, 29, 1, g_textcolor_hl);
  170.         gr.FillGradRect(5, 29,10, 1, 0, RGB(255,255,255), g_textcolor_hl);
  171.         gr.FillGradRect(ww-20, 29,10, 1, 0, g_textcolor_hl,RGB(255,255,255));
  172.     } else {
  173.         gr.GdiDrawText("[playback stopped]", g_font, g_textcolor, 0, 0, ww, wh, DT_VCENTER | DT_CENTER | DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
  174.     }
  175. }
  176.  
  177. function on_playback_new_track(mdb) {
  178.     playing = true;
  179.     if (!pausing) pb_time += pf.Time;
  180.     pausing = false;
  181.     pb_time = Math.round(pb_time / 1000);
  182.     if (sc_cache.length > 0) {
  183.         if (window.GetProperty("scrobble")) {
  184.             entry = sc_cache[sc_cache.length-1];
  185.             if (pb_time <= 5 || entry[0] == -1)
  186.             sc_cache.pop();
  187.             else {
  188.                 if (entry.length == 9) entry.push(pb_time);
  189.                 if (!scrobbling && !window.GetProperty("offline")) {
  190.                     //fb.trace("==============scrobble=======");
  191.                     scrobbling = true;
  192.                     lastfm_scrobble(get_sc_list());
  193.                 }
  194.             }
  195.         } else sc_cache.pop();
  196.     }
  197.     pb_time = 0;
  198.     pf.Reset();
  199.     sc_cache_add(mdb, pb_start_time = Math.round(Date.parse(Date()) / 1000));
  200.  
  201.     g_metadb && g_metadb.Dispose();
  202.     g_metadb = mdb;
  203.     alartist = fb.TitleFormat("%album artist%").EvalWithMetadb(g_metadb);
  204.     album = fb.TitleFormat("%album%").EvalWithMetadb(g_metadb);
  205.     title = fb.TitleFormat("%title%").EvalWithMetadb(g_metadb);
  206.     if (startplay) {
  207.         artist = fb.TitleFormat("%artist%").EvalWithMetadb(g_metadb);
  208.         load();
  209.         return;
  210.     }
  211.     if (artist == fb.TitleFormat("%artist%").EvalWithMetadb(g_metadb)) return;
  212.     artist = fb.TitleFormat("%artist%").EvalWithMetadb(g_metadb);
  213.     load();
  214. }
  215.  
  216. function on_playback_seek() {
  217.     pb_time += pf.Time;
  218.     pf.Reset();
  219. }
  220.  
  221. function on_playback_pause(state) {
  222.     if (state) {
  223.         pb_time += pf.Time;
  224.         pausing = true;
  225.     } else {
  226.         pausing = false;
  227.         pf.Reset();
  228.     }
  229. }
  230.  
  231. function on_playback_edited() {
  232.     if (artist != fb.TitleFormat("%artist%").EvalWithMetadb(g_metadb)) load();
  233.     if (!window.GetProperty("scrobble")) return;
  234.     if (artist != fb.TitleFormat("%artist%").EvalWithMetadb(g_metadb) || alartist != fb.TitleFormat("%album artist%").EvalWithMetadb(g_metadb) || album != fb.TitleFormat("%album%").EvalWithMetadb(g_metadb) || title != fb.TitleFormat("%title%").EvalWithMetadb(g_metadb)) {
  235.         artist = fb.TitleFormat(tf_artist).EvalWithMetadb(g_metadb);
  236.         alartist = fb.TitleFormat("%album artist%").EvalWithMetadb(g_metadb);
  237.         album = fb.TitleFormat("%album%").EvalWithMetadb(g_metadb);
  238.         title = fb.TitleFormat(tf_title).EvalWithMetadb(g_metadb);
  239.         entry = sc_cache[sc_cache.length-1];
  240.         entry[1] = false;
  241.         entry[3] = album;
  242.         entry[4] = alartist;
  243.         entry[5] = artist;
  244.         entry[7] = title;
  245.         if (!lfm_np_updating && !window.GetProperty("offline")) {
  246.             lfm_np_updating = true;
  247.             set_lfm_np(sc_cache.slice());
  248.         }
  249.     }
  250. }
  251.  
  252. function on_playback_stop(reason) {
  253.     if (reason == 0) startplay = true;
  254.     if (reason != 2) {
  255.         if (reason != 3) playing = false;
  256.         if (!pausing) pb_time += pf.Time;
  257.         pausing = false;
  258.         pb_time = Math.round(pb_time / 1000);
  259.         if (window.GetProperty("scrobble")) {
  260.             entry = sc_cache[sc_cache.length-1];
  261.             if (pb_time <= 5 || entry[0] == -1)
  262.             sc_cache.pop();
  263.             else {
  264.                 if (entry.length == 9) entry.push(pb_time);
  265.             }
  266.         } else sc_cache.pop();
  267.         window.Repaint();
  268.     }
  269. }
  270.  
  271. function get_playing_track_info(tartist, ttitle) {
  272.     if (username.length == 0 || api_key.length != 32) return(fb.trace("Can't contact Last.fm. Check your username / API KEY settings."));
  273.     var listeners = 0;
  274.     var playcount = 0;
  275.     var userplaycount = 0;
  276.     var userloved = 0;
  277.     var lfm_artist = '';
  278.     var lfm_track = '';
  279.     trackxmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  280.     qs = "&method=track.getinfo&autocorrect=1&username=" + username + "&artist=" + encodeURIComponent(tartist) + "&track=" + encodeURIComponent(ttitle);
  281.     trackxmlhttp.open("GET", "http://ws.audioscrobbler.com/2.0/?api_key=" + api_key + "&user=" + username + qs + "&s=" + Math.random(), true);
  282.     trackxmlhttp.setRequestHeader('User-Agent', useragent);
  283.     trackxmlhttp.send();
  284.     trackxmlhttp.onreadystatechange = function() {
  285.         if (trackxmlhttp.readyState == 4) {
  286.             if (trackxmlhttp.status == 200) {
  287.                 trackxml = trackxmlhttp.responseText;
  288.                 var trackxmldom= new ActiveXObject("Microsoft.XMLDOM");
  289.                 trackxmldom.async="false";
  290.                 trackxmldom.loadXML(trackxml);
  291.                 try {
  292.                     lfm_artist = trackxmldom.getElementsByTagName("artist")[0].childNodes[0].childNodes[0].nodeValue;
  293.                 } catch (e) {};
  294.                 try {
  295.                     lfm_track = trackxmldom.getElementsByTagName("track")[0].childNodes[1].childNodes[0].nodeValue;
  296.                 } catch (e) {};
  297.                 try {
  298.                     listeners = trackxmldom.getElementsByTagName("listeners")[0].childNodes[0].nodeValue;
  299.                 } catch (e) {};
  300.                 try {
  301.                     playcount = trackxmldom.getElementsByTagName("playcount")[0].childNodes[0].nodeValue;
  302.                 } catch (e) {};
  303.                 try {
  304.                     userplaycount = trackxmldom.getElementsByTagName("userplaycount")[0].childNodes[0].nodeValue;
  305.                 } catch (e) {};
  306.                 try {
  307.                     userloved = trackxmldom.getElementsByTagName("userloved")[0].childNodes[0].nodeValue;
  308.                 } catch (e) {};
  309.             } else {
  310.                 fb.trace(trackxmlhttp.responseText);
  311.             }
  312.             window.NotifyOthers("playingtrack", [lfm_artist, lfm_track, listeners, playcount, userplaycount, userloved]);
  313.         }
  314.     }
  315. }
  316.  
  317. function get_lastfm_chart(method, type, period, charts_folder) {
  318.     if(username.length == 0 || api_key.length != 32) return(fb.trace("Last.fm Charts: Can't contact Last.fm. Check your username / API KEY settings."));
  319.     top_el = method.substring(3).toLowerCase();
  320.     filename = charts_folder + "\\" + username+ "_" + type + "_" + period + ".xml";
  321.     ranks = new Array();
  322.     names = new Array();
  323.     name_widths = new Array();
  324.     tt_texts = new Array();
  325.     playcounts = new Array();
  326.     urls = new Array();
  327.     artists = new Array();
  328.     if(fso.fileExists(filename)) {
  329.         file = fso.Getfile(filename);
  330.         if((refreshlastfmchart || (Date.parse(Date()) - Date.parse(file.DateLastModified) > 86400000)) && !window.GetProperty("offline")) {
  331.             refreshlastfmchart = false;
  332.             lastfm("&user=" + username + "&method=user." + method + "&period=" + period, useragent, function() {save_xml_file(filename); get_lastfm_chart(method, type, period, charts_folder);});
  333.             return;
  334.         }
  335.         chartxml = utils.ReadTextFile(filename);
  336.         if(chartxml.length > 0) {
  337.             var temp_bmp = gdi.CreateImage(1, 1);
  338.             var temp_gr = temp_bmp.GetGraphics();
  339.             var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  340.             xmlDoc.async="false";
  341.             xmlDoc.loadXML(chartxml);
  342.             try {
  343.                 var tops = xmlDoc.getElementsByTagName(top_el)[0];
  344.                 for(i = 0; i < tops.childNodes.length; i++) {
  345.                     var top = tops.childNodes[i];
  346.                     ranks[i] = top.getAttribute("rank");
  347.                     for(j = 0; j < top.childNodes.length; j++) {
  348.                         if(top.childNodes[j].tagName == "url") urls[i] = top.childNodes[j].childNodes[0].nodeValue;
  349.                         if(top.childNodes[j].tagName == "name") names[i] = top.childNodes[j].childNodes[0].nodeValue;
  350.                         if(top.childNodes[j].tagName == "playcount") playcounts[i] = top.childNodes[j].childNodes[0].nodeValue;
  351.                         if(i > 0 && playcounts[i] == playcounts[i -1]) ranks[i] = ranks[i -1];
  352.                         if(type != 0 && top.childNodes[j].tagName == "artist") {
  353.                             artists[i] = top.childNodes[j].childNodes[0].childNodes[0].nodeValue;
  354.                         }
  355.                     }
  356.                     tt_texts[i] = ((artists.length > 0) ? artists[i] + " - " : "") + names[i];
  357.                     name_widths[i] = temp_gr.CalcTextWidth(names[i], g_font);
  358.                 }
  359.                 window.NotifyOthers("lastfmchart", [ranks, names, name_widths, tt_texts, playcounts, urls]);
  360.             } catch (e) {
  361.                 window.NotifyOthers("lastfmchart", [[], [], [], [], [], []]);
  362.             }
  363.             temp_bmp.ReleaseGraphics(temp_gr);
  364.             temp_bmp.Dispose();
  365.             temp_gr = null;
  366.             temp_bmp = null;
  367.         }
  368.     } else if (!window.GetProperty("offline")){
  369.         lastfm("&user=" + username + "&method=user." + method + "&period=" + period, useragent, function() {save_xml_file(filename); get_lastfm_chart(method, type, period, charts_folder);});
  370.     } else window.NotifyOthers("lastfmchart", [[], [], [], [], [], []]);
  371. }
  372.  
  373. function get_recent_tracks() {
  374.     if(username.length == 0 || api_key.length != 32) return(fb.trace("Last.fm Charts: Can't contact Last.fm. Check your username / API KEY settings."));
  375.     var ret = "";
  376.     recentxmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  377.     recentxmlhttp.open("GET", "http://ws.audioscrobbler.com/2.0/?api_key=" + api_key + "&user=" + username + "&method=user.getrecenttracks&limit=20" + "&s=" + Math.random(), true);
  378.     recentxmlhttp.setRequestHeader('User-Agent',useragent);
  379.     recentxmlhttp.send();
  380.     recentxmlhttp.onreadystatechange = function() {
  381.         if (recentxmlhttp.readyState == 4) {
  382.             if (recentxmlhttp.status == 200) {
  383.                 recentxml = recentxmlhttp.responseText;
  384.                 var recentxmldom = new ActiveXObject("Microsoft.XMLDOM");
  385.                 recentxmldom.async="false";
  386.                 recentxmldom.loadXML(recentxml);
  387.                 try {
  388.                     tracks = recentxmldom.getElementsByTagName("name");
  389.                     artists = recentxmldom.getElementsByTagName("artist");
  390.                     for (i = 0; i < tracks.length; i++) {
  391.                         ret += zeroPad((i + 1),2) + ". " + tracks[i].childNodes[0].nodeValue + "\n";
  392.                         ret += "      By " + artists[i].childNodes[0].nodeValue;
  393.                         if (i < tracks.length - 1) ret += "\n";
  394.                     }
  395.                 } catch(e) {
  396.                     ret = "User " + username + " does not have a recent track information on Last.fm.";
  397.                 }
  398.             } else ret = "User " + username + " does not have a recent track information on Last.fm.";
  399.             window.NotifyOthers("recenttracks", ret);
  400.         }
  401.     }
  402. }
  403.  
  404. function get_lastfm_token(func) {
  405.     lfmtokenxmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  406.     lfmtokenxmlhttp.open("GET", "http://ws.audioscrobbler.com/2.0/?api_key=" + api_key + "&method=auth.getToken" + "&s=" + Math.random(), true);
  407.     lfmtokenxmlhttp.setRequestHeader('User-Agent',useragent);
  408.     lfmtokenxmlhttp.send();
  409.     lfmtokenxmlhttp.onreadystatechange = function() {
  410.         if (lfmtokenxmlhttp.readyState == 4) {
  411.             if (lfmtokenxmlhttp.status == 200) {
  412.                 lfmtokenxml = lfmtokenxmlhttp.responseText;
  413.                 var lfmtokenxmldom = new ActiveXObject("Microsoft.XMLDOM");
  414.                 lfmtokenxmldom.async="false";
  415.                 lfmtokenxmldom.loadXML(lfmtokenxml);
  416.                 try {
  417.                     lfm_token = lfmtokenxmldom.getElementsByTagName("token")[0].childNodes[0].nodeValue;
  418.                     token_timer && window.KillTimer(token_timer) && token_timer.Dispose();
  419.                     token_timer = window.CreateTimerTimeout(3600000);
  420.                     get_lastfm_sk(func);
  421.                 } catch (e) {
  422.                     fb.trace(lfmtokenxml);
  423.                 }
  424.             } else {
  425.                 fb.trace(lfmtokenxmlhttp.responseText);
  426.                 fb.ShowPopupMessage("Unable to get last.fm token. Please check foobar2000 console for furthur information.");
  427.             }
  428.         }
  429.     }
  430. }
  431.  
  432. function get_lastfm_sk(func) {
  433.     if (api_key.length != 32) return(fb.ShowPopupMessage("Can't contact Last.fm. Check your username / API KEY settings."));
  434.     if (lfm_secret == "") return(fb.ShowPopupMessage("Last.fm secret missing, please reenter your last.fm secret in bio panel then try again."));
  435.     if (lfm_token == "") {
  436.         get_lastfm_token(func);
  437.         return;
  438.     }
  439.     WshShell.Run("\"" + lfm_auth_vbs + "\" http://www.last.fm/api/auth/?api_key=" + api_key + "&token=" + lfm_token, 0, true);
  440.     var api_sig = md5("api_key" + api_key + "methodauth.getSessiontoken" + lfm_token + lfm_secret);
  441.     lfmskxmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  442.     lfmskxmlhttp.open("GET", "http://ws.audioscrobbler.com/2.0/?api_key=" + api_key + "&method=auth.getSession&token=" + lfm_token + "&api_sig=" + api_sig, true);
  443.     lfmskxmlhttp.setRequestHeader('User-Agent',useragent);
  444.     lfmskxmlhttp.send();
  445.     lfmskxmlhttp.onreadystatechange = function() {
  446.         if (lfmskxmlhttp.readyState == 4) {
  447.             if (lfmskxmlhttp.status == 200) {
  448.                 lfmskxml = lfmskxmlhttp.responseText;
  449.                 var lfmskxmldom = new ActiveXObject("Microsoft.XMLDOM");
  450.                 lfmskxmldom.async="false";
  451.                 lfmskxmldom.loadXML(lfmskxml);
  452.                 try {
  453.                     lfm_sk = lfmskxmldom.getElementsByTagName("key")[0].childNodes[0].nodeValue;
  454.                     utils.WriteINI(inifile, "default", "session_key", lfm_sk);
  455.                     fb.trace("Last.fm authentication complete");
  456.                     func();
  457.                 } catch (e) {
  458.                     fb.trace(lfmskxml);
  459.                 }
  460.             } else {
  461.                 fb.trace(lfmskxmlhttp.responseText);
  462.                 fb.ShowPopupMessage("Unable to get last.fm session key. Please check foobar2000 console for furthur information.");
  463.             }
  464.         }
  465.     }
  466. }
  467.  
  468. function alt_lastfm_loved_state(artist, track, love) {
  469.     if (api_key.length != 32) return(fb.ShowPopupMessage("Can't contact Last.fm. Check your username / API KEY settings."));
  470.     if (lfm_secret == "") return(fb.ShowPopupMessage("Last.fm secret missing, please reenter your last.fm secret in bio panel then try again."));
  471.     if (lfm_sk == "") {
  472.         get_lastfm_sk(function() {alt_lastfm_loved_state(artist, track, love)});
  473.         return;
  474.     }
  475.     var method = love ? "track.love" : "track.unlove";
  476.     var api_sig = md5("api_key" + api_key + "artist" + artist + "method" + method + "sk" + lfm_sk + "track" + track + lfm_secret);
  477.     lfmaltlovehttp = new ActiveXObject("Microsoft.XMLHTTP");
  478.     lfmaltlovehttp.open("POST", "http://ws.audioscrobbler.com/2.0/", true);
  479.     lfmaltlovehttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  480.     lfmaltlovehttp.setRequestHeader('User-Agent',useragent);
  481.     lfmaltlovehttp.send("api_key=" + api_key + "&method=" + method + "&api_sig=" + api_sig + "&artist=" + encodeURIComponent(artist) + "&track=" + encodeURIComponent(track) + "&sk=" + lfm_sk);
  482.     lfmaltlovehttp.onreadystatechange = function() {
  483.         if (lfmaltlovehttp.readyState == 4) {
  484.             if (lfmaltlovehttp.status == 200) {
  485.                 window.NotifyOthers("lastfmlovedstate", love);
  486.             } else {
  487.                 fb.trace(lfmaltlovehttp.responseText);
  488.             }
  489.         }
  490.     }
  491. }
  492.  
  493. function sc_cache_save() {
  494.     ts = fso.OpenTextFile(sc_cache_file, 2, true, -1);
  495.     if (playing) {
  496.         if (!pausing) pb_time += pf.Time;
  497.         pb_time = Math.round(pb_time / 1000);
  498.         if (window.GetProperty("scrobble")) {
  499.             entry = sc_cache[sc_cache.length-1];
  500.             if (pb_time <= 5 || entry[0] == -1)
  501.             sc_cache.pop();
  502.             else {
  503.                 if (entry.length == 9) entry.push(pb_time);
  504.             }
  505.         } else sc_cache.pop();
  506.     }
  507.     var sc_cache_str = "";
  508.     for (i in sc_cache) {
  509.         entry = sc_cache[i];
  510.         if (entry[0] != -1 && entry.length == 10) {
  511.             sc_cache_str += entry.join(String.fromCharCode(31));
  512.             sc_cache_str += String.fromCharCode(30);
  513.         }
  514.     }
  515.     ts.Write(sc_cache_str);
  516.     ts.Close();
  517. }
  518.  
  519. function sc_cache_restore() {
  520.     var sc_cache_str = utils.ReadTextFile(sc_cache_file, 1200);
  521.     if (sc_cache_str) {
  522.         var entries = sc_cache_str.split(String.fromCharCode(30));
  523.         for (i in entries) {
  524.             if (entries[i]) {
  525.                 entry = (entries[i]).split(String.fromCharCode(31));
  526.                 sc_cache.push(entry);
  527.             }
  528.         }
  529.         /*fb.trace("SC Total " + sc_cache.length + ":")
  530.         for (i in sc_cache) {
  531.             fb.trace(i + ":")
  532.             fb.trace(sc_cache[i].join("\n"));
  533.         }*/
  534.         if (!lfm_np_updating && !window.GetProperty("offline")) {
  535.             lfm_np_updating = true;
  536.             set_lfm_np(sc_cache.slice());
  537.         }
  538.         //lastfm_scrobble(get_sc_list());
  539.     }
  540. }
  541.  
  542. function sc_cache_add(mdb, timestamp) {
  543.     var ID;
  544.     if (window.GetProperty("onlymlfile")) {
  545.         if (fb.IsMetadbInMediaLibrary(mdb))
  546.         ID = Math.random();
  547.         else
  548.         ID = -1;
  549.     } else
  550.     ID = Math.random();
  551.  
  552.     var track = fb.TitleFormat(tf_title).EvalWithMetadb(mdb);
  553.     var artist = fb.TitleFormat(tf_artist).EvalWithMetadb(mdb);
  554.     var album = fb.TitleFormat("%album%").EvalWithMetadb(mdb);
  555.     var albumArtist = fb.TitleFormat("%album artist%").EvalWithMetadb(mdb);
  556.     var trackNumber = fb.TitleFormat("$meta(tracknumber)").EvalWithMetadb(mdb);
  557.     var duration = Math.round(fb.PlaybackLength);
  558.     sc_cache.push([ID, false, timestamp, album, albumArtist, artist, duration, track, trackNumber]);
  559.     if (window.GetProperty("scrobble")) {
  560.         sc_np_timer && window.KillTimer(sc_np_timer) && sc_np_timer.Dispose();
  561.         sc_np_timer = window.CreateTimerTimeout(5000);
  562.     }
  563. }
  564.  
  565. function sc_cache_update(ID, album, albumArtist, artist, track) {
  566.     for (i = 0; i < sc_cache.length; i++) {
  567.         entry = sc_cache[i];
  568.         if (ID == entry[0]) {
  569.             entry[1] = true;
  570.             if (album) entry[3] = album;
  571.             if (albumArtist && albumArtist != entry[4]) entry[4] = albumArtist;
  572.             if (artist) entry[5] = artist;
  573.             if (track) entry[7] = track;
  574.         }
  575.         //fb.trace(entry.join("\n"))
  576.     }
  577. }
  578.  
  579. function sc_cache_remove(ID) {
  580.     for (i = 0; i < sc_cache.length; i++) {
  581.         entry = sc_cache[i];
  582.         if (ID == entry[0]) sc_cache.splice(i, 1);
  583.     }
  584. }
  585.  
  586. function set_lfm_np(entries) {
  587.     if (api_key.length != 32) return(fb.ShowPopupMessage("Can't contact Last.fm. Check your username / API KEY settings."));
  588.     if (lfm_secret == "") return(fb.ShowPopupMessage("Last.fm secret missing, please reenter your last.fm secret in bio panel then try again."));
  589.     if (lfm_sk == "") {
  590.         get_lastfm_sk(function() {set_lfm_np(entries)});
  591.         return;
  592.     }
  593.     if (entries.length == 0) {
  594.         lfm_np_updating = false;
  595.         return;
  596.     }
  597.  
  598.     var entry = entries.shift();
  599.  
  600.     if (entry[1]) {
  601.         set_lfm_np(entries);
  602.         return;
  603.     }
  604.  
  605.     //fb.trace("=======================called set_lfm_np========")
  606.  
  607.     var ID = entry[0];
  608.     var artist = entry[5];
  609.     var track = entry[7];
  610.     if (track == "" || artist == "?" || track == "?" || artist == "") {
  611.         set_lfm_np(entries);
  612.         return(fb.trace("Track tags are incomplete, unable to set last.fm now playing."));
  613.     }
  614.     var album = entry[3];
  615.     var albumArtist = entry[4];
  616.     var duration = entry[6];
  617.     var trackNumber = entry[8];
  618.     var api_sig_raw = "";
  619.     var qs = "";
  620.     if (album != "?" && window.GetProperty("walbum")) {
  621.         api_sig_raw += "album" + album;
  622.         qs += "album=" + encodeURIComponent(album);
  623.     }
  624.     if (albumArtist != "?" && albumArtist != artist && window.GetProperty("walbumartist")) {
  625.         api_sig_raw += "albumArtist" + albumArtist;
  626.         qs += "&albumArtist=" + encodeURIComponent(albumArtist);
  627.     }
  628.     api_sig_raw += "api_key" + api_key;
  629.     qs += "&api_key=" + api_key;
  630.     api_sig_raw += "artist" + artist;
  631.     qs += "&artist=" + encodeURIComponent(artist);
  632.     if (duration != 0 && window.GetProperty("wduration")) {
  633.         api_sig_raw += "duration" + duration;
  634.         qs += "&duration=" + duration;
  635.     }
  636.     api_sig_raw += "methodtrack.updateNowPlaying" + "sk" + lfm_sk;
  637.     qs += "&method=track.updateNowPlaying" + "&sk=" + lfm_sk;
  638.     api_sig_raw += "track" + track;
  639.     qs += "&track=" + encodeURIComponent(track);
  640.     if (trackNumber != "" && window.GetProperty("wtracknumber")) {
  641.         api_sig_raw += "trackNumber" + trackNumber;
  642.         qs += "&trackNumber=" + trackNumber;
  643.     }
  644.     api_sig_raw += lfm_secret
  645.     var api_sig = md5(api_sig_raw);
  646.     qs += "&api_sig=" + api_sig;
  647.  
  648.     //fb.trace(qs)
  649.  
  650.     lfmsetnphttp = new ActiveXObject("Microsoft.XMLHTTP");
  651.     lfmsetnphttp.open("POST", "http://ws.audioscrobbler.com/2.0/", true);
  652.     lfmsetnphttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  653.     lfmsetnphttp.setRequestHeader('User-Agent',useragent);
  654.     lfmsetnphttp.send(qs);
  655.     lfmsetnphttp.onreadystatechange = function() {
  656.         if (lfmsetnphttp.readyState == 4) {
  657.             if (lfmsetnphttp.status == 200) {
  658.                 lfmsetnpxml = lfmsetnphttp.responseText;
  659.                 var lfmsetnpdom = new ActiveXObject("Microsoft.XMLDOM");
  660.                 lfmsetnpdom.async="false";
  661.                 lfmsetnpdom.loadXML(lfmsetnpxml);
  662.                 var t_artist = t_track = t_album = t_albumArtist = "";
  663.                 try {
  664.                     t_artist = lfmsetnpdom.getElementsByTagName("artist")[0].childNodes[0].nodeValue;
  665.                 } catch (e) {}
  666.                 try {
  667.                     t_track = lfmsetnpdom.getElementsByTagName("track")[0].childNodes[0].nodeValue;
  668.                 } catch (e) {}
  669.                 try {
  670.                     t_album = lfmsetnpdom.getElementsByTagName("album")[0].childNodes[0].nodeValue;
  671.                 } catch (e) {}
  672.                 try {
  673.                     t_albumArtist = lfmsetnpdom.getElementsByTagName("albumArtist")[0].childNodes[0].nodeValue;
  674.                 } catch (e) {}
  675.                 sc_cache_update(ID, t_album, t_albumArtist, t_artist, t_track)
  676.                 if (entries.length == 0 && fb.IsPlaying) fb.trace("Last.fm submission: Now playing... OK");
  677.                 set_lfm_np(entries);
  678.             } else {
  679.                 fb.trace(lfmsetnphttp.responseText);
  680.                 set_lfm_np(entries);
  681.             }
  682.         }
  683.     }
  684. }
  685.  
  686. function get_sc_list() {
  687.     var sc_list = [];
  688.     var sc_batch = [];
  689.     var c = 0;
  690.     for (i = 0; i < sc_cache.length; i++) {
  691.         entry = sc_cache[i];
  692.         if (entry[0] != -1 && entry[1] && entry.length == 10) {
  693.             sc_batch.push(entry);
  694.             c++;
  695.             if (c == 50) {
  696.                 sc_list.push(sc_batch.slice());
  697.                 sc_batch = [];
  698.                 c = 0;
  699.             }
  700.         }
  701.     }
  702.     sc_list.push(sc_batch);
  703.     return sc_list;
  704. }
  705.  
  706. function lastfm_scrobble(sl) {
  707.     if (api_key.length != 32) return(fb.ShowPopupMessage("Can't contact Last.fm. Check your username / API KEY settings."));
  708.     if (lfm_secret == "") return(fb.ShowPopupMessage("Last.fm secret missing, please reenter your last.fm secret in bio panel to scrobble."));
  709.     if (lfm_sk == "") {
  710.         get_lastfm_sk(function() {lastfm_scrobble(sl)});
  711.         return;
  712.     }
  713.  
  714.     if (sl.length == 0) {
  715.         scrobbling = false;
  716.         return;
  717.     }
  718.  
  719.     var to_scrobble = false;
  720.     var entries = sl.shift();
  721.     var qs_arr = [];
  722.     var scrobbled = [];
  723.     var qs = "";
  724.     var api_sig = "";
  725.     var duration, played_t = c = 0;
  726.     var album, albumArtist, artist, track, trackNumber = '';
  727.     for (i = 0; i < entries.length; i++) {
  728.         entry = entries[i];
  729.         ID = entry[0];
  730.         timestamp = entry[2];
  731.         album = entry[3];
  732.         albumArtist = entry[4];
  733.         artist = entry[5];
  734.         duration = entry[6];
  735.         track = entry[7];
  736.         trackNumber = entry[8];
  737.         played_t = entry[9];
  738.  
  739.         scrobbled.push(ID);
  740.  
  741.         switch (true) {
  742.         case (duration < 30):
  743.         case (played_t < 240 && played_t < Math.floor(duration / 2)):
  744.         case (track == "" || artist == "?" || track == "?" || artist == ""):
  745.             continue;
  746.             break;
  747.         default:
  748.             to_scrobble = true;
  749.             qs_arr.push("timestamp[" + i + "]" + timestamp);
  750.             qs += "&timestamp[" + i + "]=" + timestamp;
  751.             if (album != "?" && window.GetProperty("walbum")) {
  752.                 qs_arr.push("album[" + i + "]" + album);
  753.                 qs += "&album[" + i + "]=" + encodeURIComponent(album);
  754.             }
  755.             if (albumArtist != "?" && albumArtist != artist && window.GetProperty("walbumartist")) {
  756.                 qs_arr.push("albumArtist[" + i + "]" + albumArtist);
  757.                 qs += "&albumArtist[" + i + "]=" + encodeURIComponent(albumArtist);
  758.             }
  759.             qs_arr.push("artist[" + i + "]" + artist);
  760.             qs += "&artist[" + i + "]=" + encodeURIComponent(artist);
  761.             if (duration != 0 && window.GetProperty("wduration")) {
  762.                 qs_arr.push("duration[" + i + "]" + duration);
  763.                 qs += "&duration[" + i + "]=" + duration;
  764.             }
  765.             qs_arr.push("track[" + i + "]" + track);
  766.             qs += "&track[" + i + "]=" + encodeURIComponent(track);
  767.             if (trackNumber != "" && window.GetProperty("wtracknumber")) {
  768.                 qs_arr.push("trackNumber[" + i + "]" + trackNumber);
  769.                 qs += "&trackNumber[" + i + "]=" + trackNumber;
  770.             }
  771.             c++;
  772.         }
  773.     }
  774.     if (to_scrobble) {
  775.         qs_arr.push("api_key" + api_key);
  776.         qs = "api_key=" + api_key + qs;
  777.         qs_arr.push("methodtrack.scrobble");
  778.         qs += "&method=track.scrobble";
  779.         qs_arr.push("sk" + lfm_sk);
  780.         qs += "&sk=" + lfm_sk;
  781.         qs_arr.sort();
  782.         var api_sig = md5(qs_arr.join("") + lfm_secret);
  783.         qs += "&api_sig=" + api_sig;
  784.  
  785.         //fb.trace(qs)
  786.  
  787.         lfmscrobblehttp = new ActiveXObject("Microsoft.XMLHTTP");
  788.         lfmscrobblehttp.open("POST", "http://ws.audioscrobbler.com/2.0/", true);
  789.         lfmscrobblehttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  790.         lfmscrobblehttp.setRequestHeader('User-Agent',useragent);
  791.         lfmscrobblehttp.send(qs);
  792.         lfmscrobblehttp.onreadystatechange = function() {
  793.             if (lfmscrobblehttp.readyState == 4) {
  794.                 if (lfmscrobblehttp.status == 200) {
  795.                     fb.trace("Last.fm submission: Scrobbled " + c + " track(s)... OK");
  796.                     while (scrobbled.length > 0)
  797.                     sc_cache_remove(scrobbled.shift());
  798.                     lastfm_scrobble(sl);
  799.                 } else {
  800.                     fb.trace(lfmscrobblehttp.responseText);
  801.                     lastfm_scrobble(sl);
  802.                 }
  803.             }
  804.         }
  805.     } else {
  806.         while (scrobbled.length > 0)
  807.         sc_cache_remove(scrobbled.shift());
  808.     }
  809. }
  810.  
  811. function get_playing_artistart(path, artist) {
  812.     arr = [];
  813.     arr = read_images(path);
  814.     if (arr.length > 0) {
  815.         arr.push(path);
  816.         notify_artistart(arr);
  817.         return;
  818.     }
  819.     if (!window.GetProperty("auto") || window.GetProperty("offline")) {
  820.         notify_artistart([path]);
  821.         return;
  822.     }
  823.     if (username.length == 0 || api_key.length != 32) return(fb.trace("Can't contact Last.fm. Check your username / API KEY settings."));
  824.     wget = "\"" + script_path + "wget.exe\"";
  825.     if (artist != "") {
  826.         str = utils.ReadTextFile(path + "\\blacklist.txt");
  827.         if (!str) blacklist = "";
  828.         blacklist = str.split("|");
  829.         for (i in blacklist)
  830.         blacklist[i] = blacklist[i].split("\\").pop();
  831.         artistxmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  832.         qs = "&method=artist.getimages&autocorrect=1&limit=" + limit + "&artist=" + encodeURIComponent(artist);
  833.         artistxmlhttp.open("GET", "http://ws.audioscrobbler.com/2.0/?api_key=" + api_key + qs + "&s=" + Math.random(), true);
  834.         artistxmlhttp.setRequestHeader('User-Agent',useragent);
  835.         artistxmlhttp.send();
  836.         artistxmlhttp.onreadystatechange = function() {
  837.             if (artistxmlhttp.readyState == 4) {
  838.                 working++;
  839.                 window.NotifyOthers("gettingartistart", true);
  840.                 if (artistxmlhttp.status == 200) {
  841.                     artistxml = artistxmlhttp.responseText;
  842.                     artistxmldom = new ActiveXObject("Microsoft.XMLDOM");
  843.                     artistxmldom.async="false";
  844.                     artistxmldom.loadXML(artistxml);
  845.                     try {
  846.                         nodeList = artistxmldom.getElementsByTagName("size");
  847.                         ts = fso.OpenTextFile(path + "\\dllist.txt", 2, true, 0);
  848.                         getfiles = [];
  849.                         geturls = [];
  850.                         tails = [];
  851.                         for (i = 0; i < nodeList.length; i++) {
  852.                             if (nodeList[i].attributes != null && nodeList[i].attributes.getNamedItem("name") != null && nodeList[i].attributes.getNamedItem("name").nodeValue == artistartsize) {
  853.                                 geturl = nodeList[i].childNodes[0].nodeValue;
  854.                                 orifilename = geturl.split("/").pop();
  855.                                 getfiles.push(orifilename);
  856.                                 geturls.push(geturl.replace(orifilename, encodeURIComponent(orifilename)));
  857.                             }
  858.                         }
  859.                         for (i in blacklist) {
  860.                             tails = blacklist[i].match(/\.(\d+)\.(jpg|png|gif)$/);
  861.                             count = 0;
  862.                             for (j in getfiles) {
  863.                                 if (tails) {
  864.                                     delfile = blacklist[i].replace(tails[0], "." + tails[2]);
  865.                                     if (delfile == getfiles[j]) {
  866.                                         if (count == tails[1]) {
  867.                                             geturls[j] = "";
  868.                                             break;
  869.                                         }
  870.                                         count++;
  871.                                     }
  872.                                 } else {
  873.                                     if (blacklist[i] == getfiles[j]) {
  874.                                         geturls[j] = "";
  875.                                         break;
  876.                                     }
  877.                                 }
  878.                             }
  879.                         }
  880.                         ts.Write(geturls.join("\n"));
  881.                         ts.close();
  882.                         var pathobj = fso.GetFolder(path);
  883.                         WshShell.Run(wget + " -q " + "-P \"" + pathobj.ShortPath + "\" -i \"" + pathobj.ShortPath + "\\dllist.txt\"", 0, true);
  884.                         fix_wget_clobber(path);
  885.                         fso.DeleteFile(path + "\\dllist.txt");
  886.                         arr = read_images(path);
  887.                         arr.push(path);
  888.                     } catch (e) { arr = [path]; }
  889.                 } else {
  890.                     arr = [path];
  891.                 }
  892.                 working--;
  893.                 if (working == 0) {
  894.                     window.NotifyOthers("gettingartistart", false);
  895.                     notify_artistart(arr);
  896.                 }
  897.             }
  898.         }
  899.     } else notify_artistart([path]);
  900. }
  901.  
  902. function fix_wget_clobber(path) {
  903.     if (fso.FolderExists(path)) {
  904.         var files = new Enumerator((fso.GetFolder(path)).Files);
  905.         for (; !files.atEnd(); files.moveNext()) {
  906.             fnchunks = ((files.item()).Name).match(/^(.*)\.(jpg|png|gif)\.(\d+)$/);
  907.             if (fnchunks) {
  908.                 newname = fnchunks[1] + "." + fnchunks[3] + "." + fnchunks[2];
  909.                 fso.MoveFile((files.item()).Path, path + "\\" + newname);
  910.             }
  911.         }
  912.     }
  913. }
  914.  
  915. function notify_artistart(arr) {
  916.     if (!fb.IsPlaying) return;
  917.     artist_folder = data_folder + "\\" + fb.TitleFormat("$crc32(%artist%)").EvalWithMetadb(g_metadb);
  918.     if (arr[arr.length - 1] != artist_folder) {
  919.         arr = [];
  920.         arr = read_images(artist_folder);
  921.         arr.push(artist_folder);
  922.     }
  923.     window.NotifyOthers("artistart", arr);
  924. }
  925.  
  926. function load() {
  927.     if(!g_metadb) return(window.Repaint());
  928.     startplay = false;
  929.     if (data_folder == "/") data_folder = fb.ProfilePath + "wsh_lastfm";
  930.     df_chunks = data_folder.match(/^\?(.*)$/);
  931.     if (df_chunks) {
  932.         data_folder = fb.TitleFormat(df_chunks[1]).EvalWithMetadb(g_metadb) + "\\wsh_lastfm";
  933.     }
  934.     if(!fso.FolderExists(data_folder)) fso.CreateFolder(data_folder);
  935.     lastfm_artist = ret = "";
  936.     simartist_height = 0;
  937.     simartists_height = 0;
  938.     simartists = [];
  939.     simartist_urls_ori = [];
  940.     artist_folder = data_folder + "\\" + fb.TitleFormat("$crc32(%artist%)").EvalWithMetadb(g_metadb);
  941.     if(!fso.FolderExists(artist_folder)) fso.CreateFolder(artist_folder);
  942.     filename = artist_folder + "\\artistinfo.xml";
  943.     if(fso.fileExists(filename)) {
  944.         file = fso.Getfile(filename);
  945.         if (cache_life > 0 && (Date.parse(Date()) - Date.parse(file.DateLastModified) > cache_life)) {
  946.             get(filename, artist);
  947.             if (window.GetProperty("artistartcacherefresh")) {
  948.                 var arr = [];
  949.                 arr = read_images(artist_folder);
  950.                 arr.push(artist_folder);
  951.                 window.NotifyOthers("artistart", arr);
  952.                 window.NotifyOthers("refreshartistart", 1);
  953.             }
  954.             return;
  955.         }
  956.         ret = utils.ReadTextFile(filename);
  957.         if (ret.match(/^offline/)) {
  958.             if (!window.GetProperty("offline")) {
  959.                 get(filename, artist);
  960.                 return;
  961.             }
  962.             ret = "offline";
  963.         } else {
  964.             var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  965.             xmlDoc.async="false";
  966.             xmlDoc.loadXML(ret);
  967.             ret = ""
  968.             getartistart = false;
  969.             try {
  970.                 lastfm_artist = xmlDoc.getElementsByTagName("name")[0].childNodes[0].nodeValue;
  971.                 if (lastfm_artist != artist)
  972.                 ret = "(redirected from " + artist + ")\n\n";
  973.             } catch (e) { lastfm_artist = ""; }
  974.             try {
  975.                 if (xmlDoc.getElementsByTagName("image")[0].childNodes[0].nodeValue != "")
  976.                 getartistart = true;
  977.             } catch (e) { getartistart = false; }
  978.             if (getartistart)
  979.             get_playing_artistart(artist_folder, lastfm_artist);
  980.             else
  981.             notify_artistart([artist_folder]);
  982.             if (dlartistart) return;
  983.             try {
  984.                 bioraw = xmlDoc.getElementsByTagName("content")[0].childNodes[0].nodeValue;
  985.                 ret += decodeXML(bioraw);
  986.             } catch(e) {
  987.                 ret += "This artist does not have a biography page on Last.fm.";
  988.             }
  989.             try {
  990.                 ret += "\n\nListeners: " + xmlDoc.getElementsByTagName("listeners")[0].childNodes[0].nodeValue;
  991.             } catch (e) {}
  992.             try {
  993.                 playcount = xmlDoc.getElementsByTagName("playcount")[0].childNodes[0].nodeValue;
  994.                 ret += "\nPlaycount: " + playcount + (playcount > 1 ? " times" : " time");
  995.             } catch (e) {}
  996.             try {
  997.                 similars = xmlDoc.getElementsByTagName("similar")[0];
  998.                 if (similars.childNodes.length > 1) {
  999.                     ret += "\n\nSimilar artists:\n";
  1000.                     for (i = 0; i < similars.childNodes.length; i++) {
  1001.                         simartist = (i+1) + ". " + similars.childNodes[i].childNodes[0].childNodes[0].nodeValue;
  1002.                         ret += simartist;
  1003.                         if (i < similars.childNodes.length - 1) ret += "\n";
  1004.                         simartists.push(simartist);
  1005.                         simartist_urls_ori[i] = similars.childNodes[i].childNodes[1].childNodes[0].nodeValue;
  1006.                     }
  1007.                 }
  1008.             } catch (e) {}
  1009.             try {
  1010.                 lastfm_artist_url = xmlDoc.getElementsByTagName("url")[0].childNodes[0].nodeValue;
  1011.             } catch (e) { lastfm_artist_url = "http://www.last.fm/music/" + ((lastfm_artist != "") ? encodeURIComponent(lastfm_artist.replace(/\s+/g,"+")) : encodeURIComponent(artist)); }
  1012.         }
  1013.         reset();
  1014.         g_tooltip.Text = p_title = (lastfm_artist != "") ? lastfm_artist : artist;
  1015.         g_text = ret;
  1016.         window.Repaint();
  1017.     } else {
  1018.         get(filename, artist);
  1019.     }
  1020. }
  1021.  
  1022. function get(path, artist) {
  1023.     if (username.length == 0 || api_key.length != 32) return(fb.trace("Can't contact Last.fm. Check your username / API KEY settings."));
  1024.     if (!window.GetProperty("offline"))
  1025.     lastfm("&lang=" + lang + "&method=artist.getinfo&artist=" + encodeURIComponent(artist) + "&autocorrect=1", useragent, function() {save_xml_file(path); load()});
  1026.     else {
  1027.         xmlDoc = "offline";
  1028.         save_xml_file(path);
  1029.         load();
  1030.     }
  1031. }
  1032.  
  1033. function lastfm(qs, user_agent, func) {
  1034.     xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  1035.     xmlhttp.open("GET", "http://ws.audioscrobbler.com/2.0/?api_key=" + api_key + "&user=" + username + qs + "&s=" + Math.random(), true);
  1036.     xmlhttp.setRequestHeader('User-Agent',user_agent);
  1037.     xmlhttp.send();
  1038.     xmlhttp.onreadystatechange = function() {
  1039.         if (xmlhttp.readyState == 4) {
  1040.             if (xmlhttp.status == 200) {
  1041.                 xmlDoc = xmlhttp.responseText;
  1042.                 func();
  1043.             } else {
  1044.                 fb.trace(xmlhttp.responseText);
  1045.                 func();
  1046.             }
  1047.         }
  1048.     }
  1049. }
  1050.  
  1051. function save_xml_file(path) {
  1052.     try {
  1053.         ts = fso.OpenTextFile(path, 2, true, -1);
  1054.         ts.WriteLine(xmlDoc);
  1055.         ts.close();
  1056.     } catch(e) {
  1057.     }
  1058. }
  1059.  
  1060. function calc_simartists_dim() {
  1061.     var temp_bmp = gdi.CreateImage(1, 1);
  1062.     var temp_gr = temp_bmp.GetGraphics();
  1063.     t_arr = [];
  1064.     simartist_widths = [];
  1065.     simartist_urls = [];
  1066.     for (i in simartists)
  1067.     t_arr[i] = temp_gr.CalcTextWidth(simartists[i], g_font);
  1068.     for (i = 0; i < t_arr.length; i++) {
  1069.         if (t_arr[i] >= ww-16) {
  1070.             wrapped_lines = temp_gr.EstimateLineWrap(simartists[i], g_font, ww-16).toArray();
  1071.             for (j = 1; j < wrapped_lines.length; j = j + 2) {
  1072.                 simartist_widths.push(wrapped_lines[j]);
  1073.                 simartist_urls.push(simartist_urls_ori[i]);
  1074.             }
  1075.         } else {
  1076.             simartist_widths.push(t_arr[i]);
  1077.             simartist_urls.push(simartist_urls_ori[i]);
  1078.         }
  1079.     }
  1080.     if (simartist_widths.length != 0) {
  1081.         simartist_height = temp_gr.CalcTextHeight(simartist_widths[0], g_font);
  1082.         simartists_height = simartist_height * simartist_widths.length;
  1083.     }
  1084.     need_calc_simartists_dim = false;
  1085.     temp_bmp.ReleaseGraphics(temp_gr);
  1086.     temp_bmp.Dispose();
  1087.     temp_gr = null;
  1088.     temp_bmp = null;
  1089. }
  1090.  
  1091. function text_input_box(title, message, section, key, value) {
  1092.     WshShell.Run("\"" + inputbox + "\" \"" + title + "\" \"" + message + "\" \"" + value + "\"", 0, true);
  1093.     var wshEnv = WshShell.Environment("Volatile");
  1094.     var input = wshEnv("WshEnv");
  1095.     if (input != "") {
  1096.         utils.WriteINI(inifile, section, key, input);
  1097.         return input;
  1098.     }
  1099.     return value;
  1100. }
  1101.  
  1102. function read_images(path) {
  1103.     var ret = [];
  1104.     if (fso.FolderExists(path)) {
  1105.         var files = new Enumerator((fso.GetFolder(path)).Files);
  1106.         for (; !files.atEnd(); files.moveNext()) {
  1107.             if (((files.item()).Name).match(/^.*\.(jpg|png|gif)$/)) {
  1108.                 ret.push(path + "\\" + (files.item()).Name);
  1109.             }
  1110.         }
  1111.     }
  1112.     return ret;
  1113. }
  1114.  
  1115. function decodeXML(value) {
  1116.     value = value.replace(/<\/?[^>]+(>|$)/g, "");
  1117.     doc = new ActiveXObject("htmlfile");
  1118.     doc.open();
  1119.     div = doc.createElement("div");
  1120.     div.innerHTML = value.replace(/\n/g, "<br>");
  1121.     value = div.innerHTML;
  1122.     value = value.replace(/<BR>/g,"\n");
  1123.     value = value.replace(/&gt;/g,">");
  1124.     value = value.replace(/&lt;/g,"<");
  1125.     value = value.replace(/&nbsp;/g," ");
  1126.     return value.replace(/&amp;/g,"&");
  1127. }
  1128.  
  1129. function zeroPad(num,count) {
  1130.     var numZeropad = num + '';
  1131.     while(numZeropad.length < count) {
  1132.         numZeropad = "0" + numZeropad;
  1133.     }
  1134.     return numZeropad;
  1135. }
  1136.  
  1137. function on_mouse_wheel(delta) {
  1138.     if (!fb.IsPlaying) return;
  1139.     applyDelta(delta * 20, defoffset);
  1140. }
  1141.  
  1142. function on_mouse_lbtn_down(x, y) {
  1143.     g_drag = true;
  1144.     g_drag_y = y;
  1145. }
  1146.  
  1147. function on_mouse_move(x,y) {
  1148.     if (!fb.IsPlaying) {
  1149.         g_tooltip.Deactivate();
  1150.         window.SetCursor(IDC_ARROW);
  1151.         return;
  1152.     }
  1153.     index = Math.floor((y - start_y - 1)/simartist_height);
  1154.     switch (true) {
  1155.     case (simartists_height > 0 && x > 6 && x < Math.min(ww-16, 6 + simartist_widths[index]) && y > start_y && y < start_y + simartists_height && y < wh-11):
  1156.         window.SetCursor(IDC_HAND);
  1157.         if (g_tooltip.Text != simartist_urls[index]) g_tooltip.Text = simartist_urls[index];
  1158.         g_tooltip.Activate();
  1159.         break;
  1160.     case (lastfm_artist_url != "" && x > 6 && x < 6 + p_title_width && y > 6 && y < 30):
  1161.         if (p_title_width >= ww - 12) {
  1162.             if (g_tooltip.Text != p_title) g_tooltip.Text = p_title;
  1163.             g_tooltip.Activate();
  1164.         } else g_tooltip.Deactivate();
  1165.         window.SetCursor(IDC_HAND);
  1166.         break;
  1167.     default:
  1168.         g_tooltip.Deactivate();
  1169.         window.SetCursor(IDC_ARROW);
  1170.     }
  1171.     if (fb.IsPlaying && g_drag) {
  1172.         applyDelta(y - g_drag_y, defoffset);
  1173.         g_drag_y = y;
  1174.     }
  1175. }
  1176.  
  1177. function on_mouse_lbtn_up(x, y) {
  1178.     g_drag = false;
  1179.     if (!fb.IsPlaying) return;
  1180.     if (lastfm_artist_url != "" && x > 6 && x < 6 + p_title_width && y > 6 && y < 30)
  1181.     WshShell.run(lastfm_artist_url);
  1182.     index = Math.floor((y - start_y - 1)/simartist_height);
  1183.     if (simartists_height > 0 && x > 6 && x < Math.min(ww-16, 6 + simartist_widths[index]) && y > start_y && y < start_y + simartists_height && y < wh-11)
  1184.     WshShell.run(simartist_urls[index]);
  1185. }
  1186.  
  1187. function on_mouse_rbtn_up(x, y) {
  1188.     var _menu = window.CreatePopupMenu();
  1189.     var _languages = window.CreatePopupMenu();
  1190.     var _lastfm = window.CreatePopupMenu();
  1191.     var _artistart = window.CreatePopupMenu();
  1192.     var _artistartsize = window.CreatePopupMenu();
  1193.     var _limit = window.CreatePopupMenu();
  1194.     var _scrobbler = window.CreatePopupMenu();
  1195.     var idx;
  1196.     _menu.AppendMenuItem(username.length > 0 && api_key.length == 32 && g_metadb && !window.GetProperty("offline") && fb.IsPlaying ? MF_STRING : MF_GRAYED, 1, "Update");
  1197.     _menu.AppendMenuItem(MF_STRING, 2, "Work offline");
  1198.     _menu.CheckMenuItem(2, window.GetProperty("offline"));
  1199.     _menu.AppendMenuItem(MF_SEPARATOR, 0, 0);
  1200.     _lastfm.AppendMenuItem(MF_STRING, 3, "Set your username");
  1201.     _lastfm.AppendMenuItem(MF_STRING, 4, "Set your API KEY");
  1202.     _lastfm.AppendMenuItem(MF_STRING, 5, "Set your secret");
  1203.     _lastfm.AppendMenuItem(MF_SEPARATOR, 0, 0);
  1204.     _lastfm.AppendMenuItem(MF_STRING, 6, "Set biography text cache life");
  1205.     _lastfm.AppendMenuItem(MF_STRING, 7, "Set data folder");
  1206.     _lastfm.AppendMenuItem(MF_SEPARATOR, 0, 0);
  1207.     _lastfm.AppendMenuItem(MF_STRING, 8, "Enable scrobbler");
  1208.     _lastfm.CheckMenuItem(8, window.GetProperty("scrobble"));
  1209.     _scrobbler.AppendMenuItem(MF_STRING, 81, "Only file in media library");
  1210.     _scrobbler.CheckMenuItem(81, window.GetProperty("onlymlfile"));
  1211.     _scrobbler.AppendMenuItem(MF_SEPARATOR, 0, 0);
  1212.     _scrobbler.AppendMenuItem(MF_GRAYED, 0, "Modification");
  1213.     _scrobbler.AppendMenuItem(MF_STRING, 82, "Artist");
  1214.     _scrobbler.AppendMenuItem(MF_STRING, 83, "Title");
  1215.     _scrobbler.AppendMenuItem(MF_SEPARATOR, 0, 0);
  1216.     _scrobbler.AppendMenuItem(MF_GRAYED, 0, "Query inclusion");
  1217.     _scrobbler.AppendMenuItem(MF_STRING, 84, "Album");
  1218.     _scrobbler.CheckMenuItem(84, window.GetProperty("walbum"));
  1219.     _scrobbler.AppendMenuItem(MF_STRING, 85, "Album Artist");
  1220.     _scrobbler.CheckMenuItem(85, window.GetProperty("walbumartist"));
  1221.     _scrobbler.AppendMenuItem(MF_STRING, 86, "Track duration");
  1222.     _scrobbler.CheckMenuItem(86, window.GetProperty("wduration"));
  1223.     _scrobbler.AppendMenuItem(MF_STRING, 87, "Track number");
  1224.     _scrobbler.CheckMenuItem(87, window.GetProperty("wtracknumber"));
  1225.     _lastfm.AppendMenuItem(window.GetProperty("scrobble") ? MF_STRING | MF_POPUP : MF_GRAYED, _scrobbler.ID, "Scrobble options");
  1226.     _menu.AppendMenuItem(MF_STRING | MF_POPUP, _lastfm.ID, "Last.fm options");
  1227.     _artistart.AppendMenuItem(MF_STRING, 1000, "Automatically download");
  1228.     _artistart.CheckMenuItem(1000, window.GetProperty("auto"));
  1229.     _artistart.AppendMenuItem(MF_STRING, 1001, "Refresh artist art with biography text cache");
  1230.     _artistart.CheckMenuItem(1001, window.GetProperty("artistartcacherefresh"));
  1231.     for (i in artistartsizes) {
  1232.         _artistartsize.AppendMenuItem(MF_STRING, 400 + parseInt(i), artistartsizes[i]);
  1233.     }
  1234.     _artistartsize.CheckMenuRadioItem(400, 405, window.GetProperty("artistartsize", 100));
  1235.     _artistart.AppendMenuItem(MF_STRING | MF_POPUP, _artistartsize.ID, "Size");
  1236.     _limit.AppendMenuItem(MF_STRING, 301, "1");
  1237.     _limit.AppendMenuItem(MF_STRING, 303, "3");
  1238.     _limit.AppendMenuItem(MF_STRING, 305, "5");
  1239.     _limit.AppendMenuItem(MF_STRING, 310, "10");
  1240.     _limit.AppendMenuItem(MF_STRING, 320, "20");
  1241.     _limit.CheckMenuRadioItem(301, 320, window.GetProperty("limit"));
  1242.     _artistart.AppendMenuItem(MF_STRING | MF_POPUP, _limit.ID, "Limit");
  1243.     _artistart.AppendMenuItem(MF_SEPARATOR, 0, 0)
  1244.     _artistart.AppendMenuItem(MF_STRING, 1002, "Wget settings")
  1245.     _menu.AppendMenuItem(MF_STRING | MF_POPUP, _artistart.ID, "Artist art options");
  1246.     for(i in languages) {
  1247.         _languages.AppendMenuItem(MF_STRING, 100 + parseInt(i), languages[i]);
  1248.     }
  1249.     _languages.CheckMenuRadioItem(100, 111, window.GetProperty("language",100));
  1250.     _menu.AppendMenuItem(MF_STRING | MF_POPUP, _languages.ID, "Language");
  1251.     if(utils.IsKeyPressed(0x10)) {
  1252.         _menu.AppendMenuItem(MF_SEPARATOR, 0, 0);
  1253.         _menu.AppendMenuItem(MF_STRING, 10, "Configure...");
  1254.     }
  1255.     idx = _menu.TrackPopupMenu(x, y);
  1256.     switch(idx) {
  1257.     case 100:
  1258.     case 101:
  1259.     case 102:
  1260.     case 103:
  1261.     case 104:
  1262.     case 105:
  1263.     case 106:
  1264.     case 107:
  1265.     case 108:
  1266.     case 109:
  1267.     case 110:
  1268.     case 111:
  1269.         window.SetProperty("language", idx);
  1270.         lang = langs[window.GetProperty("language",100) - 100];
  1271.         if (!fb.IsPlaying) return;
  1272.         get(filename, artist);
  1273.         break;
  1274.     case 1:
  1275.         get(filename, artist);
  1276.         break;
  1277.     case 2:
  1278.         window.SetProperty("offline", !window.GetProperty("offline"));
  1279.         if (!window.GetProperty("offline")) {
  1280.             fb.IsPlaying && load();
  1281.             if (!lfm_np_updating && window.GetProperty("scrobble")) {
  1282.                 lfm_np_updating = true;
  1283.                 set_lfm_np(sc_cache.slice());
  1284.             }
  1285.         }
  1286.         break;
  1287.     case 3:
  1288.         username = text_input_box("Simple Biography", "Please enter your Last.fm username", "default", "username", username);
  1289.         if (username != "" && api_key != "") {
  1290.             fb.IsPlaying && load();
  1291.             window.NotifyOthers("lastfm_account", 1);
  1292.         }
  1293.         break;
  1294.     case 4:
  1295.         api_key = text_input_box("Simple Biography", "Please enter your Last.fm API KEY\n\nhttp://www.last.fm/api/account", "default", "api_key", api_key);
  1296.         if (username != "" && api_key != "") {
  1297.             fb.IsPlaying && load();
  1298.             window.NotifyOthers("lastfm_account", 1);
  1299.         }
  1300.         break;
  1301.     case 5:
  1302.         lfm_secret = text_input_box("Simple Biography", "Please enter your Last.fm secret\n\nhttp://www.last.fm/api/account", "default", "secret", lfm_secret);
  1303.         break;
  1304.     case 6:
  1305.         cache_life = text_input_box("Simple Biography", "Please enter your Last.fm artist biography text cache life (in days).\n\nUse 0 to disable", "default", "cache_life", cache_life / 86400000) * 86400000;
  1306.         break;
  1307.     case 7:
  1308.         data_folder = text_input_box("Simple Biography", "Please enter your Last.fm cache data folder.\nTo use titleformatting please prefix your string with '?'.\n\nBy default Last.fm cache data is stored in wsh_lastfm folder inside foobar profile directory (enter / to use default).", "default", "data_folder", utils.ReadINI(inifile, "default", "data_folder", "/"));
  1309.         if (data_folder == "/") data_folder = fb.ProfilePath + "wsh_lastfm";
  1310.         break;
  1311.     case 8:
  1312.         window.SetProperty("scrobble", !window.GetProperty("scrobble"));
  1313.         if (!lfm_np_updating && window.GetProperty("scrobble") && !window.GetProperty("offline")) {
  1314.             lfm_np_updating = true;
  1315.             set_lfm_np(sc_cache.slice());
  1316.         }
  1317.         break;
  1318.     case 81:
  1319.         window.SetProperty("onlymlfile", !window.GetProperty("onlymlfile"))
  1320.         break;
  1321.     case 82:
  1322.         tf_artist = text_input_box("Simple Biography", "Enter titleformatting string to get track title.\n\nDefault is %artist% (enter blank string to use default)", "scrobbler", "tf_artist", tf_artist);
  1323.         break;
  1324.     case 83:
  1325.         tf_title = text_input_box("Simple Biography", "Enter titleformatting string to get artist title.\n\nDefault is $meta(title) (enter blank string to use default)", "scrobbler", "tf_title", tf_title);
  1326.         break;
  1327.     case 84:
  1328.         window.SetProperty("walbum", !window.GetProperty("walbum"));
  1329.         break;
  1330.     case 85:
  1331.         window.SetProperty("walbumartist", !window.GetProperty("walbumartist"));
  1332.         break;
  1333.     case 86:
  1334.         window.SetProperty("wduration", !window.GetProperty("wduration"));
  1335.         break;
  1336.     case 87:
  1337.         window.SetProperty("wtracknumber", !window.GetProperty("wtracknumber"));
  1338.         break;
  1339.     case 10:
  1340.         window.ShowConfigure();
  1341.         break;
  1342.     case 301:
  1343.     case 303:
  1344.     case 305:
  1345.     case 310:
  1346.     case 320:
  1347.         window.SetProperty("limit", idx);
  1348.         limit = idx - 300;
  1349.         fb.IsPlaying && window.NotifyOthers("refreshartistart", 1);
  1350.         break;
  1351.     case 400:
  1352.     case 401:
  1353.     case 402:
  1354.     case 403:
  1355.     case 404:
  1356.     case 405:
  1357.         window.SetProperty("artistartsize", idx);
  1358.         artistartsize = artistartsizetext[window.GetProperty("artistartsize", 400) - 400];
  1359.         fb.IsPlaying && window.NotifyOthers("refreshartistart", 1);
  1360.         break;
  1361.     case 1000:
  1362.         window.SetProperty("auto", !window.GetProperty("auto"));
  1363.         fb.IsPlaying && window.NotifyOthers("refreshartistart", 1);
  1364.         break;
  1365.     case 1001:
  1366.         window.SetProperty("artistartcacherefresh", !window.GetProperty("artistartcacherefresh"));
  1367.         break;
  1368.     case 1002:
  1369.         WshShell.run("notepad.exe " + proxy_file, 1, true);
  1370.         fb.IsPlaying && window.NotifyOthers("refreshartistart", 1);
  1371.         break;
  1372.     }
  1373.     _scrobbler.Dispose();
  1374.     _languages.Dispose();
  1375.     _limit.Dispose();
  1376.     _lastfm.Dispose();
  1377.     _artistartsize.Dispose();
  1378.     _artistart.Dispose();
  1379.     _menu.Dispose();
  1380.     return true;
  1381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement