Release 0.4-0
[marketstoday] / src / qml / Library / js / CoreLogic.js
1 /*
2 @version: 0.4
3 @author: Sudheer K. <scifi1947 at gmail.com>
4 @license: GNU General Public License
5 */
6
7 var strErrorMessage;
8
9 function reloadQuotes(){
10     var query = getQuery();
11     if (query){
12         quoteRefreshStarted();
13         logUtility.logMessage("Reloading Data..");
14
15         //var queryURL = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.quotes where symbol in ("INDU","^IXIC","^GSPC","CLJ11.NYM","YHOO","AAPL","GOOG","MSFT")&env=store://datatables.org/alltableswithkeys';
16         var queryURL = 'http://query.yahooapis.com/v1/public/yql?q=select Symbol,Name,LastTradePriceOnly,Change,ChangeinPercent,Volume,MarketCapitalization from yahoo.finance.quotes where symbol in ('+query+')&env=store://datatables.org/alltableswithkeys';
17         logUtility.logMessage(queryURL);
18
19         var response = new XMLHttpRequest();
20         response.onreadystatechange = function() {
21             if (response.readyState == XMLHttpRequest.DONE) {
22                 var success = refreshDataModel(response);
23                 if (success === true){
24                     logUtility.logMessage("Data Reload Completed..");
25                 }
26                 else{
27                     logUtility.logMessage("Data Reload Failed..");
28                 }
29                 quoteRefreshCompleted(success,strErrorMessage);
30             }
31         }
32
33         response.open("GET", queryURL);
34         response.send();
35     }
36     else{
37         logUtility.logMessage("No stock symbols found in configuration.");
38         if (!isDesktopWidget)
39             strErrorMessage = "Tap the title bar to add stock tickers and update settings."
40         else
41             strErrorMessage = "Use the widget settings screen to add stock tickers and update configuration."
42         stockQuoteDataModel.clear();
43         quoteRefreshCompleted(false,strErrorMessage);
44     }
45 }
46
47 function getQuery(){
48     var query;
49     var symbolsArray = DBUtility.getAllSymbols();
50     if (symbolsArray && symbolsArray.length > 0){
51         var i = 0;
52         for (i = 0; i< symbolsArray.length; i++) {
53             logUtility.logMessage("Appending "+symbolsArray[i]+ " to Query");
54
55             if (!query){
56                 query = '"'+symbolsArray[i]+'"';
57             }
58             else{
59                 query = query + ',"' + symbolsArray[i]+'"';
60             }
61         }
62     }
63
64     return query;
65 }
66
67 function reloadNews(){
68     if (!rssURL || rssURL == "Unknown") {
69         logUtility.logMessage("Invalid RSS URL: "+rssURL);
70     }
71     else{
72         logUtility.logMessage("Reloading news from "+rssURL);
73         //var queryURL = "http://finance.yahoo.com/rss/topfinstories";
74         logUtility.logMessage(rssURL);
75         var response = new XMLHttpRequest();
76         response.onreadystatechange = function() {
77             if (response.readyState == XMLHttpRequest.DONE) {
78                 var success = refreshNewsModel(response);
79                 if (success === true){
80                     logUtility.logMessage("News Reload Completed..");
81                 }
82                 else{
83                     logUtility.logMessage("News Reload Failed..");
84                 }
85                 newsReloadCompleted(success,strErrorMessage);
86             }
87         }
88
89         response.open("GET", rssURL);
90         response.send();
91     }
92 }
93
94 function refreshDataModel(response){
95     var status = false;   
96     if (!response.responseXML) {
97         //This shouldn't happen
98         strErrorMessage = "Error occurred while loading stock quotes."
99         if (response.responseText)
100             logUtility.logMessage(response.responseText);
101         else
102             logUtility.logMessage("No responseXML for quotes");
103         return status;
104     }
105
106     var xmlDoc = response.responseXML.documentElement;
107     var results = xmlDoc.firstChild;
108
109     //Not the best code I ever wrote, but got no choice
110     //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
111
112     if (results) {
113         var quoteNodes = results.childNodes;
114         if (quoteNodes && quoteNodes.length > 0){
115             logUtility.logMessage("Clearing Data Model");
116             stockQuoteDataModel.clear();
117
118             var i = 0;
119             for (i = 0; i < quoteNodes.length; i++) {
120
121                 var quoteElements = quoteNodes[i].childNodes;
122                 var j = 0;
123                 var symbol,stockName,lastTradedPrice,change,changePercentage,volume,marketCap
124
125                 for (j = 0; j < quoteElements.length; j++){
126
127                     switch (quoteElements[j].nodeName){
128                         case 'Symbol':
129                             symbol = quoteElements[j].childNodes[0].nodeValue;
130                             break;
131                         case 'Name':
132                             stockName = quoteElements[j].childNodes[0].nodeValue;
133                             break;
134                         case 'LastTradePriceOnly':
135                             lastTradedPrice = quoteElements[j].childNodes[0].nodeValue;
136                             break;
137                         case 'Change':
138                             change = (quoteElements[j].childNodes[0])? quoteElements[j].childNodes[0].nodeValue:"";
139                             break;
140                         case 'ChangeinPercent':
141                             changePercentage = (quoteElements[j].childNodes[0])? quoteElements[j].childNodes[0].nodeValue:"";
142                             break;
143                         case 'Volume':
144                             volume = (quoteElements[j].childNodes[0])? quoteElements[j].childNodes[0].nodeValue:"";
145                             break;
146                         case 'MarketCapitalization':
147                             marketCap = (quoteElements[j].childNodes[0])? quoteElements[j].childNodes[0].nodeValue:"";
148                             break;
149                         default:
150                     }
151                 }
152                 stockQuoteDataModel.append({"symbol":symbol,"stockName":stockName,"lastTradedPrice":lastTradedPrice,"change":change,"changePercentage":changePercentage,"volume":volume,"marketCap":marketCap});
153                 //logUtility.logMessage("Symbol: "+stockQuoteDataModel.get(i).symbol+", Name: "+ stockQuoteDataModel.get(i).stockName+", LastTraded: "+stockQuoteDataModel.get(i).lastTradedPrice+", Change: "+stockQuoteDataModel.get(i).change+", ChangePercent: "+stockQuoteDataModel.get(i).changePercentage+", Volume: "+stockQuoteDataModel.get(i).volume+", MarketCap: "+stockQuoteDataModel.get(i).marketCap);
154                 logUtility.logMessage(stockQuoteDataModel.get(i).symbol+", "+stockQuoteDataModel.get(i).lastTradedPrice+", "+stockQuoteDataModel.get(i).change+", "+stockQuoteDataModel.get(i).changePercentage+", "+stockQuoteDataModel.get(i).volume+", "+stockQuoteDataModel.get(i).marketCap);
155             }
156
157             status = true;
158         }
159         else
160         {
161             strErrorMessage = "Quotes could not be fetched from Yahoo! Finance. Please verify the tickers and try again later."
162             logUtility.logMessage(response.responseText);
163             status = false;
164         }
165     }
166     else{
167         strErrorMessage = "Stock quote data from Yahoo! Finance is currently not available. Please try again later."
168         logUtility.logMessage(response.responseText);
169         status = false;
170     }
171
172
173     var queryNode = xmlDoc;
174     if (queryNode) {
175         i = 0;
176         var queryAttributes = queryNode.attributes;
177         for (i = 0; i < queryAttributes.length; i++) {
178             if (queryAttributes[i].name == 'created') {
179                 lastUpdatedTimeStamp = "Updated: "+DateLib.ISODate.format(queryAttributes[i].value);
180                 logUtility.logMessage(lastUpdatedTimeStamp);
181                 break;
182             }
183         }
184     }
185
186     return status;
187 }
188
189 function refreshNewsModel(response){
190     var status = false;
191     if (!response.responseXML) {
192         //This shouldn't happen
193         strErrorMessage = "Error occurred while loading news."
194         if (response.responseText)
195             logUtility.logMessage(response.responseText);
196         else
197             logUtility.logMessage("No responseXML for news");
198         return status;
199     }
200
201     //Not the best code I ever wrote, but got no choice
202     //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
203
204
205     var xmlDoc = response.responseXML.documentElement;
206     //var channel = xmlDoc.firstChild; Doesn't work with some RSS providers. THANK YOU, YAHOO
207
208     var channel;
209
210     var i = 0;
211     for (i = 0; i < xmlDoc.childNodes.length; i++){
212         if (xmlDoc.childNodes[i].nodeName === 'channel') {
213             channel = xmlDoc.childNodes[i];
214             break;
215         }
216     }
217
218     if (channel) {
219         var itemNodes = channel.childNodes;
220         if (itemNodes){
221
222             logUtility.logMessage("Clearing News Model");
223             newsDataModel.clear();
224             logUtility.logMessage("No. of news stories = "+itemNodes.length);
225
226             for (i = 0; i < itemNodes.length; i++) {
227                 if (itemNodes[i].nodeName === 'item'){
228                     var newsElements = itemNodes[i].childNodes;
229                     var j = 0;
230                     var newsTitle,newsLink
231                     for (j = 0; j < newsElements.length; j++){
232
233                         switch (newsElements[j].nodeName){
234                             case 'title':
235                                 newsTitle = newsElements[j].childNodes[0].nodeValue;
236                                 break;
237                             case 'link':
238                                 newsLink = newsElements[j].childNodes[0].nodeValue;
239                                 break;
240                             default:
241                         }
242                     }
243                     newsDataModel.append({"title":newsTitle,"link":newsLink});
244                     //logUtility.logMessage("Title: "+newsDataModel.get(i).title+", Link: "+ newsDataModel.get(i).link);
245                     //logUtility.logMessage("Title: "+newsTitle+", Link: "+ newsLink);
246                 }
247             }
248             status = true;
249         }
250         else{
251             strErrorMessage = "The RSS feed did not contain any news stories. Please try again later."
252             logUtility.logMessage(response.responseText);
253             status = false;
254         }
255     }
256     else{
257         strErrorMessage = "The RSS feed did not return valid data. Please check the URL and try again later."
258         logUtility.logMessage(response.responseText);
259         status = false;
260     }
261
262     return status;
263 }
264
265 function loadSettings(){
266     var value;
267     value  = DBUtility.getSetting("UpdateFreqency");
268     if (!value || value == "0.0" || value === "" || isNaN(value)){
269         autoUpdateInterval = 0;
270     }
271     else{
272         autoUpdateInterval = parseInt(value)*60*1000; //Convert minutes to milliseconds
273     }
274     value  = DBUtility.getSetting("UpdateWeekdaysOnly");
275     if (!value || value == "0.0" || value === ""){
276         updateWeekDaysOnly = false;
277     }
278     else{
279         updateWeekDaysOnly = true;
280     }
281
282 /*
283     value  = DBUtility.getSetting("UpdateOnSavedNetworksOnly");
284     if (!value || value == "0.0" || value === ""){
285         updateOnSavedNetworksOnly = false;
286     }
287     else{
288         updateOnSavedNetworksOnly = true;
289     }
290 */
291
292     value  = DBUtility.getSetting("RSSURL");
293     if (!value || value == "Unknown" || value === ""){
294         //Do Nothing
295     }
296     else if (value === 'http://finance.yahoo.com/rss/topstories'){
297         /*
298           Yahoo changed their Top New rss feed from http://finance.yahoo.com/rss/topstories to http://finance.yahoo.com/rss/topfinstories.
299           Since the application has a hardcoded default rss feed, it is better to update it here. Not sure if this is the best way to deal with such changes.
300          */
301
302             rssURL = "http://finance.yahoo.com/rss/topfinstories";
303             DBUtility.setSetting("RSSURL",rssURL);
304     }
305     else
306     {
307         rssURL = value;
308     }
309 }
310
311 function initialize(){
312     if (autoUpdateTimer.running) autoUpdateTimer.stop();
313     loadSettings();
314     reloadQuotes();
315     reloadNews();
316
317     if (autoUpdateInterval !== 0) {
318         logUtility.logMessage("Starting Timer..");
319         autoUpdateTimer.start();
320     }
321 }