GRAPHIC: New Entity Operations™ Alpha Logo

EntityScript



build




# -*- coding: utf-8 -*-
"""
COPYRIGHT (C) 2020-2023 NEW ENTITY OPERATIONS INC. ALL RIGHTS RESERVED
INSTANCE: build
MODIFIED: 2023/05/10
OVERVIEW: Run this program with python build.py to assemble the NOVASTORE
data-structure

NOVASTORE will assemble itself based on the inputs provided to the
system-wide instance in TRINE.

When you need to specific endpoints, you can retrieve them from CORE
by retrieving them by a valid key i.e. CoreRetrieve("B03A")

This will also set the progams default build parameters
"""
__version__ = "1.0.0"
__author__ = "New Entity Operations Inc."
__copyright__ = "Copyright (C) 2020-2023 New Entity Operations Inc."
__credits__ = ["New Entity Operations Inc.", "Ryan McKenna"]
__email__ = "Operator@NewEntityOperations.com"
__license__ = "New Entity License"
__maintainer__ = "Ryan McKenna"
__status__ = "Production"

## imports: custom
from MODE.facilities import (ACTIVE_TOKEN, ACTIVE_TOKEN_BUCKET,
 ALREADY_CRAWED_BUCKET, CRAW_BUCKET_NOW, Cure, DictAssemblyLine,
 DictPath, EXHAUSTED_TOKEN, FINAL_BUCKET, FORMATTED_TOKEN_BUCKET,
 glob, IGNORE_BUCKET, NESTED_NODE, oFo, path, Path, PATH_NOW,
 SLUG_BUCKET, SysPath, TOKENIZE_NOW, TokenSlug)
from FILTER.regex import Extractor as eX
from MODE.debug_build import DEBUG_BUILD

## establish the system path
path_project = path.abspath(Cure.muted)
SysPath.insert(0, path_project)

## Instance construction prompt
DEBUG_BUILD.default_node_assembler(NODE_MAIN=path_project)

## local instance assembly hook Add the root path
## Provide a DEFAULT_PATH for the _CRAWER
DEFAULT_PATH_CRAWER = path_project+TokenSlug.glob_location
START_SLUG = TokenSlug.Start_Slug+str(TokenSlug.Start_Number)
FINAL_BUCKET.append(">>>>"+path_project+"<<<"+START_SLUG)

## NodeAssembler
class NodeAssembler:
 """
 Define the node structure for your NOVASTORE instance
 """
 def build(Node=Cure.muted, PathFull=Cure.muted):
  """
  Tokenizers start with <<<, and are in-line
  Root structures start with >>>>
  Sub-directories start with >>>
  Files start with >>
  Transmution-linkers start with <
  Each layer switches between a number and a letter and if need be, will repeat
  """
  COUNTER_FILE = 0
  COUNTER_NESTED_NODE = 0
  COUNTER_ANCHOR = 0
  COUNTER_SUB_NODE = 0
  if Node==Cure.muted:
   DEBUG_BUILD.node_anchor_empty()
  else:
   if PathFull==Cure.muted:
    DEBUG_BUILD.node_location_unavailable()
   else:
    DEBUG_BUILD.building_now(LOCATION=Node)
    NODE_TOKENIZER_BUCKET = []
    structure_node_reader = open("structure.ds", oFo.read)
    for i in structure_node_reader:
     DEBUG_BUILD.node_evaluation(LOCATION=i)
     if i.startswith('>>>>') == True:
      if COUNTER_ANCHOR == 1:
       DEBUG_BUILD.building_failed_duplicate_nodes()
      else:
       DEBUG_BUILD.anchor_set(LOCATION=i)
       COUNTER_ANCHOR = COUNTER_ANCHOR+1
       ROOT_SLUG = eX.FINDER_ROOT.findall(i)
       LOCATION_SLUG = eX.TOKEN_FINDER.findall(i)
       NODE_TOKENIZER_BUCKET.append(
        "Slug:Node-> "+ROOT_SLUG[0]+" : Location "+LOCATION_SLUG[0])
       DictAssemblyLine['node_slug'] = [LOCATION_SLUG[0], ROOT_SLUG[0]]
     elif i.startswith('>>>') == True:
      DEBUG_BUILD.anchor_nested(LOCATION=i)
      COUNTER_SUB_NODE = COUNTER_SUB_NODE+1
      SUB_NODE_SLUG = eX.FINDER_SUB_NODE.findall(i)
      LOCATION_SLUG = eX.TOKEN_FINDER.findall(i)
      NODE_TOKENIZER_BUCKET.append(
       "Slug:Node-> "+SUB_NODE_SLUG[0]+" : Location "+LOCATION_SLUG[0])
      DictAssemblyLine['node_slug'].append([LOCATION_SLUG[0], SUB_NODE_SLUG[0]])
     elif i.startswith('<') == True:
      DEBUG_BUILD.anchor_exhausted(LOCATION=i)
      COUNTER_NESTED_NODE = COUNTER_NESTED_NODE+1
      FINDER_NESTED_NODE_SLUG = eX.FINDER_NESTED_NODE.findall(i)
      FINDER_NESTED_NODE_NAME_SLUG = eX.FINDER_NESTED_NODE_NAME.findall(i)

      LOCATION_SLUG = eX.TOKEN_FINDER.findall(i)
      ## Get the second instance of LOCATION_SLUG
      try:
       NODE_TOKENIZER_BUCKET.append(
        "Slug:Node-> "+FINDER_NESTED_NODE_SLUG[0]+\
         " : Location "+"<<"+LOCATION_SLUG[0])
       DictAssemblyLine['node_slug'].append(
        [LOCATION_SLUG[0], "Belongs to->"+\
         str(FINDER_NESTED_NODE_SLUG[0]), "Name-> "+\
          FINDER_NESTED_NODE_NAME_SLUG[0]])
      except IndexError as e:
       DEBUG_BUILD.error_syntax()

     ## At the bottom so we don't catch any of the other conditions
     elif i.startswith('>>') == True:
      DEBUG_BUILD.endpoint(ENDPOINT=i)
      COUNTER_FILE = COUNTER_FILE+1
      FILE_SLUG = eX.FINDER_FILE.findall(i)
      FILE_NAME_SLUG = eX.FINDER_NESTED_NODE.findall(i)
      LOCATION_SLUG = eX.TOKEN_FINDER.findall(i)
      NODE_TOKENIZER_BUCKET.append(
       "Slug:File-> "+FILE_SLUG[0]+" : Location "+LOCATION_SLUG[0])
      DictAssemblyLine['node_slug'].append(
       [LOCATION_SLUG[0], "Belongs to->"+\
        str(FILE_SLUG[0]), "Name-> "+FILE_NAME_SLUG[1]+"."+FILE_NAME_SLUG[2]])
     else:
      pass
    DEBUG_BUILD.node_tokenizer_assembled(
     ANCHOR=DictAssemblyLine['node_slug'][0:2],
     BUCKET=NODE_TOKENIZER_BUCKET[:],
     DICTIONARY=DictAssemblyLine)
    DictCombCounter = 2
    try:
     while True:
      z = DictAssemblyLine['node_slug'][DictCombCounter]
      DictCombCounter = DictCombCounter+1
      DEBUG_BUILD.node_tokenizer_added_value(VALUE=z)
    except IndexError as e:
     DEBUG_BUILD.node_tokenizer_exhausted(error=e)
## PATH
class PATH:
 PATH_BUCKET = [path_project]
 def path_logic(path_dest=Cure.muted):
  """
  clear the current PATH_BUCKET and determine what path to assemble next
  """
  PATH.PATH_BUCKET.clear()
  if path_dest==Cure.muted:
   ## if no path is supplied fall back to the provided default
   DEBUG_BUILD.path_invalid()
   z = glob(DEFAULT_PATH_CRAWER)
   for i in z:
    PATH.PATH_BUCKET.append(i)
  else:
   ## if a path is provided in path_dest, utilize it
   z = glob(path_dest)
   for i in z:
    PATH.PATH_BUCKET.append(i)

def construct_path(i=Cure.muted, TOKEN=Cure.muted):
 if TokenSlug.Sub_Level_Counter == 0:
  ## The first run executes this, or being passed a default
  ##FinalBucket.make() value the run must also be checked for overloading
  if TokenSlug.OVERLOADED >= 1:
   ## If the path is overloaded, use the overloaded path
   PATH.path_logic(path_dest=i+TokenSlug.glob_nested)
   PATH_NOW.clear()
   PATH_NOW.append(path_project)
   ACTIVE_TOKEN.clear()
   ACTIVE_TOKEN.append(TokenSlug.Start_Slug+str(TokenSlug.Start_Number))
   DictPath[Path(path_project)] = ACTIVE_TOKEN[0]
  else:
   ## If the path isn't overloaded, use the default path
   PATH.path_logic(path_dest=DEFAULT_PATH_CRAWER)
   PATH_NOW.clear()
   PATH_NOW.append(path_project)
   ACTIVE_TOKEN.clear()
   ACTIVE_TOKEN.append(TokenSlug.Start_Slug+str(TokenSlug.Start_Number))
   DictPath[Path(path_project)] = ACTIVE_TOKEN[0]
 else:
  ## All subsequent runs will have a Sub_Level_Counter of >= 1
  ALREADY_CRAWED_BUCKET.append(i)
  PATH_NOW.clear()
  PATH_NOW.append(i)
  DictPath[Path(i)] = TOKEN
  PATH.path_logic(path_dest=i+TokenSlug.glob_nested)
  PATH.PATH_BUCKET

## SlugMaker
class SlugMaker:
 def construct():
  ## On the first run 'A' and '0'
  SLUG_BUCKET.append(TokenSlug.Start_Slug+str(TokenSlug.Start_Number))
  ## Increment the Start_Number, which will reset on each provided TOKEN
  TokenSlug.Start_Number = TokenSlug.Start_Number + 1
  ## Clone the PATH.PATH_BUCKET into the updated SLUG_BUCKET
  for i in PATH.PATH_BUCKET:
   SLUG_BUCKET.append(i)
 def IncrementSlugCounter():
  ## On the first run, this will go from 0->1
  TokenSlug.SLUG_COUNTER = TokenSlug.SLUG_COUNTER+1
  DEBUG_BUILD.increment_token_counter(
   FROM=TokenSlug.SLUG_COUNTER, TO=TokenSlug.SLUG_COUNTER+1)
 ## The tree logic goes here
 def LocationSlug():
  ## Make the 'deep crawl' logic
  try:
   ## Condition 1: If the token has no more available slugs
   if TokenSlug.available_slugs[TokenSlug.SLUG_COUNTER] == \
    TokenSlug.available_slugs[-1]:
    DEBUG_BUILD.node_recursion_item_nested(ITEM=TokenSlug.Sub_Level_Counter)
    ## Add a ladder incrementer
    #TokenSlug.LADDER = TokenSlug.LADDER + 1
    TokenSlug.Start_Slug = \
     str(TokenSlug.LADDER)+TokenSlug.available_slugs[TokenSlug.SLUG_COUNTER]
   ## Condition 2, the slugs are root level complex directories
   else:
    DEBUG_BUILD.node_recursion_item_anchor(ITEM=TokenSlug.Sub_Level_Counter)
    #TokenSlug.LADDER = TokenSlug.LADDER + 1
    TokenSlug.Start_Slug = TokenSlug.available_slugs[TokenSlug.SLUG_COUNTER]
  except IndexError as e:
   ## Condition 3, the slugs are in a sub-node
   if "list index out of range" in str(e):
    ## If the node is the anchor and complex,
    if TokenSlug.Sub_Level_Counter == 0:
     DEBUG_BUILD.node_recursion_item_sub(ITEM=TokenSlug.Sub_Level_Counter)
     TokenSlug.Start_Slug = \
      str(TokenSlug.LADDER)+\
       TokenSlug.available_slugs[TokenSlug.SLUG_COUNTER]+\
       TokenSlug.available_slugs[TokenSlug.SLUG_COUNTER]
     TokenSlug.Sub_Level_Counter = TokenSlug.LADDER+TokenSlug.Sub_Level_Counter
    else:
     DEBUG_BUILD.node_recursion_item_sub(ITEM=TokenSlug.Sub_Level_Counter)
     TokenSlug.Sub_Level_Counter = TokenSlug.Sub_Level_Counter + 1
     ## In this case, we always reset the index
     ## Reset the counter and add an index location
     TokenSlug.SLUG_COUNTER = 0
     ## Condition 4, undefined
   else:
    DEBUG_BUILD.error_recorded(error=e)

 def build():
  ## Reload the SLUG_BUCKET index
  SlugMaker.construct()
  ## Advance through the Slug structure levels
  SlugMaker.IncrementSlugCounter()

## Tokenizer
class Tokenizer:
 def evaluate():
  ## Construct the SlugMaker.build() routine
  SlugMaker.build()
  ## Utilize the SLUG_BUCKET to determine the index
  for i in SLUG_BUCKET:
   if str(i) == str(SLUG_BUCKET[0]):
    DEBUG_BUILD.token_index(INDEX=i)
    ## Look for matches, and if a match occurs overwrite the name of the INDEX
    for M in EXHAUSTED_TOKEN:
     DEBUG_BUILD.mode_value_exhausted(EXHAUSTED=M)
     if M == SLUG_BUCKET[0]:
      DEBUG_BUILD.confirmed_exhausted_mode(VALUE=SLUG_BUCKET[0])
      OLD_SLUG = SLUG_BUCKET[0]
      SLUG_BUCKET.clear()
      SLUG_BUCKET.append(OLD_SLUG+"A"+str(1))
      DEBUG_BUILD.remade_slug_bucket(WITH=SLUG_BUCKET[0])
      #TokenSlug.ALTER_INDEX_COUNTER = 1
     else:
      DEBUG_BUILD.path_mismatch()
   else:
    DEBUG_BUILD.generated_index_mapper(MAPPER=SLUG_BUCKET[0])
    ## Determine if the i value is a file,
    ## and if it is append the correct syntax
    if path.isfile(i):
     DEBUG_BUILD.located_endpoint(ENDPOINT=i)
     ## Always TOKENIZE the instnace
     TOKENIZE_NOW.append(i)
     FORMATTED_TOKEN_BUCKET.append(
      ">><"+SLUG_BUCKET[0]+">"+i+"<<<"+\
       str(SLUG_BUCKET[0])+str(TokenSlug.Start_Number))
    ## Determine if the i value is a Node,
    ## and if it is append the correct syntax
    else:
     DEBUG_BUILD.located_node(NODE=i)
     IGNORE_CHECK = Path(i)
     CHECKED_SLUG = IGNORE_CHECK.stem
     DEBUG_BUILD.node_stem(STEM=CHECKED_SLUG)
     ## Determine if the i value is restricted Node and if it is, exclude it
     if CHECKED_SLUG in IGNORE_BUCKET or "/"+CHECKED_SLUG+"/" in i:
      DEBUG_BUILD.node_ignored_or_already_checked()
     ## If the Node is no retricted, determine if it is a
     ## anchor level or Sub level instance. Then, apply the correct syntax
     else:
      ## Always TOKENIZE the instnace
      TOKENIZE_NOW.append(i)
      ## Add the instance to the CRAW_BUCKET_NOW
      CRAW_BUCKET_NOW.append(i)
      ## Add the instance to the NESTED_NODE
      NESTED_NODE.append(i)
      ## If the Token is the same as the initial TOKEN,
      ## we are dealing with a root level instance
      if TokenSlug.Start_Slug == TokenSlug.available_slugs[0]:
       FORMATTED_TOKEN_BUCKET.append(
        ">>><"+SLUG_BUCKET[0]+">"+i+"<<<"+str(SLUG_BUCKET[0]))
      ## If the Token is not the same as the initial TOKEN,
      ## we are dealing with a sub level instance
      else:
       FORMATTED_TOKEN_BUCKET.append(
        "<"+SLUG_BUCKET[0]+">"+i+"<<<"+str(SLUG_BUCKET[0]))
      ## Exhaust the token when it's a node instance
      EXHAUSTED_TOKEN.append(SLUG_BUCKET[0])
  DEBUG_BUILD.tokenizing_now()
  ## Format the TOKEN to the desired result
  for i in TOKENIZE_NOW:
   DEBUG_BUILD.token_now(
    BELONGS_TO=SLUG_BUCKET[0],
    ITEM=i, NUMBER=TokenSlug.Start_Number,
    TOKEN=SLUG_BUCKET[0])
   DEBUG_BUILD.token_now_formatted(
    TOKEN_FORMATTED=\
     FORMATTED_TOKEN_BUCKET[TokenSlug.FORMATTED_TOKEN_NUMBER]+\
     str(TokenSlug.Start_Number))
   SLUG = \
    FORMATTED_TOKEN_BUCKET[TokenSlug.FORMATTED_TOKEN_NUMBER]+\
     str(TokenSlug.Start_Number)
   DEBUG_BUILD.token_formatted(
    TOKEN_FORMATTED=SLUG_BUCKET[0]+str(TokenSlug.Start_Number))
   TokenSlug.FORMATTED_TOKEN_NUMBER = TokenSlug.FORMATTED_TOKEN_NUMBER + 1
   FINAL_BUCKET.append(SLUG)
   DEBUG_BUILD.finalizing_slug(VALUE=SLUG)
   TokenSlug.Start_Number = TokenSlug.Start_Number + 1

  ## Add to the TokenSlug.Sub_Level_Counter to
  ## indicate additional sturcture levels
  TokenSlug.Sub_Level_Counter = TokenSlug.Sub_Level_Counter + 1
  TOKENIZE_NOW.clear()
  ## Make the location slug
  SlugMaker.LocationSlug()
  ## Clear past values and reset ques
  SLUG_BUCKET.clear()
  FORMATTED_TOKEN_BUCKET.clear()
  TokenSlug.Start_Number = 0
  TokenSlug.FORMATTED_TOKEN_NUMBER = 0
  DEBUG_BUILD.node_evaluation_crawler(TREE=CRAW_BUCKET_NOW[:])

## Operate
class Operate:
 def RUN_CRAW_PARSER():
  ## Determine the length of the current CRAW_BUCKET_
  g = len(CRAW_BUCKET_NOW)
  DEBUG_BUILD.node_craw_length(LENGTH=g)
  ## For each item in the CRAW_BUCKET_
  for i in CRAW_BUCKET_NOW:
   ## Skip all slugs that have already been crawed
   if i in ALREADY_CRAWED_BUCKET:
    DEBUG_BUILD.node_craw_already_took_place()
   ## Continue to all uncrawed slugs
   else:
    ## For all valid items, set the CURRENT_PARSE_BUCKET
    CURRENT_PARSE_BUCKET = i
    ## Reset the ACTIVE_TOKEN_BUCKET
    ACTIVE_TOKEN_BUCKET.clear()
    ## Set the ACTIVE_TOKEN_BUCKET parameters to the matched DictPath values
    for k, v in DictPath.items():
     DEBUG_BUILD.evaluating_dictionary(
      KEY=k, VALUE=v,
      PATH_K=Path(k), PATH_NOW=Path(PATH_NOW[0]))
     ## If the Path from the match is valid, you're on a valid craw-ready path
     if str(Path(k)) == str(Path(PATH_NOW[0])):
      z = str(v)
      ACTIVE_TOKEN_BUCKET.append(v)
      DEBUG_BUILD.path_match(MATCH=z)
     else:
      DEBUG_BUILD.path_mismatch()
    ## Once a valid ACTIVE_TOKEN_BUCKET has been built,
    ## you can eliminate the old lookup value
    try:
     ## Pop at the DELIMITER
     POPPED = CRAW_BUCKET_NOW.pop(TokenSlug.DELIMITER)
     ## Reconstruct the path with the current valid item
     construct_path(i=CURRENT_PARSE_BUCKET, TOKEN=ACTIVE_TOKEN_BUCKET[0])
     DEBUG_BUILD.path_popped(PATH=POPPED)
     ## Perform the Operation functions for the current valies
     Operate.RUN_EXTENDED_PATH_LOGIC()
     Operate.RUN_CRAW_PARSER()
     ## When there are no values left to operate on, exhaust the function
    except IndexError as e:
     DEBUG_BUILD.path_exhausted()

 ## Determine which types of data the corresponding TOKEN is linked to
 def RUN_EXTENDED_PATH_LOGIC():
  Tokenizer.evaluate()

## FinalBukcet
class FinalBucket:
 """
 When you want to run the program, utilize the runner command->
 FinalBucket.make()
 """
 def make(path_overloaded=Cure.muted):
  """
  First run is by construct_path(i="", TOKEN=ACTIVE_TOKEN[0]) with values:
  i="", TOKEN="A0"
  Allow for overloading by using FinalBucket.make(path="/YOUR_PATH/HERE")
  """
  if path_overloaded==Cure.muted:
   DEBUG_BUILD.path_not_overloaded()
   ## Default to the anchor node
   construct_path(i=Cure.muted, TOKEN=ACTIVE_TOKEN_BUCKET[0])
  else:
   ## Pass an overloaded node-start location
   DEBUG_BUILD.path_overloaded(PATH=path_overloaded)
   ## Increment the OVERLOADED counter
   TokenSlug.OVERLOADED = TokenSlug.OVERLOADED + 1
   construct_path(i=path_overloaded, TOKEN=ACTIVE_TOKEN_BUCKET[0])
  ## Use the operations command to determine the
  ## EXTENDED_PATH_LOGIC and build the CRAW_PARSER
  Operate.RUN_EXTENDED_PATH_LOGIC()
  Operate.RUN_CRAW_PARSER()
  ## Reset the parameters
  TokenSlug.DELIMITER = 0
  CRAW_BUCKET_NOW.clear()
  DEBUG_BUILD.tokenizing_bucket_final(
   TOKENIZED_BUCKET_FINAL=FINAL_BUCKET[:])
  DEBUG_BUILD.tokenized_output(FINALIZED_BUCKET=FINAL_BUCKET)
  ## View the exhausted TOKENS
  DEBUG_BUILD.tokenized_output_exhausted_tokens(
   EXHAUSTED_TOKENS=EXHAUSTED_TOKEN[:])
  ## Sort the file-system
  ALREADY_CRAWED_BUCKET.sort()
  DEBUG_BUILD.build_summary(INSTANCE=ALREADY_CRAWED_BUCKET)

def Flush_FINAL_BUCKET():
 FINAL_BUCKET.clear()
## Program Runner
## Overloaded
#FinalBucket.make(path_overloaded="/NOVASTORE")
## Default
FinalBucket.make()
## Optionally clear the final bucket ->
## Useful if you don't want to concat two runs together
#Flush_FINAL_BUCKET()



Return HOME