Integrating up through commit 90f050496
This commit is contained in:
+44
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# The __init__.py files help guide import statements without automatically
|
||||
# importing all of the modules
|
||||
"""azpy.shared.ui.__init__"""
|
||||
|
||||
import os
|
||||
import logging
|
||||
import logging.config
|
||||
|
||||
# global space debug flag
|
||||
_G_DEBUG = os.getenv('DCCSI_GDEBUG', False)
|
||||
|
||||
# global space debug flag
|
||||
_DCCSI_DEV_MODE = os.getenv('DCCSI_DEV_MODE', False)
|
||||
|
||||
if _DCCSI_DEV_MODE:
|
||||
_PACKAGENAME = __name__
|
||||
if _PACKAGENAME is '__main__':
|
||||
_PACKAGENAME = 'noodely'
|
||||
|
||||
_PKG_PARENT_PATH = str('azpy.shared')
|
||||
_PKG_PATH = str('{0}.{1}'.format(_PKG_PARENT_PATH, _PACKAGENAME))
|
||||
_LOGGER = logging.getLogger(_PACKAGENAME)
|
||||
_LOGGER.debug('Invoking __init__.py for {0}.'.format({_PKG_PATH}))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
#
|
||||
__all__ = ['config', 'find_arg', 'master', 'node', 'synth',
|
||||
'synth_arg_kwarg', 'test_foo']
|
||||
#
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
del _LOGGER
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# find_arg.py
|
||||
# A simple function for arg, kwarg retrieval
|
||||
# version: 0.1
|
||||
# maintenance: Gallowj
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
"""Module docstring: A simple function for retrieval of arg, kwarg"""
|
||||
__author__ = 'HogJonny'
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def find_arg(argPosIndex=None, argTag=None, removeKwarg=None,
|
||||
inArgs=None, inKwargs=None, defaultValue=None):
|
||||
"""
|
||||
# finds and returns an arg...
|
||||
# if a positional index is given argPosIndex=0, it checks args first
|
||||
# if a argTag is given, it checks kwargs
|
||||
# If removeKwarg=True, it will remove the found arg from kwargs
|
||||
# * I actually want/need to do this often
|
||||
#
|
||||
# a set kwarg will ALWAYS take precident over
|
||||
# positional arg!!!
|
||||
#
|
||||
# return outArg, args, kwargs <-- get back modified kwargs!
|
||||
#
|
||||
# proper usage:
|
||||
#
|
||||
# foundArg, args, kwargs = find_arg(0, 'name',)
|
||||
"""
|
||||
if argPosIndex != None:
|
||||
if not isinstance(argPosIndex, int):
|
||||
raise TypeError('argPosIndex: accepts a index integer!\r'
|
||||
'got: {0}'.format(argPosIndex))
|
||||
|
||||
# positional args ... check the position
|
||||
if len(inArgs) > 0:
|
||||
try:
|
||||
foundArg = inArgs[argPosIndex]
|
||||
except:
|
||||
pass
|
||||
|
||||
# check kwargs ... a set kwarg will ALWAYS take precident over
|
||||
# positional arg!!!
|
||||
try:
|
||||
foundArg
|
||||
except:
|
||||
foundArg = inKwargs.get(argTag, defaultValue) # defaults to None
|
||||
|
||||
if removeKwarg:
|
||||
if argTag in inKwargs:
|
||||
del inKwargs[argTag]
|
||||
|
||||
# if we didn't find the arg/kwarg, the defualt return will be None
|
||||
return foundArg, inKwargs
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# --call block-------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
print ("# ----------------------------------------------------------------------- #\r")
|
||||
print ('~ find_arg.py ... Running script as __main__')
|
||||
print ("# ----------------------------------------------------------------------- #\r")
|
||||
|
||||
_G_DEBUG = True
|
||||
|
||||
from test_foo import Foo
|
||||
|
||||
#######################################################################
|
||||
# Node Class
|
||||
# ---------------------------------------------------------------------
|
||||
class TestNode(Foo):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__()
|
||||
self._name, kwargs = find_arg(argTag='foo', removeKwarg=True,
|
||||
inArgs=args, inKwargs=kwargs)
|
||||
self._name, kwargs = find_arg(argPosIndex=0, argTag='name',
|
||||
removeKwarg=True,
|
||||
inArgs=args, inKwargs=kwargs) # <-- first positional OR kwarg
|
||||
self._parent, kwargs = find_arg(argPosIndex=1, argTag='parent',
|
||||
removeKwarg=True,
|
||||
inArgs=args, inKwargs=kwargs) # <-- second positional OR kwarg
|
||||
|
||||
self._kwargsDict = {}
|
||||
|
||||
# arbitrary argument properties
|
||||
# checking **kwargs, any kwargs left
|
||||
# will be used to synthesize a property
|
||||
for key, value in kwargs.items():
|
||||
self._kwargsDict[key] = value
|
||||
# synthesize(self, '{0}'.format(key), value) <-- I have a method,
|
||||
# which synthesizes properties... with gettr, settr, etc.
|
||||
if _G_DEBUG:
|
||||
print("{0}:{1}".format(key, value))
|
||||
|
||||
# representation
|
||||
def __repr__(self):
|
||||
return '{0}({1})\r'.format(self.__class__.__name__, self.__dict__)
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
testNode = TestNode('foo')
|
||||
|
||||
testNode2 = TestNode(name='fooey', parent=testNode)
|
||||
|
||||
testNode3 = TestNode('kablooey', testNode2, goober='dufus')
|
||||
|
||||
print ('testNode2, name: {0}, parent: {1}'.format(testNode2._name, testNode2._parent))
|
||||
print (testNode3)
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
###########################################################################
|
||||
# HELPER method functions
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def istext(filename):
|
||||
"""
|
||||
A guess if a file is text or binary
|
||||
"""
|
||||
s = open(filename).read(512)
|
||||
text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b"))
|
||||
_null_trans = string.maketrans("", "")
|
||||
if not s:
|
||||
# Empty files are considered text
|
||||
return True
|
||||
if "\0" in s:
|
||||
# Files with null bytes are likely binary
|
||||
return False
|
||||
# Get the non-text characters (maps a character to itself then
|
||||
# use the 'remove' option to get rid of the text characters.)
|
||||
t = s.translate(_null_trans, text_characters)
|
||||
# If more than 30% non-text characters, then
|
||||
# this is considered a binary file
|
||||
if float(len(t)) / float(len(s)) > 0.30:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def display_cached_value(cache, cache_key):
|
||||
try:
|
||||
cached_value = cache[cache_key]
|
||||
print("{0}={1}".format(cache_key, cached_value))
|
||||
except KeyError:
|
||||
print("{0}=Not in cache".format(cache_key))
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# master.py
|
||||
# Allows for project based setup to be used with noodly
|
||||
# version: 0.1
|
||||
# author: Gallowj
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
import os
|
||||
|
||||
from unipath import Path
|
||||
|
||||
_G_DEFAULT_PROJECT_DIR = os.getcwd()
|
||||
_G_MASTER_ROOT_NODE = None
|
||||
|
||||
|
||||
@property
|
||||
def _G_DEFAULT_PROJECT_DIR(value):
|
||||
_G_DEFAULT_PROJECT_DIR = value
|
||||
return _G_DEFAULT_PROJECT_DIR
|
||||
|
||||
|
||||
def set_PROJECT_DIR(value):
|
||||
"""Sets and returns _G_DEFAULT_PROJECT_DIR"""
|
||||
global _G_DEFAULT_PROJECT_DIR
|
||||
_G_DEFAULT_PROJECT_DIR = Path(value).expand()
|
||||
return Path(_G_DEFAULT_PROJECT_DIR)
|
||||
|
||||
|
||||
@property
|
||||
def _G_MASTER_ROOT_NODE(value):
|
||||
_G_MASTER_ROOT_NODE = value
|
||||
return _G_MASTER_ROOT_NODE
|
||||
|
||||
|
||||
def set_MASTER_ROOT_NODE(value):
|
||||
"""Sets and returns _G_MASTER_ROOT_NODE"""
|
||||
global _G_MASTER_ROOT_NODE
|
||||
if not isinstance(inNode, ProjectRootNode):
|
||||
raise TypeError('self._projectRootNode is: {0}\r'
|
||||
'A _projectRootNode, needs to be properly set\r'
|
||||
'So that we can acces:\r'
|
||||
'\tself._projectRootNode._sourceRoot\r'
|
||||
'\tself._projectRootNode._overrideRoot\r'
|
||||
'Use self.assignProjectRootNode(<projectRootNode>)\r'
|
||||
''.format(type(inNode)))
|
||||
|
||||
_G_MASTER_ROOT_NODE = inNode
|
||||
return _G_MASTER_ROOT_NODE
|
||||
|
||||
|
||||
###########################################################################
|
||||
# tests(), code block for testing module
|
||||
# -------------------------------------------------------------------------
|
||||
def tests():
|
||||
set_PROJECT_DIR(os.getcwd())
|
||||
print(_G_DEFAULT_PROJECT_DIR)
|
||||
print(_G_DEFAULT_PROJECT_DIR.parent)
|
||||
print(_G_DEFAULT_PROJECT_DIR.components())
|
||||
|
||||
# NOT implemented yet
|
||||
# set_PROJECT_DIR
|
||||
|
||||
return
|
||||
|
||||
|
||||
###########################################################################
|
||||
# --call block-------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
print ("# ----------------------------------------------------------------------- #")
|
||||
print ('~ noodly.master ... Running script as __main__')
|
||||
print ("# ----------------------------------------------------------------------- #\r")
|
||||
|
||||
# run simple tests
|
||||
tests()
|
||||
|
||||
#_G_DEFAULT_PROJECT_DIR = Path(os.getcwd())
|
||||
print(_G_DEFAULT_PROJECT_DIR.components())
|
||||
+623
@@ -0,0 +1,623 @@
|
||||
"""
|
||||
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
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
# node.py
|
||||
# simple base Node Class, for tool creation.
|
||||
# version: 0.1
|
||||
# author: Gallowj
|
||||
# -------------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------------
|
||||
"""
|
||||
Module docstring:
|
||||
A Simple Node Base Class Module, for creating basic nodes within a hierarchy.
|
||||
"""
|
||||
|
||||
__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, unless provided
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# built-ins
|
||||
import os
|
||||
import copy
|
||||
import traceback
|
||||
import string
|
||||
import logging
|
||||
|
||||
# using hashids to generate unique name identifiers for nodes
|
||||
import hashids
|
||||
import cachetools
|
||||
from sched import scheduler
|
||||
|
||||
# local imports
|
||||
from LyPy.si_shared.noodly.helpers import display_cached_value
|
||||
from LyPy.si_shared.noodly.find_arg import find_arg
|
||||
from LyPy.si_shared.noodly.synth import synthesize
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# quick test code (remove later)
|
||||
from hashids import Hashids
|
||||
hashids = Hashids(min_length=16, salt='DCCsi')
|
||||
if _G_DEBUG:
|
||||
print (hashids.encrypt(193487)) # test hash
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# set up logger
|
||||
_G_LOGGER = logging.getLogger(__name__)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# 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
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
###########################################################################
|
||||
# HELPER method functions
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def return_node_from_hashid(hashid):
|
||||
if not isinstance(hashid, str):
|
||||
raise TypeError("{0},{1}: Accepts hashids as str types!\r"
|
||||
"Input hashid:{2}\r"
|
||||
"".format('noodly',
|
||||
'return_node_from_hashid(hashid)',
|
||||
type(hashid)))
|
||||
|
||||
temp_node = Node(temp_node=True).get_sibling_node_from_hashid('{0}'.format(hashid))
|
||||
|
||||
return temp_node
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
class Node(object):
|
||||
"""Class constructor: makes a node."""
|
||||
|
||||
# share the debug state
|
||||
_DEBUG = _G_DEBUG
|
||||
|
||||
# logger
|
||||
_LOGGER = _G_LOGGER
|
||||
|
||||
# class header
|
||||
message_header = 'noodly, Node(): Message'
|
||||
|
||||
# class variable
|
||||
_cls_node_count = 0
|
||||
_cls_node_list = []
|
||||
_cls_node_dict = {}
|
||||
|
||||
# --BASE-METHODS-------------------------------------------------------
|
||||
# --constructor-
|
||||
def __init__(self, node_name=None, parent_node=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 = {}
|
||||
self._children = []
|
||||
|
||||
# private local access to the cls_node_list
|
||||
self._cls_node_list = Node._cls_node_list
|
||||
|
||||
# -- 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._kwargs_dict['temp_node'] = self._temp_node
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# -- store message header -----------------------------------------
|
||||
# setup the .message_header <-- kwarg only
|
||||
message_header, kwargs = find_arg(argPosIndex=None, argTag='message_header',
|
||||
removeKwarg=True, inArgs=args, inKwargs=kwargs,
|
||||
defaultValue=('{0}(), Message'
|
||||
.format(self._node_type)))
|
||||
self._message_header = message_header
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# -- hashid -------------------------------------------------------
|
||||
self._name_is_uni_hashid = False
|
||||
self._node_class_index = len(Node._cls_node_list)
|
||||
if Node._DEBUG:
|
||||
print ('__init__.node_class_index: {0}'.format(self._node_class_index))
|
||||
self._uni_hashid = hashids.encrypt(self._node_class_index)
|
||||
if Node._DEBUG:
|
||||
print ('__init__.uni_hashid: {0}'.format(self._uni_hashid))
|
||||
|
||||
# update class dict
|
||||
if not self._temp_node:
|
||||
Node._cls_node_dict[self._uni_hashid] = self
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# -- store the node name ------------------------------------------
|
||||
self._node_name = node_name
|
||||
if (self._node_class_index == 0 and self._node_name == None):
|
||||
self._node_name = 'MASTER'
|
||||
elif (self._node_class_index > 0 and self._node_name == None):
|
||||
# set a default node_name if none, based on the unihashid
|
||||
if not self._name_is_uni_hashid:
|
||||
self._node_name = self._uni_hashid
|
||||
self._name_is_uni_hashid = True
|
||||
if Node._DEBUG:
|
||||
print ('__init__.node_name: {0}'.format(self._node_name))
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# -- node parent_node --------------------------------------------------
|
||||
# set up the parent_node property
|
||||
self._parent_node = parent_node
|
||||
|
||||
if self._parent_node != None:
|
||||
# add this node, to the parent_nodes list of children
|
||||
try:
|
||||
self._parent_node.add_child(self)
|
||||
except:
|
||||
pass # <-- parent_node object passed is NOT a noodly.node?
|
||||
|
||||
# Update class variables
|
||||
Node.cls_node_count_up(self)
|
||||
Node.cls_node_list_append(self)
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# arbitrary argument properties
|
||||
# check postions *args and **kwargs
|
||||
# any kwargs left will be used to synthesize a property
|
||||
try:
|
||||
# checking import due to the way the code is structured
|
||||
# the code was passing even if module was not imported
|
||||
synthesize
|
||||
synthExists = True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise e
|
||||
|
||||
for key, value in kwargs.items():
|
||||
self._kwargs_dict[key] = value
|
||||
try:
|
||||
synthesize(self, key, value)
|
||||
except Exception as e: # <-- maybe it can't synthesize?
|
||||
# in which case fall back to setting the property
|
||||
print(e)
|
||||
code = compile(r'self._{0}={1}'.format(key, value), 'synthProp', 'exec')
|
||||
pass
|
||||
if Node._DEBUG:
|
||||
print("{0}:{1}".format(key, value))
|
||||
# -----------------------------------------------------------------
|
||||
|
||||
# if temp node, adjust the class counter
|
||||
if temp_node:
|
||||
self.cls_node_count_down()
|
||||
self.cls_node_list_remove()
|
||||
|
||||
# -- properties ------------------------------------------------------------
|
||||
@property
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@logger.setter
|
||||
def logger(self, logger):
|
||||
self._logger = logger
|
||||
return self._logger
|
||||
|
||||
@logger.getter
|
||||
def logger(self):
|
||||
return self._logger
|
||||
|
||||
@property
|
||||
def kwargs_dict(self):
|
||||
return self._kwargs_dict
|
||||
|
||||
@kwargs_dict.getter
|
||||
def kwargs_dict(self):
|
||||
return self._kwargs_dict
|
||||
|
||||
@property
|
||||
def message_header(self):
|
||||
return self._message_header
|
||||
|
||||
@message_header.setter
|
||||
def message_header(self, message_header):
|
||||
self._message_header = message_header
|
||||
return self._message_header
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
return self._node_type
|
||||
|
||||
@node_type.setter
|
||||
def node_type(self, node_type):
|
||||
self._node_type = node_type
|
||||
return self._node_type
|
||||
|
||||
@node_type.getter
|
||||
def node_type(self):
|
||||
return self._node_type
|
||||
|
||||
@property
|
||||
def temp_node(self):
|
||||
return self._temp_node
|
||||
|
||||
@temp_node.setter
|
||||
def temp_node(self, temp_node):
|
||||
self._temp_node = temp_node
|
||||
return self._temp_node
|
||||
|
||||
@temp_node.getter
|
||||
def temp_node(self):
|
||||
return self._temp_node
|
||||
|
||||
@property
|
||||
def node_name(self):
|
||||
return self._node_name
|
||||
|
||||
@node_name.setter
|
||||
def node_name(self, nameStr):
|
||||
if nameStr != None:
|
||||
if not isinstance(nameStr, str):
|
||||
raise TypeError("{0}, {1}: Accepts str types!"
|
||||
"".format(self.__class__.__name__,
|
||||
self._node_name.__name__))
|
||||
try:
|
||||
self._node_name = nameStr
|
||||
except:
|
||||
synthesize(self, '_node_name', None)
|
||||
|
||||
return self._node_name
|
||||
|
||||
@node_name.getter
|
||||
def node_name(self):
|
||||
return self._node_name
|
||||
|
||||
@property
|
||||
def name_is_uni_hashid(self):
|
||||
return self._name_is_uni_hashid
|
||||
|
||||
@node_type.setter
|
||||
def name_is_uni_hashid(self, value):
|
||||
self._name_is_uni_hashid = value
|
||||
return self._name_is_uni_hashid
|
||||
|
||||
@node_type.getter
|
||||
def name_is_uni_hashid(self):
|
||||
return self._name_is_uni_hashid
|
||||
|
||||
@property
|
||||
def node_class_index(self):
|
||||
return self._node_class_index
|
||||
|
||||
@property
|
||||
def uni_hashid(self):
|
||||
return self._uni_hashid
|
||||
|
||||
@property
|
||||
def cls_node_dict(self):
|
||||
return Node._cls_node_dict
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
# --method-set---------------------------------------------------------
|
||||
def cls_node_count_up(self):
|
||||
Node._cls_node_count += 1
|
||||
return Node._cls_node_count
|
||||
|
||||
def cls_node_count_down(self):
|
||||
Node._cls_node_count -= 1
|
||||
return Node._cls_node_count
|
||||
|
||||
def cls_node_list_append(self):
|
||||
Node._cls_node_list.append(self)
|
||||
return Node._cls_node_list
|
||||
|
||||
def cls_node_list_remove(self):
|
||||
Node._cls_node_list.remove(self)
|
||||
return Node._cls_node_list
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-set---------------------------------------------------------
|
||||
@property
|
||||
def parent_node(self):
|
||||
return self._parent_node
|
||||
|
||||
@parent_node.setter
|
||||
def parent_node(self, parent_node):
|
||||
self._parent_node = parent_node
|
||||
return self._parent_node
|
||||
|
||||
@parent_node.getter
|
||||
def parent_node(self):
|
||||
return self._parent_node
|
||||
|
||||
def add_child(self, child):
|
||||
self._children.append(child)
|
||||
|
||||
# --method--
|
||||
def remove_child(self, child):
|
||||
self._children.remove(child)
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
return self._children
|
||||
|
||||
def child(self, row):
|
||||
return self._children[row]
|
||||
|
||||
def child_count(self):
|
||||
return len(self._children)
|
||||
|
||||
def row(self):
|
||||
if self._parent_node != None:
|
||||
return self._parent_node._children.index(self)
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def get_sibling_node_from_hashid(self, hashid):
|
||||
if not isinstance(hashid, str):
|
||||
raise TypeError("{0}.{1}: Accepts hashids as str types!"
|
||||
"".format(self.__class__.__name__,
|
||||
'get_sibling_node_from_hashid(hashid)'))
|
||||
|
||||
if hashid in self.cls_node_dict.keys():
|
||||
return self.cls_node_dict[hashid]
|
||||
else:
|
||||
return None
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def clear_node_dep(self):
|
||||
self.clear_children
|
||||
self.clear_node_list()
|
||||
self.clear_node_count()
|
||||
return self
|
||||
|
||||
def clear_node_list(self):
|
||||
Node._cls_node_list = []
|
||||
return Node._cls_node_list
|
||||
|
||||
def clear_node_count(self):
|
||||
Node._cls_node_count = 0
|
||||
return Node._cls_node_count
|
||||
|
||||
def clear_children(self):
|
||||
self._children = []
|
||||
return self._children
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
@cachetools.cached(cachetools.LFUCache(maxsize=2048))
|
||||
def cache_node(self):
|
||||
return self
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
def hierarchy(self, tab_level=-1):
|
||||
|
||||
output = ''
|
||||
tab_level += 1
|
||||
|
||||
for i in range(tab_level):
|
||||
output += '\t'
|
||||
|
||||
output += ('{tab}/------node_name:: "{0}"\n'
|
||||
'{1} |type:: {2}\n'
|
||||
'{1} |_uni_hashid:: "{3}"\r'
|
||||
''.format(self._node_name,
|
||||
'\t' * tab_level,
|
||||
self._node_type,
|
||||
self._uni_hashid,
|
||||
tab=tab_level))
|
||||
|
||||
# TO DO:: object hierarchy "'hips'|'rightLeg'|'etc'"
|
||||
|
||||
for child in self._children:
|
||||
output += child.hierarchy(tab_level)
|
||||
|
||||
tab_level -= 1
|
||||
# output += '\n'
|
||||
|
||||
return output
|
||||
|
||||
def log_hierarchy(self):
|
||||
# Not implemented
|
||||
self._logger.autolog(self.hierarchy(),
|
||||
"return_node_from_hashid('{0}').log_hierarchy()"
|
||||
"".format(self._uni_hashid()))
|
||||
return
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
# --method-------------------------------------------------------------
|
||||
# representation
|
||||
def __str__(self):
|
||||
'''Returns a nice string representation of the object.'''
|
||||
|
||||
# TO DO: need to improve this
|
||||
if self.node_name == None or self.name_is_uni_hashid == True:
|
||||
# open parenthesis only
|
||||
output = ("{0}(node_name='{1}'"
|
||||
"".format(self.__class__.__name__,
|
||||
self.uni_hashid))
|
||||
else:
|
||||
output = ("{0}(node_name='{1}'"
|
||||
"".format(self.__class__.__name__,
|
||||
self.node_name))
|
||||
|
||||
if self.parent_node != None:
|
||||
output += (", parent_node=return_node_from_hashid('{0}')"
|
||||
"".format(self.parent_node.uni_hashid))
|
||||
|
||||
if len(self.kwargs_dict) > 0:
|
||||
for key, value in self.kwargs_dict.items():
|
||||
if not isinstance(value, str):
|
||||
output += (", {0}={1}".format(key, value))
|
||||
else: # if a str add the extra quotes
|
||||
output += (", {0}='{1}'".format(key, value))
|
||||
|
||||
# add the close parenthesis
|
||||
output += ')'
|
||||
|
||||
if self.name_is_uni_hashid == True or self.temp_node:
|
||||
output = ("return_node_from_hashid('{0}')"
|
||||
"".format(self.node_name))
|
||||
|
||||
# Node(self, node_name, parent_node=None, path='')
|
||||
return output
|
||||
|
||||
# representation
|
||||
def __repr__(self):
|
||||
return '{0}({1})\r'.format(self.__class__.__name__, self.__dict__)
|
||||
# --Class End--------------------------------------------------------------
|
||||
|
||||
|
||||
class ClassProperty(property):
|
||||
"""Decorator"""
|
||||
|
||||
def __get__(self, cls, owner):
|
||||
return self.fget.__get__(None, owner)()
|
||||
# --Class End--------------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# tests(), code block for testing module
|
||||
# -------------------------------------------------------------------------
|
||||
def tests():
|
||||
default_node = Node()
|
||||
print(str(default_node))
|
||||
print(repr(default_node))
|
||||
print(default_node.uni_hashid)
|
||||
print(default_node.kwargs_dict)
|
||||
print(default_node.message_header)
|
||||
print(default_node.node_name)
|
||||
print(default_node.parent_node)
|
||||
print(default_node.node_class_index)
|
||||
# print(default_node.cls_node_dict)
|
||||
|
||||
# temp_node = Node()
|
||||
temp_node = Node(temp_node=True)
|
||||
print(temp_node)
|
||||
|
||||
test_default_node = Node(temp_node=True).get_sibling_node_from_hashid('kxYLm0XQeXJ7jWaP')
|
||||
print(test_default_node)
|
||||
|
||||
another_test = return_node_from_hashid('kxYLm0XQeXJ7jWaP')
|
||||
print(another_test)
|
||||
|
||||
second_node = Node(node_name='foo', parent_node=default_node)
|
||||
print(str(second_node))
|
||||
print(second_node.uni_hashid)
|
||||
print(second_node.kwargs_dict)
|
||||
print(second_node.message_header)
|
||||
print(second_node.node_name)
|
||||
print(second_node.parent_node.node_name)
|
||||
print(second_node.node_class_index)
|
||||
# print(second_node.cls_node_dict)
|
||||
|
||||
second_child = Node(node_name='fooey', parent_node=another_test)
|
||||
print(str(second_child))
|
||||
print(second_child.uni_hashid)
|
||||
print(second_child.kwargs_dict)
|
||||
print(second_child.message_header)
|
||||
print(second_child.node_name)
|
||||
print(second_child.parent_node.node_name)
|
||||
print(second_child.node_class_index)
|
||||
# print(second_child.cls_node_dict)
|
||||
|
||||
third_node = Node(node_name='kablooey', parent_node=second_node,
|
||||
message_header='Node(): CUSTOM Message')
|
||||
print(str(third_node))
|
||||
print(third_node.uni_hashid)
|
||||
print(third_node.kwargs_dict)
|
||||
print(third_node.message_header)
|
||||
print(third_node.node_name)
|
||||
print(third_node.parent_node.node_name)
|
||||
print(third_node.node_class_index)
|
||||
|
||||
fourth_node = Node(parent_node=second_node,
|
||||
message_header='Node(): CUSTOM Message')
|
||||
print(str(fourth_node))
|
||||
print(fourth_node.uni_hashid)
|
||||
print(fourth_node.kwargs_dict)
|
||||
print(fourth_node.message_header)
|
||||
print(fourth_node.node_name)
|
||||
print(fourth_node.parent_node.node_name)
|
||||
print(fourth_node.node_class_index)
|
||||
|
||||
kwarg_test_child = Node(node_name='kwargChild', parent_node=default_node, garble=1001001) # custom kwarg
|
||||
print(str(kwarg_test_child))
|
||||
print(kwarg_test_child.uni_hashid)
|
||||
print(kwarg_test_child.node_name)
|
||||
print(kwarg_test_child.parent_node.node_name)
|
||||
print(kwarg_test_child.kwargs_dict)
|
||||
# check the custom arg/property garble
|
||||
print(kwarg_test_child.garble)
|
||||
|
||||
# check the node hierarchy
|
||||
print(default_node.hierarchy())
|
||||
|
||||
# retreive a node from it's known hashid
|
||||
master_node = return_node_from_hashid('kxYLm0XQeXJ7jWaP')
|
||||
print(master_node.uni_hashid) # verify hasid
|
||||
# should return the same node as default_node
|
||||
print(master_node.node_name) # should be 'MASTER'
|
||||
return
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def cache_tests():
|
||||
cache = cachetools.LFUCache(maxsize=128)
|
||||
runner = scheduler()
|
||||
cache["HogJonny"] = 1001001
|
||||
runner.enter(2, 1, display_cached_value,
|
||||
kwargs={'cache': cache, 'cache_key': 'HogJonny'})
|
||||
runner.enter(6, 1, display_cached_value,
|
||||
kwargs={'cache': cache, 'cache_key': 'HogJonny'})
|
||||
runner.run()
|
||||
return
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def main():
|
||||
return
|
||||
# - END, main() --
|
||||
|
||||
|
||||
###########################################################################
|
||||
# --call block-------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
print ("# ----------------------------------------------------------------------- #")
|
||||
print ('~ noodly.Node ... Running script as __main__')
|
||||
print ("# ----------------------------------------------------------------------- #\r")
|
||||
|
||||
# run simple tests
|
||||
tests()
|
||||
|
||||
cache_tests()
|
||||
+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()
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# synth.py
|
||||
# Convenience module for a standardized attr interface for classes/objects.
|
||||
# version: 0.1
|
||||
# date: 11/14/2013
|
||||
# author: jGalloway
|
||||
# -------------------------------------------------------------------------
|
||||
__author__ = 'HogJonny'
|
||||
# -------------------------------------------------------------------------
|
||||
"""
|
||||
This module contains the function
|
||||
|
||||
.synthesize(inst, name, value, readonly=False)
|
||||
|
||||
It is useful in object oriented class attributes, providing a stardard
|
||||
interface for creating properties of classes.
|
||||
|
||||
Can be called within an objects Class, or an instance of an object can be
|
||||
passed into the function to have the properties added. The property will
|
||||
be added and set/get/del attr interface will be created.
|
||||
"""
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
def synthesize(inst, name, value, readonly=False):
|
||||
"""
|
||||
Convenience method to create getters, setters and a property for the
|
||||
instance. Should the instance already have the getters or setters
|
||||
defined this won't add them and the property will reference the already
|
||||
defined getters and setters Should be called from within __init__.
|
||||
|
||||
Creates [name], _[name], get[Name], set[Name], del[Name], and on inst.
|
||||
|
||||
:param inst: An instance of the class to add the methods to.
|
||||
:param name: Base name to build function names and storage variable.
|
||||
:param value: Initial state of the created variable.
|
||||
|
||||
"""
|
||||
cls = type(inst)
|
||||
storageName = '_{0}'.format(name)
|
||||
getterName = 'get{0}{1}'.format(name[0].capitalize(), name[1:])
|
||||
setterName = 'set{0}{1}'.format(name[0].capitalize(), name[1:])
|
||||
deleterName = 'del{0}{1}'.format(name[0].capitalize(), name[1:])
|
||||
|
||||
setattr(inst, storageName, value)
|
||||
|
||||
# We always define the getter
|
||||
def buildCustomGetter(self):
|
||||
return getattr(self, storageName)
|
||||
|
||||
# Add the Getter
|
||||
if not hasattr(inst, getterName):
|
||||
setattr(cls, getterName, buildCustomGetter)
|
||||
|
||||
# Handle Read Only
|
||||
if readonly:
|
||||
if not hasattr(inst, name):
|
||||
setattr(cls, name,
|
||||
property(fget=getattr(cls, getterName, None) or buildCustomGetter,
|
||||
fdel=getattr(cls, getterName, None)))
|
||||
else:
|
||||
# We only define the setter if we arn't read only
|
||||
def buildCustomSetter(self, state):
|
||||
setattr(self, storageName, state)
|
||||
if not hasattr(inst, setterName):
|
||||
setattr(cls, setterName, buildCustomSetter)
|
||||
member = None
|
||||
if hasattr(cls, name):
|
||||
# we need to try to update the property fget, fset, fdel
|
||||
# incase the class has defined its own custom functions
|
||||
member = getattr(cls, name)
|
||||
if not isinstance(member, property):
|
||||
raise ValueError('Member "{0}" for class "{1}" exists and is not a property.'
|
||||
''.format(name, cls.__name__))
|
||||
|
||||
# If the class has the property or not we still try to set it
|
||||
setattr(cls, name,
|
||||
property(fget=getattr(member, 'fget', None)
|
||||
or getattr(cls, getterName, None)
|
||||
or buildCustomGetter,
|
||||
fset=getattr(member, 'fset', None)
|
||||
or getattr(cls, setterName, None)
|
||||
or buildCustomSetter,
|
||||
fdel=getattr(member, 'fdel', None)
|
||||
or getattr(cls, getterName, None)))
|
||||
|
||||
return getattr(inst, name)
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# Main Code Block, will run the tool
|
||||
# -------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
"""Self Testing"""
|
||||
|
||||
from test_foo import Foo
|
||||
|
||||
# create an object from Foo Class
|
||||
myFoo = Foo()
|
||||
|
||||
pass
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# synth_arg_kwarg.py
|
||||
# Convenience module for a standardized attr interface for classes/objects.
|
||||
# -------------------------------------------------------------------------
|
||||
__author__ = 'HogJonny'
|
||||
# -------------------------------------------------------------------------
|
||||
from find_arg import find_arg
|
||||
from synth import synthesize
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
|
||||
def setSynthArgKwarg(inst, argPosIndex=None, argTag=None, defaultValue=None,
|
||||
inArgs=None, inKwargs=None, removeKwarg=True,
|
||||
setAnyway=True):
|
||||
"""
|
||||
Uses find_arg and sets a property on a object.
|
||||
|
||||
Special args:
|
||||
setAnyway <-- if the object has the property already, set it
|
||||
|
||||
If the arg/property doesn't exist we synthesize it
|
||||
"""
|
||||
|
||||
foundArg = None
|
||||
argValueDict = {}
|
||||
|
||||
# find the argument, or set to default value
|
||||
foundArg, inKwargs = find_arg(argPosIndex, argTag, removeKwarg,
|
||||
inArgs, inKwargs,
|
||||
defaultValue)
|
||||
|
||||
if foundArg:
|
||||
argTag = foundArg
|
||||
|
||||
# single arg first
|
||||
# make sure the object doesn't arealdy have this property
|
||||
try:
|
||||
hasattr(inst, argTag) # check if property exists
|
||||
if setAnyway:
|
||||
try:
|
||||
setattr(inst, argTag, defaultValue) # try to set
|
||||
except Exception as e:
|
||||
raise e
|
||||
except:
|
||||
pass
|
||||
|
||||
# make it a synthetic property
|
||||
if argTag:
|
||||
try:
|
||||
argValue = synthesize(inst, argTag, defaultValue)
|
||||
argValueDict[argTag] = argValue
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
# multiple and/or remaining kwards next
|
||||
if inKwargs:
|
||||
if len(inKwargs) > 0:
|
||||
for k, v in inKwargs.items():
|
||||
try:
|
||||
hasattr(inst, k) # check if property exists
|
||||
if setAnyway:
|
||||
try:
|
||||
setattr(inst, k, v) # try to set
|
||||
except Exception as e:
|
||||
raise e
|
||||
except:
|
||||
pass
|
||||
|
||||
if k:
|
||||
try:
|
||||
argValue = synthesize(inst, k, v)
|
||||
argValueDict[k] = argValue
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
return argValueDict
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# Main Code Block, will run the tool
|
||||
# -------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
|
||||
from test_foo import Foo
|
||||
|
||||
# define a arg/property tag we know doesn't exist
|
||||
synthArgTag = 'syntheticArg'
|
||||
|
||||
# create a test object
|
||||
print('~ creating the test foo object...')
|
||||
myFoo = Foo()
|
||||
|
||||
print('~ Starting - single synthetic arg test...')
|
||||
# find and set existing, or create and set
|
||||
argValueDict = setSynthArgKwarg(myFoo,
|
||||
argTag=synthArgTag,
|
||||
defaultValue='kablooey')
|
||||
|
||||
# what was returned
|
||||
print('~ single value returned...')
|
||||
for k, v in argValueDict.items():
|
||||
print("Arg '{0}':'{1}'".format(k, v))
|
||||
|
||||
# attempt to access the new synthetic property directly
|
||||
print('~ direct property access test...')
|
||||
try:
|
||||
myFoo.syntheticArg
|
||||
print('myFoo.{0}: {1}'.format(synthArgTag, myFoo.syntheticArg))
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
# can we create a bunch of kwargs?
|
||||
print('~ Starting - multiple synthetic kwarg test...')
|
||||
newKwargs = {'fooey': 'chop suey', 'success': True}
|
||||
|
||||
# find and set existing, or create and set
|
||||
argValueDict = setSynthArgKwarg(myFoo,
|
||||
inKwargs=newKwargs,
|
||||
defaultValue='kablooey')
|
||||
|
||||
# what was returned
|
||||
print('~ multiple values returned...')
|
||||
for k, v in argValueDict.items():
|
||||
print("Arg '{0}':'{1}'".format(k, v))
|
||||
|
||||
print('~ multiple direct property access test...')
|
||||
try:
|
||||
myFoo.fooey
|
||||
print('myFoo.{0}: {1}'.format('fooey', myFoo.fooey))
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
try:
|
||||
myFoo.success
|
||||
print('myFoo.{0}: {1}'.format('success', myFoo.success))
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
print('~ Starting - known failure test...')
|
||||
try:
|
||||
myFoo.knownBad
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print('Test failed as expected!!!')
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# test_foo.py
|
||||
# just a dumb test object
|
||||
# -------------------------------------------------------------------------
|
||||
__author__ = 'HogJonny'
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
from synth import synthesize
|
||||
|
||||
|
||||
class Foo(object):
|
||||
"""
|
||||
This is a Class, it creates a Foo object... which does nothing really
|
||||
"""
|
||||
|
||||
__propertyTag = 'fooProperty'
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
def __init__(self, name='Foo', value='defaultValue', *args, **kwargs):
|
||||
'''Class __init__'''
|
||||
synthesize(self, 'name', name)
|
||||
synthesize(self, Foo.__propertyTag, value)
|
||||
|
||||
synthesize(self, 'test', 'testValue')
|
||||
|
||||
self.testDump = object.__getattribute__(self, 'test')
|
||||
|
||||
# This calls a class method
|
||||
self.methodA()
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
def methodA(self):
|
||||
'''Class synthesized property methods self-tests'''
|
||||
|
||||
"""test getters"""
|
||||
print ('{0}.fooProperty is: {1}'
|
||||
''.format(self.getName(), self.getFooProperty()))
|
||||
|
||||
"""test property retreival"""
|
||||
print ('{0}.testDump is: {1}'
|
||||
''.format(self.name, self.testDump))
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
||||
###########################################################################
|
||||
# Main Code Block, will run the tool
|
||||
# -------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
# create an object from Foo Class
|
||||
myFoo = Foo()
|
||||
Reference in New Issue
Block a user