[dev] Patches for Jonah Stocks

Joe Wilson joe.wilson at mindcandy.org
Mon Jun 2 21:28:56 PDT 2003


The attached patches convert Jonah stock quotes to using Yahoo and enable
the display of the major US indices again (I have not checked indices from other
countries but have no reason to believe that they won't work).

Yahoo does not support all of the fields that Nasdaq did, but the vast majority
are.  It may be that with further knowledge of the Yahoo format string,
additional fields could be obtained.

I also took the liberty of adding the NASDAQ Composite index to the "standard"
quotes.  Hence the change to prefs.php.dist.

Regards,

Joe

-------------- next part --------------
Index: lib/Jonah.php
===================================================================
RCS file: /usr/local/cvs/horde/jonah/lib/Jonah.php,v
retrieving revision 1.54
diff -u -r1.54 Jonah.php
--- lib/Jonah.php	23 May 2003 13:21:24 -0000	1.54
+++ lib/Jonah.php	3 Jun 2003 03:55:25 -0000
@@ -25,11 +25,11 @@
 /**
  * Jonah Base Class.
  *
- * $Horde: jonah/lib/Jonah.php,v 1.53 2003/05/20 17:50:07 chuck Exp $
+ * $Horde: jonah/lib/Jonah.php,v 1.54 2003/05/23 13:21:24 chuck Exp $
  *
  * @author Chuck Hagenbuch <chuck at horde.org>
  * @author  Eric Rechlin <eric at hpcalc.org>
- * @version $Revision: 1.54 $
+ * @version $Revision: 1.55 $
  * @package jonah
  */
 class Jonah {
@@ -172,51 +172,15 @@
      *
      * @param string $tickerSymbol  Ticker symbol of stock.
      */
-    function jonahUpdateStock($tickerSymbol)
+    function jonahUpdateStocks()
     {
-        global $conf;
-
-        if (!@is_dir($conf['paths']['data'])) {
-            $umask = umask(0);
-            mkdir($conf['paths']['data'], 0700);
-            umask($umask);
-        }
-
-        if (!@is_dir($conf['paths']['data'] . '/stocks')) {
-            $umask = umask(0);
-            mkdir($conf['paths']['data'] . '/stocks', 0700);
-            umask($umask);
-        }
-
-        $quoteFile = $conf['paths']['data'] . '/stocks/' . $tickerSymbol . '.xml';
-        if (file_exists($quoteFile)) {
-            $lastUpdated = filemtime($quoteFile);
-            if (($lastUpdated + $conf['stocks']['expire']) < time()) {
-                $update = 1;
-            } else {
-                $update = 0;
-            }
-        } else {
-            $update = 1;
-        }
-        if ($update) {
-            $fp = @fopen('http://quotes.nasdaq.com/quote.dll?page=xml&mode=stock&symbol=' . $tickerSymbol, 'rb');
-            if (!is_resource($fp)) {
-                echo '<span style="color:red">' . sprintf(_("error: could not update quote %s."), $tickerSymbol) . '</span><br>';
-            }
-            $xmlFile = Horde::bufferOutput('fpassthru', $fp);
-
-            if (!($fp = @fopen($conf['paths']['data'] . '/stocks/' . $tickerSymbol . '.xml', 'wb'))) {
-                echo  '<span style="color:red">' . sprintf(_("error: could not open quote %s cache file for writing."), $tickerSymbol) . '</span><br>';
-                return;
-            }
+	$tickerSymbols = Jonah::getTickerSymbols();
 
-            if (!@fwrite($fp, $xmlFile)) {
-                echo  '<span style="color:red">' . sprintf(_("error: write to quote %s cache file failed."), $tickerSymbol) . '</span><br>';
-            }
+	require_once JONAH_BASE . "/lib/Stocks/yahoo.php";
+	$stocks = &new Jonah_Stocks_yahoo($tickerSymbols);
 
-            fclose($fp);
-        }
+	$quotes = $stocks->fetch_quotes();
+	return $quotes; 
     }
 
     /**
@@ -421,10 +385,13 @@
         }
 
         if ($prefs->getValue('djia')) {
-            array_unshift($tickerSymbols, 'indu');
+            array_unshift($tickerSymbols, '^DJI');
         }
         if ($prefs->getValue('sp500')) {
-            array_unshift($tickerSymbols, 'spx');
+            array_unshift($tickerSymbols, '^GSPC');
+        }
+        if ($prefs->getValue('nasdaq')) {
+            array_unshift($tickerSymbols, '^IXIC');
         }
         return $tickerSymbols;
     }
@@ -442,44 +409,36 @@
 
         $html = '<table border="0" cellpadding="0" cellspacing="1" width="100%">';
 
-        require_once JONAH_BASE . '/lib/Stocks/nasdaq.php';
-        $quotes = &new Jonah_Stocks_nasdaq();
-
+	$quotes = Jonah::jonahUpdateStocks();
         foreach ($tickerSymbols as $tickerSymbol) {
             $tickerSymbol = String::lower($tickerSymbol);
-            Jonah::jonahUpdateStock($tickerSymbol);
-
-            $quotes->parse($conf['paths']['data'] . '/stocks/' . $tickerSymbol . '.xml');
 
             $html .= '<tr><td nowrap="nowrap" class="item">';
             $html .= Horde::link(Horde::addParameter(Horde::applicationUrl('stockquote.php', true),
-                                                     'ticker=' . $tickerSymbol),
+                                 'ticker', $tickerSymbol),
                                  _("View Quote Details"), '', '',
                                  "window.open('" . Horde::addParameter(Horde::applicationUrl('stockquote.php', true),
-                                                                       'ticker=' . $tickerSymbol) .
+                                 'ticker', $tickerSymbol) .
                                  "', '_blank', 'toolbar=no, menubar=no, " .
                                  "status=no, resizable=yes, location=no, " .
                                  "scrollbars=yes, width=340, height=370'); " .
                                  "return false;");
-            $html .= String::upper($tickerSymbol) . '</a>: ';
-            if (array_key_exists('lastPrice', $quotes->quote)) {
-                $html .= $quotes->quote['lastPrice'] . ' ';
+            $html .= String::upper($quotes[$tickerSymbol]['name']) . '</a>: ';
+            if (array_key_exists('lastPrice', $quotes[$tickerSymbol])) {
+                $html .= $quotes[$tickerSymbol]['lastPrice'] . ' ';
             }
-            if (array_key_exists('changePrice', $quotes->quote)) {
-                if ($quotes->quote['changePrice'] > 0) {
+            if (array_key_exists('changePrice', $quotes[$tickerSymbol])) {
+                if ($quotes[$tickerSymbol]['changePrice'] > 0) {
                     $html .= '<span style="color:green">';
-                } elseif ($quotes->quote['changePrice'] < 0) {
+                } elseif ($quotes[$tickerSymbol]['changePrice'] < 0) {
                     $html .= '<span style="color:red">';
                 }
-                $html .= $quotes->quote['changePrice'];
-                if ($quotes->quote['changePrice'] != 0) {
+                $html .= $quotes[$tickerSymbol]['changePrice'];
+                if ($quotes[$tickerSymbol]['changePrice'] != 0) {
                     $html .= '</span>';
                 }
             }
             $html .= '</td></tr>';
-
-            /* We're done; now clean up. */
-            $quotes->cleanup();
         }
 
         $html .= '</table>';
@@ -524,3 +483,4 @@
     }
 
 }
+
-------------- next part --------------
Index: config/prefs.php.dist
===================================================================
RCS file: /usr/local/cvs/horde/jonah/config/prefs.php.dist,v
retrieving revision 1.13
diff -u -r1.13 prefs.php.dist
--- config/prefs.php.dist	29 Apr 2003 03:52:20 -0000	1.13
+++ config/prefs.php.dist	3 Jun 2003 04:24:45 -0000
@@ -23,7 +23,7 @@
     'column' => _("Your Content"),
     'label' => _("Stocks"),
     'desc' => _("Set which stock ticker symbols to watch."),
-    'members' => array('ticker', 'djia', 'sp500'));
+    'members' => array('ticker', 'djia', 'sp500', 'nasdaq'));
 
 $prefGroups['display'] = array(
     'column' => _("Other Options"),
@@ -130,6 +130,13 @@
     'shared' => false,
     'type' => 'checkbox',
     'desc' => _("Show Dow Jones Industrial Average (INDU)?"));
+
+$_prefs['nasdaq'] = array(
+    'value' => 1,
+    'locked' => false,
+    'shared' => false,
+    'type' => 'checkbox',
+    'desc' => _("Show NASDAQ Composite Index?"));
 
 $_prefs['sp500'] = array(
     'value' => 1,
-------------- next part --------------
Index: stockquote.php
===================================================================
RCS file: /usr/local/cvs/horde/jonah/stockquote.php,v
retrieving revision 1.11
diff -u -r1.11 stockquote.php
--- stockquote.php	27 Apr 2003 00:32:05 -0000	1.11
+++ stockquote.php	3 Jun 2003 03:53:50 -0000
@@ -1,14 +1,14 @@
 <?php
 /**
- * $Horde: jonah/stockquote.php,v 1.10 2003/04/27 00:27:40 chuck Exp $
- *
- * Copyright 2002-2003 Eric Rechlin <eric at hpcalc.org>
- *
- * Returns detailed information about the specified ticker symbol.
- *
- * See the enclosed file LICENSE for license information (BSD). If you
- * did not receive this file, see http://cvs.horde.org/co.php/jonah/LICENSE.
- */
+* $Horde: jonah/stockquote.php,v 1.10 2003/04/27 00:27:40 chuck Exp $
+*
+* Copyright 2002-2003 Eric Rechlin <eric at hpcalc.org>
+*
+* Returns detailed information about the specified ticker symbol.
+*
+* See the enclosed file LICENSE for license information (BSD). If you
+* did not receive this file, see http://cvs.horde.org/co.php/jonah/LICENSE.
+*/
 
 define('JONAH_BASE', dirname(__FILE__));
 require_once JONAH_BASE . '/lib/base.php';
@@ -20,7 +20,7 @@
 
 $tickerSymbol = Horde::getFormData('ticker');
 
-require_once JONAH_BASE . '/lib/Stocks/nasdaq.php';
+require_once JONAH_BASE . '/lib/Stocks/yahoo.php';
 
 if (!@is_dir($conf['paths']['data'])) {
     $umask = umask(0);
@@ -40,117 +40,115 @@
 <?php
 if (!empty($tickerSymbol)) {
     $tickerSymbol = String::lower($tickerSymbol);
-    Jonah::jonahUpdateStock($tickerSymbol);
 
-    $quotes = &new Jonah_Stocks_nasdaq();
-
-    $quotes->parse($conf['paths']['data'] . '/stocks/' . $tickerSymbol . '.xml');
+    $quotes = Jonah::getUpdatedStocks();
     echo '<table border="0" cellpadding="1" cellspacing="0" width="100%">';
-    if (array_key_exists('name', $quotes->quote)) {
+    if (array_key_exists('name', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
         echo 'Name:</td><td>';
-        if (array_key_exists('website', $quotes->quote)) {
-            echo '<a href="' . $quotes->quote['website'] . '">';
+        if (array_key_exists('website', $quotes[$tickerSymbol])) {
+            echo '<a href="' . $quotes[$tickerSymbol]['website'] . '">';
         }
-        echo htmlentities($quotes->quote['name']);
-        if (array_key_exists('website', $quotes->quote)) {
+        echo htmlentities($quotes[$tickerSymbol]['name']);
+        if (array_key_exists('website', $quotes[$tickerSymbol])) {
             echo '</a>';
         }
         echo '</td></tr>';
     }
-    if (array_key_exists('marketCenter', $quotes->quote)) {
+    if (array_key_exists('marketCenter', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo 'Market Center:</td><td>' . htmlentities($quotes->quote['marketCenter']) . '</td></tr>';
+        echo 'Market Center:</td><td>' . htmlentities($quotes[$tickerSymbol]['marketCenter']) . '</td></tr>';
     }
-    if (array_key_exists('lastPrice', $quotes->quote)) {
+    if (array_key_exists('lastPrice', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo 'Last price:</td><td>' . $quotes->quote['lastPrice'] . '</td></tr>';
+        echo 'Last price:</td><td>' . $quotes[$tickerSymbol]['lastPrice'] . '</td></tr>';
     }
-    if (array_key_exists('changePrice', $quotes->quote)) {
+    if (array_key_exists('changePrice', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
         echo 'Change:</td><td>';
-        if ($quotes->quote['changePrice'] > 0) {
+        if ($quotes[$tickerSymbol]['changePrice'] > 0) {
             echo '<font color="green">';
-        } elseif ($quotes->quote['changePrice'] < 0) {
+        } elseif ($quotes[$tickerSymbol]['changePrice'] < 0) {
             echo '<font color="red">';
         }
-        echo $quotes->quote['changePrice'];
-        if ($quotes->quote['changePrice'] != 0) {
+        echo $quotes[$tickerSymbol]['changePrice'];
+        if ($quotes[$tickerSymbol]['changePrice'] != 0) {
             echo '</font>';
         }
         echo '</td></tr>';
     }
-    if (array_key_exists('changePct', $quotes->quote)) {
+    if (array_key_exists('changePct', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
         echo 'Change %:</td><td>';
-        if ($quotes->quote['changePct'] > 0) {
+        if ($quotes[$tickerSymbol]['changePct'] > 0) {
             echo '<font color="green">';
-        } elseif ($quotes->quote['changePct'] < 0) {
+        } elseif ($quotes[$tickerSymbol]['changePct'] < 0) {
             echo '<font color="red">';
         }
-        echo $quotes->quote['changePct'];
-        if ($quotes->quote['changePct'] != 0) {
+        echo $quotes[$tickerSymbol]['changePct'];
+        if ($quotes[$tickerSymbol]['changePct'] != 0) {
             echo '</font>';
         }
         echo '</td></tr>';
     }
-    if (array_key_exists('high', $quotes->quote)) {
+    if (array_key_exists('high', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Today's high:</td><td>" . $quotes->quote['high'] . '</td></tr>';
+        echo "Today's high:</td><td>" . $quotes[$tickerSymbol]['high'] . '</td></tr>';
     }
-    if (array_key_exists('low', $quotes->quote)) {
+    if (array_key_exists('low', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Today's low:</td><td>" . $quotes->quote['low'] . '</td></tr>';
+        echo "Today's low:</td><td>" . $quotes[$tickerSymbol]['low'] . '</td></tr>';
     }
-    if (array_key_exists('yearlyHigh', $quotes->quote)) {
+    if (array_key_exists('yearlyHigh', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "52-week high:</td><td>" . $quotes->quote['yearlyHigh'] . '</td></tr>';
+        echo "52-week high:</td><td>" . $quotes[$tickerSymbol]['yearlyHigh'] . '</td></tr>';
     }
-    if (array_key_exists('yearlyLow', $quotes->quote)) {
+    if (array_key_exists('yearlyLow', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "52-week low:</td><td>" . $quotes->quote['yearlyLow'] . '</td></tr>';
+        echo "52-week low:</td><td>" . $quotes[$tickerSymbol]['yearlyLow'] . '</td></tr>';
     }
-    if (array_key_exists('lastClose', $quotes->quote)) {
+    if (array_key_exists('lastClose', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Previous close:</td><td>" . $quotes->quote['lastClose'] . '</td></tr>';
+        echo "Previous close:</td><td>" . $quotes[$tickerSymbol]['lastClose'] . '</td></tr>';
     }
-    if (array_key_exists('volume', $quotes->quote)) {
+    if (array_key_exists('volume', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Volume:</td><td>" . number_format($quotes->quote['volume']) . '</td></tr>';
+        echo "Volume:</td><td>" . number_format($quotes[$tickerSymbol]['volume']) . '</td></tr>';
     }
-    if (array_key_exists('peRatio', $quotes->quote)) {
+    if (array_key_exists('peRatio', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "P-E ratio:</td><td>" . $quotes->quote['peRatio'] . '</td></tr>';
+        echo "P-E ratio:</td><td>" . $quotes[$tickerSymbol]['peRatio'] . '</td></tr>';
     }
-    if (array_key_exists('yieldPct', $quotes->quote)) {
+    if (array_key_exists('yieldPct', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Yield %:</td><td>" . $quotes->quote['yieldPct'] . '</td></tr>';
+        echo "Yield %:</td><td>" . $quotes[$tickerSymbol]['yieldPct'] . '</td></tr>';
     }
-    if (array_key_exists('earnings', $quotes->quote)) {
+    if (array_key_exists('earnings', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Earnings:</td><td>" . $quotes->quote['earnings'] . '</td></tr>';
+        echo "Earnings:</td><td>" . $quotes[$tickerSymbol]['earnings'] . '</td></tr>';
     }
-    if (array_key_exists('dividendAmt', $quotes->quote)) {
+    if (array_key_exists('dividendAmt', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Last dividend:</td><td>" . $quotes->quote['dividendAmt'] . '</td></tr>';
+        echo "Last dividend:</td><td>" . $quotes[$tickerSymbol]['dividendAmt'] . '</td></tr>';
     }
-    if (array_key_exists('dividendDate', $quotes->quote)) {
-        if ($quotes->quote['dividendDate'] > 19700000) {
+    if (array_key_exists('dividendDate', $quotes[$tickerSymbol])) {
+        if ($quotes[$tickerSymbol]['dividendDate'] > 19700000) {
             echo '<tr><td class="text" valign="top">';
-            echo "Last dividend date:</td><td>" . $quotes->quote['dividendDate'] . '</td></tr>';
+            echo "Last dividend date:</td><td>" . $quotes[$tickerSymbol]['dividendDate'] . '</td></tr>';
         }
     }
-    if (array_key_exists('sp500Beta', $quotes->quote)) {
+    if (array_key_exists('sp500Beta', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "S&amp;P 500 beta:</td><td>" . $quotes->quote['sp500Beta'] . '</td></tr>';
+        echo "S&amp;P 500 beta:</td><td>" . $quotes[$tickerSymbol]['sp500Beta'] . '</td></tr>';
     }
-    if (array_key_exists('tradeDate', $quotes->quote)) {
+    if (array_key_exists('tradeDate', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Quote date:</td><td>" . $quotes->quote['tradeDate'] . '</td></tr>';
+        echo "Quote date:</td><td>" . $quotes[$tickerSymbol]['tradeDate'] . '</td></tr>';
     }
-    if (array_key_exists('marketCap', $quotes->quote)) {
+    if (array_key_exists('marketCap', $quotes[$tickerSymbol])) {
         echo '<tr><td class="text" valign="top">';
-        echo "Market cap:</td><td>" . number_format($quotes->quote['marketCap']) . '</td></tr>';
+//        echo "Market cap:</td><td>" . number_format($quotes[$tickerSymbol]['marketCap']) . '</td></tr>';
+        echo "Market cap:</td><td>" . $quotes[$tickerSymbol]['marketCap'] . '</td></tr>';
     }
 
     /* We're done -- now clean up. */
@@ -161,3 +159,4 @@
 echo '</td></tr></table>';
 
 require JONAH_TEMPLATES . '/common-footer.inc';
+
-------------- next part --------------
Index: lib/Stocks/yahoo.php
===================================================================
RCS file: /usr/local/cvs/horde/jonah/lib/Stocks/yahoo.php,v
retrieving revision 1.3
diff -u -r1.3 yahoo.php
--- lib/Stocks/yahoo.php	11 Feb 2003 20:58:14 -0000	1.3
+++ lib/Stocks/yahoo.php	3 Jun 2003 04:08:46 -0000
@@ -1,16 +1,16 @@
 <?php
 /**
- * Jonah_Stocks_yahoo
- * 
- * Copyright (c) 2003 Charles Hagenbuch <chuck at horde.org>.
- *
- * $Horde: jonah/lib/Stocks/yahoo.php,v 1.2 2003/01/29 04:20:06 chuck Exp $
- *
- * @author  Chuck Hagenbuch <chuck at horde.org>
- * @version $Revision: 1.3 $
- * @since   Jonah 0.0.4
- * @package jonah
- */
+* Jonah_Stocks_yahoo
+* 
+* Copyright (c) 2003 Charles Hagenbuch <chuck at horde.org>.
+*
+* $Horde: jonah/lib/Stocks/yahoo.php,v 1.2 2003/01/29 04:20:06 chuck Exp $
+*
+* @author  Chuck Hagenbuch <chuck at horde.org>
+* @version $Revision: 1.3 $
+* @since   Jonah 0.0.4
+* @package jonah
+*/
 class Jonah_Stocks_yahoo {
 
     /**
@@ -20,7 +20,7 @@
 
     function Jonah_Stocks_yahoo($symbols)
     {
-        $this->symbols = $symbols;
+	$this->symbols = $symbols;
     }
 
     function fetch_quotes()
@@ -34,31 +34,35 @@
         $allsymbols = substr($allsymbols, 0, -1);
         $YAHOO_URL = "http://quote.yahoo.com/d?f=snl1d1t1c1p2va2bapomwerr1dyj1&s=$allsymbols";
 
+        Horde::logMessage($YAHOO_URL, __FILE__, __LINE__, LOG_INFO);
         $fp = Jonah::getCachedFP($YAHOO_URL);
         $quotes = array();
         while ($data = fgetcsv($fp, 4096, ',')) {
-            $quotes[] = array(
+	    list($dayLow, $dayHigh) = split("-", $data[13]);
+	    list($yearLow, $yearHigh) = split("-", $data[14]);
+            $quotes[String::lower($data[0])] = array(
                 'symbol' => $data[0],  
-                'company' => $data[1],
-                'lastprice' => $data[2],
-                'tradedate' => $data[3], 
-                'tradetime' => $data[4], 
-                'change' => $data[5], 
-                'changepercent' => $data[6],
+                'name' => $data[1],
+                'lastPrice' => $data[2],
+                'tradeDate' => $data[3] . " " . $data[4], 
+                'changePrice' => $data[5], 
+                'changePct' => $data[6],
                 'volume' => $data[7],
                 'avgvolume' => $data[8],
-                'bid' => $data[9],
-                'ask' => $data[10], 
-                'yesterdaysclose' => $data[11],
+                'bestBid' => $data[9],
+                'bestAsk' => $data[10], 
+                'lastClose' => $data[11],
                 'open' => $data[12],
-                'dayrange' => $data[13],
-                'yearrange' => $data[14],   
-                'earnpershare' => $data[15],
-                'pe' => $data[16], 	
-                'divdate' => $data[17],  
-                'yield' => $data[18], 
-                'divshr' => $data[19], 
-                'marketcap' => $data[20]);
+                'high' => $dayHigh,
+                'low' => $dayLow,
+                'yearlyLow' => $yearLow,   
+                'yearlyHigh' => $yearHigh,   
+                'earnings' => $data[15],
+                'peRatio' => $data[16],     
+                'dividendDate' => $data[17],  
+                'yieldPct' => $data[18], 
+                'dividendAmt' => $data[19], 
+                'marketCap' => $data[20]);
         }
         return $quotes;
     }


More information about the dev mailing list