Skip to content

Commit 389b514

Browse files
author
Chris Bellew
committed
Moved all pattern matching into xml so they can be localized.
1 parent dc18887 commit 389b514

File tree

6 files changed

+91
-30
lines changed

6 files changed

+91
-30
lines changed

Voice Control For Plex/src/main/java/com/atomjack/vcfp/MainActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ public void importTaskerProject(MenuItem item) {
377377
is.close();
378378

379379
String xmlContents = new String(buffer);
380-
xmlContents = xmlContents.replace("%RECOGNITION_REGEX%", VoiceControlForPlexApplication.recognition_regex);
380+
xmlContents = xmlContents.replace("%RECOGNITION_REGEX%", getString(R.string.pattern_recognition));
381381
buffer = xmlContents.getBytes();
382382
Logger.d("directory: %s", Environment.getExternalStorageDirectory());
383383

Voice Control For Plex/src/main/java/com/atomjack/vcfp/PlayReceiver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void onReceive(final Context context, final Intent intent)
1616
if(queryText == null && intent.getStringExtra(GoogleSearchApi.KEY_QUERY_TEXT) != null)
1717
queryText = intent.getStringExtra(GoogleSearchApi.KEY_QUERY_TEXT);
1818

19-
if(queryText != null && queryText.matches(VoiceControlForPlexApplication.recognition_regex)) {
19+
if(queryText != null && queryText.matches(context.getResources().getString(R.string.pattern_recognition))) {
2020
queryText = queryText.toLowerCase();
2121
Intent sendIntent = new Intent(context, PlexSearch.class);
2222
sendIntent.setAction("com.atomjack.vcfp.intent.ACTION_SEARCH");

Voice Control For Plex/src/main/java/com/atomjack/vcfp/PlexSearch.java

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
7373
if (intent.getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS) != null) {
7474
ArrayList<String> voiceResults = intent.getExtras().getStringArrayList(RecognizerIntent.EXTRA_RESULTS);
7575
for(String q : voiceResults) {
76-
if(q.matches(VoiceControlForPlexApplication.recognition_regex)) {
76+
if(q.matches(getString(R.string.pattern_recognition))) {
7777
queryText = q;
7878
break;
7979
}
@@ -217,22 +217,22 @@ private void handleVoiceSearch() {
217217
Logger.d("Servers: %d", VoiceControlForPlexApplication.getPlexMediaServers().size());
218218

219219
// Check for a sentence starting with "resume watching"
220-
p = Pattern.compile("^resume watching (.*)");
220+
p = Pattern.compile(getString(R.string.pattern_resume_watching));
221221
matcher = p.matcher(queryText);
222222
if(matcher.find()) {
223223
resumePlayback = true;
224224
// Replace "resume watching" with just "watch" so the pattern matching below works
225-
queryText = queryText.replaceAll("^resume watching ", "watch ");
225+
queryText = matcher.replaceAll(getString(R.string.pattern_watch));
226226
}
227227

228-
p = Pattern.compile( "watch movie (.*)", Pattern.DOTALL);
228+
p = Pattern.compile( getString(R.string.pattern_watch_movie), Pattern.DOTALL);
229229
matcher = p.matcher(queryText);
230230
if(matcher.find()) {
231231
mediaType = "movie";
232232
queryTerm = matcher.group(1);
233233
}
234234
if(mediaType.equals("")) {
235-
p = Pattern.compile("watch season ([0-9]+) episode ([0-9]+) of (.*)");
235+
p = Pattern.compile(getString(R.string.pattern_watch_season_episode_of_show));
236236
matcher = p.matcher(queryText);
237237

238238
if(matcher.find()) {
@@ -243,7 +243,7 @@ private void handleVoiceSearch() {
243243
}
244244
}
245245
if(mediaType.equals("")) {
246-
p = Pattern.compile("watch (.*) season ([0-9]+) episode ([0-9]+)");
246+
p = Pattern.compile(getString(R.string.pattern_watch_show_season_episode));
247247
matcher = p.matcher(queryText);
248248

249249
if(matcher.find()) {
@@ -254,7 +254,7 @@ private void handleVoiceSearch() {
254254
}
255255
}
256256
if(mediaType.equals("")) {
257-
p = Pattern.compile("watch episode (.*) of (.*)");
257+
p = Pattern.compile(getString(R.string.pattern_watch_episode_of_show));
258258
matcher = p.matcher(queryText);
259259
if(matcher.find()) {
260260
mediaType = "show";
@@ -263,7 +263,7 @@ private void handleVoiceSearch() {
263263
}
264264
}
265265
if(mediaType.equals("")) {
266-
p = Pattern.compile("watch the next episode of (.*)");
266+
p = Pattern.compile(getString(R.string.pattern_watch_next_episode_of_show));
267267
matcher = p.matcher(queryText);
268268

269269
if(matcher.find()) {
@@ -273,7 +273,7 @@ private void handleVoiceSearch() {
273273
}
274274
}
275275
if(mediaType.equals("")) {
276-
p = Pattern.compile("watch( the)? latest episode of (.*)");
276+
p = Pattern.compile(getString(R.string.pattern_watch_latest_episode_of_show));
277277
matcher = p.matcher(queryText);
278278

279279
if(matcher.find()) {
@@ -283,7 +283,7 @@ private void handleVoiceSearch() {
283283
}
284284
}
285285
if(mediaType.equals("")) {
286-
p = Pattern.compile("watch (.*) episode (.*)");
286+
p = Pattern.compile(getString(R.string.pattern_watch_show_episode_named));
287287
matcher = p.matcher(queryText);
288288
if(matcher.find()) {
289289
mediaType = "show";
@@ -293,7 +293,7 @@ private void handleVoiceSearch() {
293293
}
294294
// Lastly, try to find a movie matching whatever comes after "watch"
295295
if(mediaType.equals("")) {
296-
p = Pattern.compile("watch (.*)");
296+
p = Pattern.compile(getString(R.string.pattern_watch2));
297297
matcher = p.matcher(queryText);
298298

299299
if(matcher.find()) {
@@ -302,7 +302,7 @@ private void handleVoiceSearch() {
302302
}
303303
}
304304
if(mediaType.equals("")) {
305-
p = Pattern.compile("listen to the album (.*) by (.*)");
305+
p = Pattern.compile(getString(R.string.pattern_listen_to_album_by_artist));
306306
matcher = p.matcher(queryText);
307307
if(matcher.find()) {
308308
mediaType = "music";
@@ -311,13 +311,14 @@ private void handleVoiceSearch() {
311311
}
312312
}
313313
if(mediaType.equals("")) {
314-
p = Pattern.compile("listen to the album (.*)");
314+
p = Pattern.compile(getString(R.string.pattern_listen_to_album));
315315
matcher = p.matcher(queryText);
316316
if(matcher.find()) {
317317
mediaType = "music";
318318
album = matcher.group(1);
319319
}
320320
}
321+
/*
321322
if(mediaType.equals("")) {
322323
p = Pattern.compile("listen to (.*) by (.*)");
323324
matcher = p.matcher(queryText);
@@ -327,48 +328,49 @@ private void handleVoiceSearch() {
327328
artist = matcher.group(2);
328329
}
329330
}
331+
*/
330332
if(mediaType.equals("")) {
331-
p = Pattern.compile("pause playback", Pattern.DOTALL);
333+
p = Pattern.compile(getString(R.string.pattern_pause_playback), Pattern.DOTALL);
332334
matcher = p.matcher(queryText);
333335
if (matcher.find()) {
334336
Logger.d("pausing playback");
335337
pausePlayback();
336338
return;
337339
}
338-
p = Pattern.compile("resume playback", Pattern.DOTALL);
340+
p = Pattern.compile(getString(R.string.pattern_resume_playback), Pattern.DOTALL);
339341
matcher = p.matcher(queryText);
340342
if (matcher.find()) {
341343
Logger.d("resuming playback");
342344
resumePlayback();
343345
return;
344346
}
345-
p = Pattern.compile("stop playback", Pattern.DOTALL);
347+
p = Pattern.compile(getString(R.string.pattern_stop_playback), Pattern.DOTALL);
346348
matcher = p.matcher(queryText);
347349
if (matcher.find()) {
348350
Logger.d("stopping playback");
349351
stopPlayback();
350352
return;
351353
}
352-
p = Pattern.compile("(offset|timecode) ([0-9]+|two) (hours?|minutes?|seconds?)(?: ([0-9]+|two) (minutes?|seconds?))?(?: ([0-9]+|two) (seconds?))?", Pattern.DOTALL);
354+
p = Pattern.compile(getString(R.string.pattern_offset), Pattern.DOTALL);
353355
matcher = p.matcher(queryText);
354356
if (matcher.find()) {
355-
String groupOne = matcher.group(2) != null && matcher.group(2).equals("two") ? "2" : matcher.group(2);
356-
String groupThree = matcher.group(4) != null && matcher.group(4).equals("two") ? "2" : matcher.group(4);
357-
String groupFive = matcher.group(6) != null && matcher.group(6).equals("two") ? "2" : matcher.group(6);
357+
String groupOne = matcher.group(2) != null && matcher.group(2).matches("two|to") ? "2" : matcher.group(2);
358+
String groupThree = matcher.group(4) != null && matcher.group(4).matches("two|to") ? "2" : matcher.group(4);
359+
String groupFive = matcher.group(6) != null && matcher.group(6).matches("two|to") ? "2" : matcher.group(6);
358360
int hours = 0, minutes = 0, seconds = 0;
359-
if(matcher.group(5) != null && matcher.group(5).startsWith("minute"))
361+
if(matcher.group(5) != null && matcher.group(5).matches(getString(R.string.pattern_minutes)))
360362
minutes = Integer.parseInt(groupThree);
361-
else if(matcher.group(3) != null && matcher.group(3).startsWith("minute"))
363+
else if(matcher.group(3) != null && matcher.group(3).matches(getString(R.string.pattern_minutes)))
362364
minutes = Integer.parseInt(groupOne);
363365

364-
if(matcher.group(6) != null && matcher.group(6).startsWith("second"))
366+
if(matcher.group(7) != null && matcher.group(7).matches(getString(R.string.pattern_seconds)))
365367
seconds = Integer.parseInt(groupFive);
366-
else if(matcher.group(5) != null && matcher.group(5).startsWith("second"))
368+
else if(matcher.group(5) != null && matcher.group(5).matches(getString(R.string.pattern_seconds)))
367369
seconds = Integer.parseInt(groupThree);
368-
else if(matcher.group(3).startsWith("second"))
370+
else if(matcher.group(3).matches(getString(R.string.pattern_seconds)))
369371
seconds = Integer.parseInt(groupOne);
370372

371-
if(matcher.group(3).startsWith("hour"))
373+
if(matcher.group(3).matches(getString(R.string.pattern_hours)))
372374
hours = Integer.parseInt(groupOne);
373375

374376
seekTo(hours, minutes, seconds);

Voice Control For Plex/src/main/java/com/atomjack/vcfp/VoiceControlForPlexApplication.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public class VoiceControlForPlexApplication
2727

2828
public final static String INTENT_GDMRECEIVE = "0";
2929

30-
public final static String recognition_regex = "^(((watch|resume watching|listen to|watch movie) )|((offset|timecode) (.*))|((pause|stop|resume) playback))(.*)(on )?";
3130
private static ConcurrentHashMap<String, PlexServer> plexmediaServers = new ConcurrentHashMap<String, PlexServer>();
3231

3332
public static ConcurrentHashMap<String, PlexServer> getPlexMediaServers() {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
This file contains the regular expressions patterns used for figuring out what action the user wishes to take. When
4+
adding translations, please to not modify (.*), $1, ([0-9]+), etc.
5+
-->
6+
<resources>
7+
<!--
8+
This pattern is the main pattern that will need to be matched in order for anything to be done. As you can see it is
9+
a quite complicated regular expression. Plugging it into https://www.debuggex.com/ should help you figure out how
10+
it is constructed.
11+
-->
12+
<item name="pattern_recognition" type="string">^(((watch|resume watching|listen to|watch movie) (.+))|((offset|timecode) (.+))|((pause|stop|resume) playback))(on (.+))?</item>
13+
14+
<item name="pattern_resume_watching" type="string">^resume watching (.*)</item>
15+
<item name="pattern_watch" type="string">watch $1</item>
16+
<item name="pattern_watch_movie" type="string">watch movie (.*)</item>
17+
<item name="pattern_watch_season_episode_of_show" type="string">watch season ([0-9]+) episode ([0-9]+) of (.*)</item>
18+
<item name="pattern_watch_show_season_episode" type="string">watch (.*) season ([0-9]+) episode ([0-9]+)</item>
19+
<item name="pattern_watch_episode_of_show" type="string">watch episode (.*) of (.*)</item>
20+
<item name="pattern_watch_next_episode_of_show" type="string">watch the next episode of (.*)</item>
21+
<item name="pattern_watch_latest_episode_of_show" type="string">watch( the)? latest episode of (.*)</item>
22+
<item name="pattern_watch_show_episode_named" type="string">watch (.*) episode (.*)</item>
23+
<item name="pattern_watch2" type="string">watch (.*)</item>
24+
25+
<!--
26+
The following pattern lets the user say "listen to <album> by <artist>" or
27+
"listen to the album <album> by <artist>".
28+
-->
29+
<item name="pattern_listen_to_album_by_artist" type="string">listen to( the album)? (.*) by (.*)</item>
30+
31+
<item name="pattern_listen_to_album" type="string">listen to the album (.*)</item>
32+
<item name="pattern_pause_playback" type="string">pause playback</item>
33+
<item name="pattern_resume_playback" type="string">resume playback</item>
34+
<item name="pattern_stop_playback" type="string">stop playback</item>
35+
36+
<!--
37+
The following are used in conjunction with the pattern_offset below. These should match the
38+
(hours?minutes?seconds?), with the addition of the ^ character (to indicate that in the matching
39+
pattern group starts with (hours or minutes or seconds). Unreliable behavior may result if
40+
these to not match the corresponding groups in pattern_offset.
41+
-->
42+
<item name="pattern_hours" type="string">^hours?</item>
43+
<item name="pattern_minutes" type="string">^minutes?</item>
44+
<item name="pattern_seconds" type="string">^seconds?</item>
45+
46+
<!--
47+
Offset pattern. This lets the user start with with "offset" or "timecode", followed by:
48+
any number followed by "hour(s)" or "minute(s)" or "second(s)", and optionally followed by:
49+
any number followed by "minute(s)" or "second(s)", and optionally followed by:
50+
any number followed by "second(s)"
51+
The ([0-9]+|two|to) pattern will most likely only need to be ([0-9]+) for other languages, as in English,
52+
the number 2 sounds the same as "to" and "two", so sometimes the Voice Recognition engine will confuse the
53+
number 2 with "to" or "two". If your language has numbers that sound exactly like other words that the
54+
Voice Recognition will sometimes mis-translate, please contact Chris Bellew as some further changes will need
55+
to be made to the code to accommodate this.
56+
57+
The (hours?|minutes?|seconds?) means hour, with or without an s at the end (singular or plural), and the
58+
same for minutes and seconds (the | means "or").
59+
-->
60+
<item name="pattern_offset" type="string">^(offset|timecode) ([0-9]+|two|to) (hours?|minutes?|seconds?)(?: ([0-9]+|two|to) (minutes?|seconds?))?(?: ([0-9]+|two|to) (seconds?))?</item>
61+
</resources>

Voice Control For Plex/src/main/res/values/strings.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<resources>
22
<string name="app_name">Voice Control for Plex</string>
33
<string name="action_settings">Settings</string>
4-
<string name="hello_world">Hello world!</string>
54
<string name="ok">OK</string>
65
<string name="got_it">Got it</string>
76
<string name="stream_video_from_server">Stream video from the server</string>

0 commit comments

Comments
 (0)