From 2fb07e33bc07ad435731e43cf59a961627570fcd Mon Sep 17 00:00:00 2001
From: Jacek Kowalski <Jacek@jacekk.info>
Date: Wed, 29 Aug 2012 12:12:08 +0000
Subject: [PATCH] 1. Usunięcie modułu pogoda opartego o Google Weather API, 2. Stworzenie nowego modułu wykorzystującego API GeoNames oraz yr.no, 3. Dodanie nowych ikon pogodowych, 4. Uwzględnienie licencji ikon w pliku LICENCE, 5. Aktualizacja pliku UPGRADE w związku z powyższymi zmianami.

---
 data/pogoda/3.png                         |    0 
 data/pogoda/8.png                         |    0 
 data/pogoda/12.png                        |    0 
 LICENCE                                   |   27 +
 data/pogoda/7.png                         |    0 
 data/pogoda/21.png                        |    0 
 modules/30_pogoda/init.php                |   57 ++++
 data/pogoda/9.png                         |    0 
 data/pogoda/13.png                        |    0 
 data/pogoda/4.png                         |    0 
 data/pogoda/22.png                        |    0 
 data/pogoda/14.png                        |    0 
 modules/30_pogoda/api_yrno.php            |  221 +++++++++++++++
 modules/30_pogoda/handler.php             |  171 ++++++++++++
 data/pogoda/1.png                         |    0 
 data/pogoda/10.png                        |    0 
 data/pogoda/23.png                        |    0 
 data/pogoda/5.png                         |    0 
 modules/30_pogoda/api_geonames.php        |   54 +++
 /dev/null                                 |  233 ----------------
 modules/30_pogoda/api_geonames_config.php |    6 
 data/pogoda/15.png                        |    0 
 UPGRADE                                   |   22 
 data/pogoda/6.png                         |    0 
 data/pogoda/11.png                        |    0 
 data/pogoda/2.png                         |    0 
 data/pogoda/20.png                        |    0 
 27 files changed, 537 insertions(+), 254 deletions(-)

diff --git a/LICENCE b/LICENCE
index 5411fef..671e9b6 100644
--- a/LICENCE
+++ b/LICENCE
@@ -5,9 +5,9 @@
 |  |____ |  ||  \____ |  |____ |  |\   ||  \____ |  \__/  ||   ____   |
 |_______||__| \______||_______||__| \__| \______| \______/ |__|    |__|
 
-======================
-Creative Commons by-nc
-======================
+========================
+ Creative Commons by-nc
+========================
 
 Niniejszy program, za wyjątkiem wymienionych poniżej zbiorów, jest rozpowszechniany na licencji:
 
@@ -17,9 +17,9 @@
 http://creativecommons.org/licenses/by-nc/2.5/legalcode.pl
 
 
-=======
-GNU GPL
-=======
+=========
+ GNU GPL
+=========
 
 Niektóre zbiory danych wykorzystywane w programie są udostępniane na licencji GNU GPL, której treść znajduje się w pliku GNU-GPL. Bot może działać bez tych plików po usunięciu odpowiedniego modułu z katalogu /modules/
 
@@ -40,10 +40,19 @@
    praca pochodna od w/w na potrzeby bota, wygenerowana za pomoca: /data/synonimy/parse.php
 
 
+===========================
+ CC BY (uznanie autorstwa)
+===========================
 
-=============
-Inna/nieznana
-=============
+Niektóre zbiory danych wykorzystywane w programie są udostępniane na licencji CC BY 3.0, której treść znajduje się pod adresem http://creativecommons.org/licenses/by/3.0/
+
+/data/pogoda/*.png
+   http://api.yr.no/license_data.html
+
+
+===============
+ Inna/nieznana
+===============
 
 Poniższe zbiory zostały znalezione w Internecie, a autor nie zaznaczył licencji:
 
diff --git a/UPGRADE b/UPGRADE
index 7dabaeb..6267d4c 100644
--- a/UPGRADE
+++ b/UPGRADE
@@ -6,10 +6,13 @@
   z katalogu ./modules
 * nadpisz wszystkie pliki w katalogach ./class i ./modules,
   za wyjątkiem ./class/config.php
+* usuń wszystkie pliki z katalogu ./data/pogoda
+* wgraj nowe pliki do folderu ./data/pogoda
+* usuń wszystkie pliki z katalogu ./cache
 
-===========================
- AKTUALIZACJA Z WERSJI 2.2
-===========================
+======================================
+ AKTUALIZACJA Z WERSJI 2.2/2.1/2.0 RC
+======================================
 
 * usuń wszystkie pliki i katalogi (za wyjątkiem własnych modułów)
   z katalogu ./modules
@@ -17,7 +20,10 @@
   za wyjątkiem ./class/config.php
 * zastąp plik ./data/lotto/pobierz.php
 * zastąp plik ./data/tv/pobierz.php
+* usuń wszystkie pliki z katalogu ./data/pogoda
+* wgraj nowe pliki do folderu ./data/pogoda
 * usuń wszystkie pliki z katalogów ./cache oraz ./data/tv/cache
+* dokonaj aktualizacji danych (cd ./data ; ./update_all.sh)
 * pobierz Account Key ze strony https://datamarket.azure.com/
   (wymaga identyfikatora Windows Live ID) i uzyskaj subskrybcję Microsoft Translator:
   https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb
@@ -31,13 +37,6 @@
 class msapi_config {
         protected $accountKey = 'A123BC9238...ADD';
 
-==================================
- AKTUALIZACJA Z WERSJI 2.0 RC/2.1
-==================================
-
-* wykonaj kroki opisane w sekcji "AKTUALIZACJA Z WERSJI 2.2"
-* dokonaj aktualizacji danych (cd ./data ; ./update_all.sh)
-
 ================================
  AKTUALIZACJA Z WERSJI 2.0 Beta
 ================================
@@ -45,8 +44,7 @@
 * zastąp wszystkie pliki (bez podfolderów!) w ./data,
   a następnie popraw ścieżkę do bota w ./data/update.sh
 * zastąp plik aliases w ./data/tv
-* wykonaj polecenia z działu "AKTUALIZACJA Z WERSJI 2.2"
-* dokonaj aktualizacji danych (cd ./data ; ./update_all.sh)
+* wykonaj polecenia z działu "AKTUALIZACJA Z WERSJI 2.2/2.1/2.0 RC"
 
 -------
  UWAGA
diff --git a/data/pogoda/.emptydir b/data/pogoda/.emptydir
deleted file mode 100644
index e69de29..0000000
--- a/data/pogoda/.emptydir
+++ /dev/null
diff --git a/data/pogoda/1.png b/data/pogoda/1.png
new file mode 100644
index 0000000..5b94c2d
--- /dev/null
+++ b/data/pogoda/1.png
Binary files differ
diff --git a/data/pogoda/10.png b/data/pogoda/10.png
new file mode 100644
index 0000000..bb74e13
--- /dev/null
+++ b/data/pogoda/10.png
Binary files differ
diff --git a/data/pogoda/11.png b/data/pogoda/11.png
new file mode 100644
index 0000000..1ddb1a8
--- /dev/null
+++ b/data/pogoda/11.png
Binary files differ
diff --git a/data/pogoda/12.png b/data/pogoda/12.png
new file mode 100644
index 0000000..851428b
--- /dev/null
+++ b/data/pogoda/12.png
Binary files differ
diff --git a/data/pogoda/13.png b/data/pogoda/13.png
new file mode 100644
index 0000000..709fc80
--- /dev/null
+++ b/data/pogoda/13.png
Binary files differ
diff --git a/data/pogoda/14.png b/data/pogoda/14.png
new file mode 100644
index 0000000..6ed333e
--- /dev/null
+++ b/data/pogoda/14.png
Binary files differ
diff --git a/data/pogoda/15.png b/data/pogoda/15.png
new file mode 100644
index 0000000..9c3ffc6
--- /dev/null
+++ b/data/pogoda/15.png
Binary files differ
diff --git a/data/pogoda/2.png b/data/pogoda/2.png
new file mode 100644
index 0000000..f988256
--- /dev/null
+++ b/data/pogoda/2.png
Binary files differ
diff --git a/data/pogoda/20.png b/data/pogoda/20.png
new file mode 100644
index 0000000..a32e304
--- /dev/null
+++ b/data/pogoda/20.png
Binary files differ
diff --git a/data/pogoda/21.png b/data/pogoda/21.png
new file mode 100644
index 0000000..17ea0db
--- /dev/null
+++ b/data/pogoda/21.png
Binary files differ
diff --git a/data/pogoda/22.png b/data/pogoda/22.png
new file mode 100644
index 0000000..77a8090
--- /dev/null
+++ b/data/pogoda/22.png
Binary files differ
diff --git a/data/pogoda/23.png b/data/pogoda/23.png
new file mode 100644
index 0000000..4286ef7
--- /dev/null
+++ b/data/pogoda/23.png
Binary files differ
diff --git a/data/pogoda/3.png b/data/pogoda/3.png
new file mode 100644
index 0000000..77f4f1e
--- /dev/null
+++ b/data/pogoda/3.png
Binary files differ
diff --git a/data/pogoda/4.png b/data/pogoda/4.png
new file mode 100644
index 0000000..48e3e09
--- /dev/null
+++ b/data/pogoda/4.png
Binary files differ
diff --git a/data/pogoda/5.png b/data/pogoda/5.png
new file mode 100644
index 0000000..e34b05f
--- /dev/null
+++ b/data/pogoda/5.png
Binary files differ
diff --git a/data/pogoda/6.png b/data/pogoda/6.png
new file mode 100644
index 0000000..4c38dc7
--- /dev/null
+++ b/data/pogoda/6.png
Binary files differ
diff --git a/data/pogoda/7.png b/data/pogoda/7.png
new file mode 100644
index 0000000..b2c9746
--- /dev/null
+++ b/data/pogoda/7.png
Binary files differ
diff --git a/data/pogoda/8.png b/data/pogoda/8.png
new file mode 100644
index 0000000..8287f45
--- /dev/null
+++ b/data/pogoda/8.png
Binary files differ
diff --git a/data/pogoda/9.png b/data/pogoda/9.png
new file mode 100644
index 0000000..c78a491
--- /dev/null
+++ b/data/pogoda/9.png
Binary files differ
diff --git a/modules/30_pogoda.php b/modules/30_pogoda.php
deleted file mode 100644
index 60cb39e..0000000
--- a/modules/30_pogoda.php
+++ /dev/null
@@ -1,233 +0,0 @@
-<?php
-class pogoda implements module {
-	static $wojewodztwa = array(
-		'Kuiavia-Pomerania' => 'kujawsko-pomorskie',
-		'Kuyavian-Pomeranian' => 'kujawsko-pomorskie',
-		'Kujawsko-Pomorskie' => 'kujawsko-pomorskie',
-		
-		'Lesser Poland' => 'małopolskie',
-		
-		'Lodz' => 'łódzkie',
-		'Łódź' => 'łódzkie',
-		
-		'Lower Silesia' => 'dolnośląskie',
-		'Lower Silesian' => 'dolnośląskie',
-		
-		'Lublin' => 'lubelskie',
-		'Lubelskie' => 'lubelskie',
-		
-		'Lubuskie' => 'lubuskie',
-		
-		'Mazovia' => 'mazowieckie',
-		'Masovian' => 'mazowieckie',
-		'Mazowieckie' => 'mazowieckie',
-		
-		'Opole' => 'opolskie',
-		
-		'Subcarpathia' => 'podkarpackie',
-		'Podkarpackie' => 'podkarpackie',
-		
-		'Podlachia' => 'podlaskie',
-		
-		'Pomerania' => 'pomorskie',
-		'Pomorskie' => 'pomorskie',
-		
-		'Silesia' => 'śląskie',
-		
-		'Swietokrzyskie' => 'świętokrzyskie',
-		
-		'Warmia and Masuria' => 'warmińsko-mazurskie',
-		
-		'Western Pomerania' => 'zachodniopomorskie',
-		
-		'Greater Poland' => 'wielkopolskie',
-		'Wielkopolskie' => 'wielkopolskie',
-	);
-	
-	static function register_cmd() {
-		return array(
-			'pogoda' => 'cmd_pogoda',
-			'p' => 'cmd_pogoda',
-			'weather' => 'cmd_pogoda',
-			'miasto' => 'cmd_miasto',
-			'm' => 'cmd_miasto',
-			'temp' => 'cmd_pogoda',
-			'temperatura' => 'cmd_pogoda',
-		);
-	}
-	
-	static function help($cmd=NULL) {
-		if($cmd === NULL) {
-			GGapi::putRichText('pogoda ', TRUE);
-			GGapi::putRichText('[miasto]', FALSE, TRUE);
-			GGapi::putRichText("\n".'   Podaje pogodę dla miasta'."\n");
-			
-			GGapi::putRichText('miasto ', TRUE);
-			GGapi::putRichText('miasto', FALSE, TRUE);
-			GGapi::putRichText("\n".'   Ustala domyślne miasto dla funkcji pogoda'."\n\n");
-		}
-		elseif(substr($cmd, 0, 1)=='m')
-		{
-			GGapi::putRichText('miasto ', TRUE);
-			GGapi::putRichText('miasto', FALSE, TRUE);
-			GGapi::putRichText(' (alias: ');
-			GGapi::putRichText('m', TRUE);
-			GGapi::putRichText(')'."\n".'   Ustawia domyślne ');
-			GGapi::putRichText('miasto', FALSE, TRUE);
-			GGapi::putRichText(' dla funkcji pogoda dla danego numeru Gadu-Gadu.');
-		}
-		else
-		{
-			GGapi::putRichText('pogoda ', TRUE);
-			GGapi::putRichText('miasto', FALSE, TRUE);
-			GGapi::putRichText(' (alias: ');
-			GGapi::putRichText('p', TRUE);
-			GGapi::putRichText(')'."\n".'   Podaje pogodę dla danego miasta na najbliższe dni. Domyślne miasto można ustawić komendą ');
-			GGapi::putRichText('miasto', TRUE);
-		}
-	}
-	
-	static function putIcon($icon) {
-		if(!empty($icon)) {
-			if(!file_exists('./data/pogoda/'.basename($icon))) {
-				if(substr($icon, 0, 1) == '/') {
-					$icon = 'http://www.google.com'.$icon;
-				}
-				$img = @file_get_contents($icon);
-				if($img) {
-					file_put_contents('./data/pogoda/'.basename($icon), $img);
-				}
-			}
-			
-			GGapi::putImage('./data/pogoda/'.basename($icon));
-			GGapi::putText("\n");
-		}
-
-	}
-	
-	static function cmd_pogoda($name, $arg) {
-		$forced = FALSE;
-		
-		if(empty($arg)) {
-			$arg = database::get($_GET['from'], 'pogoda', 'miasto');
-			if(empty($arg)) {
-				$arg = GGapi::getPublicData();
-				$arg = trim($arg['city']);
-				if(empty($arg)) {
-					$arg = 'Warszawa';
-					$forced = TRUE;
-				}
-				GGapi::putText('Nie ustawiono miasta (pomoc - wpisz: help miasto) - '.(!$forced ? 'na podstawie danych z katalogu publicznego ' : '').'wybieram miasto '.$arg."\n\n");
-			}
-		}
-		
-		$dane = @file_get_contents('http://www.google.pl/ig/api?weather='.urlencode(ucwords(funcs::utfToAscii($arg))));
-		if(!$dane) {
-			GGapi::putText('Przepraszamy, nie udało się połączyć z serwisem');
-			return;
-		}
-		
-		$dane = iconv('iso-8859-2', 'utf-8', $dane);
-		
-		$dane = @simplexml_load_string($dane);
-		if(!$dane) {
-			GGapi::putText('Przepraszamy, błąd przy pobieraniu danych');
-			return;
-		}
-		
-		if($dane->weather->problem_cause) {
-			GGapi::putText('Problem w serwisie bądź danego miasta nie ma w bazie'."\n\n".'Przykład:'."\n".'pogoda Warszawa'."\n".'pogoda Kraków');
-			return;
-		}
-		
-		$short2day = array(
-			'pon.' => 'Poniedziałek',
-			'wt.' => 'Wtorek',
-			'śr.' => 'Środa',
-			'czw.' => 'Czwartek',
-			'pt.' => 'Piątek',
-			'sob.' => 'Sobota',
-			'niedz.' => 'Niedziela',
-		);
-		
-		$region = substr(strstr($dane->weather->forecast_information->city['data'], ', '), 2);
-		$region = trim(str_replace('Voivodeship', '', $region));
-		if(isset(self::$wojewodztwa[$region])) {
-			$region = 'województwo '.self::$wojewodztwa[$region];
-		}
-		
-		$miasto = trim((string)$dane->weather->forecast_information->postal_code['data']);
-		if(($a=strpos($miasto, '-'))!==FALSE) {
-			$miasto = substr($miasto, 0, $a).'-'.ucfirst(substr($miasto, $a+1));
-		}
-		
-		GGapi::putRichText('Pogoda dla miasta '.$miasto.', '.$region."\n\n", TRUE);
-		
-		GGapi::putRichText('Teraz'."\n", TRUE);
-		self::putIcon((string)$dane->weather->current_conditions->icon['data']);
-		
-		$condition = (string)$dane->weather->current_conditions->condition['data'];
-		GGapi::putRichText(($condition ? $condition."\n" : '').'Temp.: '.($dane->weather->current_conditions->temp_c['data']).'°C'."\n".($dane->weather->current_conditions->humidity['data'])."\n".($dane->weather->current_conditions->wind_condition['data']));
-		
-		$num = TRUE;
-		foreach($dane->weather->forecast_conditions as $day) {
-			GGapi::putRichText("\n\n".($num ? 'Później' : $short2day[(string)$day->day_of_week['data']])."\n", TRUE);
-			self::putIcon((string)$day->icon['data']);
-			GGapi::putRichText(($day->condition['data'])."\n".'Temp. od '.($day->low['data']).'°C do '.($day->high['data']).'°C');
-			$num = FALSE;
-		}
-		
-	}
-	
-	static function cmd_miasto($name, $arg) {
-		$arg = trim(funcs::utfToAscii($arg));
-		if(empty($arg)) {
-			$arg = database::get($_GET['from'], 'pogoda', 'miasto');
-			if(!empty($arg)) {
-				GGapi::putText('Aktualnie ustawione miasto to: '.$arg);
-				return;
-			}
-			
-			$arg = GGapi::getPublicData();
-			$arg = funcs::utfToAscii($arg['city']);
-			
-			if(empty($arg)) {
-				GGapi::putText('Nie podano wymaganego argumentu ');
-				GGapi::putRichText('miasto', FALSE, TRUE);
-				return;
-			}
-			
-			
-			GGapi::putText('Z katalogu publicznego pobrano miasto '.$arg."\n\n");
-		}
-		
-		$data = @file_get_contents('http://ws.geonames.org/search?name='.urlencode($arg));
-		if($data) {
-			$data = simplexml_load_string($data);
-			if($data && $data->totalResultsCount > 0) {
-				$data = $data->geoname[0];
-			}
-			else
-			{
-				GGapi::putText('Podane miasto nie zostało odnalezione!');
-				return;
-			}
-		}
-		else
-		{
-			GGapi::putText('Wystąpił błąd przy wyszukiwaniu miasta. Spróbuj ponownie później.');
-			return;
-		}
-		
-		if(!$data->geonameId || $data->geonameId=='756135') {
-			$data = new SimpleXMLElement('<geoname><name>Warszawa</name><lat>52.25</lat><lng>21.0</lng><geonameId>756135</geonameId><countryCode>PL</countryCode><countryName>Poland</countryName></geoname>');
-		}
-		
-		GGapi::putText('Miasto zostało ustawione na '.(string)$data->name);
-		database::add($_GET['from'], 'pogoda', 'miasto', (string)$data->name);
-		database::add($_GET['from'], 'pogoda', 'kraj', (string)$data->countryName);
-		database::add($_GET['from'], 'pogoda', 'cc', (string)$data->countryCode);
-		database::add($_GET['from'], 'pogoda', 'geo', array('lat' => (string)$data->lat, 'lon' => (string)$data->lng));
-	}
-}
-?>
diff --git a/modules/30_pogoda/api_geonames.php b/modules/30_pogoda/api_geonames.php
new file mode 100644
index 0000000..5463ea8
--- /dev/null
+++ b/modules/30_pogoda/api_geonames.php
@@ -0,0 +1,54 @@
+<?php
+require_once(dirname(__FILE__).'/api_geonames_config.php');
+
+class api_geonames extends api_geonames_config {
+	function search($name) {
+		$url = 'http://'.$this->host.'/search?name='.urlencode($name).'&lang=pl&maxrows=3'.($this->username !== NULL ? '&username='.urlencode($this->username) : '');
+		
+		try {
+			$download = new DownloadHelper($url);
+			$data = $download->exec();
+			
+			if(!$data) {
+				$download->cacheFor(600);
+				return FALSE;
+			}
+			
+			libxml_use_internal_errors();
+			$data = simplexml_load_string();
+			libxml_clear_errors();
+			
+			if(!$data) {
+				$download->cacheFor(600);
+				return FALSE;
+			}
+			
+			// Trzymaj w cache przez około 278 dni
+			$download->cacheFor(1000000);
+			
+			if($data->geoname[0]->getName() != 'geoname'
+				|| $data->geoname[0]->name->getName() != 'name'
+				|| $data->geoname[0]->countryName->getName() != 'countryName'
+				|| $data->geoname[0]->lat->getName() != 'lat'
+				|| $data->geoname[0]->lng->getName() != 'lng') {
+				return NULL;
+			}
+			
+			$data = (array)$this->geoname[0];
+			foreach($data as &$value) {
+				$value = trim($value);
+			}
+			unset($value);
+			
+			if(isset($data['countryName']) && $data['countryName'] == 'Rzeczpospolita Polska') {
+				$data['countryName'] = 'Polska';
+			}
+			
+			return $data;
+		}
+		catch(Exception $e) {
+			return FALSE;
+		}
+	}
+}
+?>
\ No newline at end of file
diff --git a/modules/30_pogoda/api_geonames_config.php b/modules/30_pogoda/api_geonames_config.php
new file mode 100644
index 0000000..babc968
--- /dev/null
+++ b/modules/30_pogoda/api_geonames_config.php
@@ -0,0 +1,6 @@
+<?php
+class api_geonames_config {
+	protected $host = 'ws.geonames.org';
+	protected $username = NULL;
+}
+?>
\ No newline at end of file
diff --git a/modules/30_pogoda/api_yrno.php b/modules/30_pogoda/api_yrno.php
new file mode 100644
index 0000000..56b95b2
--- /dev/null
+++ b/modules/30_pogoda/api_yrno.php
@@ -0,0 +1,221 @@
+<?php
+class api_yrno_parse {
+	protected $xml;
+	protected $dane;
+	
+	var $symbols = array(
+		1 => 'Słonecznie',
+		2 => 'Lekkie zachmurzenie',
+		3 => 'Częściowe zachmurzenie',
+		4 => 'Zachmurzenie',
+		5 => 'Lekki deszcz z przejaśnieniami',
+		6 => 'Lekki deszcz i burze',
+		7 => 'Lekki deszcz ze śniegiem',
+		8 => 'Śnieg',
+		9 => 'Lekki deszcz',
+		10 => 'Deszcz',
+		11 => 'Burze z deszczem',
+		12 => 'Deszcz ze śniegiem',
+		13 => 'Śnieg',
+		14 => 'Burze ze śniegiem',
+		15 => 'Mgły',
+		16 => 1,
+		17 => 2,
+		18 => 5,
+		19 => 8,
+		20 => 'Deszcz ze śniegiem, burze, możliwe przejaśnienia',
+		21 => 'Burze ze śniegiem, możliwe przejaśnienia',
+		22 => 'Lekki deszcz i burze',
+		23 => 'Deszcz ze śniegiem, burze'
+	);
+	
+	var $wind = array(
+		'N' => 'północny',
+		'NW' => 'północno-zachodni',
+		'W' => 'zachodni',
+		'SW' => 'południowo-zachodni',
+		'S' => 'południowy',
+		'SE' => 'południowo-wschodni',
+		'E' => 'wschodni',
+		'NE' => 'północno-wschodni',
+	);
+	
+	function __construct($xml) {
+		libxml_use_internal_errors();
+		$this->xml = simplexml_load_string($xml);
+		libxml_clear_errors();
+		
+		if(!$this->xml) {
+			throw new Exception('Niepoprawny format danych meteorologicznych!');
+		}
+	}
+	
+	function mktime($time) {
+		return strtotime(substr($time, 0, -1));
+	}
+	
+	function wind($dir) {
+		if(isset($this->wind[$dir])) {
+			return $this->wind[$dir];
+		}
+		else
+		{
+			return '';
+		}
+	}
+	
+	function parseForecast() {
+		$this->dane = array(
+			'0h' => array(),
+			'3h' => array(),
+			'6h' => array(),
+		);
+		
+		foreach($this->xml->product->time as $time) {
+			$to = $this->mktime((string)$time->attributes()->to);
+			$from = $this->mktime((string)$time->attributes()->from);
+			
+			$time = $time->location;
+			
+			if($to == $from) {
+				$this->dane['0h'][$to] = array(
+					'temp' => (string)$time->temperature->attributes()->value,
+					'wind_speed' => (string)$time->windSpeed->attributes()->mps,
+					'wind_dir' => (string)$time->windDirection->attributes()->name,
+					'humidity' => (string)$time->humidity->attributes()->value,
+					'pressure' => (string)$time->pressure->attributes()->value,
+				);
+			}
+			elseif($to-$from > 0) {
+				if($to-$from > 14400) {
+					$put = '6h';
+				}
+				else
+				{
+					$put = '3h';
+				}
+				
+				$icon = (int)$time->symbol->attributes()->number;
+				if(is_int($this->symbols[$icon])) {
+					$icon = $this->symbols[$icon];
+				}
+				
+				$this->dane[$put][$to] = array(
+					'from' => $from,
+					'to' => $to,
+					'icon' => $icon
+				);
+			}
+		}
+	}
+	
+	function getCurrentIcon() {
+		$now = time();
+		foreach($this->dane['3h'] as $value) {
+			if($value['from'] <= $now && $now < $value['to']) {
+				return $value['icon'];
+			}
+		}
+		
+		return NULL;
+	}
+	
+	function getCurrentWeather() {
+		$dist = PHP_INT_MAX;
+		$current = NULL;
+		foreach($this->dane['0h'] as $time => $value) {
+			if(abs($time - time()) < $dist) {
+				$dist = abs($time - time());
+				$current = $value;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		return $current;
+	}
+	
+	function getDaypartWeather($timestamp) {
+		$start = strtotime('6:00', $timestamp);
+		$dayend = strtotime('19:30', $timestamp);
+		$end = $start + 22*3600;
+		
+		$wind = $temp = array(
+			'day' => array(),
+			'night' => array(),
+		);
+		
+		foreach($this->dane['0h'] as $time => $value) {
+			$part = NULL;
+			if($start <= $time && $time < $dayend) {
+				$part = 'day';
+			}
+			elseif($dayend < $time && $time <= $end) {
+				$part = 'night';
+			}
+			elseif($end <= $time) {
+				break;
+			}
+			
+			if($part !== NULL) {
+				if(!isset($temp[$part]['from']) || $value['temp'] < $temp[$part]['from']) {
+					$temp[$part]['from'] = $value['temp'];
+				}
+				if(!isset($temp[$part]['to']) || $value['temp'] > $temp[$part]['to']) {
+					$temp[$part]['to'] = $value['temp'];
+				}
+				
+				if(!isset($wind[$part]['from']) || $value['wind_speed'] < $wind[$part]['from']) {
+					$wind[$part]['from'] = $value['wind_speed'];
+				}
+				if(!isset($wind[$part]['to']) || $value['wind_speed'] > $wind[$part]['to']) {
+					$wind[$part]['to'] = $value['wind_speed'];
+				}
+			}
+		}
+		
+		if($temp['day'] == array() || $wind['day'] == array()) {
+			unset($temp['day']);
+			unset($wind['day']);
+		}
+		
+		return array($temp, $wind);
+	}
+	
+	function getDaypartIcon($timestamp) {
+		$start = strtotime('6:00', $timestamp);
+		$end = strtotime('24:00', $timestamp);
+		
+		$return = array();
+		foreach($this->dane['3h'] as $time => $value) {
+			if($start <= $value['from'] && $value['to'] <= $end) {
+				$return[] = $value['icon'];
+			}
+			elseif($end <= $value['from']) {
+				break;
+			}
+		}
+		
+		return $return;
+	}
+}
+
+function yrno_weather($lat, $lon) {
+	$down = new DownloadHelper('http://api.yr.no/weatherapi/locationforecastlts/1.1/?lat='.urlencode($lat).';lon='.urlencode($lon));
+	$down->setopt(CURLOPT_USERAGENT, 'BotGG/'.main::VERSION_NUM.' WeatherModule/1.0 (http://bot.jacekk.net/weather.html)');
+	try {
+		$data = $down->exec();
+		$data = new api_yrno_parse($data);
+		$data->parseForecast();
+	}
+	catch(Exception $e) {
+		$down->cacheFor(600);
+		return FALSE;
+	}
+	
+	$down->cacheFor(7200);
+	return $data;
+}
+?>
\ No newline at end of file
diff --git a/modules/30_pogoda/handler.php b/modules/30_pogoda/handler.php
new file mode 100644
index 0000000..6394cd7
--- /dev/null
+++ b/modules/30_pogoda/handler.php
@@ -0,0 +1,171 @@
+<?php
+require_once(dirname(__FILE__).'/api_geonames.php');
+require_once(dirname(__FILE__).'/api_yrno.php');
+
+class bot_pogoda_module extends BotModule {
+	function pogoda($msg, $params) {
+		$arg = trim($msg->args);
+		
+		$out = new BotMsg();
+		
+		
+		if(empty($arg)) {
+			$msg->session->setClass('pogoda');
+			
+			if(isset($msg->session->miasto) && !isset($msg->session->geo)) {
+				if(strlen($msg->session->miasto) > 0) {
+					$out->a('<p>Wymagane przekonwertowanie danych... Wywoływanie komendy <i>miasto '.htmlspecialchars($msg->session->miasto).'</i>...</p>');
+					
+					$out->a($this->miasto($msg, $msg->session->miasto));
+					$out->a('<p></p>');
+				}
+				else
+				{
+					unset($msg->session->miasto);
+				}
+			}
+			
+			if(!isset($msg->session->miasto)) {
+				try {
+					$api = new BotAPIGG();
+					$data = $api->getPublicData($msg->user);
+					if(is_array($data) && isset($data['city'])) {
+						$arg = trim($data['city']);
+					}
+					unset($data, $api);
+				}
+				catch(Exception $e) {
+				}
+				
+				if(empty($arg)) {
+					$arg = 'Warszawa';
+					$forced = TRUE;
+				}
+				
+				$out->a('<p>Nie ustawiono miasta (pomoc - wpisz: help miasto) - '.(!$forced ? 'na podstawie danych z katalogu publicznego ' : '').'wybieram miasto '.$arg.'</p>'."\n\n");
+				
+				$loc = new api_geonames();
+				$loc = $loc->search($arg);
+				
+				if($loc === FALSE) {
+					return new BotMsg('Nie udało się pobrać danych o podanym miejscu - spróbuj ponownie za około 10 minut.');
+				}
+				elseif($loc === NULL) {
+					return new BotMsg('Dla podanego miejsca nie udało się uzyskać współrzędnych geograficznych - spróbuj wpisać inną nazwę.');
+				}
+			}
+			else
+			{
+				$loc = array(
+					'name' => $msg->session->miasto,
+					'countryName' => $msg->session->kraj,
+					'coutryCode' => $msg->session->cc,
+					'lat' => $msg->session->geo['lat'],
+					'lng' => $msg->session->geo['lon']
+				);
+			}
+		}
+		
+		$api = yrno_weather($loc['lat'], $loc['lng']);
+		if($api == FALSE) {
+			return new BotMsg('Nie udało się pobrać danych o pogodzie - spróbuj ponownie za około 10 minut.');
+		}
+		
+		$out->a('<p>Pogoda dla '.htmlspecialchars($loc->name).', '.htmlspecialchars($loc->countryName).'.</p>'."\n\n");
+		
+		$icon = $api->symbols[$api->getCurrentIcon()];
+		$weather = $api->getCurrentWeather();
+		
+		$out->a('<p><b>Teraz</b><br />'."\n"
+			. $icon.'<br />'."\n"
+			. 'Temp.: '.htmlspecialchars($weather['temp']).'°C<br />'."\n"
+			. 'Wiatr: '.htmlspecialchars($weather['wind']).' km/h, '.$api->wind($weather['wind']).'<br />'."\n"
+			. 'Ciśnienie: '.htmlspecialchars($weather['pressure']).' hPa</p>'."\n\n");
+		
+		$when = time();
+		if($when < strtotime('19:00')) {
+			$out->a($this->getHTMLforWeather('Dziś', $api->getDaypartIcon($when), $api->getDaypartWeather($when)));
+		}
+		
+		$when = strtotime('+1 day', $when);
+		$out->a($this->getHTMLforWeather('Jutro', $api->getDaypartIcon($when), $api->getDaypartWeather($when)));
+		$when = strtotime('+1 day', $when);
+		$out->a($this->getHTMLforWeather('Pojutrze', $api->getDaypartIcon($when), $api->getDaypartWeather($when)));
+		
+		$out->a('<p>Dane lokalizacyjne pochodzą z serwisu GeoNames.<br />'."\n"
+			. 'Dane pogodowe pochodzą z Norweskiego Instytutu Meteorologicznego.</p>');
+		
+		return $out;
+	}
+	
+	function getHTMLforWeather($name, $icons, $weather) {
+		$html = '<p><b>'.$name.'</b><br />'."\n";
+		foreach($icons as $icon) {
+			if(is_file('./data/pogoda/'.htmlspecialchars($icon).'.png')) {
+				$html .= '<img src="./data/pogoda/'.htmlspecialchars($icon).'.png" alt="" /> ';
+			}
+		}
+		$html .= '<br />'."\n"
+			. 'Temp.: '.$weather['temp']['from'].($weather['temp']['from'] != $weather['temp']['to'] ? '-'.$weather['temp']['to'] : '').'°C<br />'."\n"
+			. 'Wiatr: '.$weather['wind']['from'].($weather['wind']['from'] != $weather['wind']['to'] ? '-'.$weather['wind']['to'] : '').' km/h</p>'."\n\n";
+		
+		return $html;
+	}
+	
+	function miasto($msg, $params) {
+		$msg->session->setClass('pogoda');
+		
+		if(strlen($params) > 0) {
+			$arg = trim($params);
+		}
+		else
+		{
+			$arg = trim($msg->args);
+		}
+		
+		if(empty($arg)) {
+			if(isset($this->session->miasto)) {
+				return new BotMsg('Aktualnie ustawione miejsce to: '.htmlspecialchars($this->session->miasto).', '.htmlspecialchars($this->session->countryName));
+			}
+			
+			try {
+				$api = new BotAPIGG();
+				$dane = $api->getPublicData($msg->user);
+				if(!isset($arg['city']) || empty($arg['city'])) {
+					throw new Exception('Brak miasta w danych w katalogu publicznym.');
+				}
+				
+				$arg = trim($arg['city']);
+			}
+			catch(Exception $e) {
+				return new BotMsg('Nie podano wymaganego argumentu <i>miasto</i>.');
+			}
+			
+			$out->a('<p>Na podstawie danych z katalogu publicznego wybieram miasto: '.htmlspecialchars($arg).'</p>'."\n\n");
+		}
+		else
+		{
+			$out = new BotMsg();
+		}
+		
+		$api = new api_geonames();
+		$dane = $api->search($arg);
+		
+		if($dane === FALSE) {
+			return new BotMsg('Wystąpił błąd przy wyszukiwaniu miasta. Spróbuj ponownie później.');
+		}
+		elseif($dane === NULL) {
+			return new BotMsg('Nie udało się zlokalizować podanego miejsca. Spróbuj wpisać inną nazwę.');
+		}
+		
+		$msg->session->miasto = $dane['name'];
+		$msg->session->kraj = $dane['countryName'];
+		$msg->session->cc = $dane['countryCode'];
+		$msg->session->geo = array('lat' => $dane['lat'], 'lon' => $dane['lng']);
+		
+		$out->a('<p>Ustawiono miejsce: '.htmlspecialchars($this->session->miasto).', '.htmlspecialchars($this->session->countryName).'</p>');
+		
+		return $out;
+	}
+}
+?>
\ No newline at end of file
diff --git a/modules/30_pogoda/init.php b/modules/30_pogoda/init.php
new file mode 100644
index 0000000..2d19093
--- /dev/null
+++ b/modules/30_pogoda/init.php
@@ -0,0 +1,57 @@
+<?php
+class bot_pogoda_init implements BotModuleInit {
+	function register() {
+		$handler_pogoda = array(
+			array(
+				'file' => 'handler.php',
+				'class' => 'bot_pogoda_module',
+				'method' => 'pogoda',
+			)
+		);
+		$handler_miasto = array(
+			array(
+				'file' => 'handler.php',
+				'class' => 'bot_pogoda_module',
+				'method' => 'miasto',
+			)
+		);
+		
+		return array(
+			'pogoda' => $handler_pogoda,
+			'p' => $handler_pogoda,
+			'weather' => $handler_pogoda,
+			'temperatura' => $handler_pogoda,
+			'temp' => $handler_pogoda,
+			'miasto' => $handler_miasto,
+			'm' => $handler_miasto,
+		);
+	}
+	
+	function help($params = NULL) {
+		if($params === NULL) {
+			return new BotMsg('<b>pogoda</b> <i>[miasto]</i><br />'."\n"
+				. '   Pogoda dla miasta.<br />'."\n"
+				. '<b>miasto</b> <i>miasto</i><br />'."\n"
+				. '   Ustawia domyślne miasto dla funkcji pogoda.<br />'."\n"
+				. '<br />'."\n");
+		}
+		elseif(substr($params, 0, 1) == 'm') {
+			return new BotMsg('<b>miasto</b> <i>miasto</i> (alias: <b>m</b>)<br />'."\n"
+				. '   Ustawia domyślne miasto dla komendy <b>pogoda</b>. Dane o lokalizacji są również wykorzystywane do wyliczania godziny wschodu i zachodu słońca w funkcji <b>data</b>.<br />'."\n"
+				. '<br />'."\n"
+				. '<u>Przykład:</u><br />'."\n"
+				. 'miasto Warszawa');
+		}
+		else
+		{
+			return new BotMsg('<b>pogoda</b> <i>[miasto]</i> (aliasy: <b>p, weather, temp</b>)<br />'."\n"
+				. '   Podaje pogodę dla danego miasta na najbliższe dni. Domyślne miasto można ustawić komendą <b>miasto</p>.<br />'."\n"
+				. '<br />'."\n"
+				. '<u>Przykład:</u><br />'."\n"
+				. 'pogoda Warszawa');
+		}
+	}
+}
+
+return 'bot_data_init';
+?>
\ No newline at end of file

--
Gitblit v1.9.1