Integrating up through commit 90f050496
This commit is contained in:
+407
@@ -0,0 +1,407 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# this has to be at the beginning
|
||||
from __future__ import division
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# pathnode.py
|
||||
# simple path objecy based Node Class, for tool creation.
|
||||
# version: 0.1
|
||||
# author: Gallowj
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
"""
|
||||
Module docstring:
|
||||
A simple path objecy based Node Class, for creating path hierarchies.
|
||||
"""
|
||||
__author__ = 'HogJonny'
|
||||
|
||||
_G_DEBUG = True # global state for debugging
|
||||
_G_SETTINGS = None # global Settings storage
|
||||
_G_LOG = None # global LOGger storage
|
||||
|
||||
_G_MASTER_NODE = None # We intend to init a master node
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# built-ins
|
||||
import os
|
||||
import copy
|
||||
import subprocess
|
||||
import traceback
|
||||
import string
|
||||
import logging
|
||||
from unipath import Path, AbstractPath
|
||||
|
||||
# local ly imports
|
||||
from LyPy.si_shared.noodly.helpers import istext
|
||||
from LyPy.si_shared.noodly.find_arg import find_arg
|
||||
from LyPy.si_shared.noodly.synth import synthesize
|
||||
from LyPy.si_shared.noodly.node import Node
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Use unicode strings
|
||||
_base = str # Python 3 str (=unicode), or Python 2 bytes.
|
||||
if os.path.supports_unicode_filenames:
|
||||
try:
|
||||
_base = unicode # Python 2 unicode.
|
||||
except NameError:
|
||||
pass
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# set up logger
|
||||
_G_LOGGER = logging.getLogger(__name__)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PathNode(Node):
|
||||
"""doc string"""
|
||||
|
||||
# share the debug state
|
||||
_DEBUG = _G_DEBUG
|
||||
|
||||
# logger
|
||||
_LOGGER = _G_LOGGER
|
||||
|
||||
# class header
|
||||
_message_header = 'noodly, PathNode(): Message'
|
||||
|
||||
# App Launcher paths...
|
||||
try:
|
||||
_maya_exe_path = Path(os.environ['MAYAPY'])
|
||||
except:
|
||||
_maya_exe_path = Path(r"C:\Program Files\Autodesk\Maya2019\bin\maya.exe")
|
||||
try:
|
||||
_notepad_exe_path = Path(os.environ['DEFAULT_TXT_EXE'])
|
||||
except:
|
||||
_notepad_exe_path = Path(r"C:\Program Files (x86)\Notepad++\notepad++.exe")
|
||||
|
||||
# --BASE-METHODS-------------------------------------------------------
|
||||
def __new__(cls, path="", root_path=None, *args, **kwargs):
|
||||
'''docstring'''
|
||||
# if not isinstance(path, str) and not isinstance(path, Path):
|
||||
# raise TypeError("{0}, {1}: Accepts paths as str or Path() types!\r"
|
||||
# "Input data is:{2}\r"
|
||||
# "".format('noodly, PathNode',
|
||||
# 'PathNode(filename)', type(path)))
|
||||
#
|
||||
self = super(PathNode, cls).__new__(cls)
|
||||
return self
|
||||
|
||||
# --constructor--------------------------------------------------------
|
||||
def __init__(self, path="", root_path=None, parent_is_root=None,
|
||||
name_is_path=None, *args, **kwargs):
|
||||
|
||||
self._logger = Node._LOGGER
|
||||
|
||||
self._node_type = self.__class__.__name__
|
||||
|
||||
# a dict to store properties/attrs
|
||||
# in the event an object is re-built / re-init
|
||||
# it is important to store anything here that needs retention
|
||||
self._kwargs_dict = {}
|
||||
|
||||
# -- secret keyword -----------------------------------------------
|
||||
self._temp_node = False
|
||||
temp_node, kwargs = find_arg(argPosIndex=None, argTag='temp_node',
|
||||
removeKwarg=True, inArgs=args,
|
||||
inKwargs=kwargs) # <-- kwarg only
|
||||
|
||||
self._temp_node = temp_node
|
||||
if self._temp_node:
|
||||
self.k_wargs_dict['temp_node'] = self._temp_node
|
||||
|
||||
# -- Node class args/kwargs ---------------------------------------
|
||||
node_name, kwargs = find_arg(argPosIndex=2, argTag='node_name',
|
||||
removeKwarg=True, inArgs=args,
|
||||
inKwargs=kwargs) # <-- third arg, kwarg
|
||||
|
||||
parent_node, kwargs = find_arg(argPosIndex=3, argTag='parent_node',
|
||||
removeKwarg=True, inArgs=args,
|
||||
inKwargs=kwargs) # <-- fourth arg, kwarg
|
||||
|
||||
self._root_path = root_path
|
||||
|
||||
self._parent_is_root = parent_is_root
|
||||
if self._parent_is_root != None:
|
||||
self._kwargs_dict['parent_is_root'] = self.parent_is_root
|
||||
|
||||
if parent_is_root: # <-- do it
|
||||
self._root_path = parent_node
|
||||
|
||||
# make sure the path is a Path
|
||||
self._path = path
|
||||
if not isinstance(self._path, Path):
|
||||
try:
|
||||
self._path = Path(path)
|
||||
except:
|
||||
self._path = Path() # empty path object fallback
|
||||
|
||||
self._name_is_path = name_is_path
|
||||
if self._name_is_path:
|
||||
self._kwargs_dict['name_is_path'] = self._name_is_path
|
||||
|
||||
# this might only work if the file actually exists
|
||||
self._node_name = node_name
|
||||
if self._name_is_path:
|
||||
if self._path.name != None or self._path.name != '':
|
||||
self._node_name = str(self._path.name)
|
||||
|
||||
# Path.__init__(self)
|
||||
super(PathNode, self).__init__(self._node_name, parent_node,
|
||||
temp_node=temp_node,
|
||||
*args, **kwargs)
|
||||
|
||||
# -- properties -------------------------------------------------------
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
@path.setter
|
||||
def path(self, path):
|
||||
self._path = path
|
||||
return self._path
|
||||
|
||||
@path.getter
|
||||
def path(self):
|
||||
return self._path
|
||||
|
||||
@property
|
||||
def root_path(self):
|
||||
return self._root_path
|
||||
|
||||
@root_path.setter
|
||||
def root_path(self, root_path):
|
||||
self._root_path = root_path
|
||||
return self._root_path
|
||||
|
||||
@root_path.getter
|
||||
def root_path(self):
|
||||
return self._root_path
|
||||
|
||||
@property
|
||||
def parent_is_root(self):
|
||||
return self._parent_is_root
|
||||
|
||||
@parent_is_root.setter
|
||||
def parent_is_root(self, parent_is_root):
|
||||
self._parent_is_root = parent_is_root
|
||||
return self._parent_is_root
|
||||
|
||||
@parent_is_root.getter
|
||||
def parent_is_root(self):
|
||||
return self._parent_is_root
|
||||
|
||||
@property
|
||||
def name_is_path(self):
|
||||
return self._name_is_path
|
||||
|
||||
# @name_is_path.setter
|
||||
# def name_is_path(self, name_is_path):
|
||||
# self._name_is_path = name_is_path
|
||||
# return self._name_is_path
|
||||
|
||||
@name_is_path.getter
|
||||
def name_is_path(self):
|
||||
return self._name_is_path
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def set_file_path(self, path):
|
||||
if not isinstance(path, Path):
|
||||
try:
|
||||
path = Path(path)
|
||||
except:
|
||||
raise TypeError("must be Path compatible")
|
||||
|
||||
# retreive a copy of the old _kwargs dict
|
||||
_kwargs_dict_copy = copy.copy(self._kwargs_dict)
|
||||
_name_is_uni_hashid = copy.copy(self.name_is_uni_hashid)
|
||||
|
||||
# create a new me (self), with new value
|
||||
# attempt to keep existing attrs/settings
|
||||
self = PathNode(path=path,
|
||||
root_path=self.root_path,
|
||||
parent_is_root=self.parent_is_root,
|
||||
name_is_path=self.name_is_path,
|
||||
temp_node=self.temp_node,
|
||||
node_name=self.node_name,
|
||||
parent_node=self.parent_node,
|
||||
name_is_uni_hashid=self.name_is_uni_hashid)
|
||||
|
||||
# now we need to restore any custom properties on the replacement object
|
||||
for key, value in _kwargs_dict_copy.items():
|
||||
self._kwargs_dict[key] = value
|
||||
try:
|
||||
synthesize(self, '{0}'.format(key), value)
|
||||
except:
|
||||
code = compile('self._{0} = {1}'.format(key, value), 'synthProp', 'exec')
|
||||
if Node._DEBUG:
|
||||
self.logger.error('can not set: self._{0} = {1}'.format(key, value))
|
||||
|
||||
# replace myself in the class nodeDict, based on my unihashid
|
||||
self.cls_node_dict[self.uni_hashid] = self
|
||||
|
||||
# return the new version of myself
|
||||
return self.cls_node_dict[self.uni_hashid]
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def start_file(self, filepath=None):
|
||||
'''opens the file in the prefered os editor for the filetype'''
|
||||
if filepath == None:
|
||||
filepath = self.path
|
||||
|
||||
if not isinstance(filepath, Path): # <-any subclass of Path works?
|
||||
filepath = Path(filepath)
|
||||
|
||||
self.logger.debug('starting file: {0}'.format(filepath))
|
||||
try:
|
||||
os.startfile(filepath)
|
||||
except IOError as e:
|
||||
self.logger.error(e)
|
||||
|
||||
return filepath
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def explore_file(self, filepath=None):
|
||||
if filepath == None:
|
||||
filepath = self.path
|
||||
|
||||
if not isinstance(filepath, Path):
|
||||
filepath = Path(filepath)
|
||||
|
||||
self.logger.debug('exploring file: {0}'.format(filepath))
|
||||
if filepath.exists():
|
||||
try:
|
||||
subprocess.Popen(r'explorer /select,"{0}"'.format(filepath))
|
||||
except IOError as e:
|
||||
self.logger.error(e)
|
||||
else:
|
||||
self.logger.error('file does not exist: {0}'.format(filepath))
|
||||
|
||||
return filepath
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def hierarchy(self, tabLevel=-1):
|
||||
|
||||
output = ''
|
||||
if isinstance(self, RootNode):
|
||||
if gDebug:
|
||||
func = inspect.currentframe().f_back.f_code
|
||||
output += ('{0}Called from:\n'
|
||||
'{0}{1}\n'.format('\t' * (tabLevel + 1), func))
|
||||
|
||||
tabLevel += 1
|
||||
|
||||
for i in range(tabLevel):
|
||||
output += '\t'
|
||||
|
||||
output += ('{tab}/------ nodeName:: "{0}"\n'
|
||||
'{1} |typeInfo:: {2}\n'
|
||||
'{1} |_uniHashid:: "{3}"\r'
|
||||
'{1} |path:: "{4}"\n'
|
||||
'{1} |get_root():: "{5}"\n'
|
||||
'{1} |getPathFromRoot():: "{6}"\n'
|
||||
''.format(self.getNodeName(),
|
||||
'\t' * tabLevel,
|
||||
self.get_typeInfo(),
|
||||
self.get_uniHashid(),
|
||||
self,
|
||||
self.get_root(),
|
||||
self.getPathFromRoot(),
|
||||
tab=tabLevel))
|
||||
|
||||
for child in self._children:
|
||||
output += child.hierarchy(tabLevel)
|
||||
|
||||
tabLevel -= 1
|
||||
|
||||
return output
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --Class End--------------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# tests(), code block for testing module
|
||||
# -------------------------------------------------------------------------
|
||||
def tests():
|
||||
from node import Node
|
||||
default_node = Node() # result: Node(node_name='MASTER')
|
||||
print(default_node)
|
||||
|
||||
first_child = PathNode(path=None, node_name='first_child', parent_node=default_node)
|
||||
print(first_child)
|
||||
# result: PathNode(temp_node=True, parent_node=Node(node_name='MASTER')).siblingNodeFromHashid('WNPZoKBVpXV16QLz')
|
||||
# first_child.nodeType
|
||||
# first_child.parent_node
|
||||
# first_child.node_name
|
||||
|
||||
try:
|
||||
# PathNode requires a arg 'path' input (should be a path str)
|
||||
fubar_path_node = PathNode() # <-- this should fail
|
||||
print (fubar_path_node)
|
||||
except Exception as err:
|
||||
print ('\r{0}'.format(err))
|
||||
print (traceback.format_exc())
|
||||
|
||||
foo = PathNode(r'\foo\fooey\kablooey', node_name='foo',
|
||||
parent_node=default_node)
|
||||
print(foo)
|
||||
|
||||
testes = Path(r'/foo/fooey/kablooey')
|
||||
|
||||
print(foo.path.exists())
|
||||
print(foo.path.parent)
|
||||
print(foo.path.norm_case())
|
||||
print(foo.path.absolute())
|
||||
|
||||
fooey = PathNode(None, parent_node=foo)
|
||||
print(fooey)
|
||||
|
||||
kablooey = PathNode(r'\foo\fooey\kablooey',
|
||||
parent_node=default_node,
|
||||
name_is_path=True)
|
||||
print(kablooey)
|
||||
|
||||
kablooey = kablooey.set_file_path(r'c:\mytemp\fubar.txt')
|
||||
print(kablooey)
|
||||
kablooey.start_file()
|
||||
kablooey.explore_file()
|
||||
|
||||
return
|
||||
# - END, tests() ----------------------------------------------------------
|
||||
|
||||
|
||||
def main():
|
||||
pass
|
||||
return
|
||||
# - END, main() -----------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# --call block-------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
print ("# ----------------------------------------------------------------------- #")
|
||||
print ('~ noodly.PathNode ... Running script as __main__')
|
||||
print ("# ----------------------------------------------------------------------- #\r")
|
||||
|
||||
# run simple tests
|
||||
tests()
|
||||
Reference in New Issue
Block a user