From 4ed65c290de08fe9974ff446d529a4d5bac661ce Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 13 Apr 2018 10:25:37 -0400 Subject: [PATCH 01/16] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_hi.ts | 283 ++++++++++++++++++++++--------------------- lang/calamares_id.ts | 38 +++--- lang/calamares_lt.ts | 6 +- lang/calamares_sk.ts | 19 +-- 4 files changed, 174 insertions(+), 172 deletions(-) diff --git a/lang/calamares_hi.ts b/lang/calamares_hi.ts index 5e36c160c..78adb1e1d 100644 --- a/lang/calamares_hi.ts +++ b/lang/calamares_hi.ts @@ -4,17 +4,17 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - + इस सिस्टम का <strong>boot वातावरण</strong>।<br><br>पुराने x86 सिस्टम केवल <strong>BIOS</strong> का समर्थन करते हैं।<br>आधुनिक सिस्टम आमतौर पर <strong>EFI</strong> का उपयोग करते हैं, लेकिन compatibilty मोड में शुरू होने पर BIOS के रूप में दिखाई दे सकते हैं। This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - + यह सिस्टम <strong>EFI</strong> boot वातावरण के साथ शुरू किया गया।<br><br>EFI वातावरण से स्टार्टअप विन्यस्त करने के लिए इंस्टॉलर को <strong>GRUB</strong> या <strong>systemd-boot</strong> जैसे boot loader अनुप्रयोग <strong>EFI सिस्टम विभाजन</strong> पर स्थापित करने जरूरी हैं। यह स्वत: होता है, परंतु अगर आप मैनुअल विभाजन करना चुनते है; तो आपको या तो इसे चुनना होगा या फिर खुद ही बनाना होगा। This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. - + यह सिस्टम <strong>BIOS</strong> boot वातावरण के साथ शुरू किया गया।<br><br>BIOS वातावरण से स्टार्टअप विन्यस्त करने के लिए इंस्टॉलर को <strong>GRUB</strong> जैसे boot loader को, या तो विभाजन की शुरुआत में या फिर <strong>Master Boot Record</strong> पर विभाजन तालिका की शुरुआत में इंस्टॉल (preferred) करना होगा। यह स्वत: होता है, परंतु अगर आप मैनुअल विभाजन करना चुनते है; तो आपको इसे खुद ही बनाना होगा। @@ -22,27 +22,27 @@ Master Boot Record of %1 - + %1 का Master Boot Record Boot Partition - + Boot विभाजन System Partition - + सिस्टम विभाजन Do not install a boot loader - + Boot loader इंस्टॉल न करें %1 (%2) - + %1 (%2) @@ -50,48 +50,48 @@ Form - + रूप GlobalStorage - + GlobalStorage JobQueue - + JobQueue Modules - + Modules Type: - + प्रकार none - + कुछ नहीं Interface: - + अंतरफलक : Tools - + साधन Debug information - + डीबग संबंधी जानकारी @@ -99,7 +99,7 @@ Install - + इंस्टॉल करें @@ -107,7 +107,7 @@ Done - + हो गया @@ -115,12 +115,12 @@ Run command %1 %2 - + कमांड %1%2 चलाएँ Running command %1 %2 - + कमांड %1%2 चल रही हैं @@ -128,32 +128,32 @@ Running %1 operation. - + %1 चल रहा है। Bad working directory path - + कार्यरत फोल्डर का पथ गलत है Working directory %1 for python job %2 is not readable. - + Python job %2 के लिए कार्यरत डायरेक्टरी %1 read करने योग्य नहीं है। Bad main script file - + मुख्य script फ़ाइल गलत है Main script file %1 for python job %2 is not readable. - + Python job %2 के लिए मुख्य script फ़ाइल %1 read करने योग्य नहीं है। Boost.Python error in job "%1". - + Job "%1" में Boost.Python error। @@ -161,90 +161,91 @@ &Back - + &वापस &Next - + &आगे &Cancel - + &रद्द करें Cancel installation without changing the system. - + सिस्टम में बदलाव किये बिना इंस्टॉल रद्द करें। Cancel installation? - + इंस्टॉल रद्द करें? Do you really want to cancel the current install process? The installer will quit and all changes will be lost. - + क्या आप वाकई वर्तमान इंस्टॉल प्रक्रिया रद्द करना चाहते हैं? +इंस्टॉलर बंद हो जाएगा व सभी बदलाव नष्ट। &Yes - + &हाँ &No - + &नहीं &Close - + &बंद करें Continue with setup? - + सेटअप करना जारी रखें? The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> - + %2 इंस्टॉल करने के लिए %1 इंस्टॉलर आपकी डिस्क में बदलाव करने वाला है।<br/><strong>आप इन बदलावों को पूर्ववत नहीं कर पाएंगे।</strong> &Install now - + अभी &इंस्टॉल करें Go &back - + &वापस जाएँ &Done - + हो &गया The installation is complete. Close the installer. - + इंस्टॉल पूर्ण हुआ।अब इंस्टॉलर को बंद करें। Error - + Error Installation Failed - + इंस्टॉल विफल रहा। @@ -252,22 +253,22 @@ The installer will quit and all changes will be lost. Unknown exception type - + अपवाद का प्रकार अज्ञात है unparseable Python error - + unparseable Python error unparseable Python traceback - + unparseable Python traceback Unfetchable Python error. - + Unfetchable Python error. @@ -275,12 +276,12 @@ The installer will quit and all changes will be lost. %1 Installer - + %1 इंस्टॉलर Show debug information - + डीबग संबंधी जानकारी दिखाएँ @@ -288,27 +289,27 @@ The installer will quit and all changes will be lost. This computer does not satisfy the minimum requirements for installing %1.<br/>Installation cannot continue. <a href="#details">Details...</a> - + यह कंप्यूटर %1 को इंस्टॉल करने की न्यूनतम आवश्यकताओं को पूरा नहीं करता।<br/>इंस्टॉल जारी नहीं रखा जा सकता।<a href="#details">विवरण...</a> This computer does not satisfy some of the recommended requirements for installing %1.<br/>Installation can continue, but some features might be disabled. - + यह कंप्यूटर %1 को इंस्टॉल करने की सुझायी गई आवश्यकताओं को पूरा नहीं करता।<br/>इंस्टॉल जारी रखा जा सकता, लेकिन कुछ विशेषताएँ निष्क्रिय हो सकती हैं। This program will ask you some questions and set up %2 on your computer. - + यह program आपसे कुछ सवाल पूछेगा व आपके कंप्यूटर पर %2 को सेट करेगा। For best results, please ensure that this computer: - + उत्तम परिणामों के लिए, कृपया सुनिश्चित करें कि यह कंप्यूटर: System requirements - + सिस्टम की आवश्यकताएँ @@ -316,32 +317,32 @@ The installer will quit and all changes will be lost. Form - + रूप After: - + बाद में: <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. - + <strong>मैनुअल विभाजन</strong><br/> आप स्वयं भी विभाजन बना व उनका आकार बदल सकते है। Boot loader location: - + Boot loader की location: %1 will be shrunk to %2MB and a new %3MB partition will be created for %4. - + %1 को छोटा करके %2MB किया जाएगा व %4 के लिए %3MB का एक नया विभाजन बनेगा। Select storage de&vice: - + Storage डि&वाइस चुनें : @@ -349,42 +350,42 @@ The installer will quit and all changes will be lost. Current: - + मौजूदा : Reuse %1 as home partition for %2. - + %2 के होम विभाजन के लिए %1 को पुनः उपयोग करें। <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> - + <strong>छोटा करने के लिए विभाजन चुनें, फिर नीचे bar से उसका आकर सेट करें</strong> <strong>Select a partition to install on</strong> - + <strong>इंस्टॉल के लिए विभाजन चुनें</strong> An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. - + इस सिस्टम पर कहीं भी कोई EFI सिस्टम विभाजन नहीं मिला। कृपया वापस जाएँ व %1 को सेट करने के लिए मैनुअल रूप से विभाजन करें। The EFI system partition at %1 will be used for starting %2. - + %1 वाले EFI सिस्टम विभाजन का उपयोग %2 को शुरू करने के लिए किया जाएगा। EFI system partition: - + EFI सिस्टम विभाजन: This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + इस storage डिवाइस पर लगता है कि कोई ऑपरेटिंग सिस्टम नहीं है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। @@ -392,12 +393,12 @@ The installer will quit and all changes will be lost. <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. - + <strong>डिस्क erase करें</strong><br/>इससे चयनित storage डिवाइस पर मौजूद सारा डाटा <font color="red">delete</font> हो जाएगा। This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + इस storage डिवाइस पर %1 है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। @@ -405,7 +406,7 @@ The installer will quit and all changes will be lost. <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. - + <strong>साथ में इंस्टॉल करें</strong><br/>इंस्टॉलर %1 के लिए स्थान बनाने हेतु एक विभाजन को छोटा कर देगा। @@ -413,17 +414,17 @@ The installer will quit and all changes will be lost. <strong>Replace a partition</strong><br/>Replaces a partition with %1. - + <strong>विभाजन को बदलें</strong>एक विभाजन को %1 से बदलें। This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + इस storage डिवाइस पर पहले से एक ऑपरेटिंग सिस्टम है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + इस storage डिवाइस पर एक से अधिक ऑपरेटिंग सिस्टम है। आप क्या करना चाहेंगे?<br/>आप storage डिवाइस में किसी भी बदलाव से पहले उसकी समीक्षा व पुष्टि कर सकेंगे। @@ -431,17 +432,17 @@ The installer will quit and all changes will be lost. Clear mounts for partitioning operations on %1 - + %1 पर विभाजन कार्य हेतु mount हटाएँ Clearing mounts for partitioning operations on %1. - + %1 पर विभाजन कार्य हेतु mount हटाएँ जा रहे हैं। Cleared all mounts for %1 - + %1 के लिए सभी mount हटा दिए गए @@ -449,22 +450,22 @@ The installer will quit and all changes will be lost. Clear all temporary mounts. - + सभी अस्थायी mount हटाएँ। Clearing all temporary mounts. - + सभी अस्थायी mount हटाएँ जा रहे हैं। Cannot get list of temporary mounts. - + अस्थाई mount की सूची नहीं मिली। Cleared all temporary mounts. - + सभी अस्थायी mount हटा दिए गए। @@ -472,12 +473,12 @@ The installer will quit and all changes will be lost. Could not run command. - + कमांड run नहीं की जा सकी। No rootMountPoint is defined, so command cannot be run in the target environment. - + कोई rootMountPoint परिभाषित नहीं है, इसलिए कमांड को लक्ष्य वातावरण में run नहीं किया जा सकता है। @@ -485,7 +486,7 @@ The installer will quit and all changes will be lost. Contextual Processes Job - + Contextual Processes Job @@ -493,22 +494,22 @@ The installer will quit and all changes will be lost. Create a Partition - + एक विभाजन बनाएँ MiB - + MiB Partition &Type: - + विभाजन का प्र&कार : &Primary - + &मुख्य @@ -528,7 +529,7 @@ The installer will quit and all changes will be lost. Flags: - + Flags: @@ -543,7 +544,7 @@ The installer will quit and all changes will be lost. En&crypt - + En&crypt @@ -553,12 +554,12 @@ The installer will quit and all changes will be lost. Primary - + मुख्य GPT - + GPT @@ -609,12 +610,12 @@ The installer will quit and all changes will be lost. Master Boot Record (MBR) - + Master Boot Record (MBR) GUID Partition Table (GPT) - + GUID Partition Table (GPT) @@ -769,7 +770,7 @@ The installer will quit and all changes will be lost. %1 - %2 (%3) - + %1 - %2 (%3) @@ -795,7 +796,7 @@ The installer will quit and all changes will be lost. Dummy C++ Job - + Dummy C++ Job @@ -818,12 +819,12 @@ The installer will quit and all changes will be lost. Format - + फॉर्मेट करें Warning: Formatting the partition will erase all existing data. - + चेतावनी: विभाजन फॉर्मेट करने से सारा मौजूदा डाटा मिट जायेगा। @@ -838,7 +839,7 @@ The installer will quit and all changes will be lost. MiB - + MiB @@ -848,7 +849,7 @@ The installer will quit and all changes will be lost. Flags: - + Flags: @@ -861,7 +862,7 @@ The installer will quit and all changes will be lost. Form - + रूप @@ -889,7 +890,7 @@ The installer will quit and all changes will be lost. Set partition information - + विभाजन संबंधी जानकारी सेट करें @@ -927,7 +928,7 @@ The installer will quit and all changes will be lost. Form - + रूप @@ -1014,7 +1015,7 @@ The installer will quit and all changes will be lost. Script - + Script @@ -1035,7 +1036,7 @@ The installer will quit and all changes will be lost. Keyboard - कीबोर्ड + कुंजीपटल @@ -1053,7 +1054,7 @@ The installer will quit and all changes will be lost. &Cancel - + &रद्द करें @@ -1066,7 +1067,7 @@ The installer will quit and all changes will be lost. Form - + रूप @@ -1176,7 +1177,7 @@ The installer will quit and all changes will be lost. %1 (%2) Language (Country) - + %1 (%2) @@ -1453,7 +1454,7 @@ The installer will quit and all changes will be lost. The configuration file is malformed - + विन्यास फाइल ख़राब है @@ -1471,7 +1472,7 @@ The installer will quit and all changes will be lost. Form - + रूप @@ -1489,7 +1490,7 @@ The installer will quit and all changes will be lost. Form - + रूप @@ -1506,7 +1507,7 @@ The installer will quit and all changes will be lost. font-weight: normal - + font-weight: normal @@ -1559,7 +1560,7 @@ The installer will quit and all changes will be lost. Root - + Root @@ -1569,7 +1570,7 @@ The installer will quit and all changes will be lost. Boot - + Boot @@ -1594,7 +1595,7 @@ The installer will quit and all changes will be lost. %1 %2 - + %1 %2 @@ -1637,7 +1638,7 @@ The installer will quit and all changes will be lost. Form - + रूप @@ -1685,12 +1686,12 @@ The installer will quit and all changes will be lost. Gathering system information... - + सिस्टम की जानकारी प्राप्त की जा रही है... Partitions - + विभाजन @@ -1740,12 +1741,12 @@ The installer will quit and all changes will be lost. Current: - + मौजूदा : After: - + बाद में: @@ -1783,7 +1784,7 @@ The installer will quit and all changes will be lost. Plasma Look-and-Feel Job - + Plasma Look-and-Feel Job @@ -1797,12 +1798,12 @@ The installer will quit and all changes will be lost. Form - + रूप Placeholder - + Placeholder @@ -1905,12 +1906,12 @@ Output: extended - + विस्तृत unformatted - + फॉर्मेट नहीं हो रखा है @@ -1928,7 +1929,7 @@ Output: Form - + रूप @@ -1990,12 +1991,12 @@ Output: The EFI system partition at %1 will be used for starting %2. - + %1 वाले EFI सिस्टम विभाजन का उपयोग %2 को शुरू करने के लिए किया जाएगा। EFI system partition: - + EFI सिस्टम विभाजन: @@ -2003,7 +2004,7 @@ Output: Gathering system information... - + सिस्टम की जानकारी प्राप्त की जा रही है... @@ -2397,12 +2398,12 @@ Output: Form - + रूप Placeholder - + Placeholder @@ -2414,14 +2415,14 @@ Output: TextLabel - + TextLabel ... - + ... @@ -2504,7 +2505,7 @@ Output: Form - + रूप @@ -2534,27 +2535,27 @@ Output: <h1>Welcome to the %1 installer.</h1> - + <h1>%1 इंस्टॉलर में आपका स्वागत है।</h1> <h1>Welcome to the Calamares installer for %1.</h1> - + <h1>%1 के लिए Calamares इंस्टॉलर में आपका स्वागत है।</h1> About %1 installer - + %1 इंस्टॉलर के बारे में <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Thanks to: Anke Boersma, Aurélien Gâteau, Kevin Kofler, Lisa Vitolo, Philip Müller, Pier Luigi Fiorini, Rohan Garg and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. - + <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Anke Boersma, Aurélien Gâteau, Kevin Kofler, Lisa Vitolo, Philip Müller, Pier Luigi Fiorini, रोहन गर्ग व <a href="https://www.transifex.com/calamares/calamares/">Calamares अनुवादक टीम</a> का धन्यवाद।<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. %1 support - + %1 सहायता @@ -2562,7 +2563,7 @@ Output: Welcome - + स्वागतं \ No newline at end of file diff --git a/lang/calamares_id.ts b/lang/calamares_id.ts index 1256b7be5..0ea8a0218 100644 --- a/lang/calamares_id.ts +++ b/lang/calamares_id.ts @@ -475,12 +475,12 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Could not run command. - + Tidak dapat menjalankan perintah No rootMountPoint is defined, so command cannot be run in the target environment. - + rootMountPoint tidak didefiniskan, sehingga perintah tidak dapat dijalankan dalam lingkungan environment @@ -488,7 +488,7 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Contextual Processes Job - + Memproses tugas kontekstual @@ -526,7 +526,7 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. LVM LV name - + Nama LV LVM @@ -935,7 +935,7 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style=" font-style:italic;">Done</span> or close the installer.</p></body></html> - + Ketika kotak ini dicentang, sistem kamu akan segera dimulai kembali saat mengklik Selesai atau menutup pemasang. @@ -1004,7 +1004,7 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Please install KDE Konsole and try again! - + Silahkan pasang KDE Konsole dan ulangi lagi! @@ -1061,7 +1061,7 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. &OK - + &OK @@ -1215,7 +1215,7 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Network Installation. (Disabled: Received invalid groups data) - + Pemasangan jaringan. (Menonaktifkan: Penerimaan kelompok data yang tidak sah) @@ -1231,57 +1231,57 @@ Pemasangan dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Password is too short - + Kata sandi terlalu pendek Password is too long - + Kata sandi terlalu panjang Password is too weak - + kata sandi terlalu lemah Memory allocation error when setting '%1' - + Kesalahan alokasi memori saat menyetel '%1' Memory allocation error - + Kesalahan alokasi memori The password is the same as the old one - + Kata sandi sama dengan yang lama The password is a palindrome - + Kata sandi palindrom The password differs with case changes only - + Kata sandi berbeda hanya dengan perubahan huruf saja The password is too similar to the old one - + Kata sandi terlalu mirip dengan yang lama The password contains the user name in some form - + Kata sandi berisi nama pengguna dalam beberapa form The password contains words from the real name of the user in some form - + Kata sandi berisi kata-kata dari nama asli pengguna dalam beberapa form diff --git a/lang/calamares_lt.ts b/lang/calamares_lt.ts index c8ca26668..8024763e3 100644 --- a/lang/calamares_lt.ts +++ b/lang/calamares_lt.ts @@ -172,7 +172,7 @@ &Cancel - A&tšaukti + A&tsisakyti @@ -189,7 +189,7 @@ Do you really want to cancel the current install process? The installer will quit and all changes will be lost. - Ar tikrai norite atšaukti dabartinio diegimo procesą? + Ar tikrai norite atsisakyti dabartinio diegimo proceso? Diegimo programa užbaigs darbą ir visi pakeitimai bus prarasti. @@ -1648,7 +1648,7 @@ Diegimo programa užbaigs darbą ir visi pakeitimai bus prarasti. &Revert All Changes - &Atšaukti visus pakeitimus + &Sugrąžinti visus pakeitimus diff --git a/lang/calamares_sk.ts b/lang/calamares_sk.ts index b196209c4..4312b4124 100644 --- a/lang/calamares_sk.ts +++ b/lang/calamares_sk.ts @@ -1244,7 +1244,7 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. Memory allocation error when setting '%1' - + Chyba počas vyhradzovania pamäte pri nastavovaní „%1“ @@ -1259,12 +1259,12 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. The password is a palindrome - + Heslo je palindróm The password differs with case changes only - + Heslo sa odlišuje iba vo veľkosti písmen @@ -1289,7 +1289,7 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. The password contains less than %1 digits - + Heslo obsahuje menej ako %1 číslic @@ -1299,7 +1299,7 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. The password contains less than %1 uppercase letters - + Heslo obsahuje menej ako %1 veľkých písmen @@ -1309,7 +1309,7 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. The password contains less than %1 lowercase letters - + Heslo obsahuje menej ako %1 malých písmen @@ -1399,12 +1399,12 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. The password fails the dictionary check - %1 - + Heslo zlyhalo pri slovníkovej kontrole - %1 The password fails the dictionary check - + Heslo zlyhalo pri slovníkovej kontrole @@ -1825,7 +1825,8 @@ Inštalátor sa ukončí a všetky zmeny budú stratené. There was no output from the command. - + +Žiadny výstup z príkazu. From ef2a15b45bb4a41bd8bc924fbb15a61bb4aec212 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 13 Apr 2018 10:25:37 -0400 Subject: [PATCH 02/16] i18n: [desktop] Automatic merge of Transifex translations --- calamares.desktop | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/calamares.desktop b/calamares.desktop index 1bb0c0168..d0a46d5e2 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -59,6 +59,10 @@ Name[he]=קלמארס Icon[he]=קלמארס GenericName[he]=אשף התקנה Comment[he]=קלמארס - אשף התקנה +Name[hi]=Calamares +Icon[hi]=calamares +GenericName[hi]=सिस्टम इंस्टॉलर +Comment[hi]=Calamares — सिस्टम इंस्टॉलर Name[hr]=Calamares Icon[hr]=calamares GenericName[hr]=Instalacija sustava From 8ba4de6d0ab95bcb12841cf718785b3b12ce6093 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 13 Apr 2018 10:25:38 -0400 Subject: [PATCH 03/16] i18n: [dummypythonqt] Automatic merge of Transifex translations --- .../lang/hi/LC_MESSAGES/dummypythonqt.mo | Bin 419 -> 1014 bytes .../lang/hi/LC_MESSAGES/dummypythonqt.po | 15 ++++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/modules/dummypythonqt/lang/hi/LC_MESSAGES/dummypythonqt.mo b/src/modules/dummypythonqt/lang/hi/LC_MESSAGES/dummypythonqt.mo index 198aba348e83eb9ea74cc86b0ba91e36eb1af704..74b0fba49d89b9d574192e9eeaa158b8f60746c6 100644 GIT binary patch literal 1014 zcmb7?&u`N(6vqP$(1N%O2`(Ucw~gT@t;AL`iYRTz3hUZ+VG^8hQ?K<%>?n5ERfq$- zz=3I}{Rb)94a5Ph5`rWD1@fQ3nG-MVen`_eVD*!)pYy)YuJe9PjO`gPE(13K7q|j^ z0FrS4Tm=Te6z~%m2Yv%LfIq->VB(x%%z{pX?gKA@YY>lLFpMJTEzsMb4ba551Dg2y zp!Yz(fr4c?&chQzV{8;2KQF;7Ip@V>C674mqLn4mpneJ>sfg-G6i_Kii=uTAp<*Wp zdZ^Y@ZNXO*dLkMrqu?{|6=Y2sr{1nH+FeyNG~6~l!wJhwBKWB@U#C!FYYsQu5Dg?r zPde!J8>1G94eBXeZsIi>NhY|1YWc#`{NoZ@E7e!a)n&6zLlG%lkuBE5k2)=hUEv_J zR&{Y9qC|lS7m1<{%Gl{FwlmnCL+Pw@H#=jeZ5tACoo=$E_+j4jQofEWRb0%Y#i~;& z&%CHEm&_$16?P-SrB9TI98~ob*<^&n9r;3{`yP=YgmWR~T?Wo&ykZMB&-ZC1*a z(#d_KQ?^+UTu~0k>xJ+?72Q%+=o7~0k=G`Xq$>B!UBKCsykx6&8sQT6M3eEBgR%{# zjt}XeHZyB}Cn7#x5K#bMgNMUV<}&kWG|f$MG?_!`>3P%8@xG2f>G=C$Pw9Sqx<#OY zkdF6s{~gE|9skhrF3fge?Wp~9e4yiP9e;!*9e+)V466>Hu#Vr3>^n#9y`2C0F8$?=Rq0_M5~mbwNe V3I-NdhGsy<, 2018\n" "Language-Team: Hindi (https://www.transifex.com/calamares/teams/20061/hi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,24 +20,24 @@ msgstr "" #: src/modules/dummypythonqt/main.py:84 msgid "Click me!" -msgstr "" +msgstr "यहाँ क्लिक करें!" #: src/modules/dummypythonqt/main.py:94 msgid "A new QLabel." -msgstr "" +msgstr "नया QLabel।" #: src/modules/dummypythonqt/main.py:97 msgid "Dummy PythonQt ViewStep" -msgstr "" +msgstr "Dummy PythonQt ViewStep" #: src/modules/dummypythonqt/main.py:183 msgid "The Dummy PythonQt Job" -msgstr "" +msgstr "The Dummy PythonQt Job" #: src/modules/dummypythonqt/main.py:186 msgid "This is the Dummy PythonQt Job. The dummy job says: {}" -msgstr "" +msgstr "यह Dummy PythonQt Job है।The dummy job says: {}" #: src/modules/dummypythonqt/main.py:190 msgid "A status message for Dummy PythonQt Job." -msgstr "" +msgstr "Dummy PythonQt Job के लिए एक status संदेश।" From 4161120385c094e5c4d2b7e098ff54d8f31823fb Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 13 Apr 2018 10:25:38 -0400 Subject: [PATCH 04/16] i18n: [python] Automatic merge of Transifex translations --- lang/python/hi/LC_MESSAGES/python.mo | Bin 419 -> 1368 bytes lang/python/hi/LC_MESSAGES/python.po | 19 ++++++++++--------- lang/python/id/LC_MESSAGES/python.mo | Bin 645 -> 987 bytes lang/python/id/LC_MESSAGES/python.po | 16 ++++++++-------- lang/python/is/LC_MESSAGES/python.mo | Bin 1052 -> 1066 bytes lang/python/is/LC_MESSAGES/python.po | 2 +- lang/python/pl/LC_MESSAGES/python.mo | Bin 1370 -> 1362 bytes lang/python/pl/LC_MESSAGES/python.po | 2 +- 8 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lang/python/hi/LC_MESSAGES/python.mo b/lang/python/hi/LC_MESSAGES/python.mo index 57a9d3d2ca96489a0a1e9fff46f2cb2d06838f7b..30ae668804055e50440d604f4f6213396889d9d8 100644 GIT binary patch literal 1368 zcmbtTK~EDw6kZk7)RV@iNq_nA(MB`=H9ooU&na$1=XpA0= z33@P`xM8?#6XhcDBp1Ev*`tY>pWsjMZEH(FAQ~t6_S^YpzBlj9zWs4wV8eiM7H}Ex z2yhOt35drRzjM-pjDp4wy3VZjFNn42t!4>6@UMqk)6L+QV21``DW=K3dB|=}?hzFgi z%#Dnr?rSc|(Uly^q{b8b+wSN_-0MG7@AagPHgvS3+iN;{uG^8Jqix-O8LP3hiFDLi zi9YJ~YaMOr_A4EI0QI129VC$d+Wc8Z?{)MEESp{0(a~=AZ8uH;Qt371zeQa?5VE}n rLMP$g;!1CesLrGgu)&CUR4{=-u@qPUQKR+7a delta 69 zcmcb?wV2uBo)F7a1|VPrVi_P-0b*t#)&XJ=umIvrprj>`2C0F8$txK9CzmnZ0RR)= B2uJ_` diff --git a/lang/python/hi/LC_MESSAGES/python.po b/lang/python/hi/LC_MESSAGES/python.po index 21403be21..aabb581aa 100644 --- a/lang/python/hi/LC_MESSAGES/python.po +++ b/lang/python/hi/LC_MESSAGES/python.po @@ -10,6 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-02-07 18:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Octavian Pylos , 2018\n" "Language-Team: Hindi (https://www.transifex.com/calamares/teams/20061/hi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -19,35 +20,35 @@ msgstr "" #: src/modules/dummypython/main.py:44 msgid "Dummy python job." -msgstr "" +msgstr "Dummy python job." #: src/modules/dummypython/main.py:97 msgid "Dummy python step {}" -msgstr "" +msgstr "Dummy python step {}" #: src/modules/machineid/main.py:35 msgid "Generate machine-id." -msgstr "" +msgstr "machine-id generate करें।" #: src/modules/packages/main.py:60 #, python-format msgid "Processing packages (%(count)d / %(total)d)" -msgstr "" +msgstr "पैकेज (%(count)d / %(total)d) process किए जा रहे हैं" #: src/modules/packages/main.py:62 src/modules/packages/main.py:72 msgid "Install packages." -msgstr "" +msgstr "पैकेज इंस्टॉल करें।" #: src/modules/packages/main.py:65 #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "एक पैकेज इंस्टॉल किया जा रहा है।" +msgstr[1] "%(num)d पैकेज इंस्टॉल किए जा रहे हैं।" #: src/modules/packages/main.py:68 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "एक पैकेज हटाया जा रहा है।" +msgstr[1] "%(num)d पैकेज हटाए जा रहे हैं।" diff --git a/lang/python/id/LC_MESSAGES/python.mo b/lang/python/id/LC_MESSAGES/python.mo index 66d329c779dc15fe9bf3b1f69e2d8d1a980737e1..865533faca9acc56b58ce79af9f3ad75a4f712d6 100644 GIT binary patch delta 554 zcmZ9Hze)o^5Qit47(p!*Q45O&Nk|Yc7Gm$8CJ-TrrG@L=dbix|?vcF{gGef^Y=YP+ z*5Yee=raUtd;uT9-^m?D7ry(LnVq?v>&mD)_*f|46V5bP1;=0pJb>)HfqC!_7Qra@ z7o6oQC88~O8D57w@Fsi#--2hbfOvb7XbEn^EARmh zra&2FkIl|R_8H3kL0j8|M-hv;8**P*hw_ZnJ~LVrg+KXPL#L|g6*V+Bvp*yYuDo(_ce18!v$a?KQX1F6M^^c;%0MF(CGiiDI|M?>iXAPtmeU, 2017\n" +"Last-Translator: Choiril Abdul, 2017\n" "Language-Team: Indonesian (https://www.transifex.com/calamares/teams/20061/id/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,33 +20,33 @@ msgstr "" #: src/modules/dummypython/main.py:44 msgid "Dummy python job." -msgstr "Dummy python job." +msgstr "Tugas dumi python." #: src/modules/dummypython/main.py:97 msgid "Dummy python step {}" -msgstr "Dummy python step {}" +msgstr "Langkah {} dumi python" #: src/modules/machineid/main.py:35 msgid "Generate machine-id." -msgstr "Generate machine-id." +msgstr "Menghasilkan machine-id." #: src/modules/packages/main.py:60 #, python-format msgid "Processing packages (%(count)d / %(total)d)" -msgstr "" +msgstr "Paket pemrosesan (%(count)d/%(total)d)" #: src/modules/packages/main.py:62 src/modules/packages/main.py:72 msgid "Install packages." -msgstr "" +msgstr "pasang paket" #: src/modules/packages/main.py:65 #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] "" +msgstr[0] "memasang paket %(num)d" #: src/modules/packages/main.py:68 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] "" +msgstr[0] "mencopot %(num)d paket" diff --git a/lang/python/is/LC_MESSAGES/python.mo b/lang/python/is/LC_MESSAGES/python.mo index 76412409d86cb6d2398982ffb2918000eac55525..d59f915de02c17d8a72cbd2fcb4a4b8bc5ad4616 100644 GIT binary patch delta 94 zcmbQkv5I3tjO}_x28NYDEXcsX5XsEIAOfVbp>zX~769_60%<)Uy$ndJ0_m$z{_l-5 dH!=#8WF20Zr{J5Io_BaxadCd$W*?>ti~!}q6m|dr delta 80 zcmZ3*F^6M9jO{{328NYDEXcsX;LXgyAOfUgp>z?D769_wfwUfwo&ls)f%I`G|Lw+^ P8yT63GdD*uU0?(N*c}Z| diff --git a/lang/python/is/LC_MESSAGES/python.po b/lang/python/is/LC_MESSAGES/python.po index 91e8eb121..064735626 100644 --- a/lang/python/is/LC_MESSAGES/python.po +++ b/lang/python/is/LC_MESSAGES/python.po @@ -10,7 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-02-07 18:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Krissi, 2017\n" +"Last-Translator: Kristján Magnússon, 2017\n" "Language-Team: Icelandic (https://www.transifex.com/calamares/teams/20061/is/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/lang/python/pl/LC_MESSAGES/python.mo b/lang/python/pl/LC_MESSAGES/python.mo index d8a064d3528df88f98c0b331456571b1ea43f7aa..27720b059c9aea0a7598b7dcb22d0ccfd20c8193 100644 GIT binary patch delta 87 zcmcb`b%|?2jI9Y11H(#21_lWR28Mgg3=HBx`a6&o2Gaa25Ly{X*8utEKw2M2ZvoP| bK>EqXnTHuUQyp?minH}H^ET%)y=4LbY&#Hi delta 95 zcmcb_b&G34jI9k51H(#21_lWR28L(M3=HBx`ah5s2GZgz5Lz2Z*8utUKw2M2?*Y=e jK>E$bnTHt#O^UM(^Bl@D%Mx=^GWGIOOE#x6y=4Lb3`rB< diff --git a/lang/python/pl/LC_MESSAGES/python.po b/lang/python/pl/LC_MESSAGES/python.po index b7a5fadc3..a29efca8d 100644 --- a/lang/python/pl/LC_MESSAGES/python.po +++ b/lang/python/pl/LC_MESSAGES/python.po @@ -10,7 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-02-07 18:58+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Marcin Mikołajczak , 2017\n" +"Last-Translator: Marcin Mikołajczak , 2017\n" "Language-Team: Polish (https://www.transifex.com/calamares/teams/20061/pl/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" From 2cd4461b57fed9275badb351c52dffd2dcb7b34f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 04:32:49 -0400 Subject: [PATCH 05/16] [locale] Rename JSON handler - The handler for JSON data should be called that, not named specially after the original provider it was implemented for. - Make filename and classname consistent, GeoIPJSON. --- src/modules/locale/CMakeLists.txt | 2 +- .../locale/{GeoIPFreeGeoIP.cpp => GeoIPJSON.cpp} | 4 ++-- src/modules/locale/{GeoIPFreeGeoIP.h => GeoIPJSON.h} | 11 +++++------ src/modules/locale/GeoIPTests.cpp | 6 +++--- src/modules/locale/LocaleViewStep.cpp | 6 +++--- src/modules/locale/test_geoip.cpp | 4 ++-- 6 files changed, 16 insertions(+), 17 deletions(-) rename src/modules/locale/{GeoIPFreeGeoIP.cpp => GeoIPJSON.cpp} (95%) rename src/modules/locale/{GeoIPFreeGeoIP.h => GeoIPJSON.h} (83%) diff --git a/src/modules/locale/CMakeLists.txt b/src/modules/locale/CMakeLists.txt index 3c0cc3712..384135d4c 100644 --- a/src/modules/locale/CMakeLists.txt +++ b/src/modules/locale/CMakeLists.txt @@ -6,7 +6,7 @@ endif() include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ) -set( geoip_src GeoIP.cpp GeoIPFreeGeoIP.cpp ) +set( geoip_src GeoIP.cpp GeoIPJSON.cpp ) set( geoip_libs ) find_package(Qt5 COMPONENTS Xml) diff --git a/src/modules/locale/GeoIPFreeGeoIP.cpp b/src/modules/locale/GeoIPJSON.cpp similarity index 95% rename from src/modules/locale/GeoIPFreeGeoIP.cpp rename to src/modules/locale/GeoIPJSON.cpp index 9ef534a5d..78f6c67a7 100644 --- a/src/modules/locale/GeoIPFreeGeoIP.cpp +++ b/src/modules/locale/GeoIPJSON.cpp @@ -17,7 +17,7 @@ * along with Calamares. If not, see . */ -#include "GeoIPFreeGeoIP.h" +#include "GeoIPJSON.h" #include "utils/Logger.h" #include "utils/YamlUtils.h" @@ -27,7 +27,7 @@ #include GeoIP::RegionZonePair -FreeGeoIP::processReply( const QByteArray& data ) +GeoIPJSON::processReply( const QByteArray& data ) { try { diff --git a/src/modules/locale/GeoIPFreeGeoIP.h b/src/modules/locale/GeoIPJSON.h similarity index 83% rename from src/modules/locale/GeoIPFreeGeoIP.h rename to src/modules/locale/GeoIPJSON.h index e8986db3f..26a0560f6 100644 --- a/src/modules/locale/GeoIPFreeGeoIP.h +++ b/src/modules/locale/GeoIPJSON.h @@ -16,20 +16,19 @@ * along with Calamares. If not, see . */ -#ifndef GEOIPFREEGEOIP_H -#define GEOIPFREEGEOIP_H +#ifndef GEOIPJSON_H +#define GEOIPJSON_H #include "GeoIP.h" -/** @brief GeoIP lookup via freegeoip.com +/** @brief GeoIP lookup for services that return JSON. * * This is the original implementation of GeoIP lookup, - * using the FreeGeoIP service, or similar which returns - * data in the same format. + * (e.g. using the FreeGeoIP.net service), or similar. * * The data is assumed to be in JSON format with a time_zone attribute. */ -struct FreeGeoIP : public GeoIP +struct GeoIPJSON : public GeoIP { virtual RegionZonePair processReply( const QByteArray& ); } ; diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index 2c59aa729..4f946b8b7 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -18,7 +18,7 @@ #include "GeoIPTests.h" -#include "GeoIPFreeGeoIP.h" +#include "GeoIPJSON.h" #ifdef HAVE_XML #include "GeoIPXML.h" #endif @@ -46,7 +46,7 @@ GeoIPTests::testJSON() static const char data[] = "{\"time_zone\":\"Europe/Amsterdam\"}"; - FreeGeoIP handler; + GeoIPJSON handler; auto tz = handler.processReply( data ); QCOMPARE( tz.first, QLatin1String( "Europe" ) ); @@ -65,7 +65,7 @@ GeoIPTests::testJSONbad() { static const char data[] = "time_zone: 1"; - FreeGeoIP handler; + GeoIPJSON handler; auto tz = handler.processReply( data ); tz = handler.processReply( data ); diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 7cafd8793..243ad436c 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -20,7 +20,7 @@ #include "LocaleViewStep.h" #include "GeoIP.h" -#include "GeoIPFreeGeoIP.h" +#include "GeoIPJSON.h" #ifdef HAVE_XML #include "GeoIPXML.h" #endif @@ -124,11 +124,11 @@ LocaleViewStep::fetchGeoIpTimezone() if ( m_geoipStyle.isEmpty() || m_geoipStyle == "legacy" ) { actualUrl.append( "/json/" ); - handler = new FreeGeoIP; + handler = new GeoIPJSON; } else if ( m_geoipStyle == "json" ) { - handler = new FreeGeoIP; + handler = new GeoIPJSON; } #if defined(HAVE_XML) else if ( m_geoipStyle == "xml" ) diff --git a/src/modules/locale/test_geoip.cpp b/src/modules/locale/test_geoip.cpp index 5797ad9ff..70c205b40 100644 --- a/src/modules/locale/test_geoip.cpp +++ b/src/modules/locale/test_geoip.cpp @@ -22,7 +22,7 @@ #include -#include "GeoIPFreeGeoIP.h" +#include "GeoIPJSON.h" #ifdef HAVE_XML #include "GeoIPXML.h" #endif @@ -39,7 +39,7 @@ int main(int argc, char** argv) GeoIP* handler = nullptr; if ( QLatin1String( "json" ) == argv[1] ) - handler = new FreeGeoIP; + handler = new GeoIPJSON; #ifdef HAVE_XML else if ( QLatin1String( "xml" ) == argv[1] ) handler = new XMLGeoIP; From 79a6d7ccbdfa13e5399afc79adfc8ce8af82c346 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 04:35:32 -0400 Subject: [PATCH 06/16] [locale] Make file and class consistent GeoIPXML - Rename the class to match the filename. --- src/modules/locale/GeoIPTests.cpp | 6 +++--- src/modules/locale/GeoIPXML.cpp | 2 +- src/modules/locale/GeoIPXML.h | 2 +- src/modules/locale/LocaleViewStep.cpp | 2 +- src/modules/locale/test_geoip.cpp | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index 4f946b8b7..d4522836c 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -100,7 +100,7 @@ GeoIPTests::testXML() )"; #ifdef HAVE_XML - XMLGeoIP handler; + GeoIPXML handler; auto tz = handler.processReply( data ); QCOMPARE( tz.first, QLatin1String( "Europe" ) ); @@ -115,7 +115,7 @@ GeoIPTests::testXML2() "America/North Dakota/Beulah"; #ifdef HAVE_XML - XMLGeoIP handler; + GeoIPXML handler; auto tz = handler.processReply( data ); QCOMPARE( tz.first, QLatin1String( "America" ) ); @@ -127,7 +127,7 @@ void GeoIPTests::testXMLbad() { #ifdef HAVE_XML - XMLGeoIP handler; + GeoIPXML handler; auto tz = handler.processReply( "{time_zone: \"Europe/Paris\"}" ); QCOMPARE( tz.first, QString() ); diff --git a/src/modules/locale/GeoIPXML.cpp b/src/modules/locale/GeoIPXML.cpp index a0f9b7a2d..28761e163 100644 --- a/src/modules/locale/GeoIPXML.cpp +++ b/src/modules/locale/GeoIPXML.cpp @@ -24,7 +24,7 @@ #include GeoIP::RegionZonePair -XMLGeoIP::processReply( const QByteArray& data ) +GeoIPXML::processReply( const QByteArray& data ) { QString domError; int errorLine, errorColumn; diff --git a/src/modules/locale/GeoIPXML.h b/src/modules/locale/GeoIPXML.h index 8eec22a75..adffc5bca 100644 --- a/src/modules/locale/GeoIPXML.h +++ b/src/modules/locale/GeoIPXML.h @@ -28,7 +28,7 @@ * element, which contains the text (string) for the region/zone. This * format is expected by, e.g. the Ubiquity installer. */ -struct XMLGeoIP : public GeoIP +struct GeoIPXML : public GeoIP { virtual RegionZonePair processReply( const QByteArray& ); } ; diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 243ad436c..73121581c 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -133,7 +133,7 @@ LocaleViewStep::fetchGeoIpTimezone() #if defined(HAVE_XML) else if ( m_geoipStyle == "xml" ) { - handler = new XMLGeoIP; + handler = new GeoIPXML; } #endif else diff --git a/src/modules/locale/test_geoip.cpp b/src/modules/locale/test_geoip.cpp index 70c205b40..7b6584f0c 100644 --- a/src/modules/locale/test_geoip.cpp +++ b/src/modules/locale/test_geoip.cpp @@ -42,7 +42,7 @@ int main(int argc, char** argv) handler = new GeoIPJSON; #ifdef HAVE_XML else if ( QLatin1String( "xml" ) == argv[1] ) - handler = new XMLGeoIP; + handler = new GeoIPXML; #endif if ( !handler ) From fe20416a54184ef913fab5958e53e3f6c8b4fbe9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 04:55:37 -0400 Subject: [PATCH 07/16] [locale] Make the selector configurable - GeoIP gets a string selector; the interpretation is up to derived classes. - GeoIPXML and GeoIPJSON use the selector to select an element by tag or an attribute, respectively. --- src/modules/locale/GeoIP.cpp | 5 +++++ src/modules/locale/GeoIP.h | 8 +++++++- src/modules/locale/GeoIPJSON.cpp | 19 ++++++++++++++++--- src/modules/locale/GeoIPJSON.h | 6 +++++- src/modules/locale/GeoIPTests.cpp | 3 +++ src/modules/locale/GeoIPXML.cpp | 13 ++++++++++++- src/modules/locale/GeoIPXML.h | 8 +++++++- 7 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/modules/locale/GeoIP.cpp b/src/modules/locale/GeoIP.cpp index 1bed7d3f4..f11a44db7 100644 --- a/src/modules/locale/GeoIP.cpp +++ b/src/modules/locale/GeoIP.cpp @@ -20,6 +20,11 @@ #include "utils/Logger.h" +GeoIP::GeoIP(const QString& e) + : m_element( e ) +{ +} + GeoIP::~GeoIP() { } diff --git a/src/modules/locale/GeoIP.h b/src/modules/locale/GeoIP.h index c84a9b5e4..6088c8a45 100644 --- a/src/modules/locale/GeoIP.h +++ b/src/modules/locale/GeoIP.h @@ -32,8 +32,9 @@ class QByteArray; * and can handle the data returned from its interpretation of that * configured URL, returning a region and zone. */ -struct GeoIP +class GeoIP { +public: using RegionZonePair = QPair; virtual ~GeoIP(); @@ -51,6 +52,11 @@ struct GeoIP /** @brief Splits a region/zone string into a pair. */ static RegionZonePair splitTZString( const QString& s ); + +protected: + GeoIP( const QString& e = QString() ); + + QString m_element; // string for selecting from data } ; #endif diff --git a/src/modules/locale/GeoIPJSON.cpp b/src/modules/locale/GeoIPJSON.cpp index 78f6c67a7..aa5a2b411 100644 --- a/src/modules/locale/GeoIPJSON.cpp +++ b/src/modules/locale/GeoIPJSON.cpp @@ -26,6 +26,17 @@ #include +GeoIPJSON::GeoIPJSON(const QString& attribute) + : GeoIP( attribute ) +{ +} + +GeoIPJSON::GeoIPJSON() + : GeoIPJSON( QLatin1Literal( "time_zone" ) ) +{ +} + + GeoIP::RegionZonePair GeoIPJSON::processReply( const QByteArray& data ) { @@ -39,12 +50,14 @@ GeoIPJSON::processReply( const QByteArray& data ) var.type() == QVariant::Map ) { QVariantMap map = var.toMap(); - if ( map.contains( "time_zone" ) && - !map.value( "time_zone" ).toString().isEmpty() ) + if ( map.contains( m_element ) && + !map.value( m_element ).toString().isEmpty() ) { - return splitTZString( map.value( "time_zone" ).toString() ); + return splitTZString( map.value( m_element ).toString() ); } } + else + cWarning() << "Invalid YAML data for GeoIPJSON"; } catch ( YAML::Exception& e ) { diff --git a/src/modules/locale/GeoIPJSON.h b/src/modules/locale/GeoIPJSON.h index 26a0560f6..dbe1eeffa 100644 --- a/src/modules/locale/GeoIPJSON.h +++ b/src/modules/locale/GeoIPJSON.h @@ -28,8 +28,12 @@ * * The data is assumed to be in JSON format with a time_zone attribute. */ -struct GeoIPJSON : public GeoIP +class GeoIPJSON : public GeoIP { +public: + explicit GeoIPJSON( const QString& attribute ); + explicit GeoIPJSON(); + virtual RegionZonePair processReply( const QByteArray& ); } ; diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index d4522836c..4848f1a2d 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -76,6 +76,9 @@ GeoIPTests::testJSONbad() tz = handler.processReply( "404 Forbidden" ); QCOMPARE( tz.first, QString() ); + + tz = handler.processReply( "{ time zone = 'America/LosAngeles'}" ); + QCOMPARE( tz.first, QString() ); } diff --git a/src/modules/locale/GeoIPXML.cpp b/src/modules/locale/GeoIPXML.cpp index 28761e163..a2117b2f2 100644 --- a/src/modules/locale/GeoIPXML.cpp +++ b/src/modules/locale/GeoIPXML.cpp @@ -23,6 +23,17 @@ #include #include +GeoIPXML::GeoIPXML( const QString& element ) + : GeoIP( element ) +{ +} + +GeoIPXML::GeoIPXML() + : GeoIPXML( QLatin1Literal( "TimeZone" ) ) +{ +} + + GeoIP::RegionZonePair GeoIPXML::processReply( const QByteArray& data ) { @@ -32,7 +43,7 @@ GeoIPXML::processReply( const QByteArray& data ) QDomDocument doc; if ( doc.setContent( data, false, &domError, &errorLine, &errorColumn ) ) { - const auto tzElements = doc.elementsByTagName( "TimeZone" ); + const auto tzElements = doc.elementsByTagName( m_element ); cDebug() << "GeoIP found" << tzElements.length() << "elements"; for ( int it = 0; it < tzElements.length(); ++it ) { diff --git a/src/modules/locale/GeoIPXML.h b/src/modules/locale/GeoIPXML.h index adffc5bca..bda359485 100644 --- a/src/modules/locale/GeoIPXML.h +++ b/src/modules/locale/GeoIPXML.h @@ -28,8 +28,14 @@ * element, which contains the text (string) for the region/zone. This * format is expected by, e.g. the Ubiquity installer. */ -struct GeoIPXML : public GeoIP +class GeoIPXML : public GeoIP { +public: + /** @brief Configure the element name which is selected. */ + explicit GeoIPXML( const QString& element ); + /** @brief Use default TimeZone element. */ + explicit GeoIPXML(); + virtual RegionZonePair processReply( const QByteArray& ); } ; From b1b59b27b277d9d294da5c16eece56754395a951 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 05:05:06 -0400 Subject: [PATCH 08/16] [locale] Expand tests for alternate selectors - Check that the alternate selectors are used --- src/modules/locale/GeoIPTests.cpp | 42 ++++++++++++++++++++++++------- src/modules/locale/GeoIPTests.h | 2 ++ 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index 4848f1a2d..554e6f0c0 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -40,14 +40,14 @@ GeoIPTests::initTestCase() { } +static const char json_data_attribute[] = + "{\"time_zone\":\"Europe/Amsterdam\"}"; + void GeoIPTests::testJSON() { - static const char data[] = - "{\"time_zone\":\"Europe/Amsterdam\"}"; - GeoIPJSON handler; - auto tz = handler.processReply( data ); + auto tz = handler.processReply( json_data_attribute ); QCOMPARE( tz.first, QLatin1String( "Europe" ) ); QCOMPARE( tz.second, QLatin1String( "Amsterdam" ) ); @@ -60,6 +60,18 @@ GeoIPTests::testJSON() QCOMPARE( tz.first, "America" ); } +void GeoIPTests::testJSONalt() +{ + GeoIPJSON handler( "zona_de_hora" ); + + auto tz = handler.processReply( json_data_attribute ); + QCOMPARE( tz.first, QString() ); // Not found + + tz = handler.processReply( "tarifa: 12\nzona_de_hora: Europe/Madrid" ); + QCOMPARE( tz.first, QLatin1String( "Europe" ) ); + QCOMPARE( tz.second, QLatin1String( "Madrid" ) ); +} + void GeoIPTests::testJSONbad() { @@ -82,10 +94,7 @@ GeoIPTests::testJSONbad() } -void -GeoIPTests::testXML() -{ - static const char data[] = +static const char xml_data_ubiquity[] = R"( 85.150.1.1 OK @@ -102,9 +111,12 @@ GeoIPTests::testXML() Europe/Amsterdam )"; +void +GeoIPTests::testXML() +{ #ifdef HAVE_XML GeoIPXML handler; - auto tz = handler.processReply( data ); + auto tz = handler.processReply( xml_data_ubiquity ); QCOMPARE( tz.first, QLatin1String( "Europe" ) ); QCOMPARE( tz.second, QLatin1String( "Amsterdam" ) ); @@ -126,6 +138,18 @@ GeoIPTests::testXML2() #endif } + +void GeoIPTests::testXMLalt() +{ +#ifdef HAvE_XML + GeoIPXML handler( "ZT" ); + + auto tz = handler.processReply( "Moon/Dark_side" ); + QCOMPARE( tz.first, QLatin1String( "Moon" ) ); + QCOMPARE( tz.second, QLatin1String( "Dark_side" ) ); +#endif +} + void GeoIPTests::testXMLbad() { diff --git a/src/modules/locale/GeoIPTests.h b/src/modules/locale/GeoIPTests.h index e673a0740..87918ace0 100644 --- a/src/modules/locale/GeoIPTests.h +++ b/src/modules/locale/GeoIPTests.h @@ -31,9 +31,11 @@ public: private Q_SLOTS: void initTestCase(); void testJSON(); + void testJSONalt(); void testJSONbad(); void testXML(); void testXML2(); + void testXMLalt(); void testXMLbad(); }; From 352b385b121e447c11db80ec0d9c6b541342a084 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 05:16:23 -0400 Subject: [PATCH 09/16] [locale] Make the selector configurable via the config file --- src/modules/locale/LocaleViewStep.cpp | 7 ++++--- src/modules/locale/LocaleViewStep.h | 6 ++++-- src/modules/locale/locale.conf | 13 ++++++++++++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/modules/locale/LocaleViewStep.cpp b/src/modules/locale/LocaleViewStep.cpp index 73121581c..4a6eb229a 100644 --- a/src/modules/locale/LocaleViewStep.cpp +++ b/src/modules/locale/LocaleViewStep.cpp @@ -124,16 +124,16 @@ LocaleViewStep::fetchGeoIpTimezone() if ( m_geoipStyle.isEmpty() || m_geoipStyle == "legacy" ) { actualUrl.append( "/json/" ); - handler = new GeoIPJSON; + handler = new GeoIPJSON( m_geoipSelector ); } else if ( m_geoipStyle == "json" ) { - handler = new GeoIPJSON; + handler = new GeoIPJSON( m_geoipSelector ); } #if defined(HAVE_XML) else if ( m_geoipStyle == "xml" ) { - handler = new GeoIPXML; + handler = new GeoIPXML( m_geoipSelector ); } #endif else @@ -295,4 +295,5 @@ LocaleViewStep::setConfigurationMap( const QVariantMap& configurationMap ) // Optional m_geoipUrl = CalamaresUtils::getString( configurationMap, "geoipUrl" ); m_geoipStyle = CalamaresUtils::getString( configurationMap, "geoipStyle" ); + m_geoipSelector = CalamaresUtils::getString( configurationMap, "geoipSelector" ); } diff --git a/src/modules/locale/LocaleViewStep.h b/src/modules/locale/LocaleViewStep.h index 003978d6a..b02f6adbd 100644 --- a/src/modules/locale/LocaleViewStep.h +++ b/src/modules/locale/LocaleViewStep.h @@ -75,8 +75,10 @@ private: QPair< QString, QString > m_startingTimezone; QString m_localeGenPath; - QString m_geoipUrl; - QString m_geoipStyle; + + QString m_geoipUrl; // The URL, depening on style might be modified on lookup + QString m_geoipStyle; // String selecting which kind of geoip data to expect + QString m_geoipSelector; // String selecting data from the geoip lookup QList< Calamares::job_ptr > m_jobs; }; diff --git a/src/modules/locale/locale.conf b/src/modules/locale/locale.conf index 327b53784..643ccd7c1 100644 --- a/src/modules/locale/locale.conf +++ b/src/modules/locale/locale.conf @@ -37,7 +37,9 @@ zone: "New_York" # the URL may be modified before use. The request should return # valid data in a suitable format, depending on geoipStyle; # generally this includes a string value with the timezone -# in / format. +# in / format. For services that return data which +# does not follow the conventions of "suitable data" described +# below, *geoIPSelector* may be used to pick different data. # # Note that this example URL works, but the service is shutting # down in June 2018. @@ -68,3 +70,12 @@ zone: "New_York" # shutting down in June 2018. There are other providers with the same # format. XML format is provided for Ubiquity. #geoipStyle: "legacy" + +# GeoIP selector. Leave commented out for the default selector +# (which depends on the style: JSON uses "time_zone" and XML +# uses TimeZone, for the FreeGeoIP-alike and the Ubiquity-alike +# respectively). If the service configured via *geoipUrl* uses +# a different attribute name (e.g. "timezone") in JSON or a +# different element tag (e.g. "") in XML, set this +# string to the name or tag to be used. +#geoipSelector: "" From fa5d40006cc22b51dd231052367684eb107e3915 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 05:27:01 -0400 Subject: [PATCH 10/16] [locale] Fix interpretation of configured selector - In GeoIP handler constructors that take a string (to configure the selector to use), interpret the empty string (which generally isn't a meaningful selector) as meaning "use the default". - Drop the no-argument constructors in favor of a default-argument which is empty. --- src/modules/locale/GeoIPJSON.cpp | 8 +------- src/modules/locale/GeoIPJSON.h | 8 ++++++-- src/modules/locale/GeoIPXML.cpp | 8 +------- src/modules/locale/GeoIPXML.h | 10 ++++++---- 4 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/modules/locale/GeoIPJSON.cpp b/src/modules/locale/GeoIPJSON.cpp index aa5a2b411..b5cf40214 100644 --- a/src/modules/locale/GeoIPJSON.cpp +++ b/src/modules/locale/GeoIPJSON.cpp @@ -27,16 +27,10 @@ #include GeoIPJSON::GeoIPJSON(const QString& attribute) - : GeoIP( attribute ) + : GeoIP( attribute.isEmpty() ? QLatin1String( "time_zone" ) : attribute ) { } -GeoIPJSON::GeoIPJSON() - : GeoIPJSON( QLatin1Literal( "time_zone" ) ) -{ -} - - GeoIP::RegionZonePair GeoIPJSON::processReply( const QByteArray& data ) { diff --git a/src/modules/locale/GeoIPJSON.h b/src/modules/locale/GeoIPJSON.h index dbe1eeffa..3c08f577b 100644 --- a/src/modules/locale/GeoIPJSON.h +++ b/src/modules/locale/GeoIPJSON.h @@ -31,8 +31,12 @@ class GeoIPJSON : public GeoIP { public: - explicit GeoIPJSON( const QString& attribute ); - explicit GeoIPJSON(); + /** @brief Configure the attribute name which is selected. + * + * If an empty string is passed in (not a valid attribute name), + * then "time_zone" is used. + */ + explicit GeoIPJSON( const QString& attribute = QString() ); virtual RegionZonePair processReply( const QByteArray& ); } ; diff --git a/src/modules/locale/GeoIPXML.cpp b/src/modules/locale/GeoIPXML.cpp index a2117b2f2..a9aa43f76 100644 --- a/src/modules/locale/GeoIPXML.cpp +++ b/src/modules/locale/GeoIPXML.cpp @@ -24,16 +24,10 @@ #include GeoIPXML::GeoIPXML( const QString& element ) - : GeoIP( element ) + : GeoIP( element.isEmpty() ? QLatin1String( "TimeZone" ) : element ) { } -GeoIPXML::GeoIPXML() - : GeoIPXML( QLatin1Literal( "TimeZone" ) ) -{ -} - - GeoIP::RegionZonePair GeoIPXML::processReply( const QByteArray& data ) { diff --git a/src/modules/locale/GeoIPXML.h b/src/modules/locale/GeoIPXML.h index bda359485..bc3f23bec 100644 --- a/src/modules/locale/GeoIPXML.h +++ b/src/modules/locale/GeoIPXML.h @@ -31,10 +31,12 @@ class GeoIPXML : public GeoIP { public: - /** @brief Configure the element name which is selected. */ - explicit GeoIPXML( const QString& element ); - /** @brief Use default TimeZone element. */ - explicit GeoIPXML(); + /** @brief Configure the element tag which is selected. + * + * If an empty string is passed in (not a valid element tag), + * then "TimeZone" is used. + */ + explicit GeoIPXML( const QString& element = QString() ); virtual RegionZonePair processReply( const QByteArray& ); } ; From d04e243c4e1ce57237516de51d605a089c96d3d9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 05:45:48 -0400 Subject: [PATCH 11/16] [locale] Auto-clean up time zone data - Some providers return weirdly escaped data; strip out useless escaping before splitting (there are no characters in correct time zone names that need escaping) - Add some tests for TZ splitting --- src/modules/locale/GeoIP.cpp | 5 ++++- src/modules/locale/GeoIPTests.cpp | 24 ++++++++++++++++++++++++ src/modules/locale/GeoIPTests.h | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/modules/locale/GeoIP.cpp b/src/modules/locale/GeoIP.cpp index f11a44db7..3001273bb 100644 --- a/src/modules/locale/GeoIP.cpp +++ b/src/modules/locale/GeoIP.cpp @@ -30,8 +30,11 @@ GeoIP::~GeoIP() } GeoIP::RegionZonePair -GeoIP::splitTZString( const QString& timezoneString ) +GeoIP::splitTZString( const QString& tz ) { + QString timezoneString( tz ); + timezoneString.remove( '\\' ); + QStringList tzParts = timezoneString.split( '/', QString::SkipEmptyParts ); if ( tzParts.size() >= 2 ) { diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index 554e6f0c0..5b5c27bff 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -165,3 +165,27 @@ GeoIPTests::testXMLbad() QCOMPARE( tz.first, QString() ); #endif } + +void GeoIPTests::testSplitTZ() +{ + auto tz = GeoIP::splitTZString( QLatin1String("Moon/Dark_side") ); + QCOMPARE( tz.first, QLatin1String("Moon") ); + QCOMPARE( tz.second, QLatin1String("Dark_side") ); + + // Some providers return weirdly escaped data + tz = GeoIP::splitTZString( QLatin1String("America\\/NewYork") ); + QCOMPARE( tz.first, QLatin1String("America") ); + QCOMPARE( tz.second, QLatin1String("NewYork") ); // That's not actually the zone name + + // Check that bogus data fails + tz = GeoIP::splitTZString( QString() ); + QCOMPARE( tz.first, QString() ); + + tz = GeoIP::splitTZString( QLatin1String("America.NewYork") ); + QCOMPARE( tz.first, QString() ); + + // Check that three-level is split properly + tz = GeoIP::splitTZString( QLatin1String("America/North Dakota/Beulah") ); + QCOMPARE( tz.first, QLatin1String("America") ); + QCOMPARE( tz.second, QLatin1String("North Dakota/Beulah") ); +} diff --git a/src/modules/locale/GeoIPTests.h b/src/modules/locale/GeoIPTests.h index 87918ace0..7aaefee81 100644 --- a/src/modules/locale/GeoIPTests.h +++ b/src/modules/locale/GeoIPTests.h @@ -37,6 +37,7 @@ private Q_SLOTS: void testXML2(); void testXMLalt(); void testXMLbad(); + void testSplitTZ(); }; #endif From 0f5e061c4ae50d4db643a598846fce820fb43f7d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 09:13:06 -0400 Subject: [PATCH 12/16] [locale] Support multi-level selection from JSON data - Some providers don't provide a single flat JSON object (e.g. "{time_zone: foo}") but a nested structure (e.g. "{location: {time_zone: foo}}"), so allow dots in the selector to do multi-level selection. --- src/modules/locale/GeoIPJSON.cpp | 26 ++++++++++++++++++++------ src/modules/locale/locale.conf | 11 +++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/modules/locale/GeoIPJSON.cpp b/src/modules/locale/GeoIPJSON.cpp index b5cf40214..ee99e6c11 100644 --- a/src/modules/locale/GeoIPJSON.cpp +++ b/src/modules/locale/GeoIPJSON.cpp @@ -19,6 +19,7 @@ #include "GeoIPJSON.h" +#include "utils/CalamaresUtils.h" #include "utils/Logger.h" #include "utils/YamlUtils.h" @@ -31,6 +32,24 @@ GeoIPJSON::GeoIPJSON(const QString& attribute) { } +static QString +selectMap( const QVariantMap& m, const QStringList& l, int index) +{ + if ( index >= l.count() ) + return QString(); + + QString attributeName = l[index]; + if ( index == l.count() - 1 ) + return CalamaresUtils::getString( m, attributeName ); + else + { + bool success = false; // bogus + if ( m.contains( attributeName ) ) + return selectMap( CalamaresUtils::getSubMap( m, attributeName, success ), l, index+1 ); + return QString(); + } +} + GeoIP::RegionZonePair GeoIPJSON::processReply( const QByteArray& data ) { @@ -43,12 +62,7 @@ GeoIPJSON::processReply( const QByteArray& data ) var.isValid() && var.type() == QVariant::Map ) { - QVariantMap map = var.toMap(); - if ( map.contains( m_element ) && - !map.value( m_element ).toString().isEmpty() ) - { - return splitTZString( map.value( m_element ).toString() ); - } + return splitTZString( selectMap( var.toMap(), m_element.split('.'), 0 ) ); } else cWarning() << "Invalid YAML data for GeoIPJSON"; diff --git a/src/modules/locale/locale.conf b/src/modules/locale/locale.conf index 643ccd7c1..262345c7e 100644 --- a/src/modules/locale/locale.conf +++ b/src/modules/locale/locale.conf @@ -78,4 +78,15 @@ zone: "New_York" # a different attribute name (e.g. "timezone") in JSON or a # different element tag (e.g. "") in XML, set this # string to the name or tag to be used. +# +# In JSON: +# - if the string contains "." characters, this is used as a +# multi-level selector, e.g. "a.b" will select the timezone +# from data "{a: {b: "Europe/Amsterdam" } }". +# - each part of the string split by "." characters is used as +# a key into the JSON data. +# In XML: +# - all elements with the named tag (e.g. all TimeZone) elements +# from the document are checked; the first one with non-empty +# text value is used. #geoipSelector: "" From 3ef0fbe892ce981f83b4137b7ffc4ea159196cb8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 16 Apr 2018 09:17:18 -0400 Subject: [PATCH 13/16] [locale] Add tests for a bunch of GeoIP providers - Since these tests use network resources, they are not enabled by default. Set the environment variable TEST_HTTP_GET to actually do them. - Do one request for each provider and check that they are all consistent. (This works for me, yielding Europe/Amsterdam for all). --- src/modules/locale/GeoIPTests.cpp | 63 ++++++++++++++++++++++++++++++- src/modules/locale/GeoIPTests.h | 2 + 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index 5b5c27bff..32faf7138 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -141,7 +141,7 @@ GeoIPTests::testXML2() void GeoIPTests::testXMLalt() { -#ifdef HAvE_XML +#ifdef HAVE_XML GeoIPXML handler( "ZT" ); auto tz = handler.processReply( "Moon/Dark_side" ); @@ -189,3 +189,64 @@ void GeoIPTests::testSplitTZ() QCOMPARE( tz.first, QLatin1String("America") ); QCOMPARE( tz.second, QLatin1String("North Dakota/Beulah") ); } + + +static QByteArray +synchronous_get( const char* urlstring ) +{ + QUrl url( urlstring ); + QNetworkAccessManager manager; + QEventLoop loop; + + QObject::connect( &manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit ); + + QNetworkRequest request( url ); + QNetworkReply* reply = manager.get( request ); + loop.exec(); + reply->deleteLater(); + return reply->readAll(); +} + +#define CHECK_GET(t, selector, url) \ + { \ + auto tz = GeoIP##t( selector ).processReply( synchronous_get( url ) ); \ + QCOMPARE( default_tz, tz ); \ + qDebug() << "Checked" << url; \ + } + +void GeoIPTests::testGet() +{ + if ( !QProcessEnvironment::systemEnvironment().contains( QLatin1String("TEST_HTTP_GET") ) ) + { + qDebug() << "Skipping HTTP GET tests"; + return; + } + + GeoIPJSON default_handler; + // Call the KDE service the definitive source, even though this + // service is temporary and might go away any time. + auto default_tz = default_handler.processReply( synchronous_get( "http://drax.kde.org:9129/calamares" ) ); + + // This is bogus, because the test isn't always run by me + // QCOMPARE( default_tz.first, QLatin1String("Europe") ); + // QCOMPARE( default_tz.second, QLatin1String("Amsterdam") ); + QVERIFY( !default_tz.first.isEmpty() ); + QVERIFY( !default_tz.second.isEmpty() ); + + // Each expansion of CHECK_GET does a synchronous GET, then checks that + // the TZ data is the same as the default_tz; this is fragile if the + // services don't agree on the location of where the test is run. + CHECK_GET( JSON, QString(), "http://drax.kde.org:9129/calamares" ) // Temporary KDE service + CHECK_GET( JSON, QString(), "http://freegeoip.net/json/" ) // Original FreeGeoIP service + CHECK_GET( JSON, QLatin1String("timezone"), "https://ipapi.co/json" ) // Different JSON + CHECK_GET( JSON, QLatin1String("timezone"), "http://ip-api.com/json" ) + + CHECK_GET( JSON, QLatin1String("location.time_zone"), "http://geoip.nekudo.com/api/" ) // 2-level JSON + + CHECK_GET( JSON, QLatin1String("Location.TimeZone"), "http://drax.kde.org:9129/" ) // 2-level JSON + +#ifdef HAVE_XML + CHECK_GET( XML, QString(), "http://geoip.ubuntu.com/lookup" ) // Ubiquity's XML format + CHECK_GET( XML, QString(), "http://drax.kde.org:9129/ubiquity" ) // Temporary KDE service +#endif +} diff --git a/src/modules/locale/GeoIPTests.h b/src/modules/locale/GeoIPTests.h index 7aaefee81..a320e3263 100644 --- a/src/modules/locale/GeoIPTests.h +++ b/src/modules/locale/GeoIPTests.h @@ -38,6 +38,8 @@ private Q_SLOTS: void testXMLalt(); void testXMLbad(); void testSplitTZ(); + + void testGet(); }; #endif From b4e4b691fdf2e9217de397f2d9edbc513985daa9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 17 Apr 2018 07:32:27 -0400 Subject: [PATCH 14/16] [locale] Accomodate more dodgy GeoIP providers - Force spaces to _ - Document the bits FIXES #933 --- src/modules/locale/GeoIP.cpp | 1 + src/modules/locale/GeoIP.h | 10 +++++++++- src/modules/locale/locale.conf | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/modules/locale/GeoIP.cpp b/src/modules/locale/GeoIP.cpp index 3001273bb..4c031f286 100644 --- a/src/modules/locale/GeoIP.cpp +++ b/src/modules/locale/GeoIP.cpp @@ -34,6 +34,7 @@ GeoIP::splitTZString( const QString& tz ) { QString timezoneString( tz ); timezoneString.remove( '\\' ); + timezoneString.replace( ' ', '_' ); QStringList tzParts = timezoneString.split( '/', QString::SkipEmptyParts ); if ( tzParts.size() >= 2 ) diff --git a/src/modules/locale/GeoIP.h b/src/modules/locale/GeoIP.h index 6088c8a45..41abd2042 100644 --- a/src/modules/locale/GeoIP.h +++ b/src/modules/locale/GeoIP.h @@ -50,7 +50,15 @@ public: */ virtual RegionZonePair processReply( const QByteArray& ) = 0; - /** @brief Splits a region/zone string into a pair. */ + /** @brief Splits a region/zone string into a pair. + * + * Cleans up the string by removing backslashes (\\) + * since some providers return silly-escaped names. Replaces + * spaces with _ since some providers return human-readable names. + * Splits on the first / in the resulting string, or returns a + * pair of empty QStrings if it can't. (e.g. America/North Dakota/Beulah + * will return "America", "North_Dakota/Beulah"). + */ static RegionZonePair splitTZString( const QString& s ); protected: diff --git a/src/modules/locale/locale.conf b/src/modules/locale/locale.conf index 262345c7e..ddd0bc97e 100644 --- a/src/modules/locale/locale.conf +++ b/src/modules/locale/locale.conf @@ -53,6 +53,11 @@ zone: "New_York" # Europe/Brussels # ``` # +# To accomodate providers of GeoIP timezone data with peculiar timezone +# naming conventions, the following cleanups are performed automatically: +# - backslashes are removed +# - spaces are replaced with _ +# #geoipUrl: "freegeoip.net" # GeoIP style. Leave commented out for the "legacy" interpretation. From 5acf67a05778079b57586e13f5ffa3066742a46a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 17 Apr 2018 07:39:51 -0400 Subject: [PATCH 15/16] [locale] Fix tests with spaces in zone names - "North Dakota" -> "North_Dakota" following the change that fixes up dodgy names automatically. --- src/modules/locale/GeoIPTests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index 32faf7138..a98aa25ee 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -127,14 +127,14 @@ void GeoIPTests::testXML2() { static const char data[] = - "America/North Dakota/Beulah"; + "America/North Dakota/Beulah"; // With a space! #ifdef HAVE_XML GeoIPXML handler; auto tz = handler.processReply( data ); QCOMPARE( tz.first, QLatin1String( "America" ) ); - QCOMPARE( tz.second, QLatin1String( "North Dakota/Beulah" ) ); + QCOMPARE( tz.second, QLatin1String( "North_Dakota/Beulah" ) ); // Without space #endif } @@ -184,10 +184,10 @@ void GeoIPTests::testSplitTZ() tz = GeoIP::splitTZString( QLatin1String("America.NewYork") ); QCOMPARE( tz.first, QString() ); - // Check that three-level is split properly + // Check that three-level is split properly and space is replaced tz = GeoIP::splitTZString( QLatin1String("America/North Dakota/Beulah") ); QCOMPARE( tz.first, QLatin1String("America") ); - QCOMPARE( tz.second, QLatin1String("North Dakota/Beulah") ); + QCOMPARE( tz.second, QLatin1String("North_Dakota/Beulah") ); } From 522adf766a2ce8b40ba88bc328c837d8e5df8005 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 17 Apr 2018 07:38:19 -0400 Subject: [PATCH 16/16] [locale] Switch HTTP GET test to KDE servers - Use the official name of the KDE GeoIP service - Log the URL *before* the check, in case one fails --- src/modules/locale/GeoIPTests.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/locale/GeoIPTests.cpp b/src/modules/locale/GeoIPTests.cpp index a98aa25ee..8739b47ac 100644 --- a/src/modules/locale/GeoIPTests.cpp +++ b/src/modules/locale/GeoIPTests.cpp @@ -198,6 +198,8 @@ synchronous_get( const char* urlstring ) QNetworkAccessManager manager; QEventLoop loop; + qDebug() << "Fetching" << url; + QObject::connect( &manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit ); QNetworkRequest request( url ); @@ -211,7 +213,6 @@ synchronous_get( const char* urlstring ) { \ auto tz = GeoIP##t( selector ).processReply( synchronous_get( url ) ); \ QCOMPARE( default_tz, tz ); \ - qDebug() << "Checked" << url; \ } void GeoIPTests::testGet() @@ -223,9 +224,8 @@ void GeoIPTests::testGet() } GeoIPJSON default_handler; - // Call the KDE service the definitive source, even though this - // service is temporary and might go away any time. - auto default_tz = default_handler.processReply( synchronous_get( "http://drax.kde.org:9129/calamares" ) ); + // Call the KDE service the definitive source. + auto default_tz = default_handler.processReply( synchronous_get( "https://geoip.kde.org/v1/calamares" ) ); // This is bogus, because the test isn't always run by me // QCOMPARE( default_tz.first, QLatin1String("Europe") ); @@ -236,17 +236,17 @@ void GeoIPTests::testGet() // Each expansion of CHECK_GET does a synchronous GET, then checks that // the TZ data is the same as the default_tz; this is fragile if the // services don't agree on the location of where the test is run. - CHECK_GET( JSON, QString(), "http://drax.kde.org:9129/calamares" ) // Temporary KDE service + CHECK_GET( JSON, QString(), "https://geoip.kde.org/v1/calamares" ) // Check it's consistent CHECK_GET( JSON, QString(), "http://freegeoip.net/json/" ) // Original FreeGeoIP service CHECK_GET( JSON, QLatin1String("timezone"), "https://ipapi.co/json" ) // Different JSON CHECK_GET( JSON, QLatin1String("timezone"), "http://ip-api.com/json" ) CHECK_GET( JSON, QLatin1String("location.time_zone"), "http://geoip.nekudo.com/api/" ) // 2-level JSON - CHECK_GET( JSON, QLatin1String("Location.TimeZone"), "http://drax.kde.org:9129/" ) // 2-level JSON + CHECK_GET( JSON, QLatin1String("Location.TimeZone"), "https://geoip.kde.org/debug" ) // 2-level JSON #ifdef HAVE_XML CHECK_GET( XML, QString(), "http://geoip.ubuntu.com/lookup" ) // Ubiquity's XML format - CHECK_GET( XML, QString(), "http://drax.kde.org:9129/ubiquity" ) // Temporary KDE service + CHECK_GET( XML, QString(), "https://geoip.kde.org/v1/ubiquity" ) // Temporary KDE service #endif }