Forum: Poser Python Scripting


Subject: Anyone with Python RPC/IPC experience?

an0malaus opened this issue on Aug 30, 2019 ยท 7 posts


an0malaus posted Fri, 30 August 2019 at 7:54 AM

I'm looking for a way to bypass a current Poser bug, whereby Poser overwrites the LibraryPrefs.xml file, thus erasing any changes a python script run from within Poser might have made. There seems to be an opinion that this may be a Mac only bug, and that Windows Poser will merge any changes it finds in the file with the list of known runtimes it holds in memory.

In any case, MacOS Poser is overwriting any modifications made which destroys the point of the script.

I am wondering if it might be feasible to have Poser launch a shell command, and have that run a python script external to Poser, which can monitor the status of Poser's process, and then restore changes to the LibraryPrefs.xml file once the Poser process terminates.

The only reason Poser needs to terminate, is that there is currently no mechanism by which a python script from within Poser can tell poser to reload its LibraryPrefs.xml. If there were (and a request has been made for such but is unlikely to be implemented any time soon), then a Poser restart would be redundant. The whole point of the script is to save the user from having to create a new Runtime hierarchy and manually add that to Poser's list of Library runtimes.

It's possible that there would be no need for the remote script to communicate directly with the internal script which launches it. It just needs to find a new candidate LibraryPrefs.xml, continue to execute while waiting for the user to manually shutdown Poser (though the launch script could conceivably automate a Quit), detect the Poser process termination and overwrite the overwritten LibraryPrefs.xml with the replacement candidate.

It has occurred to me that there may be specific issues which would prevent any shell launched within Poser from remaining active once Poser terminates, but such things are possible at the Unix shell level.



My ShareCG Stuff

Verbosity: Profusely promulgating Graham's number epics of complete and utter verbiage by the metric monkey barrel.


raven posted Fri, 30 August 2019 at 9:30 AM

What if you just made the LibraryPrefs.xml read only? That way Poser would be unable to change it. Would that work?

Worth a try surely?



an0malaus posted Fri, 30 August 2019 at 10:24 AM

I suppose that if the script gets launched automatically by Poser, and decides based on the writability of the file whether to make changes and set to read only, or else reset to writable and do nothing, the two separate launches of Poser would complete the required cycle.

Thanks very much! That might just work, and be far simpler that creating other files as FirstRun or Cleanup flags. Brilliant. I'll give it a try!



My ShareCG Stuff

Verbosity: Profusely promulgating Graham's number epics of complete and utter verbiage by the metric monkey barrel.


ironsoul posted Fri, 30 August 2019 at 1:19 PM

Readonly might lead to corruption or unexplained crashes. Depending on your constraints one option would be to replace Poser with your own script. Your script would then fork/spawn Poser in child wait mode (your script waits until child process finishes) and then your script kicks in and merges your changes into LibraryPrefs.xml. Simple file i/o could be used for this and avoid any firewall issues possible with a rpc type solution.



an0malaus posted Sat, 31 August 2019 at 2:53 AM

@ironsoul the script is intended to be a first run kind of thing. It could run every time if added to poserStartup.py, but it can tell if it needs to do anything and avoid action if everything's in place. In that situation, it will only need one Poser exit with read only prefs to prevent overwrite. On next Poser launch, it can restore the writability of the Prefs and then do nothing. Every subsequent exit and launch of Poser will be unaffected. This will be tested, and still needs user interaction to Quit and relaunch Poser as instructed by the script.

I absolutely agree on the RPC/interprocess communication complication. I only mentioned that since I'd been browsing the Python framework within the Poser app and noticed those modules. Far better just to have sufficient, identifiable conditions to act once, repair preference permissions then remain dormant.

At the point where Poser (hopefully) eventually supports Python updates to the Runtime libraries, mucking about with preferences and filesystems (apart from folder creation) will become moot.



My ShareCG Stuff

Verbosity: Profusely promulgating Graham's number epics of complete and utter verbiage by the metric monkey barrel.


ironsoul posted Sat, 31 August 2019 at 6:56 AM

Yes, would be good if Poser python could support pip :)

Regarding launching an external script this can be done with the subprocess.popen function. The code I tested is Windows, I'm assuming popen also works in Mac/Unix land.

The following would be in the Poser python code...

import subprocess
import os
poserpid = os.getpid()
subprocess.Popen(["cmd.exe","/c python c:/tmp/checklock.py "+ poserpid.str()],creationflags=subprocess.CREATE_NEW_PROCESS_GROUP)

The external python script could then grab the poserpid as a process arg and go into a check,sleep loop waiting for Poser to finish before carrying out any tidy up actions.

Checkng for process pids is os specific. There is a stackoverflow article here

Other approaches are to use a global resource like semaphore locks or file locks to keep the two programs aware of each other. The main thing is to chose a method that auto clears up on Poser exit irrespective of how it terminated...



an0malaus posted Mon, 02 September 2019 at 9:44 AM

Sounds like a useful plan. Current tactic is just to use sys.exit() to kill Poser and then manually restart Poser. Job done.

Pip support would be marvelous. There are quite a few modules which need replacement under macOS to get equivalent functionality to Poser Python under Windows. PIL is just one. I have to manually replace it with every single Poser update in order to be able to export JPEG images from Python. It would also be nice to have EXR libraries to allow manipulation of HDR renders without loss of dynamic range converting to other formats. Can't even export an area render in that format.



My ShareCG Stuff

Verbosity: Profusely promulgating Graham's number epics of complete and utter verbiage by the metric monkey barrel.