diff options
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | cpanfile | 2 | ||||
-rw-r--r-- | cpanfile.snapshot | 807 | ||||
-rw-r--r-- | examples/travelynx.conf | 11 | ||||
-rwxr-xr-x | lib/Travelynx.pm | 1 | ||||
-rw-r--r-- | lib/Travelynx/Controller/Account.pm | 12 | ||||
-rwxr-xr-x | lib/Travelynx/Controller/Traveling.pm | 13 | ||||
-rw-r--r-- | lib/Travelynx/Helper/HAFAS.pm | 114 | ||||
-rw-r--r-- | t/22-transit-visibility.t | 40 | ||||
-rw-r--r-- | t/23-journey-visibility.t | 16 | ||||
-rw-r--r-- | t/24-past-visibility.t | 16 | ||||
-rw-r--r-- | templates/_checked_in.html.ep | 18 | ||||
-rw-r--r-- | templates/_public_status_card.html.ep | 9 | ||||
-rw-r--r-- | templates/about.html.ep | 13 | ||||
-rw-r--r-- | templates/changelog.html.ep | 31 | ||||
-rw-r--r-- | templates/select_backend.html.ep | 10 |
16 files changed, 610 insertions, 516 deletions
@@ -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. @@ -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{(}{(}g; - $body =~ s{)}{)}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 { % } % 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' %>&from=<%= $journey->{dep_name} %>&to=<%= $journey->{arr_name} %>&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' %>&from=<%= $journey->{dep_name} %>&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. |