mirror of
https://github.com/ZaidElkurdi/AssistantPlus.git
synced 2025-01-22 11:28:31 +00:00
- 1.1.0
This commit is contained in:
parent
6ada354e53
commit
1f95829caa
@ -1 +1 @@
|
||||
58
|
||||
74
|
@ -0,0 +1 @@
|
||||
1
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
Package: com.zaid.assistant+
|
||||
Package: org.thebigboss.assistantplus
|
||||
Name: Assistant+
|
||||
Depends: libactivator (>= 1.8.3), mobilesubstrate
|
||||
Version: 1.0.1
|
||||
Version: 1.1.0
|
||||
Architecture: iphoneos-arm
|
||||
Description: Assign commands to trigger Activator events from Siri, set up custom replies for Siri, and also use and create plugins for Siri using the Assistant+ plugin framework
|
||||
Maintainer: Zaid Elkurdi
|
||||
|
Binary file not shown.
@ -175,10 +175,12 @@ typedef enum {
|
||||
|
||||
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 60, 50)];
|
||||
|
||||
UITextField *nameField = [[UITextField alloc] initWithFrame:CGRectMake(80, 2, self.view.frame.size.width-60, 50)];
|
||||
UITextField *nameField = [[UITextField alloc] initWithFrame:CGRectMake(80, 2, self.view.frame.size.width-80, 50)];
|
||||
nameField.delegate = self;
|
||||
nameField.tag = -1;
|
||||
nameField.returnKeyType = UIReturnKeyDone;
|
||||
nameField.adjustsFontSizeToFitWidth = YES;
|
||||
nameField.minimumFontSize = 3.0f;
|
||||
|
||||
if (cellType == APNameCell) {
|
||||
nameLabel.text = @"Name:";
|
||||
@ -197,6 +199,8 @@ typedef enum {
|
||||
} else if (cellType == APCommandCell) {
|
||||
nameLabel.hidden = YES;
|
||||
nameField.text = self.currCommand.command;
|
||||
nameField.autocorrectionType = UITextAutocorrectionTypeNo;
|
||||
nameField.autocapitalizationType = UITextAutocapitalizationTypeNone;
|
||||
self.commandField = nameField;
|
||||
|
||||
CGRect oldFrame = self.commandField.frame;
|
||||
@ -214,20 +218,39 @@ typedef enum {
|
||||
UITableViewCell *cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
|
||||
cell.selectionStyle = UITableViewCellSelectionStyleNone;
|
||||
|
||||
UITextField *nameField = [[UITextField alloc] initWithFrame:CGRectMake(10, 2, self.view.frame.size.width-10, 50)];
|
||||
UITextField *nameField = [[UITextField alloc] initWithFrame:CGRectMake(10, 2, self.view.frame.size.width-200, 50)];
|
||||
nameField.delegate = self;
|
||||
nameField.tag = 100+index;
|
||||
nameField.returnKeyType = UIReturnKeyDone;
|
||||
nameField.adjustsFontSizeToFitWidth = YES;
|
||||
nameField.minimumFontSize = 8.0f;
|
||||
nameField.placeholder = @"Unnamed Variable";
|
||||
|
||||
NSString *variableName = [self.mutableVariables objectAtIndex:index];
|
||||
|
||||
|
||||
NSString *variableName = self.mutableVariables[index][0];
|
||||
|
||||
if (variableName.length > 0) {
|
||||
nameField.text = variableName;
|
||||
} else {
|
||||
nameField.text = @"";
|
||||
}
|
||||
|
||||
CGFloat nameFieldEnd = nameField.frame.origin.x + nameField.frame.size.width;
|
||||
UILabel *escapeLabel = [[UILabel alloc] initWithFrame:CGRectMake(nameFieldEnd+15, 1, 110, 50)];
|
||||
escapeLabel.text = @"URL Encode:";
|
||||
|
||||
CGFloat escapeLabelEnd = escapeLabel.frame.origin.x + escapeLabel.frame.size.width;
|
||||
UISwitch *escapeSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(escapeLabelEnd+5, 9.5, 51, 31)];
|
||||
[escapeSwitch addTarget:self action:@selector(didToggleSwitch:) forControlEvents:UIControlEventValueChanged];
|
||||
escapeSwitch.tag = index;
|
||||
|
||||
BOOL enabled = [self.mutableVariables[index][1] boolValue];
|
||||
escapeSwitch.on = enabled;
|
||||
|
||||
[cell.contentView addSubview:nameField];
|
||||
[cell.contentView addSubview:escapeLabel];
|
||||
[cell.contentView addSubview:escapeSwitch];
|
||||
|
||||
return cell;
|
||||
}
|
||||
@ -359,6 +382,11 @@ typedef enum {
|
||||
[actionSheet showInView:self.view];
|
||||
}
|
||||
|
||||
- (void)didToggleSwitch:(UISwitch*)theSwitch {
|
||||
self.didChange = YES;
|
||||
self.mutableVariables[theSwitch.tag] = @[self.mutableVariables[theSwitch.tag][0], [NSNumber numberWithBool:theSwitch.on]];
|
||||
}
|
||||
|
||||
- (void)whenButtonPressedForIndex:(UIButton*)button {
|
||||
self.conditionalToEdit = button.tag;
|
||||
self.editingType = APWhenValue;
|
||||
@ -373,7 +401,8 @@ typedef enum {
|
||||
|
||||
- (void)displayVariableSelection {
|
||||
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Select Variable..." delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:nil, nil];
|
||||
for (NSString *name in self.mutableVariables) {
|
||||
for (NSArray *currVariable in self.mutableVariables) {
|
||||
NSString *name = currVariable[0];
|
||||
if (name.length > 0) {
|
||||
[actionSheet addButtonWithTitle:name];
|
||||
}
|
||||
@ -389,7 +418,7 @@ typedef enum {
|
||||
if (buttonIndex == 1) {
|
||||
//variable
|
||||
section = 2;
|
||||
[self.mutableVariables addObject:@""];
|
||||
[self.mutableVariables addObject:@[@"", [NSNumber numberWithBool:NO]]];
|
||||
row = self.mutableVariables.count-1;
|
||||
|
||||
} else if (buttonIndex == 2) {
|
||||
@ -410,7 +439,7 @@ typedef enum {
|
||||
}
|
||||
|
||||
- (void)variableSelectionSheetClickedButtonAtIndex:(NSInteger)buttonIndex {
|
||||
NSString *variableName = [self.mutableVariables objectAtIndex:buttonIndex-1];
|
||||
NSString *variableName = [self.mutableVariables objectAtIndex:buttonIndex-1][0];
|
||||
if (self.editingType == APSetValue) {
|
||||
[[self.mutableConditionals objectAtIndex:self.conditionalToEdit] setObject:variableName atIndexedSubscript:2];
|
||||
} else if (self.editingType == APWhenValue) {
|
||||
@ -455,17 +484,20 @@ typedef enum {
|
||||
|
||||
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
|
||||
self.didChange = YES;
|
||||
|
||||
NSString *newText = [textField.text stringByReplacingCharactersInRange:range withString:string];
|
||||
if (textField.tag - 2000 >= 0) {
|
||||
[[self.mutableConditionals objectAtIndex:textField.tag-2000] setObject:newText atIndexedSubscript:3];
|
||||
} else if (textField.tag - 1000 >= 0) {
|
||||
[[self.mutableConditionals objectAtIndex:textField.tag-1000] setObject:newText atIndexedSubscript:1];
|
||||
} else if (textField.tag - 100 >= 0) {
|
||||
[self.mutableVariables setObject:newText atIndexedSubscript:textField.tag-100];
|
||||
[self.mutableVariables setObject:@[newText, self.mutableVariables[textField.tag-100][1]] atIndexedSubscript:textField.tag-100];
|
||||
} else if (textField == self.nameField) {
|
||||
self.currCommand.name = newText;
|
||||
} else if (textField == self.triggerField) {
|
||||
self.currCommand.trigger = newText;
|
||||
} else if (textField == self.commandField) {
|
||||
self.currCommand.command = newText;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
@ -477,11 +509,12 @@ typedef enum {
|
||||
#pragma mark - Helpers
|
||||
|
||||
- (NSString*)getHelpMessage {
|
||||
return @"Enabled: For a listener to appear in Activator it must be enabled\n"
|
||||
"\nPassthrough: If enabled, Assistant+ will continue searching for another Activator listener, custom reply, or plugin to handle the command. If it doesn't find anything to handle the command, Siri will go to its default action. You can add a voice confirmation for your Activator listener if you create a custom reply for the same trigger and then enable passthrough for your listener\n"
|
||||
"\nName: A name to describe your listener. This can be anything and is purely for informational purposes\n"
|
||||
"\nTrigger: The command that will trigger the Activator listener, you must have at least one for the listener to appear in Activator. You may use wildcards in the trigger by using (.*). For example, '(.*)turn on the lights' will trigger on \"Turn on the lights\", \"Siri turn on the lights\", \"Hey Siri please turn on the lights\", etc.\n"
|
||||
"\nOnce you create an Activator listener here you must go to Activator and assign it to an event.";
|
||||
return @"Name: A name to describe your capture group command. This can be anything and is purely for informational purposes\n"
|
||||
"\nTrigger: The command that will trigger the capture group command. In order to capture what the user says and assign it to a variable you must surround the variable's name in square brackets. For example, if 'Search for [query] on Yelp' were your trigger, then the command 'Search for Italian Restaurants on Yelp' would assign 'Italian Restaurants' to the 'query' variable. This field also supports NSRegularExpression syntax, with the only difference being the capture group syntax.\n"
|
||||
"\nVariables: The variables that are involved in your capture group command. In order to capture a variable in your trigger you must first create one with the same name.\n"
|
||||
"\nURL Encode: If you enable this option your variable will be percent encoded. This is useful if you intend to use your variable as an argument in a network call or with uiopen.\n"
|
||||
"\nConditionals: A conditional can be used to assign a value to a variable based on the value of another (or the same) variable. Conditionals are evaluated after your capture group command is triggered and the initial variable values have been captured. Remember that all values will be compared as strings, so \"5.0\" will not equal \"5\".\n"
|
||||
"\nCommand: The shell command that will be executed when your capture group command is triggered. In order to use variables in this command you must follow the same syntax as the trigger and surround the variable's name with square brackets. Following the example in the trigger description, 'uiopen yelp:///search?terms=[query]' will evaluate to 'uiopen yelp:///search?terms=italian%20restaurants'.";
|
||||
}
|
||||
|
||||
@end
|
||||
|
Binary file not shown.
@ -9,7 +9,8 @@
|
||||
#import "APCaptureGroupCommand.h"
|
||||
|
||||
@implementation APCaptureGroupCommand {
|
||||
NSArray *variableRanges;
|
||||
NSArray *commandVariableRanges;
|
||||
NSArray *triggerVariableRanges;
|
||||
}
|
||||
|
||||
-(id)initWithDictionary:(NSDictionary*)dict {
|
||||
@ -25,29 +26,77 @@
|
||||
self.variables = variables ? variables : [NSArray array];
|
||||
self.conditionals = conditionals ? conditionals : [NSArray array];
|
||||
self.command = command ? command : @"";
|
||||
self.trigger = [NSRegularExpression regularExpressionWithPattern:trigger options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
self.uuid = uuid ? uuid : [NSString stringWithFormat:@"%@", [NSUUID UUID]];
|
||||
[self buildRangeDictionary];
|
||||
|
||||
[self buildRangeDictionariesWithTrigger:trigger andCommand:self.command];
|
||||
self.trigger = [self buildRegularExpressionWithString:trigger];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)buildRangeDictionary {
|
||||
NSMutableArray *newVariableRanges = [[NSMutableArray alloc] init];
|
||||
for (NSString *currVariable in self.variables) {
|
||||
NSRange currRange = [self.command rangeOfString:[NSString stringWithFormat:@"[%@]", currVariable]];
|
||||
if (currRange.location != NSNotFound) {
|
||||
[newVariableRanges addObject:@[currVariable, [NSValue valueWithRange:currRange]]];
|
||||
- (void)buildRangeDictionariesWithTrigger:(NSString*)trigger andCommand:(NSString*)command {
|
||||
NSMutableArray *newCommandVariableRanges = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *newTriggerVariableRanges = [[NSMutableArray alloc] init];
|
||||
|
||||
for (NSArray *currVariableInfo in self.variables) {
|
||||
NSString *currVariable = [NSString stringWithFormat:@"\\[%@\\]", currVariableInfo[0]];
|
||||
NSLog(@"Expression: %@", currVariable);
|
||||
NSRegularExpression *currExpression = [NSRegularExpression regularExpressionWithPattern:currVariable options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
|
||||
NSArray *triggerMatches = [currExpression matchesInString:trigger options:0 range:NSMakeRange(0, [trigger length])];
|
||||
for (NSTextCheckingResult *match in triggerMatches) {
|
||||
if (match.numberOfRanges > 0) {
|
||||
for (NSInteger currIndex = 0; currIndex < match.numberOfRanges; currIndex++) {
|
||||
NSString *variableValue = [[trigger substringWithRange:[match rangeAtIndex:currIndex]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
NSLog(@"Trigger Match %ld: %@", (long)currIndex, variableValue);
|
||||
[newTriggerVariableRanges addObject:@[currVariableInfo[0], [NSValue valueWithRange:[match rangeAtIndex:currIndex]], currVariableInfo[1]]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NSArray *commandMatches = [currExpression matchesInString:command options:0 range:NSMakeRange(0, [command length])];
|
||||
for (NSTextCheckingResult *match in commandMatches) {
|
||||
if (match.numberOfRanges > 0) {
|
||||
for (NSInteger currIndex = 0; currIndex < match.numberOfRanges; currIndex++) {
|
||||
NSString *variableValue = [[command substringWithRange:[match rangeAtIndex:currIndex]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
NSLog(@"Command Match %ld: %@", (long)currIndex, variableValue);
|
||||
[newCommandVariableRanges addObject:@[currVariableInfo[0], [NSValue valueWithRange:[match rangeAtIndex:currIndex]]]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Sort the variables by location in order to calculate offset easily
|
||||
variableRanges = [newVariableRanges sortedArrayUsingComparator:^NSComparisonResult(NSArray *first, NSArray *second) {
|
||||
NSComparator rangeComparator = ^NSComparisonResult(NSArray *first, NSArray *second) {
|
||||
NSRange firstRange = [first[1] rangeValue];
|
||||
NSRange secondRange = [second[1] rangeValue];
|
||||
|
||||
return firstRange.location > secondRange.location;
|
||||
}];
|
||||
};
|
||||
|
||||
|
||||
//Sort the variables by location in order to calculate offset easily
|
||||
commandVariableRanges = [newCommandVariableRanges sortedArrayUsingComparator:rangeComparator];
|
||||
triggerVariableRanges = [newTriggerVariableRanges sortedArrayUsingComparator:rangeComparator];
|
||||
}
|
||||
|
||||
- (NSRegularExpression*)buildRegularExpressionWithString:(NSString*)triggerString {
|
||||
NSMutableString *mutableExpression = [triggerString mutableCopy];
|
||||
NSInteger offset = 0;
|
||||
for (NSArray *currVariablePair in triggerVariableRanges) {
|
||||
NSString *currVariable = currVariablePair[0];
|
||||
NSLog(@"Currently on %@", currVariable);
|
||||
if (!currVariable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
NSRange rangeToReplace = [currVariablePair[1] rangeValue];
|
||||
rangeToReplace.location += offset;
|
||||
|
||||
[mutableExpression replaceCharactersInRange:rangeToReplace withString:@"(.*)"];
|
||||
offset += 4 - rangeToReplace.length;
|
||||
}
|
||||
NSLog(@"Finished trigger: %@", mutableExpression);
|
||||
return [NSRegularExpression regularExpressionWithPattern:mutableExpression options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
}
|
||||
|
||||
-(NSString*)buildCommandWithValues:(NSArray*)values {
|
||||
@ -57,16 +106,21 @@
|
||||
NSLog(@"Values: %@", values);
|
||||
for (NSString *currValue in values) {
|
||||
NSLog(@"On: %@", currValue);
|
||||
if (currIndex < self.variables.count) {
|
||||
NSLog(@"Adding: %@", currValue);
|
||||
NSString *currVariable = self.variables[currIndex];
|
||||
if (currIndex < triggerVariableRanges.count) {
|
||||
BOOL shouldEscape = [triggerVariableRanges[currIndex][2] boolValue];
|
||||
NSString *valueToSave = currValue;
|
||||
if (shouldEscape) {
|
||||
valueToSave = [currValue stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
NSLog(@"Adding: %@", valueToSave);
|
||||
NSString *currVariable = triggerVariableRanges[currIndex][0];
|
||||
NSLog(@"Assigning to %@", currVariable);
|
||||
variablesToValues[currVariable] = currValue;
|
||||
variablesToValues[currVariable] = valueToSave;
|
||||
}
|
||||
currIndex++;
|
||||
}
|
||||
|
||||
//Second, check the conditionals to see
|
||||
//Second, check the conditionals to see if we should reassign anything
|
||||
for (NSArray *currRule in self.conditionals) {
|
||||
NSString *conditionalVariable = currRule[0];
|
||||
NSString *conditionalValue = currRule[1];
|
||||
@ -77,7 +131,9 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
NSLog(@"V to V: %@", variablesToValues);
|
||||
NSString *actualValue = variablesToValues[conditionalVariable];
|
||||
NSLog(@"Actual: %@ Conditional: %@", actualValue, conditionalValue);
|
||||
if (actualValue) {
|
||||
if ([actualValue compare:conditionalValue options:NSCaseInsensitiveSearch] == NSOrderedSame) {
|
||||
variablesToValues[targetVariable] = targetValue;
|
||||
@ -86,9 +142,10 @@
|
||||
}
|
||||
|
||||
NSLog(@"Var to Val: %@", variablesToValues);
|
||||
NSLog(@"Command to Val: %@", commandVariableRanges);
|
||||
NSMutableString *mutableCommand = [self.command mutableCopy];
|
||||
NSInteger offset = 0;
|
||||
for (NSArray *currVariablePair in variableRanges) {
|
||||
for (NSArray *currVariablePair in commandVariableRanges) {
|
||||
NSString *currVariable = currVariablePair[0];
|
||||
NSString *currValue = variablesToValues[currVariable];
|
||||
NSLog(@"Currently on %@ %@", currVariable, currValue);
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
Package: com.zaid.assistant+
|
||||
Package: org.thebigboss.assistantplus
|
||||
Name: Assistant+
|
||||
Depends: libactivator (>= 1.8.3), mobilesubstrate
|
||||
Version: 1.0.1
|
||||
Version: 1.1.0
|
||||
Architecture: iphoneos-arm
|
||||
Description: Assign commands to trigger Activator events from Siri, set up custom replies for Siri, and also use and create plugins for Siri using the Assistant+ plugin framework
|
||||
Maintainer: Zaid Elkurdi
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user