From 9ef641fb48e44710ff32f6b30f4bf9a66490bc5a Mon Sep 17 00:00:00 2001 From: Jeremy Date: Fri, 23 Aug 2019 13:27:37 -0500 Subject: [PATCH] Added for each and timout to angular --- _angularjs_grammar.py | 19 ++- _custom_globals.py | 2 +- _explorer_tools.py | 246 ++++++++++++++++++++++++++++ _firefox.py | 354 +++++++++++++++++++++++++++++++++++++++++ _html_grammar.py | 9 +- _javascript_grammar.py | 8 +- 6 files changed, 627 insertions(+), 11 deletions(-) create mode 100644 _explorer_tools.py create mode 100644 _firefox.py diff --git a/_angularjs_grammar.py b/_angularjs_grammar.py index 77b3028..6389040 100644 --- a/_angularjs_grammar.py +++ b/_angularjs_grammar.py @@ -2,18 +2,22 @@ # This script includes commands that are to be used for Angular programming from dragonfly import (Grammar, CompoundRule, Dictation, RuleRef, DictList, DictListRef, Text, Key, AppContext, MappingRule, Function, Sequence, Mimic) +import win32com.client +speaker = win32com.client.Dispatch("SAPI.SpVoice") def doSomethingToCommand(command): newCommand = Sequence(command) newCommand.execute() class AngularEnabler(CompoundRule): - spec = "Activate Angular JS" # Spoken form of command. + spec = "Activate Angular" # Spoken form of command. def _process_recognition(self, node, extras): # Callback when command is spoken. AngularBootstrap.disable() AngularGrammar.enable() - print "Angular JS grammar enabled" + s = "Angular JS grammar activated" + print s + speaker.Speak(s) class AngularDisabler(CompoundRule): spec = "switch language" # Spoken form of command. @@ -21,11 +25,12 @@ class AngularDisabler(CompoundRule): def _process_recognition(self, node, extras): # Callback when command is spoken. AngularGrammar.disable() AngularBootstrap.enable() - print "Angular JS grammar disabled" - + s = "Angular JS grammar deactivated" + print s + speaker.Speak(s) class AngularTestRule(CompoundRule): - spec = "test Angular JS" # Spoken form of command. + spec = "test Angular" # Spoken form of command. def _process_recognition(self, node, extras): # Callback when command is spoken. print "Angular JS grammar tested" @@ -35,7 +40,9 @@ class AngularControlStructures(MappingRule): mapping = { "variable": Text("var "), "function": Text("function functionName() {") + Key("enter")+ Key("enter"), #+ Text("}"), - "self function": Text("(function() {") + Key("enter")+ Key("enter"), #+ Text("}())"), + "self function": Text("(function() {") + Key("enter") + Key("enter"), #+ Text("}())"), + "for each": Text("angular.forEach( , function(o) {") + Key("enter") + Key("enter") + Text("});") + Key("up"), #+ Key("up"), + "timeout": Text("$timeout(function() {") + Key("enter") + Key("enter") + Text("}, 100);") + Key("up"), #+ Key("up"), "code block": Text("{") + Key("enter")+ Key("enter"), #+ Text("}"), "if": Text("if() {") + Key("enter")+ Key("enter"), #+ Text("}"), "if else": Text("if() {") + Key("enter")+ Key("enter") + Text("}") + Key("enter") + Text("else {") + Key("enter")+ Key("enter"), #+ Text("}"), diff --git a/_custom_globals.py b/_custom_globals.py index fcbf93a..23082cc 100644 --- a/_custom_globals.py +++ b/_custom_globals.py @@ -19,7 +19,7 @@ class UsefulStuff(MappingRule): "enter|slap": Key("enter"), "east": Key("end"), "west": Key("home"), - + "format": Key("ctrl") + Key("alt") + Key("b"), } globalStuff = Grammar("useful custom global commands") # Create a grammar to contain the command rule. diff --git a/_explorer_tools.py b/_explorer_tools.py new file mode 100644 index 0000000..f5ff5ed --- /dev/null +++ b/_explorer_tools.py @@ -0,0 +1,246 @@ +# +# This file is a command-module for Dragonfly. +# (c) Copyright 2008 by Christo Butcher +# Licensed under the LGPL, see +# + +""" +Command-module to control **Windows Explorer** +============================================================================ + +This module defines various voice-commands for use with Windows Explorer. + +.. note:: + + This module is still under development. + +Installation +---------------------------------------------------------------------------- + +If you are using DNS and Natlink, simply place this file in you Natlink +macros directory. It will then be automatically loaded by Natlink when +you next toggle your microphone or restart Natlink. + +""" + +try: + import pkg_resources + pkg_resources.require("dragonfly >= 0.6.5beta1.dev-r76") +except ImportError: + pass + +import os.path +import string +import subprocess +import time +from urllib import unquote +from dragonfly import (ConnectionGrammar, AppContext, CompoundRule, + Choice, Window, Config, Section, Item) + + +#--------------------------------------------------------------------------- + +class SingleFile(object): + + def __init__(self, spec, command_line): + self.spec = spec + self.command_line = command_line + + def execute(self, paths, directory): + for path in paths: + self.execute_single(path, directory) + + def execute_single(self, path, directory): + data = {"path": path, "dir": directory} + arguments = [s % data for s in self.command_line] + print "Arguments: %r" % arguments + process = subprocess.Popen(arguments, stdout=subprocess.PIPE) + out, err = process.communicate() + print "Output:"; print out and out.strip() + print "Error:"; print err and err.strip() + + +class MultiFile(object): + + def __init__(self, spec, command_line_pre, command_line_post): + self.spec = spec + self.command_line_pre = command_line_pre + self.command_line_post = command_line_post + + def execute(self, paths, directory): + data = {"dir": directory} + arguments_pre = [s % data for s in self.command_line_pre] + arguments_post = [s % data for s in self.command_line_post] + arguments = arguments_pre + paths + if arguments_post: + arguments += arguments_post + + print "Arguments: %r" % arguments + process = subprocess.Popen(arguments, stdout=subprocess.PIPE) + out, err = process.communicate() + print "Output:"; print out and out.strip() + print "Error:"; print err and err.strip() + + +class CreateArchiveHere(object): + + def __init__(self, spec, extension): + self.spec = spec + self.extension = extension + + def execute(self, paths, directory): + archive_path = os.path.splitext(os.path.basename(paths[0]))[0] + archive_path = os.path.join(directory, archive_path) + archive_path += time.strftime("-%y%m%d") + + def filenames(basename, extension): +# yield basename + extension + for letter in string.lowercase: + yield basename + letter + extension + + available = False + for archive_path in filenames(archive_path, self.extension): + if not os.path.exists(archive_path): + available = True + break + if not available: + print "Warning: could not create archive." + return + + arguments = [r"C:\Program Files\7-Zip\7z.exe", "a"] + arguments.append("-o" + directory) + arguments.append(archive_path) +# arguments.append(os.path.splitext(archive_path)[0]) + arguments.extend(paths) + + print "Arguments: %r" % arguments + process = subprocess.Popen(arguments, stdout=subprocess.PIPE) + out, err = process.communicate() + print "Output:"; print out and out.strip() + print "Error:"; print err and err.strip() + +class RenameFile(object): + + python_path = r"C:\Python25\python.exe" + rename_dialog_path = os.path.join(os.path.dirname(__file__), + "dialog_rename.py") + + def __init__(self, spec): + self.spec = spec + + def execute(self, paths, directory): + if len(paths) == 0: + print "Rename file error: nothing selected." + return + path = paths[0] + + arguments = [self.python_path, self.rename_dialog_path, path] + subprocess.Popen(arguments) + + +#--------------------------------------------------------------------------- + +commands = [ + SingleFile("open with ultra [edit]", + [r"C:\Program Files\IDM Computer Solutions\UltraEdit\Uedit32.exe", "%(path)s"]), + MultiFile("scan for (virus | viruses) | virus scan", + [r"C:\Program Files\F-Secure\Anti-Virus\fsav.exe"], ["/list"]), + SingleFile("extract archive here", + [r"C:\Program Files\7-Zip\7z.exe", "x", "-o%(dir)s", "%(path)s"]), + CreateArchiveHere("create zip archive here", ".zip"), + CreateArchiveHere("create [7] archive here", ".7z"), + RenameFile("rename file dialog"), + ] + + +#--------------------------------------------------------------------------- +# Utility generator function for iterating over COM collections. + +def collection_iter(collection): + for index in xrange(collection.Count): + yield collection.Item(index) + + +#--------------------------------------------------------------------------- +# This module's main grammar. + +class ControlGrammar(ConnectionGrammar): + + def __init__(self): + ConnectionGrammar.__init__( + self, + name="Explorer control", + context=AppContext(executable="explorer"), + app_name="Shell.Application" + ) + + def get_active_explorer(self): + handle = Window.get_foreground().handle + for window in collection_iter(self.application.Windows()): + if window.HWND == handle: + return window + self._log.warning("%s: no active explorer." % self) + return None + + def get_selected_paths(self): + window = self.get_active_explorer() + items = window.Document.SelectedItems() + paths = [] + for item in collection_iter(items): + paths.append(item.Path) + print "Selected paths: %r" % paths + return paths + + def get_selected_filenames(self): + paths = self.get_selected_paths() + return [os.path.basename(p) for p in paths] + + def get_current_directory(self): + window = self.get_active_explorer() + path = window.LocationURL[8:] + if path.startswith("file:///"): + path = path[8:] + return unquote(path) + +grammar = ControlGrammar() + + +#--------------------------------------------------------------------------- + +class ListSelectionRule(CompoundRule): + spec = "list current selection" + def _process_recognition(self, node, extras): + print "Current selection:" + for filename in self.grammar.get_selected_filenames(): + print " - %r" % filename + +grammar.add_rule(ListSelectionRule()) + + +#--------------------------------------------------------------------------- + +class CommandRule(CompoundRule): + + spec = "[command] " + extras = [Choice("command", dict((c.spec, c) for c in commands))] + + def _process_recognition(self, node, extras): + command = extras["command"] + paths = self.grammar.get_selected_paths() + directory = self.grammar.get_current_directory() + print "Selected paths: %r" % paths + command.execute(paths, directory) + +grammar.add_rule(CommandRule()) + + +#--------------------------------------------------------------------------- +# Load the grammar instance and define how to unload it. + +grammar.load() + +# Unload function which will be called by natlink at unload time. +def unload(): + global grammar + if grammar: grammar.unload() + grammar = None diff --git a/_firefox.py b/_firefox.py new file mode 100644 index 0000000..4c60d42 --- /dev/null +++ b/_firefox.py @@ -0,0 +1,354 @@ +# +# This file is a command-module for Dragonfly. +# (c) Copyright 2008 by Christo Butcher +# Licensed under the LGPL, see +# + +""" +Command-module for **Firefox** +============================================================================ + +This module offers direct control of the `Firefox +`_ web browser. It +requires the `mouseless-browsing +`_ +(mlb) add-on for reliable access to hyperlinks. + +This module includes direct searching using Firefox's +search bar and Firefox's keyword searching. It also +allows single-utterance submitting of text into form text +fields. + +Installation +---------------------------------------------------------------------------- + +If you are using DNS and Natlink, simply place this file in you Natlink +macros directory. It will then be automatically loaded by Natlink when +you next toggle your microphone or restart Natlink. + +Customization +---------------------------------------------------------------------------- + +Users should customize this module by editing its +configuration file. In this file they should edit the +``search.searchbar`` and ``search.keywords`` settings to +match their own personal search preferences. These +variables map *what you say* to which *search engines* to +use. + +""" + +try: + import pkg_resources + pkg_resources.require("dragonfly >= 0.6.5beta1.dev-r76") +except ImportError: + pass + +from dragonfly import * + + +#--------------------------------------------------------------------------- +# Set up this module's configuration. + +config = Config("Firefox control") +config.search = Section("Search-related section") +config.search.keywords = Item( + default={ + "wikipedia": "wikipedia", + }, + doc="Mapping of spoken-forms to Firefox search-keywords.", + ) +config.search.searchbar = Item( + default=[ + "google", + "yahoo", + "amazon", + "answers", + "creative commons", + "eBay", + "wikipedia", + ], + doc="Spoken-forms of search engines in the Firefox search-bar; they must be given in the same order here as they are available in Firefox.", + ) + +config.lang = Section("Language section") +config.lang.new_win = Item("new (window | win)") +config.lang.new_tab = Item("new (tab | sub)") +config.lang.close_tab = Item("close (tab | sub)") +config.lang.close_tab_n = Item("close (tab | sub) ") +config.lang.close_n_tabs = Item("close (tabs | subs)") +config.lang.address_bar = Item("address [bar]") +config.lang.copy_address = Item("copy address") +config.lang.paste_address = Item("paste address") +config.lang.search_bar = Item("search bar") +config.lang.go_home = Item("go home") +config.lang.stop_loading = Item("stop loading") +config.lang.toggle_tags = Item("toggle tags") +config.lang.fresh_tags = Item("fresh tags") +config.lang.caret_browsing = Item("(caret | carrot) browsing") +config.lang.bookmark_page = Item("bookmark [this] page") +config.lang.save_page_as = Item("save [page | file] as") +config.lang.print_page = Item("print [page | file]") +config.lang.show_tab_n = Item("show tab ") +config.lang.back = Item("back []") +config.lang.forward = Item("forward []") +config.lang.next_tab = Item("next tab []") +config.lang.prev_tab = Item("(previous | preev) tab []") +config.lang.normal_size = Item("normal text size") +config.lang.smaller_size = Item("smaller text size []") +config.lang.bigger_size = Item("bigger text size []") +config.lang.find = Item("find") +config.lang.find_text = Item("find ") +config.lang.find_next = Item("find next []") + +config.lang.submit = Item("submit") +config.lang.submit_text = Item("submit ") +config.lang.submit_clipboard = Item("submit (clipboard | clip board)") +config.lang.link_open = Item("[link] [open]") +config.lang.link_save = Item("save [link] [as]") +config.lang.link_save_now = Item("save [link] now now") +config.lang.link_select = Item("[link] select") +config.lang.link_menu = Item("[link] (menu | pop up)") +config.lang.link_force = Item("[link] force") +config.lang.link_window = Item("[link] [in [new]] window") +config.lang.link_tab = Item("[link] [in [new]] tab") +config.lang.link_copy = Item("[link] copy") +config.lang.link_copy_into_tab = Item("[link] copy into tab") +config.lang.link_list = Item("[link] list") +config.lang.link_submit = Item("[link] submit") +config.lang.link_submit_text = Item("[link] submit ") +config.lang.link_submit_clipboard = Item("[link] submit (clipboard | clip board)") +config.lang.link_dictation_box = Item("edit [link] ") +config.lang.link_assign_keyword = Item("assign [a] keyword to [link] ") +config.lang.tabify_links = Item("tab if I ") +config.lang.tabify_links_sep = Item("comma") + +config.lang.search_text = Item("[power] search [for] ") +config.lang.search_keyword_text = Item("[power] search [for] ") +config.lang.search_searchbar_text = Item("[power] search [for] ") +config.lang.search_clipboard = Item("[power] search [for] (clipboard | clip board)") +config.lang.search_keyword_clipboard = Item("[power] search [for] clipboard") +config.lang.search_searchbar_clipboard = Item("[power] search [for] clipboard") + +#config.generate_config_file() +config.load() + + +#--------------------------------------------------------------------------- +# Check and prepare search-related config values. + +keywords = config.search.keywords +searchbar = dict([(n,i) for i,n in enumerate(config.search.searchbar)]) + + +#--------------------------------------------------------------------------- +# Create the rule to match mouseless-browsing link numbers. + +class LinkRule(Rule): + + def __init__(self): + element = Number(zero=True) + Rule.__init__(self, "link_rule", element, exported=False) + + def value(self, node): + # Format and return keystrokes to select the link. + digits = str(node.children[0].value()) + link_keys = "f6,s-f6," + ",".join(["numpad"+i for i in digits]) + self._log.debug("Link keys: %r" % link_keys) + return link_keys + +link = RuleRef(name="link", rule=LinkRule()) + + +#--------------------------------------------------------------------------- +# Create the main command rule. + +class CommandRule(MappingRule): + + mapping = { + config.lang.new_win: Key("c-n"), + config.lang.new_tab: Key("c-t"), + config.lang.close_tab: Key("c-w"), + config.lang.close_tab_n: Key("0, %(n)d, enter/20, c-w"), + config.lang.close_n_tabs: Key("c-w/20:%(n)d"), + config.lang.address_bar: Key("a-d"), + config.lang.copy_address: Key("a-d, c-c"), + config.lang.paste_address: Key("a-d, c-v, enter"), + config.lang.search_bar: Key("c-k"), + config.lang.go_home: Key("a-home"), + config.lang.stop_loading: Key("escape"), + config.lang.toggle_tags: Key("f12"), + config.lang.fresh_tags: Key("f12, f12"), + config.lang.caret_browsing: Key("f7"), + config.lang.bookmark_page: Key("c-d"), + config.lang.save_page_as: Key("c-s"), + config.lang.print_page: Key("c-p"), + + config.lang.show_tab_n: Key("0, %(n)d, enter"), + config.lang.back: Key("a-left/15:%(n)d"), + config.lang.forward: Key("a-right/15:%(n)d"), + config.lang.next_tab: Key("c-tab:%(n)d"), + config.lang.prev_tab: Key("cs-tab:%(n)d"), + + config.lang.normal_size: Key("a-v/20, z/20, r"), + config.lang.smaller_size: Key("c-minus:%(n)d"), + config.lang.bigger_size: Key("cs-equals:%(n)d"), + + config.lang.submit: Key("enter"), + config.lang.submit_text: Text("%(text)s") + Key("enter"), + config.lang.submit_clipboard: Key("c-v, enter"), + + config.lang.find: Key("c-f"), + config.lang.find_text: Key("c-f") + Text("%(text)s"), + config.lang.find_next: Key("f3/10:%(n)d"), + + config.lang.link_open: Key("%(link)s, enter"), + config.lang.link_save: Key("%(link)s, shift/10, apps/20, k"), + config.lang.link_save_now: Key("%(link)s, shift/10, apps/20, k") + + WaitWindow(title="Enter name of file") + + Pause("20") + Key("enter"), + config.lang.link_select: Key("%(link)s, shift"), + config.lang.link_menu: Key("%(link)s, shift/10, apps"), + config.lang.link_force: Key("%(link)s, shift/10, enter"), + config.lang.link_window: Key("%(link)s, shift/10, apps/20, w"), + config.lang.link_tab: Key("%(link)s, shift/10, apps/20, t"), + config.lang.link_copy: Key("%(link)s, shift/10, apps/20, a"), + config.lang.link_copy_into_tab: Key("%(link)s, shift/10, apps/20, a/10, c-t/20, c-v, enter"), + config.lang.link_list: Key("%(link)s, enter, a-down"), + config.lang.link_submit: Key("%(link)s, enter/30, enter"), + config.lang.link_submit_text: Key("%(link)s, enter/30") + + Text("%(text)s") + Key("enter"), + config.lang.link_submit_clipboard: Key("%(link)s, enter/30, c-v, enter"), + config.lang.link_dictation_box: Key("%(link)s, enter/30, cs-d"), + config.lang.link_assign_keyword: Key("%(link)s, enter/10, apps/20, k"), + + config.lang.search_text: Key("c-k") + + Text("%(text)s") + Key("enter"), + config.lang.search_searchbar_text: Key("c-k, c-up:20, c-down:%(searchbar)d") + + Text("%(text)s") + Key("enter"), + config.lang.search_keyword_text: Key("a-d") + + Text("%(keyword)s %(text)s") + + Key("enter"), + config.lang.search_clipboard: Key("c-k, c-v, enter"), + config.lang.search_searchbar_clipboard: Key("c-k, c-up:20, c-down:%(searchbar)d, c-v, enter"), + config.lang.search_keyword_clipboard: Key("a-d") + Text("%(keyword)s") + + Key("c-v, enter"), + } + extras = [ + link, + IntegerRef("n", 1, 20), + Dictation("text"), + Choice("keyword", keywords), + Choice("searchbar", searchbar), + ] + defaults = { + "n": 1, + } + + +#--------------------------------------------------------------------------- +# Create the command rule for sliding. + +slide_directions = { + "up": (0,-1), + "down": (0,+1), + } +slide_speeds = { + "1": 10, + "2": 20, + "3": 30, + "4": 40, + } +slide_default_speed = 15 +slide_start_spec = "(-15,0.6)" + +slide_grammar = None + +def start_sliding(direction, speed): + offset_x = direction[0] * speed + offset_y = direction[1] * speed + offset_spec = "<%d,%d>" % (offset_x, offset_y) + action = Key("escape") + action.execute() + action = Mouse("%s/25, middle/25, %s" % (slide_start_spec, offset_spec)) + action.execute() + + global slide_grammar + if not slide_grammar: + slide_grammar = Grammar("Firefox slide grammar") + slide_grammar.add_rule(SlideControlRule()) + slide_grammar.load() + slide_grammar.set_exclusive(True) + +def stop_sliding(): + action = Key("escape") + action.execute() + + global slide_grammar + if slide_grammar: + slide_grammar.set_exclusive(False) + slide_grammar.unload() + slide_grammar = None + +class SlideStartRule(MappingRule): + + mapping = { + "slide []": Function(start_sliding), + } + extras = [ + Choice("direction", slide_directions), + Choice("speed", slide_speeds), + ] + defaults = { + "speed": slide_default_speed, + } + + +class SlideControlRule(MappingRule): + + mapping = { + "[slide] []": Function(start_sliding), + "[slide] stop": Function(stop_sliding), + } + extras = [ + Choice("direction", slide_directions), + Choice("speed", slide_speeds), + ] + defaults = { + "speed": slide_default_speed, + } + + +#--------------------------------------------------------------------------- +# Create the main command rule. + +class TabifyRule(CompoundRule): + + spec = config.lang.tabify_links + sep_element = Compound(config.lang.tabify_links_sep) + repeat_element = Sequence([sep_element, link]) + repetitions = Repetition(child=repeat_element, min=0, max=8) + extras = [Sequence(name="links", children=(link, repetitions))] + + def _process_recognition(self, node, extras): + link_nodes = node.get_children_by_name("link") + for n in link_nodes: + action = Key(n.value()) + Key("shift/10, apps/20, t/20") + action.execute() + + +#--------------------------------------------------------------------------- +# Create and load this module's grammar. + +context = AppContext(executable="firefox") +grammar = Grammar("firefox_general", context=context) +grammar.add_rule(CommandRule()) +grammar.add_rule(SlideStartRule()) +grammar.add_rule(TabifyRule()) +grammar.load() + +# Unload function which will be called by natlink at unload time. +def unload(): + global grammar + if grammar: grammar.unload() + grammar = None diff --git a/_html_grammar.py b/_html_grammar.py index 080c12c..8a4a7cd 100644 --- a/_html_grammar.py +++ b/_html_grammar.py @@ -1,4 +1,5 @@ -# Author:Brandon Lovrien +# Author: Jeremy Hayes +# Modified from: Brandon Lovrien version # This script includes commands used for HTML coding from dragonfly import (Grammar, CompoundRule, Dictation, Text, Key, AppContext, MappingRule, Choice) @@ -57,7 +58,9 @@ class HTMLTags(MappingRule): "title": "title", "SRC": "src", "HREF": "href", - "type": "type" + "type": "type", + "value": "value", + } ), Choice("tagname", { @@ -101,7 +104,7 @@ class HTMLTags(MappingRule): "H1": "h1", "H2": "h2", "H3": "h3", - "H4": "h4", + "(header 4 |H4)": "h4", "H5": "h5", "H6": "h6", "head": "head", diff --git a/_javascript_grammar.py b/_javascript_grammar.py index af2d665..aef32a7 100644 --- a/_javascript_grammar.py +++ b/_javascript_grammar.py @@ -40,7 +40,12 @@ class JavaScriptControlStructures(MappingRule): mapping = { "variable": Text("var "), - "console": Text("console.log();"), + "true": Text("true"), + "false": Text("false"), + "model": Text("model."), + "console": Text("console.log();") + Key("left") + Key("left"), + "parse Float": Text("parseFloat();") + Key("left") + Key("left"), + "parse INT": Text("parseInt();") + Key("left") + Key("left"), "function": Text("function functionName() {") + Key("enter")+ Key("enter"), #+ Text("}"), "variable function": Text("functionName = function () {") + Key("enter")+ Key("enter"), #+ Text("}"), "self function": Text("(function() {") + Key("enter")+ Key("enter"), #+ Text("}())"), @@ -101,6 +106,7 @@ class JavaScriptAssignmentOperators(MappingRule): "multiply equals": Text("*="), "divide equals": Text("/="), "modulus equals": Text("%="), + "modulus": Text("%"), }