5
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* @author Robert Basic
* @email dpfreak@gmail.com
* @link http://vtssu.rs/~kazil/
* @copyright 2008 Robert Basic
* @package myWeather
* @version 0.0.1
*/
class myWeather
{
/**
* The URL from witch the information is gathered
*
* @var string
*/
var $url = "http://weather.weatherbug.com/Serbia%20and%20Montenegro/{city}-weather/local-forecast/detailed-forecast.html?zcode=z6286";
/**
* The cURL status code
*
* @var integer
*/
var $curl_status_code = 0;
/**
* Array of cities for which weather information can be gathered
*
* @var array
*/
var $cities = array("Subotica","Belgrade","Novi Sad");
/**
* The city for which the weather information is gathered
*
* @var string
*/
var $city = "";
/**
* How many days to show in the forecast? Max is 7
*
* @var integer
*/
var $number_of_days_for_forecast = 7;
/**
* Array with the forecast details (day, date, image, high, low, description)
*
* @var array
*/
var $forecast = array();
/**
* Should it translate to Serbian?
*
* @var bool
*/
var $translate = true;
/**
* Array with the translation text (must be filled at time, 'cause "new" words can show up)
*
* @var array
*/
var $translate_text = array(
"Weather forcast for" => "Vremenska prognoza za",
"Monday" => "Ponedeljak",
"Tuesday" => "Utorak",
"Wednesday" => "Sreda",
"Thursday" => "Cetvrtak",
"Friday" => "Petak",
"Saturday" => "Subota",
"Sunday" => "Nedelja",
"Hi" => "Najvi�a dnevna",
"Lo" => "Najni�a dnevna",
"Afternoon clouds" => "Popodne naoblacenje",
"Morning clouds" => "Ujutro naoblacenje",
"Showers early" => "Ujutro pljusak",
"Sprinkles early" => "Ujutro ki�ica",
"Sprinkles late" => "Uvece ki�ica",
"Hot" => "Toplo",
"Mostly cloudy" => "Uglavnom oblacno",
"Mostly sunny" => "Uglavnom suncano",
"Mild" => "Umereno",
"Pleasantly warm" => "Prijatno toplo",
"Pleasantly warm, Dry" => "Prijatno toplo, suvo",
"More sun than clouds" => "Vi�e sunca nego oblaka",
"Numerous showers" => "Brojni pljuskovi",
"Temperature of" => "Temperatura",
"Winds" => "Vetar ce duvati brzinom od",
"Humidity will be" => "Vla�nost vazduha ce biti",
"There is a" => "�ansa za padavine je"
);
/**
* Date formats in which the parsed date can be transformed to
*
* @var array
*/
var $date_formats = array("sr" => "d.m.Y.");
/**
* Convert to this date format
*
* @var string
*/
var $date_format = "sr";
/**
* The name of the cache file (to put into, or to get out from)
* Naming: content_randomNumber_unixTimeStamp.html
*
* @var string
*/
var $cache_file;
/**
* Folder for the cache. Default is html
*
* @var string
*/
var $cache_folder;
/**
* How long should the cache live? Default is 7200 seconds (2 hours)
*
* @var integer
*/
var $cache_lifetime = 7200;
/**
* Get the information from the cache file?
*
* @var bool
*/
var $from_cache = false;
/**
* Constructor
*
* @param string $city
* @param integer $number_of_days_for_forecast
* @param string $cache_folder
* @param string $date_format
* @param bool $translate
*/
function __construct($city = "Belgrade",$number_of_days_for_forecast = 7,$cache_folder = "html",$date_format = "sr",$translate = true)
{
// If no cURL functions available, it should die();
if(function_exists("curl_init") === FALSE){
echo "No cURL functions available!";
exit;
}
(in_array($city,$this->cities)) ? $this->city = $city : $this->city = "Belgrade";
if($number_of_days_for_forecast < 1) $number_of_days_for_forecast = 1;
elseif($number_of_days_for_forecast > 7) $number_of_days_for_forecast = 7;
$this->number_of_days_for_forecast = $number_of_days_for_forecast;
$this->cache_folder = $cache_folder;
(in_array($date_format,$this->date_formats)) ? $this->date_format = $date_format : $this->date_format = "sr";
$this->translate = $translate;
// Check if cache is young enough or exists
$this->checkCache();
// If not from cache
if(!$this->from_cache){
$this->clearCache();
$this->setCityInUrl();
$this->createHtmlFile();
$this->getDataFromUrl();
}
// Get the data from the cache file
if($this->curl_status_code == 200 || $this->from_cache){
$this->getDataFromHtmlFile();
}
// if there is forecast to show, show it
if(count($this->forecast) > 0){
$this->showForecast();
}
}
/**
* Show the forecast. Needs some Javascript/CSS tuning.
*
*/
private function showForecast()
{
$box = "\n";
$box .= "
\n";
echo $box;
}
/**
* Translate the forecast. If they change how the info is showing up, this'll need a full rewrite :-/
*
* @param string $string
* @param integer $type
*/
private function translate($string, $type = 1)
{
// Do not translate
if($this->translate === false) return $string;
switch($type){
case 1:{ // An ordinary sentence to translate (ie. "Sunny", "Hot", "Raining" etc...)
if(array_key_exists($string,$this->translate_text)) return $this->translate_text[$string];
else return $string;
}
break;
case 2:{ // Translate the date
return date($this->date_formats[$this->date_format],strtotime($string));
}
break;
case 3:{ // Translate the high/low temperatures
$string = explode(":",$string);
list($text, $temperature) = $string;
if(array_key_exists($text,$this->translate_text)) $text = $this->translate_text[$text];
return $text .": ". trim($temperature) ."C";
}
break;
case 4:{ // Translate sentences with variable data in them. (ie. "Temperature of 24�C", "There is a 37% chance of precipitation." etc)
$sentences = explode(".",$string); // We go sentence by sentence
for($i=0;$itranslate_text)){ // If an ordinary translation...
$sentences[$i] = $this->translate_text[$sentences[$i]];
}
else{
//First type of sentences...
if(preg_match("'(?<=Temperature \s of \s) \d .*'ixs",$sentences[$i],$temp_degree) && array_key_exists("Temperature of",$this->translate_text)){
preg_match("'(?:Temperature \s of)'ixs",$sentences[$i],$temp_text);
$sentences[$i] = $this->translate_text[$temp_text[0]] . " " . $temp_degree[0];
}
// Second type of sentences
elseif(preg_match("'(?<=Winds \s) \d .*'ixs",$sentences[$i],$wind_speed_direction) && array_key_exists("Winds",$this->translate_text)){
preg_match("'(?:Winds)'ixs",$sentences[$i],$wind_text);
$from = array("E","W","N","S","NE","NW","SE","SW","ENE","WNW","ESE","WSW","NNE","NNW","SSE","SSW");
$to = array("I","Z","S","J","SI","SZ","JI","JZ","ISI","ZSZ","IJI","ZJZ","SSI","SSZ","JJI","JJZ");
$wind_speed_direction[0] = str_replace($from,$to,$wind_speed_direction[0]);
$sentences[$i] = $this->translate_text[$wind_text[0]] . " " . $wind_speed_direction[0];
}
//Third type of sentences
elseif(preg_match("'(?<=Humidity \s will \s be \s) \d{2,3}.'ixs",$sentences[$i],$humidity_percent) && array_key_exists("Humidity will be",$this->translate_text)){
preg_match("'(?:Humidity \s will \s be)'ixs",$sentences[$i],$humidity_text);
$sentences[$i] = $this->translate_text[$humidity_text[0]] . " " . $humidity_percent[0];
}
// Fourth type of sentences
elseif(preg_match("'(?<=There \s is \s a \s) \d{1,2}.'ixs",$sentences[$i],$precipitation_percent) && array_key_exists("There is a",$this->translate_text)){
preg_match("'(?:There \s is \s a)'ixs",$sentences[$i],$precipitation_text);
$sentences[$i] = $this->translate_text[$precipitation_text[0]] . " " . $precipitation_percent[0];
}
}
}
return implode(". ",$sentences); // Glue the sentences back together...
}
break;
default:{
if(array_key_exists($string,$this->translate_text)) return $this->translate_text[$string];
else return $string;
}
break;
}
}
/**
* Get the data from the URL. Uses cURL library
*
* @param string $string
* @param integer $type
*/
private function getDataFromUrl()
{
// Init
$ch = curl_init($this->url);
// Open up the cache file for writing
$fh = fopen($this->cache_file, "wb+");
// The output of curl goes into the cache file
curl_setopt($ch, CURLOPT_FILE, $fh);
// Execute curl
curl_exec($ch);
// Get the status code
$this->curl_status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//Close...
curl_close($ch);
fclose($fh);
}
/**
* Check the cache, if the cache file is young enough
*
*/
private function checkCache()
{
$files = scandir($this->cache_folder);
$files = implode(",",$files);
preg_match_all('/(?<=content\_)\w{1,}/i',$files,$matches);
$matches = $matches[0];
$file_ts = array(); // the timestamp that is glued to the file name
$file_rnd = array(); // the random number that is glued to the file name
for($i=0;$i $val){
$diff = $now - $val;
if($diff < $this->cache_lifetime){ // if it's young enough
$this->from_cache = true;
$this->cache_file = $this->cache_folder . "/" . "content_" . $file_rnd[$key] . "_" . $val . ".html";
}
else{
$this->from_cache = false;
}
}
}
/**
* Clear the cache folder, we don't want old files hangin' around...
*
*/
private function clearCache()
{
$files = scandir($this->cache_folder);
foreach($files as $file){
if($file != "." || $file != "..") @unlink("html/$file");
}
}
/**
* Get the data from the html (cache) file
*
*/
private function getDataFromHtmlFile()
{
$file_content = file_get_contents($this->cache_file);
if($file_content != ""){
$this->getForecast($file_content);
}
}
/**
* Gets the forecast information from the html (cache) file
* It's done in several stages, this way was easier...
*
*/
private function getForecast(&$file_content)
{
$forecast = array();
for($i=0;$i<$this->number_of_days_for_forecast;$i++){
$j=$i+1;
// For the last day it's a bit different regex
$regex_1st_part = "'
(.*?)";
($i==6) ? $regex_2nd_part = "
'ixs" : $regex_2nd_part = "
'ixs";
$regex = $regex_1st_part . $regex_2nd_part;
preg_match($regex,$file_content,$forecast[$i]);
}
foreach($forecast as $key => $val){
$forecast[$key] = $forecast[$key][1];
}
$tmp_forecast = array();
foreach($forecast as $key => $val){
// Get the day
preg_match("'
(.*?)
'ixs",$val,$tmp_forecast['day'][$key]);
// Get the date
preg_match("'
(.*?)
'ixs",$val,$tmp_forecast['date'][$key]);
// Get the image
preg_match("'
(.*?)
'ixs",$val,$tmp_forecast['image'][$key]);
// Get the high
preg_match("'
(.*?)
'ixs",$val,$tmp_forecast['high'][$key]);
// Get the low
preg_match("'
(.*?)
'ixs",$val,$tmp_forecast['low'][$key]);
// Get the whole text
preg_match("'
(.*?)
'ixs",$val,$tmp_forecast['description'][$key]);
}
for($i=0;$iforecast[$i]['day'] = $tmp_forecast['day'][$i][1];
$this->forecast[$i]['date'] = $tmp_forecast['date'][$i][1];
$this->forecast[$i]['image'] = $tmp_forecast['image'][$i][1];
$this->forecast[$i]['high'] = $tmp_forecast['high'][$i][1];
$this->forecast[$i]['low'] = $tmp_forecast['low'][$i][1];
$this->forecast[$i]['description'] = $tmp_forecast['description'][$i][1];
}
}
/**
* Set the city in the URL
*
*/
private function setCityInUrl()
{
$this->url = str_replace("{city}",$this->city,$this->url);
}
/**
* Actually, create the cache file... but it's the same...
*
*/
private function createHtmlFile()
{
if(!is_dir($this->cache_folder)){
mkdir($this->cache_folder);
chmod($this->cache_folder, 0755);
}
mt_srand();
$random = mt_rand()."_".time();
$this->cache_file = $this->cache_folder . "/" . "content_".$random.".html";
}
}
?>