Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 24 08:57
    codebold commented #358
  • Jan 24 08:41
    codebold commented #358
  • Jan 24 08:34
    m-spisiak commented #358
  • Jan 24 08:28
    m-spisiak commented #358
  • Jan 23 12:37
    codebold commented #358
  • Jan 23 11:52
    codebold commented #358
  • Jan 23 02:32
    Danesprite commented #358
  • Jan 23 02:31
    Danesprite commented #358
  • Jan 22 16:36
    codebold commented #358
  • Jan 22 12:36
    Danesprite commented #358
  • Jan 21 15:28
    kendonB commented #358
  • Jan 21 11:12
    m-spisiak commented #358
  • Jan 21 11:00
    m-spisiak commented #358
  • Jan 20 06:25
    Danesprite labeled #358
  • Jan 20 06:24
    Danesprite commented #358
  • Jan 19 20:10
    kendonB commented #358
  • Dec 16 2021 07:24
    Danesprite commented #326
  • Dec 16 2021 07:14
    Danesprite commented #326
  • Dec 09 2021 06:29

    Danesprite on 0.34.0

    (compare)

  • Dec 09 2021 06:29
    Danesprite closed #361
LexiconCode
@LexiconCode

Hi All, Im very new to dragonfly, trying to get the BringApp action to work but it fails to open the directory when I pass it BringApp("explorer", r"C:\DT\natlink\src\natlinkpy\MacroSystem"). I read it passes to subprocess.Popen so I tried to replicate it in cmd and use subprocess.Popen(["explorer", r"C:\DT\natlink\src\natlinkpy\MacroSystem"]) directly and that DID work. Anyone know what I might be doing wrong with BringApp? I tried passing my args in a list and Ive succesfully used other rules in the grammerfile, but so far no luck with BringApp..

Is it part of a function or is it tied directly to command?

If it's part of the function then it needs .execute() BringApp("explorer", r"C:\DT\natlink\src\natlinkpy\MacroSystem").execute() at the end of the action

LexiconCode
@LexiconCode

For debugging I recommend Running Test Engine from Dragonfly CLI which can run alongside DNS/Speech recognition engine. Which allows you to type commands as if the engine heard them with 100% accuracy. You can debug individual files _dragonfly_example_rule.py Or anything with an _ via_*.py.

python -m dragonfly test _dragonfly_example_rule.py -l DEBUG --delay 3

Type commands to emulate as if they are being dictated by voice.
lowercase mimics commands, UPPERCASE mimics free dictation
Upper and lowercase words can be mixed e.g say THIS IS A TEST

Edit the --delay 3 to change command delay in seconds.
The delay allows user to switch to the relevant application to test commands

LexiconCode
@LexiconCode
@samVanDerStoop However there must be an issue. Double checking I can utilize BringApp to launch other applications such as Notepad. However "explorer" does not seem to work for me either. For now StartApp("explorer", r"C:\Windows").execute() works as expected. I could've swore BringApp was capable opening up file paths from explore.
An alternative way to test executing a python file with some dragonfly debugging.
https://dragonfly2.readthedocs.io/en/latest/_modules/dragonfly/log.html#setup_log
import logging

logging.basicConfig()
logging.getLogger('action').setLevel(logging.DEBUG)

from dragonfly import BringApp, StartApp
BringApp("explorer", r"C:\Windows").execute()
samVanDerStoop
@samVanDerStoop
@LexiconCode Ill look into those methods of debugging. The fact it didn't work for you either makes me think it's not a problem in my code. I thought it hardly could be as Im literally using a modified sample file (I believe you gave it to :) thx) where I commented out all but that one rule. For now Ill use StartApp instead for this specific case
@LexiconCode it wasnt part of a function btw, just a rule in a mapping
LexiconCode
@LexiconCode

The fact it didn't work for you either makes me think it's not a problem in my code.

Yeah I'm pretty sure it's not related to your code.

samVanDerStoop
@samVanDerStoop

Odd question regarding the Key action, does this:
Key("shift:down") + Key("w:down"),

equal:
Key("s-w:down"),

Or is this not proper use of the modifier?

3 replies
LexiconCode
@lexicon-code:matrix.org
[m]
Is there a call back in dragonfly when it shuts down that I can execute a function?
Ryan Hileman
@lunixbochs
can you just use python's atexit.register?
LexiconCode
@lexicon-code:matrix.org
[m]

can you just use python's atexit.register?

That thought I hadn't considered. Thanks

Doug Ransom
@dougransom
for anyone interestd in debugging their stuff, you can use ouptutdebugstring from https://pypi.org/project/pydebugstring/. you only see the debug ouptut when you run debugview from microsoft.
David Zurow
@daanzu
@dougransom Neat, thanks!
Dane Finlay
@Danesprite

@samVanDerStoop @LexiconCode Regarding BringApp and explorer.exe, this problem is occurring because BringApp is internally matching any explorer.exe window and concluding that the specified application is already open.

This problem can be solved by specifying additional BringApp keyword arguments or with a subclass of BringApp. I have uploaded a BringFileman subclass for this as a GitHub "gist": https://gist.github.com/Danesprite/96f5a27eadaf61ced95e5de55950f31c

LexiconCode
@LexiconCode

@samVanDerStoop @LexiconCode Regarding BringApp and explorer.exe, this problem is occurring because BringApp is internally matching any explorer.exe window and concluding that the specified application is already open.

This problem can be solved by specifying additional BringApp keyword arguments or with a subclass of BringApp. I have uploaded a BringFileman subclass for this as a GitHub "gist": https://gist.github.com/Danesprite/96f5a27eadaf61ced95e5de55950f31c

Thanks Dane

Is there an easy way to get dragons interpretation of the If an utterance is dictation or a command?
LexiconCode
@LexiconCode
("some", 1000000), ("dictation ", 1000000) or ('some', 0), ('command', 0) Currently I can get it through DEBUG:engine:Grammar
Ideally you be nice to get during some sort of callback like on_recognition
LexiconCode
@LexiconCode
I think I figured it out.
[('say', 2), ('hello', 1000000)]
hello how are you # Free dictation
[('hello', 0), ('how', 0), ('are', 0), ('you', 0)]
say hello # Command
[('say', 2), ('hello', 1000000)]
def on_recognition(self, words, results):
        print("{}".format(" ".join(words)))
        print("{}".format(results.getResults(0)))
samVanDerStoop
@samVanDerStoop

@samVanDerStoop @LexiconCode Regarding BringApp and explorer.exe, this problem is occurring because BringApp is internally matching any explorer.exe window and concluding that the specified application is already open.

This problem can be solved by specifying additional BringApp keyword arguments or with a subclass of BringApp. I have uploaded a BringFileman subclass for this as a GitHub "gist": https://gist.github.com/Danesprite/96f5a27eadaf61ced95e5de55950f31c

Thank you much. For my own understanding could you explain how I might specify additional BringApp kwargs correctly for the natlink\MacroSystem example? It would help me understand what your subclass is correcting before passing to BringApp

2 replies
samVanDerStoop
@samVanDerStoop

Reading about dragonfly I found multiple references to the multi edit grammar at https://github.com/t4ngo/dragonfly-modules/tree/master/command-modules
I tried to get it to work myself (as a way of practicing with sequences of commands and config files) but had little luck.
As is, I only get this message

An exception occurred loading 'natlinkmain' module
Error message:
'_multiedit'

When I altered some odd indenting in the file and tried again, I got

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python38-32\lib\site-packages\dragonfly\engines\base\timer.py", line 159, in main_callback
    now = time.time()
SystemError: <built-in function time> returned a result with an error set

If there is a problem with a built-in function might this be a python2/python3 issue (I installed natlink succesfully using the experimental python3 version)? I know the grammar is quite old. Any ideas for a quick fix, or maybe better examples of grammars using configs and sequences of commands/continous command recognition that I can base my own rules on?

LexiconCode
@LexiconCode
@samVanDerStoop Testing just with _multiedit everything seems to work fine. If you haven't already update to the latest Natlink natlink 5.1.1 for Python 3. Instructions dictation-toolbox/Caster#911 works for anybody not just Caster users.
9 replies
samVanDerStoop
@samVanDerStoop
@LexiconCode Thats cool! Please forgive a few noobie questions: Does the new Natlink change anything for dragonfly, does it need to be updated too? Once Ive unregistered natlink, uninstalling just means deleting the cloned repository, right? I havent used/set a userdirectory yet,(I only put dragonfly scripts in \MacroSystem directly so far), so I dont think there are any other settings I need to revert..
LexiconCode
@LexiconCode
@samVanDerStoop No worries, I'm glad help. Nope the new version of nalink does not impact dragonfly. None of Nalinks Interfaces have changed just updated a Python 3 and packaged on a much easier way to install. Yes after un-registering and deleting the cloned repository (with DNS closed) you should be good upgrade. This new version is somewhat experimental so if you experience any issues let us know on the natlink repository/chat.
samVanDerStoop
@samVanDerStoop
@LexiconCode Thanks a lot! Seeing as it is still so new, do you think I might better wait a bit in case changes have to be made (I dont know how easy it would be to update)?
LexiconCode
@LexiconCode
@samVanDerStoop I've already updated once with the with the new version. It was a simple pip install natlink --upgrade and using thenatlinkconfig_cli as needed. Since the user directory was set I didn't have to reset it. It is a heck of a lot easier then utilizing the old way. So it's up to you.
LexiconCode
@lexicon-code:matrix.org
[m]
Is it possible @Danesprite to get DPI is formatted output in recognition Observer? Like if I dictate five thousand the observer returns 5000 or whatever DNS is final output would be?
Dane Finlay
@Danesprite

@LexiconCode Formatting is done after observer events. To do it yourself, pass the unformatted words list to Dragonfly's DNS dictation word formatter classes:

from dragonfly.engines.backend_natlink.dictation_format import WordFormatter

words = "\\all-caps\\All-Caps hello world".split()
formatter = WordFormatter()
formatted_output = formatter.format_dictation(words)
print(formatted_output)

There are more examples in the doctests: https://dragonfly2.readthedocs.io/en/latest/test_word_formatting_v11_doctest.html

This is not done for integers. IIRC DNS does not provide this information to client applications. You need to pass the words through Dragonfly's integer content classes for that.

LexiconCode
@LexiconCode
Thank you!
Dane Finlay
@Danesprite
No worries!
Dane Finlay
@Danesprite
I should mention that you can use the DNS dictation formatting classes to save state information between utterances. Dragonfly doesn't do that because it would lead to some commands having inconsistent effects.
Alex Boche
@alexboche
i made an issue about that formatting stuff a while back #110 Not sure if anything there is relevant to what you're talking about. I think there was also a caster issue. Last I checked the talon community seemed to be pretty die hard into just using various "say [dictation]" type commands for everying instead of fancing transitioning or using separate modes. They may be right, especially with super low latency where pausing isn't so bad.
LexiconCode
@lexicon-code:matrix.org
[m]
natlink 5.1.2 has been released in which you can give an environment variable DICTATIONTOOLBOXUSER pointing to a directory in which the folder .natlink can be located. Simply re-register natlink after setting up the variable
Doug Ransom
@dougransom
@lexicon-code:matrix.org can you note that in the readme.md? otherwise it will be a big secret.
LexiconCode
@LexiconCode
@dougransom Sure in Natlink docs?
Quintijn Hoogenboom
@quintijn
I will work on the readthedocs, yes!
LexiconCode
@LexiconCode

@LexiconCode Formatting is done after observer events. To do it yourself, pass the unformatted words list to Dragonfly's DNS dictation word formatter classes:

from dragonfly.engines.backend_natlink.dictation_format import WordFormatter

words = "\\all-caps\\All-Caps hello world".split()
formatter = WordFormatter()
formatted_output = formatter.format_dictation(words)
print(formatted_output)

There are more examples in the doctests: https://dragonfly2.readthedocs.io/en/latest/test_word_formatting_v11_doctest.html

This is not done for integers. IIRC DNS does not provide this information to client applications. You need to pass the words through Dragonfly's integer content classes for that.

This solves formatting the problem of free dictation with DNS and commands are not a problem. However the dictation element remains troublesome. The purpose of displaying things on a HUD would be what you see is what you got for output on the screen. If any formatting has been applied to a dictation element it of course does not show as it's not applied yet. Any thoughts to overcome the issue with dictation elements?

1 reply
Quintijn Hoogenboom
@quintijn
Did you ever try the nsformat module in natlinkcore? This was originally written by Joel Gould, to solve the formatting of the <dgndictation> imported rule
LexiconCode
@LexiconCode

Did you ever try the nsformat module in natlinkcore? This was originally written by Joel Gould, to solve the formatting of the <dgndictation> imported rule

@quintijn That's an interesting thought as I'm already importing DNS the specific code so why not Natlink directly. Thank you.

Quintijn Hoogenboom
@quintijn
@LexiconCode : I checked nsformat.py with unittestNsformat.py. One failure, that was in 2010 already a failure. I did only commit to "makeflitinstall". If you want an extra release, I will make it...
LexiconCode
@LexiconCode

@LexiconCode : I checked nsformat.py with unittestNsformat.py. One failure, that was in 2010 already a failure. I did only commit to "makeflitinstall". If you want an extra release, I will make it...

When you get a chance it would be good. It's a bit more reliable specifically with the 1st letter in a sentence compared to dragonfly's formater

Quintijn Hoogenboom
@quintijn
I will do so beginning of next week. When you have the preceding text (one character) available, you can start with the appropriate option. I will go through this and work on the documentation...
Rebecca Stevenson
@rebeccaFste_twitter

Hello! I'm new to this chat and first off wanted to thank everyone who has contributed to the dragonfly toolbox or shared their command modules – I'm a researcher and after a bad case of RSI would have been pretty screwed without some way to code by voice. Seriously, thank you! I've recently been trying to find/develop more command modules (right now I'm mostly using _vim and _multiedit) but I'm not a developer and am running into a few issues.

For example, I can't get _bringme to pull up a specific folder (https://github.com/simianhacker/code-by-voice/blob/master/macros/_bringme.py). It works fine for websites and for opening documents but not for opening folders. I'm also on the hunt for a command module to use with slack (for whatever reason my set up fails miserably in this app) – if anyone has a lead it would be much appreciated.

Not sure if this is the best place to post these questions – if there is another forum geared towards more basic questions please let me know!

Shervin Emami
@shervinemami
Hi @rebeccaFste_twitter , welcome to our community! Sorry to hear you've got RSI but glad you found us. This is the right place to ask beginner questions, even if we are a mix of beginners and experts and in-between. Are you using Windows, Mac and/or Linux?I haven't tried the _bringme functionality yet but I know some others here have. I do use a grammar that was based off _multiedit but I've customised my one over time.
LexiconCode
@LexiconCode
@rebeccaFste_twitter Welcome! I'd be willing to help you make slack grammar. I will be available for a few days as I work but I can check in a little later.
Dane Finlay
@Danesprite

Hello Rebecca and welcome! Sorry to hear about the RSI. It can be very painful and frustrating. Glad you've found your way here.

For opening folders using the _bringme.py module, I have managed to get it working. As the module's documentation specifies, you need to add folder entries to the configuration. However, the author is slightly wrong about the use of the r in front of the open-quote. This doesn't work for strings ending with backslashes, e.g. "C:\".

Try the following targets.mapping entries in your configuration:

"my local folder":       folder(r"C:"),  # Without a backslash.
"program files":         folder(r"C:\Program Files"),
"macro system":          folder(r"C:\Natlink\Natlink\MacroSystem"),
Rebecca Stevenson
@rebeccaFste_twitter
Thanks for the welcome everyone! Glad I joined.
@Danesprite, that does the trick, thank you! I just started using the _bringme module a few weeks ago and it makes life so much easier. Glad to have the folder functionality working
1 reply
Rebecca Stevenson
@rebeccaFste_twitter
@LexiconCode , oh wow thank you! I found one bare-bones module here (https://github.com/haughki/MyDragonflyModules/blob/master/slack.py) but I suspect my real issue might be that some kind of built-in shortcut in slack is interacting with my set up and messing things up (it always does unexpected things e.g selecting the menu etc). I guess I can deactivate my current grammars one at a time to try to track down the culprit, if that makes sense.
@shervinemami, I use Windows. As I mentioned above, I just started using _bringme and it is pretty magical. Highly recommended
MeteorVsBunny
@MeteorVsBunny

the commands in that grammer do not really look like slack to me
I have a slack grammar but I am using caster rather than dragonfly so if I shared the whole file it would not work for you. And I'm not familiar with setting up dragonfly only files
I replaced the commands in that file with my own, which should work but I have not tested it
control slash in Slack brings up the list of shortcuts so you can map any commands you want

from dragonfly import (Grammar, AppContext, MappingRule, Integer, Key, Text, Dictation, Repeat)
from supporting import utils

class SlackMapping(MappingRule):
mapping = {
"next [message]": Key("as-down"),
"prior [message]": Key("as-up"),
"open channel": Key("c-k"),
"next channel [<n>]": Key("a-down/15") Repeat(extra="n"),
"prior channel [<n>]": Key("a-up/15")
Repeat(extra="n"),
"keyboard": Key("c-slash"),
"info": Key("cs-i"),
"jump": Key("c-j"),
"attach file": Key("c-u"),
"edit last [message]": Key("c-up"),
"code block": Key("cas-c"),
"quit slack": Key("c-q"),

}
extras=[
    Integer("n", 1, 50),
    Integer("number", 1, 9999),
    Dictation("text"),
]
defaults = {
    "n": 1,
}

context = AppContext(executable="slack")
slack_grammar = Grammar("Slack Grammar", context=context)
slack_grammar.add_rule(SlackMapping())
slack_grammar.load()

def unload():
global slack_grammar
slack_grammar= utils.unloadHelper(slack_grammar, name)