· 6 years ago · Aug 28, 2019, 08:06 PM
1// ==UserScript==
2// @name Torn Stock Alert
3// @namespace http://eu.relentless.pw/
4// @version 0.9.1.2
5// @description Notifies user defined stock market events
6// @author Afwas [1337627]
7// @match *://*.torn.com/index.php
8// @match *://*.torn.com/preferences.php*
9// @match *://*.torn.com/stockexchange.php*
10// @require https://code.jquery.com/jquery-1.12.0.min.js
11// @require https://raw.githubusercontent.com/jdfreder/pingjs/master/ping.js
12// @grant GM_setValue
13// @grant GM_getValue
14// @grant GM_log
15// @grant GM_getResourceText
16// @connect api.torn.com
17// @grant GM_xmlhttpRequest
18// @updateURL https://github.com/Afwas/stock-alert/raw/master/TornStockAlert.user.js
19// @license GPL v2 or higher. See https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20// ==/UserScript==
21/* jshint -W097 */
22/*global
23 GM_setValue, GM_getValue, GM_log, $, jQuery, document, window, alert, GM_getResourceText, GM_xmlhttpRequest, ping,
24 console
25 */
26'use strict';
27
28// Globals
29
30//******
31//* ADD YOUR API KEY TO THE NEXT LINE
32//* THERE IS NOTHING ELSE YOU NEED TO CHANGE
33//******
34var myAPI = "7PpxzRlbaK8ve0qR";
35
36var stockUrl = "https://api.torn.com/torn/?selections=stocks&key=" + myAPI;
37
38// Interval for refreshing banners in seconds. A good refresh-time is 60 seconds.
39// The stockmarket seems to refresh just after 00, 15, 30, 45 minutes every hour.
40var interval = 60;
41
42function getTime() {
43 var now = new Date().toISOString().slice(11, -1);
44 return now;
45}
46
47function getDate() {
48 var now = new Date().toISOString().slice(0, 10);
49 return now;
50}
51
52// Prevent caching
53$.ajaxSetup({ cache: false });
54
55// The JSON needs to be retreived. Might as well do it here and now
56var stocks = [];
57var newData = 1;
58var refresh = 0;
59function getStocks() {
60 GM_xmlhttpRequest({
61 method: "GET",
62 url: stockUrl, // + "?" + new Date().getTime().toString(),
63 responseType: 'json',
64 onload: function(resp) {
65 var data = JSON.parse(resp.responseText);
66 // console.log(data);
67 stocks = [];
68 for(var key in data.stocks) {
69 if (key == 25) {
70 stocks.push(["FOO", "Foo", 0, 0.0, "Average"]);
71 }
72 stocks.push([data.stocks[key].acronym.trim(), data.stocks[key].name, data.stocks[key].current_price, data.stocks[key].available_shares, data.stocks[key].forecast]);
73 }
74 // If a page is new loaded refresh is 0 --> Add the banners
75 // newData denotes a change in data from the servers. Go refresh!
76 newData = checkNewData();
77 // console.log( getTime() + " Checked newData. newData is : " + newData);
78 if (!refresh || newData) {
79 $(".stock-alert").remove();
80 processAlerts();
81 newData = 0;
82 }
83 if (GM_getValue("toggle-color", "checked") === "checked") {
84 addColorToStockMarket();
85 }
86 experimental = GM_getValue("toggle-experimental", "");
87 if (experimental === "checked") {
88 // This is a rather dirty hack. I offer 100M if you can come up with
89 // a *WORKING* solution to add the banners to pages or elements that
90 // are loaded AFTER the DOM. Examples of those pages: forums, laptop.
91 selected = GM_getValue("toggle-selected", "");
92 if (selected === "checked") {
93 window.setTimeout(function() {
94 $(".stock-alert").remove();
95 processAlerts();
96 $("h4").click(function() {
97 $(".stock-alert").remove();
98 processAlerts();
99 });
100 }, 2000);
101 if (window.location.href.indexOf("/laptop.php") > -1) {
102 setInterval(function() {
103 $(".stock-alert").remove();
104 processAlerts();
105 $("h4").click(function() {
106 $(".stock-alert").remove();
107 processAlerts();
108 });
109 }, 2000);
110 }
111 }
112 } // End experimental
113 }
114 });
115}
116getStocks();
117
118// Try to prevent refresh if data from server is not new
119function checkNewData() {
120 // Check 'random' shares
121 var change = 0;
122 var TCP = GM_getValue("TCP", 0.0);
123 if (parseFloat(TCP) !== parseFloat(stocks[stockId.TCP][2])) {
124 GM_setValue("TCP", stocks[stockId.TCP][2]);
125 change = 1;
126 }
127 var FHG = GM_getValue("FHG", 0.0);
128 if (parseFloat(FHG) !== parseFloat(stocks[stockId.FHG][2])) {
129 GM_setValue("FHG", stocks[stockId.FHG][2]);
130 change = 1;
131 }
132 // change denotes a change in shareprices. Go update!
133 return change;
134}
135
136// Notify adds the cool banner to the top of page index,php
137$.fn.notify = function(message) {
138 var pre = "<div class=\"info-msg-cont green border-round m-top10 stock-alert\">";
139 pre += "<div class=\"info-msg border-round\"><i class=\"info-icon\">";
140 pre += "</i><div class=\"delimiter\"><div class=\"msg right-round\"><ul><li>";
141 var post = "</li></ul></div></div></div></div>";
142 this.after(
143 pre + message + post
144 );
145 return this;
146};
147
148function placeBanner(message) {
149 // If "checked" then banners are shown on all pages
150 // Defaults to Home page only
151 selected = GM_getValue("toggle-selected", "");
152 if (selected === "checked") {
153 $("hr.page-head-delimiter:first").notify(message);
154 } else {
155 if ($("h4.left:contains('Home')").text().length) {
156 $("hr.page-head-delimiter:first").notify(message);
157 }
158 }
159}
160
161// Utility function
162// https://stackoverflow.com/questions/5731193/how-to-format-numbers-using-javascript
163function formatNumber(number)
164{
165 // number = number.toFixed(2) + '';
166 number = number + '';
167 var x = number.split('.');
168 var x1 = x[0];
169 var x2 = x.length > 1 ? '.' + x[1] : '';
170 var rgx = /(\d+)(\d{3})/;
171 while (rgx.test(x1)) {
172 x1 = x1.replace(rgx, '$1' + ',' + '$2');
173 }
174 return x1 + x2;
175}
176
177var stockId = {"TCSE": "0",
178 "TSBC": "1",
179 "TCB": "2",
180 "SYS": "3",
181 "SLAG": "4",
182 "IOU": "5",
183 "GRN": "6",
184 "TCHS": "7",
185 "YAZ": "8",
186 "TCT": "9",
187 "CNC": "10",
188 "MSG": "11",
189 "TMI": "12",
190 "TCP": "13",
191 "IIL": "14",
192 "FHG": "15",
193 "SYM": "16",
194 "LSC": "17",
195 "PRN": "18",
196 "EWM": "19",
197 "TCM": "20",
198 "ELBT": "21",
199 "HRG": "22",
200 "TGP": "23",
201 "WSSB": "25",
202 "ISTC": "26",
203 "BAG": "27",
204 "EVL": "28",
205 "MCS": "29",
206 "WLT": "30",
207 "TCC": "31"};
208
209// Add item to mobile preferences menu
210$("#categories").append("<option value=\"stock_market\">Stock market alerts</option>");
211
212// Add a link to the settings menu in preferences.php
213$(".headers").children("div.clear").before("<li class=\"delimiter\"></li>\n"+
214 "<li class=\"c-pointer left-bottom-round\" data-title-name=\"Stock market alerts\" "+
215 "id=\"stock-market\">\n"+
216 "<a class=\"t-gray-6 bold h stock-market\">Stock Market Alerts</a>\n"+
217 "</li>");
218
219// Selector to toggle showing on very page
220// selected is ["checked" | ""]
221var selected = GM_getValue("toggle-selected", "");
222var addColor = GM_getValue("toggle-color", "checked");
223var experimental = GM_getValue("toggle-experimental", "");
224
225// Create settings page/pane for stocks
226var page = "</div><div id=\"stock-market-page\" class=\"prefs-cont left ui-tabs-panel ";
227page += "ui-widget-content ui-corner-bottom\" aria-labelledby=\"ui-id-33\" ";
228page += "role=\"tabpanel\" aria-expanded=\"true\" aria-hidden=\"true\" style=\"display: none;\">";
229page += "\t<div class=\"inner-block\">";
230page += "\t\t<p class=\"m-top3\">These are the watches you have currently set. Click any to remove.</p>";
231page += "\t\t<ul class=\"m-top3\" id=\"stock-alert-list\">";
232page += "\t\t</ul>";
233page += "\t\t<div class=\"m-top3\" id=\"stock-alert-messages\"></div>";
234page += "\t\t<form class=\"m-top10\" action=\"\" id=\"stock-form\">";
235page += "\t\t\t<select id=\"stock-alert-stock\" name=\"stock-alert-stock\">";
236page += "\t\t\t\t<option value=\"TCSE\">TCSE</option>";
237page += "\t\t\t\t<option value=\"TCB\">TCB</option>";
238page += "\t\t\t\t<option value=\"SYS\">SYS</option>";
239page += "\t\t\t\t<option value=\"SLAG\">SLAG</option>";
240page += "\t\t\t\t<option value=\"IOU\">IOU</option>";
241page += "\t\t\t\t<option value=\"GRN\">GRN</option>";
242page += "\t\t\t\t<option value=\"TCHS\">TCHS</option>";
243page += "\t\t\t\t<option value=\"YAZ\">YAZ</option>";
244page += "\t\t\t\t<option value=\"TCT\">TCT</option>";
245page += "\t\t\t\t<option value=\"CNC\">CNC</option>";
246page += "\t\t\t\t<option value=\"MSG\">MSG</option>";
247page += "\t\t\t\t<option value=\"TMI\">TMI</option>";
248page += "\t\t\t\t<option value=\"TCP\">TCP</option>";
249page += "\t\t\t\t<option value=\"IIL\">IIL</option>";
250page += "\t\t\t\t<option value=\"FHG\">FHG</option>";
251page += "\t\t\t\t<option value=\"SYM\">SYM</option>";
252page += "\t\t\t\t<option value=\"LSC\">LSC</option>";
253page += "\t\t\t\t<option value=\"PRN\">PRN</option>";
254page += "\t\t\t\t<option value=\"EWM\">EWM</option>";
255page += "\t\t\t\t<option value=\"TCM\">TCM</option>";
256page += "\t\t\t\t<option value=\"ELBT\">ELBT</option>";
257page += "\t\t\t\t<option value=\"HRG\">HRG</option>";
258page += "\t\t\t\t<option value=\"TGP\">TGP</option>";
259page += "\t\t\t\t<option value=\"WSSB\">WSSB</option>";
260page += "\t\t\t\t<option value=\"ISTC\">ISTC</option>";
261page += "\t\t\t\t<option value=\"BAG\">BAG</option>";
262page += "\t\t\t\t<option value=\"EVL\">EVL</option>";
263page += "\t\t\t\t<option value=\"MCS\">MCS</option>";
264page += "\t\t\t\t<option value=\"WLT\">WLT</option>";
265page += "\t\t\t\t<option value=\"TCC\">TCC</option>";
266page += "\t\t\t</select>";
267page += "\t\t\t<select id=\"stock-action\" name=\"stock-action\">";
268page += "\t\t\t\t<option value=\"price\">Price</option>";
269page += "\t\t\t\t<option value=\"available\">Available</option>";
270page += "\t\t\t\t<option value=\"forecast\">Forecast</option>";
271page += "\t\t\t</select>";
272page += "\t\t\t<select id=\"stock-mutation\" name=\"stock-mutation\">";
273page += "\t\t\t\t<option value=\"less\">Less than</option>";
274page += "\t\t\t\t<option value=\"equal\">Equals</option>";
275page += "\t\t\t\t<option value=\"more\">More than</option>";
276page += "\t\t\t</select>";
277page += "\t\t\t<select id=\"stock-forecast\" name=\"stock-forecast\" style=\"display: none\">";
278page += "\t\t\t\t<option value=\"verypoor\">Very Poor</option>";
279page += "\t\t\t\t<option value=\"poor\">Poor</option>";
280page += "\t\t\t\t<option value=\"average\">Average</option>";
281page += "\t\t\t\t<option value=\"good\">Good</option>";
282page += "\t\t\t\t<option value=\"verygood\">Very Good</option>";
283page += "\t\t\t</select>";
284page += "\t\t\t<input type=\"text\" name=\"stock-value\" id=\"stock-value\" value=\"0\">";
285// page += "\t\t\t <input type=\"text\" name=\"stock-note\" id=\"stock-note\" value=\"Add a note\">";
286page += "\t\t\t<div class=\"btn-wrap silver change\">";
287page += "\t\t\t\t<div class=\"btn\" id=\"stock-market-submit\">";
288// page += "\t\t\t\t\t<input class=\"c-pointer\" type=\"submit\" value=\"CREATE\">";
289page += 'CREATE';
290page += "\t\t\t\t</div>";
291page += "\t\t\t</div>";
292page += "\t\t\t<div>";
293page += "\t\t\t\t<br><input type=\"checkbox\" name=\"city-wide\" value=\"city-wide\" " + selected + "> Check this if you want the banner throughout the city.";
294page += "\t\t\t</div>";
295page += "\t\t\t<div>";
296page += "\t\t\t\t<br><input type=\"checkbox\" name=\"color\" value=\"color\" " + addColor + "> Check this if you want colors on the Stock Market page.";
297page += "\t\t\t</div>";
298page += "\t\t</form>";
299page += "\t</div>";
300page += "</div>";
301
302// Put 'page' somewhere between similar panes
303$("#management").after(page);
304
305$("input:checkbox[name='city-wide']").change(function() {
306 // New state
307 console.log("Checkbox changed");
308 if(this.checked) {
309 GM_setValue("toggle-selected", "checked");
310 selected = "checked";
311 } else {
312 GM_setValue("toggle-selected", "");
313 selected = "";
314 }
315});
316
317$("input:checkbox[name='color']").change(function() {
318 // New state
319 if(this.checked) {
320 GM_setValue("toggle-color", "checked");
321 addColor = "checked";
322 } else {
323 GM_setValue("toggle-color", "");
324 addColor = "";
325 }
326});
327
328// Add alerts. This is for page-load
329addAlertsToSettings();
330
331// Add page to settingspage
332$("li#stock-market").click(function() {
333 // Just the fancy click on the left-side menu
334 $("li.ui-tabs-active").removeClass("ui-state-active").removeClass("ui-tabs-active");
335 $("li#stock-market").addClass("ui-tabs-active").addClass("ui-state-active");
336 // Remove current pane and show Stock page
337 $("div.prefs-cont[aria-hidden='false']").css("display", "none").attr("aria-expanded", "false").attr("aria-hidden", "true");
338 $("#stock-market-page").css("display", "table-cell").attr("aria-expanded", "true").attr("aria-hidden", "false");
339 // $("div.prefs-cont[aria-hidden='false']").replaceWith(page);
340 // Bind an eventhandler to the new submit button
341 $("div#stock-market-submit").on("click", clickSubmitButton);
342 // If another link is clicked remove the pane (revert to it's original state)
343 $("li.c-pointer").children("a").click(function() {
344 $("li#stock-market").removeClass("ui-state-active").removeClass("ui-tabs-active");
345 $("#stock-market-page").css("display", "none").attr("aria-expanded", "false").attr("aria-hidden", "true");
346 });
347});
348
349// Add existing alerts to settings page
350function addAlertsToSettings() {
351 // Use .detach() here? .empty() kills the eventhandler
352 $("ul#stock-alert-list").empty();
353 // This first part is identical to processAlerts()
354 var alerts = GM_getValue("stock-alert", "");
355 if (alerts === "") {
356 // Nothing to do
357 return;
358 }
359 // String split() gets individual alerts
360 var alertsInArray = alerts.split("|");
361 if (alertsInArray[0].length === 0 ) {
362 // .split returns an array with one empty string element
363 // if split on an empty string
364 return;
365 }
366 for (var alertKey in alertsInArray) {
367 // Split the alert to get the data
368 // Example [4,YAZ,available,more,0]
369 if (alertsInArray[alertKey] === "") {
370 // Nothing to do
371 return;
372 }
373 var alert = alertsInArray[alertKey].split("-");
374 var str = "#" + alert[0] + ": \t" + alert[1] + "\t" + alert[2] +
375 "\t" + alert[3] + ((alert[2] === "forecast") ? "" : "\t" + alert[4]);
376 $("ul#stock-alert-list").append(
377 "<li id=\"stock" + alert[0] + "\">" + str + "</li>"
378 );
379 }
380 // Adds an eventListener to the list
381 // Remove an alert by clicking on it in settings
382 $("ul#stock-alert-list").children().click(function() {
383 var id = $(this).attr("id");
384 // get the number
385 id = id.substr(5);
386 console.log("id: " + id);
387 // Remove alert from list; store new list
388 removeAlert(id);
389 // Append the new list to the <ul>
390 addAlertsToSettings();
391 });
392}
393
394function removeAlert(id) {
395 var newAlerts = "";
396 // This first part is identical to processAlerts()
397 var alerts = GM_getValue("stock-alert", "");
398 // String split() gets individual alerts
399 var alertsInArray = alerts.split("|");
400 for (var alertKey in alertsInArray) {
401 // Split the alert to get the data
402 // Example [4,YAZ,available,more,0]
403 var alert = alertsInArray[alertKey].split("-");
404 if (alert[0] === id) {
405 $("div#stock-alert-messages").css("color", "#FF4000").text(
406 "Removed alert: " + alertsInArray[alertKey]);
407 continue;
408 } else {
409 if (newAlerts === "") {
410 newAlerts = alertsInArray[alertKey];
411 } else {
412 newAlerts += "|" + alertsInArray[alertKey];
413 }
414 }
415 }
416 GM_setValue("stock-alert", newAlerts);
417}
418
419// Toggle menu after forecast is selected. Forecast uses a different sub-menu
420$("#stock-action").change(function() {
421 if ($(this).val() == "forecast") {
422 $("#stock-forecast").css("display", "inline");
423 $("#stock-mutation").css("display", "none");
424 $("#stock-value").css("display", "none");
425 } else {
426 $("#stock-forecast").css("display", "none");
427 $("#stock-mutation").css("display", "inline");
428 $("#stock-value").css("display", "inline");
429 }
430});
431
432// Event handler for clicking Create
433function clickSubmitButton() {
434 var data = $("#stock-form").serializeArray();
435 // Debug
436/* for (var key in data) {
437 // data is an array of "name" / "value" pairs
438 console.log(data[key]);
439 }
440*/
441 // data[0] is name. data[1] is action, data[2] is less/equal/more,
442 // data[3] is value, data[4] is poor/average/good
443 createAlert(data[0].value, data[1].value,
444 ((data[1].value === "forecast") ? data[3].value : data[2].value),
445 ((data[1].value === "forecast") ? "" : data[4].value));
446}
447
448// Here it happens. The alert gets created and stored
449function createAlert(stock, action, mutation, value) {
450 var first = 0;
451 // Manual reset
452 //GM_setValue("stock-alert", "");
453 var stored = GM_getValue("stock-alert", "");
454 if (stored === "") {
455 // Reset counter
456 GM_setValue("serial", "0");
457 first = 1;
458 }
459 var newAlert = getSerial() + "-" + stock + "-" + action + "-" +
460 mutation + ((action === "forecast") ? "" : "-" + value);
461 $("div#stock-alert-messages").css("color", "#00FF80").text(
462 "Created alert: " + newAlert);
463 stored = ((first) ? "" : stored + "|") + newAlert;
464 GM_setValue("stock-alert", stored);
465 // I think we are now on the settings page, so refresh it.
466 addAlertsToSettings();
467}
468
469// Get a unique number to distinguish similar looking queries
470function getSerial() {
471 // Manual reset
472 //GM_setValue("serial", "");
473 var serial = GM_getValue("serial", 0);
474 if (serial === 0) {
475 serial = "1";
476 GM_setValue("serial", serial);
477 } else {
478 serial = (parseInt(serial)+1).toString();
479 GM_setValue("serial", serial);
480 }
481 console.log("Serial: " + serial);
482 return serial;
483}
484
485// Done creating alerts. Now retreive them
486function processAlerts() {
487 var text, st;
488
489 // Stored alerts
490 var alerts = GM_getValue("stock-alert", "");
491 // String split() gets individual alerts
492 if (alerts === "") {
493 // Nothing to do
494 return;
495 }
496 var alertsInArray = alerts.split("|");
497 for (var alert in alertsInArray) {
498 // Split the alert to get hte data
499 // Example [4,YAZ,available,more,0]
500 var al = alertsInArray[alert].split("-");
501 // Get stock data for this stock
502 var stId = stockId[al[1]];
503
504 st = stocks[stId];
505 // console.log("Compare stocks[stId] with al[1]: " + stocks[stId][0] + " <-> " + al[1] + ". stId = " + stId);
506 // Switch over action 'price', 'available', 'forecast'
507 switch (al[2]) {
508 case "price":
509 switch (al[3]) {
510 case "less":
511 // if (stock[name][current_value] < value) { ... }
512 if (parseFloat(st[2]) < parseFloat(al[4])) {
513 // Print banner
514 text = al[1] + " - The price of " + st[1] + " (TC$ " + formatNumber(st[2]) + " ) is less than " + formatNumber(al[4]) + ".";
515 placeBanner(text);
516 }
517 break;
518 case "equal":
519 // Won't happen. Skip
520 break;
521 case "more":
522 // if (stock[name][current_value] > value) { ... }
523 if (parseFloat(st[2]) > parseFloat(al[4])) {
524 // Print banner
525 text = al[1] + " - The price of " + st[1] + " (TC$ " + formatNumber(st[2]) + " ) is greater than " + formatNumber(al[4]) + ".";
526 placeBanner(text);
527 }
528 break;
529 default:
530 console.log("al[3] seems not to match [less|equal|more] ->" + al[3]);
531 break;
532 }
533 break;
534 case "available":
535 switch (al[3]) {
536 case "less":
537 // if (stock[name][available_share] < available) { ... }
538 if (parseInt(st[3]) < parseInt(al[4])) {
539 // Print banner
540 text = al[1] + " - There are less than " + formatNumber(al[4]) + " (" + formatNumber(st[4]) + ") shares in " + st[1] + " available.";
541 placeBanner(text);
542 }
543 break;
544 case "equal":
545 // if (stock[name][available_share] == available) { ... }
546 if (parseInt(st[3]) === parseInt(al[4])) {
547 // Print banner
548 text = al[1] + " - There are exactly " + formatNumber(al[4]) + " shares in " + st[1] + " available.";
549 placeBanner(text);
550 }
551 break;
552 case "more":
553 // if (stock[name][available_share] > available) { ... }
554 //
555 if (parseInt(st[3]) > parseInt(al[4])) {
556 // Print banner
557 text = al[1] + " - There more than " + formatNumber(al[4]) + " (" + formatNumber(st[3]) + ") shares in " + st[1] + " available.";
558 placeBanner(text);
559 }
560 break;
561 default:
562 console.log("al[3] doesn't seem to match [less|equal|more] -> " + al[3]);
563 } // most inner switch
564 break;
565 case "forecast":
566 // console.log("al[3]: " + al[3]);
567 switch (al[3]) {
568 case "verypoor":
569 if (st[4] === "Very Poor") {
570 // Print banner
571 text = al[1] + " - Forecast for " + st[1] + " is VERY POOR.";
572 placeBanner(text);
573 }
574 break;
575 case "poor":
576 if (st[4] === "Poor") {
577 // Print banner
578 text = al[1] + " - Forecast for " + st[1] + " is POOR.";
579 placeBanner(text);
580 }
581 break;
582 case "average":
583 if(st[4] === "Average") {
584 // Print banner
585 text = al[1] + " - Forecast for " + st[1] + " is AVERAGE.";
586 placeBanner(text);
587 }
588 break;
589 case "good":
590 if (st[4] === "Good") {
591 // Print banner
592
593 text = al[1] + " - Forecast for " + st[1] + " is GOOD.";
594 placeBanner(text);
595 }
596 break;
597 case "verygood":
598 if (st[4] === "Very Good") {
599 // Print banner
600 text = al[1] + " - Forecast for " + st[1] + " is VERY GOOD.";
601 placeBanner(text);
602 }
603 break;
604 default:
605 console.log("al[3] doesn't seem to match [poor|average|good] -> " + al[3]);
606 } // inner switch (al[3])
607 break;
608 default:
609 console.log("al[2] doesn't match [price|available|forecast] -> " + al[2]);
610 } // outer most switch
611 } // for loop
612}
613
614interval = interval * 1000;
615window.setInterval(function() {
616 refresh = 1;
617 getStocks();
618 // newData = checkNewData();
619 console.log(getTime() + " Auto-refresh");
620 if (newData) {
621 // $(".stock-alert").remove();
622 console.log(getTime() + " New data! Refreshing now");
623 }
624}, interval);
625
626// http://www.colorpicker.com/
627var colors = {
628 "veryPoor": "#EBD3F2", // "#F5A9F2",
629 "veryPoorUnavailable": "#D2BDD9",
630 "poor": "#F2DBD3", // "#CEECF5",
631 "poorUnavailable": "#D9C4BD",
632 "good": "#D3EAF2", // "#F5F6CE",
633 "goodUnavailable": "#BDD2D9",
634 "veryGood": "#BDF2D3", //"#D8F6CE",
635 "veryGoodUnavailable": "#C4D98D",
636 "unavailable": "#D8D8D8"
637};
638
639function addColorToStockMarket() {
640 if (window.location.href.indexOf("stockexchange.php?step=portfolio") > -1) {
641 $("li.item-wrap").each(function() {
642 var stock = $(this).attr("data-stock").toUpperCase();
643 var forecast = stocks[parseInt(stockId[stock])][4];
644 var available = stocks[parseInt(stockId[stock])][3];
645 var availableTreshold = 100000;
646 var availableBool = parseInt(available) < availableTreshold;
647 if (availableBool) {
648 $(this).css("background-color", colors.unavailable);
649 }
650 switch (forecast) {
651 case "Very Good":
652 if(availableBool) {
653 $(this).css("background-color", colors.veryGoodUnavailable);
654 } else {
655 $(this).css("background-color", colors.veryGood);
656 }
657 break;
658 case "Good":
659 if(availableBool) {
660 $(this).css("background-color", colors.goodUnavailable);
661 } else {
662 $(this).css("background-color", colors.good);
663 }
664 break;
665 case "Poor":
666 if(availableBool) {
667 $(this).css("background-color", colors.poorUnavailable);
668 } else {
669 $(this).css("background-color", colors.poor);
670 }
671 break;
672 case "Very Poor":
673 if(availableBool) {
674 $(this).css("background-color", colors.veryPoorUnavailable);
675 } else {
676 $(this).css("background-color", colors.veryPoor);
677 }
678 break;
679 }
680 });
681 }
682 if (window.location.href.endsWith("stockexchange.php")) {
683 $("li.item").each(function() {
684 var stock = $(this).find("div.abbr-name.d-hide").text();
685 var forecast = stocks[parseInt(stockId[stock])][4];
686 var available = stocks[parseInt(stockId[stock])][3];
687 var availableTreshold = 100000;
688 var availableBool = parseInt(available) < availableTreshold;
689 if (availableBool) {
690 $(this).css("background-color", colors.unavailable);
691 }
692 switch (forecast) {
693 case "Very Good":
694 if(availableBool) {
695 $(this).css("background-color", colors.veryGoodUnavailable);
696 } else {
697 $(this).css("background-color", colors.veryGood);
698 }
699 break;
700 case "Good":
701 if(availableBool) {
702 $(this).css("background-color", colors.goodUnavailable);
703 } else {
704 $(this).css("background-color", colors.good);
705 }
706 break;
707 case "Poor":
708 if(availableBool) {
709 $(this).css("background-color", colors.poorUnavailable);
710 } else {
711 $(this).css("background-color", colors.poor);
712 }
713 break;
714 case "Very Poor":
715 if(availableBool) {
716 $(this).css("background-color", colors.veryPoorUnavailable);
717 } else {
718 $(this).css("background-color", colors.veryPoor);
719 }
720 break;
721 }
722 });
723 }
724}