630f8946d8b384c0bf002735d6b7dab4dea7ab9d
[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         //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';
15         //var queryURL = 'http://download.finance.yahoo.com/d/quotes.csv?s=INDU+^IXIC+^GSPC+CLJ11.NYM+YHOO+AAPL+GOOG+MSFT+ACT&f=snl1c1p2vj1&e=.csv';
16         var queryURL = 'http://download.finance.yahoo.com/d/quotes.csv?s='+query+'&f=snl1c1p2vj1&e=.csv';
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.responseText) {
97         strErrorMessage = "Error occurred while loading stock quotes."
98         logUtility.logMessage("No responseText for quotes");
99         return status;
100     }
101     else{
102         //snl1c1p2vj1
103         var quoteDetails = CSVUtility.csvToArray(response.responseText.trim());
104         var i = 0;
105         if (quoteDetails && quoteDetails.length > 0){
106             logUtility.logMessage("Clearing Data Model");
107             stockQuoteDataModel.clear();
108
109             for (i = 0; i < quoteDetails.length; i++){
110
111                 var symbol,stockName,lastTradedPrice,change,changePercentage,volume,marketCap;
112                 symbol = quoteDetails[i][0];
113                 stockName = quoteDetails[i][1];
114                 lastTradedPrice = quoteDetails[i][2];
115                 change = (quoteDetails[i][3] !== 'N/A')? quoteDetails[i][3]:'';
116                 changePercentage = (quoteDetails[i][4] !== 'N/A')? quoteDetails[i][4]:'';
117                 volume = (quoteDetails[i][5] !== 'N/A')? quoteDetails[i][5]:'';
118                 marketCap = (quoteDetails[i][6] !== 'N/A')? quoteDetails[i][6]:'';
119
120                 stockQuoteDataModel.append({"symbol":symbol,"stockName":stockName,"lastTradedPrice":lastTradedPrice,"change":change,"changePercentage":changePercentage,"volume":volume,"marketCap":marketCap});
121                 //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);
122                 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);
123             }
124
125             status = true;
126             var timeNow = new Date();
127             try{
128                 lastUpdatedTimeStamp = "Updated: "+DateLib.ISODate.format(timeNow);
129                 logUtility.logMessage(lastUpdatedTimeStamp);
130             }
131             catch(exception){
132                 logUtility.logMessage("Error occured while converting timestamp");
133                 logUtility.logMessage(exception);
134             }
135         }
136         else
137         {
138             strErrorMessage = "Quotes could not be fetched from Yahoo! Finance. Please verify the tickers and try again later."
139             logUtility.logMessage(response.responseText);
140             status = false;
141         }
142     }
143
144     return status;
145 }
146
147 function refreshNewsModel(response){
148     var status = false;
149     if (!response.responseXML) {
150         //This shouldn't happen
151         strErrorMessage = "Error occurred while loading news."
152         if (response.responseText)
153             logUtility.logMessage(response.responseText);
154         else
155             logUtility.logMessage("No responseXML for news");
156         return status;
157     }
158
159     //Not the best code I ever wrote, but got no choice
160     //Refer to Memory leak issue with XMLListModel --> http://bugreports.qt.nokia.com/browse/QTBUG-15191
161
162
163     var xmlDoc = response.responseXML.documentElement;
164     //var channel = xmlDoc.firstChild; Doesn't work with some RSS providers. THANK YOU, YAHOO
165
166     var channel;
167
168     var i = 0;
169     for (i = 0; i < xmlDoc.childNodes.length; i++){
170         if (xmlDoc.childNodes[i].nodeName === 'channel') {
171             channel = xmlDoc.childNodes[i];
172             break;
173         }
174     }
175
176     if (channel) {
177         var itemNodes = channel.childNodes;
178         if (itemNodes){
179
180             logUtility.logMessage("Clearing News Model");
181             newsDataModel.clear();
182             logUtility.logMessage("No. of news stories = "+itemNodes.length);
183
184             for (i = 0; i < itemNodes.length; i++) {
185                 if (itemNodes[i].nodeName === 'item'){
186                     var newsElements = itemNodes[i].childNodes;
187                     var j = 0;
188                     var newsTitle,newsLink
189                     for (j = 0; j < newsElements.length; j++){
190
191                         switch (newsElements[j].nodeName){
192                             case 'title':
193                                 newsTitle = newsElements[j].childNodes[0].nodeValue;
194                                 break;
195                             case 'link':
196                                 newsLink = newsElements[j].childNodes[0].nodeValue;
197                                 break;
198                             default:
199                         }
200                     }
201                     newsDataModel.append({"title":newsTitle,"link":newsLink});
202                     //logUtility.logMessage("Title: "+newsDataModel.get(i).title+", Link: "+ newsDataModel.get(i).link);
203                     //logUtility.logMessage("Title: "+newsTitle+", Link: "+ newsLink);
204                 }
205             }
206             status = true;
207         }
208         else{
209             strErrorMessage = "The RSS feed did not contain any news stories. Please try again later."
210             logUtility.logMessage(response.responseText);
211             status = false;
212         }
213     }
214     else{
215         strErrorMessage = "The RSS feed did not return valid data. Please check the URL and try again later."
216         logUtility.logMessage(response.responseText);
217         status = false;
218     }
219
220     return status;
221 }
222
223 function loadSettings(){
224     var value;
225     value  = DBUtility.getSetting("UpdateFreqency");
226     if (!value || value == "0.0" || value === "" || isNaN(value)){
227         autoUpdateInterval = 0;
228     }
229     else{
230         autoUpdateInterval = parseInt(value)*60*1000; //Convert minutes to milliseconds
231     }
232     value  = DBUtility.getSetting("UpdateWeekdaysOnly");
233     if (!value || value == "0.0" || value === ""){
234         updateWeekDaysOnly = false;
235     }
236     else{
237         updateWeekDaysOnly = true;
238     }
239
240 /*
241     value  = DBUtility.getSetting("UpdateOnSavedNetworksOnly");
242     if (!value || value == "0.0" || value === ""){
243         updateOnSavedNetworksOnly = false;
244     }
245     else{
246         updateOnSavedNetworksOnly = true;
247     }
248 */
249
250     value  = DBUtility.getSetting("RSSURL");
251     if (!value || value == "Unknown" || value === ""){
252         //Do Nothing
253     }
254     else if (value === 'http://finance.yahoo.com/rss/topstories'){
255         /*
256           Yahoo changed their Top New rss feed from http://finance.yahoo.com/rss/topstories to http://finance.yahoo.com/rss/topfinstories.
257           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.
258          */
259
260             rssURL = "http://finance.yahoo.com/rss/topfinstories";
261             DBUtility.setSetting("RSSURL",rssURL);
262     }
263     else
264     {
265         rssURL = value;
266     }
267 }
268
269 function initialize(){
270     if (autoUpdateTimer.running) autoUpdateTimer.stop();
271     loadSettings();
272     reloadQuotes();
273     reloadNews();
274
275     if (autoUpdateInterval !== 0) {
276         logUtility.logMessage("Starting Timer..");
277         autoUpdateTimer.start();
278     }
279 }