Exemplo n.º 1
0
def erase_multi_clipboard():
    global _CLIP
    _CLIP = {}
    utilities.save_json_file(
        _CLIP, settings.settings([u'paths', u'SAVED_CLIPBOARD_PATH']))
Exemplo n.º 2
0
from dragonfly import (IntegerRef, Integer)
from dragonfly.grammar.elements import RuleWrap, Choice
from dragonfly.language.base.integer_internal import MapIntBuilder
from dragonfly.language.loader import language

from castervoice.lib import settings
from castervoice.rules.core.alphabet_rules import alphabet_support
'''
Integer Remap feature needs to be rewritten:
    - allow customization
    - make it language sensitive (can this be done without eval?)
'''
if not settings.settings(["miscellaneous", "integer_remap_crash_fix"]):

    class IntegerRefST(RuleWrap):
        def __init__(self, name, min, max, default=None):
            if not settings.settings(
                ["miscellaneous", "short_integer_opt_out"]):
                content = language.ShortIntegerContent
            else:
                content = language.IntegerContent

            if "en" in language.language_map and settings.settings(
                ["miscellaneous", "integer_remap_opt_in"]):
                content.builders[1] = MapIntBuilder(
                    alphabet_support.numbers_map_1_to_9())

            element = Integer(None, min, max, content=content)
            RuleWrap.__init__(self, name, element, default=default)

else:
Exemplo n.º 3
0
def initialize_clipboard():
    global _CLIP
    if len(_CLIP) == 0:
        _CLIP = utilities.load_json_file(
            settings.settings(["paths", "SAVED_CLIPBOARD_PATH"]))
Exemplo n.º 4
0
class BringRule(BaseSelfModifyingRule):
    """
    BringRule adds entries to a 2-layered map which can be described as
    {type: {extra: target}}
    type: used for internal organization; types include website, file, folder, etc.
    extra: the word or words used to label the target
    target: a url or file/folder location
    """

    pronunciation = "bring me"

    # Contexts
    _browser_context = AppContext(["chrome", "firefox"])
    _explorer_context = AppContext("explorer.exe") | contexts.DIALOGUE_CONTEXT
    _terminal_context = contexts.TERMINAL_CONTEXT
    # Paths
    _terminal_path = settings.settings(["paths", "TERMINAL_PATH"])
    _explorer_path = str(Path("C:\\Windows\\explorer.exe"))
    _user_dir = settings.SETTINGS["paths"]["USER_DIR"]
    _home_dir = str(Path.home())

    def __init__(self):
        super(BringRule, self).__init__(settings.settings(["paths", "SM_BRINGME_PATH"]))

    def _initialize(self):
        """
        Sets up defaults for first time only.
        """
        if len(self._config.get_copy()) == 0:
            self._bring_reset_defaults()

    def _deserialize(self):
        """
        This _deserialize creates mapping which uses the user-made extras.
        """

        self._initialize()

        self._smr_mapping = {
            "bring me <program>": R(Function(self._bring_program)),
            "bring me <website>": R(Function(self._bring_website)),
            "bring me <folder> [in <app>]": R(Function(self._bring_folder)),
            "bring me <file>": R(Function(self._bring_file)),
            "refresh bring me": R(Function(self._load_and_refresh)),
            "<launch_type> to bring me as <key>": R(Function(self._bring_add)),
            "to bring me as <key>": R(Function(self._bring_add_auto)),
            "remove <key> from bring me": R(Function(self._bring_remove)),
            "restore bring me defaults": R(Function(self._bring_reset_defaults)),
        }
        self._smr_extras = [
            Choice(
                "launch_type", {
                    "[current] program": "program",
                    "website": "website",
                    "folder": "folder",
                    "file": "file",
                }),
            Choice("app", {
                "terminal": "terminal",
                "explorer": "explorer",
            }),
            Dictation("key"),
        ]
        self._smr_extras.extend(self._rebuild_items())
        self._smr_defaults = {"app": None}

    def _rebuild_items(self):
        # E.g. [Choice("folder", {"my pictures": ...}), ...]
        config_copy = self._config.get_copy()
        return [
            Choice(header,
                   {key: os.path.expandvars(value)
                    for key, value in section.iteritems()})
            for header, section in config_copy.iteritems()
        ]

    def _refresh(self, *args):
        """
        :param args: in this case, args is the pre-altered copy of the state map to replace the current map with
        """
        self._config.replace(args[0])
        self.reset()

    def _load_and_refresh(self):
        """

        """
        self.reset()

    def _bring_add(self, launch_type, key):
        # Add current program or highlighted text to bring me
        if launch_type == "program":
            path = utilities.get_active_window_path()
            if not path:
                # dragonfly.get_engine().speak("program not detected")
                printer.out("Program path for bring me not found ")
        elif launch_type == 'file':
            files = utilities.get_selected_files(folders=False)
            path = files[0] if files else None # or allow adding multiple files
        elif launch_type == 'folder':
            files = utilities.get_selected_files(folders=True)
            path = files[0] if files else None # or allow adding multiple folders
        else:
            Key("a-d/5").execute()
            fail, path = context.read_selected_without_altering_clipboard()
            if fail == 2:
                # FIXME: A better solution would be to specify a number of retries and the time interval.
                time.sleep(0.1)
                _, path = context.read_selected_without_altering_clipboard()
                if not path:
                    printer.out("Selection for bring me not found ")
            Key("escape").execute()
        if not path:
            # logger.warn('Cannot add %s as %s to bringme: cannot get path', launch, key)
            return

        config_copy = self._config.get_copy()
        config_copy[launch_type][str(key)] = path
        self._refresh(config_copy)

    def _bring_remove(self, key):
        # Remove item from bring me
        config_copy = self._config.get_copy()
        deleted = False
        for section in config_copy.keys():
            if key in config_copy[section]:
                del config_copy[section][str(key)]
                deleted = True
                break
        if deleted:
            self._refresh(config_copy)

    def _bring_reset_defaults(self):
        """
        Restore bring me list to defaults
        """
        self._refresh(BringRule._bm_defaults)

    def _bring_add_auto(self, key):
        """
        Adds an entry for a program, a website, or a folder (without specifying),
        depending on which context get detected (if either).
        """
        def add(launch_type):
            return Function(lambda: self._bring_add(launch_type, key))

        ContextAction(add("program"), [
            (BringRule._browser_context, add("website")),
            (BringRule._explorer_context, add("folder")),
        ]).execute()

    # =================== BringMe actions --> these do not change state

    def _bring_website(self, website):
        browser = utilities.default_browser_command()
        Popen(shlex.split(browser.replace('%1', website)))

    def _bring_folder(self, folder, app):
        if not app:
            ContextAction(Function(lambda: Popen([BringRule._explorer_path, folder])), [
                (BringRule._terminal_context, Text("cd \"%s\"\n" % folder)),
                (BringRule._explorer_context, Key("c-l/5") + Text("%s\n" % folder))
            ]).execute()
        elif app == "terminal":
            Popen([BringRule._terminal_path, "--cd=" + folder.replace("\\", "/")])
        elif app == "explorer":
            Popen([BringRule._explorer_path, folder])

    def _bring_program(self, program):
        Popen(program)

    def _bring_file(self, file):
        threading.Thread(target=os.startfile, args=(file, )).start()

    # =================== BringMe default setup:
    _bm_defaults = {
        "website": {
            # Documentation
            "caster documentation": "https://caster.readthedocs.io/en/latest/",
            "dragonfly documentation": "https://dragonfly2.readthedocs.io/en/latest/",

            # Caster Support
            "dragonfly gitter": "https://gitter.im/dictation-toolbox/dragonfly",
            "caster gitter": "https://gitter.im/dictation-toolbox/Caster",
            "caster discord": "https://discord.gg/9eAAsCJr",

            # General URLs
            "google": "https://www.google.com",
        },
        "folder": {
            # OS folder Navigation
            "libraries | home": _home_dir,
            "my pictures": str(Path(_home_dir).joinpath("Pictures")),
            "my documents": str(Path(_home_dir).joinpath("Documents")),

            # Caster User Dir Navigation
            "caster user": str(Path(_user_dir)),
            "caster hooks": str(Path(_user_dir).joinpath("hooks")),
            "caster transformers": str(Path(_user_dir).joinpath("transformers")),
            "caster rules": str(Path(_user_dir).joinpath("rules")),
            "caster data": str(Path(_user_dir).joinpath("data")),
            "caster settings": str(Path(_user_dir).joinpath("settings")),
            "sick you lee": str(Path(_user_dir).joinpath("sikuli")),
        },
        "program": {
            "notepad": str(Path("C:\\Windows\\notepad.exe")),
        },
        "file": {
            # User Settings
            "caster settings file": str(Path(_user_dir).joinpath("settings/settings.toml")),
            "caster rules file": str(Path(_user_dir).joinpath("settings/rules.toml")),
            "caster bring me file": str(Path(_user_dir).joinpath("settings/sm_bringme.toml")),
            "caster hooks file": str(Path(_user_dir).joinpath("settings/hooks.toml")),
            "caster companion file": str(Path(_user_dir).joinpath("settings/companion_config.toml")),
            "caster transformers file": str(Path(_user_dir).joinpath("settings/transformers.toml")),

            # Caster Data
            "caster alias file": str(Path(_user_dir).joinpath("data/sm_aliases.toml")),
            "caster chain aliases file": str(Path(_user_dir).joinpath("data/sm_chain_aliases.toml")),
            "caster clipboard file": str(Path(_user_dir).joinpath("data/clipboard.json")),
            "caster record from history file": str(Path(_user_dir).joinpath("data/sm_history.toml")),
            "caster log file": str(Path(_user_dir).joinpath("data/log.txt")),

            # Simplified Transformer 
            "caster transformer file": str(Path(_user_dir).joinpath("transformers/words.txt")),
        }
    }
Exemplo n.º 5
0
 def __init__(self):
     super(BringRule, self).__init__(settings.settings(["paths", "SM_BRINGME_PATH"]))
Exemplo n.º 6
0
 def __init__(self):
     super(HistoryRule,
           self).__init__(settings.settings(["paths", "SM_HISTORY_PATH"]))
     self._history = recognition_history.get_and_register_history(20)
     self._preserved = None
Exemplo n.º 7
0
from castervoice.lib import settings


class Text(TextBase):
    # dragonfly default is 0.02, too slow!
    _pause_default = 0.003

    def __init__(self,
                 spec=None,
                 static=False,
                 pause=_pause_default,
                 autofmt=False,
                 use_hardware=False):
        TextBase.__init__(self,
                          spec=spec,
                          static=static,
                          pause=pause,
                          autofmt=autofmt,
                          use_hardware=use_hardware)


# Override imported dragonfly actions with aenea's if the 'use_aenea' setting
# is set to true.
if settings.settings(["miscellaneous", "use_aenea"]):
    try:
        from aenea import Key, Text, Mouse
    except ImportError:
        print("Unable to import aenea actions. Dragonfly actions will be used "
              "instead.")
Exemplo n.º 8
0
 def __init__(self):
     super(CompanionConfig, self).__init__(
         settings.settings(["paths", "COMPANION_CONFIG_PATH"]))
     self.load()
     self._initialize()
Exemplo n.º 9
0
    def _create_merger(smrc, transformers_runner):
        compat_checker = SimpleCompatibilityChecker()
        merge_strategy = ClassicMergingStrategy()
        max_repetitions = settings.settings(["miscellaneous", "max_ccr_repetitions"])

        return CCRMerger2(transformers_runner, compat_checker, merge_strategy, max_repetitions, smrc)
Exemplo n.º 10
0
Command-module for Atom
Official Site "https://atom.io/"
"""

# How long to wait for the Atom palette to load before hitting the enter key
from dragonfly import Pause, Function, Repeat, Dictation, Choice, MappingRule

from castervoice.lib.actions import Text, Key

from castervoice.lib import settings, navigation
from castervoice.lib.ctrl.mgr.rule_details import RuleDetails
from castervoice.lib.merge.additions import IntegerRefST
from castervoice.lib.merge.state.short import R

atom_palette_wait = 30
if settings.settings(["miscellaneous", "atom_palette_wait"]):
    atom_palette_wait = int(settings.SETTINGS["miscellaneous"]["atom_palette_wait"])


def ACP(command):
    """Utilize the Palette UI to execute commands."""
    return R(Key("cs-p") + Pause(str(atom_palette_wait)) + Text(command) + Key("enter"))

class AtomRule(MappingRule):
    """
    Commands for the Atom editor.

    `R(Key("command keys"))`
        Registers a key and label combination for use in a voice commands.
    `ACP("command name")`
        Registers an Atom Palette Command and label combination for use in voice commands.
Exemplo n.º 11
0
 def __init__(self, **kwargs):
     super(Alias,
           self).__init__(settings.settings(["paths", "SM_ALIAS_PATH"]),
                          **kwargs)
Exemplo n.º 12
0
class Text(TextBase):
    # dragonfly _pause_default 0.02 is too slow! Caster default 0.003
    _pause_default = settings.settings(["miscellaneous", "dragonfly_pause_default"])
    def __init__(self, spec=None, static=False, pause=_pause_default, autofmt=False, use_hardware=False):
        TextBase.__init__(self, spec=spec, static=static, pause=pause, autofmt=autofmt, use_hardware=use_hardware)
Exemplo n.º 13
0
        self.capitalization, self.spacing = self.normalize_text_format(
            capitalization, spacing)

    def clear_text_format(self):
        self.capitalization = self.default_cap
        self.spacing = self.default_spacing

    def __str__(self):
        return self.get_text_format_description(self.capitalization,
                                                self.spacing)

    def get_formatted_text(self, t):
        return TextFormat.formatted_text(self.capitalization, self.spacing, t)


format = TextFormat(*settings.settings(["formats", "_default", "text_format"],
                                       default_value=[5, 0]))
secondary_format = TextFormat(*settings.settings(
    ["formats", "_default", "secondary_format"], default_value=[1, 0]))


def _choose_format(big):
    return format if not big else secondary_format


# module interface
def set_text_format(big, capitalization, spacing):
    _choose_format(big).set_text_format(capitalization, spacing)


def clear_text_format(big):
    _choose_format(big).clear_text_format()
Exemplo n.º 14
0
 def __init__(self):
     from castervoice.lib import settings
     super(CompanionConfig, self).__init__(
         settings.settings(["paths", "COMPANION_CONFIG_PATH"]))
     self.load()
     self._initialize()
Exemplo n.º 15
0

def _is_aenea_available():
    try:
        import aenea
        return True
    except ImportError:
        print("Unable to import aenea, dragonfly.Clipboard will be used "
              "instead.")
        return False


# Use a subclass of dragonfly's clipboard class instead if the 'use_aenea'
# setting is set to true. This will allow commands like 'stoosh' to work
# properly server-side if the RPC functions are available.
if settings.settings(["miscellaneous", "use_aenea"]) and _is_aenea_available():
    # pylint: disable=import-error
    import aenea
    from jsonrpclib import ProtocolError

    class Clipboard(DragonflyClipboard):  # pylint: disable=function-redefined
        @classmethod
        def get_system_text(cls):
            # Get the server's clipboard content if possible and update this
            # system's clipboard.
            try:
                server_text = aenea.communications.server.paste()
                DragonflyClipboard.set_system_text(server_text)
                return server_text
            except ProtocolError as e:
                print("ProtocolError caught when calling server.paste(): %s" %
Exemplo n.º 16
0
from castervoice.lib import control, settings, printer


def kill():
    control.nexus().comm.get_com("hmc").kill()


if not settings.settings(["miscellaneous", "hmc"]):
    printer.out(
        "WARNING: Tk Window controls have been disabled -- this is not advised!"
    )