generated from ministryofjustice/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial commit * Add in additional fields * Update page format and add postcode * Add in postcode box and geocode lookup * Make trufflehog ignore env files * Update the street address field logic * Add in email validation * add callback field and conditionals * Add thirdparty options * Add in another day logic * Migrate all the js * Add validation to day time field * UPdate another call logic to persist * Add error message to postcode field * Allow postcode to search on Enter * Add bsl logic * Refactor the bsl webcam code * Add payload constructor * Add payload * Initial setup of backend connection * Post to backend * Redirect to confirmation page * Repair RFC * Refactor the time code * Add email orchestrator code * Add exception catching for duplicate case * Update validators * UPdate os places key * Update variables for contact number * Amend languages config call * Change Config to current app config * Update welsh logic * Add in eligible pagee * Add default welsh if welsh selected * Add in eligility notes * Change how rfc notes is handled * Update error handling * Remove today if no slots * Update logic for handling another day * Add another day logic * Add handling for no slots * Hide call me back if no slots are available * Add domestic abuse exit this page * Add domestic abuse exit this page * Add in progress bar * Add welsh translations * Update functional tests * Fix accessibility tests * Fix contact tests * Amend the eligible route * Fix test cases * Fix test session * Replace pytz with zoneinfo * Remove post from confirmation * Add in unit tests * Add additional unit tests * Update test contact * Add mocked checker slots * Add test contact changes * Update notify unit tests * Update welsh translations * Update unit tests to test validators * Remove API log * Change to pytest from unit test * Seperate callback funcs and add tests * Update naming * Add key dynamically to address lookup * Add tests for get all time slots * Add additional unit tests * Move domestic abuse to contact us if risk * Refactor code * Update and repair tests * Api test repair * Add domestic abuse field * Add test get email * Update comments * Update routing * Update formatting of headings and change time slots * Update contact tests to use conftest * Amend CSS, add url to property of address, change to jsonify * Change time format to ., update domestic abuse family route, hard code email ids * Remove spellcheck * Update slots to use params * Fix adaptation data not retaining information when form is reloaded * Amend erroneous Welsh translation * Add missing Welsh translations * Refactor get callback time method * Replace all SelectMultipleFields with SelectField * Refactor ContactUsForm __init__ * Update unit tests * Update validators and tests to work with SelectFields * Set LANG_CHOICES to use the lowercase value as the constant * Update ec notes to include text from "Tell us more about your problem" * Only validate the bsl_email field is the user has not entered an email in the optional field * Update bsl_email validator * Refactor send email * Run toggleEmailFields on pageload * Refactor confirmation email sending * Refactor confirmation email * Fix test get email * Update unit tests * Update confirmation email tests * Add tests for the ContactUs view * Add get callback time tests * Add freezegun as a requirement * Merge changes * Merge changes * Add tests for the ValidateIf validator * Add tests for the ValidateIf validator * Add additional ContactUs unit tests * Add Welsh translation for the contact preferences * Add in welsh for time slots * Update translations * Add clear eligibility to session * Clear session but persist case reference * Persist additional data * Merge the dpa format address * Revert means test validator * Remove print statements * Update formatting * Update tests and change session clear eligibility * Update test validators * Rebase contact.html * Repair the welsh translation issue * Minor amendments to translations and naming of css * Remove duplicate session cookie secure --------- Co-authored-by: Ben Millar <ben.millar@digital.justice.gov.uk>
- Loading branch information
1 parent
54019d4
commit 7127d77
Showing
49 changed files
with
3,798 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import logging | ||
import re | ||
from flask import current_app | ||
|
||
import requests | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class AddressLookup(object): | ||
url = "https://api.os.uk/search/places/v1/postcode" | ||
|
||
def __init__(self): | ||
self.key = current_app.config["OS_PLACES_API_KEY"] | ||
|
||
def by_postcode(self, postcode): | ||
params = { | ||
"postcode": postcode, | ||
"key": self.key, | ||
"output_srs": "WGS84", # Specifies the coordinate reference system (WGS84 is a global standard) | ||
"dataset": "DPA", # Specifies the dataset to query ("DPA" stands for "Definitive Postcode Address") | ||
} | ||
try: | ||
os_places_response = requests.get(self.url, params=params, timeout=3) | ||
os_places_response.raise_for_status() | ||
except requests.exceptions.ConnectTimeout as e: | ||
logger.error(f"OS Places request timed out: {e}") | ||
except requests.exceptions.RequestException as e: | ||
logger.error(f"OS Places request error: {e}") | ||
else: | ||
try: | ||
return os_places_response.json().get("results", []) | ||
except ValueError as e: | ||
logger.warning(f"OS Places response JSON parse error: {e}") | ||
return [] | ||
|
||
|
||
class FormattedAddressLookup(AddressLookup): | ||
""" | ||
A subclass of AddressLookup that formats the raw address data returned by the OS Places API. | ||
This class transforms the raw address components into a well-structured, readable address string. | ||
""" | ||
|
||
def format_address_from_result(self, raw_result): | ||
dpa_result = raw_result.get("DPA") | ||
|
||
if dpa_result: | ||
address_format = [ | ||
{"fields": ["ORGANISATION_NAME"]}, | ||
{"fields": ["SUB_BUILDING_NAME"]}, | ||
{"fields": ["BUILDING_NAME"]}, | ||
{"fields": ["BUILDING_NUMBER", "THOROUGHFARE_NAME"]}, | ||
{"fields": ["DEPENDENT_LOCALITY"]}, | ||
{"fields": ["POST_TOWN"]}, | ||
{"fields": ["POSTCODE"], "transform": "upper"}, | ||
] | ||
|
||
formatted_lines = self.format_lines(address_format, dpa_result) | ||
return "\n".join([c for c in formatted_lines if c]) | ||
else: | ||
return None | ||
|
||
def format_lines(self, address_format, raw_result): | ||
for line_format in address_format: | ||
line_components = [] | ||
for field in line_format["fields"]: | ||
line_components.append(raw_result.get(field, "")) | ||
line_string = " ".join(line_components) | ||
transform = line_format.get("transform") | ||
if transform: | ||
transformed_line = getattr(line_string, transform)() | ||
else: | ||
transformed_line = self.special_title_case(line_string) | ||
yield transformed_line.strip() | ||
|
||
@staticmethod | ||
def special_title_case(original_string, exceptions=None): | ||
if not exceptions: | ||
exceptions = ["of", "the"] | ||
word_list = re.split(" ", original_string.lower()) | ||
final = [word_list[0].capitalize()] | ||
for word in word_list[1:]: | ||
final.append(word if word in exceptions else word.title()) | ||
return " ".join(final) | ||
|
||
def by_postcode(self, postcode): | ||
os_places_results = super(FormattedAddressLookup, self).by_postcode(postcode) | ||
return [self.format_address_from_result(result) for result in os_places_results] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
from flask_babel import lazy_gettext as _ | ||
|
||
ADAPTATION_LANGUAGES = [ | ||
("", ""), | ||
("ASSAMESE", "Assamese"), | ||
("AZERI", "Azeri"), | ||
("AFRIKAANS", "Afrikaans"), | ||
("ALGERIAN", "Algerian"), | ||
("ASHANTI", "Ashanti"), | ||
("AKAN", "Akan"), | ||
("ALBANIAN", "Albanian"), | ||
("AMHARIC", "Amharic"), | ||
("ARMENIAN", "Armenian"), | ||
("ARABIC", "Arabic"), | ||
("ASSYRIAN", "Assyrian"), | ||
("AZERBAIJANI", "Azerbaijani"), | ||
("BADINI", "Badini"), | ||
("BENGALI", "Bengali"), | ||
("BURMESE", "Burmese"), | ||
("BAJUNI", "Bajuni"), | ||
("BELORUSSIAN", "Belorussian"), | ||
("BOSNIAN", "Bosnian"), | ||
("BERBER", "Berber"), | ||
("BASQUE", "Basque"), | ||
("BULGARIAN", "Bulgarian"), | ||
("BRAVA", "Brava"), | ||
("BRAZILIAN", "Brazilian"), | ||
("CANTONESE", "Cantonese"), | ||
("CEBUANO", "Cebuano"), | ||
("CREOLE", "Creole"), | ||
("CHINESE", "Chinese"), | ||
("CHEROKEE", "Cherokee"), | ||
("COLUMBIAN", "Columbian"), | ||
("CAMBODIAN", "Cambodian"), | ||
("CHAOCHOW", "Chaochow"), | ||
("CROATIAN", "Croatian"), | ||
("CATALAN", "Catalan"), | ||
("CZECH", "Czech"), | ||
("DANISH", "Danish"), | ||
("DARI", "Dari"), | ||
("DUTCH", "Dutch"), | ||
("EGYPTIAN", "Egyptian"), | ||
("ENGLISH", "English"), | ||
("ESTONIAN", "Estonian"), | ||
("ERITREAN", "Eritrean"), | ||
("ESPERANTO", "Esperanto"), | ||
("ETHIOPIAN", "Ethiopian"), | ||
("FARSI", "Farsi"), | ||
("FIJIAN", "Fijian"), | ||
("FLEMISH", "Flemish"), | ||
("FANTI", "Fanti"), | ||
("FRENCH", "French"), | ||
("FINNISH", "Finnish"), | ||
("FULLA", "Fulla"), | ||
("GA", "Ga"), | ||
("GERMAN", "German"), | ||
("GURMUKHI", "Gurmukhi"), | ||
("GAELIC", "Gaelic"), | ||
("GORANI", "Gorani"), | ||
("GEORGIAN", "Georgian"), | ||
("GREEK", "Greek"), | ||
("GUJARATI", "Gujarati"), | ||
("HAKKA", "Hakka"), | ||
("HEBREW", "Hebrew"), | ||
("HINDI", "Hindi"), | ||
("HOMA", "Homa"), | ||
("HAUSA", "Hausa"), | ||
("HUNGARIAN", "Hungarian"), | ||
("HUI", "Hui"), | ||
("ICELANDIC", "Icelandic"), | ||
("IGBO", "Igbo"), | ||
("ILOCANO", "Ilocano"), | ||
("INDONESIAN", "Indonesian"), | ||
("IRAQI", "Iraqi"), | ||
("IRANIAN", "Iranian"), | ||
("ITALIAN", "Italian"), | ||
("JAPANESE", "Japanese"), | ||
("KASHMIRI", "Kashmiri"), | ||
("KREO", "Kreo"), | ||
("KIRUNDI", "Kirundi"), | ||
("KURMANJI", "Kurmanji"), | ||
("KANNADA", "Kannada"), | ||
("KOREAN", "Korean"), | ||
("KRIO", "Krio"), | ||
("KOSOVAN", "Kosovan"), | ||
("KURDISH", "Kurdish"), | ||
("KINYARWANDA", "Kinyarwanda"), | ||
("KINYAMIRENGE", "Kinyamirenge"), | ||
("KAZAKH", "Kazakh"), | ||
("LATVIAN", "Latvian"), | ||
("LAOTIAN", "Laotian"), | ||
("LAO", "Lao"), | ||
("LUBWISI", "Lubwisi"), | ||
("LEBANESE", "Lebanese"), | ||
("LINGALA", "Lingala"), | ||
("LUO", "Luo"), | ||
("LUSOGA", "Lusoga"), | ||
("LITHUANIAN", "Lithuanian"), | ||
("LUGANDA", "Luganda"), | ||
("MANDARIN", "Mandarin"), | ||
("MACEDONIAN", "Macedonian"), | ||
("MOLDOVAN", "Moldovan"), | ||
("MIRPURI", "Mirpuri"), | ||
("MANDINKA", "Mandinka"), | ||
("MALAY", "Malay"), | ||
("MONGOLIAN", "Mongolian"), | ||
("MOROCCAN", "Moroccan"), | ||
("MARATHI", "Marathi"), | ||
("MALTESE", "Maltese"), | ||
("MALAYALAM", "Malayalam"), | ||
("NDEBELE", "Ndebele"), | ||
("NEPALESE", "Nepalese"), | ||
("NIGERIAN", "Nigerian"), | ||
("NORWEGIAN", "Norwegian"), | ||
("NYAKUSE", "Nyakuse"), | ||
("OROMO", "Oromo"), | ||
("OTHER", "Other"), | ||
("PAHARI", "Pahari"), | ||
("PERSIAN", "Persian"), | ||
("PORTUGUESE", "Portuguese"), | ||
("PHILIPINO", "Philipino"), | ||
("POLISH", "Polish"), | ||
("POTHWARI", "Pothwari"), | ||
("PUSTHU", "Pusthu"), | ||
("PUNJABI", "Punjabi"), | ||
("ROMANIAN", "Romanian"), | ||
("RUSSIAN", "Russian"), | ||
("SOTHO", "Sotho"), | ||
("SERBO-CROAT", "Serbo-Croat"), | ||
("SWEDISH", "Swedish"), | ||
("SERBIAN", "Serbian"), | ||
("SHONA", "Shona"), | ||
("SINHALESE", "Sinhalese"), | ||
("SIRAIKI", "Siraiki"), | ||
("SLOVAK", "Slovak"), | ||
("SAMOAN", "Samoan"), | ||
("SLOVENIAN", "Slovenian"), | ||
("SOMALI", "Somali"), | ||
("SORANI", "Sorani"), | ||
("SPANISH", "Spanish"), | ||
("SRI LANKAN", "Sri Lankan"), | ||
("SCOTTISH GAELIC", "Scottish Gaelic"), | ||
("SUDANESE", "Sudanese"), | ||
("SWAHILI", "Swahili"), | ||
("SWAHILLI", "Swahilli"), | ||
("SYLHETI", "Sylheti"), | ||
("TAMIL", "Tamil"), | ||
("TIBETAN", "Tibetan"), | ||
("TELEGU", "Telegu"), | ||
("ELAKIL", "Elakil"), | ||
("TAGALOG", "Tagalog"), | ||
("THAI", "Thai"), | ||
("TIGRINIAN", "Tigrinian"), | ||
("TIGRE", "Tigre"), | ||
("TAJIK", "Tajik"), | ||
("TAIWANESE", "Taiwanese"), | ||
("TURKMANISH", "Turkmanish"), | ||
("TSWANA", "Tswana"), | ||
("TURKISH", "Turkish"), | ||
("TWI", "Twi"), | ||
("UGANDAN", "Ugandan"), | ||
("UKRANIAN", "Ukranian"), | ||
("URDU", "Urdu"), | ||
("USSIAN", "Ussian"), | ||
("UZBEK", "Uzbek"), | ||
("VIETNAMESE", "Vietnamese"), | ||
("WELSH", "Welsh"), | ||
("WOLOF", "Wolof"), | ||
("XHOSA", "Xhosa"), | ||
("YUGOSLAVIAN", "Yugoslavian"), | ||
("YIDDISH", "Yiddish"), | ||
("YORUBA", "Yoruba"), | ||
("ZULU", "Zulu"), | ||
] | ||
|
||
LANG_CHOICES = [ | ||
(lang_code.lower(), lang_name) | ||
for lang_code, lang_name in ADAPTATION_LANGUAGES | ||
if lang_code not in ("ENGLISH", "WELSH") | ||
] | ||
|
||
CONTACT_PREFERENCE = [ | ||
("call", _("I will call you")), | ||
("callback", _("Call me back")), | ||
("thirdparty", _("Call someone else instead of me")), | ||
] | ||
|
||
# If there are no slots available for call me back this will show | ||
NO_SLOT_CONTACT_PREFERENCE = [ | ||
("call", _("I will call you")), | ||
("thirdparty", _("Call someone else instead of me")), | ||
] | ||
|
||
SELECT_OPTION_DEFAULT = [("", _("-- Please select --"))] | ||
THIRDPARTY_RELATIONSHIP = [ | ||
("parent_guardian", _("Parent or guardian")), | ||
("family_friend", _("Family member or friend")), | ||
("professional", _("Professional")), | ||
("legal_advisor", _("Legal adviser")), | ||
("other", _("Other")), | ||
] | ||
THIRDPARTY_RELATIONSHIP_CHOICES = SELECT_OPTION_DEFAULT + THIRDPARTY_RELATIONSHIP |
Oops, something went wrong.