From 987bcc09bd11474e448ff47ab6c6af8bb6f1e9d3 Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Fri, 1 Mar 2024 14:55:05 +0300 Subject: [PATCH 01/16] Switched from ip to tz for geolocation --- static/files/countries.json | 251 +++ static/files/timezones.json | 3560 +++++++++++++++++++++++++++++++++ static/js/src/intlTelInput.js | 3 +- webapp/app.py | 4 +- webapp/views.py | 22 +- 5 files changed, 3835 insertions(+), 5 deletions(-) create mode 100644 static/files/countries.json create mode 100644 static/files/timezones.json diff --git a/static/files/countries.json b/static/files/countries.json new file mode 100644 index 00000000000..ff5aba35b8d --- /dev/null +++ b/static/files/countries.json @@ -0,0 +1,251 @@ +{ + "AD": "Andorra", + "AE": "United Arab Emirates", + "AF": "Afghanistan", + "AG": "Antigua and Barbuda", + "AI": "Anguilla", + "AL": "Albania", + "AM": "Armenia", + "AO": "Angola", + "AQ": "Antarctica", + "AR": "Argentina", + "AS": "American Samoa", + "AT": "Austria", + "AU": "Australia", + "AW": "Aruba", + "AX": "Åland Islands", + "AZ": "Azerbaijan", + "BA": "Bosnia and Herzegovina", + "BB": "Barbados", + "BD": "Bangladesh", + "BE": "Belgium", + "BF": "Burkina Faso", + "BG": "Bulgaria", + "BH": "Bahrain", + "BI": "Burundi", + "BJ": "Benin", + "BL": "Saint Barthélemy", + "BM": "Bermuda", + "BN": "Brunei", + "BO": "Bolivia", + "BQ": "Caribbean Netherlands", + "BR": "Brazil", + "BS": "Bahamas", + "BT": "Bhutan", + "BV": "Bouvet Island", + "BW": "Botswana", + "BY": "Belarus", + "BZ": "Belize", + "CA": "Canada", + "CC": "Cocos Islands", + "CD": "Democratic Republic of the Congo", + "CF": "Central African Republic", + "CG": "Republic of the Congo", + "CH": "Switzerland", + "CI": "Ivory Coast", + "CK": "Cook Islands", + "CL": "Chile", + "CM": "Cameroon", + "CN": "China", + "CO": "Colombia", + "CR": "Costa Rica", + "CU": "Cuba", + "CV": "Cabo Verde", + "CW": "Curaçao", + "CX": "Christmas Island", + "CY": "Cyprus", + "CZ": "Czechia", + "DE": "Germany", + "DJ": "Djibouti", + "DK": "Denmark", + "DM": "Dominica", + "DO": "Dominican Republic", + "DZ": "Algeria", + "EC": "Ecuador", + "EE": "Estonia", + "EG": "Egypt", + "EH": "Western Sahara", + "ER": "Eritrea", + "ES": "Spain", + "ET": "Ethiopia", + "FI": "Finland", + "FJ": "Fiji", + "FK": "Falkland Islands", + "FM": "Micronesia", + "FO": "Faroe Islands", + "FR": "France", + "GA": "Gabon", + "GB": "United Kingdom", + "GD": "Grenada", + "GE": "Georgia", + "GF": "French Guiana", + "GG": "Guernsey", + "GH": "Ghana", + "GI": "Gibraltar", + "GL": "Greenland", + "GM": "Gambia", + "GN": "Guinea", + "GP": "Guadeloupe", + "GQ": "Equatorial Guinea", + "GR": "Greece", + "GS": "South Georgia and the South Sandwich Islands", + "GT": "Guatemala", + "GU": "Guam", + "GW": "Guinea-Bissau", + "GY": "Guyana", + "HK": "Hong Kong", + "HM": "Heard Island and McDonald Islands", + "HN": "Honduras", + "HR": "Croatia", + "HT": "Haiti", + "HU": "Hungary", + "ID": "Indonesia", + "IE": "Ireland", + "IL": "Israel", + "IM": "Isle of Man", + "IN": "India", + "IO": "British Indian Ocean Territory", + "IQ": "Iraq", + "IR": "Iran", + "IS": "Iceland", + "IT": "Italy", + "JE": "Jersey", + "JM": "Jamaica", + "JO": "Jordan", + "JP": "Japan", + "KE": "Kenya", + "KG": "Kyrgyzstan", + "KH": "Cambodia", + "KI": "Kiribati", + "KM": "Comoros", + "KN": "Saint Kitts and Nevis", + "KP": "North Korea", + "KR": "South Korea", + "KW": "Kuwait", + "KY": "Cayman Islands", + "KZ": "Kazakhstan", + "LA": "Laos", + "LB": "Lebanon", + "LC": "Saint Lucia", + "LI": "Liechtenstein", + "LK": "Sri Lanka", + "LR": "Liberia", + "LS": "Lesotho", + "LT": "Lithuania", + "LU": "Luxembourg", + "LV": "Latvia", + "LY": "Libya", + "MA": "Morocco", + "MC": "Monaco", + "MD": "Moldova", + "ME": "Montenegro", + "MF": "Saint Martin", + "MG": "Madagascar", + "MH": "Marshall Islands", + "MK": "North Macedonia", + "ML": "Mali", + "MM": "Myanmar", + "MN": "Mongolia", + "MO": "Macao", + "MP": "Northern Mariana Islands", + "MQ": "Martinique", + "MR": "Mauritania", + "MS": "Montserrat", + "MT": "Malta", + "MU": "Mauritius", + "MV": "Maldives", + "MW": "Malawi", + "MX": "Mexico", + "MY": "Malaysia", + "MZ": "Mozambique", + "NA": "Namibia", + "NC": "New Caledonia", + "NE": "Niger", + "NF": "Norfolk Island", + "NG": "Nigeria", + "NI": "Nicaragua", + "NL": "Netherlands", + "NO": "Norway", + "NP": "Nepal", + "NR": "Nauru", + "NU": "Niue", + "NZ": "New Zealand", + "OM": "Oman", + "PA": "Panama", + "PE": "Peru", + "PF": "French Polynesia", + "PG": "Papua New Guinea", + "PH": "Philippines", + "PK": "Pakistan", + "PL": "Poland", + "PM": "Saint Pierre and Miquelon", + "PN": "Pitcairn", + "PR": "Puerto Rico", + "PS": "Palestine", + "PT": "Portugal", + "PW": "Palau", + "PY": "Paraguay", + "QA": "Qatar", + "RE": "Réunion", + "RO": "Romania", + "RS": "Serbia", + "RU": "Russia", + "RW": "Rwanda", + "SA": "Saudi Arabia", + "SB": "Solomon Islands", + "SC": "Seychelles", + "SD": "Sudan", + "SE": "Sweden", + "SG": "Singapore", + "SH": "Saint Helena, Ascension and Tristan da Cunha", + "SI": "Slovenia", + "SJ": "Svalbard and Jan Mayen", + "SK": "Slovakia", + "SL": "Sierra Leone", + "SM": "San Marino", + "SN": "Senegal", + "SO": "Somalia", + "SR": "Suriname", + "SS": "South Sudan", + "ST": "Sao Tome and Principe", + "SV": "El Salvador", + "SX": "Sint Maarten", + "SY": "Syria", + "SZ": "Eswatini", + "TC": "Turks and Caicos Islands", + "TD": "Chad", + "TF": "French Southern Territories", + "TG": "Togo", + "TH": "Thailand", + "TJ": "Tajikistan", + "TK": "Tokelau", + "TL": "Timor-Leste", + "TM": "Turkmenistan", + "TN": "Tunisia", + "TO": "Tonga", + "TR": "Turkey", + "TT": "Trinidad and Tobago", + "TV": "Tuvalu", + "TW": "Taiwan", + "TZ": "Tanzania", + "UA": "Ukraine", + "UG": "Uganda", + "UM": "United States Minor Outlying Islands", + "US": "United States of America", + "UY": "Uruguay", + "UZ": "Uzbekistan", + "VA": "Holy See", + "VC": "Saint Vincent and the Grenadines", + "VE": "Venezuela", + "VG": "Virgin Islands (UK)", + "VI": "Virgin Islands (US)", + "VN": "Vietnam", + "VU": "Vanuatu", + "WF": "Wallis and Futuna", + "WS": "Samoa", + "YE": "Yemen", + "YT": "Mayotte", + "ZA": "South Africa", + "ZM": "Zambia", + "ZW": "Zimbabwe" +} \ No newline at end of file diff --git a/static/files/timezones.json b/static/files/timezones.json new file mode 100644 index 00000000000..c7bd1d05d46 --- /dev/null +++ b/static/files/timezones.json @@ -0,0 +1,3560 @@ +{ + "Africa/Abidjan":{ + "u":0, + "c":[ + "CI", + "BF", + "GH", + "GM", + "GN", + "ML", + "MR", + "SH", + "SL", + "SN", + "TG" + ] + }, + "Africa/Accra":{ + "a":"Africa/Abidjan", + "c":[ + "GH" + ], + "r":1 + }, + "Africa/Addis_Ababa":{ + "a":"Africa/Nairobi", + "c":[ + "ET" + ], + "r":1 + }, + "Africa/Algiers":{ + "u":60, + "c":[ + "DZ" + ] + }, + "Africa/Asmara":{ + "a":"Africa/Nairobi", + "c":[ + "ER" + ], + "r":1 + }, + "Africa/Asmera":{ + "a":"Africa/Nairobi", + "c":[ + "ER" + ], + "r":1 + }, + "Africa/Bamako":{ + "a":"Africa/Abidjan", + "c":[ + "ML" + ], + "r":1 + }, + "Africa/Bangui":{ + "a":"Africa/Lagos", + "c":[ + "CF" + ], + "r":1 + }, + "Africa/Banjul":{ + "a":"Africa/Abidjan", + "c":[ + "GM" + ], + "r":1 + }, + "Africa/Bissau":{ + "u":0, + "c":[ + "GW" + ] + }, + "Africa/Blantyre":{ + "a":"Africa/Maputo", + "c":[ + "MW" + ], + "r":1 + }, + "Africa/Brazzaville":{ + "a":"Africa/Lagos", + "c":[ + "CG" + ], + "r":1 + }, + "Africa/Bujumbura":{ + "a":"Africa/Maputo", + "c":[ + "BI" + ], + "r":1 + }, + "Africa/Cairo":{ + "u":120, + "c":[ + "EG" + ] + }, + "Africa/Casablanca":{ + "u":60, + "d":0, + "c":[ + "MA" + ] + }, + "Africa/Ceuta":{ + "u":60, + "d":120, + "c":[ + "ES" + ] + }, + "Africa/Conakry":{ + "a":"Africa/Abidjan", + "c":[ + "GN" + ], + "r":1 + }, + "Africa/Dakar":{ + "a":"Africa/Abidjan", + "c":[ + "SN" + ], + "r":1 + }, + "Africa/Dar_es_Salaam":{ + "a":"Africa/Nairobi", + "c":[ + "TZ" + ], + "r":1 + }, + "Africa/Djibouti":{ + "a":"Africa/Nairobi", + "c":[ + "DJ" + ], + "r":1 + }, + "Africa/Douala":{ + "a":"Africa/Lagos", + "c":[ + "CM" + ], + "r":1 + }, + "Africa/El_Aaiun":{ + "u":60, + "d":0, + "c":[ + "EH" + ] + }, + "Africa/Freetown":{ + "a":"Africa/Abidjan", + "c":[ + "SL" + ], + "r":1 + }, + "Africa/Gaborone":{ + "a":"Africa/Maputo", + "c":[ + "BW" + ], + "r":1 + }, + "Africa/Harare":{ + "a":"Africa/Maputo", + "c":[ + "ZW" + ], + "r":1 + }, + "Africa/Johannesburg":{ + "u":120, + "c":[ + "ZA", + "LS", + "SZ" + ] + }, + "Africa/Juba":{ + "u":120, + "c":[ + "SS" + ] + }, + "Africa/Kampala":{ + "a":"Africa/Nairobi", + "c":[ + "UG" + ], + "r":1 + }, + "Africa/Khartoum":{ + "u":120, + "c":[ + "SD" + ] + }, + "Africa/Kigali":{ + "a":"Africa/Maputo", + "c":[ + "RW" + ], + "r":1 + }, + "Africa/Kinshasa":{ + "a":"Africa/Lagos", + "c":[ + "CD" + ], + "r":1 + }, + "Africa/Lagos":{ + "u":60, + "c":[ + "NG", + "AO", + "BJ", + "CD", + "CF", + "CG", + "CM", + "GA", + "GQ", + "NE" + ] + }, + "Africa/Libreville":{ + "a":"Africa/Lagos", + "c":[ + "GA" + ], + "r":1 + }, + "Africa/Lome":{ + "a":"Africa/Abidjan", + "c":[ + "TG" + ], + "r":1 + }, + "Africa/Luanda":{ + "a":"Africa/Lagos", + "c":[ + "AO" + ], + "r":1 + }, + "Africa/Lubumbashi":{ + "a":"Africa/Maputo", + "c":[ + "CD" + ], + "r":1 + }, + "Africa/Lusaka":{ + "a":"Africa/Maputo", + "c":[ + "ZM" + ], + "r":1 + }, + "Africa/Malabo":{ + "a":"Africa/Lagos", + "c":[ + "GQ" + ], + "r":1 + }, + "Africa/Maputo":{ + "u":120, + "c":[ + "MZ", + "BI", + "BW", + "CD", + "MW", + "RW", + "ZM", + "ZW" + ] + }, + "Africa/Maseru":{ + "a":"Africa/Johannesburg", + "c":[ + "LS" + ], + "r":1 + }, + "Africa/Mbabane":{ + "a":"Africa/Johannesburg", + "c":[ + "SZ" + ], + "r":1 + }, + "Africa/Mogadishu":{ + "a":"Africa/Nairobi", + "c":[ + "SO" + ], + "r":1 + }, + "Africa/Monrovia":{ + "u":0, + "c":[ + "LR" + ] + }, + "Africa/Nairobi":{ + "u":180, + "c":[ + "KE", + "DJ", + "ER", + "ET", + "KM", + "MG", + "SO", + "TZ", + "UG", + "YT" + ] + }, + "Africa/Ndjamena":{ + "u":60, + "c":[ + "TD" + ] + }, + "Africa/Niamey":{ + "a":"Africa/Lagos", + "c":[ + "NE" + ], + "r":1 + }, + "Africa/Nouakchott":{ + "a":"Africa/Abidjan", + "c":[ + "MR" + ], + "r":1 + }, + "Africa/Ouagadougou":{ + "a":"Africa/Abidjan", + "c":[ + "BF" + ], + "r":1 + }, + "Africa/Porto-Novo":{ + "a":"Africa/Lagos", + "c":[ + "BJ" + ], + "r":1 + }, + "Africa/Sao_Tome":{ + "u":0, + "c":[ + "ST" + ] + }, + "Africa/Timbuktu":{ + "a":"Africa/Abidjan", + "c":[ + "ML" + ], + "r":1 + }, + "Africa/Tripoli":{ + "u":120, + "c":[ + "LY" + ] + }, + "Africa/Tunis":{ + "u":60, + "c":[ + "TN" + ] + }, + "Africa/Windhoek":{ + "u":120, + "c":[ + "NA" + ] + }, + "America/Adak":{ + "u":-600, + "d":-540, + "c":[ + "US" + ] + }, + "America/Anchorage":{ + "u":-540, + "d":-480, + "c":[ + "US" + ] + }, + "America/Anguilla":{ + "a":"America/Puerto_Rico", + "c":[ + "AI" + ], + "r":1 + }, + "America/Antigua":{ + "a":"America/Puerto_Rico", + "c":[ + "AG" + ], + "r":1 + }, + "America/Araguaina":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Argentina/Buenos_Aires":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Catamarca":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/ComodRivadavia":{ + "a":"America/Argentina/Catamarca", + "r":1 + }, + "America/Argentina/Cordoba":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Jujuy":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/La_Rioja":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Mendoza":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Rio_Gallegos":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Salta":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/San_Juan":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/San_Luis":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Tucuman":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Argentina/Ushuaia":{ + "u":-180, + "c":[ + "AR" + ] + }, + "America/Aruba":{ + "a":"America/Puerto_Rico", + "c":[ + "AW" + ], + "r":1 + }, + "America/Asuncion":{ + "u":-240, + "d":-180, + "c":[ + "PY" + ] + }, + "America/Atikokan":{ + "a":"America/Panama", + "c":[ + "CA" + ], + "r":1 + }, + "America/Atka":{ + "a":"America/Adak", + "r":1 + }, + "America/Bahia":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Bahia_Banderas":{ + "u":-360, + "d":-300, + "c":[ + "MX" + ] + }, + "America/Barbados":{ + "u":-240, + "c":[ + "BB" + ] + }, + "America/Belem":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Belize":{ + "u":-360, + "c":[ + "BZ" + ] + }, + "America/Blanc-Sablon":{ + "a":"America/Puerto_Rico", + "c":[ + "CA" + ], + "r":1 + }, + "America/Boa_Vista":{ + "u":-240, + "c":[ + "BR" + ] + }, + "America/Bogota":{ + "u":-300, + "c":[ + "CO" + ] + }, + "America/Boise":{ + "u":-420, + "d":-360, + "c":[ + "US" + ] + }, + "America/Buenos_Aires":{ + "a":"America/Argentina/Buenos_Aires", + "r":1 + }, + "America/Cambridge_Bay":{ + "u":-420, + "d":-360, + "c":[ + "CA" + ] + }, + "America/Campo_Grande":{ + "u":-240, + "c":[ + "BR" + ] + }, + "America/Cancun":{ + "u":-300, + "c":[ + "MX" + ] + }, + "America/Caracas":{ + "u":-240, + "c":[ + "VE" + ] + }, + "America/Catamarca":{ + "a":"America/Argentina/Catamarca", + "r":1 + }, + "America/Cayenne":{ + "u":-180, + "c":[ + "GF" + ] + }, + "America/Cayman":{ + "a":"America/Panama", + "c":[ + "KY" + ], + "r":1 + }, + "America/Chicago":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/Chihuahua":{ + "u":-420, + "d":-360, + "c":[ + "MX" + ] + }, + "America/Coral_Harbour":{ + "a":"America/Panama", + "c":[ + "CA" + ], + "r":1 + }, + "America/Cordoba":{ + "a":"America/Argentina/Cordoba", + "r":1 + }, + "America/Costa_Rica":{ + "u":-360, + "c":[ + "CR" + ] + }, + "America/Creston":{ + "a":"America/Phoenix", + "c":[ + "CA" + ], + "r":1 + }, + "America/Cuiaba":{ + "u":-240, + "c":[ + "BR" + ] + }, + "America/Curacao":{ + "a":"America/Puerto_Rico", + "c":[ + "CW" + ], + "r":1 + }, + "America/Danmarkshavn":{ + "u":0, + "c":[ + "GL" + ] + }, + "America/Dawson":{ + "u":-420, + "c":[ + "CA" + ] + }, + "America/Dawson_Creek":{ + "u":-420, + "c":[ + "CA" + ] + }, + "America/Denver":{ + "u":-420, + "d":-360, + "c":[ + "US" + ] + }, + "America/Detroit":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Dominica":{ + "a":"America/Puerto_Rico", + "c":[ + "DM" + ], + "r":1 + }, + "America/Edmonton":{ + "u":-420, + "d":-360, + "c":[ + "CA" + ] + }, + "America/Eirunepe":{ + "u":-300, + "c":[ + "BR" + ] + }, + "America/El_Salvador":{ + "u":-360, + "c":[ + "SV" + ] + }, + "America/Ensenada":{ + "a":"America/Tijuana", + "r":1 + }, + "America/Fort_Nelson":{ + "u":-420, + "c":[ + "CA" + ] + }, + "America/Fort_Wayne":{ + "a":"America/Indiana/Indianapolis", + "r":1 + }, + "America/Fortaleza":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Glace_Bay":{ + "u":-240, + "d":-180, + "c":[ + "CA" + ] + }, + "America/Godthab":{ + "a":"America/Nuuk", + "r":1 + }, + "America/Goose_Bay":{ + "u":-240, + "d":-180, + "c":[ + "CA" + ] + }, + "America/Grand_Turk":{ + "u":-300, + "d":-240, + "c":[ + "TC" + ] + }, + "America/Grenada":{ + "a":"America/Puerto_Rico", + "c":[ + "GD" + ], + "r":1 + }, + "America/Guadeloupe":{ + "a":"America/Puerto_Rico", + "c":[ + "GP" + ], + "r":1 + }, + "America/Guatemala":{ + "u":-360, + "c":[ + "GT" + ] + }, + "America/Guayaquil":{ + "u":-300, + "c":[ + "EC" + ] + }, + "America/Guyana":{ + "u":-240, + "c":[ + "GY" + ] + }, + "America/Halifax":{ + "u":-240, + "d":-180, + "c":[ + "CA" + ] + }, + "America/Havana":{ + "u":-300, + "d":-240, + "c":[ + "CU" + ] + }, + "America/Hermosillo":{ + "u":-420, + "c":[ + "MX" + ] + }, + "America/Indiana/Indianapolis":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Indiana/Knox":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/Indiana/Marengo":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Indiana/Petersburg":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Indiana/Tell_City":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/Indiana/Vevay":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Indiana/Vincennes":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Indiana/Winamac":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Indianapolis":{ + "a":"America/Indiana/Indianapolis", + "r":1 + }, + "America/Inuvik":{ + "u":-420, + "d":-360, + "c":[ + "CA" + ] + }, + "America/Iqaluit":{ + "u":-300, + "d":-240, + "c":[ + "CA" + ] + }, + "America/Jamaica":{ + "u":-300, + "c":[ + "JM" + ] + }, + "America/Jujuy":{ + "a":"America/Argentina/Jujuy", + "r":1 + }, + "America/Juneau":{ + "u":-540, + "d":-480, + "c":[ + "US" + ] + }, + "America/Kentucky/Louisville":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Kentucky/Monticello":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Knox_IN":{ + "a":"America/Indiana/Knox", + "r":1 + }, + "America/Kralendijk":{ + "a":"America/Puerto_Rico", + "c":[ + "BQ" + ], + "r":1 + }, + "America/La_Paz":{ + "u":-240, + "c":[ + "BO" + ] + }, + "America/Lima":{ + "u":-300, + "c":[ + "PE" + ] + }, + "America/Los_Angeles":{ + "u":-480, + "d":-420, + "c":[ + "US" + ] + }, + "America/Louisville":{ + "a":"America/Kentucky/Louisville", + "r":1 + }, + "America/Lower_Princes":{ + "a":"America/Puerto_Rico", + "c":[ + "SX" + ], + "r":1 + }, + "America/Maceio":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Managua":{ + "u":-360, + "c":[ + "NI" + ] + }, + "America/Manaus":{ + "u":-240, + "c":[ + "BR" + ] + }, + "America/Marigot":{ + "a":"America/Puerto_Rico", + "c":[ + "MF" + ], + "r":1 + }, + "America/Martinique":{ + "u":-240, + "c":[ + "MQ" + ] + }, + "America/Matamoros":{ + "u":-360, + "d":-300, + "c":[ + "MX" + ] + }, + "America/Mazatlan":{ + "u":-420, + "d":-360, + "c":[ + "MX" + ] + }, + "America/Mendoza":{ + "a":"America/Argentina/Mendoza", + "r":1 + }, + "America/Menominee":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/Merida":{ + "u":-360, + "d":-300, + "c":[ + "MX" + ] + }, + "America/Metlakatla":{ + "u":-540, + "d":-480, + "c":[ + "US" + ] + }, + "America/Mexico_City":{ + "u":-360, + "d":-300, + "c":[ + "MX" + ] + }, + "America/Miquelon":{ + "u":-180, + "d":-120, + "c":[ + "PM" + ] + }, + "America/Moncton":{ + "u":-240, + "d":-180, + "c":[ + "CA" + ] + }, + "America/Monterrey":{ + "u":-360, + "d":-300, + "c":[ + "MX" + ] + }, + "America/Montevideo":{ + "u":-180, + "c":[ + "UY" + ] + }, + "America/Montreal":{ + "a":"America/Toronto", + "c":[ + "CA" + ], + "r":1 + }, + "America/Montserrat":{ + "a":"America/Puerto_Rico", + "c":[ + "MS" + ], + "r":1 + }, + "America/Nassau":{ + "a":"America/Toronto", + "c":[ + "BS" + ], + "r":1 + }, + "America/New_York":{ + "u":-300, + "d":-240, + "c":[ + "US" + ] + }, + "America/Nipigon":{ + "u":-300, + "d":-240, + "c":[ + "CA" + ] + }, + "America/Nome":{ + "u":-540, + "d":-480, + "c":[ + "US" + ] + }, + "America/Noronha":{ + "u":-120, + "c":[ + "BR" + ] + }, + "America/North_Dakota/Beulah":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/North_Dakota/Center":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/North_Dakota/New_Salem":{ + "u":-360, + "d":-300, + "c":[ + "US" + ] + }, + "America/Nuuk":{ + "u":-180, + "d":-120, + "c":[ + "GL" + ] + }, + "America/Ojinaga":{ + "u":-420, + "d":-360, + "c":[ + "MX" + ] + }, + "America/Panama":{ + "u":-300, + "c":[ + "PA", + "CA", + "KY" + ] + }, + "America/Pangnirtung":{ + "u":-300, + "d":-240, + "c":[ + "CA" + ] + }, + "America/Paramaribo":{ + "u":-180, + "c":[ + "SR" + ] + }, + "America/Phoenix":{ + "u":-420, + "c":[ + "US", + "CA" + ] + }, + "America/Port-au-Prince":{ + "u":-300, + "d":-240, + "c":[ + "HT" + ] + }, + "America/Port_of_Spain":{ + "a":"America/Puerto_Rico", + "c":[ + "TT" + ], + "r":1 + }, + "America/Porto_Acre":{ + "a":"America/Rio_Branco", + "r":1 + }, + "America/Porto_Velho":{ + "u":-240, + "c":[ + "BR" + ] + }, + "America/Puerto_Rico":{ + "u":-240, + "c":[ + "PR", + "AG", + "CA", + "AI", + "AW", + "BL", + "BQ", + "CW", + "DM", + "GD", + "GP", + "KN", + "LC", + "MF", + "MS", + "SX", + "TT", + "VC", + "VG", + "VI" + ] + }, + "America/Punta_Arenas":{ + "u":-180, + "c":[ + "CL" + ] + }, + "America/Rainy_River":{ + "u":-360, + "d":-300, + "c":[ + "CA" + ] + }, + "America/Rankin_Inlet":{ + "u":-360, + "d":-300, + "c":[ + "CA" + ] + }, + "America/Recife":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Regina":{ + "u":-360, + "c":[ + "CA" + ] + }, + "America/Resolute":{ + "u":-360, + "d":-300, + "c":[ + "CA" + ] + }, + "America/Rio_Branco":{ + "u":-300, + "c":[ + "BR" + ] + }, + "America/Rosario":{ + "a":"America/Argentina/Cordoba", + "r":1 + }, + "America/Santa_Isabel":{ + "a":"America/Tijuana", + "r":1 + }, + "America/Santarem":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Santiago":{ + "u":-240, + "d":-180, + "c":[ + "CL" + ] + }, + "America/Santo_Domingo":{ + "u":-240, + "c":[ + "DO" + ] + }, + "America/Sao_Paulo":{ + "u":-180, + "c":[ + "BR" + ] + }, + "America/Scoresbysund":{ + "u":-60, + "d":0, + "c":[ + "GL" + ] + }, + "America/Shiprock":{ + "a":"America/Denver", + "r":1 + }, + "America/Sitka":{ + "u":-540, + "d":-480, + "c":[ + "US" + ] + }, + "America/St_Barthelemy":{ + "a":"America/Puerto_Rico", + "c":[ + "BL" + ], + "r":1 + }, + "America/St_Johns":{ + "u":-150, + "d":-90, + "c":[ + "CA" + ] + }, + "America/St_Kitts":{ + "a":"America/Puerto_Rico", + "c":[ + "KN" + ], + "r":1 + }, + "America/St_Lucia":{ + "a":"America/Puerto_Rico", + "c":[ + "LC" + ], + "r":1 + }, + "America/St_Thomas":{ + "a":"America/Puerto_Rico", + "c":[ + "VI" + ], + "r":1 + }, + "America/St_Vincent":{ + "a":"America/Puerto_Rico", + "c":[ + "VC" + ], + "r":1 + }, + "America/Swift_Current":{ + "u":-360, + "c":[ + "CA" + ] + }, + "America/Tegucigalpa":{ + "u":-360, + "c":[ + "HN" + ] + }, + "America/Thule":{ + "u":-240, + "d":-180, + "c":[ + "GL" + ] + }, + "America/Thunder_Bay":{ + "u":-300, + "d":-240, + "c":[ + "CA" + ] + }, + "America/Tijuana":{ + "u":-480, + "d":-420, + "c":[ + "MX" + ] + }, + "America/Toronto":{ + "u":-300, + "d":-240, + "c":[ + "CA", + "BS" + ] + }, + "America/Tortola":{ + "a":"America/Puerto_Rico", + "c":[ + "VG" + ], + "r":1 + }, + "America/Vancouver":{ + "u":-480, + "d":-420, + "c":[ + "CA" + ] + }, + "America/Virgin":{ + "a":"America/Puerto_Rico", + "c":[ + "VI" + ], + "r":1 + }, + "America/Whitehorse":{ + "u":-420, + "c":[ + "CA" + ] + }, + "America/Winnipeg":{ + "u":-360, + "d":-300, + "c":[ + "CA" + ] + }, + "America/Yakutat":{ + "u":-540, + "d":-480, + "c":[ + "US" + ] + }, + "America/Yellowknife":{ + "u":-420, + "d":-360, + "c":[ + "CA" + ] + }, + "Antarctica/Casey":{ + "u":660, + "c":[ + "AQ" + ] + }, + "Antarctica/Davis":{ + "u":420, + "c":[ + "AQ" + ] + }, + "Antarctica/DumontDUrville":{ + "a":"Pacific/Port_Moresby", + "c":[ + "AQ" + ], + "r":1 + }, + "Antarctica/Macquarie":{ + "u":600, + "d":660, + "c":[ + "AU" + ] + }, + "Antarctica/Mawson":{ + "u":300, + "c":[ + "AQ" + ] + }, + "Antarctica/McMurdo":{ + "a":"Pacific/Auckland", + "c":[ + "AQ" + ], + "r":1 + }, + "Antarctica/Palmer":{ + "u":-180, + "c":[ + "AQ" + ] + }, + "Antarctica/Rothera":{ + "u":-180, + "c":[ + "AQ" + ] + }, + "Antarctica/South_Pole":{ + "a":"Pacific/Auckland", + "c":[ + "AQ" + ], + "r":1 + }, + "Antarctica/Syowa":{ + "a":"Asia/Riyadh", + "c":[ + "AQ" + ], + "r":1 + }, + "Antarctica/Troll":{ + "u":0, + "d":120, + "c":[ + "AQ" + ] + }, + "Antarctica/Vostok":{ + "u":360, + "c":[ + "AQ" + ] + }, + "Arctic/Longyearbyen":{ + "a":"Europe/Oslo", + "c":[ + "SJ" + ], + "r":1 + }, + "Asia/Aden":{ + "a":"Asia/Riyadh", + "c":[ + "YE" + ], + "r":1 + }, + "Asia/Almaty":{ + "u":360, + "c":[ + "KZ" + ] + }, + "Asia/Amman":{ + "u":120, + "d":180, + "c":[ + "JO" + ] + }, + "Asia/Anadyr":{ + "u":720, + "c":[ + "RU" + ] + }, + "Asia/Aqtau":{ + "u":300, + "c":[ + "KZ" + ] + }, + "Asia/Aqtobe":{ + "u":300, + "c":[ + "KZ" + ] + }, + "Asia/Ashgabat":{ + "u":300, + "c":[ + "TM" + ] + }, + "Asia/Ashkhabad":{ + "a":"Asia/Ashgabat", + "r":1 + }, + "Asia/Atyrau":{ + "u":300, + "c":[ + "KZ" + ] + }, + "Asia/Baghdad":{ + "u":180, + "c":[ + "IQ" + ] + }, + "Asia/Bahrain":{ + "a":"Asia/Qatar", + "c":[ + "BH" + ], + "r":1 + }, + "Asia/Baku":{ + "u":240, + "c":[ + "AZ" + ] + }, + "Asia/Bangkok":{ + "u":420, + "c":[ + "TH", + "KH", + "LA", + "VN" + ] + }, + "Asia/Barnaul":{ + "u":420, + "c":[ + "RU" + ] + }, + "Asia/Beirut":{ + "u":120, + "d":180, + "c":[ + "LB" + ] + }, + "Asia/Bishkek":{ + "u":360, + "c":[ + "KG" + ] + }, + "Asia/Brunei":{ + "u":480, + "c":[ + "BN" + ] + }, + "Asia/Calcutta":{ + "a":"Asia/Kolkata", + "r":1 + }, + "Asia/Chita":{ + "u":540, + "c":[ + "RU" + ] + }, + "Asia/Choibalsan":{ + "u":480, + "c":[ + "MN" + ] + }, + "Asia/Chongqing":{ + "a":"Asia/Shanghai", + "r":1 + }, + "Asia/Chungking":{ + "a":"Asia/Shanghai", + "r":1 + }, + "Asia/Colombo":{ + "u":330, + "c":[ + "LK" + ] + }, + "Asia/Dacca":{ + "a":"Asia/Dhaka", + "r":1 + }, + "Asia/Damascus":{ + "u":120, + "d":180, + "c":[ + "SY" + ] + }, + "Asia/Dhaka":{ + "u":360, + "c":[ + "BD" + ] + }, + "Asia/Dili":{ + "u":540, + "c":[ + "TL" + ] + }, + "Asia/Dubai":{ + "u":240, + "c":[ + "AE", + "OM" + ] + }, + "Asia/Dushanbe":{ + "u":300, + "c":[ + "TJ" + ] + }, + "Asia/Famagusta":{ + "u":120, + "d":180, + "c":[ + "CY" + ] + }, + "Asia/Gaza":{ + "u":120, + "d":180, + "c":[ + "PS" + ] + }, + "Asia/Harbin":{ + "a":"Asia/Shanghai", + "r":1 + }, + "Asia/Hebron":{ + "u":120, + "d":180, + "c":[ + "PS" + ] + }, + "Asia/Ho_Chi_Minh":{ + "u":420, + "c":[ + "VN" + ] + }, + "Asia/Hong_Kong":{ + "u":480, + "c":[ + "HK" + ] + }, + "Asia/Hovd":{ + "u":420, + "c":[ + "MN" + ] + }, + "Asia/Irkutsk":{ + "u":480, + "c":[ + "RU" + ] + }, + "Asia/Istanbul":{ + "a":"Europe/Istanbul", + "r":1 + }, + "Asia/Jakarta":{ + "u":420, + "c":[ + "ID" + ] + }, + "Asia/Jayapura":{ + "u":540, + "c":[ + "ID" + ] + }, + "Asia/Jerusalem":{ + "u":120, + "d":180, + "c":[ + "IL" + ] + }, + "Asia/Kabul":{ + "u":270, + "c":[ + "AF" + ] + }, + "Asia/Kamchatka":{ + "u":720, + "c":[ + "RU" + ] + }, + "Asia/Karachi":{ + "u":300, + "c":[ + "PK" + ] + }, + "Asia/Kashgar":{ + "a":"Asia/Urumqi", + "r":1 + }, + "Asia/Kathmandu":{ + "u":345, + "c":[ + "NP" + ] + }, + "Asia/Katmandu":{ + "a":"Asia/Kathmandu", + "r":1 + }, + "Asia/Khandyga":{ + "u":540, + "c":[ + "RU" + ] + }, + "Asia/Kolkata":{ + "u":330, + "c":[ + "IN" + ] + }, + "Asia/Krasnoyarsk":{ + "u":420, + "c":[ + "RU" + ] + }, + "Asia/Kuala_Lumpur":{ + "u":480, + "c":[ + "MY" + ] + }, + "Asia/Kuching":{ + "u":480, + "c":[ + "MY" + ] + }, + "Asia/Kuwait":{ + "a":"Asia/Riyadh", + "c":[ + "KW" + ], + "r":1 + }, + "Asia/Macao":{ + "a":"Asia/Macau", + "r":1 + }, + "Asia/Macau":{ + "u":480, + "c":[ + "MO" + ] + }, + "Asia/Magadan":{ + "u":660, + "c":[ + "RU" + ] + }, + "Asia/Makassar":{ + "u":480, + "c":[ + "ID" + ] + }, + "Asia/Manila":{ + "u":480, + "c":[ + "PH" + ] + }, + "Asia/Muscat":{ + "a":"Asia/Dubai", + "c":[ + "OM" + ], + "r":1 + }, + "Asia/Nicosia":{ + "u":120, + "d":180, + "c":[ + "CY" + ] + }, + "Asia/Novokuznetsk":{ + "u":420, + "c":[ + "RU" + ] + }, + "Asia/Novosibirsk":{ + "u":420, + "c":[ + "RU" + ] + }, + "Asia/Omsk":{ + "u":360, + "c":[ + "RU" + ] + }, + "Asia/Oral":{ + "u":300, + "c":[ + "KZ" + ] + }, + "Asia/Phnom_Penh":{ + "a":"Asia/Bangkok", + "c":[ + "KH" + ], + "r":1 + }, + "Asia/Pontianak":{ + "u":420, + "c":[ + "ID" + ] + }, + "Asia/Pyongyang":{ + "u":540, + "c":[ + "KP" + ] + }, + "Asia/Qatar":{ + "u":180, + "c":[ + "QA", + "BH" + ] + }, + "Asia/Qostanay":{ + "u":360, + "c":[ + "KZ" + ] + }, + "Asia/Qyzylorda":{ + "u":300, + "c":[ + "KZ" + ] + }, + "Asia/Rangoon":{ + "a":"Asia/Yangon", + "r":1 + }, + "Asia/Riyadh":{ + "u":180, + "c":[ + "SA", + "AQ", + "KW", + "YE" + ] + }, + "Asia/Saigon":{ + "a":"Asia/Ho_Chi_Minh", + "r":1 + }, + "Asia/Sakhalin":{ + "u":660, + "c":[ + "RU" + ] + }, + "Asia/Samarkand":{ + "u":300, + "c":[ + "UZ" + ] + }, + "Asia/Seoul":{ + "u":540, + "c":[ + "KR" + ] + }, + "Asia/Shanghai":{ + "u":480, + "c":[ + "CN" + ] + }, + "Asia/Singapore":{ + "u":480, + "c":[ + "SG", + "MY" + ] + }, + "Asia/Srednekolymsk":{ + "u":660, + "c":[ + "RU" + ] + }, + "Asia/Taipei":{ + "u":480, + "c":[ + "TW" + ] + }, + "Asia/Tashkent":{ + "u":300, + "c":[ + "UZ" + ] + }, + "Asia/Tbilisi":{ + "u":240, + "c":[ + "GE" + ] + }, + "Asia/Tehran":{ + "u":210, + "d":270, + "c":[ + "IR" + ] + }, + "Asia/Tel_Aviv":{ + "a":"Asia/Jerusalem", + "r":1 + }, + "Asia/Thimbu":{ + "a":"Asia/Thimphu", + "r":1 + }, + "Asia/Thimphu":{ + "u":360, + "c":[ + "BT" + ] + }, + "Asia/Tokyo":{ + "u":540, + "c":[ + "JP" + ] + }, + "Asia/Tomsk":{ + "u":420, + "c":[ + "RU" + ] + }, + "Asia/Ujung_Pandang":{ + "a":"Asia/Makassar", + "r":1 + }, + "Asia/Ulaanbaatar":{ + "u":480, + "c":[ + "MN" + ] + }, + "Asia/Ulan_Bator":{ + "a":"Asia/Ulaanbaatar", + "r":1 + }, + "Asia/Urumqi":{ + "u":360, + "c":[ + "CN" + ] + }, + "Asia/Ust-Nera":{ + "u":600, + "c":[ + "RU" + ] + }, + "Asia/Vientiane":{ + "a":"Asia/Bangkok", + "c":[ + "LA" + ], + "r":1 + }, + "Asia/Vladivostok":{ + "u":600, + "c":[ + "RU" + ] + }, + "Asia/Yakutsk":{ + "u":540, + "c":[ + "RU" + ] + }, + "Asia/Yangon":{ + "u":390, + "c":[ + "MM" + ] + }, + "Asia/Yekaterinburg":{ + "u":300, + "c":[ + "RU" + ] + }, + "Asia/Yerevan":{ + "u":240, + "c":[ + "AM" + ] + }, + "Atlantic/Azores":{ + "u":-60, + "d":0, + "c":[ + "PT" + ] + }, + "Atlantic/Bermuda":{ + "u":-240, + "d":-180, + "c":[ + "BM" + ] + }, + "Atlantic/Canary":{ + "u":0, + "d":60, + "c":[ + "ES" + ] + }, + "Atlantic/Cape_Verde":{ + "u":-60, + "c":[ + "CV" + ] + }, + "Atlantic/Faeroe":{ + "a":"Atlantic/Faroe", + "r":1 + }, + "Atlantic/Faroe":{ + "u":0, + "d":60, + "c":[ + "FO" + ] + }, + "Atlantic/Jan_Mayen":{ + "a":"Europe/Oslo", + "c":[ + "SJ" + ], + "r":1 + }, + "Atlantic/Madeira":{ + "u":0, + "d":60, + "c":[ + "PT" + ] + }, + "Atlantic/Reykjavik":{ + "u":0, + "c":[ + "IS" + ] + }, + "Atlantic/South_Georgia":{ + "u":-120, + "c":[ + "GS" + ] + }, + "Atlantic/St_Helena":{ + "a":"Africa/Abidjan", + "c":[ + "SH" + ], + "r":1 + }, + "Atlantic/Stanley":{ + "u":-180, + "c":[ + "FK" + ] + }, + "Australia/ACT":{ + "a":"Australia/Sydney", + "r":1 + }, + "Australia/Adelaide":{ + "u":570, + "d":630, + "c":[ + "AU" + ] + }, + "Australia/Brisbane":{ + "u":600, + "c":[ + "AU" + ] + }, + "Australia/Broken_Hill":{ + "u":570, + "d":630, + "c":[ + "AU" + ] + }, + "Australia/Canberra":{ + "a":"Australia/Sydney", + "r":1 + }, + "Australia/Currie":{ + "a":"Australia/Hobart", + "r":1 + }, + "Australia/Darwin":{ + "u":570, + "c":[ + "AU" + ] + }, + "Australia/Eucla":{ + "u":525, + "c":[ + "AU" + ] + }, + "Australia/Hobart":{ + "u":600, + "d":660, + "c":[ + "AU" + ] + }, + "Australia/LHI":{ + "a":"Australia/Lord_Howe", + "r":1 + }, + "Australia/Lindeman":{ + "u":600, + "c":[ + "AU" + ] + }, + "Australia/Lord_Howe":{ + "u":630, + "d":660, + "c":[ + "AU" + ] + }, + "Australia/Melbourne":{ + "u":600, + "d":660, + "c":[ + "AU" + ] + }, + "Australia/NSW":{ + "a":"Australia/Sydney", + "r":1 + }, + "Australia/North":{ + "a":"Australia/Darwin", + "r":1 + }, + "Australia/Perth":{ + "u":480, + "c":[ + "AU" + ] + }, + "Australia/Queensland":{ + "a":"Australia/Brisbane", + "r":1 + }, + "Australia/South":{ + "a":"Australia/Adelaide", + "r":1 + }, + "Australia/Sydney":{ + "u":600, + "d":660, + "c":[ + "AU" + ] + }, + "Australia/Tasmania":{ + "a":"Australia/Hobart", + "r":1 + }, + "Australia/Victoria":{ + "a":"Australia/Melbourne", + "r":1 + }, + "Australia/West":{ + "a":"Australia/Perth", + "r":1 + }, + "Australia/Yancowinna":{ + "a":"Australia/Broken_Hill", + "r":1 + }, + "Brazil/Acre":{ + "a":"America/Rio_Branco", + "r":1 + }, + "Brazil/DeNoronha":{ + "a":"America/Noronha", + "r":1 + }, + "Brazil/East":{ + "a":"America/Sao_Paulo", + "r":1 + }, + "Brazil/West":{ + "a":"America/Manaus", + "r":1 + }, + "CET":{ + "u":60, + "d":120 + }, + "CST6CDT":{ + "u":-360, + "d":-300 + }, + "Canada/Atlantic":{ + "a":"America/Halifax", + "r":1 + }, + "Canada/Central":{ + "a":"America/Winnipeg", + "r":1 + }, + "Canada/Eastern":{ + "a":"America/Toronto", + "c":[ + "CA" + ], + "r":1 + }, + "Canada/Mountain":{ + "a":"America/Edmonton", + "r":1 + }, + "Canada/Newfoundland":{ + "a":"America/St_Johns", + "r":1 + }, + "Canada/Pacific":{ + "a":"America/Vancouver", + "r":1 + }, + "Canada/Saskatchewan":{ + "a":"America/Regina", + "r":1 + }, + "Canada/Yukon":{ + "a":"America/Whitehorse", + "r":1 + }, + "Chile/Continental":{ + "a":"America/Santiago", + "r":1 + }, + "Chile/EasterIsland":{ + "a":"Pacific/Easter", + "r":1 + }, + "Cuba":{ + "a":"America/Havana", + "r":1 + }, + "EET":{ + "u":120, + "d":180 + }, + "EST":{ + "u":-300 + }, + "EST5EDT":{ + "u":-300, + "d":-240 + }, + "Egypt":{ + "a":"Africa/Cairo", + "r":1 + }, + "Eire":{ + "a":"Europe/Dublin", + "r":1 + }, + "Etc/GMT":{ + "u":0 + }, + "Etc/GMT+0":{ + "a":"Etc/GMT", + "r":1 + }, + "Etc/GMT+1":{ + "u":-60 + }, + "Etc/GMT+10":{ + "u":-600 + }, + "Etc/GMT+11":{ + "u":-660 + }, + "Etc/GMT+12":{ + "u":-720 + }, + "Etc/GMT+2":{ + "u":-120 + }, + "Etc/GMT+3":{ + "u":-180 + }, + "Etc/GMT+4":{ + "u":-240 + }, + "Etc/GMT+5":{ + "u":-300 + }, + "Etc/GMT+6":{ + "u":-360 + }, + "Etc/GMT+7":{ + "u":-420 + }, + "Etc/GMT+8":{ + "u":-480 + }, + "Etc/GMT+9":{ + "u":-540 + }, + "Etc/GMT-0":{ + "a":"Etc/GMT", + "r":1 + }, + "Etc/GMT-1":{ + "u":60 + }, + "Etc/GMT-10":{ + "u":600 + }, + "Etc/GMT-11":{ + "u":660 + }, + "Etc/GMT-12":{ + "u":720 + }, + "Etc/GMT-13":{ + "u":780 + }, + "Etc/GMT-14":{ + "u":840 + }, + "Etc/GMT-2":{ + "u":120 + }, + "Etc/GMT-3":{ + "u":180 + }, + "Etc/GMT-4":{ + "u":240 + }, + "Etc/GMT-5":{ + "u":300 + }, + "Etc/GMT-6":{ + "u":360 + }, + "Etc/GMT-7":{ + "u":420 + }, + "Etc/GMT-8":{ + "u":480 + }, + "Etc/GMT-9":{ + "u":540 + }, + "Etc/GMT0":{ + "a":"Etc/GMT", + "r":1 + }, + "Etc/Greenwich":{ + "a":"Etc/GMT", + "r":1 + }, + "Etc/UCT":{ + "a":"Etc/UTC", + "r":1 + }, + "Etc/UTC":{ + "u":0 + }, + "Etc/Universal":{ + "a":"Etc/UTC", + "r":1 + }, + "Etc/Zulu":{ + "a":"Etc/UTC", + "r":1 + }, + "Europe/Amsterdam":{ + "u":60, + "d":120, + "c":[ + "NL" + ] + }, + "Europe/Andorra":{ + "u":60, + "d":120, + "c":[ + "AD" + ] + }, + "Europe/Astrakhan":{ + "u":240, + "c":[ + "RU" + ] + }, + "Europe/Athens":{ + "u":120, + "d":180, + "c":[ + "GR" + ] + }, + "Europe/Belfast":{ + "a":"Europe/London", + "c":[ + "GB" + ], + "r":1 + }, + "Europe/Belgrade":{ + "u":60, + "d":120, + "c":[ + "RS", + "BA", + "HR", + "ME", + "MK", + "SI" + ] + }, + "Europe/Berlin":{ + "u":60, + "d":120, + "c":[ + "DE" + ] + }, + "Europe/Bratislava":{ + "a":"Europe/Prague", + "c":[ + "SK" + ], + "r":1 + }, + "Europe/Brussels":{ + "u":60, + "d":120, + "c":[ + "BE" + ] + }, + "Europe/Bucharest":{ + "u":120, + "d":180, + "c":[ + "RO" + ] + }, + "Europe/Budapest":{ + "u":60, + "d":120, + "c":[ + "HU" + ] + }, + "Europe/Busingen":{ + "a":"Europe/Zurich", + "c":[ + "DE" + ], + "r":1 + }, + "Europe/Chisinau":{ + "u":120, + "d":180, + "c":[ + "MD" + ] + }, + "Europe/Copenhagen":{ + "u":60, + "d":120, + "c":[ + "DK" + ] + }, + "Europe/Dublin":{ + "u":60, + "d":0, + "c":[ + "IE" + ] + }, + "Europe/Gibraltar":{ + "u":60, + "d":120, + "c":[ + "GI" + ] + }, + "Europe/Guernsey":{ + "a":"Europe/London", + "c":[ + "GG" + ], + "r":1 + }, + "Europe/Helsinki":{ + "u":120, + "d":180, + "c":[ + "FI", + "AX" + ] + }, + "Europe/Isle_of_Man":{ + "a":"Europe/London", + "c":[ + "IM" + ], + "r":1 + }, + "Europe/Istanbul":{ + "u":180, + "c":[ + "TR" + ] + }, + "Europe/Jersey":{ + "a":"Europe/London", + "c":[ + "JE" + ], + "r":1 + }, + "Europe/Kaliningrad":{ + "u":120, + "c":[ + "RU" + ] + }, + "Europe/Kiev":{ + "u":120, + "d":180, + "c":[ + "UA" + ] + }, + "Europe/Kirov":{ + "u":180, + "c":[ + "RU" + ] + }, + "Europe/Lisbon":{ + "u":0, + "d":60, + "c":[ + "PT" + ] + }, + "Europe/Ljubljana":{ + "a":"Europe/Belgrade", + "c":[ + "SI" + ], + "r":1 + }, + "Europe/London":{ + "u":0, + "d":60, + "c":[ + "GB", + "GG", + "IM", + "JE" + ] + }, + "Europe/Luxembourg":{ + "u":60, + "d":120, + "c":[ + "LU" + ] + }, + "Europe/Madrid":{ + "u":60, + "d":120, + "c":[ + "ES" + ] + }, + "Europe/Malta":{ + "u":60, + "d":120, + "c":[ + "MT" + ] + }, + "Europe/Mariehamn":{ + "a":"Europe/Helsinki", + "c":[ + "AX" + ], + "r":1 + }, + "Europe/Minsk":{ + "u":180, + "c":[ + "BY" + ] + }, + "Europe/Monaco":{ + "u":60, + "d":120, + "c":[ + "MC" + ] + }, + "Europe/Moscow":{ + "u":180, + "c":[ + "RU" + ] + }, + "Europe/Nicosia":{ + "a":"Asia/Nicosia", + "r":1 + }, + "Europe/Oslo":{ + "u":60, + "d":120, + "c":[ + "NO", + "SJ", + "BV" + ] + }, + "Europe/Paris":{ + "u":60, + "d":120, + "c":[ + "FR" + ] + }, + "Europe/Podgorica":{ + "a":"Europe/Belgrade", + "c":[ + "ME" + ], + "r":1 + }, + "Europe/Prague":{ + "u":60, + "d":120, + "c":[ + "CZ", + "SK" + ] + }, + "Europe/Riga":{ + "u":120, + "d":180, + "c":[ + "LV" + ] + }, + "Europe/Rome":{ + "u":60, + "d":120, + "c":[ + "IT", + "SM", + "VA" + ] + }, + "Europe/Samara":{ + "u":240, + "c":[ + "RU" + ] + }, + "Europe/San_Marino":{ + "a":"Europe/Rome", + "c":[ + "SM" + ], + "r":1 + }, + "Europe/Sarajevo":{ + "a":"Europe/Belgrade", + "c":[ + "BA" + ], + "r":1 + }, + "Europe/Saratov":{ + "u":240, + "c":[ + "RU" + ] + }, + "Europe/Simferopol":{ + "u":180, + "c":[ + "RU", + "UA" + ] + }, + "Europe/Skopje":{ + "a":"Europe/Belgrade", + "c":[ + "MK" + ], + "r":1 + }, + "Europe/Sofia":{ + "u":120, + "d":180, + "c":[ + "BG" + ] + }, + "Europe/Stockholm":{ + "u":60, + "d":120, + "c":[ + "SE" + ] + }, + "Europe/Tallinn":{ + "u":120, + "d":180, + "c":[ + "EE" + ] + }, + "Europe/Tirane":{ + "u":60, + "d":120, + "c":[ + "AL" + ] + }, + "Europe/Tiraspol":{ + "a":"Europe/Chisinau", + "r":1 + }, + "Europe/Ulyanovsk":{ + "u":240, + "c":[ + "RU" + ] + }, + "Europe/Uzhgorod":{ + "u":120, + "d":180, + "c":[ + "UA" + ] + }, + "Europe/Vaduz":{ + "a":"Europe/Zurich", + "c":[ + "LI" + ], + "r":1 + }, + "Europe/Vatican":{ + "a":"Europe/Rome", + "c":[ + "VA" + ], + "r":1 + }, + "Europe/Vienna":{ + "u":60, + "d":120, + "c":[ + "AT" + ] + }, + "Europe/Vilnius":{ + "u":120, + "d":180, + "c":[ + "LT" + ] + }, + "Europe/Volgograd":{ + "u":180, + "c":[ + "RU" + ] + }, + "Europe/Warsaw":{ + "u":60, + "d":120, + "c":[ + "PL" + ] + }, + "Europe/Zagreb":{ + "a":"Europe/Belgrade", + "c":[ + "HR" + ], + "r":1 + }, + "Europe/Zaporozhye":{ + "u":120, + "d":180, + "c":[ + "UA" + ] + }, + "Europe/Zurich":{ + "u":60, + "d":120, + "c":[ + "CH", + "DE", + "LI" + ] + }, + "Factory":{ + "u":0 + }, + "GB":{ + "a":"Europe/London", + "c":[ + "GB" + ], + "r":1 + }, + "GB-Eire":{ + "a":"Europe/London", + "c":[ + "GB" + ], + "r":1 + }, + "GMT":{ + "a":"Etc/GMT", + "r":1 + }, + "GMT+0":{ + "a":"Etc/GMT", + "r":1 + }, + "GMT-0":{ + "a":"Etc/GMT", + "r":1 + }, + "GMT0":{ + "a":"Etc/GMT", + "r":1 + }, + "Greenwich":{ + "a":"Etc/GMT", + "r":1 + }, + "HST":{ + "u":-600 + }, + "Hongkong":{ + "a":"Asia/Hong_Kong", + "r":1 + }, + "Iceland":{ + "a":"Atlantic/Reykjavik", + "r":1 + }, + "Indian/Antananarivo":{ + "a":"Africa/Nairobi", + "c":[ + "MG" + ], + "r":1 + }, + "Indian/Chagos":{ + "u":360, + "c":[ + "IO" + ] + }, + "Indian/Christmas":{ + "u":420, + "c":[ + "CX" + ] + }, + "Indian/Cocos":{ + "u":390, + "c":[ + "CC" + ] + }, + "Indian/Comoro":{ + "a":"Africa/Nairobi", + "c":[ + "KM" + ], + "r":1 + }, + "Indian/Kerguelen":{ + "u":300, + "c":[ + "TF", + "HM" + ] + }, + "Indian/Mahe":{ + "u":240, + "c":[ + "SC" + ] + }, + "Indian/Maldives":{ + "u":300, + "c":[ + "MV" + ] + }, + "Indian/Mauritius":{ + "u":240, + "c":[ + "MU" + ] + }, + "Indian/Mayotte":{ + "a":"Africa/Nairobi", + "c":[ + "YT" + ], + "r":1 + }, + "Indian/Reunion":{ + "u":240, + "c":[ + "RE", + "TF" + ] + }, + "Iran":{ + "a":"Asia/Tehran", + "r":1 + }, + "Israel":{ + "a":"Asia/Jerusalem", + "r":1 + }, + "Jamaica":{ + "a":"America/Jamaica", + "r":1 + }, + "Japan":{ + "a":"Asia/Tokyo", + "r":1 + }, + "Kwajalein":{ + "a":"Pacific/Kwajalein", + "r":1 + }, + "Libya":{ + "a":"Africa/Tripoli", + "r":1 + }, + "MET":{ + "u":60, + "d":120 + }, + "MST":{ + "u":-420 + }, + "MST7MDT":{ + "u":-420, + "d":-360 + }, + "Mexico/BajaNorte":{ + "a":"America/Tijuana", + "r":1 + }, + "Mexico/BajaSur":{ + "a":"America/Mazatlan", + "r":1 + }, + "Mexico/General":{ + "a":"America/Mexico_City", + "r":1 + }, + "NZ":{ + "a":"Pacific/Auckland", + "c":[ + "NZ" + ], + "r":1 + }, + "NZ-CHAT":{ + "a":"Pacific/Chatham", + "r":1 + }, + "Navajo":{ + "a":"America/Denver", + "r":1 + }, + "PRC":{ + "a":"Asia/Shanghai", + "r":1 + }, + "PST8PDT":{ + "u":-480, + "d":-420 + }, + "Pacific/Apia":{ + "u":780, + "c":[ + "WS" + ] + }, + "Pacific/Auckland":{ + "u":720, + "d":780, + "c":[ + "NZ", + "AQ" + ] + }, + "Pacific/Bougainville":{ + "u":660, + "c":[ + "PG" + ] + }, + "Pacific/Chatham":{ + "u":765, + "d":825, + "c":[ + "NZ" + ] + }, + "Pacific/Chuuk":{ + "u":600, + "c":[ + "FM" + ] + }, + "Pacific/Easter":{ + "u":-360, + "d":-300, + "c":[ + "CL" + ] + }, + "Pacific/Efate":{ + "u":660, + "c":[ + "VU" + ] + }, + "Pacific/Enderbury":{ + "a":"Pacific/Kanton", + "r":1 + }, + "Pacific/Fakaofo":{ + "u":780, + "c":[ + "TK" + ] + }, + "Pacific/Fiji":{ + "u":720, + "d":780, + "c":[ + "FJ" + ] + }, + "Pacific/Funafuti":{ + "u":720, + "c":[ + "TV" + ] + }, + "Pacific/Galapagos":{ + "u":-360, + "c":[ + "EC" + ] + }, + "Pacific/Gambier":{ + "u":-540, + "c":[ + "PF" + ] + }, + "Pacific/Guadalcanal":{ + "u":660, + "c":[ + "SB" + ] + }, + "Pacific/Guam":{ + "u":600, + "c":[ + "GU", + "MP" + ] + }, + "Pacific/Honolulu":{ + "u":-600, + "c":[ + "US", + "UM" + ] + }, + "Pacific/Johnston":{ + "a":"Pacific/Honolulu", + "c":[ + "UM" + ], + "r":1 + }, + "Pacific/Kanton":{ + "u":780, + "c":[ + "KI" + ] + }, + "Pacific/Kiritimati":{ + "u":840, + "c":[ + "KI" + ] + }, + "Pacific/Kosrae":{ + "u":660, + "c":[ + "FM" + ] + }, + "Pacific/Kwajalein":{ + "u":720, + "c":[ + "MH" + ] + }, + "Pacific/Majuro":{ + "u":720, + "c":[ + "MH" + ] + }, + "Pacific/Marquesas":{ + "u":-510, + "c":[ + "PF" + ] + }, + "Pacific/Midway":{ + "a":"Pacific/Pago_Pago", + "c":[ + "UM" + ], + "r":1 + }, + "Pacific/Nauru":{ + "u":720, + "c":[ + "NR" + ] + }, + "Pacific/Niue":{ + "u":-660, + "c":[ + "NU" + ] + }, + "Pacific/Norfolk":{ + "u":660, + "d":720, + "c":[ + "NF" + ] + }, + "Pacific/Noumea":{ + "u":660, + "c":[ + "NC" + ] + }, + "Pacific/Pago_Pago":{ + "u":-660, + "c":[ + "AS", + "UM" + ] + }, + "Pacific/Palau":{ + "u":540, + "c":[ + "PW" + ] + }, + "Pacific/Pitcairn":{ + "u":-480, + "c":[ + "PN" + ] + }, + "Pacific/Pohnpei":{ + "u":660, + "c":[ + "FM" + ] + }, + "Pacific/Ponape":{ + "a":"Pacific/Pohnpei", + "r":1 + }, + "Pacific/Port_Moresby":{ + "u":600, + "c":[ + "PG", + "AQ" + ] + }, + "Pacific/Rarotonga":{ + "u":-600, + "c":[ + "CK" + ] + }, + "Pacific/Saipan":{ + "a":"Pacific/Guam", + "c":[ + "MP" + ], + "r":1 + }, + "Pacific/Samoa":{ + "a":"Pacific/Pago_Pago", + "c":[ + "WS" + ], + "r":1 + }, + "Pacific/Tahiti":{ + "u":-600, + "c":[ + "PF" + ] + }, + "Pacific/Tarawa":{ + "u":720, + "c":[ + "KI" + ] + }, + "Pacific/Tongatapu":{ + "u":780, + "c":[ + "TO" + ] + }, + "Pacific/Truk":{ + "a":"Pacific/Chuuk", + "r":1 + }, + "Pacific/Wake":{ + "u":720, + "c":[ + "UM" + ] + }, + "Pacific/Wallis":{ + "u":720, + "c":[ + "WF" + ] + }, + "Pacific/Yap":{ + "a":"Pacific/Chuuk", + "r":1 + }, + "Poland":{ + "a":"Europe/Warsaw", + "r":1 + }, + "Portugal":{ + "a":"Europe/Lisbon", + "r":1 + }, + "ROC":{ + "a":"Asia/Taipei", + "r":1 + }, + "ROK":{ + "a":"Asia/Seoul", + "r":1 + }, + "Singapore":{ + "a":"Asia/Singapore", + "c":[ + "SG" + ], + "r":1 + }, + "Turkey":{ + "a":"Europe/Istanbul", + "r":1 + }, + "UCT":{ + "a":"Etc/UTC", + "r":1 + }, + "US/Alaska":{ + "a":"America/Anchorage", + "r":1 + }, + "US/Aleutian":{ + "a":"America/Adak", + "r":1 + }, + "US/Arizona":{ + "a":"America/Phoenix", + "c":[ + "US" + ], + "r":1 + }, + "US/Central":{ + "a":"America/Chicago", + "r":1 + }, + "US/East-Indiana":{ + "a":"America/Indiana/Indianapolis", + "r":1 + }, + "US/Eastern":{ + "a":"America/New_York", + "r":1 + }, + "US/Hawaii":{ + "a":"Pacific/Honolulu", + "c":[ + "US" + ], + "r":1 + }, + "US/Indiana-Starke":{ + "a":"America/Indiana/Knox", + "r":1 + }, + "US/Michigan":{ + "a":"America/Detroit", + "r":1 + }, + "US/Mountain":{ + "a":"America/Denver", + "r":1 + }, + "US/Pacific":{ + "a":"America/Los_Angeles", + "r":1 + }, + "US/Samoa":{ + "a":"Pacific/Pago_Pago", + "c":[ + "WS" + ], + "r":1 + }, + "UTC":{ + "a":"Etc/UTC", + "r":1 + }, + "Universal":{ + "a":"Etc/UTC", + "r":1 + }, + "W-SU":{ + "a":"Europe/Moscow", + "r":1 + }, + "WET":{ + "u":0, + "d":60 + }, + "Zulu":{ + "a":"Etc/UTC", + "r":1 + } + } \ No newline at end of file diff --git a/static/js/src/intlTelInput.js b/static/js/src/intlTelInput.js index 2525c1f80d5..5336cbf9daf 100644 --- a/static/js/src/intlTelInput.js +++ b/static/js/src/intlTelInput.js @@ -14,7 +14,8 @@ function setupIntlTelInput(phoneInput) { hiddenInput: inputName, initialCountry: "auto", geoIpLookup: async function fetchUserIp(success, failure) { - const response = await fetch("/user-country.json"); + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; + const response = await fetch("/user-country.json?tz=" + timezone); if (!response.ok) { throw new Error(response.status); } diff --git a/webapp/app.py b/webapp/app.py index 6402d831e3f..95e52209e48 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -127,7 +127,7 @@ engage_thank_you, french_why_openstack, german_why_openstack, - get_user_country_by_ip, + get_user_country_by_tz, json_asset_query, marketo_submit, mirrors_query, @@ -628,7 +628,7 @@ def takeovers_index(): core_services_guide.init_app(app) -app.add_url_rule("/user-country.json", view_func=get_user_country_by_ip) +app.add_url_rule("/user-country.json", view_func=get_user_country_by_tz) # All other routes template_finder_view = TemplateFinder.as_view("template_finder") diff --git a/webapp/views.py b/webapp/views.py index 5f515e07867..784b4905aac 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -1,9 +1,10 @@ # Standard library +import datetime +import html import math import os import re -import html -import datetime +import json # Packages import dateutil @@ -1071,6 +1072,23 @@ def thank_you(): ) +def get_user_country_by_tz(): + APP_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + timezone = flask.request.args.get("tz") + + timezones = json.load(open(os.path.join(APP_ROOT, "static/files/timezones.json"))) + countries = json.load(open(os.path.join(APP_ROOT, "static/files/countries.json"))) + + _country = timezones[timezone]['c'][0] + country = countries[_country] + return flask.jsonify( + { + "country": country, + "country_code": _country, + } + ) + + def get_user_country_by_ip(): x_forwarded_for = flask.request.headers.get("X-Forwarded-For") From c03b7680b57eeee1e5f35c8f806513d7f66b115a Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Fri, 1 Mar 2024 16:30:45 +0300 Subject: [PATCH 02/16] Fixed formatting --- webapp/views.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/webapp/views.py b/webapp/views.py index 784b4905aac..9fb224808b1 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -1073,13 +1073,17 @@ def thank_you(): def get_user_country_by_tz(): - APP_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + APP_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) timezone = flask.request.args.get("tz") - timezones = json.load(open(os.path.join(APP_ROOT, "static/files/timezones.json"))) - countries = json.load(open(os.path.join(APP_ROOT, "static/files/countries.json"))) + timezones = json.load( + open(os.path.join(APP_ROOT, "static/files/timezones.json")) + ) + countries = json.load( + open(os.path.join(APP_ROOT, "static/files/countries.json")) + ) - _country = timezones[timezone]['c'][0] + _country = timezones[timezone]["c"][0] country = countries[_country] return flask.jsonify( { From 67448d61759350a9b3f2cf4dad49f28cb7790af5 Mon Sep 17 00:00:00 2001 From: Carlos Wu Fei Date: Mon, 4 Mar 2024 10:03:49 +0100 Subject: [PATCH 03/16] WD-9266 Add Edge AI link --- templates/ai/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/ai/index.html b/templates/ai/index.html index c234d932d1b..4afb58963cf 100644 --- a/templates/ai/index.html +++ b/templates/ai/index.html @@ -471,6 +471,9 @@

Use modular platforms to run AI at the edge or in large clouds

  • Low-ops, streamlined lifecycle management
  • A modular and open source suite for reusable deployments
  • +

    + Read more about Edge AI › +

    From 0e18686de05a89d3fe71a620b4e2bc3af96656db Mon Sep 17 00:00:00 2001 From: yelyzaveta Date: Mon, 4 Mar 2024 12:57:20 +0100 Subject: [PATCH 04/16] WD-9049 - fix contact form field not being sent --- static/js/src/static-forms.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/static/js/src/static-forms.js b/static/js/src/static-forms.js index 6e0c30e2215..8b478e587d0 100644 --- a/static/js/src/static-forms.js +++ b/static/js/src/static-forms.js @@ -129,7 +129,9 @@ function setUpStaticForms(form, formId) { }); }); - commentsFromLead.value = message; + if (formFields.length) { + commentsFromLead.value = message; + } return message; }); } From d973dab0585596a6ccaa4af0406c14092c0a2bb7 Mon Sep 17 00:00:00 2001 From: yelyzaveta Date: Mon, 4 Mar 2024 13:22:45 +0100 Subject: [PATCH 05/16] WD-9157 - add CTA button to /aws/pro --- templates/aws/pro.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/aws/pro.html b/templates/aws/pro.html index 4acb6a056cc..925e6d3f60d 100644 --- a/templates/aws/pro.html +++ b/templates/aws/pro.html @@ -12,6 +12,11 @@

    Ubuntu Pro for AWS

    For production. For professionals.

    Ubuntu Pro for AWS is a premium image delivering the most comprehensive open source security and AWS compliance. Ubuntu Pro is suitable for small to large-scale Linux enterprise operations offering pay-as-you-go billing on your existing AWS invoice.

    Available on AMD64 and Graviton architectures

    +

    Ubuntu Pro 22.04 LTS + Latest +

    +

    Delivers additional layer of security and compliance services and security patches covering a wider range of packages, until 2032.

    +

    Launch now

    Upgrade Ubuntu LTS to Ubuntu Pro

    From a5a33358dd7c88278da8d689a3e9658a8bf3a2d8 Mon Sep 17 00:00:00 2001 From: MariaPaula Trujillo Date: Mon, 4 Mar 2024 13:28:59 +0100 Subject: [PATCH 06/16] Apply copy updates --- templates/cloud/index.html | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/templates/cloud/index.html b/templates/cloud/index.html index 0e7b5c755c8..1514fc6ed72 100644 --- a/templates/cloud/index.html +++ b/templates/cloud/index.html @@ -11,10 +11,10 @@
    -

    Private cloud vs hybrid cloud, multicloud and more

    +

    Private cloud vs hybrid cloud, multicloud and more

    Choose the cloud architecture that suits you best

    There is no one size fits all cloud architecture. Developing the optimum cloud strategy requires evaluating your business needs and aligning them with the different solutions available.

    -

    Canonical fully supports public clouds and provides its own solutions for private cloud implementation and management, as well as workload orchestration in hybrid cloud and multicloud environments.

    +

    Canonical fully supports public clouds and provides its own infrastructure solutions for private cloud implementation and management, as well as workload orchestration in hybrid cloud and multicloud environments.

    Optimise your cloud infrastructure

    @@ -57,13 +57,14 @@

    What is a private cloud?

    Advantages:

      -
    • Compared to public clouds, private clouds are often more cost-effective—especially when used at scale and in the long-term.
    • +
    • If run efficiently and well-utilised, private clouds are often more cost-effective for equivalent resources than public clouds.
    • An organisation with a private cloud does not share its hosting resources with other organisations meaning in general, private clouds provide better performance.

    Disadvantages:

      +
    • Purchasing and provisioning new hardware carries relatively high fixed costs, which are wasted if the cloud has low utilisation.
    • The deployment and on-going management of a private cloud requires dedicated team resources and technical skill.
    @@ -101,20 +102,21 @@

    What is a public cloud?

    Advantages:

    • Immediate access to infrastructure as a service (IaaS) can significantly accelerate time to market for organisations.
    • -
    • Public clouds provide the ability to scale resource consumption virtually without limits.
    • +
    • Public clouds provide the ability to scale resource consumption as needed and virtually without limits.

    Disadvantages:

      -
    • While the headline costs of the public cloud look attractive, hidden ancillary costs often make it an expensive choice of cloud architecture.
    • +
    • Can be more expensive than an efficiently-managed and well-utilised private cloud.
    • +
    • In addition to the compute costs, there can be unexpected ancillary costs like egress (taking your data out of the cloud)
    -

    Major public cloud providers include Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform, Oracle and IBM Cloud.

    +

    Major public cloud providers include Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform, Oracle and IBM Cloud.

    - Learn how to build your own public cloud › + Learn more about Ubuntu on Public Clouds ›

    From 1ac5bf0cc176fd57ef2db99fc03e09a9a57439d2 Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Mon, 4 Mar 2024 16:10:05 +0300 Subject: [PATCH 07/16] Added tests --- static/js/src/intlTelInput.js | 2 +- tests/test_routes.py | 28 ++++++++++++++++++++++++++++ webapp/app.py | 4 +++- webapp/views.py | 8 ++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/static/js/src/intlTelInput.js b/static/js/src/intlTelInput.js index 5336cbf9daf..32944dd88ef 100644 --- a/static/js/src/intlTelInput.js +++ b/static/js/src/intlTelInput.js @@ -15,7 +15,7 @@ function setupIntlTelInput(phoneInput) { initialCountry: "auto", geoIpLookup: async function fetchUserIp(success, failure) { const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; - const response = await fetch("/user-country.json?tz=" + timezone); + const response = await fetch("/user-country-tz.json?tz=" + timezone); if (!response.ok) { throw new Error(response.status); } diff --git a/tests/test_routes.py b/tests/test_routes.py index 78ead435657..6c534c6339c 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -225,6 +225,34 @@ def test_18_04_bubble(self): response = self.client.get("/18-04/ibm") self.assertEqual(response.status_code, 200) + def test_get_country_code(self): + """ + Test that the country code is extracted from the timezone + """ + # Case 1: American timezone + response = self.client.get("/user-country-tz.json?tz=America/Detroit") + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.json, {"country": "United States of America", "country_code": "US"} + ) + + # Case 2: European timezone + response = self.client.get("/user-country-tz.json?tz=Europe/Vilnius") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json, {"country": "Lithuania", "country_code": "LT"}) + + # Case 3: African timezone + response = self.client.get("/user-country-tz.json?tz=Africa/Bissau") + self.assertEqual(response.status_code, 200) + self.assertEqual( + response.json, {"country": "Guinea-Bissau", "country_code": "GW"} + ) + + # Case 4: Asian timezone + response = self.client.get("/user-country-tz.json?tz=Asia/Kolkata") + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json, {"country": "India", "country_code": "IN"}) + if __name__ == "__main__": unittest.main() diff --git a/webapp/app.py b/webapp/app.py index 95e52209e48..1024afab27a 100644 --- a/webapp/app.py +++ b/webapp/app.py @@ -127,6 +127,7 @@ engage_thank_you, french_why_openstack, german_why_openstack, + get_user_country_by_ip, get_user_country_by_tz, json_asset_query, marketo_submit, @@ -628,7 +629,8 @@ def takeovers_index(): core_services_guide.init_app(app) -app.add_url_rule("/user-country.json", view_func=get_user_country_by_tz) +app.add_url_rule("/user-country.json", view_func=get_user_country_by_ip) +app.add_url_rule("/user-country-tz.json", view_func=get_user_country_by_tz) # All other routes template_finder_view = TemplateFinder.as_view("template_finder") diff --git a/webapp/views.py b/webapp/views.py index 9fb224808b1..453d209c82d 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -1073,6 +1073,14 @@ def thank_you(): def get_user_country_by_tz(): + """ + Get user country by timezone using ISO 3166 country codes. + We store the country codes and timezones as static JSON files in the + static/files directory. + + Eventually we plan to merge this function with the one below, once we + are confident that takeovers won't be broken. + """ APP_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) timezone = flask.request.args.get("tz") From 31da434a69972c4ed0f366b19ce80c311b6ff316 Mon Sep 17 00:00:00 2001 From: Samuel Olwe Date: Mon, 4 Mar 2024 16:18:43 +0300 Subject: [PATCH 08/16] Fixed formatting --- tests/test_routes.py | 13 +++++++++---- webapp/views.py | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/test_routes.py b/tests/test_routes.py index 6c534c6339c..e098176899e 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -18,7 +18,7 @@ class TestRoutes(VCRTestCase): def _get_vcr_kwargs(self): """ This removes the authorization header - from VCR so we don't record auth parameters + from VCR so we don"t record auth parameters """ return { "filter_headers": [ @@ -233,13 +233,16 @@ def test_get_country_code(self): response = self.client.get("/user-country-tz.json?tz=America/Detroit") self.assertEqual(response.status_code, 200) self.assertEqual( - response.json, {"country": "United States of America", "country_code": "US"} + response.json, + {"country": "United States of America", "country_code": "US"}, ) # Case 2: European timezone response = self.client.get("/user-country-tz.json?tz=Europe/Vilnius") self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, {"country": "Lithuania", "country_code": "LT"}) + self.assertEqual( + response.json, {"country": "Lithuania", "country_code": "LT"} + ) # Case 3: African timezone response = self.client.get("/user-country-tz.json?tz=Africa/Bissau") @@ -251,7 +254,9 @@ def test_get_country_code(self): # Case 4: Asian timezone response = self.client.get("/user-country-tz.json?tz=Asia/Kolkata") self.assertEqual(response.status_code, 200) - self.assertEqual(response.json, {"country": "India", "country_code": "IN"}) + self.assertEqual( + response.json, {"country": "India", "country_code": "IN"} + ) if __name__ == "__main__": diff --git a/webapp/views.py b/webapp/views.py index 453d209c82d..c9fa9d8b6c8 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -1074,8 +1074,8 @@ def thank_you(): def get_user_country_by_tz(): """ - Get user country by timezone using ISO 3166 country codes. - We store the country codes and timezones as static JSON files in the + Get user country by timezone using ISO 3166 country codes. + We store the country codes and timezones as static JSON files in the static/files directory. Eventually we plan to merge this function with the one below, once we From 30bfc955a73b1a5788eec66b90e1abfadad62e23 Mon Sep 17 00:00:00 2001 From: Carlos Wu Date: Mon, 4 Mar 2024 16:06:48 +0100 Subject: [PATCH 09/16] Make resource_url optional for contaact_form_only engage pages (#13624) --- templates/engage/base.html | 13 +++-- templates/engage/shared/_de_thank-you.html | 48 ++++++++--------- templates/engage/shared/_es_thank-you.html | 48 ++++++++--------- templates/engage/shared/_fr_thank-you.html | 50 ++++++++---------- templates/engage/shared/_it_thank-you.html | 46 ++++++++-------- templates/engage/shared/_pt_thank-you.html | 46 ++++++++-------- templates/engage/shared/_ru_thank-you.html | 52 +++++++++---------- templates/engage/shared/_zh-TW_thank-you.html | 15 ++---- templates/engage/thank-you.html | 9 +--- webapp/views.py | 2 +- 10 files changed, 147 insertions(+), 182 deletions(-) diff --git a/templates/engage/base.html b/templates/engage/base.html index 60e3c493983..aede8c633fc 100644 --- a/templates/engage/base.html +++ b/templates/engage/base.html @@ -30,10 +30,10 @@ {% if metadata['banner_class'] == 'light' %} {{ image( - url="https://assets.ubuntu.com/v1/04115a7e-ubuntu_black-orange_hex.svg", + url="https://assets.ubuntu.com/v1/43ef5c89-Canonical Ubuntu.svg", alt="Ubuntu", - height="32", - width="143", + width="300", + height="55", hi_def=True, loading="auto" ) | safe @@ -41,16 +41,15 @@ {% else %} {{ image( - url="https://assets.ubuntu.com/v1/f263d9c4-logo-ubuntu-white.svg", + url="https://assets.ubuntu.com/v1/b4f695ea-Canonical Ubuntu copy 2.svg", alt="Ubuntu", - height="32", - width="143", + width="300", + height="55", hi_def=True, loading="auto" ) | safe }} {% endif %} -
    diff --git a/templates/engage/shared/_de_thank-you.html b/templates/engage/shared/_de_thank-you.html index 1c804d7ab37..52a9099a592 100644 --- a/templates/engage/shared/_de_thank-you.html +++ b/templates/engage/shared/_de_thank-you.html @@ -32,37 +32,33 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} - {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} + {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} -

    Wir haben eine Kopie des Whitepapers per e-mail {{ resource_name }} an {{ form_details.email }}

    -

    - Zurück zur letzten Seite - Kontaktiere uns -

    -

    - Nicht erhalten? Überprüfen Sie Ihren Spam-Ordner und ob Sie die richtige E-Mail-Adresse verwendet haben. -

    -

    - Oder versuchen Sie es erneut -

    +

    Wir haben eine Kopie des Whitepapers per e-mail {{ resource_name }} an {{ form_details.email }}

    +

    + Zurück zur letzten Seite + Kontaktiere uns +

    +

    + Nicht erhalten? Überprüfen Sie Ihren Spam-Ordner und ob Sie die richtige E-Mail-Adresse verwendet haben. +

    +

    + Oder versuchen Sie es erneut +

    + {% else %} + {% if "thank_you_text" in metadata %} +

    {{ metadata["thank_you_text"] }}

    {% else %} - {% if "thank_you_text" in metadata %} -

    {{ metadata["thank_you_text"] }}

    - {% else %} -

    {{ resource_name }} ist jetzt zum Download bereit.

    - {% endif %} - {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} -

    - Herunterladen -

    +

    {{ resource_name }} ist jetzt zum Download bereit.

    + {% endif %} + {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %} +

    + Herunterladen +

    {% endif %} {% endif %} - {% else %} -

    - Diese Downloadanfrage wird leider nicht erkannt. Bitte teilen Sie uns dies unter Einreichung und Ausgabe auf GitHub . Und lassen Sie uns wissen, was Sie zum Herunterladen ausgenommen haben. -

    {% endif %}
    diff --git a/templates/engage/shared/_es_thank-you.html b/templates/engage/shared/_es_thank-you.html index 4adb7eaca8b..a94619abd63 100644 --- a/templates/engage/shared/_es_thank-you.html +++ b/templates/engage/shared/_es_thank-you.html @@ -31,39 +31,35 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} - {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} + {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} -

    Le hemos enviado una copia de {{ resource_name }} a {{ form_details.email }}

    -

    - A la página anterior - Contáctanos -

    +

    Le hemos enviado una copia de {{ resource_name }} a {{ form_details.email }}

    +

    + A la página anterior + Contáctanos +

    +

    + ¿No lo ha recibido? Revise la carpeta de spam y asegúrese de haber introducido el e-mail correcto. +

    +

    + O pruebe enviarlo de nuevo. +

    + + {% else %} + {% if "thank_you_text" in metadata %} +

    {{ metadata["thank_you_text"] }}

    + {% else %}

    - ¿No lo ha recibido? Revise la carpeta de spam y asegúrese de haber introducido el e-mail correcto. + El {{ resource_name }} está listo para descargar.

    + {% endif %} + {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %}

    - O pruebe enviarlo de nuevo. + Descargar

    - - {% else %} - {% if "thank_you_text" in metadata %} -

    {{ metadata["thank_you_text"] }}

    - {% else %} -

    - El {{ resource_name }} está listo para descargar. -

    - {% endif %} - {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} -

    - Descargar -

    {% endif %} {% endif %} - {% else %} -

    - Disculpa, no hemos entendido la petició de descarga. Por favor, infórmanos rellenando este formulario en GitHub. Y dinos qué esperabas descargarte. -

    {% endif %}
    diff --git a/templates/engage/shared/_fr_thank-you.html b/templates/engage/shared/_fr_thank-you.html index 4927c3ff5ec..daa6ddefe2a 100644 --- a/templates/engage/shared/_fr_thank-you.html +++ b/templates/engage/shared/_fr_thank-you.html @@ -32,40 +32,36 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} - {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} - + {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} -

    Nous avons envoyé une copie de {{ resource_name }} à {{ form_details.email }}

    -

    - Retour à la dernière page - Contactez-nous -

    -

    - Pas reçu? Vérifiez votre dossier spam et vérifiez que vous avez utilisé la bonne adresse e-mail. -

    -

    - Ou essayez de le renvoyer -

    +

    Nous avons envoyé une copie de {{ resource_name }} à {{ form_details.email }}

    +

    + Retour à la dernière page + Contactez-nous +

    +

    + Pas reçu? Vérifiez votre dossier spam et vérifiez que vous avez utilisé la bonne adresse e-mail. +

    +

    + Ou essayez de le renvoyer +

    + + {% else %} + {% if "thank_you_text" in metadata %} +

    {{ metadata["thank_you_text"] }}

    {% else %} - {% if "thank_you_text" in metadata %} -

    {{ metadata["thank_you_text"] }}

    - {% else %} +

    + La {{ resource_name }} est prête à être téléchargée. +

    + {% endif %} + {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %}

    - La {{ resource_name }} est prête à être téléchargée. + Téléchargée

    {% endif %} - {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} -

    - Téléchargée -

    - {% endif %} {% endif %} - {% else %} -

    - Désolé, nous ne reconnaissons pas cette demande de téléchargement. Veuillez nous le faire savoir en déposant et en émettant un problème sur GitHub. Et dites-nous ce que vous attendiez de télécharger. -

    {% endif %}
    diff --git a/templates/engage/shared/_it_thank-you.html b/templates/engage/shared/_it_thank-you.html index bfc635c608f..19a1551c7d1 100644 --- a/templates/engage/shared/_it_thank-you.html +++ b/templates/engage/shared/_it_thank-you.html @@ -32,39 +32,35 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} - {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} + {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} -

    Abbiamo inviato una copia di {{ resource_name }} a {{ form_details.email }}

    -

    - Torna all'ultima pagina - Contattaci -

    -

    - Non l'hai ricevuto? Controlla la tua cartella spam e di aver utilizzato l'indirizzo email corretto. -

    -

    - Oppure prova a inviarlo di nuovo -

    +

    Abbiamo inviato una copia di {{ resource_name }} a {{ form_details.email }}

    +

    + Torna all'ultima pagina + Contattaci +

    +

    + Non l'hai ricevuto? Controlla la tua cartella spam e di aver utilizzato l'indirizzo email corretto. +

    +

    + Oppure prova a inviarlo di nuovo +

    + {% else %} + {% if "thank_you_text" in metadata %} +

    {{ metadata["thank_you_text"] }}

    {% else %} - {% if "thank_you_text" in metadata %} -

    {{ metadata["thank_you_text"] }}

    - {% else %} -

    - La {{ resource_name }} risorsa è ora pronta per il scarica. -

    - {% endif %} - {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} +

    + La {{ resource_name }} risorsa è ora pronta per il scarica. +

    + {% endif %} + {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %}

    Scarica

    {% endif %} {% endif %} - {% else %} -

    - Spiacenti, non riconosciamo questa richiesta di scarica. Fatecelo sapere tramite archiviazione ed emissione su GitHub . E facci sapere cosa hai escluso per il download. -

    {% endif %}
    diff --git a/templates/engage/shared/_pt_thank-you.html b/templates/engage/shared/_pt_thank-you.html index 71a5c583344..71d9bc3ca05 100644 --- a/templates/engage/shared/_pt_thank-you.html +++ b/templates/engage/shared/_pt_thank-you.html @@ -32,38 +32,34 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} - {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} -

    Enviamos uma cópia do e-mail {{ resource_name }} para {{ form_details.email }}

    -

    - Voltar para a última página - Contate-Nos -

    -

    - Não recebeu? Verifique sua pasta de spam e se você usou o endereço de e-mail correto. -

    -

    - Ou tente reenviar -

    + {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} +

    Enviamos uma cópia do e-mail {{ resource_name }} para {{ form_details.email }}

    +

    + Voltar para a última página + Contate-Nos +

    +

    + Não recebeu? Verifique sua pasta de spam e se você usou o endereço de e-mail correto. +

    +

    + Ou tente reenviar +

    + {% else %} + {% if "thank_you_text" in metadata %} +

    {{ metadata["thank_you_text"] }}

    {% else %} - {% if "thank_you_text" in metadata %} -

    {{ metadata["thank_you_text"] }}

    - {% else %} -

    - {{ resource_name | capitalize }} está pronto para download. -

    - {% endif %} - {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} +

    + {{ resource_name | capitalize }} está pronto para download. +

    + {% endif %} + {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %}

    Download

    {% endif %} {% endif %} - {% else %} -

    - Desculpe, não reconhecemos esta solicitação de download. Informe-nos por arquivamento e problema no GitHub . E diga-nos o que você deseja baixar. -

    {% endif %}
    diff --git a/templates/engage/shared/_ru_thank-you.html b/templates/engage/shared/_ru_thank-you.html index e7a3874c047..fa30dc988b9 100644 --- a/templates/engage/shared/_ru_thank-you.html +++ b/templates/engage/shared/_ru_thank-you.html @@ -32,38 +32,34 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} - {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} -

    Мы отправили вам копию {{ resource_name }} по {{ form_details.email }}

    -

    - Вернуться к последней странице - Свяжитесь с нами -

    -

    - Не получил? Проверьте папку со спамом и убедитесь, что вы использовали правильный адрес электронной почты. -

    -

    - Или попробуйте отправить повторно -

    + {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %} +

    Мы отправили вам копию {{ resource_name }} по {{ form_details.email }}

    +

    + Вернуться к последней странице + Свяжитесь с нами +

    +

    + Не получил? Проверьте папку со спамом и убедитесь, что вы использовали правильный адрес электронной почты. +

    +

    + Или попробуйте отправить повторно +

    - {% else %} - {% if "thank_you_text" in metadata %} -

    {{ metadata["thank_you_text"] }}

    - {% else %} -

    - {{ resource_name }} готов к загрузке. -

    - {% endif %} - {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} -

    - Загрузить -

    - {% endif %} - {% endif %} {% else %} + {% if "thank_you_text" in metadata %} +

    {{ metadata["thank_you_text"] }}

    + {% else %}

    - К сожалению, мы не распознаем этот запрос на загрузку. Пожалуйста, дайте нам знать заполнив вопрос на GitHub, дайте нам знать, что вы ожидали загрузить. + {{ resource_name }} готов к загрузке.

    + {% endif %} + {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %} +

    + Загрузить +

    + {% endif %} + {% endif %} {% endif %}
    diff --git a/templates/engage/shared/_zh-TW_thank-you.html b/templates/engage/shared/_zh-TW_thank-you.html index 7ade4eddd01..7a8512d0be6 100644 --- a/templates/engage/shared/_zh-TW_thank-you.html +++ b/templates/engage/shared/_zh-TW_thank-you.html @@ -36,7 +36,6 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %}

    We've emailed a copy of {{ resource_name }} to {{ form_details.email }}

    @@ -58,17 +57,13 @@

    We've emailed a copy of {{ resource_name }} to {{ form_details.email }}

    The {{ resource_name }} is now ready to download.

    {% endif %} {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} -

    - Download -

    + {% if metadata.resource_url and metadata.resource_url != "" %} +

    + Download +

    + {% endif %} {% endif %} {% endif %} - - {% else %} -

    - Sorry, we do not recognise this download request. Please let us know by filing and issue on GitHub. And let us know what you excepted to download. -

    - {% endif %}
    diff --git a/templates/engage/thank-you.html b/templates/engage/thank-you.html index 8546c7bf196..413aa3eb4ee 100644 --- a/templates/engage/thank-you.html +++ b/templates/engage/thank-you.html @@ -31,7 +31,6 @@

    - {% if 'pages.ubuntu.com' or 'assets.ubuntu.com' in resource_url %} {% if form_details and "access_to_content" in metadata and metadata.access_to_content == "true" %}

    We've emailed a copy of the {{ resource_name }} to {{ form_details.email }}

    @@ -53,17 +52,13 @@

    We've emailed a copy of the {{ resource_name }} to {{ form_details.email }}<

    The {{ resource_name }} is now ready to download.

    {% endif %} {% if "contact_form_only" not in metadata and metadata.contact_form_only != "true" or ("access_to_content" in metadata and metadata.access_to_content == "true") %} + {% if metadata.resource_url and metadata.resource_url != "" %}

    Download

    + {% endif %} {% endif %} {% endif %} - - {% else %} -

    - Sorry, we do not recognise this download request. Please let us know by filing and issue on GitHub. And let us know what you excepted to download. -

    - {% endif %}

    diff --git a/webapp/views.py b/webapp/views.py index 5f515e07867..d4a3b4fb108 100644 --- a/webapp/views.py +++ b/webapp/views.py @@ -518,7 +518,7 @@ def render_template(language, page): "resource_url" not in metadata or metadata["resource_url"] == "" ) and ( "contact_form_only" not in metadata - or metadata["contact_form_only"] == "true" + or metadata["contact_form_only"] != "true" ): return flask.abort(404) From cfdeb89638a179b5013f9251fa23d01e2f292878 Mon Sep 17 00:00:00 2001 From: Abhigyan Ghosh <30973042+abhigyanghosh30@users.noreply.github.com> Date: Tue, 5 Mar 2024 02:45:17 +0530 Subject: [PATCH 10/16] Change truability api to new url (#13644) --- .env | 2 +- HACKING.md | 4 ++-- konf/site.yaml | 10 +++++----- webapp/shop/decorators.py | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.env b/.env index 0d6a1e1e5d0..1726fb8429a 100644 --- a/.env +++ b/.env @@ -6,7 +6,7 @@ CONTRACTS_API_URL=https://contracts.staging.canonical.com/ STRIPE_PUBLISHABLE_KEY=pk_test_yndN9H0GcJffPe0W58Nm64cM00riYG4N46 STORE_MAINTENANCE=false BADGR_URL=https://api.test.badgr.com -TRUEABILITY_URL="https://app.trueability.com" +TRUEABILITY_URL="https://app3.trueability.com" CREDLY_URL="https://api.credly.com/v1" BADGR_ISSUER="36ZEJnXdTjqobw93BJElog" CERTIFIED_BADGE="x9kzmcNhSSyqYhZcQGz0qg" diff --git a/HACKING.md b/HACKING.md index b5d6ec6257a..bf3ee0901d0 100644 --- a/HACKING.md +++ b/HACKING.md @@ -121,11 +121,11 @@ For the most part this will happen automatically as long as the subpages (/ai/wh ### Working on Credentials If you want to work on [Credentials](https://ubuntu.com/credentials) you need to add some environment vars into your `.env.local`. -If you have a TrueAbility account with API access enabled, you can find your API key in [Settings](https://app.trueability.com/settings). +If you have a TrueAbility account with API access enabled, you can find your API key in [Settings](https://app3.trueability.com/settings). ``` -TRUEABILITY_URL="https://app.trueability.com" +TRUEABILITY_URL="https://app3.trueability.com" TRUEABILITY_API_KEY= BADGR_URL=https://api.test.badgr.com BAGDR_USER= diff --git a/konf/site.yaml b/konf/site.yaml index 32306cf46bb..ca8db983131 100644 --- a/konf/site.yaml +++ b/konf/site.yaml @@ -121,7 +121,7 @@ env: value: pk_live_68aXqowUeX574aGsVck8eiIE - name: TRUEABILITY_URL - value: https://app.trueability.com + value: https://app3.trueability.com - name: TRUEABILITY_API_KEY secretKeyRef: @@ -254,7 +254,7 @@ production: name: confidentiality-webhook - name: TRUEABILITY_URL - value: https://app.trueability.com + value: https://app3.trueability.com - name: TRUEABILITY_API_KEY secretKeyRef: @@ -593,7 +593,7 @@ staging: value: pk_test_yndN9H0GcJffPe0W58Nm64cM00riYG4N46 - name: TRUEABILITY_URL - value: https://app.trueability.com + value: https://app3.trueability.com - name: TRUEABILITY_API_KEY secretKeyRef: @@ -729,7 +729,7 @@ staging: name: confidentiality-webhook - name: TRUEABILITY_URL - value: https://app.trueability.com + value: https://app3.trueability.com - name: TRUEABILITY_API_KEY secretKeyRef: @@ -1018,7 +1018,7 @@ demo: value: pk_test_yndN9H0GcJffPe0W58Nm64cM00riYG4N46 - name: TRUEABILITY_URL - value: https://app.trueability.com + value: https://app3.trueability.com - name: TRUEABILITY_API_KEY secretKeyRef: diff --git a/webapp/shop/decorators.py b/webapp/shop/decorators.py index b4d7e18daa7..d546ccf5e9f 100644 --- a/webapp/shop/decorators.py +++ b/webapp/shop/decorators.py @@ -240,7 +240,7 @@ def get_trueability_api_instance(area, trueability_session) -> TrueAbilityAPI: return None return TrueAbilityAPI( - os.getenv("TRUEABILITY_URL", "https://app.trueability.com"), + os.getenv("TRUEABILITY_URL", "https://app3.trueability.com"), os.getenv("TRUEABILITY_API_KEY", ""), trueability_session, ) From a7bbdf2a89ffc0f2c487ffe3b4053140ba019ddc Mon Sep 17 00:00:00 2001 From: abhigyanghosh30 Date: Tue, 5 Mar 2024 19:07:17 +0530 Subject: [PATCH 11/16] fix(TA api): change X_API-KEY to X-API-KEY --- webapp/shop/api/trueability/api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/shop/api/trueability/api.py b/webapp/shop/api/trueability/api.py index e16c14c5844..2c10474be54 100644 --- a/webapp/shop/api/trueability/api.py +++ b/webapp/shop/api/trueability/api.py @@ -24,7 +24,7 @@ def make_request( allow_redirects: bool = True, ): uri = f"{self.base_url}{path}" - headers["X-API_KEY"] = f"{self.api_key}" + headers["X-API-KEY"] = f"{self.api_key}" response = self.session.request( method, @@ -232,7 +232,7 @@ def get_filtered_webhook_responses( f"?ability_screen_id={ability_screen_id}" f"&page={page}" ) - headers = {"X-API_KEY": self.api_key} + headers = {"X-API-KEY": self.api_key} response = self.session.request( method="GET", url=uri, headers=headers ).json() From eb487bb3dc92944eb8565f427c6de5e9024b7799 Mon Sep 17 00:00:00 2001 From: yelyzaveta Date: Wed, 6 Mar 2024 13:36:24 +0100 Subject: [PATCH 12/16] WD-9175 - fix broken link on u.com --- build.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.js b/build.js index 4681ebefef6..5b16b9d1add 100644 --- a/build.js +++ b/build.js @@ -32,7 +32,8 @@ let entries = { "random-partner-logos": "./static/js/src/random-partner-logos.js", "credEnterprisePurchasing": "./static/js/src/advantage/credentials/app.tsx", activate: "./static/js/src/activate.js", - "chiselled-chart": "./static/js/src/charts/chiselled-chart.js" + "chiselled-chart": "./static/js/src/charts/chiselled-chart.js", + tabbedContent: "./static/js/src/tabbed-content.js", }; const isDev = process && process.env && process.env.NODE_ENV === "development"; From 422b7780e5d979d125b89b739ace90b2ed9dd994 Mon Sep 17 00:00:00 2001 From: MariaPaula Trujillo Date: Wed, 6 Mar 2024 16:59:00 +0100 Subject: [PATCH 13/16] Check notice id string before calling api --- webapp/security/views.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/security/views.py b/webapp/security/views.py index fdb0cac78e1..9a109370716 100644 --- a/webapp/security/views.py +++ b/webapp/security/views.py @@ -37,7 +37,11 @@ def get_processed_details(notice): def notice(notice_id): - notice = security_api.get_notice(notice_id) + # Check if notice_id is a valid USN or LSN + if re.fullmatch(r"(USN|LSN|SSN)-\d{1,5}-\d{1,2}", notice_id): + notice = security_api.get_notice(notice_id) + else: + flask.abort(404) if not notice: flask.abort(404) From 9183a77832e431a42f87a382eecedfcfdd067dc6 Mon Sep 17 00:00:00 2001 From: Akbar Abdrakhmanov Date: Thu, 7 Mar 2024 14:26:43 +0500 Subject: [PATCH 14/16] add an instruction to robots.txt to exclude docs search page --- static/files/robots.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/static/files/robots.txt b/static/files/robots.txt index 2581100c812..1ea03afdabe 100644 --- a/static/files/robots.txt +++ b/static/files/robots.txt @@ -1,4 +1,5 @@ User-Agent: * Disallow: /search Disallow: /search* +Disallow: /server/docs/search* Sitemap: https://ubuntu.com/sitemap.xml From b6f8a795248956ef23d4de7d280880a2833adbbb Mon Sep 17 00:00:00 2001 From: yelyzaveta Date: Thu, 7 Mar 2024 12:41:21 +0100 Subject: [PATCH 15/16] WD-9428 - remove roadshow from ai navigation --- navigation.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/navigation.yaml b/navigation.yaml index 2d0a066394e..8cfe442198c 100644 --- a/navigation.yaml +++ b/navigation.yaml @@ -216,8 +216,6 @@ ai: path: /ai/mlflow - title: Consulting path: /ai/consulting - - title: Roadshow - path: /ai/roadshow kubernetes: title: Canonical Kubernetes From a2e134d1a4d071a2346e809896f94b6cf3e9f0e9 Mon Sep 17 00:00:00 2001 From: Abhigyan Ghosh <30973042+abhigyanghosh30@users.noreply.github.com> Date: Thu, 7 Mar 2024 21:03:44 +0530 Subject: [PATCH 16/16] Wd 8766 Your Exams page logic overhaul (#13651) * fix(scheduling): add 30 min time delta for scheduling and your exams --- templates/credentials/schedule.html | 2 +- webapp/shop/api/ua_contracts/api.py | 3 +- webapp/shop/cred/views.py | 95 +++++++++++++++++++++++------ 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/templates/credentials/schedule.html b/templates/credentials/schedule.html index 5c164ede1d4..073ccc50fcb 100644 --- a/templates/credentials/schedule.html +++ b/templates/credentials/schedule.html @@ -52,7 +52,7 @@

    Schedule your exam