def reset(self): self._key = Key(); self.name = Type_Entry.CONST_DEFAULT_NAME; return self;
class Type_Entry(object): __metaclass__ = abc.ABCMeta; CONST_DEFAULT_NAME = "( default name )"; CONST_DEFAULT_DESCRIPTION = ""; CONST_NAME_REGEX = re.compile("^[a-zA-Z0-9_\'\-\. ,<>\?!\(\)%&/:]+$"); #CONST_DESCR_REGEX = re.compile("^[a-zA-Z0-9 _<>:\-\.,]*$"); NAME_NAME = "name"; NAME_KEY = "key"; CREATE_ENTRY_FIELDS_INNER = ("\n {0} TEXT PRIMARY KEY ASC ON CONFLICT ABORT UNIQUE,\n"+ " {1} TEXT UNIQUE DEFAULT \"No Name\" COLLATE NOCASE ").format( NAME_KEY, NAME_NAME); # ====== ====== Entry Class Members # ====== ====== TYPE_NAME = "Type Entry".lower(); TABLE_NAME = "n/a"; CREATE_TABLE_COMMAND = ""; # names to store and request fields with NAME_NAME_SYNS = [NAME_NAME, "title"]; NAME_KEY_SYNS = [NAME_KEY]; ALL_SYNS = [NAME_NAME_SYNS]; # ====== ====== Instance Methods # ====== ====== def __init__( self): self.reset(); def __str__(self): return self.to_string(); @staticmethod def _get_if_exists(source_dict, target_key, default_value): if target_key in source_dict: if (None != source_dict[ target_key]) and ("" !=source_dict[ target_key]): return source_dict[ target_key]; return default_value; @staticmethod def _cost_list_from_string( source_string): if (type(source_string) is list) or (None == source_string) or ("" == source_string): return []; assert(type(source_string) is str); source_string = source_string.lower().replace(' ','_').strip(", "); string_list = source_string.split(",:"); cost_dict = {}; for i, s in enumerate(string_list): s=s.strip("\"").strip(); #DEBUG # print(" this list entry: "+s); # cost_dict[]=; return string_list; def _set( self, varname, value): #print("?? _set(... " + varname +", "+value+") in "+self.TYPE_NAME); if Entry.NAME_KEY == varname: self.set_key(value); elif Entry.NAME_NAME == varname: self.set_name(value); elif Entry.NAME_DESCR == varname: self.description = value; elif Entry.NAME_TAGS == varname: self.tags.clear().from_value( value ); else: return None; return self; def coerce_field_name( self, field_name): # note: we want this to be non-static so that its fields list is polymorphic with its owner field_name = field_name.strip().lower().rstrip('s'); for sublist in self.ALL_SYNS: for search_name in sublist: if search_name == field_name: return sublist[0]; else: raise TypeError( "!! Could not coerce variable name: "+field_name); def from_dict(self, source_dict): if self.NAME_NAME in source_dict: self.name = source_dict[self.NAME_NAME]; else: print(" bad entry. available fields: "); for key in source_dict.keys(): print(" dict["+str(key)+"]=:"+str(source_dict[key])+":"); return None; fallback_key = self.name; # the key class will transform this string if necessary self.set_key( str(Type_Entry._get_if_exists(source_dict, self.NAME_KEY, fallback_key)).strip()); return self; def from_sql_row( self, row ): assert( self.NAME_NAME in row.keys()); assert( self.NAME_KEY in row.keys()); self.set_name( row[ self.NAME_NAME]); self.set_key( row[ self.NAME_NAME]); #set default key value return self; def get_create_table_string( self): return self.CREATE_TABLE_COMMAND; def get_footer(self, footer_format = Text_Format().as_yaml()): if footer_format.is_json(): return self.get_footer_json(); elif footer_format.is_dot(): return self.get_footer_dot(); else: return "" def get_footer_yaml(self): return ""; def get_footer_dot(self): return "}\n"; def get_footer_json(self): return " \n}"; def get_header(self, file_format = Text_Format().as_yaml()): if file_format.is_csv(): return self.get_footer_csv(); elif file_format.is_dot(): return self.get_header_dot(); elif file_format.is_json(): return self.get_header_json(); elif file_format.is_yaml(): return self.get_header_yaml(); else: return ""; @staticmethod def get_header_csv(): return (NAME_KEY+", "+NAME_NAME+", "); def get_header_dot(self, dim=100): return "digraph noname {\n size=\"{0},{0}!\"\n".format(dim); def get_header_json(self): return "{\""+self.get_table_name()+"\":\n"; def get_header_sql( self, wrap=False): header_str = "" header_str += self.NAME_KEY+", "; header_str += self.NAME_NAME; if wrap: header_str = "(" + header_str +")"; return header_str; def get_header_yaml(self): return self.get_table_name()+": \n"; def get_key(self): return self._key; def get_table_name( self): return self.TABLE_NAME.lower(); def get_type_name( self): return self.TYPE_NAME.lower(); @abc.abstractmethod def new( self): return Entry(); def reset(self): self._key = Key(); self.name = Type_Entry.CONST_DEFAULT_NAME; return self; def set( self, string): varname = ""; value = ""; tokens = string.lstrip('-').split(':',1); if len(tokens) == 1: varname = Type_Entry.NAME_NAME; value = tokens[0].strip(); else: varname = tokens[0].strip(); value = tokens[1].strip(); if ':' in value: value = "\""+value+"\""; #print("?? 02 set(... " + varname +", "+value+")"); #print("?? 03 set(...) in <"+self.TYPE_NAME+">: "+str(len(self.ALL_SYNS))); varname = Type_Entry._coerce_field_name( varname); #print("entry.set(): ... [<"+var+">,<"+val+">]"); #print("?? 04 set(... " + name +", "+value); retval = self._set( varname, value); if retval: return self; else: # DEBUG #print(" [WARN] Unknown varName: entry.set( "+varname+", ...)"); #raise TypeError("Unknown Type: entry.set( "+name+", ...)"); return None; def set_key(self, new_key): if( type(new_key) is Key): self._key = new_key; elif( type(new_key) is str): self._key.set_text(new_key); if False == self._key.validate(): return False; return True; def set_name( self, value): assert( type(value) is str); self.name = value; if self._key == Key.CONST_ERROR_KEY: self.set_key(value); pass def to_csv( self, quoted=True, newline=True, wrap=False, compact=True ): csv_string=""; if quoted: csv_string = ("\""+self._key.get_text()+"\", "+ "\""+self.name +"\""); else: csv_string = (self._key.get_text()+", "+ self.name); if wrap: csv_string = "[" + csv_string +"]"; if newline: csv_string += '\n'; return csv_string; def to_dict( self): new_dict = {self.NAME_KEY: str(self._key), self.NAME_NAME: self.name}; return new_dict; def to_string(self, _format = Text_Format().as_yaml()): if _format.is_csv(): return self.to_csv(); elif _format.is_dot(): return self.to_dot(); elif _format.is_json(): return self.to_json(); elif _format.is_sql(): return self.to_sql(); elif _format.is_yaml(): return self.to_yaml(); else: # default output option return self.to_yaml(); def to_sql(self, wrap=False): """ Only generates the inner variable text. """ sql_string = ("\""+self._key.get_text()+"\", "+ "\""+self.name+"\""); if wrap: sql_string = "("+ sql_string+")"; return sql_string; def to_yaml( self): retstr = (" - "+self.NAME_KEY+": "+ str(self._key)+"\n"+ " "+self.NAME_NAME+": "+ self.name+"\n"); return retstr; def validate(self, verbose=True): if not self._key.validate(): if verbose: print("could not validate key :"+self._key+":"); print(" regex= "+Key.CONST_KEY_REGEX.pattern); return None; if Key.CONST_ERROR_KEY == str(self._key): if verbose: print("Key value is still the error key. Please set a valid key."); return None; if not Type_Entry.CONST_NAME_REGEX.match(self.name): if verbose: print("could not validate name :"+self.name+":"); print(" regex= "+Entry.CONST_NAME_REGEX.pattern); return None; # no check of self.description is necessary. return self; @staticmethod def yaml_from_dict( source_dict): assert(type(source_list) is dict); flat_string = ""; for key, item in source_dict.items(): #assert(type(item) is str); flat_string += str(item) + ", "; flat_string = flat_string.rstrip(", "); return flat_string;