Forum Moderators: Staff
Poser Python Scripting F.A.Q (Last Updated: 2024 Mar 19 1:03 pm)
class gz_open(object):
def __init__(self, fname, mode="r"):
self.fname = fname
self.mode = mode
if "w" in mode:
self.open = open
else:
import os
if os.path.isfile(fname):
with open(fname, 'rb') as f:
if f.read(2) != b'\x1f\x8b':
self.open = open
else:
import gzip
self.open = gzip.open
else:
raise FileNotFoundError("File '%s' not found." % fname)
def __enter__(self):
self._fh = self.open(self.fname, self.mode)
return self._fh
def __exit__(self, exc_type, exc_val, exc_tb):
self._fh.close()
if __name__ == "__main__":
import json
with gz_open("/home/fredi/Schreibtisch/DAZ_April.dbz", "r") as fh:
js = json.load(fh)
This can make it easier to deal with dictionaries:
class _dict(dict):
def __getattr__(self, key):
if key in self:
return self[key]
return self.__getattribute__(key)
if __name__ == "__main__":
import json
with gz_open("/home/fredi/Schreibtisch/DAZ_April.dbz", "r") as fh:
js = json.load(fh)
js =_dict(js)
print(js.version)
### "js.figures" is a list holding all defined figures.
### Each figure in the list is a dict.
fig = _dict(js.figures[0])
print(fig.name, fig.center_point, fig.end_point)
Dictionaries are nice. But sometimes one needs a "real" object. If this is the case, I use the following:
class obj_cls(object):
pass
def obj_from_dict(d):
obj = obj_cls()
if isinstance(d, dict):
for k, v in d.items():
if isinstance(v, dict):
setattr(obj, k, obj_from_dict(v))
elif isinstance(v, (tuple, list)):
setattr(obj, k, type(v)(_v if isinstance(_v, (int, float, str))
else obj_from_dict(_v)
for _v in v))
else:
setattr(obj, k, v)
return obj
elif isinstance(d, (list, tuple)):
return type(d)(_d if isinstance(_d, (int, float, str))
else obj_from_dict(_d)
for _d in d)
return d
Function "obj_from_dict(<dict>)" returns an object with all key/values set. The above looks like
with gz_open("/home/fredi/Schreibtisch/DAZ_April.dbz", "r") as fh:
js = json.load(fh)
obj = obj_from_dict(js)
print(obj.version)
# "obj.figures" is a list holding all defined figures.
# Each figure in the list is an object (class obj_cls).
print(obj.figures[0].name, obj.figures[0].center_point, obj.figures[0].end_point)
And little extension to get parts of the object as JSON:
class ObjEncoder(json.JSONEncoder):
def default(self, obj):
return obj.__dict__
# JSON method added to the class from above
class obj_cls(object):
def as_json(self):
return json.dumps(self.__dict__, indent=4, cls=ObjEncoder)
print(obj.figures[0].bones[0].as_json())
results in:
{
"name": "hip",
"center_point": [
0.000440493,
103.015,
1.58171
],
"end_point": [
-0.0066126,
86.7606,
0.136487
],
"orientation": [
0,
0,
0,
1
],
"origin": [
0.000440493,
103.015,
1.58171
],
...
}
Need to find id's in a DAZ file somewhere (recursiv)? Try this extended obj_cls:
class obj_cls(object):
def __eq__(self, other):
if other.__class__ is self.__class__:
return self.id == other.id
return False
def as_json(self):
return json.dumps(self.__dict__, indent=4, cls=ObjEncoder)
def find_id(self, _id):
if hasattr(self, "id") and self.id == _id:
return self
for v in self.__dict__.values():
if isinstance(v, self.__class__):
res = self.find_id(_id)
if res:
return res
elif isinstance(v, (tuple, list)):
for entry in v:
if isinstance(entry, self.__class__):
res = entry.find_id(_id)
if res:
return res
return None
---------------------------------------------------------------------------
with gz_open("/home/fredi/Schreibtisch/DAZ Gudrun.duf") as fh:Hey. Thanks!
I had in the mean while found a solution that suits my needs. I open first as a gzip. That will give me an error when the file is not a gzip, so I can re-open in the error handling.
Too bad though gzip.open does not do this internally.
# define a dict named 'data' at this level so it will survive the file with open.
data = {}
# Opening the chosen DUF file. It is JSON format so we use JSON package. In case of errors npars is set to 0, which
# will cut short the loop over the parameters and so effectively end the script except for the DrawAll()
# first attempt is to load from a gzipped, and on error load as a noncompressed file.
if len(duf) > 0:
if duf.endswith('.duf'):
with gzip.open(duf,'r') as f:
try:
data = json.load(f)
try:
npars = len(data['scene']['animations'])
except KeyError:
poser.DialogSimple.MessageBox('file does not contain pose data. \nNo pose loaded')
npars = 0
except:
with open(duf, 'r') as g:
try:
data = json.load(g)
try:
npars = len(data['scene']['animations'])
except KeyError:
poser.DialogSimple.MessageBox('file does not contain pose data. \nNo pose loaded')
npars = 0
except:
poser.DialogSimple.MessageBox('error loading file\nNo pose loaded')
else:
poser.DialogSimple.MessageBox('file '+ os.path.basename(duf) + ' is not a .duf file\nNo pose loaded')
npars = 0
else:
npars = 0
This site uses cookies to deliver the best experience. Our own cookies make user accounts and other features possible. Third-party cookies are used to display relevant ads and to analyze how Renderosity is used. By using our site, you acknowledge that you have read and understood our Terms of Service, including our Cookie Policy and our Privacy Policy.
Is there a simple method to let Python read a file, irrespective of it being gripped or not?
I am working on a small script that can read DS4 .duf pose files and apply the pose to a figure. It works great for .duf files in text format, but I found there also are .duf files in gzipped format. The file extension is the same.
I know gzip format can be detected and files can be opened for reading with gzip.open, but before I spend hours reinventing such a wheel I would like to know if there is a ready-to-call method to let Python handle deal with this transparently so my script can remain simple.
The .duf file content is of course read via json.load().