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