I am running 2.7 and i am using pyinstaller. My goal is to output a exe and also have it run my other class file. I am also using https://code.google.com/p/dragonfly/ as a framework for voice recognition. I have created another file in the examples direction under dragonfly->examples->text.py . If i run https://code.google.com/p/dragonfly/source/browse/trunk/dragonfly/examples/dragonfly-main.py?spec=svn79&r=79 with my IDE i can say voice commands and it will understand the below file i have created and the other example files that are in the dragonfly examples.
from dragonfly.all import Grammar, CompoundRule, Text, Dictation
import sys
sys.path.append('action.py')
import action
# Voice command rule combining spoken form and recognition processing.
class ExampleRule(CompoundRule):
print "This works"
spec = "do something computer" # Spoken form of command.
def _process_recognition(self, node, extras): # Callback when command is spoken.
print "Voice command spoken."
class AnotherRule(CompoundRule):
spec = "Hi there" # Spoken form of command.
def _process_recognition(self, node, extras): # Callback when command is spoken.
print "Well, hello"
# Create a grammar which contains and loads the command rule.
grammar = Grammar("example grammar") # Create a grammar to contain the command rule.
grammar.add_rule(ExampleRule()) # Add the command rule to the grammar.
grammar.add_rule(AnotherRule()) # Add the command rule to the grammar.
grammar.load()
# Load the grammar.
I noticed in console that it will output
UNKNOWN: valid paths: ['C:\\Users\\user\\workspace\\dragonfly\\dragonfly-0.6.5\\dragonfly\\examples\\action.py',etc..etc...
After i have used pyinstaller the output for that line is
UNKNOWN: valid paths: []
So its not loading the examples because it cannot find them. How can i tell pyinstaller to also load the example files when it is creating an exe? And If it does load the files how can i make sure my exe knows where the files are?
The command i am running for pyinstaller
C:\Python27\pyinstaller-2.0>python pyinstaller.py -p-paths="C:\Users\user\worksp
ace\dragonfly\dragonfly-0.6.5\dragonfly\examples\test.py" "C:\Users\user\workspa
ce\dragonfly\dragonfly-0.6.5\dragonfly\examples\dragonfly-main.py"
If I understand clearly. You have your script and some examples scripts which call your script to show that it is working?
You are missing the point.
Your script supposes to be an end product.
If you want to test functionality do it in development version.
If you want to test exe file do it by another(separated) test script.
Other thing:
Scripts and modules are totally different things.
You are trying to import your script as module and use it in example script.
I suggest you to build main entry point to script (with parameters if you need) as it is meant to be done.
And make other example script which run your script.
Or make a module and build script which uses this module.
Then build this example script to exe file which uses that module and shows it works
PyInstaller can compile one script at once. Forcing it to do unusual things is not needed.
Related
I'm trying to create a program that copies a directory in the library directory on mac (path : "/Library"). I use shutil which works very well in other directories but not in the Library directory...
I want to be able to compile my program, so I can't run it as root.
Here is my code :
import shutil
def copy(src_path, dir_path):
try:
shutil.copytree(src_path, dir_path)
print("Success!")
except:
print("Impossible to copy the folder...")
print("Failed!")
copy("/Users/marinnagy/Desktop/Test", "Library/Test")
I think it's because the library directory is protected and requires authentication to make changes.
Do I have to make an authentication request to the user ? Or do I need to use another method than shutil ?
Thanks for your help !
After a good deal of research and many attempts, I finally managed to copy a folder into my Library directory.
On macOS, the process of writing to a protected directory like the Library directory is blocked for python program. Once compiled (I use pyinstaller), it seems to be impossible for a python application to access this kind of folder, even if you give the app Full Disk Access in the System Preferences.
So I used some AppleScript to manage this specific copy/paste task :
on run {scr_path, dir_path} # Run with arguments
# Translate standard paths to their quoted form
set formated_scr_path to quoted form of scr_path
set formated_dir_path to quoted form of dir_path
# Run a simple shell script to copy the repertory in the other
do shell script "cp -R " & formated_scr_path & space & formated_dir_path ¬
with administrator privileges # Ask for administrator privileges
end run
Then, in my python program, I call the AppleScript program when I want to copy/past to a protected repertory like the Library repertory :
import subprocess
def copy(scr_path, dir_path):
# Use the osascript process to call the AppleScript
# Give the paths in arguments
process = subprocess.call(['osascript', "path/to/applescript",
scr_path, dir_path])
return process
copy("path/to/folder 1", "path/to/folder 2")
This method worked for me on protected repertories. The AppleScript run in the background and an authentication window pop in, asking the user to identify himself as an admin :
result screenshot
Is it possible to call a script from the command prompt in windows (or bash in linux) to open Maya and then subsequently run a custom script (possibly changing each time its run) inside Maya? I am searching for something a bit more elegant than changing the userSetup file and then running Maya.
The goal here is to be able to open a .mb file, run a script to position the scene inside, setup a generic set of lights and then render the scene to a specific place and file type. I want to be able to set this up as a scheduled task to check for any new scene files in a directory and then open maya and go.
Thanks for the help!
For something like this you can use Maya standalone instead of the full blown UI mode. It is faster. It is ideal for batch scheduled jobs like these. Maya standalone is just Maya running without the GUI. Once you have initialized your Maya standalone, you can import and call any scripts you want, as part of the original calling script. To start you off here is an example: (Feel free to use this as a reference/modify it to meet your needs)
In your script you first initialize Maya standalone.
import maya.standalone
maya.standalone.initialize("Python")
import maya.cmds as cmds
cmds.loadPlugin("Mayatomr") # Load all plugins you might need
That will get Maya running. Now we open and/or import all the files necessary (egs. lights, models etc.)
# full path to your Maya file to OPEN
maya_file_to_open = r"C:/Where/Ever/Your/Maya_Scene_Files/Are/your_main_maya_file.mb"
# Open your file
opened_file = cmds.file(maya_file_to_open, o=True)
# full path to your Maya file to IMPORT
maya_file_to_import = r"C:/Where/Ever/Your/Maya_Scene_Files/Are/your_maya_file.mb"
# Have a namespace if you want (recommended)
namespace = "SomeNamespaceThatIsNotAnnoying"
# Import the file. the variable "nodes" will hold the names of all nodes imported, just in case.
nodes = cmds.file(maya_file_to_import, i=True,
renameAll=True,
mergeNamespacesOnClash=False,
namespace=namespace,
returnNewNodes=True,
options="v=0;",
type="mayaBinary" # any file type you want. this is just an example.
)
#TODO: Do all your scene setup/ positioning etc. if needed here...
#Tip: you can use cmds.viewFit(cam_name, fitFactor=1) to fit your camera on to selected objects
Now we save this file out and call Maya Batch renderer to render it out
render_file = "C:/Where/Ever/Your/Maya_Scene_Files/Are/your_RENDER_file.mb"
cmds.file(rename=render_file)
cmds.file(force=True, save=True, options='v=1;p=17', type='mayaBinary')
import sys
from os import path
from subprocess import Popen
render_project = r"C:/Where/Ever/YourRenderProjectFolder"
renderer_folder = path.split(sys.executable)[0]
renderer_exec_name = "Render"
params = [renderer_exec_name]
params += ['-percentRes', '75']
params += ['-alpha', '0']
params += ['-proj', render_project]
params += ['-r', 'mr']
params += [render_file]
p = Popen(params, cwd=renderer_folder)
stdout, stderr = p.communicate()
That's it! Of Course, your script will have to be run using Maya's Python interpreter (Mayapy).
Do check out the docs for all the commands used for more options, esp.:
cmds.file()
cmds.viewFit()
cmds.loadPlugin()
Subprocess and Popen
PLUS, because of the awesomeness of Python, you can use modules like sched (docs) to schedule the running of this method in your Python code.
Hope this was useful. Have fun with this. Cheers.
A lot depends on what you need to do.
If you want to run a script that has access to Maya functionality, you can run a Maya standalone instance as in Kartik's answer. The mayapy binary installed in the same folder as your maya is the Maya python interpreter, you can run it directly the same way you'd run python.exe Mayapy has the same command flags as a regular python interpreter.
Inside a mayapy session, once you call standalone.initialize() you will have a running Maya session - with a few exceptions, it is as if you were running inside a script tab in a regular maya session.
To force Maya to run a particular script on startup, you can call the -c flag, just the way you would in python. For example, you can start up a maya and print out the contents of an empty scene like this (note: I'm assuming mayapy.exe is on your path. You can just CD to the maya bin directory too).
mayapy -c 'import maya.standalone; maya.standalone.initialize(); import maya.cmds as cmds; print cmds.ls()'
>>> [u'time1', u'sequenceManager1', u'renderPartition', u'renderGlobalsList1', u'defaultLightList1', u'defaultShaderList1', u'postProcessList1', u'defaultRenderUtilityList1', u'defaultRenderingList1', u'lightList1', u'defaultTextureList1', u'lambert1', u'particleCloud1', u'initialShadingGroup', u'initialParticleSE', u'initialMaterialInfo', u'shaderGlow1', u'dof1', u'defaultRenderGlobals', u'defaultRenderQuality', u'defaultResolution', u'defaultLightSet', u'defaultObjectSet', u'defaultViewColorManager', u'hardwareRenderGlobals', u'hardwareRenderingGlobals', u'characterPartition', u'defaultHardwareRenderGlobals', u'lightLinker1', u'persp', u'perspShape', u'top', u'topShape', u'front', u'frontShape', u'side', u'sideShape', u'hyperGraphInfo', u'hyperGraphLayout', u'globalCacheControl', u'brush1', u'strokeGlobals', u'ikSystem', u'layerManager', u'defaultLayer', u'renderLayerManager', u'defaultRenderLayer']
You can run mayapy interactively - effectively a command line version of maya - using the -i flag: This will start mayapy and give you a command prompt:
mayapy -i -c \"import maya.standalone; maya.standalone.initialize()\""
which again starts the standalone for you but keeps the session going instead of running a command and quitting.
To run a script file, just pass in the file as an argument. In that case you'd want to do as Kartik suggests and include the standalone.initalize() in the script. Then call it with
mayapy path/to/script.py
To suppress the userSetup, you can create an environmnet variable called MAYA_SKIP_USERSETUP_PY and set it to a non-zero value, that will load maya without running usersetup. You can also change environment varialbes or path variables before running the mayap; for example I can run mayapys from two different environments with these two bash aliases (in windows you'd use SET instead of EXPORT to change the env vars):
alias mp_zip="export MAYA_DEV=;mayapy -i -c \"import maya.standalone; maya.standalone.initialize()\""
alias mp_std="export MAYA_DEV=C:/UL/tools/python/ulmaya;export ZOMBUILD='C:/ul/tools/python/dist/ulmaya.zip';mayapy -i -c \"import maya.standalone; maya.standalone.initialize()\""
This blog post includes a python module for spinning up Mayapy instances with different environments as needed.
If you want to interact with a running maya from another envrionment - say, if you're trying to remote control it from a handheld device or a C program - you can use the Maya commandPort to handle simple requests via TCP. For more complex situations you could set up a basic remoting service like this of your own, or use a pre-exiating python RPC module like RPyC or ZeroMQ
I am trying to use a JAR file and import its functionality into my python script. The jar file is located in the same directory as my python script and pig script
script.py
import sys
sys.path.append('/home/hadoop/scripts/jyson-1.0.2.jar')
from com.xhaus.jyson import JysonCodec as json
#outputSchema('output_field_name:chararray')
def get_team(arg0):
return json.loads(arg0)
script.pig
register 'script.py' using jython as script_udf;
a = LOAD 'data.json' USING PigStorage('*') as (line:chararray);
teams = FOREACH a GENERATE script_udf.get_team(line);
dump teams;
It is a very simple UDF that I am trying to use, but for some reason I always get an error saying "No module named xhaus". Here are all the classes in that jar.
$ jar tf jyson-1.0.2.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/xhaus/
com/xhaus/jyson/
com/xhaus/jyson/JSONDecodeError.class
com/xhaus/jyson/JSONEncodeError.class
com/xhaus/jyson/JSONError.class
com/xhaus/jyson/JysonCodec.class
com/xhaus/jyson/JysonDecoder.class
com/xhaus/jyson/JysonEncoder.class
So xhaus exists in the jar, but for some reason this is not being picked up. When I look at a few tutorials, they are able to run these scripts fine. I might be missing a silly detail, please help.
EDIT:
This script is executed by pig. So the pig script calls the python script. And the python script uses the JysonCodec class.
pig script.pig
In case you are running this script in pig map reduce mode you need to make the jar available at the job runtime. On the top of your pig script you need to add the following line
REGISTER /home/hadoop/scripts/jyson-1.0.2.jar;
Then you need to comment out sys.path.append('/home/hadoop/scripts/jyson-1.0.2.jar')
from your udf script. The classes from the jar will already be available to the udf since you have registered that with the pig script. So need to change sys.path
Hope it helps.
A posted a question a while back on how to add custom LLDB type summaries into Xcode. I found out that we can do so by loading a Python script.
However, I want to know if there's a way to load multiple Python files? I work with many different projects, so I want to have 1 summaries files for the general types that are used in all my projects, and 1 summaries files for project-specific types.
~/MyGenericSummaries.py
import lldb
def __lldb_init_module(debugger, dictionary):
debugger.HandleCommand('type summary add --summary-string "these are words" MyGenericClass');
~/MyProjectSummaries.py
import lldb
def __lldb_init_module(debugger, dictionary):
debugger.HandleCommand('type summary add --summary-string "these are more words" MyProjectClass');
~/.lldbinit
command script import ~/MyGenericSummaries.py
command script import ~/MyProjectSummaries.py
This never loads the type summary of MyProjectSummaries.py -- LLDB just tells me
error: module importing failed: module already imported
Is it possible to keep the generic summaries and project summaries in seperate files? This would really help, because I have some type names that clash amongst different projects, so I'd rather split these off.
Many thanks :)
Ok I got it... With a bit of Python magic:
~/MyGenericSummaries.py
import lldb
def doLoad(debugger, dictionary):
debugger.HandleCommand('type summary add --summary-string "these are words" MyGenericClass');
def __lldb_init_module(debugger, dictionary):
doLoad(debugger, dictionary);
~/MyProjectSummaries.py
import lldb
from MyGenericSummaries import doLoad
def __lldb_init_module(debugger, dictionary):
doLoad(debugger, dictionary);
debugger.HandleCommand('type summary add --summary-string "these are more words" MyProjectClass');
~/.lldbinit
command script import ~/MyProjectSummaries.py
The only downside is that I'll need to tweak .lldbinit and restart Xcode everytime I switch project, but that's something I can live with.
I'm not clear why the original code did not work. From what you've quoted, I expect that to work.
You can certainly command script import multiple Python files in your ~/.lldbinit file - I do that all the time. From the error message, it looks like you had a command script import ~/MyProjectSummaries.py in your ~/.lldbinit already. Be careful to look for a ~/.lldbinit-Xcode which is also sourced when Xcode is run (or ~/.lldbinit-lldb if the command line lldb is being used. The general form is ~/.lldbinit-DRIVER_NAME for whatever lldb is being used. This feature is useful if you want to enable certain settings only when the lldb library is being used inside Xcode, for instance.)
You may want to put your type summary entries in per-project groups. If you do type summary list you will see that the built-in summaries are already grouped into categories like libcxx, VectorTypes, CoreGraphics, etc. These groups of summaries can be enabled or disabled with type category enable|disable|list|delete.
Command line lldb will also read a .lldbinit in the current working directory where it is run - although this doesn't help the Xcode case. For what you're doing, you really want a Project-specific lldbinit file. If you had these type summaries added in your ~/.lldbinit file, the project-specific lldbinit might just enable/disable the correct type summaries for this project. But there's no feature like this in Xcode right now.
I have been trying to figure out how to use the Dragonfly module. I have taken a look at the documentation, but I can't seem to figure out how to use it. I just want to be able to recognize a few phrases and act upon those phrases.
That's correct, this example will terminate. I've seen this particular example quite a bit, and it is missing a number of key features.
The first thing is that pythoncom is not imported. This provides a main loop for the program. The above
from dragonfly.all import Grammar, CompoundRule
# Voice command rule combining spoken form and recognition processing.
class ExampleRule(CompoundRule):
spec = "do something computer" # Spoken form of command.
def _process_recognition(self, node, extras): # Callback when command is spoken.
print "Voice command spoken."
# Create a grammar which contains and loads the command rule.
grammar = Grammar("example grammar") # Create a grammar to contain the command rule.
grammar.add_rule(ExampleRule()) # Add the command rule to the grammar.
grammar.load() # Load the grammar.
while True:
pythoncom.PumpWaitingMessages()
sleep(.1)
First, in case you're using Linux, you should know that Dragonfly only works with Windows Speech Recognition or Dragon NaturallySpeaking + Natlink. (It is possible to get it working on Linux with a virtual machine and Aenea, but that seems out of the scope of this question.)
If you're using it with WSR, it should be as simple as making sure that Dragonfly is in your Python path and calling the following at the end of your main script:
while True:
pythoncom.PumpWaitingMessages()
time.sleep(0.1)
If you're using it with Dragon NaturallySpeaking, follow the link above to the Natlink website and follow the instructions there to install and activate Natlink before trying to use Dragonfly. Once it is installed (use all the defaults), you should be able to put Dragonfly scripts in your C:\NatLink\NatLink\MacroSystem folder and have them activate automatically when you start Dragon NaturallySpeaking.
I find the usage example given in this document to be pretty simple and self-explaining:
A very simple example of Dragonfly usage is to create a static voice
command with a callback that will be called when the command is
spoken. This is done as follows: ::
from dragonfly.all import Grammar, CompoundRule
# Voice command rule combining spoken form and recognition processing.
class ExampleRule(CompoundRule):
spec = "do something computer" # Spoken form of command.
def _process_recognition(self, node, extras): # Callback when command is spoken.
print "Voice command spoken."
# Create a grammar which contains and loads the command rule.
grammar = Grammar("example grammar") # Create a grammar to contain the command rule.
grammar.add_rule(ExampleRule()) # Add the command rule to the grammar.
grammar.load() # Load the grammar.