weather_es_parser.inc in Weather_es 6
Same filename and directory in other branches
Gets the data from the AEMET web
The module is compatible with Drupal 5.x
@author José Mª Sirvent
File
weather_es_parser.incView source
<?php
/**
* Weather_es shows the weather forecast of 8112 cities of Spain using the AEMET web information.
* Copyright (C) 2008 José Mª Sirvent <drupal@hykrion.com>
*
* This file is part of the Drupal weather_es module.
* It is based on the Weather module which was written in 2006 by
* Tobias Toedter <t.toedter@gmx.net>.
*
* Weather_es 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 2 of the License, or
* (at your option) any later version.
*
* Weather_es 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.
*
* You should have received a copy of the GNU General Public License
* along with Weather_es; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Gets the data from the AEMET web
*
* The module is compatible with Drupal 5.x
*
* @author José Mª Sirvent
*/
/**
* Get the td info: rain probability, tmax, tmin...
*/
function _weather_es_get_td_info($captured_td, $ampm) {
$lon = sizeof($captured_td);
// Sky state
if ($ampm == 'am') {
$end = 9;
}
else {
$end = 8;
}
// In images
for ($i = 0; $i <= $end; $i++) {
preg_match('/[0-9]{2}.gif/', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$sky_img[] = substr($data[0], 0, $data_lon - 4);
}
// In text
for ($i = 0; $i <= $end; $i++) {
preg_match('/alt=".+"/', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$sky_txt[] = substr($data[0], 5, $data_lon - 6);
}
// Begining of wind direction
$beg = $end + 1;
for ($i = $beg; $i <= $lon; $i++) {
if (preg_match('/[A-Z]{1,2}.gif/', $captured_td[$i])) {
break;
}
}
$win_beg = $i;
// Get all the data between the rain probability and the wind direction
$end = $win_beg - 1;
for ($i = $beg; $i <= $end; $i++) {
preg_match('/>[0-9]{1,4}/', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$rain_tmin[] = substr($data[0], 1, $data_lon);
}
$beg = $win_beg;
// Wind direction
if ($ampm == 'am') {
$end = $beg + 9;
}
else {
$end = $beg + 8;
}
for ($i = $beg; $i <= $end; $i++) {
preg_match('/alt=".+"/', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$win_dir[] = substr($data[0], 5, $data_lon - 6);
}
$beg = $end + 1;
// Wind speed
if ($ampm == 'am') {
$end = $beg + 9;
}
else {
$end = $beg + 8;
}
for ($i = $beg; $i <= $end; $i++) {
preg_match('/>[0-9]{1,3}/', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$win_spd[] = substr($data[0], 1, $data_lon);
}
// Violet index
$beg = $end + 1;
$end = $beg + 2;
for ($i = $beg; $i <= $end; $i++) {
preg_match('/[0-9]{1,2}</', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$vi[] = substr($data[0], 0, $data_lon - 1);
}
// Risk level
$beg = $beg + 7;
$end = $beg + 2;
for ($i = $beg; $i <= $end; $i++) {
preg_match('/alt=".+?"/', $captured_td[$i], $data);
$data_lon = strlen($data[0]);
$rsk[] = substr($data[0], 5, $data_lon - 6);
}
return array(
$sky_img,
$sky_txt,
$rain_tmin,
$win_dir,
$win_spd,
$vi,
$rsk,
);
}
/**
* Clean the data and save it
*/
function _weather_es_aemet($wuid, $city_cod, $lan, $city_nam) {
// Raw data of AEMET
$array_text = _weather_es_retrieve_data($wuid, $city_cod, $lan, $city_nam);
if ($array_text != -1) {
// Get the days
preg_match_all('/<th.+th>/', $array_text[0][0][0], $captured_th);
for ($i = 1; $i < 8; $i++) {
preg_match('/>.+</', $captured_th[0][$i], $data);
$data_lon = strlen($data[0]);
$ori_str = substr($data[0], 1, $data_lon - 2);
$htm_str = htmlentities($ori_str);
$days[] = $htm_str;
}
// Get ampm (we don't really need that...)
preg_match_all('/<th.+th>/', $array_text[0][0][1], $captured_th);
for ($i = 0; $i < sizeof($captured_th[0]); $i++) {
preg_match('/>.+</', $captured_th[0][$i], $data);
$data_lon = strlen($data[0]);
$ampm[] = substr($data[0], 1, $data_lon - 2);
}
// Get the data types and the data
for ($i = 2; $i < sizeof($array_text[0][0]); $i++) {
// Data type
preg_match_all('/<th.+th>/', $array_text[0][0][$i], $captured_th);
preg_match('/>.+</', $captured_th[0][0], $data);
$data_lon = strlen($data[0]);
$ori_data_type[] = substr($data[0], 1, $data_lon - 2);
if (preg_match('/cielo|cel|ceo|egoera|Sky|ciel/', $array_text[0][0][$i])) {
$ii = 0;
}
elseif (preg_match('#\\(%\\)#', $array_text[0][0][$i])) {
$ii = 1;
}
elseif (preg_match('#\\(m\\)#', $array_text[0][0][$i])) {
$ii = 2;
}
elseif (preg_match('#\\(.C\\)#', $array_text[0][0][$i])) {
if (!isset($jj)) {
$ii = 3;
$jj = 0;
}
else {
$ii = 4;
}
}
elseif (preg_match('/Viento|Vent|Vento|Haizeak|Wind/', $array_text[0][0][$i])) {
$ii = 5;
}
elseif (preg_match('#\\(km/h\\)#', $array_text[0][0][$i])) {
$ii = 6;
}
elseif (preg_match('/UV/', $array_text[0][0][$i])) {
$ii = 7;
}
elseif (preg_match('/Nivel|Nivell|Gehinezko|Level|Niveau/', $array_text[0][0][$i])) {
$ii = 8;
}
else {
$ii = 99;
}
switch ($ii) {
// Sky
case 0:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
// Images
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/[0-9]{2}.gif/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$sky_img[] = substr($data[0], 0, $data_lon - 4);
}
// Text
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/alt=".+"/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$sky_txt[] = substr($data[0], 5, $data_lon - 6);
}
break;
// Rain
case 1:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/>[0-9]{1,3}/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$rain[] = substr($data[0], 1, $data_lon);
}
break;
// Snow
case 2:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/>[0-9]{1,4}/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
if (sizeof($data[0]) != 0) {
$snow[] = substr($data[0], 1, $data_lon);
}
else {
$snow[] = 9999;
}
}
break;
// Tmax
case 3:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/>[0-9]{1,4}/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$tmax[] = substr($data[0], 1, $data_lon);
}
break;
// Tmin
case 4:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/>[0-9]{1,4}/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$tmin[] = substr($data[0], 1, $data_lon);
}
break;
// Wind direction
case 5:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/alt=".+"/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$win_dir[] = substr($data[0], 5, $data_lon - 6);
}
break;
// Wind speed
case 6:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/>[0-9]{1,4}/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$win_spd[] = substr($data[0], 1, $data_lon);
}
break;
// UI
case 7:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/[0-9]{1,2}</', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$ui[] = substr($data[0], 0, $data_lon - 1);
}
break;
// Risk level
case 8:
preg_match_all('/<td.+td>/', $array_text[0][0][$i], $captured_th);
for ($j = 0; $j < sizeof($captured_th[0]); $j++) {
preg_match('/alt=".+?"/', $captured_th[0][$j], $data);
$data_lon = strlen($data[0]);
$rsk[] = substr($data[0], 5, $data_lon - 6);
}
break;
}
}
if (!isset($snow)) {
for ($i = 0; $i < 7; $i++) {
$snow[$i] = 9999;
}
}
for ($i = 0; $i < sizeof($ori_data_type); $i++) {
$htm_str = htmlentities($ori_data_type[$i]);
$data_type[] = $htm_str;
}
$aemet = array(
$days,
$ampm,
$data_type,
$sky_img,
$sky_txt,
$rain,
$snow,
$tmax,
$tmin,
$win_dir,
$win_spd,
$ui,
$rsk,
);
}
else {
$aemet = -1;
}
return $aemet;
}
/**
* Get the data from AEMET
*/
function _weather_es_retrieve_data($wuid, $city_cod, $lan, $city_nam) {
global $user;
$response = -1;
// Web direction example (until 2009/12/10): http://www.aemet.es/es/eltiempo/prediccion/localidades?l=03410&p=03
// New web direction example: http://www.aemet.es/es/eltiempo/prediccion/localidades/jijona-xixona-03410
// www.aemet.es: 193.144.152.138
// Languages are: es, ca/va, gl, eu, en and fr.
// This is what we get from the bad boys of aemet (30-01-2010)
/*
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.aemet.es/es/eltiempo/prediccion/localidades/Aramaio-01030">here</a>.</p>
</body></html>
*/
//$city_nam = "jijona-xixona";
$page = '/' . $lan . '/eltiempo/prediccion/localidades/' . $city_nam . '-' . $city_cod;
$url = 'http://www.aemet.es' . $page;
if (function_exists('fsockopen')) {
$result = drupal_http_request($url);
switch ($result->code) {
case '200':
case '304':
// Get the table
preg_match('/<table.+table>/s', $result->data, $captured);
// Pass it to a string
$data_string = implode(" ", $captured);
$length = strlen($data_string);
$position = strpos($data_string, "table>");
$data_string = substr($data_string, 0, $position - $length);
preg_match_all('/<tr.+tr>/sU', $data_string, $captured_tr);
$response = array(
$captured_tr,
);
break;
case '301':
case '302':
case '307':
$result = drupal_http_request('http://www.aemet.es' . $result->redirect_url);
// Get the table
preg_match('/<table.+table>/s', $result->data, $captured);
// Pass it to a string
$data_string = implode(" ", $captured);
$length = strlen($data_string);
$position = strpos($data_string, "table>");
$data_string = substr($data_string, 0, $position - $length);
preg_match_all('/<tr.+tr>/sU', $data_string, $captured_tr);
$response = array(
$captured_tr,
);
break;
default:
if ($user->uid) {
drupal_set_message(t('fsockopen fail to open AEMET.'), 'error');
}
}
}
else {
if ($user->uid) {
drupal_set_message(t('Function fsockopen does not exist, you can\'t use this module...'), 'error');
}
}
return $response;
}
/**
* Get the user configuration
*/
function _weather_es_get_config($uid) {
$sql = "SELECT cod_pro, cod_loc FROM {weather_es_config} WHERE uid = %d";
$result = db_query($sql, $uid);
while ($data = db_fetch_object($result)) {
(string) ($cities[] = $data->cod_pro . $data->cod_loc);
}
return $cities;
}
/**
* Get the diferent cities of the user
*/
function _weather_es_filter_cities($loc, $cit) {
$user_cities = array();
for ($i = 0; $i < sizeof($cit); $i++) {
// Upper PHP 4.0.6
//if (array_key_exist($cit[$i], $arrayOfKeys))
if (key_exists($cit[$i], $loc)) {
$user_cities[] = $loc[$cit[$i]];
}
}
return $user_cities;
}
/**
* Next data update. AEMET refresh the data at Spanish local time, about 07:00am
*
* Using this code your server will look for the AEMET data once a day but I think its too much
* overhead to avoid getting the data from AEMET Web 6 times a day...
*/
function _weather_es_next_act() {
$now = spanish_time();
$hour = strftime('%H', $now);
$dif = 7 - $hour;
if ($dif >= 0) {
$next_act_in = $dif;
}
else {
$next_act_in = 24 - $hour + 7;
}
$ran = rand(0, 60) * 60;
$next_act_in *= 3600;
$next_act = $now + $next_act_in + $ran;
return $next_act;
}
/**
* Return the Spanish (peninsula) time
*/
function spanish_time() {
// get the server time and change it to Spanish time
if (function_exists('date_default_timezone_get')) {
$server_time = date_default_timezone_get();
date_default_timezone_set('Europe/Madrid');
}
else {
$server_time = ini_get('date.timezone');
ini_set('date.timezone', 'Europe/Madrid');
}
$now = time();
// save the original server timezone
if (function_exists('date_default_timezone_set')) {
date_default_timezone_set('$server_time');
}
else {
ini_set('date.timezone', '$server_time');
}
return $now;
}
/**
* Redirect the user to his correct path
*/
function _weather_es_redirect($wuid) {
// User cities list
if ($wuid == 0) {
$path = 'admin/settings/weather_es';
}
else {
$path = 'user/' . $wuid . '/weather_es';
}
return $path;
}
/**
* Available provinces
*/
function _weather_es_provincies() {
$provincies = array(
'00' => "---",
'15' => "A Coruña",
'01' => "Álava",
'02' => "Albacete",
'03' => "Alicante",
'04' => "Almería",
'33' => "Asturias",
'05' => "Ávila",
'06' => "Badajoz",
'08' => "Barcelona",
'09' => "Burgos",
'10' => "Cáceres",
'11' => "Cádiz",
'39' => "Cantabria",
'12' => "Castellón",
'51' => "Ceuta",
'13' => "Ciudad Real",
'14' => "Córdoba",
'16' => "Cuenca",
'17' => "Girona",
'18' => "Granada",
'19' => "Guadalajara",
'20' => "Guipúzcoa",
'21' => "Huelva",
'22' => "Huesca",
'07' => "Illes Balears",
'23' => "Jaén",
'26' => "La Rioja",
'35' => "Las Palmas",
'24' => "León",
'25' => "Lleida",
'27' => "Lugo",
'28' => "Madrid",
'29' => "Málaga",
'52' => "Melilla",
'30' => "Murcia",
'31' => "Navarra",
'32' => "Ourense",
'34' => "Palencia",
'36' => "Pontevedra",
'37' => "Salamanca",
'38' => "Santa Cruz de Tenerife",
'40' => "Segovia",
'41' => "Sevilla",
'42' => "Soria",
'43' => "Tarragona",
'44' => "Teruel",
'45' => "Toledo",
'46' => "Valencia",
'47' => "Valladolid",
'48' => "Vizcaya",
'49' => "Zamora",
'50' => "Zaragoza",
);
return $provincies;
}
/**
* Available cities.
*/
function _weather_es_cities($pro) {
$sql = "SELECT * FROM {weather_es_aemet} wea WHERE wea.cod_pro = %d";
$result = db_query($sql, $pro);
while ($row = db_fetch_array($result)) {
$aemet_cod = $row['cod_pro'] . $row['cod_loc'];
$cities[$aemet_cod] = $row['cit_nam'];
}
return $cities;
}
/**
* Adopt the city-name to AEMET...
*/
function _weather_es_city_name($city) {
$convert_to = array(
'a',
'e',
'i',
'o',
'u',
'n',
'-',
);
$convert_from = array(
'á',
'é',
'í',
'ó',
'ú',
'ñ',
'/',
);
return str_replace($convert_from, $convert_to, $city);
}
Functions
Name | Description |
---|---|
spanish_time | Return the Spanish (peninsula) time |
_weather_es_aemet | Clean the data and save it |
_weather_es_cities | Available cities. |
_weather_es_city_name | Adopt the city-name to AEMET... |
_weather_es_filter_cities | Get the diferent cities of the user |
_weather_es_get_config | Get the user configuration |
_weather_es_get_td_info | Get the td info: rain probability, tmax, tmin... |
_weather_es_next_act | Next data update. AEMET refresh the data at Spanish local time, about 07:00am |
_weather_es_provincies | Available provinces |
_weather_es_redirect | Redirect the user to his correct path |
_weather_es_retrieve_data | Get the data from AEMET |