[jonah] Weather station selection patch

Ben Scott bscott@chiark.greenend.org.uk
Thu Nov 21 16:13:44 2002


Attached is a patch to jonah HEAD to enable a SQL backend for the weather
station selection. The sql to add the relevant tables in mysql is in
jonah/scripts/db/  - the README has details on where to get my
pre-generated data. A noradar.gif is available at the same location to put
in jonah/graphics/ for stations without radar images (which is all of them
at the moment as I haven't had a chance to merge in the current urls)

This backend can be enabled through the admin configuration system -
select 'sql' for this backend, or 'default' to use the old style list of
stations. I think the implementation is probably a little on the hacky
side, but it works for me, doesn't appear to break anything, and might
prove useful for other people.

-- 
Ben Scott                                Powered by C8H10N4O2
bscott@chiark.greenend.org.uk (personal)
ben.scott@enfocast.com (work)
-------------- next part --------------
diff -x CVS -r --unified --new-file jonah-head/config/conf.xml jonah/config/conf.xml
--- jonah-head/config/conf.xml	2002-11-10 08:04:38.000000000 +0000
+++ jonah/config/conf.xml	2002-11-21 12:55:11.000000000 +0000
@@ -17,6 +17,43 @@
    <configstring name="expire" desc="How many seconds must have elapsed since
        updating weather before we update it again?  Default is 1800 seconds (half an
        hour).">1800</configstring>
+
+<configenum name="driver" desc="What storage driver should we use?">sql
+   <values>
+    <value>sql</value>
+    <value>default</value>
+   </values>
+  </configenum>
+
+  <configsection name="params">
+   <configdescription>
+        Any parameters that the weather source driver needs. This is 
+        either sql or default (weather.php).
+        Sample values are for a MySQL sql driver.
+   </configdescription>
+   <configenum name="phptype" desc="What database backend should we use?">mysql
+    <values>
+     <value desc="MySQL">mysql</value>
+     <value desc="PostgreSQL">pgsql</value>
+     <value desc="ODBC">odbc</value>
+     <value desc="Oracle">oci8</value>
+    </values>
+   </configenum>
+   <configenum name="protocol" desc="How should we connect to the database?">tcp
+    <values>
+     <value desc="UNIX Sockets">unix</value>
+     <value desc="TCP/IP">tcp</value>
+    </values>
+   </configenum>
+   <configstring name="hostspec" desc="Database server/host/ODBC dsn">localhost</configstring>
+   <configstring name="username" desc="Username to connect to the database as">horde</configstring>
+   <configstring name="password" desc="Password to connect with">****</configstring>
+   <configstring name="database" desc="Database name to use">horde</configstring>
+   <configstring name="stationstable" desc="Database weather stations table">jonah_weatherstations</configstring>
+   <configstring name="countriestable" desc="Database countries table">jonah_weathercountries</configstring>
+   </configsection>
+
+
  </configsection>
 
  <configsection name="stocks">
diff -x CVS -r --unified --new-file jonah-head/config/prefs.php.dist jonah/config/prefs.php.dist
--- jonah-head/config/prefs.php.dist	2002-11-05 22:27:02.000000000 +0000
+++ jonah/config/prefs.php.dist	2002-11-21 15:54:05.000000000 +0000
@@ -20,7 +20,7 @@
     'column' => _("Your Content"),
     'label' => _("Weather Station"),
     'desc' => _("Change the location for which weather is obtained."),
-    'members' => array('location'));
+    'members' => array('setlocation'));
 
 $prefGroups['stocks'] = array(
     'column' => _("Your Content"),
@@ -139,174 +139,23 @@
     'type' => 'checkbox',
     'desc' => _("Should measurements be shown in metric values?"));
 
-// These must be added to the channels weather array, too, to be selectable.
 $_prefs['location'] = array(
-    'value' => 'bismarck',
+    'value' => 'aberdeen',
     'locked' => false,
     'shared' => false,
-    'type' => 'enum',
-    'enum' => array(
-		'aberdeen' => "Aberdeen, SD",
-		'albany' => "Albany, NY",
-		'albuquerque' => "Albuquerque, NM",
-		'altus' => "Altus, OK",
-		'amarillo' => "Amarillo, TX",
-		'anchorage' => "Anchorage, AK",
-		'anderson' => "Anderson, GU",
-		'atlanta' => "Atlanta, GA",
-		'austin' => "Austin, TX",
-		'beale' => "Beale, CA",
-		'bethel' => "Bethel, AK",
-		'billings' => "Billings, MT",
-		'binghamton' => "Binghamton, NY",
-		'birmingham' => "Birmingham, AL",
-		'bismarck' => "Bismarck, ND",
-		'boise' => "Boise, ID",
-		'boston' => "Boston, MA",
-		'brownsville' => "Brownsville, TX",
-		'buffalo' => "Buffalo, NY",
-		'burlington' => "Burlington, VT",
-		'cannon' => "Cannon, NM",
-		'cedarcity' => "Cedar City, UT",
-		'charlestonsc' => "Charleston, SC",
-		'charlestonwv' => "Charleston, WV",
-		'cheyenne' => "Cheyenne, WY",
-		'chicago' => "Chicago, IL",
-		'cincinnati' => "Cincinnati, OH",
-		'cleveland' => "Cleveland, OH",
-		'columbia' => "Columbia, SC",
-		'columbus' => "Columbus, MS",
-		'corpuschristi' => "Corpus Christi, TX",
-		'dallas' => "Dallas, TX",
-		'davenport' => "Davenport, IA",
-		'denver' => "Denver, CO",
-		'desmoines' => "Des Moines, IA",
-		'detroit' => "Detroit, MI",
-		'dodgecity' => "Dodge City, KS",
-		'dover' => "Dover, DE",
-		'duluth' => "Duluth, MN",
-		'dyess' => "Dyess, TX",
-		'edwards' => "Edwards, CA",
-		'eglin' => "Eglin, FL",
-		'elpaso' => "El Paso, TX",
-		'elko' => "Elko, NV",
-		'eureka' => "Eureka, CA",
-		'fairbanks' => "Fairbanks, AK",
-		'flagstaff' => "Flagstaff, AZ",
-		'fortcampbell' => "Fort Campbell, KY",
-		'fortdrum' => "Fort Drum, NY",
-		'forthood' => "Fort Hood, TX",
-		'fortpolk' => "Fort Polk, LA",
-		'fortrucker' => "Fort Rucker, AL",
-		'fortsmith' => "Fort Smith, AR",
-		'fortwayne' => "Fort Wayne, IN",
-		'gaylord' => "Gaylord, MI",
-		'glasgow' => "Glasgow, MT",
-		'goodland' => "Goodland, KS",
-		'grandforks' => "Grand Forks, ND",
-		'grandjunction' => "Grand Junction, CO",
-		'grandrapids' => "Grand Rapids, MI",
-		'greatfalls' => "Great Falls, MT",
-		'greenbay' => "Green Bay, WI",
-		'greer' => "Greer, SC",
-		'griffiss' => "Griffiss, NY",
-		'hastings' => "Hastings, NE",
-		'holloman' => "Holloman, NM",
-		'houlton' => "Houlton, ME",
-		'houston' => "Houston, TX",
-		'huntsville' => "Huntsville, AL",
-		'indianapolis' => "Indianapolis, IN",
-		'jacksonky' => "Jackson, KY",
-		'jacksonms' => "Jackson, MS",
-		'jacksonville' => "Jacksonville, FL",
-		'kadena' => "Kadena, Okinawa",
-		'kamuela' => "Kamuela, HI",
-		'kansascity' => "Kansas City, MO",
-		'keywest' => "Key West, FL",
-		'kingsalmon' => "King Salmon, AK",
-		'knoxville' => "Knoxville, TN",
-		'kunsanab' => "Kunsan AB, Korea",
-		'lacrosse' => "La Crosse, WI",
-		'lajesab' => "Lajes AB, Azores",
-		'lakecharles' => "Lake Charles, LA",
-		'lasvegas' => "Las Vegas, NV",
-		'laughlin' => "Laughlin, TX",
-		'lincoln' => "Lincoln, IL",
-		'littlerock' => "Little Rock, AR",
-		'losangeles' => "Los Angeles, CA",
-		'louisville' => "Louisville, KY",
-		'lubbock' => "Lubbock, TX",
-		'marquette' => "Marquette, MI",
-		'maxwell' => "Maxwell, AL",
-		'medford' => "Medford, OR",
-		'melbourne' => "Melbourne, FL",
-		'memphis' => "Memphis, TN",
-		'miami' => "Miami, FL",
-		'middletonis' => "Middleton Is, AK",
-		'midland' => "Midland, TX",
-		'milwaukee' => "Milwaukee, WI",
-		'minneapolis' => "Minneapolis, MN",
-		'minot' => "Minot, ND",
-		'missoula' => "Missoula, MT",
-		'mobile' => "Mobile, AL",
-		'molokai' => "Molokai, HI",
-		'moody' => "Moody, GA",
-		'moreheadcity' => "Morehead City, NC",
-		'nashville' => "Nashville, TN",
-		'neworleans' => "New Orleans, LA",
-		'newyork city' => "New York City, NY",
-		'nome' => "Nome, AK",
-		'norfolk' => "Norfolk, VA",
-		'northplatte' => "North Platte, NE",
-		'oklahomacity' => "Oklahoma City, OK",
-		'omaha' => "Omaha, NE",
-		'paducah' => "Paducah, KY",
-		'pendleton' => "Pendleton, OR",
-		'philadelphia' => "Philadelphia, PA",
-		'phoenix' => "Phoenix, AZ",
-		'pittsburgh' => "Pittsburgh, PA",
-		'pocatello' => "Pocatello, ID",
-		'portlandme' => "Portland, ME",
-		'portlandor' => "Portland, OR",
-		'pueblo' => "Pueblo, CO",
-		'raleigh' => "Raleigh, NC",
-		'rapidcity' => "Rapid City, SD",
-		'reno' => "Reno, NV",
-		'riverton' => "Riverton, WY",
-		'roanoke' => "Roanoke, VA",
-		'robins' => "Robins, GA",
-		'sacramento' => "Sacramento, CA",
-		'saintlouis' => "Saint Louis, MO",
-		'saltlake' => "Salt Lake City, UT",
-		'sanangelo' => "San Angelo, TX",
-		'sandiego' => "San Diego, CA",
-		'sanangelo' => "San Angelo, TX",
-		'sandiego' => "San Diego, CA",
-		'sanfrancisco' => "San Francisco, CA",
-		'sanjoaquin' => "San Joaquin Vly, CA",
-		'sanjuan' => "San Juan, PR",
-		'santaana' => "Santa Ana Mtns, CA",
-		'seattle' => "Seattle, WA",
-		'shreveport' => "Shreveport, LA",
-		'siouxfalls' => "Sioux Falls, SD",
-		'sitka' => "Sitka, AK",
-		'southkauai' => "South Kauai, HI",
-		'southshore' => "South Shore, HI",
-		'spokane' => "Spokane, WA",
-		'springfield' => "Springfield, MO",
-		'statecollege' => "State College, PA",
-		'sterling' => "Sterling, VA",
-		'tallahassee' => "Tallahassee, FL",
-		'tampa' => "Tampa, FL",
-		'topeka' => "Topeka, KS",
-		'tucson' => "Tucson, AZ",
-		'tulsa' => "Tulsa, OK",
-		'vance' => "Vance, OK",
-		'vandenberg' => "Vandenberg, CA",
-		'wichita' => "Wichita, KS",
-		'wilmington' => "Wilmington, NC",
-		'yuma' => "Yuma, AZ"),
-    'desc' => _("Location for which to retrieve weather information."));
+    'type' => 'implicit');
+
+$_prefs['selectedcountry'] = array(
+    'value' => 'none',
+    'locked' => false,
+    'shared' => false,
+    'type' => 'implicit');
+
+
+$_prefs['setlocation'] = array(
+    'type' => 'special');
+
+
 
 $_prefs['ticker'] = array(
     'value' => '',
diff -x CVS -r --unified --new-file jonah-head/config/weather.php.dist jonah/config/weather.php.dist
--- jonah-head/config/weather.php.dist	2002-11-05 22:27:03.000000000 +0000
+++ jonah/config/weather.php.dist	2002-11-21 15:46:54.000000000 +0000
@@ -1,5 +1,11 @@
 <?php
 
+$conf = &$GLOBALS['conf'];
+$params = $conf['weather']['params'];
+
+
+if ($conf['weather']['driver'] == 'default') {
+
 /* These must be added to the prefs array, too, to be selectable. */
 $weather = array(
 'aberdeen' => array(
@@ -634,5 +640,65 @@
         'name' => 'Yuma, AZ',
        'radar' => 'http://66.28.69.144/data/nids/YUX19_anim.gif',
         'url'  => 'http://weather.interceptvector.com/weather.xml?city=Yuma&state=AZ'),
-
 );
+
+} else {
+
+// connect to DB and retrieve info
+    require_once 'DB.php';
+
+    if (!is_array($params)) {
+        Horde::fatal(new PEAR_Error(_("No configuration information specified for SQL Preferences.")), __FILE__, __LINE__);
+    }
+    if (!array_key_exists('phptype', $params)) {
+        Horde::fatal(new PEAR_Error(_("Required 'phptype' not specified in preferences configuration.")), __FILE__, __LINE__);
+    }
+    if (!array_key_exists('hostspec', $params)) {
+        Horde::fatal(new PEAR_Error(_("Required 'hostspec' not specified in preferences configuration.")), __FILE__, __LINE__);
+    }
+    if (!array_key_exists('username', $params)) {
+        Horde::fatal(new PEAR_Error(_("Required 'username' not specified in preferences configuration.")), __FILE__, __LINE__);
+    }
+    if (!array_key_exists('password', $params)) {
+        Horde::fatal(new PEAR_Error(_("Required 'password' not specified in preferences configuration.")), __FILE__, __LINE__);
+    }
+    if (!array_key_exists('database', $params)) {
+        Horde::fatal(new PEAR_Error(_("Required 'database' not specified in preferences configuration.")), __FILE__, __LINE__);
+    }
+    if (!array_key_exists('stationstable', $params)) {
+        $this->_params['stationstable'] = 'jonah_weatherstations';
+    }
+    if (!array_key_exists('countriestable', $params)) {
+        $this->_params['countriestable'] = 'jonah_weathercountries';
+    }    
+
+    $db = DB::connect( $params, true);
+    if (DB::isError($db)) {
+        Horde::fatal($db, __FILE__, __LINE__);
+    }
+
+    $db->setOption('optimize', 'portability');
+
+    global $prefs;
+    $country = $prefs->getValue('selectedcountry');
+    $location = $prefs->getValue('location');
+    $city = preg_replace ( '/' . $country . '/', '' , $location);
+
+    // spoof the old-style weather array with the single needed element.
+    $weather = array(
+        $location => array(
+           'name' => $city,
+           'radar' => $db->getOne(sprintf('SELECT radar FROM %s WHERE 
+                                           country = \'%s\' AND name = \'%s\'',
+                                  $params['stationstable'],
+                                  $country,
+                                  $city)),
+            'url'  => $db->getOne(sprintf('SELECT url FROM %s WHERE 
+                                           country = \'%s\' AND name = \'%s\'',
+                                  $params['stationstable'],
+                                  $country,
+                                  $city)))
+    );
+    
+    $db->disconnect();
+}
diff -x CVS -r --unified --new-file jonah-head/prefs.php jonah/prefs.php
--- jonah-head/prefs.php	2002-08-19 21:52:47.000000000 +0000
+++ jonah/prefs.php	2002-11-21 12:59:58.000000000 +0000
@@ -8,12 +8,11 @@
  * did not receive this file, see http://www.horde.org/bsdl.php.
  */
 
-function handle_weatherxselect($updated)
+function handle_setlocation($updated)
 {
     global $prefs;
-
-    $weatherx = Horde::getFormData('weather_station');
-    $prefs->setValue('weather_station', $weatherx);
+    $location = Horde::getFormData('location');
+    $prefs->setValue('location', $location);
     return true;
 }
 
diff -x CVS -r --unified --new-file jonah-head/scripts/db/README jonah/scripts/db/README
--- jonah-head/scripts/db/README	1970-01-01 00:00:00.000000000 +0000
+++ jonah/scripts/db/README	2002-11-21 15:10:11.000000000 +0000
@@ -0,0 +1,6 @@
+To add the tabes run mysql -u root -p horde < jonah_weather.sql
+
+To import the data, download the two jonah text files from http://www.chiark.greenend.org.uk/~bscott/horde/ and then run:
+mysqlimport -r -p horde jonah_weathercountries.tsv
+mysqlimport -r -p horde jonah_weatherstations.tsv
+ 
diff -x CVS -r --unified --new-file jonah-head/scripts/db/jonah_weather.sql jonah/scripts/db/jonah_weather.sql
--- jonah-head/scripts/db/jonah_weather.sql	1970-01-01 00:00:00.000000000 +0000
+++ jonah/scripts/db/jonah_weather.sql	2002-11-21 15:06:27.000000000 +0000
@@ -0,0 +1,20 @@
+-- $Horde$
+
+CREATE TABLE jonah_weathercountries (
+    country VARCHAR(4) NOT NULL,
+    fullname VARCHAR(64) NOT NULL,
+    PRIMARY KEY (country) 
+);
+
+CREATE TABLE jonah_weatherstations (
+    url VARCHAR(255) NOT NULL,
+    country VARCHAR(4) NOT NULL,
+    name VARCHAR(255) NOT NULL,
+    radar VARCHAR(255) NOT NULL DEFAULT 'graphics/noradar.jpg',
+    PRIMARY KEY (country, name)
+);
+
+GRANT SELECT, INSERT, UPDATE, DELETE ON jonah_weathercountries TO horde@localhost;
+GRANT SELECT, INSERT, UPDATE, DELETE ON jonah_weatherstations TO horde@localhost;
+
+
diff -x CVS -r --unified --new-file jonah-head/templates/prefs/setlocation.inc jonah/templates/prefs/setlocation.inc
--- jonah-head/templates/prefs/setlocation.inc	1970-01-01 00:00:00.000000000 +0000
+++ jonah/templates/prefs/setlocation.inc	2002-11-21 12:07:36.000000000 +0000
@@ -0,0 +1,161 @@
+<?php
+
+    $conf = &$GLOBALS['conf'];
+    // use stations in weather.php
+    if ($conf['weather']['driver'] == 'default') {
+
+?>
+
+<table border="0">
+<tr>
+    <td><?php echo _("Weather station:") ?><br />
+    <select name="location">
+    <?php
+        require JONAH_BASE . '/config/weather.php';
+        $current = $prefs->getValue('location');
+        foreach ($weather as $key => $details) {
+            if ($current == $key) {
+                $selected = " selected";
+            } else {
+                $selected = "";
+            }
+            echo '<option value="' . $key . '"' . $selected . '>' . 
+                  $details['name'] . "</a>\n";
+        }
+    ?>
+    </select>
+    </td>
+</tr></table>
+
+<?php
+    // use the database backend
+    } else {
+
+        if ($prefs->getValue('selectedcountry') != 
+            Horde::getGet('selectedcountry')) {
+ 
+            $prefs->setValue('selectedcountry', 
+                             Horde::getGet('selectedcountry')); 
+        }
+
+?>
+
+<table border="0">
+<tr>
+    <td><?php echo _("Weather station:") ?><br />
+    <script language="JavaScript" type="text/javascript">
+    <!--
+       function update() {
+       location=document.prefs.country.options[top.horde_main.prefs.country.selectedIndex].value;
+       }
+    // -->
+    </script>
+
+
+    <?php
+        require JONAH_BASE . '/config/weather.php';
+
+        $current = $prefs->getValue('location');
+        $params = $conf['weather']['params'];
+
+        // connect to db
+        require_once 'DB.php';
+
+        if (!is_array($params)) {
+            Horde::fatal(new PEAR_Error(_("No configuration information specified for SQL Preferences.")), __FILE__, __LINE__);
+        }
+        if (!array_key_exists('phptype', $params)) {
+            Horde::fatal(new PEAR_Error(_("Required 'phptype' not specified in preferences configuration.")), __FILE__, __LINE__);
+        }
+        if (!array_key_exists('hostspec', $params)) {
+            Horde::fatal(new PEAR_Error(_("Required 'hostspec' not specified in preferences configuration.")), __FILE__, __LINE__);
+        }
+        if (!array_key_exists('username', $params)) {
+            Horde::fatal(new PEAR_Error(_("Required 'username' not specified in preferences configuration.")), __FILE__, __LINE__);
+        }
+        if (!array_key_exists('password', $params)) {
+            Horde::fatal(new PEAR_Error(_("Required 'password' not specified in preferences configuration.")), __FILE__, __LINE__);
+        }
+        if (!array_key_exists('database', $params)) {
+            Horde::fatal(new PEAR_Error(_("Required 'database' not specified in preferences configuration.")), __FILE__, __LINE__);
+        }
+        if (!array_key_exists('stationstable', $params)) {
+            $params['stationstable'] = 'jonah_weatherstations';
+        }
+        if (!array_key_exists('countriestable', $params)) {
+            $params['countriestable'] = 'jonah_weathercountries';
+        }
+
+
+        $db = DB::connect( $params, true);
+        if (DB::isError($db)) {
+            Horde::fatal($db, __FILE__, __LINE__);
+        }
+
+        $db->setOption('optimize', 'portability');
+
+        // get list of countries and put it in an option list control
+        $countries = $db->getCol(sprintf('SELECT country FROM %s 
+                                          ORDER BY fullname',
+                                 $params['countriestable'])); 
+
+        echo '<select name="country" onchange=update()>"';
+
+        // initial state if the user hasn't picked a country
+        if ($prefs->getValue('selectedcountry') == '') {
+            echo '<option>Please select a Country/State...</option>';
+        }
+
+        foreach ($countries as $country) {
+            $fullname = $db->getOne(sprintf('SELECT fullname FROM %s WHERE 
+                                             country = \'%s\'',
+                                    $params['countriestable'],
+                                    $country));
+ 
+            if ($country == $prefs->getValue('selectedcountry')) {
+                echo(sprintf('<option value="/horde/jonah/prefs.php?group=weather&selectedcountry=%s" selected>%s</option>',
+                     $country, $fullname));
+
+            } else {
+                echo(sprintf('<option value="/horde/jonah/prefs.php?group=weather&selectedcountry=%s">%s</option>',
+                     $country, $fullname));
+            }
+
+        }
+
+        echo '</select>';
+        echo '<select name="location">';
+    
+        if ($prefs->getValue('selectedcountry') == '') {
+            echo '\n<option value="' . $current . '">--------</option>\n';
+        } else {
+
+            $cities = $db->getCol(sprintf('SELECT name FROM %s WHERE 
+                                           country = \'%s\' ORDER BY name',
+                                  $params['stationstable'],
+                                  $prefs->getValue('selectedcountry')));
+ 
+            foreach ($cities as $city) {
+
+                echo(sprintf('<option value="%s%s">%s</option>\n',
+                     $prefs->getValue('selectedcountry'),
+                     $city,
+                     $city));
+            }
+
+
+        }
+
+	$db->disconnect();        
+
+
+    ?>
+    </select>
+    </td>
+</tr></table>
+
+
+
+<?php
+    }
+?>


More information about the jonah mailing list