Run an in-memory macro as if run by MacroManager

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Run an in-memory macro as if run by MacroManager

Post by chennes »

The Addon Manager actually pulls down the full code for a macro when displaying the macro information: there is an execute button in there that allows you to run the macro, but only if it's installed. I was thinking about tweaking that a bit, given that the macro exists in memory, and allow you to run it regardless of whether it's been installed (maybe you don't really want to keep a copy of it, you just need to run it this once, then discard it, etc.). What we have right now is:

Code: Select all

macro_path = os.path.join(FreeCAD.getUserMacroDir(True), macro.filename)
if os.path.exists(macro_path):
    macro_path = macro_path.replace("\\", "/")
    FreeCADGui.open(str(macro_path))
    self.dialog.hide()
    FreeCADGui.SendMsgToActiveView("Run")
What I'd like is something more like:

Code: Select all

self.dialog.hide()
FreeCAD.Interpreter.Run(macro.code) #macro.code is the macro's code in a Python string
But if I look at the code for the Macro Manager, it's doing a bunch of setup before running the macro related the some user preferences, some environment setup, etc. and obviously I don't want to duplicate that work in the Addon Manager. Is there a simple way to get FreeCAD's Macro Manager to run a script, from another chunk of Python code?
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Run an in-memory macro as if run by MacroManager

Post by TheMarkster »

This might or might not work. The variable macro_string could be loaded from a file, but some post processing might be needed. For example \n in the string will generate an EOL error. \n can be replaced with chr(13)

Code: Select all

macro_string =\
'''
import FreeCAD
FreeCAD.Console.PrintMessage(some_variable)
'''

import sys, importlib
my_name = 'my_macro'
my_spec = importlib.util.spec_from_loader(my_name, loader=None)

my_macro = importlib.util.module_from_spec(my_spec)
my_macro.some_variable = "Hello, world!\n"

exec(macro_string, my_macro.__dict__)
wmayer
Founder
Posts: 20245
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Run an in-memory macro as if run by MacroManager

Post by wmayer »

What about FreeCADGui.doCommand?

Code: Select all

Gui.doCommand("print('hello, world')")
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Run an in-memory macro as if run by MacroManager

Post by chennes »

Yeah, turns out my grand scheme here was doomed to failure from the start... I forgot that macros can have auxiliary files. Doh!
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Run an in-memory macro as if run by MacroManager

Post by TheMarkster »

While you're working on the addon manager, I have some ideas:

1) Windows versions are failing to fetch the macro list from the wiki, something about expired certificate. ExtMan addon also fails to fetch these.
2) Would be fun to have a top 10 most installed this week/month/all-time/whatever
3) I'd like to get an idea how many people have installed my workbench/macro so I can allocate my time accordingly, privacy concerns permitting.
4) Would be nice if the addon manager could optionally add the macro to a custom macro toolbar.
5) If 4 can be done it would be nice if a macro could define getIcon(), return an XPM string, and the addon manager could use the icon in the toolbar.
6) When a macro is installed, add it to the top of the recent macros menu. This should be doable by modifying parameters.
7) If a macro creates additional files provide a mechanism to inform the addon manager the names of these files (or folder) so they can be also removed when uninstalling the macro. This might already be possible. I don't know.
8) What are system macros? AFAIK this feature has never been implemented. What if these were macros that ran on startup automatically? That could work possibly for feature python objects that are broken on restarting/reloading files containing them.
9) Currently macros can be hosted on github as gists and installed by the addon manager. Would be nice if it could fetch the .FCMacro file directly from github. Gists are a bit of a pain to update and each time you update you must also edit the link in the wiki to the new raw file url. I would like to be able to push an update to github and the addon manager automatically knows to fetch the update without need to modify the wiki.

Edit: #6 is not doable just by editing the MRU parameters. Would need to expose:

Code: Select all

getMainWindow()->appendRecentMacro(fi.filePath());
to python.
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Run an in-memory macro as if run by MacroManager

Post by chennes »

TheMarkster wrote: Mon Oct 25, 2021 7:53 pm While you're working on the addon manager, I have some ideas:
Thanks for the suggestions, those are great ideas! Let me go through them a bit here:

1) Solved by relaxing the SSL requirements -- you can do this in your own copy by changing line 49 of addonmanager_utilities.py from

Code: Select all

        ssl_ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
to

Code: Select all

        ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
I'm not thrilled about the security ramifications here, but I don't know realistically what the chances are that we need to worry about it, given that we are hard-coding a domain that we control. Any thoughts?

2 and 3) Neat ideas, but I don't think we can make it work without "phoning home" -- the way the download of the macros currently works it's not easily possible to determine whether a macro was actually installed. And I don't think we want to get into the "sending usage stats to home base" game, that has blown up in the faces of some prominent opensource projects in the past.

4) That seems doable.

5) With the new package.xml metadata file, a macro-containing package can include an icon for that macro. I don't know if this quite meets your needs or not.

6) Can probably be done by direct manipulation of user preferences, or we could expose the C++ code to Python as you suggest.

7) Already possible, and done (in theory!)

8) Hahaha, I thought maybe I was just clueless, I have no idea what system macros are.

9) I'm not sure about the gists, I've only looked at the macros installed from https://github.com/FreeCAD/FreeCAD-macros -- those are just files in a git repo, and at the code that gets pulled off the wiki via a crazy html-parsing routine. With the new package.xml metadata, IMO the best possible way to distribute a macro is to create your own github repo for it and then have it added to the FreeCAD-Addons git repo as a submodule. You still have complete control over the editing of the macro and its files, because it's your git repo, but it will show up automatically in the Addon Manager without the user having to add an external repo. Macro authors can easily package up a bunch of their related macros into one package, etc.
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Run an in-memory macro as if run by MacroManager

Post by TheMarkster »

That fixed the addon manager issue. I had tried adding some ssl-related stuff to the url, but none of it worked.
User avatar
Roy_043
Veteran
Posts: 8456
Joined: Thu Dec 27, 2018 12:28 pm

Re: Run an in-memory macro as if run by MacroManager

Post by Roy_043 »

chennes wrote: Tue Oct 26, 2021 1:45 am Solved by relaxing the SSL requirements
Is this something that can/should be backported to 0.19.3?
Syres
Veteran
Posts: 2893
Joined: Thu Aug 09, 2018 11:14 am

Re: Run an in-memory macro as if run by MacroManager

Post by Syres »

Roy_043 wrote: Tue Oct 26, 2021 8:32 am
chennes wrote: Tue Oct 26, 2021 1:45 am Solved by relaxing the SSL requirements
Is this something that can/should be backported to 0.19.3?
I really think this should be fixed properly, I've already pinged Kurt last week regarding it and haven't had a response as yet. The certificate hasn't actually expired according to my research, it expires on 23rd December 2021 but again I wanted Kurt to clarify what's happening.
User avatar
chennes
Veteran
Posts: 3884
Joined: Fri Dec 23, 2016 3:38 pm
Location: Norman, OK, USA
Contact:

Re: Run an in-memory macro as if run by MacroManager

Post by chennes »

Syres wrote: Tue Oct 26, 2021 3:38 pm I really think this should be fixed properly
Agreed - I think Yorik has recently emailed our web host about the certificates. So stay tuned...
Chris Hennes
Pioneer Library System
GitHub profile, LinkedIn profile, chrishennes.com
Post Reply