2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-12 16:46:35 +00:00

fhem.de/stats added to contrib

git-svn-id: https://svn.fhem.de/fhem/trunk@2258 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
mfr69bs 2012-12-03 15:51:06 +00:00
parent 651837960f
commit 941ee44da8
8 changed files with 7913 additions and 3 deletions

View File

@ -25,8 +25,6 @@ package main;
use strict;
use warnings;
use Config;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
sub CommandFheminfo($$);
@ -57,6 +55,21 @@ CommandFheminfo($$)
my $name = "fheminfo";
my %info;
my $module;
my $err = "Missing perl module '$module'. Please install this module first.";
my $err;
$module = "HTTP::Request::Common";
if(!checkModule($module)) {
Log 1, "$name $err";
return $err;
}
$module = "LWP::UserAgent";
if(!checkModule($module)) {
Log 1, "$name $err";
return $err;
}
return "Unknown argument $args[0], usage: fheminfo [send]" if(@args && lc($args[0]) ne "send");
my $branch = $DISTRIB_BRANCH;
@ -125,7 +138,7 @@ CommandFheminfo($$)
$ret = $str;
if(@args != 0 && $args[0] eq "send") {
my $uri = "http://fhem.de/stats/statistics.cgi";
my $uri = "http://192.168.1.5/cgi/statistics.cgi";
my $req = HTTP::Request->new("POST",$uri);
$req->content_type("application/x-www-form-urlencoded");
my $contInfo;
@ -200,6 +213,17 @@ sub checkConfigFile($) {
}
sub checkModule($) {
my $module = shift;
eval("use $module");
if($@) {
return(0);
} else {
return(1);
}
}
1;
=pod

View File

@ -0,0 +1,8 @@
Please download 'GeoLiteCity' package from
http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
and gunzip in this directory.
The GeoLite databases are distributed under the Creative Commons
Attribution-ShareAlike 3.0 Unported License.
For more Informations, visit: http://dev.maxmind.com/geoip/geolite

View File

@ -0,0 +1,4 @@
The file "fhem_statistics_db.sqlite" is the database for the delivered statistics.
The database file is created automatically.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,752 @@
package Geo::IP::Record;
use Geo::IP; #
use vars qw/$pp/;
use strict;
# here are the missing functions if the C API is used
sub latitude {
my $gir = shift;
return sprintf( "%.4f", $gir->_latitude );
}
sub longitude {
my $gir = shift;
return sprintf( "%.4f", $gir->_longitude );
}
BEGIN {
$pp = !defined(&Geo::IP::Record::city)
|| $Geo::IP::GEOIP_PP_ONLY;
}
eval <<'__PP__' if $pp;
for ( qw: country_code country_code3 country_name
region region_name city
postal_code dma_code area_code
continent_code metro_code : ) {
no strict qw/ refs /;
no warnings qw/ redefine /;
my $m = $_; # looks bogus, but it is not! it is a copy not a alias
*$_ = sub { $_[0]->{$m} };
}
# for the case warnings are globaly enabled with perl -w and the CAPI is absent
no warnings qw/ redefine /;
sub longitude {sprintf('%.4f', $_[0]->{longitude})}
sub latitude {sprintf('%.4f', $_[0]->{latitude})}
{
my $TIME_ZONE;
local $_ = <DATA>; # skip first line
while (<DATA>) {
chomp;
next if /^\s*$/;
my ( $country, $region, $timezone ) = split /\t/;
$TIME_ZONE->{$country}->{ $region || '' } = $timezone;
}
# called from Geo::IP
sub _time_zone {
my ( undef, $country, $region ) = @_;
return undef unless $country;
return undef unless defined $TIME_ZONE->{$country};
$region ||= '';
return
defined $TIME_ZONE->{$country}->{$region}
? $TIME_ZONE->{$country}->{$region}
: $TIME_ZONE->{$country}->{''};
}
sub time_zone {
my ( $self ) = @_;
my ( $country, $region ) = ( $self->country_code, $self->region );
return $self->_time_zone( $country, $region );
}
}
__PP__
1;
__DATA__
country region timezone
US AL America/Chicago
US AK America/Anchorage
US AZ America/Phoenix
US AR America/Chicago
US CA America/Los_Angeles
US CO America/Denver
US CT America/New_York
US DE America/New_York
US DC America/New_York
US FL America/New_York
US GA America/New_York
US HI Pacific/Honolulu
US ID America/Denver
US IL America/Chicago
US IN America/Indianapolis
US IA America/Chicago
US KS America/Chicago
US KY America/New_York
US LA America/Chicago
US ME America/New_York
US MD America/New_York
US MA America/New_York
US MI America/New_York
US MN America/Chicago
US MS America/Chicago
US MO America/Chicago
US MT America/Denver
US NE America/Chicago
US NV America/Los_Angeles
US NH America/New_York
US NJ America/New_York
US NM America/Denver
US NY America/New_York
US NC America/New_York
US ND America/Chicago
US OH America/New_York
US OK America/Chicago
US OR America/Los_Angeles
US PA America/New_York
US RI America/New_York
US SC America/New_York
US SD America/Chicago
US TN America/Chicago
US TX America/Chicago
US UT America/Denver
US VT America/New_York
US VA America/New_York
US WA America/Los_Angeles
US WV America/New_York
US WI America/Chicago
US WY America/Denver
CA AB America/Edmonton
CA BC America/Vancouver
CA MB America/Winnipeg
CA NB America/Halifax
CA NL America/St_Johns
CA NT America/Yellowknife
CA NS America/Halifax
CA NU America/Rankin_Inlet
CA ON America/Rainy_River
CA PE America/Halifax
CA QC America/Montreal
CA SK America/Regina
CA YT America/Whitehorse
AU 01 Australia/Canberra
AU 02 Australia/NSW
AU 03 Australia/North
AU 04 Australia/Queensland
AU 05 Australia/South
AU 06 Australia/Tasmania
AU 07 Australia/Victoria
AU 08 Australia/West
AS US/Samoa
CI Africa/Abidjan
GH Africa/Accra
DZ Africa/Algiers
ER Africa/Asmera
ML Africa/Bamako
CF Africa/Bangui
GM Africa/Banjul
GW Africa/Bissau
CG Africa/Brazzaville
BI Africa/Bujumbura
EG Africa/Cairo
MA Africa/Casablanca
GN Africa/Conakry
SN Africa/Dakar
DJ Africa/Djibouti
SL Africa/Freetown
BW Africa/Gaborone
ZW Africa/Harare
ZA Africa/Johannesburg
UG Africa/Kampala
SD Africa/Khartoum
RW Africa/Kigali
NG Africa/Lagos
GA Africa/Libreville
TG Africa/Lome
AO Africa/Luanda
ZM Africa/Lusaka
GQ Africa/Malabo
MZ Africa/Maputo
LS Africa/Maseru
SZ Africa/Mbabane
SO Africa/Mogadishu
LR Africa/Monrovia
KE Africa/Nairobi
TD Africa/Ndjamena
NE Africa/Niamey
MR Africa/Nouakchott
BF Africa/Ouagadougou
ST Africa/Sao_Tome
LY Africa/Tripoli
TN Africa/Tunis
AI America/Anguilla
AG America/Antigua
AW America/Aruba
BB America/Barbados
BZ America/Belize
CO America/Bogota
VE America/Caracas
KY America/Cayman
CR America/Costa_Rica
DM America/Dominica
SV America/El_Salvador
GD America/Grenada
FR Europe/Paris
GP America/Guadeloupe
GT America/Guatemala
GY America/Guyana
CU America/Havana
JM America/Jamaica
BO America/La_Paz
PE America/Lima
NI America/Managua
MQ America/Martinique
UY America/Montevideo
MS America/Montserrat
BS America/Nassau
PA America/Panama
SR America/Paramaribo
PR America/Puerto_Rico
KN America/St_Kitts
LC America/St_Lucia
VC America/St_Vincent
HN America/Tegucigalpa
YE Asia/Aden
JO Asia/Amman
TM Asia/Ashgabat
IQ Asia/Baghdad
BH Asia/Bahrain
AZ Asia/Baku
TH Asia/Bangkok
LB Asia/Beirut
KG Asia/Bishkek
BN Asia/Brunei
IN Asia/Calcutta
MN Asia/Choibalsan
LK Asia/Colombo
BD Asia/Dhaka
AE Asia/Dubai
TJ Asia/Dushanbe
HK Asia/Hong_Kong
TR Asia/Istanbul
IL Asia/Jerusalem
AF Asia/Kabul
PK Asia/Karachi
NP Asia/Katmandu
KW Asia/Kuwait
MO Asia/Macao
PH Asia/Manila
OM Asia/Muscat
CY Asia/Nicosia
KP Asia/Pyongyang
QA Asia/Qatar
MM Asia/Rangoon
SA Asia/Riyadh
KR Asia/Seoul
SG Asia/Singapore
TW Asia/Taipei
GE Asia/Tbilisi
BT Asia/Thimphu
JP Asia/Tokyo
LA Asia/Vientiane
AM Asia/Yerevan
BM Atlantic/Bermuda
CV Atlantic/Cape_Verde
FO Atlantic/Faeroe
IS Atlantic/Reykjavik
GS Atlantic/South_Georgia
SH Atlantic/St_Helena
CL Chile/Continental
NL Europe/Amsterdam
AD Europe/Andorra
GR Europe/Athens
YU Europe/Belgrade
DE Europe/Berlin
SK Europe/Bratislava
BE Europe/Brussels
RO Europe/Bucharest
HU Europe/Budapest
DK Europe/Copenhagen
IE Europe/Dublin
GI Europe/Gibraltar
FI Europe/Helsinki
SI Europe/Ljubljana
GB Europe/London
LU Europe/Luxembourg
MT Europe/Malta
BY Europe/Minsk
MC Europe/Monaco
NO Europe/Oslo
CZ Europe/Prague
LV Europe/Riga
IT Europe/Rome
SM Europe/San_Marino
BA Europe/Sarajevo
MK Europe/Skopje
BG Europe/Sofia
SE Europe/Stockholm
EE Europe/Tallinn
AL Europe/Tirane
LI Europe/Vaduz
VA Europe/Vatican
AT Europe/Vienna
LT Europe/Vilnius
PL Europe/Warsaw
HR Europe/Zagreb
IR Asia/Tehran
MG Indian/Antananarivo
CX Indian/Christmas
CC Indian/Cocos
KM Indian/Comoro
MV Indian/Maldives
MU Indian/Mauritius
YT Indian/Mayotte
RE Indian/Reunion
FJ Pacific/Fiji
TV Pacific/Funafuti
GU Pacific/Guam
NR Pacific/Nauru
NU Pacific/Niue
NF Pacific/Norfolk
PW Pacific/Palau
PN Pacific/Pitcairn
CK Pacific/Rarotonga
WS Pacific/Samoa
KI Pacific/Tarawa
TO Pacific/Tongatapu
WF Pacific/Wallis
TZ Africa/Dar_es_Salaam
VN Asia/Phnom_Penh
KH Asia/Phnom_Penh
CM Africa/Lagos
DO America/Santo_Domingo
ET Africa/Addis_Ababa
FX Europe/Paris
HT America/Port-au-Prince
CH Europe/Zurich
AN America/Curacao
BJ Africa/Porto-Novo
EH Africa/El_Aaiun
FK Atlantic/Stanley
GF America/Cayenne
IO Indian/Chagos
MD Europe/Chisinau
MP Pacific/Saipan
MW Africa/Blantyre
NA Africa/Windhoek
NC Pacific/Noumea
PG Pacific/Port_Moresby
PM America/Miquelon
PS Asia/Gaza
PY America/Asuncion
SB Pacific/Guadalcanal
SC Indian/Mahe
SJ Arctic/Longyearbyen
SY Asia/Damascus
TC America/Grand_Turk
TF Indian/Kerguelen
TK Pacific/Fakaofo
TT America/Port_of_Spain
VG America/Tortola
VI America/St_Thomas
VU Pacific/Efate
RS Europe/Belgrade
ME Europe/Podgorica
AX Europe/Mariehamn
GG Europe/Guernsey
IM Europe/Isle_of_Man
JE Europe/Jersey
BL America/St_Barthelemy
MF America/Marigot
AR 01 America/Argentina/Buenos_Aires
AR 02 America/Argentina/Catamarca
AR 03 America/Argentina/Tucuman
AR 04 America/Argentina/Rio_Gallegos
AR 05 America/Argentina/Cordoba
AR 06 America/Argentina/Tucuman
AR 07 America/Argentina/Buenos_Aires
AR 08 America/Argentina/Buenos_Aires
AR 09 America/Argentina/Tucuman
AR 10 America/Argentina/Jujuy
AR 11 America/Argentina/San_Luis
AR 12 America/Argentina/La_Rioja
AR 13 America/Argentina/Mendoza
AR 14 America/Argentina/Buenos_Aires
AR 15 America/Argentina/San_Luis
AR 16 America/Argentina/Buenos_Aires
AR 17 America/Argentina/Salta
AR 18 America/Argentina/San_Juan
AR 19 America/Argentina/San_Luis
AR 20 America/Argentina/Rio_Gallegos
AR 21 America/Argentina/Buenos_Aires
AR 22 America/Argentina/Catamarca
AR 23 America/Argentina/Ushuaia
AR 24 America/Argentina/Tucuman
BR 01 America/Rio_Branco
BR 02 America/Maceio
BR 03 America/Sao_Paulo
BR 04 America/Manaus
BR 05 America/Bahia
BR 06 America/Fortaleza
BR 07 America/Sao_Paulo
BR 08 America/Sao_Paulo
BR 11 America/Campo_Grande
BR 13 America/Belem
BR 14 America/Cuiaba
BR 15 America/Sao_Paulo
BR 16 America/Belem
BR 17 America/Recife
BR 18 America/Sao_Paulo
BR 20 America/Fortaleza
BR 21 America/Sao_Paulo
BR 22 America/Recife
BR 23 America/Sao_Paulo
BR 24 America/Porto_Velho
BR 25 America/Boa_Vista
BR 26 America/Sao_Paulo
BR 27 America/Sao_Paulo
BR 28 America/Maceio
BR 29 America/Sao_Paulo
BR 30 America/Recife
BR 31 America/Araguaina
CD 02 Africa/Kinshasa
CD 05 Africa/Lubumbashi
CD 06 Africa/Kinshasa
CD 08 Africa/Kinshasa
CD 10 Africa/Lubumbashi
CD 11 Africa/Lubumbashi
CD 12 Africa/Lubumbashi
CN 01 Asia/Shanghai
CN 02 Asia/Shanghai
CN 03 Asia/Shanghai
CN 04 Asia/Shanghai
CN 05 Asia/Harbin
CN 06 Asia/Chongqing
CN 07 Asia/Shanghai
CN 08 Asia/Harbin
CN 09 Asia/Shanghai
CN 10 Asia/Shanghai
CN 11 Asia/Chongqing
CN 12 Asia/Shanghai
CN 13 Asia/Urumqi
CN 14 Asia/Chongqing
CN 15 Asia/Chongqing
CN 16 Asia/Chongqing
CN 18 Asia/Chongqing
CN 19 Asia/Harbin
CN 20 Asia/Harbin
CN 21 Asia/Chongqing
CN 22 Asia/Harbin
CN 23 Asia/Shanghai
CN 24 Asia/Chongqing
CN 25 Asia/Shanghai
CN 26 Asia/Chongqing
CN 28 Asia/Shanghai
CN 29 Asia/Chongqing
CN 30 Asia/Chongqing
CN 31 Asia/Chongqing
CN 32 Asia/Chongqing
CN 33 Asia/Chongqing
EC 01 Pacific/Galapagos
EC 02 America/Guayaquil
EC 03 America/Guayaquil
EC 04 America/Guayaquil
EC 05 America/Guayaquil
EC 06 America/Guayaquil
EC 07 America/Guayaquil
EC 08 America/Guayaquil
EC 09 America/Guayaquil
EC 10 America/Guayaquil
EC 11 America/Guayaquil
EC 12 America/Guayaquil
EC 13 America/Guayaquil
EC 14 America/Guayaquil
EC 15 America/Guayaquil
EC 17 America/Guayaquil
EC 18 America/Guayaquil
EC 19 America/Guayaquil
EC 20 America/Guayaquil
EC 22 America/Guayaquil
ES 07 Europe/Madrid
ES 27 Europe/Madrid
ES 29 Europe/Madrid
ES 31 Europe/Madrid
ES 32 Europe/Madrid
ES 34 Europe/Madrid
ES 39 Europe/Madrid
ES 51 Africa/Ceuta
ES 52 Europe/Madrid
ES 53 Atlantic/Canary
ES 54 Europe/Madrid
ES 55 Europe/Madrid
ES 56 Europe/Madrid
ES 57 Europe/Madrid
ES 58 Europe/Madrid
ES 59 Europe/Madrid
ES 60 Europe/Madrid
GL 01 America/Thule
GL 02 America/Godthab
GL 03 America/Godthab
ID 01 Asia/Pontianak
ID 02 Asia/Makassar
ID 03 Asia/Jakarta
ID 04 Asia/Jakarta
ID 05 Asia/Jakarta
ID 06 Asia/Jakarta
ID 07 Asia/Jakarta
ID 08 Asia/Jakarta
ID 09 Asia/Jayapura
ID 10 Asia/Jakarta
ID 11 Asia/Pontianak
ID 12 Asia/Makassar
ID 13 Asia/Makassar
ID 14 Asia/Makassar
ID 15 Asia/Jakarta
ID 16 Asia/Makassar
ID 17 Asia/Makassar
ID 18 Asia/Makassar
ID 19 Asia/Pontianak
ID 20 Asia/Makassar
ID 21 Asia/Makassar
ID 22 Asia/Makassar
ID 23 Asia/Makassar
ID 24 Asia/Jakarta
ID 25 Asia/Pontianak
ID 26 Asia/Pontianak
ID 30 Asia/Jakarta
ID 31 Asia/Makassar
ID 33 Asia/Jakarta
KZ 01 Asia/Almaty
KZ 02 Asia/Almaty
KZ 03 Asia/Qyzylorda
KZ 04 Asia/Aqtobe
KZ 05 Asia/Qyzylorda
KZ 06 Asia/Aqtau
KZ 07 Asia/Oral
KZ 08 Asia/Qyzylorda
KZ 09 Asia/Aqtau
KZ 10 Asia/Qyzylorda
KZ 11 Asia/Almaty
KZ 12 Asia/Qyzylorda
KZ 13 Asia/Aqtobe
KZ 14 Asia/Qyzylorda
KZ 15 Asia/Almaty
KZ 16 Asia/Aqtobe
KZ 17 Asia/Almaty
MX 01 America/Mexico_City
MX 02 America/Tijuana
MX 03 America/Hermosillo
MX 04 America/Merida
MX 05 America/Mexico_City
MX 06 America/Chihuahua
MX 07 America/Monterrey
MX 08 America/Mexico_City
MX 09 America/Mexico_City
MX 10 America/Mazatlan
MX 11 America/Mexico_City
MX 12 America/Mexico_City
MX 13 America/Mexico_City
MX 14 America/Mazatlan
MX 15 America/Chihuahua
MX 16 America/Mexico_City
MX 17 America/Mexico_City
MX 18 America/Mazatlan
MX 19 America/Monterrey
MX 20 America/Mexico_City
MX 21 America/Mexico_City
MX 22 America/Mexico_City
MX 23 America/Cancun
MX 24 America/Mexico_City
MX 25 America/Mazatlan
MX 26 America/Hermosillo
MX 27 America/Merida
MX 28 America/Monterrey
MX 29 America/Mexico_City
MX 30 America/Mexico_City
MX 31 America/Merida
MX 32 America/Monterrey
MY 01 Asia/Kuala_Lumpur
MY 02 Asia/Kuala_Lumpur
MY 03 Asia/Kuala_Lumpur
MY 04 Asia/Kuala_Lumpur
MY 05 Asia/Kuala_Lumpur
MY 06 Asia/Kuala_Lumpur
MY 07 Asia/Kuala_Lumpur
MY 08 Asia/Kuala_Lumpur
MY 09 Asia/Kuala_Lumpur
MY 11 Asia/Kuching
MY 12 Asia/Kuala_Lumpur
MY 13 Asia/Kuala_Lumpur
MY 14 Asia/Kuala_Lumpur
MY 15 Asia/Kuching
MY 16 Asia/Kuching
NZ 85 Pacific/Auckland
NZ E7 Pacific/Auckland
NZ E8 Pacific/Auckland
NZ E9 Pacific/Auckland
NZ F1 Pacific/Auckland
NZ F2 Pacific/Auckland
NZ F3 Pacific/Auckland
NZ F4 Pacific/Auckland
NZ F5 Pacific/Auckland
NZ F7 Pacific/Chatham
NZ F8 Pacific/Auckland
NZ F9 Pacific/Auckland
NZ G1 Pacific/Auckland
NZ G2 Pacific/Auckland
NZ G3 Pacific/Auckland
PT 02 Europe/Lisbon
PT 03 Europe/Lisbon
PT 04 Europe/Lisbon
PT 05 Europe/Lisbon
PT 06 Europe/Lisbon
PT 07 Europe/Lisbon
PT 08 Europe/Lisbon
PT 09 Europe/Lisbon
PT 10 Atlantic/Madeira
PT 11 Europe/Lisbon
PT 13 Europe/Lisbon
PT 14 Europe/Lisbon
PT 16 Europe/Lisbon
PT 17 Europe/Lisbon
PT 18 Europe/Lisbon
PT 19 Europe/Lisbon
PT 20 Europe/Lisbon
PT 21 Europe/Lisbon
PT 22 Europe/Lisbon
RU 01 Europe/Volgograd
RU 02 Asia/Irkutsk
RU 03 Asia/Novokuznetsk
RU 04 Asia/Novosibirsk
RU 05 Asia/Vladivostok
RU 06 Europe/Moscow
RU 07 Europe/Volgograd
RU 08 Europe/Samara
RU 09 Europe/Moscow
RU 10 Europe/Moscow
RU 11 Asia/Irkutsk
RU 13 Asia/Yekaterinburg
RU 14 Asia/Irkutsk
RU 15 Asia/Anadyr
RU 16 Europe/Samara
RU 17 Europe/Volgograd
RU 18 Asia/Krasnoyarsk
RU 20 Asia/Irkutsk
RU 21 Europe/Moscow
RU 22 Europe/Volgograd
RU 23 Europe/Kaliningrad
RU 24 Europe/Volgograd
RU 25 Europe/Moscow
RU 26 Asia/Kamchatka
RU 27 Europe/Volgograd
RU 28 Europe/Moscow
RU 29 Asia/Novokuznetsk
RU 30 Asia/Vladivostok
RU 31 Asia/Krasnoyarsk
RU 32 Asia/Omsk
RU 33 Asia/Yekaterinburg
RU 34 Asia/Yekaterinburg
RU 35 Asia/Yekaterinburg
RU 36 Asia/Anadyr
RU 37 Europe/Moscow
RU 38 Europe/Volgograd
RU 39 Asia/Krasnoyarsk
RU 40 Asia/Yekaterinburg
RU 41 Europe/Moscow
RU 42 Europe/Moscow
RU 43 Europe/Moscow
RU 44 Asia/Magadan
RU 45 Europe/Samara
RU 46 Europe/Samara
RU 47 Europe/Moscow
RU 48 Europe/Moscow
RU 49 Europe/Moscow
RU 50 Asia/Yekaterinburg
RU 51 Europe/Moscow
RU 52 Europe/Moscow
RU 53 Asia/Novosibirsk
RU 54 Asia/Omsk
RU 55 Europe/Samara
RU 56 Europe/Moscow
RU 57 Europe/Samara
RU 58 Asia/Yekaterinburg
RU 59 Asia/Vladivostok
RU 60 Europe/Kaliningrad
RU 61 Europe/Volgograd
RU 62 Europe/Moscow
RU 63 Asia/Yakutsk
RU 64 Asia/Sakhalin
RU 65 Europe/Samara
RU 66 Europe/Moscow
RU 67 Europe/Samara
RU 68 Europe/Volgograd
RU 69 Europe/Moscow
RU 70 Europe/Volgograd
RU 71 Asia/Yekaterinburg
RU 72 Europe/Moscow
RU 73 Europe/Samara
RU 74 Asia/Krasnoyarsk
RU 75 Asia/Novosibirsk
RU 76 Europe/Moscow
RU 77 Europe/Moscow
RU 78 Asia/Yekaterinburg
RU 79 Asia/Irkutsk
RU 80 Asia/Yekaterinburg
RU 81 Europe/Samara
RU 82 Asia/Irkutsk
RU 83 Europe/Moscow
RU 84 Europe/Volgograd
RU 85 Europe/Moscow
RU 86 Europe/Moscow
RU 87 Asia/Novosibirsk
RU 88 Europe/Moscow
RU 89 Asia/Vladivostok
UA 01 Europe/Kiev
UA 02 Europe/Kiev
UA 03 Europe/Uzhgorod
UA 04 Europe/Zaporozhye
UA 05 Europe/Zaporozhye
UA 06 Europe/Uzhgorod
UA 07 Europe/Zaporozhye
UA 08 Europe/Simferopol
UA 09 Europe/Kiev
UA 10 Europe/Zaporozhye
UA 11 Europe/Simferopol
UA 13 Europe/Kiev
UA 14 Europe/Zaporozhye
UA 15 Europe/Uzhgorod
UA 16 Europe/Zaporozhye
UA 17 Europe/Simferopol
UA 18 Europe/Zaporozhye
UA 19 Europe/Kiev
UA 20 Europe/Simferopol
UA 21 Europe/Kiev
UA 22 Europe/Uzhgorod
UA 23 Europe/Kiev
UA 24 Europe/Uzhgorod
UA 25 Europe/Uzhgorod
UA 26 Europe/Zaporozhye
UA 27 Europe/Kiev
UZ 01 Asia/Tashkent
UZ 02 Asia/Samarkand
UZ 03 Asia/Tashkent
UZ 06 Asia/Tashkent
UZ 07 Asia/Samarkand
UZ 08 Asia/Samarkand
UZ 09 Asia/Samarkand
UZ 10 Asia/Samarkand
UZ 12 Asia/Samarkand
UZ 13 Asia/Tashkent
UZ 14 Asia/Tashkent
TL Asia/Dili
PF Pacific/Marquesas

View File

@ -0,0 +1,104 @@
=head1 NAME
Geo::IP::Record - Contains city information for GeoIP City Edition
=head1 SYNOPSIS
use Geo::IP;
my $gi = Geo::IP->open("/usr/local/share/GeoIP/GeoIPCity.dat", GEOIP_STANDARD);
my $record = $gi->record_by_addr('24.24.24.24');
print $record->country_code,
$record->country_code3,
$record->country_name,
$record->region,
$record->region_name,
$record->city,
$record->postal_code,
$record->latitude,
$record->longitude,
$record->time_zone,
$record->area_code,
$record->continent_code,
$record->metro_code;
=head1 DESCRIPTION
Geo::IP::Record represents objects containing location information
returned by the GeoIP City database. It works with both the
commercial GeoIP City and free GeoLite City databases.
=head1 OBJECT METHODS
=over 4
=item $code = $record->country_code;
Returns the ISO 3166 country code from the location object.
=item $code3 = $record->country_code3;
Returns the ISO 3166 3 letter country code from the location object.
=item $name = $record->country_name;
Returns the country name from the location object.
=item $region = $record->region;
Returns the region code from the location object.
=item $region = $record->region_name;
Returns the region name from the location object.
=item $city = $record->city;
Returns the city from the location object.
=item $postal_code = $record->postal_code;
Returns the postal code from the location object.
=item $lat = $record->latitude;
Returns the latitude from the location object.
=item $lon = $record->longitude;
Returns the longitude from the location object.
=item $time_zone = $record->time_zone;
Returns the time zone from the location object.
=item $area_code = $record->area_code;
Returns the area code from the location object (for city-level US locations only)
=item $metro_code = $record->metro_code;
Returns the metro code from the location object (for city-level US locations only)
=item $continent_code = $record->continent_code;
Returns the continent code from the location object.
Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe, North America, Oceania and South America.
=back
=head1 VERSION
1.21
=head1 AUTHOR
Copyright (c) 2008, MaxMind LLC
All rights reserved. This package is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
=cut

View File

@ -0,0 +1,400 @@
package Geo::Mirror;
use strict;
use vars qw($VERSION);
$VERSION = '1.01';
use constant PI => 3.14159265358979323846;
our (%lat, %lon, $geo_ip_pkg);
BEGIN {
if (eval { require Geo::IP }) {
$geo_ip_pkg = "Geo::IP";
}
else {
require Geo::IP::PurePerl;
$geo_ip_pkg = "Geo::IP::PurePerl";
}
$geo_ip_pkg->import('GEOIP_STANDARD');
}
{
local $_;
while (<DATA>) {
my ($country, $lat, $lon) = split(':');
$lat{$country} = $lat;
$lon{$country} = $lon;
}
}
sub new {
my ($class, %h) = @_;
my $self = \%h;
bless $self, $class;
$self->_init;
return $self;
}
sub _init {
my $self = shift;
my $mirror_file = $self->{mirror_file};
local $_;
open MIRROR, "$mirror_file" or die $!;
while(<MIRROR>) {
my ($url, $country, $fresh) = split(' ');
push @{$self->{mirror}->{$country}}, $url;
$self->{fresh}{$url} = $fresh || 0;
}
close MIRROR;
}
sub _random_mirror {
my ($self, $country, $fresh) = @_;
my @mirror = grep { $self->{fresh}{$_} >= $fresh } @{$self->{mirror}->{$country}};
my $num = scalar @mirror or return;
return $mirror[ rand($num) ];
}
sub find_mirror_by_country {
my ($self, $country, $fresh) = @_;
my $url;
$fresh ||= 0;
if (exists $self->{mirror}->{$country}) {
$url = $self->_random_mirror($country, $fresh);
}
if (!$url) {
my $nearby = $self->{nearby_cache}->{$country} ||= $self->_find_nearby_countries($country);
foreach my $new_country (@$nearby) {
$url = $self->_random_mirror($new_country, $fresh) and last;
}
}
return $url;
}
sub find_mirror_by_addr {
my ($self, $addr, $fresh) = @_;
unless($self->{gi}) {
if ($self->{database_file}) {
$self->{gi} = $geo_ip_pkg->open($self->{database_file}, GEOIP_STANDARD);
} else {
$self->{gi} = $geo_ip_pkg->new(GEOIP_STANDARD);
}
}
# default to US if country not found
my $country = lc($self->{gi}->country_code_by_addr($addr)) || 'us';
$country = 'us' if $country eq '--';
return $self->find_mirror_by_country($country, $fresh);
}
sub _find_nearby_countries {
my ($self, $country) = @_;
my %distance = map { ($_, $self->_calculate_distance($country, $_)) } keys %{$self->{mirror}};
delete $distance{$country};
[ sort { $distance{$a} <=> $distance{$b} } keys %distance ];
}
sub _calculate_distance {
my ($self, $country1, $country2) = @_;
my $lat_1 = $lat{$country1};
my $lat_2 = $lat{$country2};
my $lon_1 = $lon{$country1};
my $lon_2 = $lon{$country2};
# Convert all the degrees to radians
$lat_1 *= PI/180;
$lon_1 *= PI/180;
$lat_2 *= PI/180;
$lon_2 *= PI/180;
# Find the deltas
my $delta_lat = $lat_2 - $lat_1;
my $delta_lon = $lon_2 - $lon_1;
# Find the Great Circle distance
my $temp = sin($delta_lat/2.0)**2 + cos($lat_1) * cos($lat_2) * sin($delta_lon/2.0)**2;
return atan2(sqrt($temp),sqrt(1-$temp));
}
1;
=head1 NAME
Geo::Mirror - Find closest Mirror
=head1 SYNOPSIS
use Geo::Mirror;
my $gm = Geo::Mirror->new(mirror_file => '/path/to/mirrors.txt');
my $mirror = $gm->closest_mirror_by_country('us', $freshness); # $freshness optional, see description below
my $mirror = $gm->closest_mirror_by_addr('24.24.24.24', $freshness); # $freshness optional, see description below
=head1 DESCRIPTION
This module finds the closest mirror for an IP address. It uses L<Geo::IP>
to identify the country that the IP address originated from. If
the country is not represented in the mirror list, then it finds the
closest country using a latitude/longitude table.
The mirror file should be a space separate list of URL, Country, and mirror freshness.
The mirror freshness is optional and can be used by user
request a mirror with a minimum freshness.
=head1 AUTHOR
Copyright (c) 2004, MaxMind LLC, support@maxmind.com
All rights reserved. This package is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.
=cut
__DATA__
af:33:65
al:41:20
dz:28:3
as:-14:-170
ad:42:1
ao:-12:18
ai:18:-63
aq:-90:0
ag:17:-61
ar:-34:-64
am:40:45
aw:12:-69
au:-27:133
at:47:13
az:40:47
bs:24:-76
bh:26:50
bd:24:90
bb:13:-59
by:53:28
be:50:4
bz:17:-88
bj:9:2
bm:32:-64
bt:27:90
bo:-17:-65
ba:44:18
bw:-22:24
bv:-54:3
br:-10:-55
io:-6:71
vg:18:-64
bg:43:25
bf:13:-2
bi:-3:30
kh:13:105
cm:6:12
ca:60:-95
cv:16:-24
ky:19:-80
cf:7:21
td:15:19
cl:-30:-71
cn:35:105
cx:-10:105
cc:-12:96
co:4:-72
km:-12:44
cd:0:25
cg:-1:15
ck:-21:-159
cr:10:-84
ci:8:-5
hr:45:15
cu:21:-80
cy:35:33
cz:49:15
dk:56:10
dj:11:43
dm:15:-61
do:19:-70
ec:-2:-77
eg:27:30
sv:13:-88
gq:2:10
er:15:39
ee:59:26
et:8:38
fk:-51:-59
fo:62:-7
fj:-18:175
fi:64:26
fr:46:2
gf:4:-53
pf:-15:-140
ga:-1:11
gm:13:-16
ge:42:43
de:51:9
eu:48:10
gh:8:-2
gi:36:-5
gr:39:22
gl:72:-40
gd:12:-61
gp:16:-61
gu:13:144
gt:15:-90
gn:11:-10
gw:12:-15
gy:5:-59
ht:19:-72
hm:-53:72
va:41:12
hn:15:-86
hk:22:114
hu:47:20
is:65:-18
in:20:77
id:-5:120
ir:32:53
iq:33:44
ie:53:-8
il:31:34
it:42:12
jm:18:-77
sj:71:-8
jp:36:138
jo:31:36
ke:1:38
ki:1:173
kp:40:127
kr:37:127
kw:29:45
kg:41:75
lv:57:25
lb:33:35
ls:-29:28
lr:6:-9
ly:25:17
li:47:9
lt:56:24
lu:49:6
mo:22:113
mk:41:22
mg:-20:47
mw:-13:34
my:2:112
mv:3:73
ml:17:-4
mt:35:14
mh:9:168
mq:14:-61
mr:20:-12
mu:-20:57
yt:-12:45
mx:23:-102
fm:6:158
mc:43:7
mn:46:105
ms:16:-62
ma:32:-5
mz:-18:35
na:-22:17
nr:-0:166
np:28:84
nl:52:5
an:12:-68
nc:-21:165
nz:-41:174
ni:13:-85
ne:16:8
ng:10:8
nu:-19:-169
nf:-29:167
mp:15:145
no:62:10
om:21:57
pk:30:70
pw:7:134
pa:9:-80
pg:-6:147
py:-23:-58
pe:-10:-76
ph:13:122
pn:-25:-130
pl:52:20
pt:39:-8
pr:18:-66
qa:25:51
re:-21:55
ro:46:25
ru:60:100
rw:-2:30
sh:-15:-5
kn:17:-62
lc:13:-60
pm:46:-56
vc:13:-61
ws:-13:-172
sm:43:12
st:1:7
sa:25:45
sn:14:-14
sc:-4:55
sl:8:-11
sg:1:103
sk:48:19
si:46:15
sb:-8:159
so:10:49
za:-29:24
gs:-54:-37
es:40:-4
lk:7:81
sd:15:30
sr:4:-56
sj:78:20
sz:-26:31
se:62:15
ch:47:8
sy:35:38
tj:39:71
tz:-6:35
th:15:100
tg:8:1
tk:-9:-172
to:-20:-175
tt:11:-61
tn:34:9
tr:39:35
tm:40:60
tc:21:-71
tv:-8:178
ug:1:32
ua:49:32
ae:24:54
gb:54:-2
us:38:-97
uy:-33:-56
uz:41:64
vu:-16:167
ve:8:-66
vn:16:106
vi:18:-64
wf:-13:-176
eh:24:-13
ye:15:48
yu:44:21
zm:-15:30
zw:-20:30
tw:23:121

View File

@ -0,0 +1,681 @@
#!/usr/bin/perl -w
################################################################
# $Id: $
# vim: ts=2:et
#
# (c) 2012 Copyright: Martin Fischer (m_fischer at gmx dot de)
# All rights reserved
#
# This script 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
# any later version.
#
# The GNU General Public License can be found at
# http://www.gnu.org/copyleft/gpl.html.
# A copy is found in the textfile GPL.txt and important notices to the license
# from the author is found in LICENSE.txt distributed with these scripts.
#
# This script 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.
#
################################################################
use CGI qw(:standard Vars);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use DBI; #requires libdbd-sqlite3-perl
use lib "./lib";
use Geo::IP;
use strict;
use warnings;
no warnings 'uninitialized';
sub createDB();
sub insertDB();
sub checkColumn($$);
sub getLocation($);
sub googleVisualizationLib($);
sub drawMarkersMap(@);
sub drawPieChart(@);
sub drawRegionsMap(@);
sub drawTable(@);
sub drawColumnChartTop10Modules(@);
sub drawColumnChartTop10ModDef(@);
sub drawBarChartModules(@);
sub viewStatistics();
# cascading style sheet
my $css = "http://fhem.de/../css/style.css";
# exclude modules from top 10 graph
my $excludeFromTop10modules = "at autocreate notify telnet weblink FileLog SUNRISE_EL";
my $excludeFromTop10definitions = "at autocreate notify telnet weblink FileLog SUNRISE_EL";
# geo ip database file from http://www.maxmind.com/download/geoip/database/
# should be updated once per month
my $geoIPDat = "./data/GeoLiteCity.dat";
# database
my $dbf = "./data/fhem_statistics_db.sqlite";
my $dsn = "dbi:SQLite:dbname=$dbf";
my $sth;
# fhem node
my $ua = $ENV{HTTP_USER_AGENT};
my $ip = $ENV{REMOTE_ADDR};
my %data = Vars();
# create database if not exists
createDB() if (! -e $dbf);
my $dbh = DBI->connect($dsn,"","", { RaiseError => 1, ShowErrorStatement => 1 }) ||
die "Cannot connect: $DBI::errstr";
if(index($ua,"Fhem") > -1) {
print header("application/x-www-form-urlencoded");
insertDB();
print "==> ok";
} else {
viewStatistics();
}
sub viewStatistics() {
my $visLib = googleVisualizationLib("'corechart','geochart','table'");
my $cOS = drawPieChart("nodes","os","Operating System",400,300,"chart_os");
my $cArch = drawPieChart("nodes","arch","Architecture",400,300,"chart_arch");
my $cRelease = drawPieChart("nodes","release","FHEM Release",400,300,"chart_release");
my $cPerl = drawPieChart("nodes","perl","Perl Version",400,300,"chart_perl");
#my $cModulesTop10 = drawColumnChartTop10Modules("modules","modulestop10",,"Used",825,300,"chart_modulestop10");
#my $cModDefTop10 = drawColumnChartTop10ModDef("modules","definitions","Definitions",825,300,"chart_moddeftop10");
my $cModules = drawBarChartModules("modules","modules","Used","Definitions",825,600,"chart_modules");
my $mWorld = drawRegionsMap("locations","countryname","world","map_world");
my $mEU = drawRegionsMap("locations","countryname","150","map_europe");
my $mWesternEU = drawMarkersMap("locations","city","155","map_germany");
my $tModules = drawTable3cols("modules","total_modules","string","Module","number","Used","number","Definitions","table_modules");
#my $tModDef = drawTable("modules","total_moddef","string","Module","number","Definitions","table_moddef");
my $tModels = drawTable2cols("models","total_models","string","Model","boolean","defined","table_models");
my @res = $dbh->selectrow_array("SELECT created FROM db");
my $since = "@res";
print header;
print start_html(
-title => 'fhem.de - Statistics',
-author => 'm_fischer@gmx.de',
-base => 'true',
-style => {-src => $css},
-meta => {'keywords' => 'fhem houseautomation statistics'},
-script => [
{ -type => 'text/javascript',
-src => 'https://www.google.com/jsapi',
},
$visLib,
$cOS, $cArch, $cRelease, $cPerl,
# $cModulesTop10, $cModDefTop10,
$cModules,
$mWorld, $mEU, $mWesternEU,
$tModules, $tModels,
],
);
my ($nodes) = $dbh->selectrow_array("SELECT COUNT(uniqueID) FROM nodes");
print <<END;
<div id="logo"></div>
<div id="menu">
<table><tbody><tr><td>
<table id="room">
<tr><td></td></tr>
<tr><td><b>back to</b></td></tr>
<tr><td></td></tr>
<tr><td><a href="http://fhem.de">Homepage</a></td></tr>
<tr><td></td></tr>
</tbody></table>
</td></tr></tbody></table>
</div>
<div id="right">
<noscript>
<div style="text-align:center; border: 2px solid red; background: #D7FFFF;">
<div style="text-align:center; background: #D7FFFF; color: red;">
<h4>Please enable Javascript on your Browser!</h4>
</div>
</div>
</noscript>
<h3>Fhem Statistics ($nodes submissions since $since)</h3>
<h4>Installed on...</h4>
<div id="chart_os" style="float:left; border: 1px solid black; margin-right:25px;"></div>
<div id="chart_arch" style="float:left; border: 1px solid black;"></div>
<div style="clear:both;"></div>
<h4>Versions...</h4>
<div id="chart_release" style="float:left; border: 1px solid black; margin-right:25px;"></div>
<div id="chart_perl" style="float:left; border: 1px solid black;"></div>
<div style="clear:both;"></div>
<!-- graphs disabled
// <h4>Top 10 of most commonly used modules<small><sup>1</sup></small>...</h4>
// <div id="chart_modulestop10" style="width: 825px; height: 300px; border: 1px solid black;"></div>
// <small><sup>1</sup> excluded from graph: $excludeFromTop10modules</small>
//
// <h4>Top 10 of total definitions by module<small><sup>1</sup></small>...</h4>
// <div id="chart_moddeftop10" style="width: 825px; height: 300px; border: 1px solid black;"></div>
// <small><sup>1</sup> excluded from graph: $excludeFromTop10definitions</small>
//-->
<h4>Top 20 of most commonly used modules (with total definitions by module)...</h4>
<div id="chart_modules" style="width: 825px; height: 600px; border: 1px solid black;"></div>
<h4>Locations worldwide...</h4>
<div id="map_world" style="width: 825px; height: 500px; border: 1px solid black;"></div>
<h4>Locations in Europe...</h4>
<div id="map_europe" style="width: 825px; height: 500px; border: 1px solid black;"></div>
<h4>Locations in Western Europe...</h4>
<div id="map_germany" style="width: 825px; height: 500px; border: 1px solid black;"></div>
<div style="float:left; width: 400px; margin-right:25px;">
<h4>List of total used modules (with definitions)...</h4>
<div id="table_modules" style="width: 400px; border: 1px solid black;"></div>
</div>
<div style="float:left; width: 400px;">
<h4>List of defined models...</h4>
<div id="table_models" style="width: 400px; border: 1px solid black;"></div>
</div>
<div style="clear:both;"></div>
<div id="footer" style="position:relative; left: -100px; text-align: center;">
<p><small>Layout by M. Fischer - Click <a href="http://www.fischer-net.de/kontakt.html">here</a> to leave your comments.</small></p>
</div>
</div>
END
print end_html;
}
sub googleVisualizationLib($) {
my $packages = shift;
my $code =<<END;
// Load the Visualization API library
google.load('visualization', '1.0', {'packages':[$packages]});
END
return $code;
}
sub drawPieChart(@) {
my ($table,$column,$title,$width,$height,$divID) = @_;
my $res = $dbh->selectall_arrayref("SELECT DISTINCT $column FROM $table ORDER BY $column ASC");
my %hash = ();
foreach my $row (@$res) {
my ($value) = @$row;
my ($count) = $dbh->selectrow_array("SELECT COUNT(*) FROM $table WHERE $column = '$value'");
$hash{$value} = $count;
}
my $addRows;
foreach my $value (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
$addRows .= "\t['$value',$hash{$value}],\n";
}
chop($addRows);
my $code =<<END;
google.setOnLoadCallback(drawChart_$column);
function drawChart_$column() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows([
$addRows
]);
var options = {
title : '$title',
width : $width,
height : $height,
is3D : true,
tooltip : { showColorCode: true, },
};
var chart = new google.visualization.PieChart(document.getElementById('$divID'));
chart.draw(data, options);
};
END
return $code;
}
sub drawColumnChartTop10Modules(@) {
my ($table,$postfix,$rowtitle,$width,$height,$divID) = @_;
$sth = $dbh->prepare("SELECT * FROM $table where 1=0");
$sth->execute();
my $res = $sth->{NAME};
$sth->finish;
my %hash = ();
foreach my $column (@$res) {
#my ($sum) = $dbh->selectrow_array("SELECT sum($column) FROM $table");
my ($sum) = $dbh->selectrow_array("SELECT count('$column') FROM $table");
$hash{$column} = $sum;
}
my $data;
my $i=0;
foreach my $column (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
next if($column eq "uniqueID");
next if($excludeFromTop10modules =~ /$column/);
$data .= "\t['$column',$hash{$column}],\n";
$i++;
last if($i == 10);
}
chop($data);
my $code =<<END;
google.setOnLoadCallback(drawChart_$postfix);
function drawChart_$postfix() {
var data = google.visualization.arrayToDataTable([
['Module','$rowtitle'],
$data
]);
var options = {
// title : 'title',
};
var chart = new google.visualization.ColumnChart(document.getElementById('$divID'));
chart.draw(data, options);
};
END
return $code;
}
sub drawColumnChartTop10ModDef(@) {
my ($table,$postfix,$rowtitle,$width,$height,$divID) = @_;
$sth = $dbh->prepare("SELECT * FROM $table where 1=0");
$sth->execute();
my $res = $sth->{NAME};
$sth->finish;
my %hash = ();
foreach my $column (@$res) {
my ($sum) = $dbh->selectrow_array("SELECT sum($column) FROM $table");
$hash{$column} = $sum;
}
my $data;
my $i=0;
foreach my $column (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
next if($column eq "uniqueID");
next if($excludeFromTop10definitions =~ /$column/);
$data .= "\t['$column',$hash{$column}],\n";
$i++;
last if($i == 10);
}
chop($data);
my $code =<<END;
google.setOnLoadCallback(drawChart_$postfix);
function drawChart_$postfix() {
var data = google.visualization.arrayToDataTable([
['Module','$rowtitle'],
$data
]);
var options = {
// title : 'title',
};
var chart = new google.visualization.ColumnChart(document.getElementById('$divID'));
chart.draw(data, options);
};
END
return $code;
}
sub drawBarChartModules(@) {
my ($table,$postfix,$row1title,$row2title,$width,$height,$divID) = @_;
$sth = $dbh->prepare("SELECT * FROM $table where 1=0");
$sth->execute();
my $res = $sth->{NAME};
$sth->finish;
my %hash = ();
foreach my $column (@$res) {
my ($count) = $dbh->selectrow_array("SELECT count($column) FROM $table WHERE $column > 0");
my ($sum) = $dbh->selectrow_array("SELECT sum($column) FROM $table");
$hash{$column}{count} = $count;
$hash{$column}{sum} = $sum;
}
my $data;
my $i=0;
foreach my $column (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
next if($column eq "uniqueID");
$data .= "\t['$column',$hash{$column}{count},$hash{$column}{sum}],\n";
$i++;
last if($i == 20);
}
chop($data);
my $code =<<END;
google.setOnLoadCallback(drawChart_$postfix);
function drawChart_$postfix() {
var data = google.visualization.arrayToDataTable([
['Module','$row1title','$row2title'],
$data
]);
var options = {
height : $height,
width : $width,
chartArea : {left:150,top:20,width:"65%",height:"90%"},
// title : 'title',
};
var chart = new google.visualization.BarChart(document.getElementById('$divID'));
chart.draw(data, options);
};
END
return $code;
}
sub drawMarkersMap(@) {
my ($table,$column,$region,$divID) = @_;
my $res = $dbh->selectall_arrayref("SELECT DISTINCT $column FROM $table ORDER BY $column ASC");
my %hash = ();
foreach my $row (@$res) {
my ($value) = @$row;
my ($count) = $dbh->selectrow_array("SELECT COUNT(*) FROM $table WHERE $column = '$value'");
#$value = "Germany" if($value eq "");
next if($value eq "");
$hash{$value} = $count;
}
my $addRows;
foreach my $value (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
$addRows .= "\t['$value',$hash{$value}],\n";
}
chop($addRows);
my $code=<<END;
google.setOnLoadCallback(drawMarkersMap_$region);
function drawMarkersMap_$region() {
var data = google.visualization.arrayToDataTable([
['City','Installations'],
$addRows
]);
var options = {
region: '$region',
displayMode: 'markers',
colorAxis: {colors: ['green', 'blue']}
};
var chart = new google.visualization.GeoChart(document.getElementById('$divID'));
chart.draw(data, options);
};
END
return $code;
}
sub drawRegionsMap(@) {
my ($table,$column,$region,$divID) = @_;
my $res = $dbh->selectall_arrayref("SELECT DISTINCT $column FROM $table ORDER BY $column ASC");
my %hash = ();
foreach my $row (@$res) {
my ($value) = @$row;
my ($count) = $dbh->selectrow_array("SELECT COUNT(*) FROM $table WHERE $column = '$value'");
$hash{$value} = $count;
}
my $addRows;
foreach my $value (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
$addRows .= "\t['$value',$hash{$value}],\n";
}
chop($addRows);
my $code=<<END;
google.setOnLoadCallback(drawRegionsMap_$region);
function drawRegionsMap_$region() {
var data = google.visualization.arrayToDataTable([
['Country','Installations'],
$addRows
]);
var options = {
region: '$region',
};
var chart = new google.visualization.GeoChart(document.getElementById('$divID'));
chart.draw(data, options);
};
END
return $code;
}
sub drawTable2cols(@) {
my ($table,$postfix,$type1,$title1,$type2,$title2,$divID) = @_;
$sth = $dbh->prepare("SELECT * FROM $table where 1=0");
$sth->execute();
my $res = $sth->{NAME};
$sth->finish;
my %hash = ();
foreach my $column (@$res) {
my ($sum) = $dbh->selectrow_array("SELECT sum(\"$column\") FROM $table");
$hash{$column} = $sum;
}
my $data;
if($type2 eq "boolean") {
foreach my $column (sort keys %hash) {
next if($column eq "uniqueID");
$data .= "\t['$column',true],\n";
}
} else {
foreach my $column (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
next if($column eq "uniqueID");
$data .= "\t['$column',$hash{$column}],\n";
}
}
chop($data);
my $code=<<END;
google.setOnLoadCallback(drawTable_$postfix);
function drawTable_$postfix() {
var data = new google.visualization.DataTable();
data.addColumn('$type1', '$title1');
data.addColumn('$type2', '$title2');
data.addRows([
$data
]);
var options = {
showRowNumber : false,
sortAscending : true,
sortColumn : 0,
};
var table = new google.visualization.Table(document.getElementById('$divID'));
table.draw(data,options);
};
END
return $code;
}
sub drawTable3cols(@) {
my ($table,$postfix,$type1,$title1,$type2,$title2,$type3,$title3,$divID) = @_;
$sth = $dbh->prepare("SELECT * FROM $table where 1=0");
$sth->execute();
my $res = $sth->{NAME};
$sth->finish;
my %hash = ();
foreach my $column (@$res) {
my ($count) = $dbh->selectrow_array("SELECT count(\"$column\") FROM $table WHERE \"$column\" > 0");
my ($sum) = $dbh->selectrow_array("SELECT sum(\"$column\") FROM $table");
$hash{$column}{count} = $count;
$hash{$column}{sum} = $sum;
}
my $data;
foreach my $column (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
next if($column eq "uniqueID");
$data .= "\t['$column',$hash{$column}{count},$hash{$column}{sum}],\n";
}
chop($data);
my $code=<<END;
google.setOnLoadCallback(drawTable_$postfix);
function drawTable_$postfix() {
var data = new google.visualization.DataTable();
data.addColumn('$type1', '$title1');
data.addColumn('$type2', '$title2');
data.addColumn('$type3', '$title3');
data.addRows([
$data
]);
var options = {
showRowNumber : false,
sortAscending : true,
sortColumn : 0,
};
var table = new google.visualization.Table(document.getElementById('$divID'));
table.draw(data,options);
};
END
return $code;
}
sub createDB() {
my $dbh = DBI->connect($dsn,"","", { RaiseError => 1, ShowErrorStatement => 1 }) ||
die "Cannot connect: $DBI::errstr";
$dbh->do("CREATE TABLE db (created TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");
$dbh->do("CREATE TABLE nodes (uniqueID VARCHAR(32) PRIMARY KEY UNIQUE, release VARCHAR(16), branch VARCHAR(32), os VARCHAR(32), arch VARCHAR(64), perl VARCHAR(16), lastSeen TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");
$dbh->do("CREATE TABLE locations (uniqueID VARCHAR(32) PRIMARY KEY UNIQUE, countrycode VARCHAR(2), countrycode3 VARCHAR(3), countryname VARCHAR(64), region CHAR(2) ,regionname VARCHAR(64), city VARCHAR(255), latitude FLOAT(8,6), longitude FLOAT(8,6), timezone VARCHAR(64), continentcode CHAR(2))");
$dbh->do("CREATE TABLE modules (uniqueID VARCHAR(32) PRIMARY KEY UNIQUE)");
$dbh->do("CREATE TABLE models (uniqueID VARCHAR(32) PRIMARY KEY UNIQUE)");
$dbh->do("INSERT INTO db (created) VALUES (CURRENT_TIMESTAMP)");
$dbh->disconnect();
return;
}
sub insertDB() {
my $uniqueID = $data{uniqueID};
my $modules = $data{modules};
my $models = $data{models};
my $sth;
# insert or update fhem node
my ($release,$branch,$os,$arch,$perl);
foreach (split(/\|/,$data{system})) {
my ($k,$v) = split /:/;
$release = $v if($k eq "Release");
$branch = $v if($k eq "Branch");
$os = $v if($k eq "OS");
$arch = $v if($k eq "Arch");
$perl = $v if($k eq "Perl");
}
$sth = $dbh->prepare(q{REPLACE INTO nodes (uniqueID,release,branch,os,arch,perl,lastSeen) VALUES(?,?,?,?,?,?,CURRENT_TIMESTAMP)});
$sth->execute($uniqueID,$release,$branch,$os,$arch,$perl);
# insert or update goe location of fhem node
#### TODO: sprachcode 84.191.75.195
my @geo = getLocation($ip);
if(@geo) {
$sth = $dbh->prepare(q{REPLACE INTO locations (uniqueID,countrycode,countrycode3,countryname,region,regionname,city,latitude,longitude,timezone,continentcode) VALUES(?,?,?,?,?,?,?,?,?,?,?)});
$sth->execute($uniqueID,$geo[0],$geo[1],$geo[2],$geo[3],$geo[4],$geo[5],$geo[6],$geo[7],$geo[8],$geo[9]);
}
# delete old modules of fhem node
$sth = $dbh->prepare(q{DELETE FROM modules WHERE uniqueID=?});
$sth->execute($uniqueID);
# insert new modules of fhem node
$sth = $dbh->prepare("INSERT INTO modules (uniqueID) VALUES (?)");
$sth->execute($uniqueID);
foreach (split(/\|/,$data{modules})) {
my ($k,$v) = split /:/;
checkColumn("modules",$k);
$sth = $dbh->prepare("UPDATE modules SET '$k'='$v' WHERE uniqueID='$uniqueID'");
$sth->execute();
}
if($data{models}) {
# delete old models of fhem node
$sth = $dbh->prepare(q{DELETE FROM models WHERE uniqueID=?});
$sth->execute($uniqueID);
# insert new modules of fhem node
$sth = $dbh->prepare("INSERT INTO models (uniqueID) VALUES (?)");
$sth->execute($uniqueID);
foreach (split(/\|/,$data{models})) {
my @models = split /,/;
foreach my $m (@models) {
checkColumn("models",$m);
$sth = $dbh->prepare("UPDATE models SET '$m'='1' WHERE uniqueID='$uniqueID'");
$sth->execute();
}
}
}
$sth->finish();
$dbh->disconnect();
return;
}
sub checkColumn($$) {
my ($t,$k) = @_;
# get table info
$sth = $dbh->prepare("PRAGMA table_info($t)");
$sth->execute();
# check if column exists
my @row;
my @match = ();
while (@row = $sth->fetchrow_array()) {
@match = grep { /\b$k\b/ } @row;
last if(@match != 0);
}
# create column if not exists
if(@match == 0) {
$sth = $dbh->prepare("ALTER TABLE $t ADD COLUMN '$k' INTEGER DEFAULT 0");
$sth->execute();
}
$sth->finish;
return;
}
sub getLocation($) {
my ($ip) = shift;
my $gi = Geo::IP->open($geoIPDat, GEOIP_STANDARD);
my $rec = $gi->record_by_addr($ip);
if(!$rec) {
return;
} else {
return (
$rec->country_code,$rec->country_code3,$rec->country_name,$rec->region,$rec->region_name,$rec->city,
$rec->latitude,$rec->longitude,$rec->time_zone,$rec->continent_code
);
}
}
1;