Skip to content

Commit

Permalink
Feature/pronunciation overrides #917 (#936)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgershman authored Feb 23, 2024
1 parent 5449666 commit 1bf5a7b
Show file tree
Hide file tree
Showing 9 changed files with 267 additions and 147 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ docs/build
test-report.xml
tests/reports
coverage.xml
test-results
.phpunit.cache
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

### 4.3.0 (UNRELEASED)
* Added feature for SPAD playback `spad_option`.
* Added the ability to refine the spoken pronunciation of locations. [#917]
* Added the ability to delete groups. [#680]
* Added phone number validation for volunteers. Default is for US phone numbers, but can be configured, review the documentation for options. [#704]
* Added the ability to edit a single shift for a volunteer. [#824]
Expand Down
3 changes: 1 addition & 2 deletions app/Http/Controllers/BotController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ public function getMeetings(Request $request)
$request->has('latitude') ? $request->get('latitude') : null,
$request->has('longitude') ? $request->get('longitude') : null,
$request->has('results_count') ? $request->get('results_count') : 5,
$request->has('today') ? $request->get('today') : null,
$request->has('tomorrow') ? $request->get('tomorrow') : null
$request->has('today') ? $request->get('today') : null
);
return response()->json($meetings)->header("Content-Type", "application/json");
}
Expand Down
16 changes: 12 additions & 4 deletions app/Http/Controllers/CallFlowController.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ public function addresslookup(Request $request)
$twiml->redirect(sprintf("input-method.php?Digits=%s&Retry=1", $request->get('SearchType')))
->setMethod('GET');
} else {
$twiml->say(sprintf("%s %s", $this->settings->word('searching_meeting_information_for'), $coordinates->location))
$twiml->say(sprintf("%s %s", $this->settings->word('searching_meeting_information_for'), $this->pronunciationReplacement($coordinates->location)))
->setVoice($this->settings->voice())
->setLanguage($this->settings->get("language"));
$twiml->redirect(sprintf(
Expand Down Expand Up @@ -970,8 +970,7 @@ public function meetingSearch(Request $request)
$latitude,
$longitude,
$results_count,
null,
null
$request->get("Timestamp")
);
$results_count_num = count($meeting_results->filteredList) < $results_count ? count($meeting_results->filteredList) : $results_count;
} catch (Exception $e) {
Expand Down Expand Up @@ -1064,7 +1063,7 @@ public function meetingSearch(Request $request)

for ($ll = 0; $ll < count($results['location']); $ll++) {
$twiml->pause()->setLength(1);
$twiml->say($results['location'][$ll])
$twiml->say($this->pronunciationReplacement($results['location'][$ll]))
->setVoice($this->settings->voice())
->setLanguage($this->settings->get("language"));
}
Expand Down Expand Up @@ -1276,4 +1275,13 @@ public function geocodeAddress(mixed $address, string $sms_helpline_keyword = ""
}
return $coordinates;
}

private function pronunciationReplacement($subject): string
{
foreach ($this->settings->get("pronunciations") as $item) {
return str_replace($item['source'], $item['target'], $subject);
}

return $subject;
}
}
34 changes: 22 additions & 12 deletions app/Services/MeetingResultsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,27 @@ public function __construct(
$this->config = $config;
}

public function getMeetings($latitude, $longitude, $results_count, $today = null, $tomorrow = null)
public function getMeetings($latitude, $longitude, $results_count, $today = null)
{
$tomorrow = null;
$anchored = true;
if ($latitude != null & $longitude != null) {
$this->setTimeZoneForLatitudeAndLongitude($latitude, $longitude);
$graced_date_time = (new DateTime())->modify(sprintf("-%s minutes", $this->settings->get('grace_minutes')));
if ($today == null) {
$today = $graced_date_time->format("w") + 1;
}
if ($tomorrow == null) {
$tomorrow = $graced_date_time->modify("+24 hours")->format("w") + 1;
$today = (new DateTime())->modify(sprintf("-%s minutes", $this->settings->get('grace_minutes')));
} else {
$anchored = false;
$today = new DateTime($today);
}

$tomorrow = clone $today;
$tomorrow->modify("+24 hours");
}

$meeting_results = new MeetingResults();
$meeting_results = $this->meetingSearch($meeting_results, $latitude, $longitude, $today);
$meeting_results = $this->meetingSearch($meeting_results, $latitude, $longitude, $today, $anchored);
if (count($meeting_results->filteredList) < $results_count) {
$meeting_results = $this->meetingSearch($meeting_results, $latitude, $longitude, $tomorrow);
$meeting_results = $this->meetingSearch($meeting_results, $latitude, $longitude, $tomorrow, $anchored);
}

if ($meeting_results->originalListCount > 0) {
Expand All @@ -52,11 +56,11 @@ public function getMeetings($latitude, $longitude, $results_count, $today = null
$meeting_results->filteredList[0]->longitude
);

$today = (new DateTime())->format("w") + 1;
$today = new DateTime();
}

$sort_day_start = $this->settings->get('meeting_result_sort') == MeetingResultSort::TODAY
? $today : $this->settings->get('meeting_result_sort');
? ($today->format("w") + 1) : $this->settings->get('meeting_result_sort');

$days = array_column($meeting_results->filteredList, 'weekday_tinyint');
$today_str = strval($sort_day_start);
Expand All @@ -69,8 +73,14 @@ public function getMeetings($latitude, $longitude, $results_count, $today = null
return $meeting_results;
}

public function meetingSearch($meeting_results, $latitude, $longitude, $day)
public function meetingSearch($meeting_results, $latitude, $longitude, $timestamp, $anchored = true)
{
if ($timestamp != null) {
$day = $timestamp->format("w") + 1;
} else {
$day = null;
}

$search_results = $this->rootServer->searchForMeetings($latitude, $longitude, $day);
if (is_array($search_results->meetings) || $search_results->meetings instanceof Countable) {
$meeting_results->originalListCount += count($search_results->meetings);
Expand All @@ -87,7 +97,7 @@ public function meetingSearch($meeting_results, $latitude, $longitude, $day)
continue;
}

if (strpos($this->settings->get('custom_query'), "{DAY}")) {
if ($anchored && strpos($this->settings->get('custom_query'), "{DAY}")) {
if (!$this->isItPastTime(
$search_results->meetings[$i]->weekday_tinyint,
$search_results->meetings[$i]->start_time
Expand Down
1 change: 1 addition & 0 deletions app/Services/SettingsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class SettingsService
'postal_code_length' => ['description' => '/general/postal-code-lengths' , 'default' => 5, 'overridable' => true, 'hidden' => false],
'province_lookup' => ['description' => '/general/stateprovince-lookup' , 'default' => false, 'overridable' => true, 'hidden' => false],
'province_lookup_list' => ['description' => '/general/stateprovince-lookup' , 'default' => [], 'overridable' => true, 'hidden' => false],
'pronunciations' => ['descriptions' => '/meeting-search/pronunciations', 'default' => [], 'overridable' => true, 'hidden' => false],
'result_count_max' => ['description' => '/meeting-search/results-counts-maximums' , 'default' => 5, 'overridable' => true, 'hidden' => false],
'say_links' => ['description' => '/meeting-search/say-links', 'default' => false, 'overridable' => true, 'hidden' => false],
'service_body_id' => ['description' => '', 'default' => null, 'overridable' => true, 'hidden' => false],
Expand Down
14 changes: 14 additions & 0 deletions docs/docs/meeting-search/pronunciations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Pronunciations

---

Sometimes the speech result of meeting locations may not be accurate based off the voice's ability to say it. You can override this by specifying the original word (`source`) and the new word (`target`)

Example:

```php
static $pronunciations = [[
"source"=>"Yakima",
"target"=>"UkEEma"
]];
```
34 changes: 32 additions & 2 deletions tests/Feature/AddressLookupTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

use App\Services\SettingsService;

beforeAll(function () {
putenv("ENVIRONMENT=test");
});
Expand All @@ -10,7 +13,7 @@
$_SESSION = null;
});

test('search by address for someone to talk to with speech text result with google api key', function ($method) {
test('search by address for meeting information with speech text result with google api key', function ($method) {
$response = $this->call(
$method,
'/address-lookup.php',
Expand All @@ -31,7 +34,7 @@
], false);
})->with(['GET', 'POST']);

test('search by zip code for someone to talk to with speech text result with google api key', function ($method) {
test('search by zip code for meeting information with speech text result with google api key', function ($method) {
$response = $this->call(
$method,
'/address-lookup.php',
Expand All @@ -51,3 +54,30 @@
'</Response>'
], false);
})->with(['GET', 'POST']);

test('search by zip code for meeting information with speech text result and pronunciation override with google api key', function ($method) {
$settingsService = new SettingsService();
$settingsService->set('pronunciations', [[
"source"=>"Yakima",
"target"=>"UkEEma"
]]);
app()->instance(SettingsService::class, $settingsService);
$response = $this->call(
$method,
'/address-lookup.php',
[
"Digits" => "98901",
"SearchType" => "2",
]
);
$response
->assertStatus(200)
->assertHeader("Content-Type", "text/xml; charset=UTF-8")
->assertSeeInOrder([
'<?xml version="1.0" encoding="UTF-8"?>',
'<Response>',
'<Say voice="alice" language="en-US">searching meeting information for UkEEma, WA 98901, USA</Say>',
'<Redirect method="GET">meeting-search.php?Latitude=46.6140435&amp;Longitude=-120.4454218</Redirect>',
'</Response>'
], false);
})->with(['GET', 'POST']);
Loading

0 comments on commit 1bf5a7b

Please sign in to comment.