summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md13
-rw-r--r--cpanfile2
-rw-r--r--cpanfile.snapshot807
-rw-r--r--examples/travelynx.conf11
-rwxr-xr-xlib/Travelynx.pm1
-rw-r--r--lib/Travelynx/Controller/Account.pm12
-rwxr-xr-xlib/Travelynx/Controller/Traveling.pm13
-rw-r--r--lib/Travelynx/Helper/HAFAS.pm114
-rw-r--r--t/22-transit-visibility.t40
-rw-r--r--t/23-journey-visibility.t16
-rw-r--r--t/24-past-visibility.t16
-rw-r--r--templates/_checked_in.html.ep18
-rw-r--r--templates/_public_status_card.html.ep9
-rw-r--r--templates/about.html.ep13
-rw-r--r--templates/changelog.html.ep31
-rw-r--r--templates/select_backend.html.ep10
16 files changed, 610 insertions, 516 deletions
diff --git a/README.md b/README.md
index dd32d3b..07ac66e 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,15 @@ travelynx - Railway Travel Logger
---
[travelynx](https://finalrewind.org/projects/travelynx/) allows checking into
-and out of individual trains, thus providing a log of your railway journeys
-annotated with real-time delays and service messages. It supports german
-railways and trains exposed by the Deutsche Bahn [IRIS
+individual public transit vehicles (e.g. buses, ferries, trams, trains) across
+most of Germany, Switzerland, Austria, Luxembourg, Ireland, and parts of the
+USA. Thus, it provides a log of your railway journeys annotated with real-time
+delays and service messages, if available. It supports german railways and
+trains exposed by the Deutsche Bahn [IRIS
Interface](https://finalrewind.org/projects/Travel-Status-DE-IRIS/) as well as
-local transit and some trains outside of germany exposed by the Deutsche Bahn
-[HAFAS Interface](https://finalrewind.org/projects/Travel-Status-DE-DeutscheBahn/).
+regional and local transit exposed by supported [HAFAS
+Instances](https://finalrewind.org/projects/Travel-Status-DE-HAFAS/). Support
+for EFA instances and bahn.de is under way.
You can use the public instance on [travelynx.de](https://travelynx.de) or
host your own. See the Installation and Setup notes below.
diff --git a/cpanfile b/cpanfile
index 673b738..c230118 100644
--- a/cpanfile
+++ b/cpanfile
@@ -6,6 +6,8 @@ requires 'DateTime::Format::Strptime';
requires 'Email::Sender::Simple';
requires 'GIS::Distance';
requires 'GIS::Distance::Fast';
+requires 'IO::Socket::Socks', '>= 0.64';
+requires 'IO::Socket::SSL', '>= 2.009';
requires 'List::UtilsBy';
requires 'Math::Polygon';
requires 'MIME::Entity';
diff --git a/cpanfile.snapshot b/cpanfile.snapshot
index e71f91d..18ba180 100644
--- a/cpanfile.snapshot
+++ b/cpanfile.snapshot
@@ -382,8 +382,8 @@ DISTRIBUTIONS
Test::More 0.88
Time::HiRes 0
version 0
- DBI-1.645
- pathname: H/HM/HMBRAND/DBI-1.645.tgz
+ DBI-1.647
+ pathname: H/HM/HMBRAND/DBI-1.647.tgz
provides:
Bundle::DBI 12.008696
DBD::DBM 0.08
@@ -439,7 +439,7 @@ DISTRIBUTIONS
DBD::Sponge::dr 12.010003
DBD::Sponge::st 12.010003
DBDI 12.015129
- DBI 1.645
+ DBI 1.647
DBI::Const::GetInfo::ANSI 2.008697
DBI::Const::GetInfo::ODBC 2.011374
DBI::Const::GetInfoReturn 2.008697
@@ -479,7 +479,7 @@ DISTRIBUTIONS
DBI::SQL::Nano::Table_ 1.015544
DBI::Util::CacheMemory 0.010315
DBI::Util::_accessor 0.009479
- DBI::common 1.645
+ DBI::common 1.647
requirements:
ExtUtils::MakeMaker 6.48
Test::Simple 0.90
@@ -586,334 +586,334 @@ DISTRIBUTIONS
perl 5.008004
strict 0
warnings 0
- DateTime-TimeZone-2.63
- pathname: D/DR/DROLSKY/DateTime-TimeZone-2.63.tar.gz
- provides:
- DateTime::TimeZone 2.63
- DateTime::TimeZone::Africa::Abidjan 2.63
- DateTime::TimeZone::Africa::Algiers 2.63
- DateTime::TimeZone::Africa::Bissau 2.63
- DateTime::TimeZone::Africa::Cairo 2.63
- DateTime::TimeZone::Africa::Casablanca 2.63
- DateTime::TimeZone::Africa::Ceuta 2.63
- DateTime::TimeZone::Africa::El_Aaiun 2.63
- DateTime::TimeZone::Africa::Johannesburg 2.63
- DateTime::TimeZone::Africa::Juba 2.63
- DateTime::TimeZone::Africa::Khartoum 2.63
- DateTime::TimeZone::Africa::Lagos 2.63
- DateTime::TimeZone::Africa::Maputo 2.63
- DateTime::TimeZone::Africa::Monrovia 2.63
- DateTime::TimeZone::Africa::Nairobi 2.63
- DateTime::TimeZone::Africa::Ndjamena 2.63
- DateTime::TimeZone::Africa::Sao_Tome 2.63
- DateTime::TimeZone::Africa::Tripoli 2.63
- DateTime::TimeZone::Africa::Tunis 2.63
- DateTime::TimeZone::Africa::Windhoek 2.63
- DateTime::TimeZone::America::Adak 2.63
- DateTime::TimeZone::America::Anchorage 2.63
- DateTime::TimeZone::America::Araguaina 2.63
- DateTime::TimeZone::America::Argentina::Buenos_Aires 2.63
- DateTime::TimeZone::America::Argentina::Catamarca 2.63
- DateTime::TimeZone::America::Argentina::Cordoba 2.63
- DateTime::TimeZone::America::Argentina::Jujuy 2.63
- DateTime::TimeZone::America::Argentina::La_Rioja 2.63
- DateTime::TimeZone::America::Argentina::Mendoza 2.63
- DateTime::TimeZone::America::Argentina::Rio_Gallegos 2.63
- DateTime::TimeZone::America::Argentina::Salta 2.63
- DateTime::TimeZone::America::Argentina::San_Juan 2.63
- DateTime::TimeZone::America::Argentina::San_Luis 2.63
- DateTime::TimeZone::America::Argentina::Tucuman 2.63
- DateTime::TimeZone::America::Argentina::Ushuaia 2.63
- DateTime::TimeZone::America::Asuncion 2.63
- DateTime::TimeZone::America::Bahia 2.63
- DateTime::TimeZone::America::Bahia_Banderas 2.63
- DateTime::TimeZone::America::Barbados 2.63
- DateTime::TimeZone::America::Belem 2.63
- DateTime::TimeZone::America::Belize 2.63
- DateTime::TimeZone::America::Boa_Vista 2.63
- DateTime::TimeZone::America::Bogota 2.63
- DateTime::TimeZone::America::Boise 2.63
- DateTime::TimeZone::America::Cambridge_Bay 2.63
- DateTime::TimeZone::America::Campo_Grande 2.63
- DateTime::TimeZone::America::Cancun 2.63
- DateTime::TimeZone::America::Caracas 2.63
- DateTime::TimeZone::America::Cayenne 2.63
- DateTime::TimeZone::America::Chicago 2.63
- DateTime::TimeZone::America::Chihuahua 2.63
- DateTime::TimeZone::America::Ciudad_Juarez 2.63
- DateTime::TimeZone::America::Costa_Rica 2.63
- DateTime::TimeZone::America::Cuiaba 2.63
- DateTime::TimeZone::America::Danmarkshavn 2.63
- DateTime::TimeZone::America::Dawson 2.63
- DateTime::TimeZone::America::Dawson_Creek 2.63
- DateTime::TimeZone::America::Denver 2.63
- DateTime::TimeZone::America::Detroit 2.63
- DateTime::TimeZone::America::Edmonton 2.63
- DateTime::TimeZone::America::Eirunepe 2.63
- DateTime::TimeZone::America::El_Salvador 2.63
- DateTime::TimeZone::America::Fort_Nelson 2.63
- DateTime::TimeZone::America::Fortaleza 2.63
- DateTime::TimeZone::America::Glace_Bay 2.63
- DateTime::TimeZone::America::Goose_Bay 2.63
- DateTime::TimeZone::America::Grand_Turk 2.63
- DateTime::TimeZone::America::Guatemala 2.63
- DateTime::TimeZone::America::Guayaquil 2.63
- DateTime::TimeZone::America::Guyana 2.63
- DateTime::TimeZone::America::Halifax 2.63
- DateTime::TimeZone::America::Havana 2.63
- DateTime::TimeZone::America::Hermosillo 2.63
- DateTime::TimeZone::America::Indiana::Indianapolis 2.63
- DateTime::TimeZone::America::Indiana::Knox 2.63
- DateTime::TimeZone::America::Indiana::Marengo 2.63
- DateTime::TimeZone::America::Indiana::Petersburg 2.63
- DateTime::TimeZone::America::Indiana::Tell_City 2.63
- DateTime::TimeZone::America::Indiana::Vevay 2.63
- DateTime::TimeZone::America::Indiana::Vincennes 2.63
- DateTime::TimeZone::America::Indiana::Winamac 2.63
- DateTime::TimeZone::America::Inuvik 2.63
- DateTime::TimeZone::America::Iqaluit 2.63
- DateTime::TimeZone::America::Jamaica 2.63
- DateTime::TimeZone::America::Juneau 2.63
- DateTime::TimeZone::America::Kentucky::Louisville 2.63
- DateTime::TimeZone::America::Kentucky::Monticello 2.63
- DateTime::TimeZone::America::La_Paz 2.63
- DateTime::TimeZone::America::Lima 2.63
- DateTime::TimeZone::America::Los_Angeles 2.63
- DateTime::TimeZone::America::Maceio 2.63
- DateTime::TimeZone::America::Managua 2.63
- DateTime::TimeZone::America::Manaus 2.63
- DateTime::TimeZone::America::Martinique 2.63
- DateTime::TimeZone::America::Matamoros 2.63
- DateTime::TimeZone::America::Mazatlan 2.63
- DateTime::TimeZone::America::Menominee 2.63
- DateTime::TimeZone::America::Merida 2.63
- DateTime::TimeZone::America::Metlakatla 2.63
- DateTime::TimeZone::America::Mexico_City 2.63
- DateTime::TimeZone::America::Miquelon 2.63
- DateTime::TimeZone::America::Moncton 2.63
- DateTime::TimeZone::America::Monterrey 2.63
- DateTime::TimeZone::America::Montevideo 2.63
- DateTime::TimeZone::America::New_York 2.63
- DateTime::TimeZone::America::Nome 2.63
- DateTime::TimeZone::America::Noronha 2.63
- DateTime::TimeZone::America::North_Dakota::Beulah 2.63
- DateTime::TimeZone::America::North_Dakota::Center 2.63
- DateTime::TimeZone::America::North_Dakota::New_Salem 2.63
- DateTime::TimeZone::America::Nuuk 2.63
- DateTime::TimeZone::America::Ojinaga 2.63
- DateTime::TimeZone::America::Panama 2.63
- DateTime::TimeZone::America::Paramaribo 2.63
- DateTime::TimeZone::America::Phoenix 2.63
- DateTime::TimeZone::America::Port_au_Prince 2.63
- DateTime::TimeZone::America::Porto_Velho 2.63
- DateTime::TimeZone::America::Puerto_Rico 2.63
- DateTime::TimeZone::America::Punta_Arenas 2.63
- DateTime::TimeZone::America::Rankin_Inlet 2.63
- DateTime::TimeZone::America::Recife 2.63
- DateTime::TimeZone::America::Regina 2.63
- DateTime::TimeZone::America::Resolute 2.63
- DateTime::TimeZone::America::Rio_Branco 2.63
- DateTime::TimeZone::America::Santarem 2.63
- DateTime::TimeZone::America::Santiago 2.63
- DateTime::TimeZone::America::Santo_Domingo 2.63
- DateTime::TimeZone::America::Sao_Paulo 2.63
- DateTime::TimeZone::America::Scoresbysund 2.63
- DateTime::TimeZone::America::Sitka 2.63
- DateTime::TimeZone::America::St_Johns 2.63
- DateTime::TimeZone::America::Swift_Current 2.63
- DateTime::TimeZone::America::Tegucigalpa 2.63
- DateTime::TimeZone::America::Thule 2.63
- DateTime::TimeZone::America::Tijuana 2.63
- DateTime::TimeZone::America::Toronto 2.63
- DateTime::TimeZone::America::Vancouver 2.63
- DateTime::TimeZone::America::Whitehorse 2.63
- DateTime::TimeZone::America::Winnipeg 2.63
- DateTime::TimeZone::America::Yakutat 2.63
- DateTime::TimeZone::Antarctica::Casey 2.63
- DateTime::TimeZone::Antarctica::Davis 2.63
- DateTime::TimeZone::Antarctica::Macquarie 2.63
- DateTime::TimeZone::Antarctica::Mawson 2.63
- DateTime::TimeZone::Antarctica::Palmer 2.63
- DateTime::TimeZone::Antarctica::Rothera 2.63
- DateTime::TimeZone::Antarctica::Troll 2.63
- DateTime::TimeZone::Antarctica::Vostok 2.63
- DateTime::TimeZone::Asia::Almaty 2.63
- DateTime::TimeZone::Asia::Amman 2.63
- DateTime::TimeZone::Asia::Anadyr 2.63
- DateTime::TimeZone::Asia::Aqtau 2.63
- DateTime::TimeZone::Asia::Aqtobe 2.63
- DateTime::TimeZone::Asia::Ashgabat 2.63
- DateTime::TimeZone::Asia::Atyrau 2.63
- DateTime::TimeZone::Asia::Baghdad 2.63
- DateTime::TimeZone::Asia::Baku 2.63
- DateTime::TimeZone::Asia::Bangkok 2.63
- DateTime::TimeZone::Asia::Barnaul 2.63
- DateTime::TimeZone::Asia::Beirut 2.63
- DateTime::TimeZone::Asia::Bishkek 2.63
- DateTime::TimeZone::Asia::Chita 2.63
- DateTime::TimeZone::Asia::Colombo 2.63
- DateTime::TimeZone::Asia::Damascus 2.63
- DateTime::TimeZone::Asia::Dhaka 2.63
- DateTime::TimeZone::Asia::Dili 2.63
- DateTime::TimeZone::Asia::Dubai 2.63
- DateTime::TimeZone::Asia::Dushanbe 2.63
- DateTime::TimeZone::Asia::Famagusta 2.63
- DateTime::TimeZone::Asia::Gaza 2.63
- DateTime::TimeZone::Asia::Hebron 2.63
- DateTime::TimeZone::Asia::Ho_Chi_Minh 2.63
- DateTime::TimeZone::Asia::Hong_Kong 2.63
- DateTime::TimeZone::Asia::Hovd 2.63
- DateTime::TimeZone::Asia::Irkutsk 2.63
- DateTime::TimeZone::Asia::Jakarta 2.63
- DateTime::TimeZone::Asia::Jayapura 2.63
- DateTime::TimeZone::Asia::Jerusalem 2.63
- DateTime::TimeZone::Asia::Kabul 2.63
- DateTime::TimeZone::Asia::Kamchatka 2.63
- DateTime::TimeZone::Asia::Karachi 2.63
- DateTime::TimeZone::Asia::Kathmandu 2.63
- DateTime::TimeZone::Asia::Khandyga 2.63
- DateTime::TimeZone::Asia::Kolkata 2.63
- DateTime::TimeZone::Asia::Krasnoyarsk 2.63
- DateTime::TimeZone::Asia::Kuching 2.63
- DateTime::TimeZone::Asia::Macau 2.63
- DateTime::TimeZone::Asia::Magadan 2.63
- DateTime::TimeZone::Asia::Makassar 2.63
- DateTime::TimeZone::Asia::Manila 2.63
- DateTime::TimeZone::Asia::Nicosia 2.63
- DateTime::TimeZone::Asia::Novokuznetsk 2.63
- DateTime::TimeZone::Asia::Novosibirsk 2.63
- DateTime::TimeZone::Asia::Omsk 2.63
- DateTime::TimeZone::Asia::Oral 2.63
- DateTime::TimeZone::Asia::Pontianak 2.63
- DateTime::TimeZone::Asia::Pyongyang 2.63
- DateTime::TimeZone::Asia::Qatar 2.63
- DateTime::TimeZone::Asia::Qostanay 2.63
- DateTime::TimeZone::Asia::Qyzylorda 2.63
- DateTime::TimeZone::Asia::Riyadh 2.63
- DateTime::TimeZone::Asia::Sakhalin 2.63
- DateTime::TimeZone::Asia::Samarkand 2.63
- DateTime::TimeZone::Asia::Seoul 2.63
- DateTime::TimeZone::Asia::Shanghai 2.63
- DateTime::TimeZone::Asia::Singapore 2.63
- DateTime::TimeZone::Asia::Srednekolymsk 2.63
- DateTime::TimeZone::Asia::Taipei 2.63
- DateTime::TimeZone::Asia::Tashkent 2.63
- DateTime::TimeZone::Asia::Tbilisi 2.63
- DateTime::TimeZone::Asia::Tehran 2.63
- DateTime::TimeZone::Asia::Thimphu 2.63
- DateTime::TimeZone::Asia::Tokyo 2.63
- DateTime::TimeZone::Asia::Tomsk 2.63
- DateTime::TimeZone::Asia::Ulaanbaatar 2.63
- DateTime::TimeZone::Asia::Urumqi 2.63
- DateTime::TimeZone::Asia::Ust_Nera 2.63
- DateTime::TimeZone::Asia::Vladivostok 2.63
- DateTime::TimeZone::Asia::Yakutsk 2.63
- DateTime::TimeZone::Asia::Yangon 2.63
- DateTime::TimeZone::Asia::Yekaterinburg 2.63
- DateTime::TimeZone::Asia::Yerevan 2.63
- DateTime::TimeZone::Atlantic::Azores 2.63
- DateTime::TimeZone::Atlantic::Bermuda 2.63
- DateTime::TimeZone::Atlantic::Canary 2.63
- DateTime::TimeZone::Atlantic::Cape_Verde 2.63
- DateTime::TimeZone::Atlantic::Faroe 2.63
- DateTime::TimeZone::Atlantic::Madeira 2.63
- DateTime::TimeZone::Atlantic::South_Georgia 2.63
- DateTime::TimeZone::Atlantic::Stanley 2.63
- DateTime::TimeZone::Australia::Adelaide 2.63
- DateTime::TimeZone::Australia::Brisbane 2.63
- DateTime::TimeZone::Australia::Broken_Hill 2.63
- DateTime::TimeZone::Australia::Darwin 2.63
- DateTime::TimeZone::Australia::Eucla 2.63
- DateTime::TimeZone::Australia::Hobart 2.63
- DateTime::TimeZone::Australia::Lindeman 2.63
- DateTime::TimeZone::Australia::Lord_Howe 2.63
- DateTime::TimeZone::Australia::Melbourne 2.63
- DateTime::TimeZone::Australia::Perth 2.63
- DateTime::TimeZone::Australia::Sydney 2.63
- DateTime::TimeZone::Catalog 2.63
- DateTime::TimeZone::Europe::Andorra 2.63
- DateTime::TimeZone::Europe::Astrakhan 2.63
- DateTime::TimeZone::Europe::Athens 2.63
- DateTime::TimeZone::Europe::Belgrade 2.63
- DateTime::TimeZone::Europe::Berlin 2.63
- DateTime::TimeZone::Europe::Brussels 2.63
- DateTime::TimeZone::Europe::Bucharest 2.63
- DateTime::TimeZone::Europe::Budapest 2.63
- DateTime::TimeZone::Europe::Chisinau 2.63
- DateTime::TimeZone::Europe::Dublin 2.63
- DateTime::TimeZone::Europe::Gibraltar 2.63
- DateTime::TimeZone::Europe::Helsinki 2.63
- DateTime::TimeZone::Europe::Istanbul 2.63
- DateTime::TimeZone::Europe::Kaliningrad 2.63
- DateTime::TimeZone::Europe::Kirov 2.63
- DateTime::TimeZone::Europe::Kyiv 2.63
- DateTime::TimeZone::Europe::Lisbon 2.63
- DateTime::TimeZone::Europe::London 2.63
- DateTime::TimeZone::Europe::Madrid 2.63
- DateTime::TimeZone::Europe::Malta 2.63
- DateTime::TimeZone::Europe::Minsk 2.63
- DateTime::TimeZone::Europe::Moscow 2.63
- DateTime::TimeZone::Europe::Paris 2.63
- DateTime::TimeZone::Europe::Prague 2.63
- DateTime::TimeZone::Europe::Riga 2.63
- DateTime::TimeZone::Europe::Rome 2.63
- DateTime::TimeZone::Europe::Samara 2.63
- DateTime::TimeZone::Europe::Saratov 2.63
- DateTime::TimeZone::Europe::Simferopol 2.63
- DateTime::TimeZone::Europe::Sofia 2.63
- DateTime::TimeZone::Europe::Tallinn 2.63
- DateTime::TimeZone::Europe::Tirane 2.63
- DateTime::TimeZone::Europe::Ulyanovsk 2.63
- DateTime::TimeZone::Europe::Vienna 2.63
- DateTime::TimeZone::Europe::Vilnius 2.63
- DateTime::TimeZone::Europe::Volgograd 2.63
- DateTime::TimeZone::Europe::Warsaw 2.63
- DateTime::TimeZone::Europe::Zurich 2.63
- DateTime::TimeZone::Floating 2.63
- DateTime::TimeZone::Indian::Chagos 2.63
- DateTime::TimeZone::Indian::Maldives 2.63
- DateTime::TimeZone::Indian::Mauritius 2.63
- DateTime::TimeZone::Local 2.63
- DateTime::TimeZone::Local::Android 2.63
- DateTime::TimeZone::Local::Unix 2.63
- DateTime::TimeZone::Local::VMS 2.63
- DateTime::TimeZone::OffsetOnly 2.63
- DateTime::TimeZone::OlsonDB 2.63
- DateTime::TimeZone::OlsonDB::Change 2.63
- DateTime::TimeZone::OlsonDB::Observance 2.63
- DateTime::TimeZone::OlsonDB::Rule 2.63
- DateTime::TimeZone::OlsonDB::Zone 2.63
- DateTime::TimeZone::Pacific::Apia 2.63
- DateTime::TimeZone::Pacific::Auckland 2.63
- DateTime::TimeZone::Pacific::Bougainville 2.63
- DateTime::TimeZone::Pacific::Chatham 2.63
- DateTime::TimeZone::Pacific::Easter 2.63
- DateTime::TimeZone::Pacific::Efate 2.63
- DateTime::TimeZone::Pacific::Fakaofo 2.63
- DateTime::TimeZone::Pacific::Fiji 2.63
- DateTime::TimeZone::Pacific::Galapagos 2.63
- DateTime::TimeZone::Pacific::Gambier 2.63
- DateTime::TimeZone::Pacific::Guadalcanal 2.63
- DateTime::TimeZone::Pacific::Guam 2.63
- DateTime::TimeZone::Pacific::Honolulu 2.63
- DateTime::TimeZone::Pacific::Kanton 2.63
- DateTime::TimeZone::Pacific::Kiritimati 2.63
- DateTime::TimeZone::Pacific::Kosrae 2.63
- DateTime::TimeZone::Pacific::Kwajalein 2.63
- DateTime::TimeZone::Pacific::Marquesas 2.63
- DateTime::TimeZone::Pacific::Nauru 2.63
- DateTime::TimeZone::Pacific::Niue 2.63
- DateTime::TimeZone::Pacific::Norfolk 2.63
- DateTime::TimeZone::Pacific::Noumea 2.63
- DateTime::TimeZone::Pacific::Pago_Pago 2.63
- DateTime::TimeZone::Pacific::Palau 2.63
- DateTime::TimeZone::Pacific::Pitcairn 2.63
- DateTime::TimeZone::Pacific::Port_Moresby 2.63
- DateTime::TimeZone::Pacific::Rarotonga 2.63
- DateTime::TimeZone::Pacific::Tahiti 2.63
- DateTime::TimeZone::Pacific::Tarawa 2.63
- DateTime::TimeZone::Pacific::Tongatapu 2.63
- DateTime::TimeZone::UTC 2.63
+ DateTime-TimeZone-2.64
+ pathname: D/DR/DROLSKY/DateTime-TimeZone-2.64.tar.gz
+ provides:
+ DateTime::TimeZone 2.64
+ DateTime::TimeZone::Africa::Abidjan 2.64
+ DateTime::TimeZone::Africa::Algiers 2.64
+ DateTime::TimeZone::Africa::Bissau 2.64
+ DateTime::TimeZone::Africa::Cairo 2.64
+ DateTime::TimeZone::Africa::Casablanca 2.64
+ DateTime::TimeZone::Africa::Ceuta 2.64
+ DateTime::TimeZone::Africa::El_Aaiun 2.64
+ DateTime::TimeZone::Africa::Johannesburg 2.64
+ DateTime::TimeZone::Africa::Juba 2.64
+ DateTime::TimeZone::Africa::Khartoum 2.64
+ DateTime::TimeZone::Africa::Lagos 2.64
+ DateTime::TimeZone::Africa::Maputo 2.64
+ DateTime::TimeZone::Africa::Monrovia 2.64
+ DateTime::TimeZone::Africa::Nairobi 2.64
+ DateTime::TimeZone::Africa::Ndjamena 2.64
+ DateTime::TimeZone::Africa::Sao_Tome 2.64
+ DateTime::TimeZone::Africa::Tripoli 2.64
+ DateTime::TimeZone::Africa::Tunis 2.64
+ DateTime::TimeZone::Africa::Windhoek 2.64
+ DateTime::TimeZone::America::Adak 2.64
+ DateTime::TimeZone::America::Anchorage 2.64
+ DateTime::TimeZone::America::Araguaina 2.64
+ DateTime::TimeZone::America::Argentina::Buenos_Aires 2.64
+ DateTime::TimeZone::America::Argentina::Catamarca 2.64
+ DateTime::TimeZone::America::Argentina::Cordoba 2.64
+ DateTime::TimeZone::America::Argentina::Jujuy 2.64
+ DateTime::TimeZone::America::Argentina::La_Rioja 2.64
+ DateTime::TimeZone::America::Argentina::Mendoza 2.64
+ DateTime::TimeZone::America::Argentina::Rio_Gallegos 2.64
+ DateTime::TimeZone::America::Argentina::Salta 2.64
+ DateTime::TimeZone::America::Argentina::San_Juan 2.64
+ DateTime::TimeZone::America::Argentina::San_Luis 2.64
+ DateTime::TimeZone::America::Argentina::Tucuman 2.64
+ DateTime::TimeZone::America::Argentina::Ushuaia 2.64
+ DateTime::TimeZone::America::Asuncion 2.64
+ DateTime::TimeZone::America::Bahia 2.64
+ DateTime::TimeZone::America::Bahia_Banderas 2.64
+ DateTime::TimeZone::America::Barbados 2.64
+ DateTime::TimeZone::America::Belem 2.64
+ DateTime::TimeZone::America::Belize 2.64
+ DateTime::TimeZone::America::Boa_Vista 2.64
+ DateTime::TimeZone::America::Bogota 2.64
+ DateTime::TimeZone::America::Boise 2.64
+ DateTime::TimeZone::America::Cambridge_Bay 2.64
+ DateTime::TimeZone::America::Campo_Grande 2.64
+ DateTime::TimeZone::America::Cancun 2.64
+ DateTime::TimeZone::America::Caracas 2.64
+ DateTime::TimeZone::America::Cayenne 2.64
+ DateTime::TimeZone::America::Chicago 2.64
+ DateTime::TimeZone::America::Chihuahua 2.64
+ DateTime::TimeZone::America::Ciudad_Juarez 2.64
+ DateTime::TimeZone::America::Costa_Rica 2.64
+ DateTime::TimeZone::America::Cuiaba 2.64
+ DateTime::TimeZone::America::Danmarkshavn 2.64
+ DateTime::TimeZone::America::Dawson 2.64
+ DateTime::TimeZone::America::Dawson_Creek 2.64
+ DateTime::TimeZone::America::Denver 2.64
+ DateTime::TimeZone::America::Detroit 2.64
+ DateTime::TimeZone::America::Edmonton 2.64
+ DateTime::TimeZone::America::Eirunepe 2.64
+ DateTime::TimeZone::America::El_Salvador 2.64
+ DateTime::TimeZone::America::Fort_Nelson 2.64
+ DateTime::TimeZone::America::Fortaleza 2.64
+ DateTime::TimeZone::America::Glace_Bay 2.64
+ DateTime::TimeZone::America::Goose_Bay 2.64
+ DateTime::TimeZone::America::Grand_Turk 2.64
+ DateTime::TimeZone::America::Guatemala 2.64
+ DateTime::TimeZone::America::Guayaquil 2.64
+ DateTime::TimeZone::America::Guyana 2.64
+ DateTime::TimeZone::America::Halifax 2.64
+ DateTime::TimeZone::America::Havana 2.64
+ DateTime::TimeZone::America::Hermosillo 2.64
+ DateTime::TimeZone::America::Indiana::Indianapolis 2.64
+ DateTime::TimeZone::America::Indiana::Knox 2.64
+ DateTime::TimeZone::America::Indiana::Marengo 2.64
+ DateTime::TimeZone::America::Indiana::Petersburg 2.64
+ DateTime::TimeZone::America::Indiana::Tell_City 2.64
+ DateTime::TimeZone::America::Indiana::Vevay 2.64
+ DateTime::TimeZone::America::Indiana::Vincennes 2.64
+ DateTime::TimeZone::America::Indiana::Winamac 2.64
+ DateTime::TimeZone::America::Inuvik 2.64
+ DateTime::TimeZone::America::Iqaluit 2.64
+ DateTime::TimeZone::America::Jamaica 2.64
+ DateTime::TimeZone::America::Juneau 2.64
+ DateTime::TimeZone::America::Kentucky::Louisville 2.64
+ DateTime::TimeZone::America::Kentucky::Monticello 2.64
+ DateTime::TimeZone::America::La_Paz 2.64
+ DateTime::TimeZone::America::Lima 2.64
+ DateTime::TimeZone::America::Los_Angeles 2.64
+ DateTime::TimeZone::America::Maceio 2.64
+ DateTime::TimeZone::America::Managua 2.64
+ DateTime::TimeZone::America::Manaus 2.64
+ DateTime::TimeZone::America::Martinique 2.64
+ DateTime::TimeZone::America::Matamoros 2.64
+ DateTime::TimeZone::America::Mazatlan 2.64
+ DateTime::TimeZone::America::Menominee 2.64
+ DateTime::TimeZone::America::Merida 2.64
+ DateTime::TimeZone::America::Metlakatla 2.64
+ DateTime::TimeZone::America::Mexico_City 2.64
+ DateTime::TimeZone::America::Miquelon 2.64
+ DateTime::TimeZone::America::Moncton 2.64
+ DateTime::TimeZone::America::Monterrey 2.64
+ DateTime::TimeZone::America::Montevideo 2.64
+ DateTime::TimeZone::America::New_York 2.64
+ DateTime::TimeZone::America::Nome 2.64
+ DateTime::TimeZone::America::Noronha 2.64
+ DateTime::TimeZone::America::North_Dakota::Beulah 2.64
+ DateTime::TimeZone::America::North_Dakota::Center 2.64
+ DateTime::TimeZone::America::North_Dakota::New_Salem 2.64
+ DateTime::TimeZone::America::Nuuk 2.64
+ DateTime::TimeZone::America::Ojinaga 2.64
+ DateTime::TimeZone::America::Panama 2.64
+ DateTime::TimeZone::America::Paramaribo 2.64
+ DateTime::TimeZone::America::Phoenix 2.64
+ DateTime::TimeZone::America::Port_au_Prince 2.64
+ DateTime::TimeZone::America::Porto_Velho 2.64
+ DateTime::TimeZone::America::Puerto_Rico 2.64
+ DateTime::TimeZone::America::Punta_Arenas 2.64
+ DateTime::TimeZone::America::Rankin_Inlet 2.64
+ DateTime::TimeZone::America::Recife 2.64
+ DateTime::TimeZone::America::Regina 2.64
+ DateTime::TimeZone::America::Resolute 2.64
+ DateTime::TimeZone::America::Rio_Branco 2.64
+ DateTime::TimeZone::America::Santarem 2.64
+ DateTime::TimeZone::America::Santiago 2.64
+ DateTime::TimeZone::America::Santo_Domingo 2.64
+ DateTime::TimeZone::America::Sao_Paulo 2.64
+ DateTime::TimeZone::America::Scoresbysund 2.64
+ DateTime::TimeZone::America::Sitka 2.64
+ DateTime::TimeZone::America::St_Johns 2.64
+ DateTime::TimeZone::America::Swift_Current 2.64
+ DateTime::TimeZone::America::Tegucigalpa 2.64
+ DateTime::TimeZone::America::Thule 2.64
+ DateTime::TimeZone::America::Tijuana 2.64
+ DateTime::TimeZone::America::Toronto 2.64
+ DateTime::TimeZone::America::Vancouver 2.64
+ DateTime::TimeZone::America::Whitehorse 2.64
+ DateTime::TimeZone::America::Winnipeg 2.64
+ DateTime::TimeZone::America::Yakutat 2.64
+ DateTime::TimeZone::Antarctica::Casey 2.64
+ DateTime::TimeZone::Antarctica::Davis 2.64
+ DateTime::TimeZone::Antarctica::Macquarie 2.64
+ DateTime::TimeZone::Antarctica::Mawson 2.64
+ DateTime::TimeZone::Antarctica::Palmer 2.64
+ DateTime::TimeZone::Antarctica::Rothera 2.64
+ DateTime::TimeZone::Antarctica::Troll 2.64
+ DateTime::TimeZone::Antarctica::Vostok 2.64
+ DateTime::TimeZone::Asia::Almaty 2.64
+ DateTime::TimeZone::Asia::Amman 2.64
+ DateTime::TimeZone::Asia::Anadyr 2.64
+ DateTime::TimeZone::Asia::Aqtau 2.64
+ DateTime::TimeZone::Asia::Aqtobe 2.64
+ DateTime::TimeZone::Asia::Ashgabat 2.64
+ DateTime::TimeZone::Asia::Atyrau 2.64
+ DateTime::TimeZone::Asia::Baghdad 2.64
+ DateTime::TimeZone::Asia::Baku 2.64
+ DateTime::TimeZone::Asia::Bangkok 2.64
+ DateTime::TimeZone::Asia::Barnaul 2.64
+ DateTime::TimeZone::Asia::Beirut 2.64
+ DateTime::TimeZone::Asia::Bishkek 2.64
+ DateTime::TimeZone::Asia::Chita 2.64
+ DateTime::TimeZone::Asia::Colombo 2.64
+ DateTime::TimeZone::Asia::Damascus 2.64
+ DateTime::TimeZone::Asia::Dhaka 2.64
+ DateTime::TimeZone::Asia::Dili 2.64
+ DateTime::TimeZone::Asia::Dubai 2.64
+ DateTime::TimeZone::Asia::Dushanbe 2.64
+ DateTime::TimeZone::Asia::Famagusta 2.64
+ DateTime::TimeZone::Asia::Gaza 2.64
+ DateTime::TimeZone::Asia::Hebron 2.64
+ DateTime::TimeZone::Asia::Ho_Chi_Minh 2.64
+ DateTime::TimeZone::Asia::Hong_Kong 2.64
+ DateTime::TimeZone::Asia::Hovd 2.64
+ DateTime::TimeZone::Asia::Irkutsk 2.64
+ DateTime::TimeZone::Asia::Jakarta 2.64
+ DateTime::TimeZone::Asia::Jayapura 2.64
+ DateTime::TimeZone::Asia::Jerusalem 2.64
+ DateTime::TimeZone::Asia::Kabul 2.64
+ DateTime::TimeZone::Asia::Kamchatka 2.64
+ DateTime::TimeZone::Asia::Karachi 2.64
+ DateTime::TimeZone::Asia::Kathmandu 2.64
+ DateTime::TimeZone::Asia::Khandyga 2.64
+ DateTime::TimeZone::Asia::Kolkata 2.64
+ DateTime::TimeZone::Asia::Krasnoyarsk 2.64
+ DateTime::TimeZone::Asia::Kuching 2.64
+ DateTime::TimeZone::Asia::Macau 2.64
+ DateTime::TimeZone::Asia::Magadan 2.64
+ DateTime::TimeZone::Asia::Makassar 2.64
+ DateTime::TimeZone::Asia::Manila 2.64
+ DateTime::TimeZone::Asia::Nicosia 2.64
+ DateTime::TimeZone::Asia::Novokuznetsk 2.64
+ DateTime::TimeZone::Asia::Novosibirsk 2.64
+ DateTime::TimeZone::Asia::Omsk 2.64
+ DateTime::TimeZone::Asia::Oral 2.64
+ DateTime::TimeZone::Asia::Pontianak 2.64
+ DateTime::TimeZone::Asia::Pyongyang 2.64
+ DateTime::TimeZone::Asia::Qatar 2.64
+ DateTime::TimeZone::Asia::Qostanay 2.64
+ DateTime::TimeZone::Asia::Qyzylorda 2.64
+ DateTime::TimeZone::Asia::Riyadh 2.64
+ DateTime::TimeZone::Asia::Sakhalin 2.64
+ DateTime::TimeZone::Asia::Samarkand 2.64
+ DateTime::TimeZone::Asia::Seoul 2.64
+ DateTime::TimeZone::Asia::Shanghai 2.64
+ DateTime::TimeZone::Asia::Singapore 2.64
+ DateTime::TimeZone::Asia::Srednekolymsk 2.64
+ DateTime::TimeZone::Asia::Taipei 2.64
+ DateTime::TimeZone::Asia::Tashkent 2.64
+ DateTime::TimeZone::Asia::Tbilisi 2.64
+ DateTime::TimeZone::Asia::Tehran 2.64
+ DateTime::TimeZone::Asia::Thimphu 2.64
+ DateTime::TimeZone::Asia::Tokyo 2.64
+ DateTime::TimeZone::Asia::Tomsk 2.64
+ DateTime::TimeZone::Asia::Ulaanbaatar 2.64
+ DateTime::TimeZone::Asia::Urumqi 2.64
+ DateTime::TimeZone::Asia::Ust_Nera 2.64
+ DateTime::TimeZone::Asia::Vladivostok 2.64
+ DateTime::TimeZone::Asia::Yakutsk 2.64
+ DateTime::TimeZone::Asia::Yangon 2.64
+ DateTime::TimeZone::Asia::Yekaterinburg 2.64
+ DateTime::TimeZone::Asia::Yerevan 2.64
+ DateTime::TimeZone::Atlantic::Azores 2.64
+ DateTime::TimeZone::Atlantic::Bermuda 2.64
+ DateTime::TimeZone::Atlantic::Canary 2.64
+ DateTime::TimeZone::Atlantic::Cape_Verde 2.64
+ DateTime::TimeZone::Atlantic::Faroe 2.64
+ DateTime::TimeZone::Atlantic::Madeira 2.64
+ DateTime::TimeZone::Atlantic::South_Georgia 2.64
+ DateTime::TimeZone::Atlantic::Stanley 2.64
+ DateTime::TimeZone::Australia::Adelaide 2.64
+ DateTime::TimeZone::Australia::Brisbane 2.64
+ DateTime::TimeZone::Australia::Broken_Hill 2.64
+ DateTime::TimeZone::Australia::Darwin 2.64
+ DateTime::TimeZone::Australia::Eucla 2.64
+ DateTime::TimeZone::Australia::Hobart 2.64
+ DateTime::TimeZone::Australia::Lindeman 2.64
+ DateTime::TimeZone::Australia::Lord_Howe 2.64
+ DateTime::TimeZone::Australia::Melbourne 2.64
+ DateTime::TimeZone::Australia::Perth 2.64
+ DateTime::TimeZone::Australia::Sydney 2.64
+ DateTime::TimeZone::Catalog 2.64
+ DateTime::TimeZone::Europe::Andorra 2.64
+ DateTime::TimeZone::Europe::Astrakhan 2.64
+ DateTime::TimeZone::Europe::Athens 2.64
+ DateTime::TimeZone::Europe::Belgrade 2.64
+ DateTime::TimeZone::Europe::Berlin 2.64
+ DateTime::TimeZone::Europe::Brussels 2.64
+ DateTime::TimeZone::Europe::Bucharest 2.64
+ DateTime::TimeZone::Europe::Budapest 2.64
+ DateTime::TimeZone::Europe::Chisinau 2.64
+ DateTime::TimeZone::Europe::Dublin 2.64
+ DateTime::TimeZone::Europe::Gibraltar 2.64
+ DateTime::TimeZone::Europe::Helsinki 2.64
+ DateTime::TimeZone::Europe::Istanbul 2.64
+ DateTime::TimeZone::Europe::Kaliningrad 2.64
+ DateTime::TimeZone::Europe::Kirov 2.64
+ DateTime::TimeZone::Europe::Kyiv 2.64
+ DateTime::TimeZone::Europe::Lisbon 2.64
+ DateTime::TimeZone::Europe::London 2.64
+ DateTime::TimeZone::Europe::Madrid 2.64
+ DateTime::TimeZone::Europe::Malta 2.64
+ DateTime::TimeZone::Europe::Minsk 2.64
+ DateTime::TimeZone::Europe::Moscow 2.64
+ DateTime::TimeZone::Europe::Paris 2.64
+ DateTime::TimeZone::Europe::Prague 2.64
+ DateTime::TimeZone::Europe::Riga 2.64
+ DateTime::TimeZone::Europe::Rome 2.64
+ DateTime::TimeZone::Europe::Samara 2.64
+ DateTime::TimeZone::Europe::Saratov 2.64
+ DateTime::TimeZone::Europe::Simferopol 2.64
+ DateTime::TimeZone::Europe::Sofia 2.64
+ DateTime::TimeZone::Europe::Tallinn 2.64
+ DateTime::TimeZone::Europe::Tirane 2.64
+ DateTime::TimeZone::Europe::Ulyanovsk 2.64
+ DateTime::TimeZone::Europe::Vienna 2.64
+ DateTime::TimeZone::Europe::Vilnius 2.64
+ DateTime::TimeZone::Europe::Volgograd 2.64
+ DateTime::TimeZone::Europe::Warsaw 2.64
+ DateTime::TimeZone::Europe::Zurich 2.64
+ DateTime::TimeZone::Floating 2.64
+ DateTime::TimeZone::Indian::Chagos 2.64
+ DateTime::TimeZone::Indian::Maldives 2.64
+ DateTime::TimeZone::Indian::Mauritius 2.64
+ DateTime::TimeZone::Local 2.64
+ DateTime::TimeZone::Local::Android 2.64
+ DateTime::TimeZone::Local::Unix 2.64
+ DateTime::TimeZone::Local::VMS 2.64
+ DateTime::TimeZone::OffsetOnly 2.64
+ DateTime::TimeZone::OlsonDB 2.64
+ DateTime::TimeZone::OlsonDB::Change 2.64
+ DateTime::TimeZone::OlsonDB::Observance 2.64
+ DateTime::TimeZone::OlsonDB::Rule 2.64
+ DateTime::TimeZone::OlsonDB::Zone 2.64
+ DateTime::TimeZone::Pacific::Apia 2.64
+ DateTime::TimeZone::Pacific::Auckland 2.64
+ DateTime::TimeZone::Pacific::Bougainville 2.64
+ DateTime::TimeZone::Pacific::Chatham 2.64
+ DateTime::TimeZone::Pacific::Easter 2.64
+ DateTime::TimeZone::Pacific::Efate 2.64
+ DateTime::TimeZone::Pacific::Fakaofo 2.64
+ DateTime::TimeZone::Pacific::Fiji 2.64
+ DateTime::TimeZone::Pacific::Galapagos 2.64
+ DateTime::TimeZone::Pacific::Gambier 2.64
+ DateTime::TimeZone::Pacific::Guadalcanal 2.64
+ DateTime::TimeZone::Pacific::Guam 2.64
+ DateTime::TimeZone::Pacific::Honolulu 2.64
+ DateTime::TimeZone::Pacific::Kanton 2.64
+ DateTime::TimeZone::Pacific::Kiritimati 2.64
+ DateTime::TimeZone::Pacific::Kosrae 2.64
+ DateTime::TimeZone::Pacific::Kwajalein 2.64
+ DateTime::TimeZone::Pacific::Marquesas 2.64
+ DateTime::TimeZone::Pacific::Nauru 2.64
+ DateTime::TimeZone::Pacific::Niue 2.64
+ DateTime::TimeZone::Pacific::Norfolk 2.64
+ DateTime::TimeZone::Pacific::Noumea 2.64
+ DateTime::TimeZone::Pacific::Pago_Pago 2.64
+ DateTime::TimeZone::Pacific::Palau 2.64
+ DateTime::TimeZone::Pacific::Pitcairn 2.64
+ DateTime::TimeZone::Pacific::Port_Moresby 2.64
+ DateTime::TimeZone::Pacific::Rarotonga 2.64
+ DateTime::TimeZone::Pacific::Tahiti 2.64
+ DateTime::TimeZone::Pacific::Tarawa 2.64
+ DateTime::TimeZone::Pacific::Tongatapu 2.64
+ DateTime::TimeZone::UTC 2.64
requirements:
Class::Singleton 1.03
Cwd 3
@@ -1460,6 +1460,20 @@ DISTRIBUTIONS
ExtUtils::MakeMaker 0
Net::SSLeay 1.46
Scalar::Util 0
+ IO-Socket-Socks-0.74
+ pathname: O/OL/OLEG/IO-Socket-Socks-0.74.tar.gz
+ provides:
+ IO::Socket::Socks 0.74
+ IO::Socket::Socks::Debug 0.74
+ IO::Socket::Socks::Error 0.74
+ IO::Socket::Socks::ReadOnlyVar 0.74
+ IO::Socket::Socks::SocketClassVar 0.74
+ requirements:
+ ExtUtils::MakeMaker 6.52
+ IO::Select 0
+ Socket 1.94
+ Test::More 0.88
+ constant 1.03
IO-String-1.08
pathname: G/GA/GAAS/IO-String-1.08.tar.gz
provides:
@@ -1742,11 +1756,11 @@ DISTRIBUTIONS
Try::Tiny 0
strict 0
warnings 0
- Module-Pluggable-6.2
- pathname: S/SI/SIMONW/Module-Pluggable-6.2.tar.gz
+ Module-Pluggable-6.3
+ pathname: S/SI/SIMONW/Module-Pluggable-6.3.tar.gz
provides:
Devel::InnerPackage 0.4
- Module::Pluggable 6.2
+ Module::Pluggable 6.3
Module::Pluggable::Object 5.2
requirements:
Exporter 5.57
@@ -2142,52 +2156,53 @@ DISTRIBUTIONS
ExtUtils::MakeMaker 0
SQL::Abstract 2.0
perl 5.016
- Specio-0.48
- pathname: D/DR/DROLSKY/Specio-0.48.tar.gz
- provides:
- Specio 0.48
- Specio::Coercion 0.48
- Specio::Constraint::AnyCan 0.48
- Specio::Constraint::AnyDoes 0.48
- Specio::Constraint::AnyIsa 0.48
- Specio::Constraint::Enum 0.48
- Specio::Constraint::Intersection 0.48
- Specio::Constraint::ObjectCan 0.48
- Specio::Constraint::ObjectDoes 0.48
- Specio::Constraint::ObjectIsa 0.48
- Specio::Constraint::Parameterizable 0.48
- Specio::Constraint::Parameterized 0.48
- Specio::Constraint::Role::CanType 0.48
- Specio::Constraint::Role::DoesType 0.48
- Specio::Constraint::Role::Interface 0.48
- Specio::Constraint::Role::IsaType 0.48
- Specio::Constraint::Simple 0.48
- Specio::Constraint::Structurable 0.48
- Specio::Constraint::Structured 0.48
- Specio::Constraint::Union 0.48
- Specio::Declare 0.48
- Specio::DeclaredAt 0.48
- Specio::Exception 0.48
- Specio::Exporter 0.48
- Specio::Helpers 0.48
- Specio::Library::Builtins 0.48
- Specio::Library::Numeric 0.48
- Specio::Library::Perl 0.48
- Specio::Library::String 0.48
- Specio::Library::Structured 0.48
- Specio::Library::Structured::Dict 0.48
- Specio::Library::Structured::Map 0.48
- Specio::Library::Structured::Tuple 0.48
- Specio::OO 0.48
- Specio::PartialDump 0.48
- Specio::Registry 0.48
- Specio::Role::Inlinable 0.48
- Specio::Subs 0.48
- Specio::TypeChecks 0.48
- Test::Specio 0.48
+ Specio-0.49
+ pathname: D/DR/DROLSKY/Specio-0.49.tar.gz
+ provides:
+ Specio 0.49
+ Specio::Coercion 0.49
+ Specio::Constraint::AnyCan 0.49
+ Specio::Constraint::AnyDoes 0.49
+ Specio::Constraint::AnyIsa 0.49
+ Specio::Constraint::Enum 0.49
+ Specio::Constraint::Intersection 0.49
+ Specio::Constraint::ObjectCan 0.49
+ Specio::Constraint::ObjectDoes 0.49
+ Specio::Constraint::ObjectIsa 0.49
+ Specio::Constraint::Parameterizable 0.49
+ Specio::Constraint::Parameterized 0.49
+ Specio::Constraint::Role::CanType 0.49
+ Specio::Constraint::Role::DoesType 0.49
+ Specio::Constraint::Role::Interface 0.49
+ Specio::Constraint::Role::IsaType 0.49
+ Specio::Constraint::Simple 0.49
+ Specio::Constraint::Structurable 0.49
+ Specio::Constraint::Structured 0.49
+ Specio::Constraint::Union 0.49
+ Specio::Declare 0.49
+ Specio::DeclaredAt 0.49
+ Specio::Exception 0.49
+ Specio::Exporter 0.49
+ Specio::Helpers 0.49
+ Specio::Library::Builtins 0.49
+ Specio::Library::Numeric 0.49
+ Specio::Library::Perl 0.49
+ Specio::Library::String 0.49
+ Specio::Library::Structured 0.49
+ Specio::Library::Structured::Dict 0.49
+ Specio::Library::Structured::Map 0.49
+ Specio::Library::Structured::Tuple 0.49
+ Specio::OO 0.49
+ Specio::PartialDump 0.49
+ Specio::Registry 0.49
+ Specio::Role::Inlinable 0.49
+ Specio::Subs 0.49
+ Specio::TypeChecks 0.49
+ Test::Specio 0.49
requirements:
B 0
Carp 0
+ Clone 0
Devel::StackTrace 0
Eval::Closure 0
Exporter 0
@@ -2199,7 +2214,6 @@ DISTRIBUTIONS
Role::Tiny 1.003003
Role::Tiny::With 0
Scalar::Util 0
- Storable 0
Sub::Quote 0
Test::Fatal 0
Test::More 0.96
@@ -2397,12 +2411,12 @@ DISTRIBUTIONS
Test::Builder::Tester 1.02
Test::More 0.62
perl 5.008
- Text-CSV-2.04
- pathname: I/IS/ISHIGAKI/Text-CSV-2.04.tar.gz
+ Text-CSV-2.05
+ pathname: I/IS/ISHIGAKI/Text-CSV-2.05.tar.gz
provides:
- Text::CSV 2.04
- Text::CSV::ErrorDiag 2.04
- Text::CSV_PP 2.04
+ Text::CSV 2.05
+ Text::CSV::ErrorDiag 2.05
+ Text::CSV_PP 2.05
requirements:
ExtUtils::MakeMaker 0
IO::Handle 0
@@ -2552,19 +2566,18 @@ DISTRIBUTIONS
Test::Pod 0
Travel::Status::DE::IRIS 1.2
perl v5.20.0
- Travel-Status-DE-DeutscheBahn-6.15
- pathname: D/DE/DERF/Travel-Status-DE-DeutscheBahn-6.15.tar.gz
- provides:
- Travel::Status::DE::DeutscheBahn 6.15
- Travel::Status::DE::HAFAS 6.15
- Travel::Status::DE::HAFAS::Journey 6.15
- Travel::Status::DE::HAFAS::Location 6.15
- Travel::Status::DE::HAFAS::Message 6.15
- Travel::Status::DE::HAFAS::Polyline 6.15
- Travel::Status::DE::HAFAS::Product 6.15
- Travel::Status::DE::HAFAS::Services 6.15
- Travel::Status::DE::HAFAS::Stop 6.15
- Travel::Status::DE::HAFAS::StopFinder 6.15
+ Travel-Status-DE-HAFAS-6.18
+ pathname: D/DE/DERF/Travel-Status-DE-HAFAS-6.18.tar.gz
+ provides:
+ Travel::Status::DE::HAFAS 6.18
+ Travel::Status::DE::HAFAS::Journey 6.18
+ Travel::Status::DE::HAFAS::Location 6.18
+ Travel::Status::DE::HAFAS::Message 6.18
+ Travel::Status::DE::HAFAS::Polyline 6.18
+ Travel::Status::DE::HAFAS::Product 6.18
+ Travel::Status::DE::HAFAS::Services 6.18
+ Travel::Status::DE::HAFAS::Stop 6.18
+ Travel::Status::DE::HAFAS::StopFinder 6.18
requirements:
Carp 0
Class::Accessor 0.16
diff --git a/examples/travelynx.conf b/examples/travelynx.conf
index f8eaac0..c7c4f89 100644
--- a/examples/travelynx.conf
+++ b/examples/travelynx.conf
@@ -35,6 +35,17 @@
password => die("Changeme!"),
},
+ # Settings specific to HAFAS backends.
+ # For instance, the PKP backend is hidden behind a GeoIP filter, hence
+ # travelynx only supports it if travelynx.conf either indicates that it
+ # is reachable or specifies a proxy.
+ hafas => {
+ PKP => {
+ # geoip_ok => 1, # <- EITHER THIS
+ # proxy => 'socks://...', # <- OR THIS
+ },
+ },
+
# These settings control the amount and (re)spawn behaviour of travelynx
# worker processes as well as IP, port, and PID file. They are suitable for
# up to a few dozen concurrent users. If your site has more traffic, you
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index c73f96d..32d1e2f 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -221,6 +221,7 @@ sub startup {
my ($self) = @_;
state $hafas = Travelynx::Helper::HAFAS->new(
log => $self->app->log,
+ service_config => $self->app->config->{hafas},
main_cache => $self->app->cache_iris_main,
realtime_cache => $self->app->cache_iris_rt,
root_url => $self->base_url_for('/')->to_abs,
diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm
index 8a21ffa..9cd0edb 100644
--- a/lib/Travelynx/Controller/Account.pm
+++ b/lib/Travelynx/Controller/Account.pm
@@ -1075,10 +1075,22 @@ sub backend_form {
# operational and are thus useless for travelynx
if ( $backend->{name} eq 'Resrobot'
or $backend->{name} eq 'TPG'
+ or $backend->{name} eq 'VRN'
or $backend->{name} eq 'DB' )
{
$type = undef;
}
+
+ # PKP is behind a GeoIP filter. Only list it if travelynx.conf
+ # indicates that our IP is allowed or provides a proxy.
+ elsif (
+ $backend->{name} eq 'PKP'
+ and not( $self->app->config->{hafas}{PKP}{geoip_ok}
+ or $self->app->config->{hafas}{PKP}{proxy} )
+ )
+ {
+ $type = undef;
+ }
elsif ( my $s = $self->hafas->get_service( $backend->{name} ) ) {
$type = 'HAFAS';
$backend->{longname} = $s->{name};
diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm
index a0ae43b..1ca9d4a 100755
--- a/lib/Travelynx/Controller/Traveling.pm
+++ b/lib/Travelynx/Controller/Traveling.pm
@@ -10,6 +10,7 @@ use DateTime::Format::Strptime;
use List::Util qw(uniq min max);
use List::UtilsBy qw(max_by uniq_by);
use List::MoreUtils qw(first_index);
+use Mojo::UserAgent;
use Mojo::Promise;
use Text::CSV;
use Travel::Status::DE::IRIS::Stations;
@@ -529,9 +530,16 @@ sub geolocation {
if ($hafas_service) {
$self->render_later;
+ my $agent = $self->ua;
+ if ( my $proxy = $self->app->config->{hafas}{$hafas_service}{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
promise => 'Mojo::Promise',
- user_agent => $self->ua,
+ user_agent => $agent,
service => $hafas_service,
geoSearch => {
lat => $lat,
@@ -1132,7 +1140,8 @@ sub station {
)->wait;
}
elsif ( $err
- =~ m{svcRes|connection close|Service Temporarily Unavailable} )
+ =~ m{svcRes|connection close|Service Temporarily Unavailable|Forbidden}
+ )
{
$self->render(
'bad_gateway',
diff --git a/lib/Travelynx/Helper/HAFAS.pm b/lib/Travelynx/Helper/HAFAS.pm
index 207fadb..ebf44d2 100644
--- a/lib/Travelynx/Helper/HAFAS.pm
+++ b/lib/Travelynx/Helper/HAFAS.pm
@@ -7,11 +7,13 @@ package Travelynx::Helper::HAFAS;
use strict;
use warnings;
use 5.020;
+use utf8;
use DateTime;
use Encode qw(decode);
use JSON;
use Mojo::Promise;
+use Mojo::UserAgent;
use Travel::Status::DE::HAFAS;
sub _epoch {
@@ -39,84 +41,53 @@ sub get_service {
return Travel::Status::DE::HAFAS::get_service($service);
}
-sub get_json_p {
- my ( $self, $url, %opt ) = @_;
-
- my $cache = $self->{main_cache};
- my $promise = Mojo::Promise->new;
+sub get_departures_p {
+ my ( $self, %opt ) = @_;
- if ( $opt{realtime} ) {
- $cache = $self->{realtime_cache};
- }
- $opt{encoding} //= 'ISO-8859-15';
+ $opt{service} //= 'ÖBB';
- if ( my $content = $cache->thaw($url) ) {
- return $promise->resolve($content);
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
}
- $self->{user_agent}->request_timeout(5)->get_p( $url => $self->{header} )
- ->then(
- sub {
- my ($tx) = @_;
-
- if ( my $err = $tx->error ) {
- $promise->reject(
-"hafas->get_json_p($url) returned HTTP $err->{code} $err->{message}"
- );
- return;
- }
-
- my $body = decode( $opt{encoding}, $tx->res->body );
-
- $body =~ s{^TSLs[.]sls = }{};
- $body =~ s{;$}{};
- $body =~ s{&#x0028;}{(}g;
- $body =~ s{&#x0029;}{)}g;
- my $json = JSON->new->decode($body);
- $cache->freeze( $url, $json );
- $promise->resolve($json);
- return;
- }
- )->catch(
- sub {
- my ($err) = @_;
- $self->{log}->info("hafas->get_json_p($url): $err");
- $promise->reject("hafas->get_json_p($url): $err");
- return;
- }
- )->wait;
- return $promise;
-}
-
-sub get_departures_p {
- my ( $self, %opt ) = @_;
-
my $when = (
$opt{timestamp}
? $opt{timestamp}->clone
: DateTime->now( time_zone => 'Europe/Berlin' )
)->subtract( minutes => $opt{lookbehind} );
return Travel::Status::DE::HAFAS->new_p(
- service => $opt{service} // 'VRN',
+ service => $opt{service},
station => $opt{eva},
datetime => $when,
lookahead => $opt{lookahead} + $opt{lookbehind},
results => 300,
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(5),
+ user_agent => $agent->request_timeout(5),
);
}
sub search_location_p {
my ( $self, %opt ) = @_;
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
return Travel::Status::DE::HAFAS->new_p(
- service => $opt{service} // 'VRN',
+ service => $opt{service},
locationSearch => $opt{query},
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(5),
+ user_agent => $agent->request_timeout(5),
);
}
@@ -129,13 +100,22 @@ sub get_tripid_p {
my $train_desc = $train->type . ' ' . $train->train_no;
$train_desc =~ s{^- }{};
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
- service => $opt{service} // 'VRN',
+ service => $opt{service},
journeyMatch => $train_desc,
datetime => $train->start,
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(10),
+ user_agent => $agent->request_timeout(10),
)->then(
sub {
my ($hafas) = @_;
@@ -181,15 +161,24 @@ sub get_journey_p {
my $promise = Mojo::Promise->new;
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
- service => $opt{service} // 'VRN',
+ service => $opt{service},
journey => {
id => $opt{trip_id},
},
with_polyline => $opt{with_polyline},
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(10),
+ user_agent => $agent->request_timeout(10),
)->then(
sub {
my ($hafas) = @_;
@@ -222,8 +211,17 @@ sub get_route_p {
my $promise = Mojo::Promise->new;
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
+ $opt{service} //= 'ÖBB';
+
+ my $agent = $self->{user_agent};
+ if ( my $proxy = $self->{service_config}{ $opt{service} }{proxy} ) {
+ $agent = Mojo::UserAgent->new;
+ $agent->proxy->http($proxy);
+ $agent->proxy->https($proxy);
+ }
+
Travel::Status::DE::HAFAS->new_p(
- service => $opt{service} // 'VRN',
+ service => $opt{service},
journey => {
id => $opt{trip_id},
@@ -232,7 +230,7 @@ sub get_route_p {
with_polyline => $opt{with_polyline},
cache => $self->{realtime_cache},
promise => 'Mojo::Promise',
- user_agent => $self->{user_agent}->request_timeout(10),
+ user_agent => $agent->request_timeout(10),
)->then(
sub {
my ($hafas) = @_;
diff --git a/t/22-transit-visibility.t b/t/22-transit-visibility.t
index 90f57d1..8a68f5c 100644
--- a/t/22-transit-visibility.t
+++ b/t/22-transit-visibility.t
@@ -108,10 +108,10 @@ sub test_intransit_visibility {
$opt{effective_visibility_str}, $desc );
if ( $opt{public} ) {
- $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667});
+ $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN\s*667});
$t->get_ok('/ajax/status/test1.html')->status_is(200)
- ->content_like(qr{DPN 667});
- $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
+ $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667});
}
else {
$t->get_ok('/status/test1')->status_is(200)
@@ -124,9 +124,9 @@ sub test_intransit_visibility {
if ( $opt{with_token} ) {
$t->get_ok("/status/test1/$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
$t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/status/test1/$token")->status_is(200)
@@ -142,10 +142,10 @@ sub test_intransit_visibility {
# users can see their own status if visibility is >= followrs
if ( $opt{effective_visibility} >= 60 ) {
- $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667});
+ $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN\s*667});
$t->get_ok('/ajax/status/test1.html')->status_is(200)
- ->content_like(qr{DPN 667});
- $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
+ $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667});
}
else {
$t->get_ok('/status/test1')->status_is(200)
@@ -159,9 +159,9 @@ sub test_intransit_visibility {
# users can see their own status with token if visibility is >= unlisted
if ( $opt{effective_visibility} >= 30 ) {
$t->get_ok("/status/test1/$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
$t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/status/test1/$token")->status_is(200)
@@ -178,10 +178,10 @@ sub test_intransit_visibility {
# uid2 can see uid1 if visibility is >= followers
if ( $opt{effective_visibility} >= 60 ) {
- $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667});
+ $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN\s*667});
$t->get_ok('/ajax/status/test1.html')->status_is(200)
- ->content_like(qr{DPN 667});
- $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
+ $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667});
}
else {
$t->get_ok('/status/test1')->status_is(200)
@@ -195,9 +195,9 @@ sub test_intransit_visibility {
# uid2 can see uid1 with token if visibility is >= unlisted
if ( $opt{effective_visibility} >= 30 ) {
$t->get_ok("/status/test1/$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
$t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/status/test1/$token")->status_is(200)
@@ -214,10 +214,10 @@ sub test_intransit_visibility {
# uid3 can see uid1 if visibility is >= travelynx
if ( $opt{effective_visibility} >= 80 ) {
- $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN 667});
+ $t->get_ok('/status/test1')->status_is(200)->content_like(qr{DPN\s*667});
$t->get_ok('/ajax/status/test1.html')->status_is(200)
- ->content_like(qr{DPN 667});
- $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
+ $t->get_ok('/p/test1')->status_is(200)->content_like(qr{DPN\s*667});
}
else {
$t->get_ok('/status/test1')->status_is(200)
@@ -231,9 +231,9 @@ sub test_intransit_visibility {
# uid3 can see uid1 with token if visibility is >= unlisted
if ( $opt{effective_visibility} >= 30 ) {
$t->get_ok("/status/test1/$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
$t->get_ok("/ajax/status/test1.html?token=$j_token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/status/test1/$token")->status_is(200)
diff --git a/t/23-journey-visibility.t b/t/23-journey-visibility.t
index 58b305a..1cc7e64 100644
--- a/t/23-journey-visibility.t
+++ b/t/23-journey-visibility.t
@@ -111,7 +111,7 @@ sub test_journey_visibility {
if ( $opt{public} ) {
$t->get_ok("/p/test1/j/$jid")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid")->status_is(404)
@@ -120,7 +120,7 @@ sub test_journey_visibility {
if ( $opt{with_token} ) {
$t->get_ok("/p/test1/j/$jid$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid$token")->status_is(404)
@@ -135,7 +135,7 @@ sub test_journey_visibility {
# users can see their own status if visibility is >= followrs
if ( $opt{effective_visibility} >= 60 ) {
$t->get_ok("/p/test1/j/$jid")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid")->status_is(404)
@@ -145,7 +145,7 @@ sub test_journey_visibility {
# users can see their own status with token if visibility is >= unlisted
if ( $opt{effective_visibility} >= 30 ) {
$t->get_ok("/p/test1/j/$jid$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid$token")->status_is(404)
@@ -161,7 +161,7 @@ sub test_journey_visibility {
# uid2 can see uid1 if visibility is >= followers
if ( $opt{effective_visibility} >= 60 ) {
$t->get_ok("/p/test1/j/$jid")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid")->status_is(404)
@@ -171,7 +171,7 @@ sub test_journey_visibility {
# uid2 can see uid1 with token if visibility is >= unlisted
if ( $opt{effective_visibility} >= 30 ) {
$t->get_ok("/p/test1/j/$jid$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid$token")->status_is(404)
@@ -187,7 +187,7 @@ sub test_journey_visibility {
# uid3 can see uid1 if visibility is >= travelynx
if ( $opt{effective_visibility} >= 80 ) {
$t->get_ok("/p/test1/j/$jid")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid")->status_is(404)
@@ -197,7 +197,7 @@ sub test_journey_visibility {
# uid3 can see uid1 with token if visibility is >= unlisted
if ( $opt{effective_visibility} >= 30 ) {
$t->get_ok("/p/test1/j/$jid$token")->status_is(200)
- ->content_like(qr{DPN 667});
+ ->content_like(qr{DPN\s*667});
}
else {
$t->get_ok("/p/test1/j/$jid$token")->status_is(404)
diff --git a/t/24-past-visibility.t b/t/24-past-visibility.t
index 935ab6c..cf981b9 100644
--- a/t/24-past-visibility.t
+++ b/t/24-past-visibility.t
@@ -116,11 +116,11 @@ sub test_history_visibility {
if ( $opt{public} ) {
$t->get_ok('/p/test1')->status_is(200)
- ->content_like( qr{DPN 667}, "public $desc" );
+ ->content_like( qr{DPN\s*667}, "public $desc" );
}
else {
$t->get_ok('/p/test1')->status_is(200)
- ->content_unlike( qr{DPN 667}, "public $desc" );
+ ->content_unlike( qr{DPN\s*667}, "public $desc" );
}
login(
@@ -130,11 +130,11 @@ sub test_history_visibility {
if ( $opt{self} ) {
$t->get_ok('/p/test1')->status_is(200)
- ->content_like( qr{DPN 667}, "self $desc" );
+ ->content_like( qr{DPN\s*667}, "self $desc" );
}
else {
$t->get_ok('/p/test1')->status_is(200)
- ->content_unlike( qr{DPN 667}, "self $desc" );
+ ->content_unlike( qr{DPN\s*667}, "self $desc" );
}
logout();
@@ -145,11 +145,11 @@ sub test_history_visibility {
if ( $opt{followers} ) {
$t->get_ok('/p/test1')->status_is(200)
- ->content_like( qr{DPN 667}, "follower $desc" );
+ ->content_like( qr{DPN\s*667}, "follower $desc" );
}
else {
$t->get_ok('/p/test1')->status_is(200)
- ->content_unlike( qr{DPN 667}, "follower $desc" );
+ ->content_unlike( qr{DPN\s*667}, "follower $desc" );
}
logout();
@@ -160,11 +160,11 @@ sub test_history_visibility {
if ( $opt{travelynx} ) {
$t->get_ok('/p/test1')->status_is(200)
- ->content_like( qr{DPN 667}, "travelynx $desc" );
+ ->content_like( qr{DPN\s*667}, "travelynx $desc" );
}
else {
$t->get_ok('/p/test1')->status_is(200)
- ->content_unlike( qr{DPN 667}, "travelynx $desc" );
+ ->content_unlike( qr{DPN\s*667}, "travelynx $desc" );
}
logout();
diff --git a/templates/_checked_in.html.ep b/templates/_checked_in.html.ep
index 797ff57..a5611e9 100644
--- a/templates/_checked_in.html.ep
+++ b/templates/_checked_in.html.ep
@@ -356,24 +356,20 @@
% }
</div>
<div class="card-action">
- % my $url = 'https://bahn.expert/details/';
- % if ($journey->{train_id} =~ m{[|]}) {
- % if ($journey->{train_type} and $journey->{train_no}) {
- % $url .= $journey->{train_type} . ' ' . $journey->{train_no};
- % }
- % $url .= '/' . $journey->{sched_departure}->epoch . '000?jid=' . $journey->{train_id} =~ s{#}{%23}gr;
- % }
- % else {
- % $url .= $journey->{train_type} . ' ' . $journey->{train_no} . '/' . $journey->{sched_departure}->epoch . '000?station=' . $journey->{dep_eva};
+ % my $url = 'https://dbf.finalrewind.org/z/';
+ % if ($journey->{is_hafas}) {
+ % $url .= $journey->{train_id} =~ s{#}{%23}gr . '?hafas=' . $journey->{backend_name};
+ <a style="margin-right: 0;" href="<%= $url %>"><i class="material-icons left" aria-hidden="true">timeline</i> Details</a>
% }
- % if ($journey->{backend_id} <= 1) {
+ % elsif ($journey->{extra_data}{trip_id}) {
+ % $url .= $journey->{extra_data}{trip_id} =~ s{#}{%23}gr;
<a style="margin-right: 0;" href="<%= $url %>"><i class="material-icons left" aria-hidden="true">timeline</i> Zuglauf</a>
% }
% else {
&nbsp;
% }
% if ($journey->{extra_data}{trip_id}) {
- <a class="right" style="margin-right: 0;" href="https://dbf.finalrewind.org/map/<%= $journey->{extra_data}{trip_id} =~ s{#}{%23}gr %>/<%= $journey->{train_line} || 0 %>?hafas=<%= $journey->{backend_name} // 'DB' %>&amp;from=<%= $journey->{dep_name} %>&amp;to=<%= $journey->{arr_name} %>&amp;dark=<%= (session('theme') and session('theme') eq 'dark') ? 1 : 0 %>"><i class="material-icons left" aria-hidden="true">map</i> Karte</a>
+ <a class="right" style="margin-right: 0;" href="https://dbf.finalrewind.org/map/<%= $journey->{extra_data}{trip_id} =~ s{#}{%23}gr %>/<%= $journey->{train_line} || 0 %>?hafas=<%= $journey->{backend_name} // 'VRN' %>&amp;from=<%= $journey->{dep_name} %>&amp;to=<%= $journey->{arr_name} %>"><i class="material-icons left" aria-hidden="true">map</i> Karte</a>
% }
</div>
</div>
diff --git a/templates/_public_status_card.html.ep b/templates/_public_status_card.html.ep
index 6dda46d..84708ef 100644
--- a/templates/_public_status_card.html.ep
+++ b/templates/_public_status_card.html.ep
@@ -168,8 +168,13 @@
<div class="card-action">
% if ($journey->{traewelling_url}) {
<a style="margin-right: 0;" href="<%= $journey->{traewelling_url} %>"><i class="material-icons left">timeline</i> Träwelling</a>
- % } elsif ($journey->{backend_id} <= 1) {
- % my $url = 'https://bahn.expert/details/' . $journey->{train_type} . ' ' . $journey->{train_no} . '/' . DateTime->now(time_zone => 'Europe/Berlin')->epoch . '000';
+ % }
+ % elsif ($journey->{is_hafas}) {
+ % my $url = 'https://dbf.finalrewind.org/z/' . $journey->{train_id} =~ s{#}{%23}gr . '?hafas=' . $journey->{backend_name};
+ <a style="margin-right: 0;" href="<%= $url %>"><i class="material-icons left">timeline</i> Details</a>
+ % }
+ % elsif ($journey->{extra_data}{trip_id}) {
+ % my $url = 'https://dbf.finalrewind.org/z/' . $journey->{extra_data}{trip_id} =~ s{#}{%23}gr;
<a style="margin-right: 0;" href="<%= $url %>"><i class="material-icons left">timeline</i> Zuglauf</a>
% }
% else {
diff --git a/templates/about.html.ep b/templates/about.html.ep
index d1fcb4b..d739335 100644
--- a/templates/about.html.ep
+++ b/templates/about.html.ep
@@ -16,6 +16,19 @@
</div>
<div class="row">
+ <div class="col s12">
+ <p>
+ Travelynx ist ein kostenfreies, privat betriebenes Projekt ohne
+ Verfügbarkeitsgarantie. Unangekündigte Downtimes oder eine
+ kurzfristige Einstellung dieser Seite sind nicht vorgesehen, aber
+ möglich. Feature Requests, Bug Reports und sonstige Nachrichten
+ werden je nach Kapazität und Motivation zeitnah, verzögert oder gar
+ nicht bearbeitet / beantwortet.
+ </p>
+ </div>
+</div>
+
+<div class="row">
<div class="col s12 m12 l4 center-align" style="margin-top: 1em;">
<a href="https://social.skyshaper.org/derf" class="waves-effect waves-light btn"><i class="material-icons left">message</i>Kontakt</a>
</div>
diff --git a/templates/changelog.html.ep b/templates/changelog.html.ep
index ad3291a..3671666 100644
--- a/templates/changelog.html.ep
+++ b/templates/changelog.html.ep
@@ -2,6 +2,37 @@
<div class="row">
<div class="col s12 m1 l1">
+ 2.10
+ </div>
+ <div class="col s12 m11 l11">
+ <p>
+ <i class="material-icons left" aria-label="Neues Feature">add</i>
+ Neue HAFAS-Backends: PKP, SaarVV.
+ </p>
+ <p>
+ <i class="material-icons left" aria-label="Bug">warning</i> Das DB
+ HAFAS-Backend wurde am 8. Januar 2025 abgeschaltet und wird von
+ travelynx daher seit v2.9.11 nicht mehr angeboten. Als vorläufiger
+ Ersatz bietet sich das VRN HAFAS-Backend an. Eine Wieder-Anbindung
+ der DB mittels Travel::Status::DE::DBRIS ist in Arbeit. Bis dahin
+ ist keine Synchronisierung mit Traewelling möglich.
+ </p>
+ <p>
+ <i class="material-icons left" aria-label="Administration">announcement</i>
+ Das PKP HAFAS befindet sich hinter einem GeoIP-Filter und wird
+ daher in travelynx-Installationen außerhalb von travelynx.de
+ standardmäßig nicht angeboten. Sofern die travelynx-Instanz auf
+ einer geeigneten IP-Adresse betrieben wird oder eine solche per
+ Proxy erreichbar ist, lässt es sich über einen Eintrag in
+ travelynx.conf aktivieren. Als Nebenwirkung davon kann auch auf
+ beliebige andere HAFAS-Instanzen bei Bedarf über einen
+ Instanz-spezifischen Proxy zugegriffen werden.
+ </p>
+ </div>
+</div>
+
+<div class="row">
+ <div class="col s12 m1 l1">
2.9
</div>
<div class="col s12 m11 l11">
diff --git a/templates/select_backend.html.ep b/templates/select_backend.html.ep
index 8af157d..5397542 100644
--- a/templates/select_backend.html.ep
+++ b/templates/select_backend.html.ep
@@ -34,15 +34,15 @@
<div class="col s12">
<h2 id="help">Hilfe</h2>
<p>
- Leider gibt es seit der Abschaltung des DB HAFAS am 8. Januar 2025 derzeit kein Backend, welches allgemein für Nah- und Fernverkehr in Deutschland nutzbar ist.
- Der <strong>VRN</strong> kommt voraussichtlich am ehesten an Qualität und Umfang der im DB HAFAS verfügbaren Daten heran.
+ Leider gibt es seit der Abschaltung des DB HAFAS am 8. Januar 2025 sowie des VRN HAFAS am 3. März 2025 derzeit kein Backend, welches allgemein für Nah- und Fernverkehr in Deutschland nutzbar ist.
+ <strong>Deutsche Bahn</strong> (IRIS-TTS) eignet sich für Fahrten mit S-Bahnen, Regional- und Fernzügen.
Im Übrigen muss je nach Verkehrsmittel, Region und Wünschen an die verfügbaren Daten hier ein geeignetes Backend ausgewählt werden.
+ In einzelnen Regionen steht kein geeignetes Backend für Nahverkehrsfahrten zur Verfügung.
Abhilfe ist in Arbeit.
</p>
<p>
- <strong>VRN</strong> ist eine gute Wahl für Nah-, Regional- und Fernverkehr in Deutschland. Hier gibt es meist Echtzeitdaten, allgemeine Meldungen, Wagenreihungen und Kartendaten.
- <strong>Deutsche Bahn</strong> (IRIS-TTS) liefert Echtzeitdaten, Wagenreihungen und Verspätungsmeldungen für Regional- und Fernverkehr in Deutschland. In vielen Fällen sind auch allgemeine Meldungen und Kartendaten verfügbar.
- <strong>ÖBB</strong> liefern Kartendaten und Wagenreihungen für Fernverkehr in Deutschland, jedoch keine Meldungen. Echtzeitdaten sind teilweise verfügbar.
+ <strong>Deutsche Bahn</strong> (IRIS-TTS) liefert Echtzeitdaten (nur am Start- und Zielbahnhof), Wagenreihungen und Verspätungsmeldungen für Regional- und Fernverkehr in Deutschland. In vielen Fällen sind auch Kartendaten verfügbar.
+ <strong>ÖBB</strong> liefern Kartendaten und Wagenreihungen für Fernverkehr in Deutschland und Umgebung, jedoch keine Meldungen. Echtzeitdaten sind teilweise verfügbar.
</p>
<p>
Die restlichen Backends lohnen sich für Fahrten in den zugehörigen Verkehrsverbünden bzw. Ländern.