import os import numpy as np from io import StringIO # from .common import Common class Content : """ This class implements functions that will manipulate content of a file :split splits the content :read reads the content of a file given a filename :parse parses the content of a file given a map {index:field_name} """ def __init__(self,**_args): self._parents = {} self._lastelement = {} def split(self,_content): if type(_content) == str : _xchar = '~\n' if '~\n' in _content else ('~' if '~' in _content else ('\n' if '\n' in _content else None)) _x12 = '837' if 'CLM*' in _content else ('835' if 'CLP*' in _content else None) _map = {'835':'CLP','837':'CLM'} _claim_mark = _map[_x12] _content = _content.split(_claim_mark) _xchar = ''.join(_xchar) _chunks = [] for _block in _content : if len(_chunks) > 0 : _block = _claim_mark+ _block _splitblocks = [row.strip().split('*') for row in _block.split(_xchar) if row.strip()] _chunks.append(_splitblocks) return _chunks,_x12 # if _xchar : # _xchar = ''.join(_xchar) # _rows = _content.split(_xchar) # return [row.strip().split('*') for row in _rows if row.strip()] # else: # return _content.split('*') return [],None def read(self,**_args): """ This function will read and clean-up the content of a file """ _filename = _args['filename'] if type(_filename) == StringIO : return _filename.read() else: f = open(_filename) _content = f.read() f.close() return _content def _ix_parse (self,columns,index,**_args): """ This function encapulates how an x12 document element will be processed :columns list of attributes that make up the object :index indexes of the said items in the element :_args - row raw x12 element (string) - pointer decorated function - document """ _ELEMENT = _args['row'][0] _pointer = _args['pointer'] _document = _args['document'] if 'map' in _pointer.meta : _map = _pointer.meta['map'] _index = list(_map.keys()) _columns = [_map[_id] for _id in _index ] _info = {} _row = _args['row'] if type(_args['row']) == list else _args['row'].split('*') _index = np.array(_index) # # Sometimes the _row doesn't have all expected indexes, we will compensate # This allows to minimize parsing errors as it may relate to disconnects between configuration and x12 element variations (shitty format) # if np.max(_index) > len(_row) -1 : _delta = 1 + np.max(_index) - len(_row) _row = _row + np.repeat('',_delta).tolist() _row = np.array(_row) _info = dict(zip(_columns,_row[_index].tolist())) else: # # We should call the function that is intended to perform the parsing # _info = _pointer(row=_args['row'],document=_document,meta=_pointer.meta) # # @TODO: We should look into the object created and enforce the specifications are met # return _info # def consolidate(self,**_args): # """ # This function takes an object and addit to the document given meta data # :document document associated associated with a claim (processing the loops) # :object # :caller attributes within the decorator # """ # _document = _args['document'] if 'document' in _args else {} # _info = _args['object'] # _meta = _args['meta'] # # # # @TODO: # # Apply parsing/casting function to the object retrieved # # _apply(_info) #-- the object will be processed accordingly # # # # # # @TODO: # # The objects parsed must be augmented against the appropriate ones e.g: NM1 <- N1,N2,N3,N4 # # - Find a way to drive this from a configuration ... # # # if 'field' in _meta : #hasattr(_meta,'field') : # _field = _meta['field'] # if not _field in _document : # _item = {_field:_info} # else: # _item = self.merge(_document[_field],_info) # elif 'container' in _meta: # hasattr(_meta,'container') : # _label = _meta.container # if not _label in _document : # _item = {_label:[_info]} # else: # _item = _document[_label] + [_info] # else: # _item = _info # if 'parent' in _meta : #hasattr(_meta,'parent'): # _hasField = 'field' in _meta # _hasParent= _meta['element'] in self._parents # if _hasField and _hasParent: #_meta.element in self._parents and hasattr(_meta,'field'): # self_last = _item # pass # else: # for key in self._parents : # if _meta.element in self._parents[key] : # _ikey = list(self_last.keys())[0] # _oldinfo = self_last[_ikey] # if type(_oldinfo) != dict : # # # # Only applicable against a dictionary not a list (sorry) # pass # else: # _item = {_ikey: self.merge(_oldinfo,_item)} # break # pass # return _item class Location : @staticmethod def get(**_args): _path = _args['path'] files = [] if os.path.isdir(_path): for root,_dir,f in os.walk(_path) : if f : files += [os.sep.join([root,name]) for name in f] files = [path for path in files if os.path.isfile(path)] else: files = [_path] _chunks = 0 if 'chunks' not in _args else int(_args['chunks']) return files if not _chunks else np.array_split(files,_chunks)