ソースを参照

add weather lib and convenience helper

euromark 12 年 前
コミット
ec38c06a23

+ 137 - 0
Lib/WeatherLib.php

@@ -0,0 +1,137 @@
+<?php
+/**
+ * alternatives:
+ * http://simplepie.org/wiki/addons/yahoo_weather / http://cam.pl24.de/homepage-wetter.php
+ * http://www.phpclasses.org/browse/file/11524.html
+ * example: http://weather.yahooapis.com/forecastrss?p=GMXX0154
+ * http://www.webmashup.com/API/Weather/Yahoo-Weather-API-l1871.html
+ * http://developer.yahoo.com/weather/
+ * http://www.webmashup.com/API/Weather/AccuWeather-API-l1862.html
+ * http://www2.voegeli.li/no_cache/code-tutorials/php-scripts/class-weather-v2.html?L=1
+ */
+App::uses('Xml', 'Utility');
+App::uses('HttpSocket', 'Network/Http');
+
+/**
+ * WeatherLib to retreive the current weather + forecast
+ *
+ * You can use Configure::write('Weather', ...) to adjust settings for it globabally via configs:
+ * - key (required)
+ * - free (true/false)
+ * - format
+ * - num_of_days
+ *
+ * @author Mark Scherer
+ * @license MIT
+ * @see http://www.worldweatheronline.com/free-weather-feed.aspx
+ * 2010-08-29 ms
+ */
+class WeatherLib {
+
+	const API_URL = 'http://www.worldweatheronline.com/feed';
+
+	const API_URL_FREE = 'http://free.worldweatheronline.com/feed/';
+
+	public $settings = array(
+		'format' => 'xml', # json, csv, xml
+		'num_of_days' => 5,
+		'q' => '', # ; 48.00,11.00
+		'key' => '',
+		'free' => true, # true/false
+	);
+
+	public function __construct() {
+		$this->settings = array_merge($this->settings, (array)Configure::read('Weather'));
+	}
+
+	/**
+	 * @return array Data or false on failure
+	 */
+	public function get($q, $options = array()) {
+		$options = array_merge($this->settings, $options);
+		$options['q'] = urlencode($q);
+		$data = $this->_get('weather.ashx', $options);
+		if (empty($data) || empty($data['data'])) {
+			return false;
+		}
+		return $data['data'];
+	}
+
+	/**
+	 * @return array
+	 */
+	public function conditions() {
+		$options = array();
+		$options['format'] = $this->settings['format'];
+		if ($options['format'] === 'json') {
+			$options['format'] = 'xml';
+		}
+		$conditions = $this->_get('wwoConditionCodes.xml', $options);
+		if (empty($conditions) || empty($conditions['codes']['condition'])) {
+ 			return array();
+ 		}
+ 		return $conditions['codes']['condition'];
+	}
+
+	//.../feed/weather.ashx?q=Neufahrn&format=json&num_of_days=2&key=598dfbdaeb121715111208
+	public function _get($url, $options) {
+		if (isset($options['cache'])) {
+			$cache = $options['cache'];
+			unset($options['cache']);
+		}
+		$url = $this->_url($url, $options);
+		if (!empty($cache)) {
+			if (!Cache::isInitialized('data')) {
+				Cache::set('duration', $cache, 'data');
+			}
+			if ($cacheContent = Cache::read(md5($url), 'data')) {
+				return $cacheContent;
+			}
+		}
+
+		$Socket = new HttpSocket(array('timeout' => 5));
+		$file = $Socket->get($url);
+		$content = $file->body;
+		if (empty($content)) {
+			return false;
+		}
+ 		switch ($options['format']) {
+ 			case 'json':
+ 				$res = json_decode($content);
+ 				break;
+ 			case 'xml':
+				// now parse it
+				//debug($file);
+				$parsed_xml = Xml::build($content);
+				//debug($parsed_xml);
+				$res = Xml::toArray($parsed_xml);
+				//debug($res);
+ 				break;
+			case 'csv':
+				$res = array();
+ 		}
+
+ 		if (!empty($cache)) {
+			Cache::write(md5($url), $res, 'data');
+		}
+
+ 		if (empty($res)) {
+ 			return false;
+ 		}
+ 		return $res;
+	}
+
+	/**
+	 * @return string Url
+	 */
+	public function _url($url, $options = array()) {
+		$params = array();
+		foreach ($options as $key => $option) {
+			$params[] = $key . '=' . $option;
+		}
+		$params = (!empty($params) ? '?' : '') . implode('&', $params);
+		$domain = $this->settings['free'] ? self::API_URL_FREE : self::API_URL;
+		return $domain . $url . $params;
+	}
+
+}

+ 34 - 0
Test/Case/Lib/WeatherLibTest.php

@@ -0,0 +1,34 @@
+<?php
+App::uses('WeatherLib', 'Tools.Lib');
+App::uses('MyCakeTestCase', 'Tools.TestSuite');
+
+class WeatherLibTest extends MyCakeTestCase {
+
+	public function setUp() {
+		Configure::write('Weather.key', '598dfbdaeb121715111208');
+
+		App::uses('WeatherLib', 'Tools.Lib');
+		$this->Weather = new WeatherLib();
+	}
+
+	public function testUrl() {
+		$res = $this->Weather->_url('x.xml');
+		$this->assertEquals('http://free.worldweatheronline.com/feed/x.xml', $res);
+
+		$res = $this->Weather->_url('x.xml', array('y'=>'z'));
+		$this->assertEquals('http://free.worldweatheronline.com/feed/x.xml?y=z', $res);
+	}
+
+	public function testWeatherConditions() {
+		$res = $this->Weather->conditions();
+		$this->out($res);
+		$this->assertTrue(!empty($res));
+	}
+
+	public function testWeather() {
+		$res = $this->Weather->get('48.2,11.1');
+		$this->out($res);
+		$this->assertTrue(!empty($res));
+	}
+
+}

+ 79 - 0
Test/Case/View/Helper/WeatherHelperTest.php

@@ -0,0 +1,79 @@
+<?php
+
+App::uses('WeatherHelper', 'Tools.View/Helper');
+App::uses('HtmlHelper', 'View/Helper');
+App::uses('View', 'View');
+
+/**
+ * 2010-06-24 ms
+ */
+class WeatherHelperTest extends CakeTestCase {
+
+/**
+ * setUp method
+ */
+	public function setUp() {
+		$this->Weather = new WeatherHelper(new View(null));
+		$this->Weather->Html = new HtmlHelper(new View(null));
+	}
+
+	/** TODO **/
+
+	public function testDisplay() {
+
+		$res = $this->Weather->get('51.0872,13.8028');
+		$res = $this->_display($res);
+		pr($res);
+		$this->assertTrue(!empty($res));
+
+		echo BR.BR;
+
+
+		$res = $this->Weather->get('Berlin, Deutschland');
+		$res = $this->_display($res);
+		pr($res);
+		$this->assertTrue(!empty($res));
+
+		echo BR.BR;
+
+		$res = $this->Weather->get('Schwäbisch Hall, Deutschland');
+		$res = $this->_display($res);
+		pr($res);
+		$this->assertTrue(!empty($res));
+
+		$res = $this->Weather->get('xxxxx');
+		$res = $this->_display($res);
+		pr($res);
+		$this->assertTrue(empty($res));
+
+		echo BR.BR;
+
+	}
+
+
+	public function _display($w) {
+		$res = '';
+		if (empty($w['Request'])) {
+			return $res;
+		}
+
+		$res .= '<table><tr>';
+		for ($i = 2; $i < 5; $i++) {
+			$weather = $w['Weather'][$i];
+
+			$res .= '<td>';
+			$res .= '<h1>'.date('D', strtotime($weather['date'])).'</h1>';
+			$res .= '<div>'.date('M d, Y', strtotime($weather['date'])).'</div>';
+			$res .= '<h1>'.$this->Weather->Html->image($weather['weatherIconUrl']).'</h1>';
+			$res .= '<div>'.$weather['tempMinC'].'° - '.$weather['tempMaxC'].'°</div>';
+			$res .= '<div>'.$weather['weatherDesc'].'</div>';
+
+			$res .= '</td>';
+		}
+		$res .= '</tr></table>';
+
+		return $res;
+	}
+
+
+}

+ 71 - 0
View/Helper/WeatherHelper.php

@@ -0,0 +1,71 @@
+<?php
+App::uses('AppHelper', 'View/Helper');
+App::uses('WeatherLib', 'Tools.Lib');
+
+/**
+ * Display weather in the view
+ *
+ * @author Mark Scherer
+ * @license MIT
+ * 2010-08-29 ms
+ */
+class WeatherHelper extends AppHelper {
+
+	public $helpers = array('Html');
+
+	public $imagePath = ''; //'http://www.google.com/ig/images/weather/';
+
+	public $imageUrl = '';
+
+	public function __construct($View = null, $settings = array()) {
+		parent::__construct($View, $settings);
+
+		$this->imageUrl = $this->imagePath;
+	}
+
+	/**
+	 * Display a ready table
+	 *
+	 * //TODO
+	 * @return string
+	 */
+	public function display($location) {
+		$weather = $this->get($location);
+
+		$res = '';
+		if (empty($weather)) {
+			return $res;
+		}
+
+		$res .= '<table><tr>';
+
+		//$res .= '<td>'.[].'</td>';
+
+		$res .= '</tr></table>';
+
+		$res .= '<h1>'.$weather['city'].':</h1>';
+
+		return $res;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function imageUrl($icon, $full = false) {
+		return $this->imageUrl . $icon;
+	}
+
+	/**
+	 * @return array
+	 */
+	public function get($location, $cOptions = array()) {
+		$Weather = new WeatherLib();
+
+		$options = array(
+			'cache'=>'+1 hour'
+		);
+		$options = array_merge($options, $cOptions);
+		return $Weather->get($location, $options);
+	}
+
+}