Template:Pythonfls

From Exiled Kingdoms Wiki


Here's the files I use for updating/Creating a database and the wiki ouput files (...byname, tables)

I'm using this program solely on my phone (qpython3). Wherever you create these files you'll probably want to remove the first os.chdir as well as the sys.path.append.
I've made the dbaccess, and logging files as generic but useful as possible and store them in a directory for all programs to use (hence adding that folder to the system path). You will have to change the second os.chdir to whatever folder you store them in.

You will also need the following files filled with the data portion of the ..byName templates (After the switch) with no empty space at the top or bottom.

'MobList.txt'
'Skills.txt'
'ItemsList.txt'
'ArmorList.txt'
'WeaponsList.txt'
'QuestsList.txt'
'NPCList.txt'

First line of each file should be:

|nameofsomething=

And last line in file:

}}



After the first run you can change

updb.writedb('All', True)

To

updb.writedb('All', False)

So it doesn't drop and recreate the tables every time (bottom of ek prog in if __main__)

Feel free to use the Discussion page or pm me if you have questions or would like something else added.


EK Prog.py

import os, sys
import re
os.chdir('/sdcard/Git/Base/')
sys.path.append(os.path.normpath(os.getcwd()))
os.chdir('/sdcard/EK Prog')

#  -----------Setup Logging------------
import logging
import setup_logging
log_options = {
    'default_path': '/sdcard/Git/Base/logcfg.json',
    'info_filename': 'EKcnv.log',
    'error_filename': None,
    'default_level': logging.INFO,
    'filemode': 'w'
}
setup_logging.MyLogger(**log_options)
eklog = logging.getLogger(__name__)
#  ---------End Setup Logging ---------

import dbaccess
from DataConstruct import *

class LdDmp:
    def __init__(self, flnm):
        self.rawdata = load_file(flnm)
        self.Data = []

    def breakdown(self):
        for item in self.rawdata:
            self.Data.append(mobdata())
            citm = self.Data[-1].info
            item2 = item.split(';')
            item2.pop(0)
            for titm in item2:
                if ':' in titm:
                    titm = titm.split(':')
                    titm[0] = titm[0].strip()
                    if ' ' in titm[0]:
                        titm[0] = titm[0].replace(' ', '_')
                    if titm[0] == 'Resistances':
                        citm[titm[0]] = Conv_Res(titm[1])
                        continue
                    elif titm[0] == 'Level':
                        titm[0] = 'LevelH'
                    elif titm[0] == 'Attributes':
                        if titm[1].strip() != 'None':
                            titm[1] = titm[1].strip()
                            titm[1] = titm[1].title()
                            titm[1] = titm[1].split(' ')
                            titm[1] = [i.replace('_', ' ') for i in titm[1]]
                            titm[1] = '; '.join(['[[{}]]'.format(i) for i in titm[1]])
                        else:
                            titm[1] = ''
                    elif titm[0] == 'Skills':
                        if titm[1] != '' and titm[1] != ' ':
                            titm[1] = titm[1].split(',')
                            tmpsk = []
                            sklfix = []
                            for skl in titm[1]:
                                tmpsk.append(skl.split('='))
                                tsk = tmpsk[-1]
                                tsk[0] = tsk[0].strip()
                                tsk[0] = tsk[0].replace('_', ' ')
                                tsk[0] = tsk[0].title()
                                tsk[1] = tsk[1].strip()
                                sklfix.append('[[{}]]: {}'.format(tsk[0], tsk[1]))
                            titm[1] = '; '.join(sklfix)
                    if titm[0] in citm.keys():
                        citm[titm[0]] = titm[1].strip()




class BaseUpdate:
    sqldb = None
    def __init__(self, rawf, datsrc, dbsrc):
        self.rawfl = load_file(rawf)
        self.outplistfl = None
        self.outpfl = None
        self.MList = []
        self.TList = []
        self.datasrc = datsrc
        self.dbsrc = dbsrc
        self.lastfld = None
        self.datasort = None

    def maketxt(self, itmbynm, itmtbl):
        tmptxt = ''
        tmptxttbl = ''
        tmpnm = []
        for itm in self.MList:
            if itm.info['Name'] in tmpnm:
                continue
            tmptxt += itm.wikiout()
            tmptxttbl += itm.wikitblout()
            tmpnm.append(itm.info['Name'])
        load_file(itmbynm, tmptxt)
        load_file(itmtbl, tmptxttbl)

    def combdata(self, tmplst=None):
        TList = None
        if tmplst:
            TList = tmplst
        else:
            TList = self.TList
        match = False
        for nitms in TList:
            for dbitms in self.MList:
                if nitms.info['Name'] == dbitms.info['Name']:
                    match = True
                    for key, val in nitms.info.items():
                        if (val != '' and val != ' ' and
                            val != '\n' and val != 'None' and
                            val != 0 and val != 1):
                            if key == 'Resistances':
                                if val[1]:
                                    val = Conv_Res(val[1])
                                else:
                                    val = Conv_Res(val[0])
                            dbitms.info[key] = val
                        elif (val == 0 or val == 1):
                            if isinstance(dbitms.info[key], bool):
                                if val:
                                    dbitms.info[key] = True
                                else:
                                    dbitms.info[key] = False
                            else:
                                dbitms.info[key] = val
                    if 'Element' in dbitms.info.keys():
                        if 'Elem_Res' in dbitms.info.keys():
                            dbitms.info['Element'] = '{}/{}'.format(dbitms.info['Element'], dbitms.info['Elem_Res'])
                        else:
                            dbitms.info['Element'] = '{}/{}'.format(dbitms.info['Element'], dbitms.info['Elem_Dam'])
                        dbitms.info['Element'] = Conv_Res(dbitms.info['Element'])
            if match:
                match = False
                continue
            self.MList.append(nitms)
        self.MList.sort(key=self.datasrc.sortKey)
        eklog.info('Lists Merged')

    def bsort(self, datasrc=None, tlsto=False):
        if datasrc:
            self.datasrc = datasrc
        if len(self.MList) == 0:
            tlsto = False
            self.MList.append(self.datasrc())
        else:
            tlsto = True
            self.TList.append(self.datasrc())
        tmitm = None
        titm2 = None
        for nitem in self.rawfl:
            if tlsto:
                tmitm = self.TList[-1].info
                tmwho = self.TList[-1]
                tmlst = self.TList
            else:
                tmitm = self.MList[-1].info
                tmwho = self.MList[-1]
                tmlst = self.MList
            if ((nitem[0] == '' or nitem[0] == '\n') and
                    self.lastfld != ''):
                if 'Element' in tmitm.keys():
                    if 'Elem_Res' in tmitm.keys():
                        tmitm['Element'] = '{}/{}'.format(tmitm['Element'], tmitm['Elem_Res'])
                    else:
                        tmitm['Element'] = '{}/{}'.format(tmitm['Element'], tmitm['Elem_Dam'])
                    tmitm['Element'] = Conv_Res(tmitm['Element'])
                if 'Class' in tmitm.keys():
                    if 'CWar' in tmitm.keys():
                        clss = tmitm
                        cttl = 0
                        tcls = []
                        if clss['CWar']:
                            tcls.append('W')
                            cttl += 1
                        if clss['CRog']:
                            tcls.append('R')
                            cttl += 1
                        if clss['CCle']:
                            tcls.append('C')
                            cttl += 1
                        if clss['CMag']:
                            tcls.append('M')
                            cttl += 1
                        if cttl == 4:
                            clss['Class'] = 'All'
                        else:
                            tcls = ', '.join(tcls)
                            clss['Class'] = tcls
                tmlst.append(self.datasrc())
                self.lastfld = ''
                continue
            elif ((nitem[-2:] == '}}' or nitem[-3:] == '}}\n') 
                and (nitem[-3:] != '}}}' or nitem[-4:] != '}}}\n') and
                'Inventory' not in nitem):
                if nitem[-1:] == '\n':
                    nitem = nitem[:-3]
                else:
                    nitem = nitem[:-2]
                if not nitem:
                    continue
            if (nitem[0] == '{' or '|Step=' in nitem or 
            nitem == '}}'):
                continue
            titm = None
            #eklog.info(nitem)
            if nitem[-1:] == '\n':
                nitem = nitem[:-1]
            if 'Cost' in nitem and ('Casting' not in nitem and 'Level' not in nitem and 
            'Summary' not in nitem and '|Inventory' not in nitem):
                titm = nitem.split('|')
                tmitm['Value'] = titm[1].split('=')[1]
                tmitm['Cost'] = titm[3][:-4]
                continue
            elif 'Notes' in nitem:
                tmitm['Notes'] = nitem.split('|', 2)[2][:-1]
                self.lastfld = 'Notes'
                continue
            elif nitem[0] == '*' or nitem[0] == '#' or nitem[0] == '<' or (nitem[0] != '|' and (nitem[0] != '' and nitem[0] != ' ')):
                #eklog.info(nitem)
                if self.lastfld == 'Walkthrough' or self.lastfld == 'Backstory':
                    tmitm[self.lastfld] += '\n<br />{}'.format(nitem[2:])
                else:
                    tmitm[self.lastfld] += '\n{}'.format(nitem)
                continue
            elif ('|Location' in nitem and
                    'Location' in tmitm.keys()):
                #eklog.info(nitem)
                titm = nitem.split('=', 1)
                titm = titm[1]
                self.lastfld = 'Location'
                if 'None' in titm:
                    titm = ''
                elif titm:
                    titm = titm.split('*')
                    if titm[0] == '' or titm[0] == ' ':
                        if len(titm) > 1:
                            titm.pop(0)
                        else:
                            tmitm['Location'] = ''
                            self.lastfld = 'Location'
                            continue
                    titm = ['* {}\n'.format(i.strip()) for i in titm]
                    titm = ' '.join(titm)
                    titm = titm[:-1]
                    tmitm['Location'] = titm
                    continue
            elif '✔' in nitem:
                titm = nitem.split('|')
                for subitm in titm[1:]:
                    subitm.replace('\n', ' ')
                    titm2 = subitm.split('=')
                    if titm2[1]:
                        tmitm[titm2[0]] = True
                    else:
                        tmitm[titm2[0]] = False
                continue
            else:
                #if nitm:
                if ('Long_Description' in nitem or 'Description' in nitem or
                    'LocStart' in nitem or 'Walkthrough' in nitem or 'Action' in nitem or
                    'LocCmp' in nitem or 'LocEnd' in nitem or 'Outcome' in nitem or
                    '|Steps=' in nitem or 'Backstory' in nitem or '|Location' in nitem or 
                    '|Inventory' in nitem):
                    titm = nitem.split('|', 1)
                else:
                    titm = nitem.split('|')
                #else:
                    #titm = nitem.split('|')
                for subitm in titm:
                    if subitm == '' or subitm[0] == '}' or '|Step=' in subitm:
                        continue
                    if 'Inventory' in subitm:
                        titm2 = subitm.split('=', 1)
                    else:
                        titm2 = subitm.split('=')
                    if ' ' in titm2[0]:
                        titm2[0] = titm2[0].replace(' ', '_')
                    if titm2[0] == 'Group':
                        titm2[0] = 'Groups'
                    elif titm2[0] == tmwho.styp:
                        titm2[0] = 'Name'
                    elif titm2[0] == 'Duration\\Range':
                        titm2[0] = 'Duration_Range'
                    elif titm2[0] == 'Skills':
                        skl = titm2[1]
                        if skl:
                            skl = skl.split(';')
                            tsk = []
                            for skill in skl:
                                skill = skill.replace('[', '')
                                skill = skill.replace(']', '')
                                skill = skill.replace('_', ' ')
                                if '#' in skill:
                                    skill = skill.split('#')
                                elif '=' in skill:
                                    skill = skill.split('=')
                                else:
                                    skill = skill.split(':')
                                tsk.append('[[{}]]: {}'.format(skill[0].strip(), skill[1].strip()))
                            titm2[1] = '; '.join(tsk)
                    elif titm2[0] == 'Attributes':
                        atb = titm2[1]
                        if atb.strip() == 'None' or atb.strip() == 'None\n':
                            atb = ''
                            titm2[1] = ''
                        if atb:
                            if ',' in atb:
                                atb = atb.split(',')
                            else:
                                atb = atb.split(';')
                            tatb = []
                            for attb in atb:
                                attb = attb.replace('[', '')
                                attb = attb.replace(']', '')
                                attb = attb.title()
                                tatb.append('[[{}]]'.format(attb.strip()))
                            titm2[1] = '; '.join(tatb)
                    elif titm2[0] == 'Resistances':
                        tmitm[titm2[0]] = Conv_Res(titm2[1])
                        continue
                    elif titm2[0] == 'QstNum':
                        tmitm[titm2[0]] = int(titm2[1])
                        continue
                    if titm2[0] in tmitm.keys():
                        self.lastfld = titm2[0]
                        #eklog.info(titm2)
                        if ('None' in titm2[1]):
                            titm2[1] = ''
                        tmitm[titm2[0]] = titm2[1].strip()
                        if tmitm[titm2[0]][-1:] == '\n':
                            tmitm[titm2[0]][-1:] = ''
        if 'Element' in tmitm.keys():
            if 'Elem_Res' in tmitm.keys():
                tmitm['Element'] = '{}/{}'.format(tmitm['Element'], tmitm['Elem_Res'])
            else:
                tmitm['Element'] = '{}/{}'.format(tmitm['Element'], tmitm['Elem_Dam'])
            tmitm['Element'] = Conv_Res(tmitm['Element'])
        self.MList.sort(key=self.datasrc.sortKey)

    def update_database(self):
        tmpadded = []
        for itm in self.MList:
            iname = itm.info['Name']
            dbchk = BaseUpdate.sqldb.get_one_item(self.dbsrc, 'Name', iname)
            #dbcol = BaseUpdate.sqldb.get_table_col_names(self.dbsrc)
            tmpvalt = ''
            tmpcol = []
            tmpval = []
            if iname in tmpadded:
                continue
            for key, val in itm.info.items():
                tmpadded.append(iname)
                tmpcol.append(key)
                if isinstance(val, bool):
                    if val:
                        val = 1
                    else:
                        val = 0
                elif str(val) == '0':
                    val = ''
                if key == 'Resistances' or key == 'Element':
                    val = val[1]
                if val == 'None' or val == 'None\n':
                    val = ''
                tmpval.append(val)
                tmpvalt += '{}="{}", '.format(key, val)
            tmpvalt = tmpvalt[:-2]
            #eklog.info(tmpvalt)
            if dbchk:
                #update_item(self, table, colc,sval,selc,selcv, mult):
                BaseUpdate.sqldb.update_item(self.dbsrc, None, tmpvalt, 'Name', iname, True)
            else:
                #add_item(self, table, cols, vals):
                eklog.info('adding')
                try:
                    eklog.info(iname)
                    BaseUpdate.sqldb.add_item(self.dbsrc, tuple(tmpcol), tuple(tmpval))
                except:
                    eklog.info(iname)
                    eklog.info('{} - {}'.format(sys.exc_info()[0], sys.exc_info()[1]))
        eklog.info('{} Database Updated'.format(self.dbsrc))

    def load_database(self, ldb=None, newdbf=None):
        dbdata = None
        coln = None
        if ldb:
            dbdata = BaseUpdate.sqldb.get_table(ldb)
            coln = BaseUpdate.sqldb.get_table_col_names(ldb)
            ncoln = BaseUpdate.sqldb.get_table_col_names(newdbf)
            x = len(ncoln) - len(coln)
            coln = ncoln[:-x]
        else:
            ldb = self.dbsrc
            dbdata = BaseUpdate.sqldb.get_table(self.dbsrc)
            coln = BaseUpdate.sqldb.get_table_col_names(self.dbsrc)
        tmplist = []
        for rec in dbdata:
            tmplist.append(self.datasrc())
            curitm = tmplist[-1]
            for x, key in enumerate(coln):
                if key == 'name' or key == 'Name':
                    curitm.info['Name'] = rec[x]
                if key == 'Resistances':
                    curitm.info[key] = Conv_Res(rec[x])
                elif key in curitm.info.keys():
                    if isinstance(curitm.info[key], bool): 
                        if rec[x]:
                            rec[x] = True
                        else:
                            rec[x] = False
                    tmpx = rec[x]
                    if (rec[x] == 'None' or rec[x] == '\n' or 
                        rec[x] == ' \n' or rec[x] == '\n ' or
                        rec[x] == 'None\n' or rec[x] == '0'):
                        tmpx = ''
                    #tmpx = str(rec[x])
                    if '\n' in str(tmpx):
                        tmpx = tmpx[:-1]
                    curitm.info[key] = tmpx
            if 'Element' in curitm.info.keys():
                if 'Elem_Res' in curitm.info.keys():
                    curitm.info['Element'] = '{}/{}'.format(curitm.info['Element'], curitm.info['Elem_Res'])
                else:
                    curitm.info['Element'] = '{}/{}'.format(curitm.info['Element'], curitm.info['Elem_Dam'])
                curitm.info['Element'] = Conv_Res(curitm.info['Element'])
            if 'Class' in curitm.info.keys():
                if 'CWar' in curitm.info.keys():
                    clss = curitm.info
                    cttl = 0
                    tcls = []
                    if clss['Cwar']:
                        tcls.append('W')
                        cttl += 1
                    if clss['CRog']:
                        tcls.append('R')
                        cttl += 1
                    if clss['CCle']:
                        tcls.append('C')
                        cttl += 1
                    if clss['CMag']:
                        tcls.append('M')
                        cttl += 1
                    if cttl == 4:
                        clss['Class'] = 'All'
                    else:
                        tcls = ', '.join(tcls)
                        clss['Class'] = tcls
            if 'Skills' in curitm.info.keys():
                skl = curitm.info['Skills']
                if skl:
                    skl = skl.split(';')
                    tsk = []
                    for skill in skl:
                        skill = skill.replace('[', '')
                        skill = skill.replace(']', '')
                        skill = skill.replace('_', ' ')
                        if '#' in skill:
                            skill = skill.split('#')
                        else:
                            skill = skill.split(':')
                        tsk.append('[[{}]]: {}'.format(skill[0], skill[1].strip()))
                    curitm.info['Skills'] = '; '.join(tsk)
            if 'Attributes' in curitm.info.keys():
                atb = curitm.info['Attributes']
                if atb:
                    if ',' in atb:
                        atb = atb.split(',')
                    else:
                        atb = atb.split(';')
                    tatb = []
                    for attb in atb:
                        attb = attb.replace('[', '')
                        attb = attb.replace(']', '')
                        attb = attb.title()
                        tatb.append('[[{}]]'.format(attb))
                    curitm.info['Attributes'] = '; '.join(tatb)
        tmplist.sort(key=self.datasrc.sortKey)
        self.MList = tmplist
        eklog.info('{} Database Loaded'.format(ldb))


class update_info:
    def __init__(self, curdb):
        self.skilldata = None
        self.itemdata = None
        self.mobdata = None
        self.armordata = None
        self.weapondata = None
        self.questdata = None
        self.npcdata = None
        self.sqldb = dbaccess.DatabaseAccess(curdb)

    def getdata(self):
        BaseUpdate.sqldb = self.sqldb
        self.mobdata = BaseUpdate('MobList.txt', mobdata, 'nbeast')
        self.skilldata = BaseUpdate('Skills.txt', skilldata, 'Skills')
        self.itemdata = BaseUpdate('ItemsList.txt', itmdata, 'Items')
        self.armordata = BaseUpdate('ArmorList.txt', armdata, 'Armor')
        self.weapondata = BaseUpdate('WeaponsList.txt', wpndata, 'Weapon')
        self.questdata = BaseUpdate('QuestsList.txt', qstdata, 'Quest')
        self.nonpcdata = BaseUpdate('NPCList.txt', npcdata, 'NPC')
        eklog.info('All data loaded')

    def updateitms(self, itmu):
        if itmu == 'Mob' or itmu == 'All':
            #self.sqldb.remove_item('nbeast', 'Name', 'Monstrous Spider')
            #self.sqldb.remove_item('Beastiary', 'name', 'Monstrous Spider')
            self.mobdata.load_database('Beastiary', 'nbeast')
            newmobdata = LdDmp('Mobs.txt')
            newmobdata.breakdown()
            self.mobdata.bsort()
            self.mobdata.combdata()
            self.mobdata.combdata(newmobdata.Data)
        if itmu == 'Skill' or itmu == 'All':
            self.skilldata.bsort()
        if itmu == 'Item' or itmu == 'All':
            self.itemdata.bsort()
        if itmu == 'Armor' or itmu == 'All':
            self.armordata.bsort()
        if itmu == 'Weapon' or itmu == 'All':
            self.weapondata.bsort()
        if itmu == 'Quest' or itmu == 'All':
            self.questdata.bsort()
        if itmu == 'NPC' or itmu == 'All':
            self.nonpcdata.bsort()

    def writewikifl(self, wkflot):
        if wkflot == 'Mob' or wkflot == 'All':
            self.mobdata.maketxt('mob3.txt', 'mob3tbl.txt')
        if wkflot == 'Skill' or wkflot == 'All':
            self.skilldata.maketxt('skills3.txt', 'skills3tbl.txt')
        if wkflot == 'Item' or wkflot == 'All':
            self.itemdata.maketxt('items3.txt', 'items3tbl.txt')
        if wkflot == 'Armor' or wkflot == 'All':
            self.armordata.maketxt('armor3.txt', 'armor3tbl.txt')
        if wkflot == 'Weapon' or wkflot == 'All':
            self.weapondata.maketxt('weapon3.txt', 'weapon3tbl.txt')
        if wkflot == 'Quest' or wkflot == 'All':
            self.questdata.maketxt('quest3.txt', 'quest3tbl.txt')
        if wkflot == 'NPC' or wkflot == 'All':
            self.nonpcdata.maketxt('npc3.txt', 'npc3tbl.txt')
        eklog.info('Text files for wiki written')

    def writedb(self, dbuitm, rmake=False):
        if dbuitm == 'Mob' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.mobdata.update_database()
        if dbuitm == 'Skill' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.skilldata.update_database()
        if dbuitm == 'Item' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.itemdata.update_database()
        if dbuitm == 'Armor' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.armordata.update_database()
        if dbuitm == 'Weapon' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.weapondata.update_database()
        if dbuitm == 'Quest' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.questdata.update_database()
        if dbuitm == 'NPC' or dbuitm == 'All':
            if rmake:
                self.createtable(dbuitm)
            self.nonpcdata.update_database()

    def createtable(self, tbl):
        makeTable(self.sqldb, tbl)


def load_file(flnm, flwt=None):
    if flwt:
        with open(flnm, 'w') as f:
            f.write(flwt)
        eklog.info('File: {} successfully written'.format(flnm))
    else:
        lnlst = []
        with open(flnm, 'r') as f:
            for line in f:
                lnlst.append(line)
        eklog.info('File: {} successfully loaded'.format(flnm))
        return lnlst

def Conv_Res(resist, rev=False):
    EleTypes = ('Fire', 'Cold', 'Shock',
	                'Death', 'Toxic', 'Spirit')
    txtres = ''
    reslst = [0,0,0,0,0,0]
    if resist == '' or resist == ' ' or resist == '/':
        return [[0,0,0,0,0,0], '']
    if type(resist) is list:
        if len(resist) < 3:
            if '/' in resist:
                pass
            elif resist[1]:
                resist = resist[1]
            else:
                resist = [str(i) for i in resist]
                resist = ','.join(resist)
        else:
            resist = [str(i) for i in resist]
            resist = ','.join(resist)
    if '[' not in resist:
        resist = resist.split(',')
        for idx, ele in enumerate(resist):
            if int(ele) != 0:
                if txtres == '':
                    txtres = '[[{}]]: {}'.format(EleTypes[idx], ele)
                else:
                    txtres += ', [[{}]]: {}'.format(EleTypes[idx], ele)
            else:
                txtres += ''
            reslst[idx] = int(ele)
    else:
        txtres = resist
        resistt = ''
        if ',' in resist:
            resistt = resist.replace(']]', '')
            resistt = resistt.replace('[[', '')
            #eklog.info(', - {}'.format(resistt))
            resistt = resistt.split(',')
        elif '/' in resist:
            resistt = resist.replace(']]', '')
            resistt = resistt.replace('[[', '')
            resistt = resistt.split('/')
            #eklog.info('Raw={}'.format(resistt))
            half = 0
            if len(resistt) > 2:
                half = int(len(resistt) / 2)
            else:
                half = 1
            ctr = half
            tmpre = []
            tmpret = ''
            for i in resistt:
                tmpre.append('{}: {}'.format(i, resistt[ctr]))
                tmpret += '[[{}]]/'.format(i)
                ctr += 1
                if ctr == len(resistt):
                    break
            resistt = tmpre
            txtres = tmpret[:-1]
            #eklog.info('Fixed={}'.format(resistt))
        else:
            resistt = resist.split('[[')
            #eklog.info(resistt)
            resistt = [i.split(']]') for i in resistt]
            resistt.pop(0)
            resistt = [', '.join(x) for x in resistt]
        #eklog.info(resistt)
        for ele in resistt:
            ele = ele.split(':')
            ele[1] = ele[1].strip()
            if ele[0] == 'Fire':
                reslst[0] = int(ele[1])
            elif ele[0] == 'Cold':
                reslst[1] = int(ele[1])
            elif ele[0] == 'Shock':
                reslst[2] = int(ele[1])
            elif ele[0] == 'Death':
                reslst[3] = int(ele[1])
            elif ele[0] == 'Toxic':
                reslst[4] = int(ele[1])
            elif ele[0] == 'Spirit':
                reslst[5] = int(ele[1])
    return [reslst, txtres]

def makeTable(msql, tbl):
    if tbl == 'Mob' or tbl == 'All':
        ncollist = ('spawn_ID varchar', 'Name varchar', 'Race varchar',
            'Class varchar', 'LevelL integer', 'LevelH integer', 'weapon_ID varchar',
            'Defense integer', 'Resistances varchar', 'Movement float',
            'Attributes varchar', 'Drops varchar', 'Icon varchar', 'Size float',
            'Skills varchar', 'AI varchar', 'Faction varchar', 'Gender varchar',
            'Portrait integer', 'onDieConditions varchar', 'onDieActions varchar',
            'onAggroSound varchar', 'onDieSound varchar', 'Groups Text',
            'Location memo', 'Long_Description memo', 'Description memo',
            'Quest memo', 'XP integer', 'HP integer', 'MP integer',
            'Armor integer', 'DPS float', 'Attack_Speed integer',
            'Base_damage varchar', 'Critical varchar',
            'Extra_damage varchar', 'Notes memo') # , 'Type varchar')
        ocollist = ('spawn_ID', 'name', 'race',
            'class', 'minlevel', 'maxlevel', 'weapon_id',
            'defense', 'resist', 'movement',
            'attributes', 'loot', 'sprite', 'Size',
            'Skillset', 'AI', 'faction', 'gender',
            'portrait', 'onDieConditions', 'onDieActions',
            'onAggroSound', 'onDieSound', 'Type',
            'Location', 'Long_Description', 'Description',
            'Quest')
        try:
            msql.drop_table('nbeast')
        except:
            eklog.info('No nbeast table to drop')
        msql.add_table('nbeast', ncollist) #, 'Beastiary', ocollist)
    if tbl == 'Skill' or tbl == 'All':
        skillfld = ('Name varchar', 'Class varchar',
            'CWar bool', 'CRog bool', 'CCle bool',
            'CMag bool', 'CAll bool', 'Gen bool',
            'Adv bool', 'Icon varchar', 'Prerequisite varchar',
            'LearnedFrom varchar', 'Level1Effect varchar',
            'Level1Cost integer', 'Level1ManaCost integer',
            'Level1Cooldown varchar', 'Level2Effect varchar',
            'Level2Cost integer', 'Level2ManaCost integer',
            'Level2Cooldown varchar', 'Level3Effect varchar',
            'Level3Cost integer', 'Level3ManaCost integer',
            'Level3Cooldown varchar', 'Level4Effect varchar',
            'Level4Cost integer', 'Level4ManaCost integer',
            'Level4Cooldown varchar', 'EffectSummary varchar',
            'CostSummary varchar', 'ManaCostSummary varchar',
            'CooldownSummary varchar', 'Long_Description varchar',
            'Description varchar', 'Notes memo')
        try:
            msql.drop_table('Skills')
        except:
            eklog.info('No Skills table to drop')
        msql.add_table('Skills', skillfld)
        eklog.info('Skill Table Added')
    if tbl == 'Item' or tbl == 'All':
        itmfld = ('Name varchar', 'Icon varchar',
            'Groups varchar', 'Class varchar', 'CWar bool',
            'CRog bool', 'CCle bool', 'CMag bool',
            'CAll bool', 'Stackable bool', 'Effect varchar',
            'Effect_Amount varchar', 'Duration_Range varchar',
            'CastingCost integer', 'CastingReq varchar',
            'Value integer', 'Cost integer', 'Quest varchar',
            'Long_Description memo', 'Location memo',
            'Notes memo', 'Description memo')
        try:
            msql.drop_table('Items')
        except:
            eklog.info('No Items table to drop')
        msql.add_table('Items', itmfld)
        eklog.info('Items Table Added')
    if tbl == 'Armor' or tbl == 'All':
        armfld = ('Name varchar', 'Icon varchar',
            'Slot varchar', 'Groups varchar', 'Class varchar',
            'CWar bool', 'CRog bool', 'CCle bool',
            'CMag bool', 'CAll bool', 'Armor integer',
            'Health integer', 'Mana integer', 'Attribute varchar',
            'Element varchar', 'Elem_Res varchar', 'Trait varchar',
            'Trait_Bonus varchar', 'Value integer', 'Cost varchar',
            'Quest varchar', 'Long_Description memo',
            'Location varchar', 'Notes memo', 'Description varchar'
        )
        try:
            msql.drop_table('Armor')
        except:
            eklog.info('No Armor table to drop')
        msql.add_table('Armor', armfld)
        eklog.info('Armor Table Added')
    if tbl == 'Weapon' or tbl == 'All':
        wpnfld = ('Name', 'Icon', 'Type', 
            'Category', 'Groups', 'Class',
            'CWar bool', 'CRog bool', 'CCle bool',
            'CMag bool', 'CAll bool', 'Min',
            'Max', 'Speed', 'Crit', 'DPS',
            'Attribute', 'Element', 'Elem_Dam',
            'Value integer', 'Cost varchar',
            'Quest varchar', 'Long_Description memo',
            'Location varchar', 'Notes memo', 
            'Description varchar')
        try:
            msql.drop_table('Weapon')
        except:
            eklog.info('No Weapon table to drop')
        msql.add_table('Weapon', wpnfld)
        eklog.info('Weapon Table Added')
    if tbl == 'Quest':
        qstfld = ('Name varchar', 'Icon varchar', 'Giver varchar', 'QstNum varchar',
        'LocStart varchar', 'LocCmp1 varchar', 'LocCmp2 varchar', 'LocCmp3 varchar',
        'LocCmp4 varchar', 'LocCmp5 varchar', 'LocCmp6 varchar', 'LocEnd varchar', 'Groups varchar',
        'Steps varchar', 'Walkthrough memo', 
        'Outcome1 varchar', 'Reputation1 varchar', 'Reward1 varchar',
        'Outcome2 varchar', 'Reputation2 varchar', 'Reward2 varchar',
        'Outcome3 varchar', 'Reputation3 varchar', 'Reward3 varchar',
        'Outcome4 varchar', 'Reputation4 varchar', 'Reward4 varchar',
        'Outcome5 varchar', 'Reputation5 varchar', 'Reward5 varchar',
        'Outcome6 varchar', 'Reputation6 varchar', 'Reward6 varchar',
        'Outcome7 varchar', 'Reputation7 varchar', 'Reward7 varchar',
        'Outcome8 varchar', 'Reputation8 varchar', 'Reward8 varchar',
        'Related varchar', 'Completable varchar', 'Notes memo', 
        'Long_Description memo')
        try:
            msql.drop_table('Quest')
        except:
            eklog.info('No Quest table to drop')
        msql.add_table('Quest', qstfld)
        eklog.info('Quest Table Added')
    if tbl == 'NPC':
        npcfld = ('Name varchar', 'Race varchar',
            'Class varchar', 'Level integer', 'Inventory varchar',
            'Icon varchar', 'Faction varchar',
            'Groups Text', 'Quest varchar',
            'Location1 varchar', 'Location2 varchar', 'Situational varchar',
            'Quotation varchar', 'Backstory memo', 'Actions varchar',
            'Description memo', 'Notes memo')
        try:
            msql.drop_table('NPC')
        except:
            eklog.info('No NPC table to drop')
        msql.add_table('NPC', npcfld)
        eklog.info('NPC Table Added')


if __name__ == '__main__':
    eklog.info('EK DB')
    curdb = 'Master Equipment.db3'
    updb = update_info(curdb)
    updb.getdata()
    #updb.updateitms('NPC')
    #updb.writewikifl('NPC')
    #updb.writedb('NPC', True)
    updb.updateitms('All')
    updb.writewikifl('All')
    updb.writedb('All', True)

DataConstruct.py



class BaseInfo:
    def __init__(self):
        self.ltyp = ''
        self.styp = ''
        self.sorter = 'Name'
        self.info = {
            'Name': '', 'Icon': '',
            'Class': '', 'Groups': '',
            'Quest': '', 'CWar': '',
            'CRog': '', 'CCle': '', 
            'CMag': '', 'CAll': '',
            'Value': '', 'Cost': '',
            'Long_Description': '', 'Location': '',
            'Notes': '', 'Description': '',
        }
        #super().__init__()
        
    def wikitblout(self):
        begi = '{{'
        begi += '{}byName|'.format(self.ltyp)
        endd = '|{}'.format(self.styp)
        endd += 'Tbl}}\n'
        cmplt = '{}{}{}'.format(begi, self.info['Name'], endd)
        return cmplt
    
    def uclschk(self):
        tmpbl = []
        if self.info['CWar']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        if self.info['CRog']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        if self.info['CCle']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        if self.info['CMag']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        if self.info['CAll']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        return tmpbl
    
    def __repr__(self):
        return self.info['Name']
    
    def __str__(self):
        return self.info['Name']
    
    def sortKey(self):
        return self.info[self.sorter]

    def fixkeys(self, keylst):
        for key in keylst:
            if key in self.info.keys():
                del self.info[key]


class mobdata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'Mob'
        self.styp = 'Mob'
        self.info.update({'LevelL': '',
            'LevelH': '', 'XP': '',
            'Attributes': '', 'Portrait': '',
            'Skills': '', 'HP': '', 'weapon_ID': '',
            'MP': '', 'Armor': '', 'spawn_ID': '',
            'DPS': '', 'Movement': '',
            'Attack_Speed': '', 'Base_damage': '',
            'Critical': '', 'Drops': '',
            'Resistances': [[0,0,0,0,0,0],''], 'Extra_damage': '',
            'AI': '', 'Faction': '', 'Gender': '',
            'onDieConditions': '', 'onDieActions': '',
            'onAggroSound': '', 'onDieSound': ''})
        self.fixkeys(['CWar','CRog', 'CCle',
            'CMag', 'CAll',
            'Value', 'Cost'])

    def wikiout(self):
        qd = self.info
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|Mob={}\n'.format(qd['Name'])
        wikitxt += '|LevelL={}|LevelH={}|XP={}\n'.format(qd['LevelL'], qd['LevelH'], qd['XP'])
        wikitxt += '|Class={}\n|Attributes={}\n'.format(qd['Class'], qd['Attributes'])
        wikitxt += '|Skills={}\n'.format(qd['Skills'])
        wikitxt += '|HP={}|MP={}|Armor={}\n'.format(qd['HP'], qd['MP'], qd['Armor'])
        wikitxt += '|DPS={}|Movement={}\n'.format(qd['DPS'], qd['Movement'])
        wikitxt += '|Attack_Speed={}|Base_damage={}\n'.format(qd['Attack_Speed'], qd['Base_damage'])
        wikitxt += '|Critical={}|Extra_damage={}\n'.format(qd['Critical'], qd['Extra_damage'])
        wikitxt += '|Resistances={}\n'.format(qd['Resistances'][1])
        wikitxt += '|Groups={}\n'.format(qd['Groups'])
        wikitxt += '|Quest={}\n'.format(qd['Quest'])
        wikitxt += '|Drops={}\n'.format(qd['Drops'])
        wikitxt += '|Long_Description={}\n'.format(qd['Long_Description'])
        wikitxt += '|Location={}\n'.format(qd['Location'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '|Description={}\n'.format(qd['Description'])
        wikitxt += '}}\n\n'
        return wikitxt


class skilldata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'Skill'
        self.styp = 'Skill'
        self.info.update({'Prerequisite': '',
            'LearnedFrom': '', 'Gen': '', 'Adv': '',
            'Level1Effect': '', 'Level1Cost': '',
            'Level1ManaCost': '', 'Level1Cooldown': '',
            'Level2Effect': '', 'Level2Cost': '',
            'Level2ManaCost': '', 'Level2Cooldown': '',
            'Level3Effect': '', 'Level3Cost': '',
            'Level3ManaCost': '', 'Level3Cooldown': '',
            'Level4Effect': '', 'Level4Cost': '',
            'Level4ManaCost': '', 'Level4Cooldown': '',
            'EffectSummary': '', 'CostSummary': '',
            'ManaCostSummary': '', 'CooldownSummary': '',})
        self.fixkeys(['Value', 'Cost',
            'Location', 'Groups', 'Quest'])

    def wikiout(self):
        qd = self.info
        tmpbl = self.uclschk()
        if qd['Gen']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        if qd['Adv']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Skill={}\n'.format(qd['Name'])
        wikitxt += '|Class={}\n'.format(qd['Class'])
        wikitxt += '|CWar={}|CRog={}|CCle={}|CMag={}|CAll={}\n'.format(tmpbl[0], tmpbl[1], tmpbl[2], tmpbl[3], tmpbl[4])
        wikitxt += '|Gen={}|Adv={}\n'.format(tmpbl[5], tmpbl[6])
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|Prerequisite={}\n'.format(qd['Prerequisite'])
        wikitxt += '|LearnedFrom={}\n'.format(qd['LearnedFrom'])
        wikitxt += '|Level1Effect={}\n'.format(qd['Level1Effect'])
        wikitxt += '|Level1Cost={}\n'.format(qd['Level1Cost'])
        wikitxt += '|Level1ManaCost={}\n'.format(qd['Level1ManaCost'])
        wikitxt += '|Level1Cooldown={}\n'.format(qd['Level1Cooldown'])
        wikitxt += '|Level2Effect={}\n'.format(qd['Level2Effect'])
        wikitxt += '|Level2Cost={}\n'.format(qd['Level2Cost'])
        wikitxt += '|Level2ManaCost={}\n'.format(qd['Level2ManaCost'])
        wikitxt += '|Level2Cooldown={}\n'.format(qd['Level2Cooldown'])
        wikitxt += '|Level3Effect={}\n'.format(qd['Level3Effect'])
        wikitxt += '|Level3Cost={}\n'.format(qd['Level3Cost'])
        wikitxt += '|Level3ManaCost={}\n'.format(qd['Level3ManaCost'])
        wikitxt += '|Level3Cooldown={}\n'.format(qd['Level3Cooldown'])
        wikitxt += '|Level4Effect={}\n'.format(qd['Level4Effect'])
        wikitxt += '|Level4Cost={}\n'.format(qd['Level4Cost'])
        wikitxt += '|Level4ManaCost={}\n'.format(qd['Level4ManaCost'])
        wikitxt += '|Level4Cooldown={}\n'.format(qd['Level4Cooldown'])
        wikitxt += '|EffectSummary={}\n'.format(qd['EffectSummary'])
        wikitxt += '|CostSummary={}\n'.format(qd['CostSummary'])
        wikitxt += '|ManaCostSummary={}\n'.format(qd['ManaCostSummary'])
        wikitxt += '|CooldownSummary={}\n'.format(qd['CooldownSummary'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '|Long_Description={}\n'.format(qd['Long_Description'])
        wikitxt += '|Description={}\n'.format(qd['Description'])
        wikitxt += '}}\n\n'
        return wikitxt


class itmdata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'Item'
        self.styp = 'Itm'
        self.info.update({'Stackable': '', 'Effect': '',
            'Effect_Amount': '', 'Duration_Range': '',
            'CastingCost': '', 'CastingReq': ''})

    def wikiout(self):
        qd = self.info
        tmpbl = self.uclschk()
        if qd['Stackable']:
            tmpbl.append('✔')
        else:
            tmpbl.append('')
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|Itm={}\n'.format(qd['Name'])
        wikitxt += '|Groups={}|Class={}\n'.format(qd['Groups'], qd['Class'])
        wikitxt += '|CWar={}|CRog={}|CCle={}|CMag={}|CAll={}\n'.format(tmpbl[0], tmpbl[1], tmpbl[2], tmpbl[3], tmpbl[4])
        wikitxt += '|Stackable={}\n'.format(tmpbl[5])
        wikitxt += '|Effect={}\n'.format(qd['Effect'])
        wikitxt += '|Effect_Amount={}\n'.format(qd['Effect_Amount'])
        wikitxt += '|CastingCost={}\n'.format(qd['CastingCost'])
        wikitxt += '|CastingReq={}\n'.format(qd['CastingReq'])
        wikitxt += '|Duration_Range={}\n'.format(qd['Duration_Range'])
        wikitxt += '|Value={}|Cost='.format(qd['Value'])
        wikitxt += '{{{Cost|'
        wikitxt += '{}'.format(qd['Cost'])
        wikitxt += '}}}\n'
        wikitxt += '|Quest={}\n'.format(qd['Quest'])
        wikitxt += '|Long_Description={}\n'.format(qd['Long_Description'])
        wikitxt += '|Location={}\n'.format(qd['Location'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '|Description={}\n'.format(qd['Description'])
        wikitxt += '}}\n\n'
        return wikitxt


class armdata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'Armor'
        self.styp = 'Arm'
        self.info.update({'Slot': '',
            'Armor': '', 'Health': '',
            'Mana': '', 'Attribute': '',
            'Element': [[0,0,0,0,0,0],''], 'Elem_Res': '', 'Trait': '',
            'Trait_Bonus': ''})

    def wikiout(self):
        qd = self.info
        tmpbl = self.uclschk()
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|Arm={}\n'.format(qd['Name'])
        wikitxt += '|Slot={}\n'.format(qd['Slot'])
        wikitxt += '|Groups={}|Class={}\n'.format(qd['Groups'], qd['Class'])
        wikitxt += '|CWar={}|CRog={}|CCle={}|CMag={}|CAll={}\n'.format(tmpbl[0], tmpbl[1], tmpbl[2], tmpbl[3], tmpbl[4])
        wikitxt += '|Armor={}|Health={}|Mana={}\n'.format(qd['Armor'], qd['Health'], qd['Mana'])
        wikitxt += '|Attribute={}\n'.format(qd['Attribute'])
        wikitxt += '|Element={}|Elem_Res={}\n'.format(qd['Element'][1], qd['Elem_Res'])
        wikitxt += '|Trait={}|Trait_Bonus={}\n'.format(qd['Trait'], qd['Trait_Bonus'])
        wikitxt += '|Value={}|Cost='.format(qd['Value'])
        wikitxt += '{{{Cost|'
        wikitxt += '{}'.format(qd['Cost'])
        wikitxt += '}}}\n'
        wikitxt += '|Quest={}\n'.format(qd['Quest'])
        wikitxt += '|Long_Description={}\n'.format(qd['Long_Description'])
        wikitxt += '|Location={}\n'.format(qd['Location'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '|Description={}\n'.format(qd['Description'])
        wikitxt += '}}\n\n'
        return wikitxt


class wpndata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'Weapon'
        self.styp = 'Wpn'
        self.info.update({'Type': '', 'Category': '',  
            'Min': '', 'Max': '', 'Speed': '', 'Crit': '', 
            'DPS': '', 'Attribute': '', 'Element': [[0,0,0,0,0,0],''], 
            'Elem_Dam': ''})

    def wikiout(self):
        qd = self.info
        tmptbl = self.uclschk()
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|Wpn={}\n'.format(qd['Name'])
        wikitxt += '|Type={}\n'.format(qd['Type'])
        wikitxt += '|Category={}\n'.format(qd['Category'])
        wikitxt += '|Groups={}|Class={}\n'.format(qd['Groups'], qd['Class'])
        wikitxt += '|CWar={}|CRog={}|CCle={}|CMag={}|CAll={}\n'.format(tmptbl[0], tmptbl[1], tmptbl[2], tmptbl[3], tmptbl[4])
        wikitxt += '|Min={}|Max={}|Speed={}|Crit={}\n'.format(qd['Min'], qd['Max'], qd['Speed'], qd['Crit'])
        wikitxt += '|DPS={}\n'.format(qd['DPS'])
        wikitxt += '|Attribute={}\n'.format(qd['Attribute'])
        wikitxt += '|Element={}|Elem_Dam={}\n'.format(qd['Element'][1], qd['Elem_Dam'])
        wikitxt += '|Value={}|Cost='.format(qd['Value'])
        wikitxt += '{{{Cost|'
        wikitxt += '{}'.format(qd['Cost'])
        wikitxt += '}}}\n'
        wikitxt += '|Quest={}\n'.format(qd['Quest'])
        wikitxt += '|Long_Description={}\n'.format(qd['Long_Description'])
        wikitxt += '|Location={}\n'.format(qd['Location'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '|Description={}\n'.format(qd['Description'])
        wikitxt += '}}\n\n'
        return wikitxt


class qstdata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'Quest'
        self.styp = 'Qst'
        self.sorter = 'QstNum'
        self.info.update({'Giver': '', 'QstNum': 0,
            'LocStart': '', 'LocCmp1': '', 'LocCmp2': '', 'LocCmp3': '',
            'LocCmp4': '', 'LocCmp5': '', 'LocCmp6': '', 'LocEnd': '',
            'Steps': '', 'Walkthrough': '', 
            'Outcome1': '', 'Reputation1': '', 'Reward1': '',
            'Outcome2': '', 'Reputation2': '', 'Reward2': '',
            'Outcome3': '', 'Reputation3': '', 'Reward3': '',
            'Outcome4': '', 'Reputation4': '', 'Reward4': '',
            'Outcome5': '', 'Reputation5': '', 'Reward5': '',
            'Outcome6': '', 'Reputation6': '', 'Reward6': '',
            'Outcome7': '', 'Reputation7': '', 'Reward7': '',
            'Outcome8': '', 'Reputation8': '', 'Reward8': '',
            'Related': '', 'Completable': ''})
        self.fixkeys(['Value', 'Cost', 'CWar',
            'CRog', 'CCle', 'CMag', 'CAll', 'Class',
            'Location', 'Quest', 'Description'])

    def wikiout(self):
        qd = self.info
        #wikitxt += '|={}\n'.format(qd[''])
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|Qst={}\n'.format(qd['Name'])
        wikitxt += '|Groups={}|QstNum={}\n'.format(qd['Groups'], qd['QstNum'])
        wikitxt += '|Giver={}\n'.format(qd['Giver'])
        wikitxt += '|LocStart={}\n'.format(qd['LocStart'])
        wikitxt += '|LocCmp1={}|LocCmp2={}\n'.format(qd['LocCmp1'], qd['LocCmp2'])
        wikitxt += '|LocCmp3={}|LocCmp4={}\n'.format(qd['LocCmp3'], qd['LocCmp4'])
        wikitxt += '|LocCmp5={}|LocCmp6={}\n'.format(qd['LocCmp5'], qd['LocCmp6'])
        wikitxt += '|LocEnd={}\n'.format(qd['LocEnd'])
        wikitxt += '|Steps={}\n'.format(qd['Steps'])
        wikitxt += '|Walkthrough={}\n'.format(qd['Walkthrough'])
        wikitxt += '|Outcome1={}\n'.format(qd['Outcome1'])
        wikitxt += '|Reputation1={}\n'.format(qd['Reputation1'])
        wikitxt += '|Reward1={}\n'.format(qd['Reward1'])
        wikitxt += '|Outcome2={}\n'.format(qd['Outcome2'])
        wikitxt += '|Reputation2={}|Reward2={}\n'.format(qd['Reputation2'], qd['Reward2'])
        wikitxt += '|Outcome3={}\n'.format(qd['Outcome3'])
        wikitxt += '|Reputation3={}|Reward3={}\n'.format(qd['Reputation3'], qd['Reward3'])
        wikitxt += '|Outcome4={}\n'.format(qd['Outcome4'])
        wikitxt += '|Reputation4={}|Reward4={}\n'.format(qd['Reputation4'], qd['Reward4'])
        wikitxt += '|Outcome5={}\n'.format(qd['Outcome5'])
        wikitxt += '|Reputation5={}|Reward5={}\n'.format(qd['Reputation5'], qd['Reward5'])
        wikitxt += '|Outcome6={}\n'.format(qd['Outcome6'])
        wikitxt += '|Reputation6={}|Reward6={}\n'.format(qd['Reputation6'], qd['Reward6'])
        wikitxt += '|Outcome7={}\n'.format(qd['Outcome7'])
        wikitxt += '|Reputation7={}|Reward7={}\n'.format(qd['Reputation7'], qd['Reward7'])
        wikitxt += '|Outcome8={}\n'.format(qd['Outcome8'])
        wikitxt += '|Reputation8={}|Reward8={}\n'.format(qd['Reputation8'], qd['Reward8'])
        wikitxt += '|Related={}\n'.format(qd['Related'])
        wikitxt += '|Long_Description={}\n'.format(qd['Long_Description'])
        wikitxt += '|Completable={}\n'.format(qd['Completable'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '}}\n\n'
        return wikitxt


class npcdata(BaseInfo):
    def __init__(self):
        super().__init__()
        self.ltyp = 'NPC'
        self.styp = 'npc'
        self.sorter = 'Name'
        self.info.update({'Race': '',
            'Level': '', 'Inventory': '',
            'Faction': '', 'Location1': '', 'Location2': '',
            'Situational': '',
            'Quotation': '', 'Backstory': '', 'Actions': ''})
        self.fixkeys(['Value', 'Cost', 'CWar',
            'CRog', 'CCle', 'CMag', 'CAll',
            'Location', 'Long_Description'])

    def wikiout(self):
        qd = self.info
        #wikitxt += '|={}\n'.format(qd[''])
        wikitxt  = '|{}=\n'.format(qd['Name'])
        wikitxt += '{{{{{3|Output-Format}}} |Format={{{2}}}\n'
        wikitxt += '|Step={{{4|}}}\n'
        wikitxt += '|Icon={}\n'.format(qd['Icon'])
        wikitxt += '|npc={}\n'.format(qd['Name'])
        wikitxt += '|Race={}|Class={}\n'.format(qd['Race'], qd['Class'])
        wikitxt += '|Level={}|Faction={}\n'.format(qd['Level'], qd['Faction'])
        wikitxt += '|Inventory={}\n'.format(qd['Inventory'])
        wikitxt += '|Quotation={}\n'.format(qd['Quotation'])
        wikitxt += '|Location1={}\n'.format(qd['Location1'])
        wikitxt += '|Location2={}\n'.format(qd['Location2'])
        wikitxt += '|Quest={}\n'.format(qd['Quest'])
        wikitxt += '|Actions={}\n'.format(qd['Actions'])
        wikitxt += '|Backstory={}\n'.format(qd['Backstory'])
        wikitxt += '|Situational={}\n'.format(qd['Situational'])
        wikitxt += '|Description={}\n'.format(qd['Description'])
        wikitxt += '|Notes='
        wikitxt += '{{{Notes|'
        wikitxt += '{}'.format(qd['Notes'])
        wikitxt += '}}}\n'
        wikitxt += '}}\n\n'
        return wikitxt


dbaccess.py

import sqlite3 as lite
import sys

#  ----------Logging Setup----------
import logging
#import setup_logging

#setup_logging.my_logger()
dblog = logging.getLogger(__name__)
#  --------End Logging Setup--------

class DatabaseAccess:
    def __init__(self, dbdir):
        self.conn = None
        self.cur = None
        self.load_db(dbdir)

    def load_db(self, dbdir):
        self.conn = lite.connect(dbdir)
        self.conn.row_factory = lite.Row
        self.cur = self.conn.cursor()

    def close_db(self):
        self.conn.close()

    def commit_changes(self):
        self.conn.commit()

    def get_selected_data(self, table, col, item):
        query = 'SELECT * FROM {} WHERE {}="{}"'.format(table, col, item)
        self.cur.execute(query)
        tbldata = self.cur.fetchall()
        return tbldata

    def get_one_item(self, table, col, item):
        query = 'SELECT * FROM {} WHERE "{}"="{}"'.format(table, col, item)
        self.cur.execute(query)
        tbldata = self.cur.fetchone()
        return tbldata

    def get_table_col(self, table, col, colcond1='', colval=''):
        query = ''
        if colcond1:
            query = 'SELECT "{}" FROM {} WHERE "{}" = "{}";'.format(col, table, colcond1, colval)
        else:
            query = 'SELECT "{}" FROM "{}";'.format(col, table)
        self.cur.execute(query)
        tbldata = self.cur.fetchall()
        #dblog.debug('{} - {}\n {}'.format(colval, tbldata, query))
        tbldata = [title[0] for title in tbldata]
        return tbldata
    
    def get_table_col_names(self, table):
        query = 'SELECT * FROM "{}"'.format(table)
        self.cur.execute(query)
        tblkeys = self.cur.fetchone().keys()
        #dblog.debug(tblkeys)
        return tblkeys

    def get_table(self, table):
        query = 'SELECT * FROM {}'.format(table)
        self.cur.execute(str(query))
        return self.cur.fetchall()
    
    def add_table(self, table, cols, insertfrm=None, rcols=None):
        # cols must be a tuple
        query = 'CREATE TABLE {} ({})'.format(table, ', '.join(cols))
        dblog.info('\nAdd Table Query: {}'.format(query))
        self.cur.execute(query)
        dblog.info('Adding table: {}'.format(table))
        if insertfrm:
            query = '''INSERT INTO {} {} SELECT * FROM {};'''.format(table, rcols, insertfrm)
            self.cur.execute(query)
        self.commit_changes()

    def drop_table(self, table):
        dblog.debug('Dropping Table: {}'.format(table))
        query = 'DROP TABLE {}'.format(table)
        self.cur.execute(query)
        self.commit_changes()

    def add_item(self, table, cols, vals):
        # cols, vals must be tuple
        query = ('INSERT INTO {} {} VALUES {}'.format(table,cols,vals))
        try:
            #dblog.info('Adding: {}'.format(query))
            self.cur.execute(query)
            self.commit_changes()
        except lite.OperationalError:
            dblog.info('{} - {}'.format(sys.exc_info()[0], sys.exc_info()[1]))
            dblog.info('Failed add with: {}'.format(vals))
            return query
        except lite.IntegrityError:
            dblog.info('Item Already Exists: {}'.format(vals))

    def update_item(self, table, colc, sval, selc, selcv, mult=False):
        query = ''
        if mult:
            # sval in format x=c, y=u
            query = ('UPDATE {} SET {} WHERE {}="{}"'.format(table, 
                sval, selc, selcv))
        else:
            query = ('UPDATE {} SET {}="{}"  WHERE {}="{}"'.format(table, 
                colc, sval, selc, selcv))
        
        #dblog.info('Updating Item {}'.format(selcv))
        self.cur.execute(query)
        self.commit_changes()

    def remove_item(self, table, col, title):
        query = 'DELETE FROM {} WHERE {}="{}"'.format(table,col, title)
        try:
            self.cur.execute(query)
            self.commit_changes()
            dblog.debug('Deleted Item')
        except:
            dblog.debug('Failed to Delete Item - Rollingback')
            self.conn.rollback()

    def db_summary(self, table):
        ''' Summary of Table Data '''
        query = 'SELECT COUNT(*) FROM {}'.format(table)
        self.cur.execute(query)
        count = self.cur.fetchall()
        dblog.info('Total Rows: {}'.format(count[0][0]))
        query2 = 'PRAGMA TABLE_INFO({})'.format(table)
        self.cur.execute(query2)
        info = self.cur.fetchall()
        dblog.info('Column Info: \nID, Name, Type, NotNull, DefaultVal, PrimaryKey')
        for col in info:
            tmp = ''
            for item in col:
                tmp += str(item) + ' '
            dblog.info(tmp)

setup_logging.py

import os
import json
import logging.config


class MyLogger():
    def __init__(self,
            default_path = '/sdcard/Git/Base/logcfg.json',
            default_level = logging.INFO,
            env_key = 'LOG_CFG',
            info_filename = None,
            error_filename = None,
            filemode = 'a'):
        self.path = default_path
        self.level = default_level
        self.env_key = env_key
        self.info_filename = info_filename
        self.error_filename = error_filename
        self.filemode = filemode
        self.config = None
        self.load_config()
        
    def load_config(self):
        value = os.getenv(self.env_key, None)
        if value:
            self.path=value
        if os.path.exists(self.path):
            with open(self.path, 'rt') as f:
                self.config = json.load(f)
            self.load_handlers()
            self.config['root']['level'] = self.level
            logging.config.dictConfig(self.config)
        else:
            logging.basicConfig(level=self.level)

    def load_handlers(self):
        if self.info_filename:
            self.setup_handler('info_file_handler', self.info_filename)
        if self.error_filename:
            self.setup_handler('error_file_handler', self.error_filename)
        else:
            self.setup_handler('error_file_handler', self.info_filename)

    def setup_handler(self, txtnm, flref):
        self.config['handlers'][txtnm]['filename'] = flref
        self.config['handlers'][txtnm]['mode'] = self.filemode

if __name__ == "__main__":
    import logging
    my_logger(info_filename='test1.log')
    mlog = logging.getLogger(__name__)
    mlog.info('test')


"""
#  -----------Setup Logging------------
import logging
import setup_logging
log_options = {
    'default_path': '/sdcard/Git/Base/logcfg.json',
    'info_filename': 'MTA.log',
    'error_filename': None,
    'default_level': logging.DEBUG,
    'filemode': 'w'
}
setup_logging.MyLogger(**log_options)
mtalog = logging.getLogger(__name__)
#  ---------End Setup Logging ---------

submodule

#  -----------Setup Logging------------
import logging
sublog = logging.getLogger(__name__)
#  ---------End Setup Logging ---------

"""

logcfg.json

{
    "version": 1,
    "disable_existing_loggers": false,
    "formatters":  {
        "simple":  {
            "format":  "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
            "datefmt":  "%m-%d-%y %H:%M:%S"
        }
    },

    "handlers": {
        "console":  {
            "class":  "logging.StreamHandler",
            "level":  "DEBUG",
            "formatter":  "simple",
            "stream":  "ext://sys.stdout"
        },

        "info_file_handler":  {
            "class":  "logging.FileHandler",
            "level":  "INFO",
            "formatter":  "simple",
            "filename":  "test.log",
            "encoding":  "utf8"
        },

        "error_file_handler":  {
            "class":  "logging.FileHandler",
            "level":  "ERROR",
            "formatter":  "simple",
            "filename":  "test.log",
            "encoding":  "utf8"
        }
    },

    "loggers":  {
        "my_module":  {
            "level":  "INFO",
            "handlers":  ["console"],
            "propagate":  "no"
        }
    },

    "root":  {
        "level":  "INFO",
        "handlers":  ["console", "info_file_handler", "error_file_handler"]
    }
}