From 03cee3293238b077a0eff790a91219714f2c2b7e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:13:13 +0100 Subject: [PATCH 001/310] committed to dropping attribs --- lift.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/lift.py b/lift.py index 22acb311..3c21fddb 100644 --- a/lift.py +++ b/lift.py @@ -49,7 +49,6 @@ def __init__(self, filename,nsyls=None): datetime.datetime.utcnow().isoformat()[:-16], #once/day '.txt'] self.backupfilename=''.join(backupbits) - self.initattribs() self.getguids() #sets: self.guids and self.nguids self.getsenseids() #sets: self.senseids and self.nsenseids log.info("Working on {} with {}, entries " @@ -76,8 +75,6 @@ def __init__(self, filename,nsyls=None): """Think through where this belongs; what classes/functions need it?""" log.info("Language initialization done.") def initattribs(self): - # """This dictionary defines where to find each node in the xml {url}, - # and what we're looking for in each case (node, node text, or attribute # value.""" # """Make all urls fully specified for guid, lang, etc; they will be # removed if the relevant variable is None.""" From d8ee9c1cfbaeb902259c24e22a5f6644855ad5f6 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:14:31 +0100 Subject: [PATCH 002/310] until fixed --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 3c21fddb..084c4575 100644 --- a/lift.py +++ b/lift.py @@ -71,7 +71,7 @@ def __init__(self, filename,nsyls=None): self.slists() #sets: self.c self.v, not done with self.segmentsnotinregexes[lang] self.extrasegments() #tell me if there's anything not in a V or C regex. self.findduplicateforms() - self.findduplicateexamples() + # self.findduplicateexamples() #Fix this! """Think through where this belongs; what classes/functions need it?""" log.info("Language initialization done.") def initattribs(self): From 79e181a570c64a2b1877ee4a3bdea7fe42687b6a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:25:16 +0100 Subject: [PATCH 003/310] reduce url calls --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 084c4575..f3c89622 100644 --- a/lift.py +++ b/lift.py @@ -40,6 +40,7 @@ def __init__(self, filename,nsyls=None): self.debug=False self.filename=filename #lift_file.liftstr() self.logfile=filename+".changes" + self.urls={} #store urls generated """Problems reading a valid LIFT file are dealt with in main.py""" try: self.read() #load and parse the XML file. (Should this go to check?) From 2eff6d8ec7db40f926079a6c0bb72f8e5d1c20ea Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:25:47 +0100 Subject: [PATCH 004/310] don't worry if the rest of this class loads, yet. --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index f3c89622..f586a862 100644 --- a/lift.py +++ b/lift.py @@ -46,6 +46,7 @@ def __init__(self, filename,nsyls=None): self.read() #load and parse the XML file. (Should this go to check?) except: raise BadParseError(self.filename) + return #for testing, for now backupbits=[filename,'_', datetime.datetime.utcnow().isoformat()[:-16], #once/day '.txt'] From aea5f41eefa96e96a5a032757fc730d9a5668cf4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:26:06 +0100 Subject: [PATCH 005/310] don't need this anymore --- lift.py | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/lift.py b/lift.py index f586a862..619b5949 100644 --- a/lift.py +++ b/lift.py @@ -76,33 +76,6 @@ def __init__(self, filename,nsyls=None): # self.findduplicateexamples() #Fix this! """Think through where this belongs; what classes/functions need it?""" log.info("Language initialization done.") - def initattribs(self): - # value.""" - # """Make all urls fully specified for guid, lang, etc; they will be - # removed if the relevant variable is None.""" - # """In the following language attributes, the field
can - # exist in multiple fields, so pay attention to the difference - # between - # form='{analang}' (always in the language to be analyzed: - # lexeme, citation) - # form='{glosslang}' (always in a gloss language: - # gloss, definition) - # form='{lang}' (either: field --under entry, sense, or - # pronunciation) - # Controlling this difference allows for things like getting an entry - # with a form in a particular language, and a gloss in a particular - # (other) language, and/or a tone description () in a - # particular (yet another) language. - # For now, I'm just going to assume people write meta descriptions - # in their primary gloss language. - # url here is a tuple with a base URL and a list of variable names - # that will be added to it later (and/or removed, if None). The URL - # should have each in {braces}, and the variable list each in - # 'quotes', as those are strings/names of variables, to be assigned - # values later. In any case, the names and number of arguments - # should match --except for duplicates in the URL, which - # should occur only once in the variable list. I'm keeping the order - # the same as far as possible, but that doesn't ultimately matter.""" def geturlnattr(self, attribute, **kwargs): if attribute == 'attributes': return self.attribdict.keys() From f36f537618452b91ab642fc081b00e3fddea0bc2 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:26:51 +0100 Subject: [PATCH 006/310] generalize get and getfrom --- lift.py | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 619b5949..f04c1586 100644 --- a/lift.py +++ b/lift.py @@ -100,9 +100,45 @@ def geturlnattr(self, attribute, **kwargs): log.log(2,'After removenone: {}'.format(url)) log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) return {'url':url,'attr':self.attribdict[attribute]['attr']} - def get(self, attribute, **kwargs): - getfrom(self.node, attribute, **kwargs) - def getfrom(node, attribute, **kwargs): + def getwurl(self,node,url,what='node'): + n=node.findall(url) + if n != []: + log.debug("found: {} (x{}), looking for {}".format(n[:1],len(n),what)) + if n == [] or what is None or what == 'node': + return n + elif what == 'text': + r=[i.text for i in n] + log.debug(r) + return r + else: + r=[i.get(what) for i in n] + log.debug(r) + return r + def get(self, target, **kwargs): + return self.getfrom(self.nodes, target, **kwargs) + def getfrom(self, node, target, **kwargs): + base=kwargs['base']=node.tag #in case this is specified, but shouldn't be + # log.info("base: {}".format(base)) + what=kwargs.get('what','node') + path=kwargs.get('path',[]) + if type(path) is not list: + path=kwargs['path']=[path] + showurl=kwargs.get('showurl',False) + kwargs['target']=target #not kwarg here, but we want it to be one for LiftURL + kwargscopy=kwargs.copy() #for only differences that change the URL + kwargscopy.pop('showurl',False) + #unique key, tuple of tuples with str contents only, per url + k=tuple(sorted([(str(x),str(y)) for (x,y) in kwargscopy.items()])) + # k=tuple(sorted(kwargscopy.items())) + if k in self.urls: + url=self.urls[k] + else: + link=LiftURL(**kwargs) #needs base and target to be sensible; attribute? + url=self.urls[k]=link.url + if showurl: + log.info("Using URL {}".format(url)) + return self.getwurl(node,url,what=what) #'what' comes in a kwarg, if wanted + return link.get(node,get) #get="text", "node" or an attribute name """kwargs are guid=None, senseid=None, analang=None, glosslang=None, lang=None, ps=None, form=None, fieldtype=None, location=None, fieldvalue=None, showurl=False):""" From 39af273fef79cad29c9571eb79faad884ce53a9c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:27:43 +0100 Subject: [PATCH 007/310] no longer needed --- lift.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/lift.py b/lift.py index f04c1586..5edf6458 100644 --- a/lift.py +++ b/lift.py @@ -149,17 +149,6 @@ def getfrom(self, node, target, **kwargs): access them consistently later.""" """I need to be careful to not mix up lang=glosslang and lang=analang: @lang should only be used here when referring to a field.""" - if attribute == 'Test': - from random import randint - guid=self.guids[randint(0, len(self.guids))-1] - log.info("Showing info for randomly selected *entry*: {}".format(guid)) - for attribute in self.geturlnattr('attributes'): - log.info('{}: {}'.format(attribute,self.get(attribute,guid=guid)))#,showurl=True - senseid=self.senseids[randint(0, len(self.senseids))-1] - log.info("Showing info for randomly selected *sense*: {}".format(senseid)) - for attribute in self.geturlnattr('attributes'): - log.info('{}: {}'.format(attribute,self.get(attribute,senseid=senseid)))#,showurl=True - return log.log(3,'kwargs: {}'.format(kwargs)) """pull output from urlnattr, where first is string with {}, second is strings naming fields. convert those names to field values here, From f1187ee7435ce9d86e72c1c39270a2a9dce32905 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:30:13 +0100 Subject: [PATCH 008/310] moving to kwargs --- lift.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/lift.py b/lift.py index 5edf6458..72174106 100644 --- a/lift.py +++ b/lift.py @@ -321,19 +321,25 @@ def addexamplefields(self,**kwargs): # already the relevant node --since it is agnostic of what is already # there. log.info(_("Adding values (in lift.py) : {}").format(kwargs)) - node=self.getsensenode(senseid=kwargs['senseid']) + # showurl=kwargs.get('showurl',False) + senseid=kwargs.get('senseid') + location=kwargs.get('location') node=self.getsensenode(senseid=senseid) if node is None: - log.info("Sorry, this didn't return a node: {}".format( - kwargs['senseid'])) + log.info("Sorry, this didn't return a node: {}".format(senseid)) return + fieldtype=kwargs.get('fieldtype') + fieldvalue=kwargs.get('fieldvalue') # Logic to check if this example already here # This function returns a text node (from any one of a number of # example nodes, which match form, gloss and location) containing a # tone sorting value, or None (if no example nodes match form, gloss # and location) #We're adding a node to kwargs here. - exfieldvalue=self.exampleissameasnew(**kwargs,node=node,showurl=False) + # exfieldvalue=self.get('examplebylocation',senseid=senseid,location=location) + exfieldvalue=self.geturlnattr('exfieldvaluenode',senseid=senseid, + fieldtype=fieldtype,location=location, + fieldvalue=fieldvalue) if exfieldvalue is None: #If not already there, make it. log.info("Didn't find that example already there, creating it...") p=ET.SubElement(node, 'example') From a6af2b9dd8973f28dce4f851479ed8be81628a9d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:33:59 +0100 Subject: [PATCH 009/310] standardize kwarg use --- lift.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lift.py b/lift.py index 72174106..a26b1dac 100644 --- a/lift.py +++ b/lift.py @@ -342,13 +342,18 @@ def addexamplefields(self,**kwargs): fieldvalue=fieldvalue) if exfieldvalue is None: #If not already there, make it. log.info("Didn't find that example already there, creating it...") - p=ET.SubElement(node, 'example') - form=ET.SubElement(p,'form',attrib={'lang':kwargs['analang']}) - t=ET.SubElement(form,'text') - t.text=kwargs['forms'][kwargs['analang']] + analang=kwargs.get('analang') + glosslang=kwargs.get('glosslang') + glosslang2=kwargs.get('glosslang2',None) + db=kwargs.get('db') + forms=db.forms + glosses=db.glosses + glosslangs=db.glosslangs + p=Node(node, tag='example') #ET.SubElement + p.makeformnode(analang,db.analang) """Until I have reason to do otherwise, I'm going to assume these fields are being filled in in the glosslang language.""" - fieldgloss=ET.SubElement(p,'translation',attrib={'type': + fieldgloss=Node(p,'translation',attrib={'type': 'Frame translation'}) for lang in [kwargs['glosslang'],kwargs['glosslang2']]: if lang != None and lang in kwargs['forms']: @@ -411,10 +416,10 @@ def exampleisnotsameasnew(self, showurl=False, **kwargs): except: log.log(2,'Node: {} ; Likely no text node!'.format(node.tag)) if (node.tag == 'form'): - if ((node.get('lang') == kwargs['analang']) - and (node.find('text').text != kwargs['forms'][kwargs['analang']])): - log.log(2,'{} == {}; {} != {}'.format(node.get('lang'), - kwargs['analang'], node.find('text').text, kwargs['forms'][kwargs['analang']])) + if ((node.get('lang') == analang) + and (node.find('text').text != forms[analang])): + log.info('{} == {}; {} != {}'.format(node.get('lang'), + analang, node.find('text').text, forms[analang])) return elif ((node.tag == 'translation') and (node.get('type') == 'Frame translation')): From 0fd5e95b4f09f37a87433f8604adabd4a7b11d52 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:36:16 +0100 Subject: [PATCH 010/310] doc --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index a26b1dac..dc794165 100644 --- a/lift.py +++ b/lift.py @@ -349,7 +349,7 @@ def addexamplefields(self,**kwargs): forms=db.forms glosses=db.glosses glosslangs=db.glosslangs - p=Node(node, tag='example') #ET.SubElement + p=Node(node, tag='example') p.makeformnode(analang,db.analang) """Until I have reason to do otherwise, I'm going to assume these fields are being filled in in the glosslang language.""" From 1305cdf293462dd446a82dc736c96fe3887af8dd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:37:22 +0100 Subject: [PATCH 011/310] new Node methods --- lift.py | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/lift.py b/lift.py index dc794165..c42b9986 100644 --- a/lift.py +++ b/lift.py @@ -355,35 +355,26 @@ def addexamplefields(self,**kwargs): fields are being filled in in the glosslang language.""" fieldgloss=Node(p,'translation',attrib={'type': 'Frame translation'}) - for lang in [kwargs['glosslang'],kwargs['glosslang2']]: - if lang != None and lang in kwargs['forms']: - form=ET.SubElement(fieldgloss,'form', - attrib={'lang':lang}) - glosstext=ET.SubElement(form,'text') - glosstext.text=kwargs['forms'][lang] - exfield=ET.SubElement(p,'field', - attrib={'type':kwargs['fieldtype']}) - form=ET.SubElement(exfield,'form', - attrib={'lang':kwargs['glosslang']}) - exfieldvalue=ET.SubElement(form,'text') - locfield=ET.SubElement(p,'field',attrib={'type':'location'}) - form=ET.SubElement(locfield,'form', - attrib={'lang':kwargs['glosslang']}) - fieldlocation=ET.SubElement(form,'text') - fieldlocation.text=kwargs['location'] - else: + for lang in glosslangs: + if lang != None and hasattr(forms,lang): + fieldgloss.makeformnode(lang,getattr(forms,lang)) + exfieldvalue=p.makefieldnode(fieldtype,glosslang,gimmetext=True) + p.makefieldnode('location',glosslang,text=location) + else: log.debug("=> Found that example already there") - exfieldvalue.text=kwargs['fieldvalue'] #change this *one* value, either way. + exfieldvalue.text=fieldvalue #change this *one* value, either way. + senseid=kwargs.get('senseid') if 'guid' in kwargs: - self.updatemoddatetime(guid=kwargs['guid'],senseid=kwargs['senseid']) + guid=kwargs.get('guid') + self.updatemoddatetime(guid=guid,senseid=senseid) else: self.updatemoddatetime(senseid=kwargs['senseid']) if self.debug == True: - log.info("add langform: {}".format(kwargs['forms'][kwargs['analang']])) - log.info("add tone: {}".format(['fieldvalue'])) - log.info("add gloss: {}".format(kwargs['forms'][kwargs['glosslang']])) + log.info("add langform: {}".format(forms.analang)) + log.info("add tone: {}".format(fieldvalue)) + log.info("add gloss: {}".format(forms.glosslang)) if glosslang2 != None: - log.info(' '.join("add gloss2:", kwargs['forms'][kwargs['glosslang2']])) + log.info("add gloss2: {}".format(forms.glosslang2)) def forminnode(self,node,value): # Returns True if `value` is in *any* text node child of any form child # of node: [node/'form'/'text' = value] From 46a048e7a4af85bf1f6da09d17d2286b14f7f83c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:38:26 +0100 Subject: [PATCH 012/310] better kwargs --- lift.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index c42b9986..6625570c 100644 --- a/lift.py +++ b/lift.py @@ -396,9 +396,22 @@ def exampleisnotsameasnew(self, showurl=False, **kwargs): # doesn't match (from form, translation and location). If they all match, # then return the tone value node to change.""" tonevalue='' # set now, will change later, or not... - log.log(2,"Looking for bits that don't match") - if kwargs['example'] == None: - log.info("Hey! You gave me an empty example!") + log.info("Looking for bits that don't match") + showurl=kwargs.get('showurl',False) + db=kwargs.get('db') + log.info("kwargs: {}".format(kwargs)) + log.info("db: {}; forms: {}".format(db,db.forms)) + analang=db.analangs[0] + location=db.location + forms=db.forms + glosses=db.glosses + glosslangs=db.glosslangs + glosslang=kwargs.get('glosslang') + glosslang2=kwargs.get('glosslang2',None) + try: + example=kwargs.get('example') + except: + log.info("Hey! You gave me an empty example?!") return for node in kwargs['example']: try: From 29622891888fb3d675e0f050556deece002aab47 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:38:45 +0100 Subject: [PATCH 013/310] better kwargs --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 6625570c..6d6e3834 100644 --- a/lift.py +++ b/lift.py @@ -413,7 +413,7 @@ def exampleisnotsameasnew(self, showurl=False, **kwargs): except: log.info("Hey! You gave me an empty example?!") return - for node in kwargs['example']: + for node in example: try: log.log(2,'Node: {} ; {}'.format(node.tag, node.find('.//text').text)) From 97b041e8af96bcf9fe8fdccbe8882fab025af5cb Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:39:09 +0100 Subject: [PATCH 014/310] visilogs --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 6d6e3834..148a6de0 100644 --- a/lift.py +++ b/lift.py @@ -415,10 +415,10 @@ def exampleisnotsameasnew(self, showurl=False, **kwargs): return for node in example: try: - log.log(2,'Node: {} ; {}'.format(node.tag, + log.info('Node: {} ; {}'.format(node.tag, node.find('.//text').text)) except: - log.log(2,'Node: {} ; Likely no text node!'.format(node.tag)) + log.info('Node: {} ; Likely no text node!'.format(node.tag)) if (node.tag == 'form'): if ((node.get('lang') == analang) and (node.find('text').text != forms[analang])): From 94be118d74e4047b4e0953c31d918c5ff3a8d592 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:40:06 +0100 Subject: [PATCH 015/310] make showurl in kwargs --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 148a6de0..3c0e7912 100644 --- a/lift.py +++ b/lift.py @@ -388,7 +388,7 @@ def convertalltodecomposed(self): if form.get('lang') in self.analangs: for t in form.findall('.//text'): t.text=rx.makeprecomposed(t.text) - def exampleisnotsameasnew(self, showurl=False, **kwargs): + def exampleisnotsameasnew(self, **kwargs): # guid,senseid,analang, glosslang, glosslang2, forms, fieldtype, # location,fieldvalue,example,ps=None, # """This checks all the above information, to see if we're dealing with From e832be3c8ab4b51a160b7d9538d5cc555b802d2f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:40:59 +0100 Subject: [PATCH 016/310] reworked --- lift.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lift.py b/lift.py index 3c0e7912..0a22f28a 100644 --- a/lift.py +++ b/lift.py @@ -427,17 +427,15 @@ def exampleisnotsameasnew(self, **kwargs): return elif ((node.tag == 'translation') and (node.get('type') == 'Frame translation')): - for form in node.find('form'): - if (((form.get('lang') == kwargs['analang']) and - (not self.forminnode(node, - kwargs['forms'][kwargs['analang']]))) or - (('glosslang2' in kwargs) and - (kwargs['glosslang2'] != None) and - (form.get('lang') == kwargs['glosslang2']) and - (not self.forminnode(node, - kwargs['forms'][kwargs['glosslang2']])))): - log.log(2,'translation {} != {}'.format( - node.find('form/text').text, kwargs['forms'])) + for form in node.findall('form'): + l=form.get('lang') + if l is None: + log.info("translation lang empty; can't test it") + continue + glform=db.glosses[l] #getattr(glosses,l,None) + if (l in glosslangs and form.find('text').text != glform): + log.info('{} translation "{}" != "{}"'.format(l, + node.find('form/text').text, glform)) return elif (node.tag == 'field'): if (node.get('type') == 'location'): From 862346fc71ff9fd2a70cb2a863d3a1d3e5730544 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:41:39 +0100 Subject: [PATCH 017/310] reworked --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 0a22f28a..d12325d7 100644 --- a/lift.py +++ b/lift.py @@ -439,9 +439,9 @@ def exampleisnotsameasnew(self, **kwargs): return elif (node.tag == 'field'): if (node.get('type') == 'location'): - if not self.forminnode(node,kwargs['location']): - log.log(2,'location {} not in {}'.format( - kwargs['location'],node)) + thislocation=node.find('form/text').text + if thislocation != location: #not node.find('form/text').text + log.info('location {} not {}'.format(thislocation,location)) return if (node.get('type') == 'tone'): for form in node: From 0c1d7516d942550e60c987c2966096b0491d09d8 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 9 Oct 2021 18:42:15 +0100 Subject: [PATCH 018/310] kwargs --- lift.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index d12325d7..63af9fbe 100644 --- a/lift.py +++ b/lift.py @@ -445,22 +445,22 @@ def exampleisnotsameasnew(self, **kwargs): return if (node.get('type') == 'tone'): for form in node: - if ((form.get('lang') == kwargs['glosslang']) - or (form.get('lang') == kwargs['glosslang2'])): + l=form.get('lang') + if l in glosslangs: """This is set once per example, since this function runs on an example node""" tonevalue=form.find('text') log.debug('tone value found: {}'.format( tonevalue.text)) else: - log.log(2,"Not the same lang for tone form: {}" - "".format(form.get('lang'))) + log.info("Not the same lang for tone form: {}" + "".format(l)) return else: log.debug("Not sure what kind of node I'm dealing with! ({})" "".format(node.tag)) return tonevalue - def exampleissameasnew(self,showurl=False, **kwargs): + def exampleissameasnew(self, **kwargs): # ,guid,senseid,analang, glosslang,glosslang2,forms, fieldtype, # location,fieldvalue,node,ps=None """This looks for any example in the given sense node, with the same From 0c8cb5218106b9af05620d9cafeabb3a7c96333d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:29:50 +0100 Subject: [PATCH 019/310] expand analang across options --- lift.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 63af9fbe..4d8417af 100644 --- a/lift.py +++ b/lift.py @@ -1020,8 +1020,10 @@ def analangs(self): log.log(1,_("Looking for analangs in lift file")) self.audiolangs=[] self.analangs=[] - possibles=list(dict.fromkeys(self.get('lexemelang')+self.get('citation' - 'lang')+self.get('pronunciationlang'))) + lxl=self.get('lang',base='entry',path=['lexeme'],target='form') + lcl=self.get('lang',base='entry',path=['citation'],target='form') + pronl=self.get('lang',base='entry',path=['pronunciation'],target='form') + possibles=list(dict.fromkeys(lxl+lcl+pronl)) log.info(_("Possible analysis language codes found: {}".format(possibles))) for glang in ['fr','en']: if glang in possibles: From eaee8afa6700be69f5b7ef0af9ad054a900f5d68 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:30:52 +0100 Subject: [PATCH 020/310] split out gloss langs --- lift.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 4d8417af..70b900d4 100644 --- a/lift.py +++ b/lift.py @@ -1052,8 +1052,9 @@ def analangs(self): log.debug('Audio languages: {}'.format(self.audiolangs)) log.debug('Analysis languages: {}'.format(self.analangs)) def glosslangs(self): - self.glosslangs=list(dict.fromkeys(self.get('glosslang')+self.get( - 'defnlang'))) + g=self.get('lang',base='sense',target='gloss') + d=self.get('lang',base='sense',target='definition') + self.glosslangs=list(dict.fromkeys(g+d)) log.debug(_("gloss languages found: {}".format(self.glosslangs))) def glossordefn(self,guid=None,senseid=None,lang='ALL',ps=None ,showurl=False): From 82a1acb01982a61d07c122539401bf138c8e9400 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:31:35 +0100 Subject: [PATCH 021/310] just return one of each --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 70b900d4..bfd1931c 100644 --- a/lift.py +++ b/lift.py @@ -1099,7 +1099,8 @@ def citationorlexeme(self,guid=None,senseid=None,lang=None,ps=None ) return forms def fields(self,guid=None,lang=None): #get all the field types in a given entry - return self.get('fieldname',guid=guid,lang=lang)#nfields=0 + return dict(self.get('type',base='field',target='field')).fromkeys()#nfields=0 + # return self.get('fieldname',guid=guid,lang=lang)#nfields=0 def getsenseids(self): #get the number entries in a lift file. self.senseids=self.get('senseid') #,showurl=True self.nsenseids=len(self.senseids) #,guid,lang,fieldtype,location From b6cf330ce337f038da0744a41b22d851f15b6b6d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:32:19 +0100 Subject: [PATCH 022/310] LiftURL class (first full draft) --- lift.py | 499 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 499 insertions(+) diff --git a/lift.py b/lift.py index bfd1931c..e1bcdd7b 100644 --- a/lift.py +++ b/lift.py @@ -1654,6 +1654,505 @@ def __init__(self, xyz): class Unused(): def removedups(x): #This removes duplicates from a list return list(dict.fromkeys(x)) +class LiftURL(): + def build(self,tag,liftattr=None,myattr=None,attrs=None): + buildanother=False + noseparator=False + log.log(21,"building {}, @dict:{}, @{}={}, on top of {}".format(tag, + attrs,liftattr,myattr, self.currentnodename())) + b=tag + if attrs is None: + attrs={liftattr: myattr} + for attr in attrs: + if (None not in [attr,attrs[attr]] and attrs[attr] in self.kwargs + and self.kwargs[attrs[attr]] is not None): + b+="[@{}='{}']".format(attr,self.kwargs[attrs[attr]]) + if ((liftattr is None or (liftattr in self.kwargs #no lift attribute + and self.kwargs[liftattr] is None)) + and tag == 'text' and myattr in self.kwargs #text value to match + and self.kwargs[myattr] is not None): + b="[{}='{}']".format(tag,self.kwargs[myattr]) + noseparator=True + if tag == 'text' and tag in self.targethead: + buildanother=True #the only way to get text node w/o value + self.url+=[b] + if noseparator: + l=self.url + self.url=[i for i in l[:len(l)-2]]+[''.join([i for i in l[len(l)-2:]])] + else: + self.level['cur']+=1 + self.level[self.alias.get(tag,tag)]=self.level['cur'] + log.log(21,"Path so far: {}".format(self.drafturl())) + if buildanother: + self.build(tag) + def parent(self): + self.level['cur']-=2 #go up for this and its parent + self.build("..") + def entry(self): + self.build("entry","guid","guid") + self.bearchildrenof("entry") + def text(self,value): + self.baselevel() + self.build("text",myattr="value") + def form(self,value=None,lang=None): + self.baselevel() + self.kwargs['value']=self.kwargs.get(value,None) #location and tonevalue + log.log(21,"form kwargs: {}".format(self.kwargs)) + self.build("form","lang","lang") #OK if lang is None + if value is not None: + self.text("value") + def citation(self): + self.baselevel() + self.build("citation") + self.form("lcform","analang") + def lexeme(self): + self.baselevel() + self.build("lexical-unit") + self.form("lxform","analang") + def pronunciation(self): + self.baselevel() + self.build("pronunciation") + self.kwargs['ftype']='location' + attrs={"name":"ftype",'value':'location'} + self.trait(attrs=attrs) + self.form("pronunciation",'analang') + def trait(self,attrs={}): + self.baselevel() + self.build("trait",attrs=attrs) + def sense(self): + self.baselevel() + self.build("sense","id","senseid") + self.bearchildrenof("sense") + def ps(self): + self.baselevel() + self.build("grammatical-info","value","ps") + def gloss(self): + self.baselevel() + self.build("gloss","lang","glosslang") + def definition(self): + self.baselevel() + self.build("definition","lang","glosslang") + self.form("definition","glosslang") + def example(self): + self.baselevel() + self.build("example") + self.maybeshow('form') + self.maybeshow('translation') + self.maybeshow('locationfield') + self.maybeshow('tonefield') + def translation(self): + self.baselevel() + self.kwargs['ftype']='Frame translation' + self.kwargs['formtext']='translationvalue' + self.build("translation","type","ftype") + self.form("translationvalue",'glosslang') + def field(self): + self.baselevel() + self.build("field","type","ftype") + def locationfield(self): + self.baselevel() + self.kwargs['ftype']='location' + self.kwargs['formtext']='location' + self.field() + self.form("location",'glosslang') + def tonefield(self): + self.baselevel() + self.kwargs['ftype']='tone' + self.kwargs['formtext']='tonevalue' + self.field() + self.form("tonevalue",'glosslang') + def morphtype(self): + if morphtype in self.kwargs: + attrs={'name':"morph-type",'value':self.kwargs[morphtype]} + self.trait(attrs) # + def attrdonothing(self): + pass + def maybeshow(self,nodename,parent=None): + # for arg in args: + # log.info("maybeshow arg: {}".format(arg)) + if self.shouldshow(nodename): #We need it for a child to show, etc + self.show(nodename,parent) + def show(self,nodename,parent=None): #call this directly if you know you want it + if nodename == 'form': #args:value,lang + if parent is None: + log.error("Sorry, I can't tell what form to pass to this field;" + "\nWhat is its parent?") + return + else: + args=self.formargsbyparent(parent) + elif nodename == 'text': #args:value,lang + args=['formtext'] #This needs to be smarter; different kinds of formtext + else: + args=list() + for arg in args: + log.debug("show arg: {}".format(arg)) + if len(args) == 0: + getattr(self,nodename)() + else: + getattr(self,nodename)(*args) + def formargsbyparent(self,parent): + args=list() + if parent in ['gloss', 'definition']: + args.append(parent) + args.append('glosslang') + if parent in ['lexeme', 'citation', 'example']: + if parent == 'example': + if 'audiolang' not in self.kwargs: + args.append('exampleform') + else: + args.append('exampleaudio') + args.append('analang') + return args + else: + args.append(parent) + args.append('analang') + return args + def lift(self): + log.error("LiftURL is trying to make a lift node; this should never " + "happen; exiting!") + exit() + def bearchildrenof(self,parent): + log.debug("bearing children of {} ({})".format(parent, + self.children[parent])) + for i in self.children[parent]: + log.debug("bearchildrenof i: {}".format(i)) + self.maybeshow(i,parent) + def levelup(self,target): + while self.level.get(target,self.level['cur']+1) < self.level['cur']: + self.parent() + def baselevel(self): + parents=self.parentsof(self.callerfn()) + for target in parents: #self.levelsokfor[self.callerfn()]: #targets: #targets should be ordered, with best first + if target in self.level and self.level[target] == self.level['cur']: + return #if we're on an acceptable level, just stop + elif target in self.level: + self.levelup(target) + elif parents.index(target) < len(parents)-1: + log.debug("level {} not in {}; checking the next one...".format( + target,self.level)) + else: + log.error("last level {} (of {}) not in {}; this is a problem!" + "".format(target,parents,self.level)) + log.error("this is where we're at: {}\n {}".format(self.kwargs, + self.drafturl())) + printurllog() + exit() + def maybeshowtarget(self,parent): + # parent here is a node ancestor to the current origin, which may + # or may not be an ancestor of targethead. If it is, show it. + f=self.getfamilyof(parent,x=[]) + log.log(21,"Maybeshowtarget: {} (family: {})".format(parent,f)) + if self.targethead in f: + if parent in self.level: + log.log(21,"Maybeshowtarget: leveling up to {}".format(parent)) + self.levelup(parent) + else: + log.log(21,"Maybeshowtarget: showing {}".format(parent)) + self.show(parent) + self.showtargetinhighestdecendance(parent) + return True + def showtargetinlowestancestry(self,nodename): + log.log(21,"Running showtargetinlowestancestry for {}/{} on {}".format( + self.targethead,self.targettail,nodename)) + #If were still empty at this point, just do the target if we can + if nodename == [] and self.targethead in self.children[self.base]: + self.show(self.targethead) + return + gen=nodename + g=1 + r=giveup=False + while not r and giveup is False: + log.debug("Trying generation {}".format(g)) + gen=self.parentsof(gen) + for p in gen: + r=self.maybeshowtarget(p) + if r: + break + g+=1 + if g>10: + giveup=True + if giveup is True: + log.error("Hey, I've looked back {} generations, and I don't see" + "an ancestor of {} (target) which is also an ancestor of " + "{} (current node).".format(g,self.targethead,nodename)) + def showtargetinhighestdecendance(self,nodename): + log.debug("Running showtargetinhighestdecendance for {} on {}".format( + self.targethead,nodename)) + children=self.children[nodename] + grandchildren=[i for child in children + if child in self.children + for i in self.children[child] + ] + greatgrandchildren=[i for child in children + if child in self.children + for grandchild in self.children[child] + if grandchild in self.children + for i in self.children[grandchild] + ] + log.debug("Looking for {} in children of {}: {}".format( + self.targethead,nodename,children)) + log.debug("Grandchildren of {}: {}".format(nodename,grandchildren)) + log.debug("Greatgrandchildren of {}: {}".format( + nodename,greatgrandchildren)) + if self.targethead in children: + log.debug("Showing '{}', child of {}".format(self.targethead,nodename)) + self.show(self.targethead,nodename) + elif self.targethead in grandchildren: + log.debug("Found target ({}) in grandchildren of {}: {}".format( + self.targethead,nodename,grandchildren)) + for c in children: + if c in self.children and self.targethead in self.children[c]: + log.debug("Showing '{}', nearest ancenstor".format(c)) + self.show(c,nodename) #others will get picked up below + self.showtargetinhighestdecendance(c) + elif self.targethead in greatgrandchildren: + log.debug("Found target ({}) in gr8grandchildren of {}: {}".format( + self.targethead,nodename,greatgrandchildren)) + for c in children: + for cc in grandchildren: + if cc in self.children and self.targethead in self.children[cc]: + log.debug("Showing '{}', nearest ancenstor".format(c)) + self.show(c,nodename) #others will get picked up below + self.showtargetinhighestdecendance(c) + else: + log.error("Target not found in children, grandchildren, or " + "greatgrandchildren!") + def nodesatlevel(self,levelname='cur'): + if levelname not in self.level: + return [] + cur=[x for x,y in self.level.items() if y == self.level[levelname] + and x != levelname] #obviously not that one... + cur.reverse() + return cur + def parsetargetlineage(self): + if '/' in self.target: #if target lineage is given + self.targetbits=self.target.split('/') + log.debug("{} : {}".format(self.target,self.targetbits)) + self.targethead=self.targetbits[0] + self.targettail=self.targetbits[1:] + else: + self.targetbits=self.targethead=self.target + self.targettail=None + if 'form' in self.targethead: + log.error("Looking for {} as the head of a target is going to " + "cause problems, as it appears in too many places, and is likely " + "to not give the desired results. Fix this, and try again. (whole " + "target: {})".format(self.targethead,self.target)) + exit() + def currentnodename(self): + last=self.url[-1:] + if len(last)>0: + n=last[0].split('[')[0] + return self.getalias(n) + def unalias(self,nodename): + if nodename in self.alias.values(): + for k in self.alias: + if self.alias[k] == nodename: + return k + return nodename #else + def getalias(self,nodename): + return self.alias.get(nodename,nodename) + def maketarget(self): + """start by breaking up target, if expressed as lineage. This is needed + to target form, with example/form distinct from example/field/form. + Without target='example/form', target form will always find field/form, + even if field has a sibling form (as it typically would) under example. + Once the level of the lineage head is decided, the rest of the lineage + is added.""" + # Now operate on the head of the target lineage + log.debug("URL (before {} target): {}".format(self.target,self.drafturl())) + if self.getalias(self.targethead) not in self.level: #If the target hasn't been made yet. + log.debug(self.url) + i=self.currentnodename() + log.debug("URL base: {}; i: {}".format(self.base,i)) + if i is None: #if it is, skip down in any case. + i=self.base + log.debug("URL bit list: {}; i: {}".format(self.url,i)) + if type(i) == list: + i=i[0] #This should be a string + f=self.getfamilyof(i,x=[]) + log.debug("Target: {}; {} family: {}".format(self.targethead,i,f)) + if self.targethead in f: + self.showtargetinhighestdecendance(i) #should get targethead + # return #only do this for the first you find (last placed). + else:#Continue here if target not a current level node decendent: + self.showtargetinlowestancestry(i) + # Either way, we finish by making the target tail, and leveling up. + if self.targettail is not None: + for b in self.targettail: + n=self.targetbits.index(b) + bp=self.targetbits[n-1].split('[')[0]#just the node, not attrs + afterbp=self.drafturl().split(self.unalias(bp)) + log.log(21,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) + if len(afterbp) <=1 or b not in afterbp[1]: + log.log(21,"showing target element {}: {} (of {})".format(n,b,bp)) + self.levelup(bp) + self.show(b,parent=bp) + self.levelup(self.targetbits[-1])#leave last in target, whatever else + def drafturl(self): + return '/'.join(self.url) + def makeurl(self): + self.url='/'.join(self.url) + def printurl(self): + print(self.url) + def usage(self): + log.info("Basic usage of this class includes the following kwargs:\n" + "\tbase: node from which we are pulling (should be supplied)\n" + "\ttarget: node we are looking for\n" + "\tget: thing we want: node (default)/'text'/attribute name\n" + "Below here implies an entry node:\n" + "\tguid: id used to identify a lift entry\n" + "\tlxform: form to find in lexeme form fields\n" + "\tlcform: form to find in citation form fields\n" + "\tmorphtype: type of morpheme (stem, affix, etc)\n" + "\tpronunciation: form to find in pronunciation form fields\n" + "Below here implies a sense node:\n" + "\tsenseid: id used to identify a lift sense\n" + "\tdefinition: definition of sense\n" + "\tgloss: gloss (one word definition) of sense\n" + "Below here implies an example node:\n" + "\ttranslation: Translation of example forms\n" + "\ttonevalue: value of an example tone group (from sorting)\n" + "" + ) + def shouldshow(self,node): + c=self.getfamilyof(node,x=[]) + # This fn is not called by showtargetinhighestgeneration or maketarget + if node == self.targethead: #do this later + log.debug("skipping node {}, in target:{}".format(node,self.target)) + return False #not self.targetlastsibling() + elif self.attrneeds(node,c): + return True + elif self.kwargsneeds(node,c): + return True + elif self.pathneeds(node,c): + return True + else: + return False + def getfamilyof(self,node,x): + log.debug("running kwargshaschildrenof.gen on '{}'".format(node)) + if type(node) is str: + node=[node] + for i in node: + log.debug("running kwargshaschildrenof.gen on '{}'".format(i)) + if i is not '': + ii=self.children.get(i,'') + log.debug("Found '{}' this time!".format(ii)) + if ii is not '': + x+=ii + self.getfamilyof(ii,x) + return x + def pathneeds(self,node,children): + path=self.path + log.debug("Path: {}; children: {}".format(path,children)) + if node in path and node not in self.level: + log.debug("Parent ({}) in path: {}".format(node,path)) + return True + if children != []: + childreninpath=set(children) & set(path) + if childreninpath != set(): + pathnotdone=childreninpath-set(self.level) + if pathnotdone != set(): + log.debug("Found descendant of {} in path, which isn't " + "already there: {}".format(node, pathnotdone)) + return True + return False + def attrneeds(self,node,children): + log.debug("looking attr(s) of {} in {}".format([node]+children, + self.attrs)) + for n in [node]+children: + if n in self.attrs: + log.debug("looking attr(s) of {} in {}".format(n,self.attrs)) + common=set(self.attrs[n])&set(list(self.kwargs)+[self.what]) + if common != set(): + log.debug("Found attr(s) {} requiring {}".format(common,n)) + return True + else: + log.debug("{} not found in {}".format(n,self.attrs.keys())) + return False + def kwargsneeds(self,node,children): + if node in self.kwargs: + log.debug("Parent ({}) in kwargs: {}".format(node,self.kwargs)) + return True + if children != []: + log.debug("Looking for descendants of {} ({}) in kwargs: {}".format( + node,children,self.kwargs)) + childreninkwargs=set(children) & set(self.kwargs) + if childreninkwargs != set(): + log.debug("Found descendants of {} in kwargs: {}".format(node, + childreninkwargs)) + pathnotdone=childreninkwargs-set(self.level) + if pathnotdone != set(): + log.debug("Found descendants of {} in kwargs, which aren't " + "already there: ".format(node,pathnotdone)) + return True + return False + def callerfn(self): + return sys._getframe(2).f_code.co_name #2 gens since this is a fn, too + def parentsof(self,nodenames): + log.debug("children: {}".format(self.children.items())) + log.debug("key pair: {}".format( + ' '.join([str(x) for x in self.children.items() if nodenames in x[1]]))) + p=[] + if type(nodenames) != list: + nodenames=[nodenames] + for nodename in nodenames: + i=[x for x,y in self.children.items() if nodename in y] + i.reverse() + p+=i + plist=list(dict.fromkeys(p)) + log.debug("parents of {}: {}".format(nodenames,plist)) + return plist + def setattrsofnodes(self): + self.attrs={} #These are atttributes we ask for, which require the field + self.attrs['entry']=['guid'] + self.attrs['sense']=['senseid'] + self.attrs['tonefield']=['tonevalue'] + self.attrs['locationfield']=['location'] + def setchildren(self): + """These are the kwargs that imply a field. field names also added to + ensure that depenents get picked up. + """ + # use self.alias.get(tag,tag) where needed! + self.children={} + self.children['lift']=['entry'] + self.children['entry']=['lexeme','pronunciation','sense', + 'citation','morphtype','trait'] + self.children['sense']=['ps','definition','gloss', + 'example','field'] + self.children['example']=['form','translation','locationfield', + 'tonefield','field'] + self.children['field']=['form'] + self.children['lexeme']=['form'] + self.children['citation']=['form'] + self.children['form']=['text'] + self.children['pronunciation']=['field','trait'] + self.children['translation']=['form'] + def setaliases(self): + self.alias={} + self.alias['lexical-unit']='lexeme' + self.alias['grammatical-info']='ps' + def __init__(self, *args,**kwargs): + super(LiftURL, self).__init__() + log.debug("LiftURL called with {}".format(kwargs)) + self.kwargs=kwargs + base=self.base=self.kwargs.pop('base','lift') # where do we start? + target=self.target=self.kwargs.pop('target','entry') # what do we want? + self.parsetargetlineage() + self.what=self.kwargs.pop('what','node') #This should always be there + self.path=kwargs.pop('path',[]) + self.url=[] + self.level={'cur':0,base:0} + self.guid=self.senseid=self.attrdonothing + self.setchildren() + self.setaliases() + self.setattrsofnodes() + self.bearchildrenof(base) + log.debug("Making Target now.") + self.maketarget() + self.makeurl() + log.log(21,"Final URL: {}".format(self.url)) + # self.printurl() """Functions I'm using, but not in a class""" def prettyprint(node): # This fn is for seeing the Element contents before writing them (in case of From 4d9c9893f175b7e6ff937a34ee4b8b6fdd962d8d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:33:03 +0100 Subject: [PATCH 023/310] debug changes --- lift.py | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index e1bcdd7b..65b8f218 100644 --- a/lift.py +++ b/lift.py @@ -2675,7 +2675,9 @@ def getnow(): # def _(x): # return str(x) """To Test:""" - loglevel=5 + # loglevel='Debug' + loglevel='INFO' + print('loglevel=',loglevel) from logsetup import * log=logsetup(loglevel) # filename="/home/kentr/Assignment/Tools/WeSay/dkx/MazHidi_Lift.lift" @@ -2684,6 +2686,125 @@ def getnow(): # filename="/home/kentr/Assignment/Tools/WeSay/gnd/gnd.lift" filename="/home/kentr/Assignment/Tools/WeSay/CAWL_demo/SILCAWL.lift" lift=Lift(filename,nsyls=2) + 'eece7037-3d55-45c7-b765-95546e5fccc6'] + locations=['1ss','Infinitive','Progressive','Isolation'] + glosslang='en' + pss=["Verb","Noun"] + analang='bfj' + # b=LiftURL(bob='ḿe', + # # guid=guid, + # # senseid=senseid, + # # location=location, + # # glosslang=glosslang, + # # ps=ps, + # # base='sense', + # target="sense", + # # tonevalue=3, + # ) + # get entries: lift.get("entry") + # lift.get("entry",what='guid') + # get senses: lift.get("sense") + # lift.get("sense",what='id') + # get *all* pss: lift.get("ps",what='value') + # Never ask for just the form! give the parent, to get a particular form: + # lift.get("lexeme/form",what='text') + # lift.get("example/form",what='text') + # lift.get("citation/form",what='text') + # just 1 of each pss: dict.fromkeys(lift.get("ps",what='value')) + # get tone value: lift.get("text", location=location, path=['tonefield'], + # what='text') + for ps in dict.fromkeys(lift.get("ps",what='value')): + log.info(ps) + # for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"],what='text')): + # log.info(tonevalue) + # log.info('\n'.join([str(x) for x in lift.urls.items()])) + # exit() + # for location in locations: + # # for guid in guids: + for senseid in senseids: + log.info(lift.get("lexeme/form",what='text',ps=ps,#"sense", #target + # tonevalue=tonevalue, + # guid=guid,# + path=['lexeme','tonefield'], senseid=senseid, + # senseid=senseid, + # showurl=True + )) + log.info(lift.get("example/form",what='text',ps=ps,#"sense", #target + # tonevalue=tonevalue, + # guid=guid,# + path=['lexeme','tonefield'], senseid=senseid, + # senseid=senseid, + # showurl=True + )) + log.info(lift.get("citation/form",what='text',ps=ps,#"sense", #target + # tonevalue=tonevalue, + # guid=guid,# + path=['lexeme','tonefield'], senseid=senseid, + # senseid=senseid, + # showurl=True + )) + # log.info(lift.get("sense", #target + # # guid=guid, + # senseid=senseid, + # # showurl=True + # )) + # log.info(lift.get("text", #target + # ps=ps,# guid=guid, + # senseid=senseid, + # location=location, + # path=['tonefield'], + # what='text' + # # showurl=True + # )) + # path=['pronunciation'],# senseid=senseid, + # guid=guid, + # glosslang=glosslang, + # ps=ps, + # base='sense', + # tonevalue=3, + # ) + # log.info(lift.urls) + printurllog() + # log.info('\n'.join([str(x) for x in lift.urls.items()])) + exit()# print('l:',l) + showurl=True + for i in l: + ll=lift.getfrom(i,'example',location="1ss",showurl=showurl) + if ll != []: + # print("ll:",ll) + for ii in ll: + lll=lift.getfrom(ii,'text',analang='en', + path=['example/form'], + # exampleform="to begin", + what='text', + showurl=showurl) + # print(lll) + # for iii in lll: + # print(iii.text) + # lllt=lift.getfrom(ii,'text',analang='en',glosslang='fr', + # path='translation',what='text', + # showurl=showurl) + # if lll != []: + # print("lll:",', '.join(lll)) + showurl=False + # showurl=False + log.info(lift.urls) + # log.info("Done with above") + # fieldtype='tone' + # fieldvalue='1' + # for i in l: + # r=i.findall("field[@type='location']" + # "/form[text='{}']/../.." + # "/field[@type='{}']" + # "/form[text='{}']/../..".format(location,fieldtype,fieldvalue) + # ) + # for ii in r: + # loc=i.find("field[@type='location']/form/text") + # val=i.find("field[@type='{}']/form/text".format(fieldtype)) + # log.info("{}: {}, {}".format(i,loc.text,val.text)) + # print(b.url) + # print(bb.url) + exit() # senseid='26532c2e-fedf-4111-85d2-75b34ed31dd8' senseid='skin (of man)_d56b5a5d-7cbf-49b9-a2dd-24eebb0ae462' lift.modverificationnode(senseid,vtype="V",add="another value3",rm="Added value") From 1e1bcf77be0787dc11d17de960bb35eb57cea361 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:33:21 +0100 Subject: [PATCH 024/310] debug changes --- lift.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lift.py b/lift.py index 65b8f218..341c28c3 100644 --- a/lift.py +++ b/lift.py @@ -2686,6 +2686,15 @@ def getnow(): # filename="/home/kentr/Assignment/Tools/WeSay/gnd/gnd.lift" filename="/home/kentr/Assignment/Tools/WeSay/CAWL_demo/SILCAWL.lift" lift=Lift(filename,nsyls=2) + senseids=["begin_7c6fe6a9-9918-48a8-bc3a-e88e61efa8fa", + 'widen_fceb550d-fc99-40af-a288-0433add4f15', + 'flatten_9fb3d2b4-bc9e-4451-b475-36ee10316e40', + 'swallow_af9c3f8f-71e6-4b9a-805c-f6a148dcab8c', + 'frighten_ecffd944-2861-495f-ae38-e7e9cdad45db'] + guids=['dd3c93bb-0019-4dce-8d7d-21c1cb8a6d4d', + '09926cec-8be1-4f66-964e-4fdd8fa75fdc', + '2902d6b3-89be-4723-a0bb-97925a905e7f', + '9ba02d67-3a44-4b7f-8f39-ea8e510df402', 'eece7037-3d55-45c7-b765-95546e5fccc6'] locations=['1ss','Infinitive','Progressive','Isolation'] glosslang='en' From 05b49b99aff8b8347d9df060641da44dff7ae4f7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:35:17 +0100 Subject: [PATCH 025/310] probably very messed up commit, but I'm removing it all anyway --- lift.py | 937 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 474 insertions(+), 463 deletions(-) diff --git a/lift.py b/lift.py index 341c28c3..0b3436dc 100644 --- a/lift.py +++ b/lift.py @@ -2191,485 +2191,496 @@ def removenone(url): return newurl def getnow(): return datetime.datetime.utcnow().isoformat()[:-7]+'Z' - -#This should be a class, constructed... -a=self.attribdict={} -a['template']={ - 'cm': "Give a prose description here", - 'url': (("url in the XML file, variables OK" - ),['guid','senseid','ps']), - 'attr': 'script'} -a['entry']= { - 'cm': 'use to get entries with a given guid or senseid', - 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']/.." - ),['guid','senseid']), - 'attr':'node'} -a['example']={ - 'cm': 'use to get examples with a given guid or senseid', - 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']/example" - ),['guid','senseid']), - 'attr':'node'} -a['examplebylocation']={ - 'cm': 'use to get examples with a given guid or senseid', - 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']/example" - "/field[@type='location']/form[text='{location}']/../.." - ),['guid','senseid','location']), - 'attr':'node'} -a['guidbyps']={ - 'cm': 'use to get guids of entries with a given ps', - 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - ),['guid','senseid','ps']), - 'attr':'guid'} -a['senseidbyps']={ - 'cm': 'use to get ids of senses with a given ps', - 'url':(("entry/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - ),['senseid','ps']), - 'attr':'id'} -a['guidwanyps']={ - 'cm': 'use to get guids of entries with any ps', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']/grammatical-info[@value]/../.." - ),['guid','analang','senseid']), - 'attr':'guid'} -a['senseidwanyps']={ - 'cm': 'use to get ids of senses with any ps', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']/grammatical-info[@value]/.." - ),['guid','analang','senseid']), - 'attr':'id'} -a['guidbypronfield']={ - 'cm': 'use to get guids of entries with fields at the ' - 'pronunciation level', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']/grammatical-info[@value='{ps}']/../.." - "/pronunciation" - "/trait[@name='location'][@value='{location}']/.." - "/form[@lang='{analang}']/.." - #lang could be any: - "/field[@type='{fieldtype}']/form[@lang='{lang}']/../../.." - ),['guid','analang','senseid','ps','location', - 'fieldtype','lang']), - 'attr':'guid'} -a['guidbypronfieldvalue']={ - 'cm': 'use to get guids of entries with fields at the ' +def another(): + #This should be a class, constructed... + a=attribdict={} + a['template']={ + 'cm': "Give a prose description here", + 'url': (("url in the XML file, variables OK" + ),['guid','senseid','ps']), + 'attr': 'script'} + a['entry']= { + 'cm': 'use to get entries with a given guid or senseid', + 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']/.." + ),['guid','senseid']), + 'attr':'node'} + a['example']={ + 'cm': 'use to get examples with a given guid or senseid', + 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']/example" + ),['guid','senseid']), + 'attr':'node'} + a['examplebylocation']={ + 'cm': 'use to get examples with a given guid or senseid', + 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']/example" + "/field[@type='location']/form[text='{location}']/../.." + ),['guid','senseid','location']), + 'attr':'node'} + a['guidbyps']={ + 'cm': 'use to get guids of entries with a given ps', + 'url':(("entry[@guid='{guid}']/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + ),['guid','senseid','ps']), + 'attr':'guid'} + a['senseidbyps']={ + 'cm': 'use to get ids of senses with a given ps', + 'url':(("entry/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + ),['senseid','ps']), + 'attr':'id'} + a['guidwanyps']={ + 'cm': 'use to get guids of entries with any ps', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']/grammatical-info[@value]/../.." + ),['guid','analang','senseid']), + 'attr':'guid'} + a['senseidwanyps']={ + 'cm': 'use to get ids of senses with any ps', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']/grammatical-info[@value]/.." + ),['guid','analang','senseid']), + 'attr':'id'} + a['guidbypronfield']={ + 'cm': 'use to get guids of entries with fields at the ' 'pronunciation level', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']/grammatical-info[@value='{ps}']/../.." + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']/grammatical-info[@value='{ps}']/../.." "/pronunciation" "/trait[@name='location'][@value='{location}']/.." "/form[@lang='{analang}']/.." - "/field[@type='{fieldtype}']" - "/form[@lang='{lang}'][text='{fieldvalue}']" - "/../../.." # ^ lang could be any + #lang could be any: + "/field[@type='{fieldtype}']/form[@lang='{lang}']/../../.." ),['guid','analang','senseid','ps','location', - 'fieldtype','lang','fieldvalue']), - 'attr':'guid'} -a['senseidbyexfieldvalue']={ - 'cm': 'use to get guids of entries with fields at the ' - 'example level', - 'url':(("entry[@guid='{guid}']" - # "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']" + 'fieldtype','lang']), + 'attr':'guid'} + a['guidbypronfieldvalue']={ + 'cm': 'use to get guids of entries with fields at the ' + 'pronunciation level', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']/grammatical-info[@value='{ps}']/../.." + "/pronunciation" + "/trait[@name='location'][@value='{location}']/.." + "/form[@lang='{analang}']/.." + "/field[@type='{fieldtype}']" + "/form[@lang='{lang}'][text='{fieldvalue}']" + "/../../.." # ^ lang could be any + ),['guid','analang','senseid','ps','location', + 'fieldtype','lang','fieldvalue']), + 'attr':'guid'} + a['senseidbyexfieldvalue']={ + 'cm': 'use to get guids of entries with fields at the ' + 'example level', + 'url':(("entry[@guid='{guid}']" + # "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/example" + "/field[@type='location']" + "/form[@lang='{glosslang}'][text='{location}']" + "/../.." + "/field[@type='{fieldtype}']" + "/form[@lang='{glosslang}']" + "[text='{fieldvalue}']/../../.." + ),['guid','analang','senseid','ps','glosslang', + 'location','fieldtype','fieldvalue']), + 'attr':'id'} + a['guidbyexfieldvalue']={ + 'cm': 'use to get guids of entries with fields at the ' + 'example level', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense" + "/grammatical-info[@value='{ps}']/.." + "/example" + "/field[@type='location']" + "/form[@lang='{glosslang}'][text='{location}']" + "/../.." + "/field[@type='{fieldtype}']" + "/form[@lang='{glosslang}']" + "[text='{fieldvalue}']/../../../.." + ),['guid','analang','ps','location','glosslang', + 'fieldtype','fieldvalue']), + 'attr':'guid'} + a['guidbysensefield']={ + 'cm': 'use to get guids of entries with fields at the ' + 'sense level', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense" "/grammatical-info[@value='{ps}']/.." - "/example" - "/field[@type='location']" - "/form[@lang='{glosslang}'][text='{location}']" - "/../.." + "/field[@type='{fieldtype}']/../.." + ),['guid','analang','ps','fieldtype']), + 'attr':'guid'} + a['guidbyentryfield']={ + 'cm': 'use to get guids of entries with fields at the ' + 'entry level', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/field[@type='{fieldtype}']/.." + ),['guid','analang','senseid','ps','fieldtype']), + 'attr':'guid'} + a['guidbylang']={ + 'cm': 'use to get guids of all entries with lexeme of a ' + 'given lang (or not)', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + ),['guid','analang']), + 'attr':'guid'} + a['guidbysenseid']={ + 'cm': 'use to get guids of sense with particular id', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']/.." + ),['guid','senseid']), + 'attr':'guid'} + a['guid']={ + 'cm': 'use to get guids of all entries (no qualifications)', + 'url':(("entry[@guid='{guid}']" + ),['guid']), + 'attr':'guid'} + a['senseid']={ + 'cm': 'use to get ids of all senses (no qualifications)', + 'url':(("entry" + "/sense[@id='{senseid}']" + ),['senseid']), + 'attr':'id'} + a['senseidbytoneUFgroup']={ + 'cm': 'use to get ids of all senses by tone group', + 'url':(("entry" + "/sense[@id='{senseid}']" "/field[@type='{fieldtype}']" - "/form[@lang='{glosslang}']" - "[text='{fieldvalue}']/../../.." - ),['guid','analang','senseid','ps','glosslang', - 'location','fieldtype','fieldvalue']), - 'attr':'id'} -a['guidbyexfieldvalue']={ - 'cm': 'use to get guids of entries with fields at the ' - 'example level', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense" + "/form[@lang='{lang}'][text='{form}']/../.." + ),['senseid','fieldtype','lang','form']), + 'attr':'id'} + a['guidbylexeme']={ + 'cm': 'use to get guid by ps and lexeme in the specified ' + 'language (no reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/lexical-unit" + "/form[@lang='{analang}'][text='{form}']" + "/../.." # ^ [.=’text'] not until python 3.7 + ),['guid','senseid','ps','analang','form']), + 'attr':'guid'} + a['guidbysense']={ + 'cm': 'use to get guid by ps and citation form in the ' + 'specified language (no reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']/.." + ),['guid','senseid']), + 'attr':'guid'} + a['senseidbylexeme']={ + 'cm': 'use to get senseid by ps and lexeme in the ' + 'specified language (no reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit" + "/form[@lang='{analang}'][text='{form}']/../.." + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + ),['guid','analang','form','senseid','ps']), + 'attr':'id'} + a['guidbycitation']={ + 'cm': 'use to get guid by ps and citation form in the ' + 'specified language (no reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/citation" + "/form[@lang=guid'{analang}'][text='{form}']" + "/../.." # ^ [].=’text'] not until python 3.7 + ),['guid','senseid','ps','analang','form']), + 'attr':'guid'} + a['toneUFfieldvalue']={ + 'cm': 'use to get tone UF values of all senses within the ' + 'constraints specified.', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" "/grammatical-info[@value='{ps}']/.." - "/example" - "/field[@type='location']" - "/form[@lang='{glosslang}'][text='{location}']" - "/../.." "/field[@type='{fieldtype}']" + "/form[@lang='{lang}']/text" + ),['guid','senseid','ps','fieldtype','lang']), + 'attr':'nodetext'} + a['lexemenode']={ + 'cm': 'use to get lexemes of all entries with a form ' + 'in the specified language (no reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/lexical-unit/form[@lang='{analang}']" + ),['guid','senseid','ps','analang']), + 'attr':'node'} + a['lexeme']={ + 'cm': 'use to get lexemes of all entries with a form in ' + 'the specified language (no reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/lexical-unit/form[@lang='{analang}']/text" + ),['guid','senseid','ps','analang']), + 'attr':'nodetext'} + a['citationnode']={ + 'cm': 'use to get citation forms of one or all entries ' + 'with a form in the specified language (no ' + 'reference to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/citation/form[@lang='{analang}']" + ),['guid','senseid','ps','analang']), + 'attr':'node'} + a['citation']={ + 'cm': 'use to get citation forms of one or all entries ' + 'with a form in the specified language (no reference ' + 'to fields)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/citation/form[@lang='{analang}']/text" + ),['guid','senseid','ps','analang']), + 'attr':'nodetext'} + a['definitionnode']={ + 'cm': 'use to get definition nodes of entries', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/definition" "/form[@lang='{glosslang}']" - "[text='{fieldvalue}']/../../../.." - ),['guid','analang','ps','location','glosslang', - 'fieldtype','fieldvalue']), - 'attr':'guid'} -a['guidbysensefield']={ - 'cm': 'use to get guids of entries with fields at the ' - 'sense level', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense" - "/grammatical-info[@value='{ps}']/.." - "/field[@type='{fieldtype}']/../.." - ),['guid','analang','ps','fieldtype']), - 'attr':'guid'} -a['guidbyentryfield']={ - 'cm': 'use to get guids of entries with fields at the ' - 'entry level', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/field[@type='{fieldtype}']/.." - ),['guid','analang','senseid','ps','fieldtype']), - 'attr':'guid'} -a['guidbylang']={ - 'cm': 'use to get guids of all entries with lexeme of a ' - 'given lang (or not)', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - ),['guid','analang']), - 'attr':'guid'} -a['guidbysenseid']={ - 'cm': 'use to get guids of sense with particular id', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']/.." - ),['guid','senseid']), - 'attr':'guid'} -a['guid']={ - 'cm': 'use to get guids of all entries (no qualifications)', - 'url':(("entry[@guid='{guid}']" - ),['guid']), - 'attr':'guid'} -a['senseid']={ - 'cm': 'use to get ids of all senses (no qualifications)', - 'url':(("entry" - "/sense[@id='{senseid}']" - ),['senseid']), - 'attr':'id'} -a['senseidbytoneUFgroup']={ - 'cm': 'use to get ids of all senses by tone group', - 'url':(("entry" - "/sense[@id='{senseid}']" - "/field[@type='{fieldtype}']" - "/form[@lang='{lang}'][text='{form}']/../.." - ),['senseid','fieldtype','lang','form']), - 'attr':'id'} -a['guidbylexeme']={ - 'cm': 'use to get guid by ps and lexeme in the specified ' - 'language (no reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/lexical-unit" - "/form[@lang='{analang}'][text='{form}']" - "/../.." # ^ [.=’text'] not until python 3.7 - ),['guid','senseid','ps','analang','form']), - 'attr':'guid'} -a['guidbysense']={ - 'cm': 'use to get guid by ps and citation form in the ' - 'specified language (no reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']/.." - ),['guid','senseid']), - 'attr':'guid'} -a['senseidbylexeme']={ - 'cm': 'use to get senseid by ps and lexeme in the ' - 'specified language (no reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit" - "/form[@lang='{analang}'][text='{form}']/../.." - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - ),['guid','analang','form','senseid','ps']), - 'attr':'id'} -a['guidbycitation']={ - 'cm': 'use to get guid by ps and citation form in the ' - 'specified language (no reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/citation" - "/form[@lang=guid'{analang}'][text='{form}']" - "/../.." # ^ [].=’text'] not until python 3.7 - ),['guid','senseid','ps','analang','form']), - 'attr':'guid'} -a['toneUFfieldvalue']={ - 'cm': 'use to get tone UF values of all senses within the ' - 'constraints specified.', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/field[@type='{fieldtype}']" - "/form[@lang='{lang}']/text" - ),['guid','senseid','ps','fieldtype','lang']), - 'attr':'nodetext'} -a['lexemenode']={ - 'cm': 'use to get lexemes of all entries with a form ' - 'in the specified language (no reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/lexical-unit/form[@lang='{analang}']" - ),['guid','senseid','ps','analang']), - 'attr':'node'} -a['lexeme']={ - 'cm': 'use to get lexemes of all entries with a form in ' - 'the specified language (no reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/lexical-unit/form[@lang='{analang}']/text" - ),['guid','senseid','ps','analang']), - 'attr':'nodetext'} -a['citationnode']={ - 'cm': 'use to get citation forms of one or all entries ' - 'with a form in the specified language (no ' - 'reference to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/citation/form[@lang='{analang}']" - ),['guid','senseid','ps','analang']), - 'attr':'node'} -a['citation']={ - 'cm': 'use to get citation forms of one or all entries ' - 'with a form in the specified language (no reference ' - 'to fields)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/citation/form[@lang='{analang}']/text" - ),['guid','senseid','ps','analang']), - 'attr':'nodetext'} -a['definitionnode']={ - 'cm': 'use to get definition nodes of entries', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/definition" - "/form[@lang='{glosslang}']" - ),['guid','senseid','ps','glosslang']), - 'attr':'node'} -a['definition']={ - 'cm': 'use to get definitions of entries', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/definition" - "/form[@lang='{glosslang}']/text" - ),['guid','senseid','ps','glosslang']), - 'attr':'nodetext'} -a['glossnode']={ - 'cm': 'use to get gloss nodes', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/gloss[@lang='{glosslang}']" - ),['guid','senseid','ps','glosslang']), - 'attr':'node'} -a['gloss']={ - 'cm': 'use to get glosses of entries', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/gloss[@lang='{glosslang}']/text" - ),['guid','senseid','ps','glosslang']), - 'attr':'nodetext'} -a['fieldnode']={ - 'cm': 'use to get whole field nodes (to modify)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/field[@type='{fieldtype}']/form[@lang='{lang}']" - "/.." - ),['guid','senseid','ps','fieldtype','lang']), - 'attr':'node'} -a['fieldname']={ - 'cm': 'use to get value(s) for type of field in sense', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/field" - ),['guid','senseid','ps']), - 'attr':'type'} -a['fieldvalue']={ - 'cm': 'use to get value(s) for field(s) of a specified ' - '(or all) type(s) with a form in the specified (or ' - 'any) language for one or all entries (no ' - 'reference to fields, nor to lexeme form language)', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/field[@type='{fieldtype}']" - "/form[@lang='{lang}']/text" #This can be ANY lang. - ),['guid','senseid','ps','fieldtype','lang']), - 'attr':'nodetext'} -a['pronunciationbylocation']={ - 'cm': 'use to get value(s) for pronunciation information ' - 'for a given location', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/pronunciation" - "/trait[@name='location'][@value='{location}']" - "/../form[@lang='{analang}']/text" - ),['guid','senseid','ps','location','analang']), - 'attr':'nodetext'} -a['pronunciationfieldname']={ - 'cm': 'use to get value(s) for a field type of a specified ' - '(or not) location', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/pronunciation" - "/trait[@name='location'][@value='{location}']" - "/../field"),['guid','senseid','ps','location']), - 'attr':'type'} -a['pronunciationfieldvalue']={ - 'cm': 'use to get value(s) for <>', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/pronunciation" - "/trait[@name='location'][@value='{location}']/.." - "/field[@type='{fieldtype}']" - "/form[@lang='{lang}']/text" - ),['guid','senseid','ps','location','fieldtype', - 'lang']), #not necessarily glosslang or analang... - 'attr':'nodetext'} -a['exfieldvaluenode']={ - 'cm': 'use to get values of fields at the example level', - 'url':(("entry[@guid='{guid}']" - # "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']" + ),['guid','senseid','ps','glosslang']), + 'attr':'node'} + a['definition']={ + 'cm': 'use to get definitions of entries', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/definition" + "/form[@lang='{glosslang}']/text" + ),['guid','senseid','ps','glosslang']), + 'attr':'nodetext'} + a['glossnode']={ + 'cm': 'use to get gloss nodes', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/gloss[@lang='{glosslang}']" + ),['guid','senseid','ps','glosslang']), + 'attr':'node'} + a['gloss']={ + 'cm': 'use to get glosses of entries', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/gloss[@lang='{glosslang}']/text" + ),['guid','senseid','ps','glosslang']), + 'attr':'nodetext'} + a['fieldnode']={ + 'cm': 'use to get whole field nodes (to modify)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/field[@type='{fieldtype}']/form[@lang='{lang}']" + "/.." + ),['guid','senseid','ps','fieldtype','lang']), + 'attr':'node'} + a['fieldname']={ + 'cm': 'use to get value(s) for type of field in sense', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/field" + ),['guid','senseid','ps']), + 'attr':'type'} + a['fieldvalue']={ + 'cm': 'use to get value(s) for field(s) of a specified ' + '(or all) type(s) with a form in the specified (or ' + 'any) language for one or all entries (no ' + 'reference to fields, nor to lexeme form language)', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/field[@type='{fieldtype}']" + "/form[@lang='{lang}']/text" #This can be ANY lang. + ),['guid','senseid','ps','fieldtype','lang']), + 'attr':'nodetext'} + a['pronunciationbylocation']={ + 'cm': 'use to get value(s) for pronunciation information ' + 'for a given location', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/pronunciation" + "/trait[@name='location'][@value='{location}']" + "/../form[@lang='{analang}']/text" + ),['guid','senseid','ps','location','analang']), + 'attr':'nodetext'} + a['pronunciationfieldname']={ + 'cm': 'use to get value(s) for a field type of a specified ' + '(or not) location', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/pronunciation" + "/trait[@name='location'][@value='{location}']" + "/../field"),['guid','senseid','ps','location']), + 'attr':'type'} + a['pronunciationfieldvalue']={ + 'cm': 'use to get value(s) for <>', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/pronunciation" + "/trait[@name='location'][@value='{location}']/.." + "/field[@type='{fieldtype}']" + "/form[@lang='{lang}']/text" + ),['guid','senseid','ps','location','fieldtype', + 'lang']), #not necessarily glosslang or analang... + 'attr':'nodetext'} + a['exfieldvaluenode']={ + 'cm': 'use to get values of fields at the example level', + 'url':(("entry[@guid='{guid}']" + # "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/example" + "/field[@type='location']" + "/form[@lang='{glosslang}']" + "[text='{location}']/../.." + "/field[@type='{fieldtype}']" + "/form[@lang='{glosslang}']/text" + ),['guid','analang','senseid','ps','glosslang', + 'location','fieldtype']), + 'attr':'node'} + a['exfieldlocation']={ + 'cm': 'use to get location of fields at the example level', + 'url':(("entry[@guid='{guid}']" + "/lexical-unit/form[@lang='{analang}']/../.." + "/sense[@id='{senseid}']" "/grammatical-info[@value='{ps}']/.." "/example" "/field[@type='location']" - "/form[@lang='{glosslang}']" - "[text='{location}']/../.." - "/field[@type='{fieldtype}']" "/form[@lang='{glosslang}']/text" - ),['guid','analang','senseid','ps','glosslang', - 'location','fieldtype']), - 'attr':'node'} -a['exfieldlocation']={ - 'cm': 'use to get location of fields at the example level', - 'url':(("entry[@guid='{guid}']" - "/lexical-unit/form[@lang='{analang}']/../.." - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/example" - "/field[@type='location']" - "/form[@lang='{glosslang}']/text" - ),['guid','analang','senseid','ps','glosslang']), - 'attr':'nodetext'} -a['pronunciationfieldlocation']={ - 'cm': 'use to get value(s) for pronunciation location' - '/context', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/pronunciation" - "/field[@type='{fieldtype}']/.." - "/trait[@name='location']" - ),['guid','senseid','ps','fieldtype']), - 'attr':'value'} -a['pronunciation']={ - 'cm': 'use to get value(s) for pronunciation in fields ' - 'with location specified', - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/pronunciation" - "/trait[@name='location'][@value='{location}']/.." - "/form[@lang='{glosslang}']/text" - ),['guid','senseid','ps','location','glosslang']), - 'attr':'nodetext'} -a['lexemelang']={ - 'cm': "analysis languages used in lexemes", - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/lexical-unit/form" - ),['guid','senseid','ps']), - 'attr': 'lang'} -a['citationlang']={ - 'cm': "analysis languages used in citation forms", - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/citation/form" - ),['guid','senseid','ps']), - 'attr': 'lang'} -a['pronunciationlang']={ - 'cm': "analysis languages used in citation forms", - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/../.." - "/pronunciation/form" - ),['guid','senseid','ps']), - 'attr': 'lang'} -a['glosslang']={ - 'cm': "gloss languages used in glosses", - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/gloss" - ),['guid','senseid','ps']), - 'attr': 'lang'} -a['defnlang']={ - 'cm': "gloss languages used in definitions", - 'url':(("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info[@value='{ps}']/.." - "/definition" - "/form"),['guid','senseid','ps']), - 'attr': 'lang'} -a['illustration']={ - 'cm': "Illustration by entry", - 'url': (("entry[@guid='{guid}']" - "/sense[@id='{senseid}']/illustration" - ),['guid','senseid','ps']), - 'attr': 'href'} -a['ps']={ - 'cm': "Part of speech, or grammatical category", - 'url': (("entry[@guid='{guid}']" - "/sense[@id='{senseid}']" - "/grammatical-info" - ),['guid','senseid']), - 'attr': 'value'} -#URLs for sense nodes: -a['senselocations']={ - 'cm': 'use to get location of fields at the example level, for a ' - 'given sense', - 'url':(("example" - "/field[@type='location']" - "/form[@lang='{glosslang}']/text" - ),['glosslang']), - 'attr':'text'} -a['examplewfieldlocvaluefromsense']={ - 'cm': 'use to get an example with a given tone/exfield ' - 'when you have the sense node.', - 'url':(("example/field[@type='location']" - "/form[text='{location}']/../.." - "/field[@type='{fieldtype}']" - "/form[text='{fieldvalue}']/../.." - ),['location','fieldtype','fieldvalue']), + ),['guid','analang','senseid','ps','glosslang']), + 'attr':'nodetext'} + a['pronunciationfieldlocation']={ + 'cm': 'use to get value(s) for pronunciation location' + '/context', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/pronunciation" + "/field[@type='{fieldtype}']/.." + "/trait[@name='location']" + ),['guid','senseid','ps','fieldtype']), + 'attr':'value'} + a['pronunciation']={ + 'cm': 'use to get value(s) for pronunciation in fields ' + 'with location specified', + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/pronunciation" + "/trait[@name='location'][@value='{location}']/.." + "/form[@lang='{glosslang}']/text" + ),['guid','senseid','ps','location','glosslang']), 'attr':'nodetext'} -#URLs for example nodes: -a['glossofexample']={ - 'cm': 'use to get glosses/translations of examples', - 'url':(("translation[@type='Frame translation']" + a['lexemelang']={ + 'cm': "analysis languages used in lexemes", + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/lexical-unit/form" + ),['guid','senseid','ps']), + 'attr': 'lang'} + a['citationlang']={ + 'cm': "analysis languages used in citation forms", + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/citation/form" + ),['guid','senseid','ps']), + 'attr': 'lang'} + a['pronunciationlang']={ + 'cm': "analysis languages used in citation forms", + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/../.." + "/pronunciation/form" + ),['guid','senseid','ps']), + 'attr': 'lang'} + a['glosslang']={ + 'cm': "gloss languages used in glosses", + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/gloss" + ),['guid','senseid','ps']), + 'attr': 'lang'} + a['defnlang']={ + 'cm': "gloss languages used in definitions", + 'url':(("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info[@value='{ps}']/.." + "/definition" + "/form"),['guid','senseid','ps']), + 'attr': 'lang'} + a['illustration']={ + 'cm': "Illustration by entry", + 'url': (("entry[@guid='{guid}']" + "/sense[@id='{senseid}']/illustration" + ),['guid','senseid','ps']), + 'attr': 'href'} + a['ps']={ + 'cm': "Part of speech, or grammatical category", + 'url': (("entry[@guid='{guid}']" + "/sense[@id='{senseid}']" + "/grammatical-info" + ),['guid','senseid']), + 'attr': 'value'} + #URLs for sense nodes: + a['senselocations']={ + 'cm': 'use to get location of fields at the example level, for a ' + 'given sense', + 'url':(("example" + "/field[@type='location']" "/form[@lang='{glosslang}']/text" - ),['glosslang']), - 'attr':'nodetext'} -a['formofexample']={ - 'cm': 'use to get analang forms of examples', - 'url':(("form[@lang='{lang}']/text" - ),['lang']), - 'attr':'nodetext'} + ),['glosslang']), + 'attr':'text'} + a['examplewfieldlocvaluefromsense']={ + 'cm': 'use to get an example with a given tone/exfield ' + 'when you have the sense node.', + 'url':(("example/field[@type='location']" + "/form[text='{location}']/../.." + "/field[@type='{fieldtype}']" + "/form[text='{fieldvalue}']/../.." + ),['location','fieldtype','fieldvalue']), + 'attr':'nodetext'} + #URLs for example nodes: + a['exampletest']={ + 'cm': 'use to get an example with a given tone/exfield ' + 'when you have the sense node.', + 'url':(("field[@type='location']" + "/form[text='{location}']/../.." + "/field[@type='{fieldtype}']" + "/form[text='{fieldvalue}']/../.." + ),['location','fieldtype','fieldvalue']), + 'attr':'nodetext'} + a['glossofexample']={ + 'cm': 'use to get glosses/translations of examples', + 'url':(("translation[@type='Frame translation']" + "/form[@lang='{glosslang}']/text" + ),['glosslang']), + 'attr':'nodetext'} + a['formofexample']={ + 'cm': 'use to get analang forms of examples', + 'url':(("form[@lang='{lang}']/text" + ),['lang']), + 'attr':'nodetext'} +def printurllog(): + log.info('\n'+'\n'.join([str(x)+'\n '+str(y) for x,y in lift.urls.items()])) if __name__ == '__main__': import time #for testing; remove in production # def _(x): From 075f9bbf9bd73023f28a3bd3fcb1462800065f47 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:37:38 +0100 Subject: [PATCH 026/310] new paradigm --- lift.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 0b3436dc..80e6f591 100644 --- a/lift.py +++ b/lift.py @@ -1102,10 +1102,12 @@ def fields(self,guid=None,lang=None): #get all the field types in a given entry return dict(self.get('type',base='field',target='field')).fromkeys()#nfields=0 # return self.get('fieldname',guid=guid,lang=lang)#nfields=0 def getsenseids(self): #get the number entries in a lift file. - self.senseids=self.get('senseid') #,showurl=True + self.senseids=self.get('senseid',base='sense',target='sense') #,showurl=True self.nsenseids=len(self.senseids) #,guid,lang,fieldtype,location + # log.info(self.nsenseids) def getguids(self): #get the number entries in a lift file. - self.guids=self.get('guid') #,showurl=True + self.guids=self.get('guid',base='entry',target='entry') #,showurl=True + # log.info(self.guids) self.nguids=len(self.guids) #,guid,lang,fieldtype,location def nc(self): nounclasses="1 2 3 4 5 6 7 8 9 10 11 12 13 14" From e702dcbdde609bc7ed72fa2a0be8aa33bf33dc64 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:38:40 +0100 Subject: [PATCH 027/310] new paradigm --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 80e6f591..2d65f2aa 100644 --- a/lift.py +++ b/lift.py @@ -1028,10 +1028,10 @@ def analangs(self): for glang in ['fr','en']: if glang in possibles: for form in ['citation','lexeme']: - gforms=self.get(form,analang=glang) + gforms=self.get(form,base='entry',target=form+'/form',analang=glang) if 0< len(gforms): - log.info("LWC lang {} found in {} field: {}".format( - glang,form,self.get(form,analang=glang))) + # log.info("LWC lang {} found in {} field: {}".format( + # glang,form,self.get(form,analang=glang))) """For Saxwe, and others who have fr or en encoding errors""" if len(gforms) <= 10: log.info("Only {} examples of LWC lang {} found " From cb8841c4289a79d34a06796bc1951698512d6824 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 12 Oct 2021 17:39:52 +0100 Subject: [PATCH 028/310] changes to be rectified later --- lift.py | 67 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/lift.py b/lift.py index 2d65f2aa..37fcf681 100644 --- a/lift.py +++ b/lift.py @@ -22,6 +22,8 @@ def _(x): return x """This returns the root node of an ElementTree tree (the entire tree as nodes), to edit the XML.""" +class Object(object): + pass class TreeParsed(object): def __init__(self, lift): self=Tree(lift).parsed @@ -465,24 +467,32 @@ def exampleissameasnew(self, **kwargs): # location,fieldvalue,node,ps=None """This looks for any example in the given sense node, with the same form, gloss, and location values""" - log.info('Looking for an example node matching these form and gloss' - 'elements: {}'.format(kwargs['forms'])) - examples=kwargs['node'].findall('example') + # showurl=kwargs.get('showurl',False) + node=kwargs.get('node') + # analang=kwargs.get('analang') + # glosslang=kwargs.get('glosslang') + # location=kwargs.get('location') + db=kwargs.get('db') + # glosslang2=kwargs.get('glosslang2',None) + # try: + # example=kwargs.get('example') + log.info('Looking for an example node matching these form and gloss ' + 'elements: {}\n(from these: {})'.format(db.forms,db.__dict__)) + examples=node.findall('example') for example in examples: log.info(_("Looking at example {} ({} of {})").format(example, - examples.index(example), len(examples))) - valuenode=self.exampleisnotsameasnew(**kwargs, example=example - # guid,senseid,analang, - # glosslang,glosslang2,forms, - # fieldtype, - # location,fieldvalue,example,ps=None - ,showurl=False) - if type(valuenode) is ET.Element: #None: #i.e., they *are* the same node - log.info(_("Found it! {}: {}".format(type(valuenode),valuenode.text))) - return valuenode #if you find the example, we're done looking - else: #if not, just keep looking, at next example node + examples.index(example)+1, len(examples))) + valuenode=self.exampleisnotsameasnew(**kwargs, example=example) + if valuenode is None: log.debug('=> This is not the example we are looking ' 'for: {}'.format(valuenode)) + continue + log.info(_("Found it? {}".format(type(valuenode)))) + # log.info(_("Found it? {}: {}".format(type(valuenode),valuenode.text))) + if isinstance(valuenode,ET.Element): #None: #i.e., they *are* the same node + log.info(_("Found it! {}: {}".format(type(valuenode), + valuenode.text))) + return valuenode #if you find the example, we're done looking def findduplicateforms(self): """This removes duplicate form nodes in lx or lc nodes, not much point. """ @@ -523,7 +533,10 @@ def getexdict(example): analangs=[] otheranalangs=[] glosslangs=[] - forms={} + forms=Object() #?!?! + forms.forms=Object() + setattr(forms,'analangs',analangs) + setattr(forms,'glosslangs',glosslangs) analang='' glosslang='' glosslang2='' @@ -539,7 +552,9 @@ def getexdict(example): formnodetext=formnode.find('text') if formnodetext is not None: analangs.append(lang) - forms[lang]=formnodetext.text + setattr(forms,'analang',formnodetext.text) + setattr(forms.forms,lang,forms.analang) + # forms[lang]=formnodetext.text# else: log.log(3,"No formnodetext! (lang: {})".format(lang)) if analangs != []: @@ -557,7 +572,13 @@ def getexdict(example): formnodetext=formnode.find('text') if formnodetext != None: glosslangs.append(lang) - forms[lang]=formnodetext.text + if len(glosslangs) >0: + forms.glosslang2=formnodetext.text + setattr(forms.forms,lang,forms.glosslang2) + else: + forms.glosslang=formnodetext.text + setattr(forms.forms,lang,forms.glosslang) + # forms[lang]=formnodetext.text# else: log.log(4,"No glossformnodetext! ({}; lang: {})".format( lang,formnodetext)) @@ -611,7 +632,7 @@ def compare(x,y): senseindex=senses.index(sense) log.log(3,"Working on sense {}: {}".format(senseindex, sense.get('id'))) - examples=sense.findall('example') + examples=sense.findall('example') #'senselocations' for example in examples: #If empty node, remove it if len(example) == 0: @@ -644,7 +665,7 @@ def compare(x,y): othertonevalue=self.exampleisnotsameasnew( node=sense, example=example2, - forms=ex1[0], + db=ex1[0], analang=ex1[1], glosslang=ex1[2], glosslang2=ex1[3], @@ -920,15 +941,15 @@ def updateexfieldvalue(self,guid=None,senseid=None,analang=None, newfieldvalue=None,showurl=False): """This updates the fieldvalue, based on current value. It assumes there is a field already there; use addexamplefields if not""" - urlnattr=self.geturlnattr('exfieldvalue',senseid=senseid, + node=self.geturlnattr('exfieldvaluenode',senseid=senseid, fieldtype=fieldtype, location=location, fieldvalue=fieldvalue - ) #just give me the sense. - url=urlnattr['url'] + ) + # url=urlnattr['url'] if showurl==True: log.info(url) - node=self.nodes.find(url) #this should always find just one node + # node=self.nodes.find(url) #this should always find just one node # for value in node.findall(f"field[@type=location]/" # f"form[text='{location}']" # f"[@type='{fieldtype}']/" From d34aa0d8c861a1937298e417e5acf29ecab9d398 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:51:18 +0100 Subject: [PATCH 029/310] this will be in tail of target --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 671e05cc..0d7da108 100644 --- a/lift.py +++ b/lift.py @@ -1712,7 +1712,7 @@ def build(self,tag,liftattr=None,myattr=None,attrs=None): and self.kwargs[myattr] is not None): b="[{}='{}']".format(tag,self.kwargs[myattr]) noseparator=True - if tag == 'text' and tag in self.targethead: + if tag == 'text' and tag in self.targettail: buildanother=True #the only way to get text node w/o value self.url+=[b] if noseparator: From dcc53c370dd4b22a97781315902308f6e0c8ada4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:52:38 +0100 Subject: [PATCH 030/310] implement name of base --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 0d7da108..a8ae0f52 100644 --- a/lift.py +++ b/lift.py @@ -1894,7 +1894,7 @@ def showtargetinlowestancestry(self,nodename): log.log(21,"Running showtargetinlowestancestry for {}/{} on {}".format( self.targethead,self.targettail,nodename)) #If were still empty at this point, just do the target if we can - if nodename == [] and self.targethead in self.children[self.base]: + if nodename == [] and self.targethead in self.children[self.basename]: self.show(self.targethead) return gen=nodename @@ -2003,9 +2003,9 @@ def maketarget(self): if self.getalias(self.targethead) not in self.level: #If the target hasn't been made yet. log.debug(self.url) i=self.currentnodename() - log.debug("URL base: {}; i: {}".format(self.base,i)) + log.debug("URL base: {}; i: {}".format(self.basename,i)) if i is None: #if it is, skip down in any case. - i=self.base + i=self.basename log.debug("URL bit list: {}; i: {}".format(self.url,i)) if type(i) == list: i=i[0] #This should be a string From dc6ad7eb7aa2b5145b0e61d5a687af6fedcc4e90 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:54:51 +0100 Subject: [PATCH 031/310] testing changes --- lift.py | 95 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 29 deletions(-) diff --git a/lift.py b/lift.py index a8ae0f52..8a301b43 100644 --- a/lift.py +++ b/lift.py @@ -2740,13 +2740,14 @@ def printurllog(): 'widen_fceb550d-fc99-40af-a288-0433add4f15', 'flatten_9fb3d2b4-bc9e-4451-b475-36ee10316e40', 'swallow_af9c3f8f-71e6-4b9a-805c-f6a148dcab8c', - 'frighten_ecffd944-2861-495f-ae38-e7e9cdad45db'] + 'frighten_ecffd944-2861-495f-ae38-e7e9cdad45db', + 'prevent_929504ce-35bb-48fe-ae95-8674a97e625f'] guids=['dd3c93bb-0019-4dce-8d7d-21c1cb8a6d4d', '09926cec-8be1-4f66-964e-4fdd8fa75fdc', '2902d6b3-89be-4723-a0bb-97925a905e7f', '9ba02d67-3a44-4b7f-8f39-ea8e510df402', 'eece7037-3d55-45c7-b765-95546e5fccc6'] - locations=['1ss','Infinitive','Progressive','Isolation'] + locations=['Progressive','Isolation']#,'Progressive','Isolation'] glosslang='en' pss=["Verb","Noun"] analang='bfj' @@ -2772,36 +2773,63 @@ def printurllog(): # just 1 of each pss: dict.fromkeys(lift.get("ps",what='value')) # get tone value: lift.get("text", location=location, path=['tonefield'], # what='text') - for ps in dict.fromkeys(lift.get("ps",what='value')): - log.info(ps) + # for ps in dict.fromkeys(lift.get("ps",what='value')): + # log.info(ps) # for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"],what='text')): # log.info(tonevalue) # log.info('\n'.join([str(x) for x in lift.urls.items()])) # exit() - # for location in locations: - # # for guid in guids: - for senseid in senseids: - log.info(lift.get("lexeme/form",what='text',ps=ps,#"sense", #target - # tonevalue=tonevalue, - # guid=guid,# - path=['lexeme','tonefield'], senseid=senseid, - # senseid=senseid, - # showurl=True - )) - log.info(lift.get("example/form",what='text',ps=ps,#"sense", #target - # tonevalue=tonevalue, - # guid=guid,# - path=['lexeme','tonefield'], senseid=senseid, - # senseid=senseid, - # showurl=True - )) - log.info(lift.get("citation/form",what='text',ps=ps,#"sense", #target - # tonevalue=tonevalue, - # guid=guid,# - path=['lexeme','tonefield'], senseid=senseid, - # senseid=senseid, - # showurl=True - )) + def test(): + for fieldvalue in [2,2]: + for location in locations: + # # for guid in guids: + for senseid in ['prevent_929504ce-35bb-48fe-ae95-8674a97e625f']: + url=lift.get('example/field/form/text', + path=['location','tonefield'], #get this one first + senseid=senseid, + fieldtype='tone',location=location, + tonevalue=fieldvalue, + # what='node' + ) #'text' + exfieldvalue=url.get('node') + for e in exfieldvalue: + log.info("exfieldvalue: {}".format(e.text)) + url.retarget("sense") + # Bind lift object to each url object; or can we store + # this in a way that allows for non-recursive storage + # only of the url object by the lift object? + + ids=url.get('senseid') + for id in [x for x in ids if x is not None]: + log.info("senseid: {}".format(id)) + + # example=lift.get('example', + # path=['location','tonefield'], #get this one first + # senseid=senseid, + # fieldtype='tone',location=location, + # tonevalue=fieldvalue, + # what='node') + # sense=lift.get('sense', + # path=['location','tonefield'], #get this one first + # senseid=senseid, + # fieldtype='tone',location=location, + # tonevalue=fieldvalue, + # what='node') + return + # log.info(lift.get("example/form",what='text',ps=ps,#"sense", #target + # # tonevalue=tonevalue, + # # guid=guid,# + # path=['lexeme','tonefield'], senseid=senseid, + # # senseid=senseid, + # # showurl=True + # )) + # log.info(lift.get("citation/form",what='text',ps=ps,#"sense", #target + # # tonevalue=tonevalue, + # # guid=guid,# + # path=['lexeme','tonefield'], senseid=senseid, + # # senseid=senseid, + # # showurl=True + # )) # log.info(lift.get("sense", #target # # guid=guid, # senseid=senseid, @@ -2822,8 +2850,17 @@ def printurllog(): # base='sense', # tonevalue=3, # ) - # log.info(lift.urls) + test() printurllog() + quit() + import timeit + def timetest(): + times=50 + out1=timeit.timeit(test, number=times) + print(out1) + timetest() + # log.info(lift.urls) + # lift.write() # log.info('\n'.join([str(x) for x in lift.urls.items()])) exit()# print('l:',l) showurl=True From fe51a1831e27cec509602fd9d01945626a077078 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:55:49 +0100 Subject: [PATCH 032/310] align forms (to lists) --- lift.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 8a301b43..8584e736 100644 --- a/lift.py +++ b/lift.py @@ -1970,8 +1970,9 @@ def parsetargetlineage(self): self.targethead=self.targetbits[0] self.targettail=self.targetbits[1:] else: - self.targetbits=self.targethead=self.target - self.targettail=None + self.targethead=self.target + self.targetbits=[self.targethead,] + self.targettail=[] if 'form' in self.targethead: log.error("Looking for {} as the head of a target is going to " "cause problems, as it appears in too many places, and is likely " From cd0567358d11af06522a7f5baf8baf642695bb49 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:56:51 +0100 Subject: [PATCH 033/310] move get to url class --- lift.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lift.py b/lift.py index 8584e736..b9ca076b 100644 --- a/lift.py +++ b/lift.py @@ -102,20 +102,6 @@ def geturlnattr(self, attribute, **kwargs): log.log(2,'After removenone: {}'.format(url)) log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) return {'url':url,'attr':self.attribdict[attribute]['attr']} - def getwurl(self,node,url,what='node'): - n=node.findall(url) - if n != []: - log.debug("found: {} (x{}), looking for {}".format(n[:1],len(n),what)) - if n == [] or what is None or what == 'node': - return n - elif what == 'text': - r=[i.text for i in n] - log.debug(r) - return r - else: - r=[i.get(what) for i in n] - log.debug(r) - return r def get(self, target, **kwargs): return self.getfrom(self.nodes, target, **kwargs) def getfrom(self, node, target, **kwargs): @@ -1694,6 +1680,22 @@ class Unused(): def removedups(x): #This removes duplicates from a list return list(dict.fromkeys(x)) class LiftURL(): + def get(self,what='node'): + log.info(self.__dict__) + n=self.base.findall(self.url) + if n != []: + log.debug("found: {} (x{}), looking for {}".format(n[:1],len(n),what)) + what=self.unalias(what) + if n == [] or what is None or what == 'node': + return n + elif what == 'text': + r=[i.text for i in n] + log.debug(r) + return r + else: + r=[i.get(what) for i in n] + log.debug(r) + return r def build(self,tag,liftattr=None,myattr=None,attrs=None): buildanother=False noseparator=False From 3db8771a8f8957c701f51c34786bbcfc801b49a4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:58:41 +0100 Subject: [PATCH 034/310] adjusting terminology --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index b9ca076b..e378e612 100644 --- a/lift.py +++ b/lift.py @@ -317,7 +317,7 @@ def addexamplefields(self,**kwargs): log.info("Sorry, this didn't return a node: {}".format(senseid)) return fieldtype=kwargs.get('fieldtype') - fieldvalue=kwargs.get('fieldvalue') + tonevalue=kwargs.get('fieldvalue') # Logic to check if this example already here # This function returns a text node (from any one of a number of # example nodes, which match form, gloss and location) containing a From 489225015986c393e53b0947bf5da87d83771305 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 16:59:41 +0100 Subject: [PATCH 035/310] rework for new paradigm --- lift.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lift.py b/lift.py index e378e612..3f473f9d 100644 --- a/lift.py +++ b/lift.py @@ -325,10 +325,18 @@ def addexamplefields(self,**kwargs): # and location) #We're adding a node to kwargs here. # exfieldvalue=self.get('examplebylocation',senseid=senseid,location=location) - exfieldvalue=self.geturlnattr('exfieldvaluenode',senseid=senseid, - fieldtype=fieldtype,location=location, - fieldvalue=fieldvalue) - if exfieldvalue is None: #If not already there, make it. + exfieldvalue=lift.get('example/field/form/text', + path=['location','tonefield'], + senseid=senseid, + fieldtype='tone',location=location, + # tonevalue=fieldvalue, + what='node') + # Do this for all duplicates, which should be removed later anyway. + # I.e., don't leave inconsisted data in the database. + if len(exfieldvalue) > 0: + for e in exfieldvalue: + e.text=tonevalue + else: #If not already there, make it. log.info("Didn't find that example already there, creating it...") analang=kwargs.get('analang') glosslang=kwargs.get('glosslang') From 3cdb41086c635734d55d0384c445620cffebcf99 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:17:28 +0100 Subject: [PATCH 036/310] implement name of base --- lift.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 3f473f9d..8717cc55 100644 --- a/lift.py +++ b/lift.py @@ -2183,21 +2183,22 @@ def setaliases(self): self.alias['lexical-unit']='lexeme' self.alias['grammatical-info']='ps' def __init__(self, *args,**kwargs): + basename=self.basename=self.base.tag super(LiftURL, self).__init__() log.debug("LiftURL called with {}".format(kwargs)) self.kwargs=kwargs - base=self.base=self.kwargs.pop('base','lift') # where do we start? + # base=self.basename=self.kwargs.pop('base','lift') # where do we start? target=self.target=self.kwargs.pop('target','entry') # what do we want? self.parsetargetlineage() self.what=self.kwargs.pop('what','node') #This should always be there self.path=kwargs.pop('path',[]) self.url=[] - self.level={'cur':0,base:0} + self.level={'cur':0,basename:0} self.guid=self.senseid=self.attrdonothing self.setchildren() self.setaliases() self.setattrsofnodes() - self.bearchildrenof(base) + self.bearchildrenof(basename) log.debug("Making Target now.") self.maketarget() self.makeurl() From 730b2a6123c73b58c67c1b4eb47fe4ef578fc86b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:17:55 +0100 Subject: [PATCH 037/310] key fn to find objects --- lift.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lift.py b/lift.py index 8717cc55..215b5c05 100644 --- a/lift.py +++ b/lift.py @@ -102,6 +102,11 @@ def geturlnattr(self, attribute, **kwargs): log.log(2,'After removenone: {}'.format(url)) log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) return {'url':url,'attr':self.attribdict[attribute]['attr']} + def urlkey(self,kwargs): + kwargscopy=kwargs.copy() #for only differences that change the URL + kwargscopy.pop('showurl',False) + k=tuple(sorted([(str(x),str(y)) for (x,y) in kwargscopy.items()])) + return k def get(self, target, **kwargs): return self.getfrom(self.nodes, target, **kwargs) def getfrom(self, node, target, **kwargs): From 5d27fab4e3dc1e713bab17d798d33e2cbdc0bac8 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:18:31 +0100 Subject: [PATCH 038/310] retarget draft --- lift.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lift.py b/lift.py index 215b5c05..ef42fd03 100644 --- a/lift.py +++ b/lift.py @@ -102,6 +102,14 @@ def geturlnattr(self, attribute, **kwargs): log.log(2,'After removenone: {}'.format(url)) log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) return {'url':url,'attr':self.attribdict[attribute]['attr']} + def retarget(self,urlobj): + k=self.urlkey(urlobj.kwargs) + urlobj.kwargs['retarget']=target + k2=self.urlkey(urlobj.kwargs) + if k2 not in self.urls: + self.urls[k2]=copy.deepcopy(urlobj) + self.urls[k2].retarget() + return self.urls[k2] def urlkey(self,kwargs): kwargscopy=kwargs.copy() #for only differences that change the URL kwargscopy.pop('showurl',False) From ee7ecc62b791586dd7143563e0beaef5e8c813d5 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:18:54 +0100 Subject: [PATCH 039/310] this moves to class --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index ef42fd03..e7fb8e9d 100644 --- a/lift.py +++ b/lift.py @@ -118,7 +118,7 @@ def urlkey(self,kwargs): def get(self, target, **kwargs): return self.getfrom(self.nodes, target, **kwargs) def getfrom(self, node, target, **kwargs): - base=kwargs['base']=node.tag #in case this is specified, but shouldn't be + # base=kwargs['base']=node.tag #in case this is specified, but shouldn't be # log.info("base: {}".format(base)) what=kwargs.get('what','node') path=kwargs.get('path',[]) From dad31209107c2545bbf692c132e877cac11d947e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:19:08 +0100 Subject: [PATCH 040/310] to fn --- lift.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lift.py b/lift.py index e7fb8e9d..e3133a66 100644 --- a/lift.py +++ b/lift.py @@ -126,11 +126,7 @@ def getfrom(self, node, target, **kwargs): path=kwargs['path']=[path] showurl=kwargs.get('showurl',False) kwargs['target']=target #not kwarg here, but we want it to be one for LiftURL - kwargscopy=kwargs.copy() #for only differences that change the URL - kwargscopy.pop('showurl',False) - #unique key, tuple of tuples with str contents only, per url - k=tuple(sorted([(str(x),str(y)) for (x,y) in kwargscopy.items()])) - # k=tuple(sorted(kwargscopy.items())) + k=self.urlkey(kwargs) if k in self.urls: url=self.urls[k] else: From 7138cf4bd13c45e39caf1d880b9ea826a46dd311 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:19:47 +0100 Subject: [PATCH 041/310] cleanup --- lift.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lift.py b/lift.py index e3133a66..f6f2cfb4 100644 --- a/lift.py +++ b/lift.py @@ -128,14 +128,12 @@ def getfrom(self, node, target, **kwargs): kwargs['target']=target #not kwarg here, but we want it to be one for LiftURL k=self.urlkey(kwargs) if k in self.urls: - url=self.urls[k] - else: - link=LiftURL(**kwargs) #needs base and target to be sensible; attribute? - url=self.urls[k]=link.url - if showurl: - log.info("Using URL {}".format(url)) - return self.getwurl(node,url,what=what) #'what' comes in a kwarg, if wanted - return link.get(node,get) #get="text", "node" or an attribute name + return self.urls[k] #These are LiftURL objects + link=LiftURL(base=node,**kwargs) #needs base and target to be sensible; attribute? + # if showurl: + # log.info("Using URL {}".format(url)) + # return link.getwurl(node,what=what) #'what' comes in a kwarg, if wanted + return link #.get(node,what=what) #get="text", "node" or an attribute name """kwargs are guid=None, senseid=None, analang=None, glosslang=None, lang=None, ps=None, form=None, fieldtype=None, location=None, fieldvalue=None, showurl=False):""" From 0bd8f00273705d1a0faf04ec35fed57b2c407f31 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:20:07 +0100 Subject: [PATCH 042/310] draft URL retartget method --- lift.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lift.py b/lift.py index f6f2cfb4..d0dc79f9 100644 --- a/lift.py +++ b/lift.py @@ -2009,6 +2009,12 @@ def unalias(self,nodename): return nodename #else def getalias(self,nodename): return self.alias.get(nodename,nodename) + def retarget(self,target): + self.url=[self.url] + self.target=target + self.parsetargetlineage() + self.maketarget() + self.makeurl() def maketarget(self): """start by breaking up target, if expressed as lineage. This is needed to target form, with example/form distinct from example/field/form. From 9239949506f9452481ffdf6b0e04f4b5045dc1dd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:20:46 +0100 Subject: [PATCH 043/310] finish making this, with value in field --- lift.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index d0dc79f9..74b6e14e 100644 --- a/lift.py +++ b/lift.py @@ -363,9 +363,8 @@ def addexamplefields(self,**kwargs): fieldgloss.makeformnode(lang,getattr(forms,lang)) exfieldvalue=p.makefieldnode(fieldtype,glosslang,gimmetext=True) p.makefieldnode('location',glosslang,text=location) - else: - log.debug("=> Found that example already there") - exfieldvalue.text=fieldvalue #change this *one* value, either way. + p.makefieldnode('tone',glosslang,text=tonevalue) + # exfieldvalue.text=fieldvalue #change this *one* value, either way. senseid=kwargs.get('senseid') if 'guid' in kwargs: guid=kwargs.get('guid') From 7c6c4becc343ec779ca4789ef23ac4513abe3b62 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:22:11 +0100 Subject: [PATCH 044/310] bring base defn into class --- lift.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lift.py b/lift.py index 74b6e14e..803bda5f 100644 --- a/lift.py +++ b/lift.py @@ -2195,6 +2195,10 @@ def setaliases(self): self.alias['lexical-unit']='lexeme' self.alias['grammatical-info']='ps' def __init__(self, *args,**kwargs): + #First, see if this one already exists: + self.base=kwargs['base'] + if type(kwargs['base']) is Lift: + self.base=kwargs['base'].nodes basename=self.basename=self.base.tag super(LiftURL, self).__init__() log.debug("LiftURL called with {}".format(kwargs)) From 910d70de6c9ad4b19bf23e0369ee1cae04f1124f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:23:27 +0100 Subject: [PATCH 045/310] update --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 803bda5f..e04b2e74 100644 --- a/lift.py +++ b/lift.py @@ -2194,6 +2194,7 @@ def setaliases(self): self.alias={} self.alias['lexical-unit']='lexeme' self.alias['grammatical-info']='ps' + self.alias['senseid']='id' def __init__(self, *args,**kwargs): #First, see if this one already exists: self.base=kwargs['base'] From bf8081f69564c709efca5b80a996dcbcd6a7fc30 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:54:07 +0100 Subject: [PATCH 046/310] make copy work --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index e04b2e74..56ac3d9d 100644 --- a/lift.py +++ b/lift.py @@ -14,6 +14,7 @@ import rx import logging import ast #For string list interpretation +import copy log = logging.getLogger(__name__) try: #Allow this module to be used without translation _ From 1045b3600ad8dc8ffc4e5af77296b779f56ffb80 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:54:21 +0100 Subject: [PATCH 047/310] target arg --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 56ac3d9d..36456cb9 100644 --- a/lift.py +++ b/lift.py @@ -103,13 +103,13 @@ def geturlnattr(self, attribute, **kwargs): log.log(2,'After removenone: {}'.format(url)) log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) return {'url':url,'attr':self.attribdict[attribute]['attr']} - def retarget(self,urlobj): + def retarget(self,urlobj,target): k=self.urlkey(urlobj.kwargs) urlobj.kwargs['retarget']=target k2=self.urlkey(urlobj.kwargs) if k2 not in self.urls: self.urls[k2]=copy.deepcopy(urlobj) - self.urls[k2].retarget() + self.urls[k2].retarget(target) return self.urls[k2] def urlkey(self,kwargs): kwargscopy=kwargs.copy() #for only differences that change the URL From a04e2dc3c882e4f8d4e839fd776dfa00cf2981f4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:54:34 +0100 Subject: [PATCH 048/310] =?UTF-8?q?switch=20alias=20so=20it=20works..?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 36456cb9..4a5175b3 100644 --- a/lift.py +++ b/lift.py @@ -2195,7 +2195,7 @@ def setaliases(self): self.alias={} self.alias['lexical-unit']='lexeme' self.alias['grammatical-info']='ps' - self.alias['senseid']='id' + self.alias['id']='senseid' def __init__(self, *args,**kwargs): #First, see if this one already exists: self.base=kwargs['base'] From 96047905ad481a688cfa91468da32ae1cf262937 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 17:54:52 +0100 Subject: [PATCH 049/310] testing --- lift.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/lift.py b/lift.py index 4a5175b3..47c4c558 100644 --- a/lift.py +++ b/lift.py @@ -2821,17 +2821,21 @@ def test(): tonevalue=fieldvalue, # what='node' ) #'text' - exfieldvalue=url.get('node') + exfieldvalue=url.get('text') for e in exfieldvalue: - log.info("exfieldvalue: {}".format(e.text)) - url.retarget("sense") - # Bind lift object to each url object; or can we store - # this in a way that allows for non-recursive storage - # only of the url object by the lift object? - - ids=url.get('senseid') - for id in [x for x in ids if x is not None]: - log.info("senseid: {}".format(id)) + log.info("exfieldvalue: {}".format(e)) + url_sense=lift.retarget(url,"sense") + # Bind lift object to each url object; or can we store + # this in a way that allows for non-recursive storage + # only of the url object by the lift object? + ids=url_sense.get('senseid') + log.info("senseids: {}".format(ids)) + for id in [x for x in ids if x is not None]: + log.info("senseid: {}".format(id)) + url_entry=lift.retarget(url,"entry") + idsentry=url_entry.get('guid') + for id in [x for x in idsentry if x is not None]: + log.info("guid: {}".format(id)) # example=lift.get('example', # path=['location','tonefield'], #get this one first From 9d85994ec6bef623e6090239e92880f8a1547725 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 18:32:51 +0100 Subject: [PATCH 050/310] tweak get --- lift.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index 47c4c558..b67eaf9c 100644 --- a/lift.py +++ b/lift.py @@ -116,11 +116,28 @@ def urlkey(self,kwargs): kwargscopy.pop('showurl',False) k=tuple(sorted([(str(x),str(y)) for (x,y) in kwargscopy.items()])) return k - def get(self, target, **kwargs): - return self.getfrom(self.nodes, target, **kwargs) - def getfrom(self, node, target, **kwargs): - # base=kwargs['base']=node.tag #in case this is specified, but shouldn't be - # log.info("base: {}".format(base)) + def get(self, target, node=None, **kwargs): + """This method calls for a URL object, if it's not already there. + Followup methods include + LiftURL.get() on that object: to get the desired text/attr/node + lift.retarget(): to move from one url to a parent (e.g., the sense + node containing a found example) before LiftURL.get() again + get entries: lift.get("entry").get() + lift.get("entry".get('guid')) + get senses: lift.get("sense").get() + lift.get("sense".get('senseid')) + get *all* pss: lift.get("ps").get('value') + Never ask for just the form! give the parent, to get a particular form: + lift.get("lexeme/form").get('text') + lift.get("example/form").get('text') + lift.get("citation/form").get('text') + just 1 of each pss: dict.fromkeys(lift.get("ps").get('value')) + get tone value: + lift.get("text", location=location, path=['tonefield']).get('text') + for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"]).get('text')): + """ + if node is None: + node=self what=kwargs.get('what','node') path=kwargs.get('path',[]) if type(path) is not list: From 1f3c71ae981f79434ddd36ce53fe0c0677ccfa79 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 18:33:28 +0100 Subject: [PATCH 051/310] cut down get --- lift.py | 56 +++++--------------------------------------------------- 1 file changed, 5 insertions(+), 51 deletions(-) diff --git a/lift.py b/lift.py index b67eaf9c..e1138b33 100644 --- a/lift.py +++ b/lift.py @@ -145,57 +145,11 @@ def get(self, target, node=None, **kwargs): showurl=kwargs.get('showurl',False) kwargs['target']=target #not kwarg here, but we want it to be one for LiftURL k=self.urlkey(kwargs) - if k in self.urls: - return self.urls[k] #These are LiftURL objects - link=LiftURL(base=node,**kwargs) #needs base and target to be sensible; attribute? - # if showurl: - # log.info("Using URL {}".format(url)) - # return link.getwurl(node,what=what) #'what' comes in a kwarg, if wanted - return link #.get(node,what=what) #get="text", "node" or an attribute name - """kwargs are guid=None, senseid=None, analang=None, - glosslang=None, lang=None, ps=None, form=None, fieldtype=None, - location=None, fieldvalue=None, showurl=False):""" - """This needs to work when there are multiple languages, etc. - I think we should iterate over possibilities, if none are specified. - over lang, what else? - NB: this would create nested dictionaries... We need to be able to - access them consistently later.""" - """I need to be careful to not mix up lang=glosslang and lang=analang: - @lang should only be used here when referring to a field.""" - log.log(3,'kwargs: {}'.format(kwargs)) - """pull output from urlnattr, where first is string with {}, second - is strings naming fields. convert those names to field values here, - once those fields/values have been defined. - """ - """This is slightly faster than kwargs""" - # was: urlnattr=attributesettings(attribute,guid,senseid,analang, - # glosslang, lang,ps,form, - # fieldtype,location, - # fieldvalue=fieldvalue - urlnattr=self.geturlnattr(attribute, **kwargs) - url=urlnattr['url'] - if 'showurl' in kwargs and kwargs['showurl']==True: - log.info(url) - try: - nodeset=node.findall(url) #This is the only place we need self=lift - except BaseException as e: - log.error("Problem getting url: {} ({})".format(url,e)) - return - output=[] - attr=urlnattr['attr'] - for n in nodeset: - if attr == 'nodetext': - if n is not None: - log.log(1,"Returning node text") - output+=[n.text] - elif attr == 'node': - if n is not None: - log.log(1,"Returning whole node") - output+=[n] - else: - log.log(1,"Returning node attribute") - output+=[n.get(attr)] - return output + if k not in self.urls: + self.urls[k]=LiftURL(base=node,**kwargs) #needs base and target to be sensible; attribute? + if showurl: + log.info("Using URL {}".format(self.urls[k].url)) + return self.urls[k] #These are LiftURL objects def makenewguid(self): from random import randint log.info("Making a new unique guid") From ff4efc968cff5e123e0f6ea1d3bb60475100edcf Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 18:33:50 +0100 Subject: [PATCH 052/310] doc, reduce logging --- lift.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/lift.py b/lift.py index e1138b33..688e9641 100644 --- a/lift.py +++ b/lift.py @@ -143,7 +143,7 @@ def get(self, target, node=None, **kwargs): if type(path) is not list: path=kwargs['path']=[path] showurl=kwargs.get('showurl',False) - kwargs['target']=target #not kwarg here, but we want it to be one for LiftURL + kwargs['target']=target # we want target to be kwarg for LiftURL k=self.urlkey(kwargs) if k not in self.urls: self.urls[k]=LiftURL(base=node,**kwargs) #needs base and target to be sensible; attribute? @@ -1667,7 +1667,7 @@ def removedups(x): #This removes duplicates from a list return list(dict.fromkeys(x)) class LiftURL(): def get(self,what='node'): - log.info(self.__dict__) + log.debug(self.__dict__) n=self.base.findall(self.url) if n != []: log.debug("found: {} (x{}), looking for {}".format(n[:1],len(n),what)) @@ -1685,7 +1685,7 @@ def get(self,what='node'): def build(self,tag,liftattr=None,myattr=None,attrs=None): buildanother=False noseparator=False - log.log(21,"building {}, @dict:{}, @{}={}, on top of {}".format(tag, + log.debug("building {}, @dict:{}, @{}={}, on top of {}".format(tag, attrs,liftattr,myattr, self.currentnodename())) b=tag if attrs is None: @@ -1709,7 +1709,7 @@ def build(self,tag,liftattr=None,myattr=None,attrs=None): else: self.level['cur']+=1 self.level[self.alias.get(tag,tag)]=self.level['cur'] - log.log(21,"Path so far: {}".format(self.drafturl())) + log.debug("Path so far: {}".format(self.drafturl())) if buildanother: self.build(tag) def parent(self): @@ -1724,7 +1724,7 @@ def text(self,value): def form(self,value=None,lang=None): self.baselevel() self.kwargs['value']=self.kwargs.get(value,None) #location and tonevalue - log.log(21,"form kwargs: {}".format(self.kwargs)) + log.debug("form kwargs: {}".format(self.kwargs)) self.build("form","lang","lang") #OK if lang is None if value is not None: self.text("value") @@ -1868,18 +1868,18 @@ def maybeshowtarget(self,parent): # parent here is a node ancestor to the current origin, which may # or may not be an ancestor of targethead. If it is, show it. f=self.getfamilyof(parent,x=[]) - log.log(21,"Maybeshowtarget: {} (family: {})".format(parent,f)) + log.debug("Maybeshowtarget: {} (family: {})".format(parent,f)) if self.targethead in f: if parent in self.level: - log.log(21,"Maybeshowtarget: leveling up to {}".format(parent)) + log.debug("Maybeshowtarget: leveling up to {}".format(parent)) self.levelup(parent) else: - log.log(21,"Maybeshowtarget: showing {}".format(parent)) + log.debug("Maybeshowtarget: showing {}".format(parent)) self.show(parent) self.showtargetinhighestdecendance(parent) return True def showtargetinlowestancestry(self,nodename): - log.log(21,"Running showtargetinlowestancestry for {}/{} on {}".format( + log.debug("Running showtargetinlowestancestry for {}/{} on {}".format( self.targethead,self.targettail,nodename)) #If were still empty at this point, just do the target if we can if nodename == [] and self.targethead in self.children[self.basename]: @@ -2017,9 +2017,9 @@ def maketarget(self): n=self.targetbits.index(b) bp=self.targetbits[n-1].split('[')[0]#just the node, not attrs afterbp=self.drafturl().split(self.unalias(bp)) - log.log(21,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) + log.debug("b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) if len(afterbp) <=1 or b not in afterbp[1]: - log.log(21,"showing target element {}: {} (of {})".format(n,b,bp)) + log.debug("showing target element {}: {} (of {})".format(n,b,bp)) self.levelup(bp) self.show(b,parent=bp) self.levelup(self.targetbits[-1])#leave last in target, whatever else @@ -2168,15 +2168,13 @@ def setaliases(self): self.alias['grammatical-info']='ps' self.alias['id']='senseid' def __init__(self, *args,**kwargs): - #First, see if this one already exists: self.base=kwargs['base'] if type(kwargs['base']) is Lift: self.base=kwargs['base'].nodes basename=self.basename=self.base.tag super(LiftURL, self).__init__() - log.debug("LiftURL called with {}".format(kwargs)) + log.info("LiftURL called with {}".format(kwargs)) self.kwargs=kwargs - # base=self.basename=self.kwargs.pop('base','lift') # where do we start? target=self.target=self.kwargs.pop('target','entry') # what do we want? self.parsetargetlineage() self.what=self.kwargs.pop('what','node') #This should always be there @@ -2191,7 +2189,7 @@ def __init__(self, *args,**kwargs): log.debug("Making Target now.") self.maketarget() self.makeurl() - log.log(21,"Final URL: {}".format(self.url)) + log.debug("Final URL: {}".format(self.url)) # self.printurl() """Functions I'm using, but not in a class""" def prettyprint(node): @@ -2790,7 +2788,7 @@ def test(): senseid=senseid, fieldtype='tone',location=location, tonevalue=fieldvalue, - # what='node' + showurl=True# what='node' ) #'text' exfieldvalue=url.get('text') for e in exfieldvalue: @@ -2800,7 +2798,7 @@ def test(): # this in a way that allows for non-recursive storage # only of the url object by the lift object? ids=url_sense.get('senseid') - log.info("senseids: {}".format(ids)) + # log.info("senseids: {}".format(ids)) for id in [x for x in ids if x is not None]: log.info("senseid: {}".format(id)) url_entry=lift.retarget(url,"entry") @@ -2855,7 +2853,10 @@ def test(): # base='sense', # tonevalue=3, # ) - test() + # test() + entries=lift.get("entry").get() + log.info(len(entries)) + log.info(entries[0].get('guid')) printurllog() quit() import timeit From f57b46b638a937f82cd52db2298087598fe467cf Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 18:37:41 +0100 Subject: [PATCH 053/310] grammar --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 688e9641..e5c4a060 100644 --- a/lift.py +++ b/lift.py @@ -56,7 +56,7 @@ def __init__(self, filename,nsyls=None): self.backupfilename=''.join(backupbits) self.getguids() #sets: self.guids and self.nguids self.getsenseids() #sets: self.senseids and self.nsenseids - log.info("Working on {} with {}, entries " + log.info("Working on {} with {} entries " "and {} senses".format(filename,self.nguids,self.nsenseids)) """These three get all possible langs by type""" self.glosslangs() #sets: self.glosslangs From 4984b36a28756eab19dd370c0a9dd5d31d868372 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 18:38:01 +0100 Subject: [PATCH 054/310] update senseid and guid count --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index e5c4a060..3573d6ad 100644 --- a/lift.py +++ b/lift.py @@ -1095,11 +1095,11 @@ def fields(self,guid=None,lang=None): #get all the field types in a given entry return dict(self.get('type',base='field',target='field')).fromkeys()#nfields=0 # return self.get('fieldname',guid=guid,lang=lang)#nfields=0 def getsenseids(self): #get the number entries in a lift file. - self.senseids=self.get('senseid',base='sense',target='sense') #,showurl=True + self.senseids=self.get('sense').get('senseid') #,showurl=True self.nsenseids=len(self.senseids) #,guid,lang,fieldtype,location # log.info(self.nsenseids) def getguids(self): #get the number entries in a lift file. - self.guids=self.get('guid',base='entry',target='entry') #,showurl=True + self.guids=self.get('entry').get('guid') #,showurl=True # log.info(self.guids) self.nguids=len(self.guids) #,guid,lang,fieldtype,location def nc(self): From 0adbd7579d9021d4d335e800bb9f8b2accb004a9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 19 Oct 2021 18:38:12 +0100 Subject: [PATCH 055/310] moved testing bar --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 3573d6ad..68537d80 100644 --- a/lift.py +++ b/lift.py @@ -49,7 +49,6 @@ def __init__(self, filename,nsyls=None): self.read() #load and parse the XML file. (Should this go to check?) except: raise BadParseError(self.filename) - return #for testing, for now backupbits=[filename,'_', datetime.datetime.utcnow().isoformat()[:-16], #once/day '.txt'] @@ -58,6 +57,7 @@ def __init__(self, filename,nsyls=None): self.getsenseids() #sets: self.senseids and self.nsenseids log.info("Working on {} with {} entries " "and {} senses".format(filename,self.nguids,self.nsenseids)) + return #for testing, for now """These three get all possible langs by type""" self.glosslangs() #sets: self.glosslangs self.analangs() #sets: self.analangs, self.audiolangs From e87fa67bf316801a002889d5a2b71f005c3f0456 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:43:05 +0100 Subject: [PATCH 056/310] count things --- lift.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lift.py b/lift.py index 68537d80..4e55d50e 100644 --- a/lift.py +++ b/lift.py @@ -15,6 +15,7 @@ import logging import ast #For string list interpretation import copy +import collections log = logging.getLogger(__name__) try: #Allow this module to be used without translation _ @@ -1031,6 +1032,9 @@ def analangs(self): "in {} field; is this correct?".format( len(gforms),glang,form)) # possibles.remove(glang) #not anymore + count=collections.Counter(lxl+lcl+pronl)[glang] + if 0< count: + if count <= 10: for lang in possibles: if 'audio' in lang: log.debug(_("Audio language {} found.".format(lang))) From 6ef978c2863eb84d819b2e5f209aae90cc68907e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:44:17 +0100 Subject: [PATCH 057/310] new counting --- lift.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/lift.py b/lift.py index 4e55d50e..17899779 100644 --- a/lift.py +++ b/lift.py @@ -1019,22 +1019,13 @@ def analangs(self): pronl=self.get('lang',base='entry',path=['pronunciation'],target='form') possibles=list(dict.fromkeys(lxl+lcl+pronl)) log.info(_("Possible analysis language codes found: {}".format(possibles))) - for glang in ['fr','en']: - if glang in possibles: - for form in ['citation','lexeme']: - gforms=self.get(form,base='entry',target=form+'/form',analang=glang) - if 0< len(gforms): - # log.info("LWC lang {} found in {} field: {}".format( - # glang,form,self.get(form,analang=glang))) - """For Saxwe, and others who have fr or en encoding errors""" - if len(gforms) <= 10: - log.info("Only {} examples of LWC lang {} found " - "in {} field; is this correct?".format( - len(gforms),glang,form)) - # possibles.remove(glang) #not anymore - count=collections.Counter(lxl+lcl+pronl)[glang] - if 0< count: - if count <= 10: + for glang in set(['fr','en']) & set(possibles): + c=collections.Counter(lxl+lcl+pronl)[glang] + if 0< c: + """For Saxwe, and others who have fr or en encoding errors""" + if c <= 10: + log.info("Only {} examples of LWC lang {} found " + "in {} field; is this correct?".format(c,glang,form)) for lang in possibles: if 'audio' in lang: log.debug(_("Audio language {} found.".format(lang))) From b81cbdf997f46f51f88f45c82a127792b9a6264c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:44:49 +0100 Subject: [PATCH 058/310] new analang detection --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 17899779..cbad35d2 100644 --- a/lift.py +++ b/lift.py @@ -1014,9 +1014,9 @@ def analangs(self): log.log(1,_("Looking for analangs in lift file")) self.audiolangs=[] self.analangs=[] - lxl=self.get('lang',base='entry',path=['lexeme'],target='form') - lcl=self.get('lang',base='entry',path=['citation'],target='form') - pronl=self.get('lang',base='entry',path=['pronunciation'],target='form') + lxl=self.get('lexeme/form').get('lang') + lcl=self.get('citation/form').get('lang') + pronl=self.get('pronunciation/form').get('lang') possibles=list(dict.fromkeys(lxl+lcl+pronl)) log.info(_("Possible analysis language codes found: {}".format(possibles))) for glang in set(['fr','en']) & set(possibles): From 929d72eca3d5401a29d10f8658f7befb1bbc0fe1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:45:08 +0100 Subject: [PATCH 059/310] logging --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index cbad35d2..c58c3b7e 100644 --- a/lift.py +++ b/lift.py @@ -1037,8 +1037,8 @@ def analangs(self): 'for each analysis language.')) for self.analang in self.analangs: self.audiolangs+=[f'{self.analang}-Zxxx-x-audio'] - log.debug('Audio languages: {}'.format(self.audiolangs)) - log.debug('Analysis languages: {}'.format(self.analangs)) + log.info('Audio languages: {}'.format(self.audiolangs)) + log.info('Analysis languages: {}'.format(self.analangs)) def glosslangs(self): g=self.get('lang',base='sense',target='gloss') d=self.get('lang',base='sense',target='definition') From b78a59c3368ec0c858274bfafb0067e7696629d7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:45:56 +0100 Subject: [PATCH 060/310] new glosslang detection --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index c58c3b7e..4930fbb4 100644 --- a/lift.py +++ b/lift.py @@ -1040,10 +1040,10 @@ def analangs(self): log.info('Audio languages: {}'.format(self.audiolangs)) log.info('Analysis languages: {}'.format(self.analangs)) def glosslangs(self): - g=self.get('lang',base='sense',target='gloss') - d=self.get('lang',base='sense',target='definition') + g=self.get('gloss').get('lang') + d=self.get('definition/form').get('lang') self.glosslangs=list(dict.fromkeys(g+d)) - log.debug(_("gloss languages found: {}".format(self.glosslangs))) + log.info(_("gloss languages found: {}".format(self.glosslangs))) def glossordefn(self,guid=None,senseid=None,lang='ALL',ps=None ,showurl=False): if lang == None: #This allows for a specified None='give me nothing' From 7abbeb3cb1e824c60903cc1638e852ef45f74cd1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:46:11 +0100 Subject: [PATCH 061/310] segments found --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 4930fbb4..b0ca313b 100644 --- a/lift.py +++ b/lift.py @@ -1254,8 +1254,9 @@ def clist(self): #This variable gives lists, to iterate over. self.s[lang][stype]=rx.inxyz(self,lang,x[stype]) log.debug('hypotheticals[{}][{}]: {}'.format(lang,stype, str(x[stype]))) - log.debug('actuals[{}][{}]: {}'.format(lang,stype, + log.debug('Actual Segments found [{}][{}]: {}'.format(lang,stype, str(self.s[lang][stype]))) + log.info('Actual Segments found: {}'.format(self.s)) def slists(self): self.segmentsnotinregexes={} self.clist() From 1096e94074bd1653b467af26528118affe467572 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:46:38 +0100 Subject: [PATCH 062/310] comment out old fn --- lift.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lift.py b/lift.py index b0ca313b..3534e281 100644 --- a/lift.py +++ b/lift.py @@ -1275,15 +1275,15 @@ def slists(self): # if s is not None: # actuals.append(s) # return list(dict.fromkeys(actuals)) - def getguidformstosearchbyps(self,ps,lang=None): - if lang is None: - lang=self.analang - self.guidformstosearch[lang][ps]={} #Erases all previous data!! - for guid in self.get('guidbyps',lang=lang,ps=ps): - form=self.get('citation',guid=guid,lang=lang,ps=ps) - if len(form) == 0: #no items returned - form=self.get('lexeme',guid=guid,lang=lang,ps=ps) - self.guidformstosearch[lang][ps][guid]=form + # def getguidformstosearchbyps(self,ps,lang=None): + # if lang is None: + # lang=self.analang + # self.guidformstosearch[lang][ps]={} #Erases all previous data!! + # for guid in self.get('guidbyps',lang=lang,ps=ps): + # form=self.get('citation',guid=guid,lang=lang,ps=ps) + # if len(form) == 0: #no items returned + # form=self.get('lexeme',guid=guid,lang=lang,ps=ps) + # self.guidformstosearch[lang][ps][guid]=form def getsenseidformstosearchbyps(self,ps,lang=None): if lang is None: lang=self.analang From b10a8db007010e5a47bceda5b07026da7008ff31 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:46:59 +0100 Subject: [PATCH 063/310] comment out old fns --- lift.py | 66 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/lift.py b/lift.py index 3534e281..c1a6025c 100644 --- a/lift.py +++ b/lift.py @@ -1293,39 +1293,39 @@ def getsenseidformstosearchbyps(self,ps,lang=None): if len(form) == 0: #no items returned form=self.get('lexeme',senseid=senseid,lang=lang,ps=ps) self.senseidformstosearch[lang][ps][senseid]=form - def getguidformstosearch(self): - # import time - """This outputs a dictionary of form {analang: {guid:form}*}*, where - form is citation if available, or else lexeme. This is to be flexible - for entries in process of analysis, and to have a dictionary to check - with regexes for output.""" - self.guidformstosearch={} - self.senseidformstosearch={} - for lang in self.analangs: - self.guidformstosearch[lang]={} #This will erase all previous data!! - self.senseidformstosearch[lang]={} - for ps in self.pss: #I need to break this up. - # start_time=time.time() - self.getguidformstosearchbyps(ps,lang=lang) - self.getsenseidformstosearchbyps(ps,lang=lang) - #"n",str(time.time() - start_time),"seconds.") - #log.info(self.guidformstosearch) - def getformstosearchbyps(self,ps,lang=None): - if lang is None: - lang=self.analang - self.formstosearch[lang][ps]={} #Erases all previous data!! - #for guid in self.get('guidbynofield',lang=lang,ps=ps): - # forms=self.citationorlexeme(lang=lang,ps=ps) - """This actually needs this logic here, since formstosearch hasn't - been made yet.""" - forms=self.get('citation',analang=lang,ps=ps) - # if len(forms) == 0: #no items returned, I should probably combine - #this at some point, list(dict.fromkeys(form1+form2)) - forms+=self.get('lexeme',analang=lang,ps=ps) - # forms1=self.get('citation',lang=lang,ps=ps) - # forms2=self.get('lexeme',lang=lang,ps=ps) - # forms=list(dict.fromkeys(forms1+forms2)) - self.formstosearch[lang][ps]=forms + # def getguidformstosearch(self): + # # import time + # """This outputs a dictionary of form {analang: {guid:form}*}*, where + # form is citation if available, or else lexeme. This is to be flexible + # for entries in process of analysis, and to have a dictionary to check + # with regexes for output.""" + # self.guidformstosearch={} + # self.senseidformstosearch={} + # for lang in self.analangs: + # self.guidformstosearch[lang]={} #This will erase all previous data!! + # self.senseidformstosearch[lang]={} + # for ps in self.pss: #I need to break this up. + # # start_time=time.time() + # self.getguidformstosearchbyps(ps,lang=lang) + # self.getsenseidformstosearchbyps(ps,lang=lang) + # #"n",str(time.time() - start_time),"seconds.") + # #log.info(self.guidformstosearch) + # def getformstosearchbyps(self,ps,lang=None): + # if lang is None: + # lang=self.analang + # self.formstosearch[lang][ps]={} #Erases all previous data!! + # #for guid in self.get('guidbynofield',lang=lang,ps=ps): + # # forms=self.citationorlexeme(lang=lang,ps=ps) + # """This actually needs this logic here, since formstosearch hasn't + # been made yet.""" + # forms=self.get('citation/form/text',analang=lang,ps=ps) + # # if len(forms) == 0: #no items returned, I should probably combine + # #this at some point, list(dict.fromkeys(form1+form2)) + # forms+=self.get('lexeme/form/text',analang=lang,ps=ps) + # # forms1=self.get('citation',lang=lang,ps=ps) + # # forms2=self.get('lexeme',lang=lang,ps=ps) + # # forms=list(dict.fromkeys(forms1+forms2)) + # self.formstosearch[lang][ps]=forms def getformstosearch(self): # import time """This outputs a dictionary of form {analang: {guid:form}*}*, where From 9c0dd9cf1f077c638019f09e0f272cd167c67add Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:47:33 +0100 Subject: [PATCH 064/310] update formstosearch --- lift.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index c1a6025c..cd0e545e 100644 --- a/lift.py +++ b/lift.py @@ -1327,7 +1327,6 @@ def getsenseidformstosearchbyps(self,ps,lang=None): # # forms=list(dict.fromkeys(forms1+forms2)) # self.formstosearch[lang][ps]=forms def getformstosearch(self): - # import time """This outputs a dictionary of form {analang: {guid:form}*}*, where form is citation if available, or else lexeme. This is to be flexible for entries in process of analysis, and to have a dictionary to check @@ -1336,10 +1335,13 @@ def getformstosearch(self): for lang in self.analangs: self.formstosearch[lang]={} #This will erase all previous data!! for ps in self.pss+[None]: #I need to break this up. - # start_time=time.time() - self.getformstosearchbyps(ps,lang=lang) - #"n",str(time.time() - start_time),"seconds.") - # log.info(self.formstosearch) + forms=self.get('citation/form/text',analang=lang,ps=ps + ).get('text') + forms+=self.get('lexeme/form/text',analang=lang,ps=ps + ).get('text') + self.formstosearch[lang][ps]=list(dict.fromkeys(forms)) + log.debug("Found the following forms to search: {}".format( + self.formstosearch)) def citationforms(self): #outputs generator object with each form in LIFT file. """This produces a dictionary, of forms for each language.""" #return self.get('citationform') From cf7bd498aeb426d352b5f8a817bb3dd8cd3670fc Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:47:52 +0100 Subject: [PATCH 065/310] update citationforms --- lift.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lift.py b/lift.py index cd0e545e..d696e432 100644 --- a/lift.py +++ b/lift.py @@ -1344,14 +1344,10 @@ def getformstosearch(self): self.formstosearch)) def citationforms(self): #outputs generator object with each form in LIFT file. """This produces a dictionary, of forms for each language.""" - #return self.get('citationform') output={} for lang in self.analangs: - output[lang]=self.get('citation',analang=lang) - #output[lang]=list() - #for form in self.nodes.findall(f"entry/citation/form[@lang='{lang}']/text"): - # output[lang]+=[form.text] #print the text of the node above - #log.info(output.keys()) #to see which languages are found + output[lang]=self.get('citation/form/text',analang=lang).get('text') + log.info("Found the following citation forms: {}".format(output)) return output def lexemes(self): output={} From 3ecbd93eee0d135e3ff1ae1c7caa7944cdf5ea0f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:48:07 +0100 Subject: [PATCH 066/310] update lexemes --- lift.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lift.py b/lift.py index d696e432..fb72be9c 100644 --- a/lift.py +++ b/lift.py @@ -1352,10 +1352,8 @@ def citationforms(self): #outputs generator object with each form in LIFT file. def lexemes(self): output={} for lang in self.analangs: - output[lang]=self.get('lexeme',analang=lang) #list() - #for form in self.nodes.findall(f"entry/lexical-unit/form[@lang='{lang}']/text"): - # output[lang]+=[form.text] #print the text of the node above - #log.info(output.keys()) #to see which languages are found + output[lang]=self.get('lexeme/form/text',analang=lang).get('text') + log.info("Found the following lexemes: {}".format(output)) return output def extrasegments(self): # start_time=time.time() #this enables boot time evaluation From a718a0602403e49a4f8b673b070339c486229202 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:48:22 +0100 Subject: [PATCH 067/310] update pss --- lift.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index fb72be9c..8d341cd3 100644 --- a/lift.py +++ b/lift.py @@ -1392,7 +1392,9 @@ def extrasegments(self): # log.log(2,"{} (lift.extrasegments run time): {}".format( # time.time()-start_time,self.segmentsnotinregexes)) def pss(self): #get all POS values in the LIFT file - return list(dict.fromkeys(self.get('ps'))) + p=list(dict.fromkeys(self.get('ps').get('value'))) + log.info("Found these ps values: {}".format(p)) + return p #pss=list() #for ps in self.nodes.findall(f"entry/sense/grammatical-info"): # thisps=ps.attrib.get('value') From 1571767e1cd437e85d6bf17a9e506b969a311eb1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:48:42 +0100 Subject: [PATCH 068/310] fix use of langs in form URL --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 8d341cd3..86d12b13 100644 --- a/lift.py +++ b/lift.py @@ -1719,7 +1719,7 @@ def form(self,value=None,lang=None): self.baselevel() self.kwargs['value']=self.kwargs.get(value,None) #location and tonevalue log.debug("form kwargs: {}".format(self.kwargs)) - self.build("form","lang","lang") #OK if lang is None + self.build("form","lang",lang) #OK if lang is None if value is not None: self.text("value") def citation(self): From 23c6cdf9631759640a0172e794149a9c11c9efef Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:48:58 +0100 Subject: [PATCH 069/310] stop when you found a good level --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 86d12b13..d66feb9e 100644 --- a/lift.py +++ b/lift.py @@ -1848,6 +1848,7 @@ def baselevel(self): return #if we're on an acceptable level, just stop elif target in self.level: self.levelup(target) + return elif parents.index(target) < len(parents)-1: log.debug("level {} not in {}; checking the next one...".format( target,self.level)) From f8f82308730284b1f8cb7bef0a1a8e1233e7be4d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:49:35 +0100 Subject: [PATCH 070/310] not needed --- lift.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lift.py b/lift.py index d66feb9e..5239ff27 100644 --- a/lift.py +++ b/lift.py @@ -1857,7 +1857,6 @@ def baselevel(self): "".format(target,parents,self.level)) log.error("this is where we're at: {}\n {}".format(self.kwargs, self.drafturl())) - printurllog() exit() def maybeshowtarget(self,parent): # parent here is a node ancestor to the current origin, which may From 4ead9e1d3191e07dcbf1198f87e4ab09219a9238 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:50:16 +0100 Subject: [PATCH 071/310] updated children --- lift.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 5239ff27..eac80ae8 100644 --- a/lift.py +++ b/lift.py @@ -2152,9 +2152,11 @@ def setchildren(self): 'tonefield','field'] self.children['field']=['form'] self.children['lexeme']=['form'] + self.children['definition']=['form'] self.children['citation']=['form'] self.children['form']=['text'] - self.children['pronunciation']=['field','trait'] + self.children['gloss']=['text'] + self.children['pronunciation']=['field','trait','form'] self.children['translation']=['form'] def setaliases(self): self.alias={} From 49643fe3477711a275ac4ea0999c487be5cf51f4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:51:02 +0100 Subject: [PATCH 072/310] fixed print urls --- lift.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index eac80ae8..7bbf7031 100644 --- a/lift.py +++ b/lift.py @@ -2713,7 +2713,7 @@ def another(): 'url':(("form[@lang='{lang}']/text" ),['lang']), 'attr':'nodetext'} -def printurllog(): +def printurllog(lift): log.info('\n'+'\n'.join([str(x)+'\n '+str(y) for x,y in lift.urls.items()])) if __name__ == '__main__': import time #for testing; remove in production @@ -2850,10 +2850,10 @@ def test(): # tonevalue=3, # ) # test() - entries=lift.get("entry").get() - log.info(len(entries)) - log.info(entries[0].get('guid')) - printurllog() + # entries=lift.get("entry").get() + # log.info(len(entries)) + # log.info(entries[0].get('guid')) + printurllog(lift) quit() import timeit def timetest(): From ec44b48378e3b0a46683883a10131ae4e655344f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:56:23 +0100 Subject: [PATCH 073/310] clean up extrasegments --- lift.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lift.py b/lift.py index 7bbf7031..cf8e36cc 100644 --- a/lift.py +++ b/lift.py @@ -1356,7 +1356,6 @@ def lexemes(self): log.info("Found the following lexemes: {}".format(output)) return output def extrasegments(self): - # start_time=time.time() #this enables boot time evaluation for lang in self.analangs: self.segmentsnotinregexes[lang]=list() extras=list() @@ -1387,10 +1386,6 @@ def extrasegments(self): "complex segments which should be counted as a single " "segment.") log.info("--those may not be covered by your regexes.") - print("No problems!") - - # log.log(2,"{} (lift.extrasegments run time): {}".format( - # time.time()-start_time,self.segmentsnotinregexes)) def pss(self): #get all POS values in the LIFT file p=list(dict.fromkeys(self.get('ps').get('value'))) log.info("Found these ps values: {}".format(p)) From 44e20da6db53b117c8e476f990f9e6122065114a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 10:56:43 +0100 Subject: [PATCH 074/310] actually print urls --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index cf8e36cc..949ccd87 100644 --- a/lift.py +++ b/lift.py @@ -2709,7 +2709,7 @@ def another(): ),['lang']), 'attr':'nodetext'} def printurllog(lift): - log.info('\n'+'\n'.join([str(x)+'\n '+str(y) for x,y in lift.urls.items()])) + log.info('\n'+'\n'.join([str(x)+'\n '+str(y.url) for x,y in lift.urls.items()])) if __name__ == '__main__': import time #for testing; remove in production # def _(x): From b84dbe5d2b29ea36d1268280fd546d96c87da940 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 11:34:32 +0100 Subject: [PATCH 075/310] rework find duplicate forms --- lift.py | 43 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/lift.py b/lift.py index 949ccd87..28f46069 100644 --- a/lift.py +++ b/lift.py @@ -469,38 +469,19 @@ def exampleissameasnew(self, **kwargs): def findduplicateforms(self): """This removes duplicate form nodes in lx or lc nodes, not much point. """ + dup=False for entry in self.nodes: - for node in entry: - if ((node.tag == 'lexical-unit') or (node.tag == 'citation')): - forms=node.findall('form') - removed=list() - for form in forms: - f1i=forms.index(form) - for form2 in forms: - f2i=forms.index(form2) - if (f2i <= f1i) or (form2 in removed): - log.log(3,"{} <= {} or form {} already removed; " - "continuing.".format(f2i,f2i,f1i)) - continue - if (form.get('lang') == form2.get('lang') and - form.find('text').text == form2.find('text').text): - log.debug("Found {} {} {}".format(f1i, - form.get('lang'), - form.find('text').text, - )) - log.debug("Found {} {} {}".format(f2i, - form2.get('lang'), - form2.find('text').text - )) - log.debug("Removing form {} {} {}".format(f2i, - form2.get('lang'), - form2.find('text').text - )) - node.remove(form2) - removed.append(form2) - else: - log.log(3,"Not removing form") - self.write() + formparents=entry.findall('lexical-unit')+entry.findall('citation') + for fp in formparents: + for lang in self.analangs: + forms=fp.findall('form[@lang="{}"]'.format(lang)) + if len(forms) >1: + log.info("Found multiple form fields in an entry: {}" + "".format([x.find('text').text for x in forms])) + dup=True + if not dup: + log.info("No duplicate form fields were found in the lexicon.") + # self.write() Not doing any changes, anyway... def findduplicateexamples(self): def getexdict(example): analangs=[] From f90b83e1314937020ead1cfc6e1704d804373241 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 12:28:30 +0100 Subject: [PATCH 076/310] new locations fn --- lift.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lift.py b/lift.py index 28f46069..b361802e 100644 --- a/lift.py +++ b/lift.py @@ -68,6 +68,7 @@ def __init__(self, filename,nsyls=None): # self.getguidformstosearch() #sets: self.guidformstosearch[lang][ps] self.citationforms=self.citationforms() self.lexemes=self.lexemes() + self.locations=self.getlocations() self.defaults=[ #these are lift related defaults 'analang', 'glosslang', @@ -1070,6 +1071,10 @@ def citationorlexeme(self,guid=None,senseid=None,lang=None,ps=None def fields(self,guid=None,lang=None): #get all the field types in a given entry return dict(self.get('type',base='field',target='field')).fromkeys()#nfields=0 # return self.get('fieldname',guid=guid,lang=lang)#nfields=0 + def getlocations(self,guid=None,lang=None): #get all the field types in a given entry + l=list(dict.fromkeys(self.get('example/locationfield').get('text'))) + log.info('Locations found in Examples: {}'.format(l)) + return l def getsenseids(self): #get the number entries in a lift file. self.senseids=self.get('sense').get('senseid') #,showurl=True self.nsenseids=len(self.senseids) #,guid,lang,fieldtype,location From 598b588ace77838e6b9514adf99eac4143656c52 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 12:29:10 +0100 Subject: [PATCH 077/310] du examples working now, though just notifying --- lift.py | 283 ++++---------------------------------------------------- 1 file changed, 16 insertions(+), 267 deletions(-) diff --git a/lift.py b/lift.py index b361802e..71ed4b9f 100644 --- a/lift.py +++ b/lift.py @@ -78,7 +78,7 @@ def __init__(self, filename,nsyls=None): self.slists() #sets: self.c self.v, not done with self.segmentsnotinregexes[lang] self.extrasegments() #tell me if there's anything not in a V or C regex. self.findduplicateforms() - # self.findduplicateexamples() #Fix this! + self.findduplicateexamples() """Think through where this belongs; what classes/functions need it?""" log.info("Language initialization done.") def geturlnattr(self, attribute, **kwargs): @@ -484,272 +484,21 @@ def findduplicateforms(self): log.info("No duplicate form fields were found in the lexicon.") # self.write() Not doing any changes, anyway... def findduplicateexamples(self): - def getexdict(example): - analangs=[] - otheranalangs=[] - glosslangs=[] - forms=Object() #?!?! - forms.forms=Object() - setattr(forms,'analangs',analangs) - setattr(forms,'glosslangs',glosslangs) - analang='' - glosslang='' - glosslang2='' - location='' - tonevalue='' - log.log(3,"Working on example {} (this sense: {})".format(exn,exindex)) - formnodes=example.findall('form') #multiple/sense - translationformnodes=example.findall( - "translation[@type='Frame translation']/form") #just one/sense - if formnodes != None: - for formnode in formnodes: - lang=formnode.get('lang') - formnodetext=formnode.find('text') - if formnodetext is not None: - analangs.append(lang) - setattr(forms,'analang',formnodetext.text) - setattr(forms.forms,lang,forms.analang) - # forms[lang]=formnodetext.text# - else: - log.log(3,"No formnodetext! (lang: {})".format(lang)) - if analangs != []: - log.log(2,"Analangs: {}".format(analangs)) - analang=analangs[0] - if len(analangs) >1: - otheranalangs=analangs[1:] - else: - analang=None - else: - log.error("No form node!") - if translationformnodes != None: - for formnode in translationformnodes: - lang=formnode.get('lang') - formnodetext=formnode.find('text') - if formnodetext != None: - glosslangs.append(lang) - if len(glosslangs) >0: - forms.glosslang2=formnodetext.text - setattr(forms.forms,lang,forms.glosslang2) - else: - forms.glosslang=formnodetext.text - setattr(forms.forms,lang,forms.glosslang) - # forms[lang]=formnodetext.text# - else: - log.log(4,"No glossformnodetext! ({}; lang: {})".format( - lang,formnodetext)) - log.log(2,"glosslangs: {}".format(glosslangs)) - if len(glosslangs) >1: - glosslang2=glosslangs[1] - else: - glosslang2=None - log.log(3,"No glosslang2formnodetext; hope that's OK!") - if len(glosslangs) >0: - glosslang=glosslangs[0] - else: - glosslang=None - log.log(4,"No glosslangformnodetext!") - else: - log.log(4,"No translation node!") - #We don't care about form[@lang] for these: - locationnode=example.find("field[@type='location']/form/text") - valuenode=example.find("field[@type='tone']/form/text") - if locationnode != None: - location=locationnode.text - else: - location=None - if valuenode != None: - tonevalue=valuenode.text - else: - tonevalue='' #this means an empty/missing tone node only. - return (forms, analang, glosslang, glosslang2, location, tonevalue, - otheranalangs) - def compare(x,y): - same=0 - for i in range(len(x)): - if x[i] == y[i]: - log.log(2,"{} =".format(x[i])) - log.log(2,"{}".format(y[i])) - same+=1 - else: - log.log(2,"{} ≠".format(x[i])) - log.log(2,"{}!".format(y[i])) - same=False - return same - forms={} - entries=self.nodes.findall('entry') - exn=0 - for entry in entries: - entindex=entries.index(entry) - log.log(2,"Working on entry {}: {}".format(entindex, - entry.get('guid'))) - senses=entry.findall('sense') - for sense in senses: - senseindex=senses.index(sense) - log.log(3,"Working on sense {}: {}".format(senseindex, - sense.get('id'))) - examples=sense.findall('example') #'senselocations' - for example in examples: - #If empty node, remove it - if len(example) == 0: - log.info("Deleting Empty example in {}".format( - entry.get('guid'))) - sense.remove(example) - continue - exn+=1 - exindex=list(examples).index(example) - ex1=getexdict(example) - if ex1[1] == None: - log.info("No analang found for example {} in {}" - "".format(ex2index,sense.get('id'))) - continue - for example2 in examples: - ex2index=list(examples).index(example2) - if exindex >= ex2index: - log.log(2,"Comparing example {} with example {}; " - "skipping.".format(exindex,ex2index)) - continue - else: - log.log(2,"Comparing example {} with example {}." - "".format(exindex,ex2index)) - #here we replicate/skip exampleissameasnew - ex2=getexdict(example2) - if ex2[1] == None: - log.info("No analang found for example {} in {}" - "".format(ex2index,sense.get('id'))) - continue - othertonevalue=self.exampleisnotsameasnew( - node=sense, - example=example2, - db=ex1[0], - analang=ex1[1], - glosslang=ex1[2], - glosslang2=ex1[3], - location=ex1[4] - # ,showurl=True - ) - if othertonevalue == None: - log.log(2,"No same node found!") - elif not ((othertonevalue == ex1[5]) or - ((type(othertonevalue) is ET.Element) and - (othertonevalue.text == ex1[5]))): - try: - log.log(3,"Same node, different value! ({}!={})" - "; copying over {}?{}".format( - othertonevalue.text, - ex1[5],type(othertonevalue.text), - type(ex1[5]))) - if ((othertonevalue.text == '') or - (othertonevalue.text == None)): - log.log(3,"empty othertonevalue node") - othertonevalue.text == ex1[5] - ex2=getexdict(example) - elif ((ex1[5] == '') or (ex1[5] == None)): - log.log(3,"empty ex1 tonevalue node") - t=example.find("field[@type='tone']/form/" - "text") - if t is not None: - log.log(2,"tone node there, adding " - "tonevalue") - t.text=othertonevalue.text - else: - log.log(2,"No tone node there, adding") - fld=ET.SubElement(example,'field', - attrib={'type':'tone'}) - f=ET.SubElement(fld,'form', - attrib={'lang':ex1[2]}) - g=ET.SubElement(f,'text') - g.text=othertonevalue.text - ex1=getexdict(example) - else: - log.error("Huh? tonevalue nodes: {}; {} in " - "{}".format(othertonevalue, - ex1[5], sense.get('id'))) - except: - log.log(2,"Same text, different value! ({}!={})" - "; copying over {}?{}".format( - othertonevalue, - ex1[5],type(othertonevalue), - type(ex1[5]))) - if (ex2[5] == '') or (ex2[5] == None): - log.log(2,"empty ex2 tonevalue node") - t=example2.find("field[@type='tone']/" - "form/text") - if t is not None: - t.text=ex1[5] - else: - fld=ET.SubElement(example2,'field', - attrib={'type':'tone'}) - f=ET.SubElement(fld,'form', - attrib={'lang':ex1[2]}) - g=ET.SubElement(f,'text') - g.text=ex1[5] - ex2=getexdict(example) - else: - log.error("Huh? tonevalues: {}; {} in {}" - "".format(othertonevalue, - ex1[5], sense.get('id'))) - compare(ex1,ex2) #This compares tuples - if (othertonevalue != None) and (ex2[5] == ex1[5]): - try: - log.log(2,"Same node, same value! ({}={}-{})" - "".format( - ex1[5],othertonevalue.text,ex2[5])) - except: - log.log(2,"Same text, same value! ({}={}-{})" - "".format( - ex1[5],othertonevalue,ex2[5])) - compare(ex1,ex2) #This compares tuples - if (ex1[6] == []) and (ex2[6] == []): - log.info("No second analang; removing second " - "example from {}.".format(sense.get('id'))) - if example2 in sense: - sense.remove(example2) - for lang in ex1[6]: - if lang in ex2[6]: - log.log(2,"Language {} found in both " - "examples.".format(lang)) - if ex1[0][lang] == ex2[0][lang]: - log.log(2,"Language {} content same in " - "both examples.".format(lang)) - if example2 in sense: - try: - log.info("Removing second " - "example from {}." - "".format( - sense.get('id'))) - except: - log.info("Removing second " - "example from {}".format( - sense.get('id'))) - sense.remove(example2) - else: - #Don't remove here - log.log(3,"Language {} content " - "DIFFERENT".format(lang)) - else: - if example2 in sense: - try: - log.info("Removing second example " - "from {}".format( - sense.get('id'))) - except: - log.info("Removing second example " - "from {}".format( - sense.get('id'))) - sense.remove(example2) - for lang in ex2[6]: - if lang not in ex1[6]: - if example in sense: - try: - log.info("Removing first example." - "from {}".format( - sense.get('id'))) - except: - log.info("Removing first example." - "from {}".format( - sense.get('id'))) - sense.remove(example) - self.write() + dup=False + senses=self.nodes.findall('entry/sense') + for sense in senses: + for l in self.locations: + examples=sense.findall('example/field[@type="location"]/' + 'form[text="{}"]/../..'.format(l)) #'senselocations' + if len(examples)>1: + log.info("Found multiple examples of the same location ({})" + " in the same sense: {}".format(l, + [x.find('form/text').text for x in examples])) + dup=True + if not dup: + log.info("No duplicate examples (same sense and location) were " + "found in the lexicon.") + # self.write() Not yet, anyway def addtoneUF(self,senseid,group,analang,guid=None,showurl=False): urlnattr=self.geturlnattr('senseid',senseid=senseid) #give the sense. url=urlnattr['url'] From b49956ea427f4cda17c191365f99c65b6d1dfda3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 12:29:35 +0100 Subject: [PATCH 078/310] done with testing up to initialization --- lift.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lift.py b/lift.py index 71ed4b9f..d012a1a9 100644 --- a/lift.py +++ b/lift.py @@ -58,7 +58,6 @@ def __init__(self, filename,nsyls=None): self.getsenseids() #sets: self.senseids and self.nsenseids log.info("Working on {} with {} entries " "and {} senses".format(filename,self.nguids,self.nsenseids)) - return #for testing, for now """These three get all possible langs by type""" self.glosslangs() #sets: self.glosslangs self.analangs() #sets: self.analangs, self.audiolangs From 09c67f1b4593bc02f202bd8a51e98f431c11929c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 12:29:49 +0100 Subject: [PATCH 079/310] fix reference problem for morphtype --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index d012a1a9..58def0f2 100644 --- a/lift.py +++ b/lift.py @@ -1511,8 +1511,8 @@ def tonefield(self): self.kwargs['formtext']='tonevalue' self.field() self.form("tonevalue",'glosslang') - def morphtype(self): - if morphtype in self.kwargs: + def morphtype(self,attrs={}): + if 'morphtype' in self.kwargs: attrs={'name':"morph-type",'value':self.kwargs[morphtype]} self.trait(attrs) # def attrdonothing(self): From 945c2f16c041a8191606caf3bf53830d98918bef Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 12:30:07 +0100 Subject: [PATCH 080/310] check for no children --- lift.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 58def0f2..9e3bfa8d 100644 --- a/lift.py +++ b/lift.py @@ -1628,7 +1628,12 @@ def showtargetinlowestancestry(self,nodename): def showtargetinhighestdecendance(self,nodename): log.debug("Running showtargetinhighestdecendance for {} on {}".format( self.targethead,nodename)) - children=self.children[nodename] + if nodename in self.children: + children=self.children[nodename] + else: + log.debug("Node {} has no children, so not looking further for " + "descendance.".format(nodename)) + return grandchildren=[i for child in children if child in self.children for i in self.children[child] From 938a2a9d9e77fb499b4ddcad7800556a9b19698b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 12:30:28 +0100 Subject: [PATCH 081/310] add greatgreat grandchildren logic --- lift.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lift.py b/lift.py index 9e3bfa8d..2c3f0c30 100644 --- a/lift.py +++ b/lift.py @@ -1644,6 +1644,14 @@ def showtargetinhighestdecendance(self,nodename): if grandchild in self.children for i in self.children[grandchild] ] + gggrandchildren=[i for child in children + if child in self.children + for grandchild in self.children[child] + if grandchild in self.children + for ggrandchild in self.children[grandchild] + if ggrandchild in self.children + for i in self.children[ggrandchild] + ] log.debug("Looking for {} in children of {}: {}".format( self.targethead,nodename,children)) log.debug("Grandchildren of {}: {}".format(nodename,grandchildren)) @@ -1669,6 +1677,16 @@ def showtargetinhighestdecendance(self,nodename): log.debug("Showing '{}', nearest ancenstor".format(c)) self.show(c,nodename) #others will get picked up below self.showtargetinhighestdecendance(c) + elif self.targethead in gggrandchildren: + log.info("Found target ({}) in gggrandchildren of {}: {}".format( + self.targethead,nodename,gggrandchildren)) + for c in children: + for cc in grandchildren: + for ccc in greatgrandchildren: + if ccc in self.children and self.targethead in self.children[ccc]: + log.debug("Showing '{}', nearest ancenstor".format(c)) + self.show(c,nodename) #others will get picked up below + self.showtargetinhighestdecendance(c) else: log.error("Target not found in children, grandchildren, or " "greatgrandchildren!") From 04551ec67708210f5c2382623717d399296cc0ef Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:21:27 +0100 Subject: [PATCH 082/310] fixed field detection --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 2c3f0c30..060c3e46 100644 --- a/lift.py +++ b/lift.py @@ -817,8 +817,8 @@ def citationorlexeme(self,guid=None,senseid=None,lang=None,ps=None ) return forms def fields(self,guid=None,lang=None): #get all the field types in a given entry - return dict(self.get('type',base='field',target='field')).fromkeys()#nfields=0 - # return self.get('fieldname',guid=guid,lang=lang)#nfields=0 + f=list(dict.fromkeys(self.get('field').get('type'))) + return f def getlocations(self,guid=None,lang=None): #get all the field types in a given entry l=list(dict.fromkeys(self.get('example/locationfield').get('text'))) log.info('Locations found in Examples: {}'.format(l)) From 7cd7b7cd055777c275733bd1d30a357eb018da7c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:22:01 +0100 Subject: [PATCH 083/310] list language codes by frequency in database --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 060c3e46..573c9071 100644 --- a/lift.py +++ b/lift.py @@ -747,7 +747,7 @@ def analangs(self): lxl=self.get('lexeme/form').get('lang') lcl=self.get('citation/form').get('lang') pronl=self.get('pronunciation/form').get('lang') - possibles=list(dict.fromkeys(lxl+lcl+pronl)) + possibles=[i[0] for i in collections.Counter(lxl+lcl+pronl).most_common()] log.info(_("Possible analysis language codes found: {}".format(possibles))) for glang in set(['fr','en']) & set(possibles): c=collections.Counter(lxl+lcl+pronl)[glang] From 4a894030ff3c73176b5870849cfd93b5f1c46b1c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:22:36 +0100 Subject: [PATCH 084/310] upgrade senseidswanyps --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 617da1be..2d82a374 100755 --- a/main.py +++ b/main.py @@ -2363,7 +2363,7 @@ def senseidtriage(self): if senseid not in self.senseidsinvalid: self.senseidsvalid+=[senseid] print(len(self.senseidsvalid),'senses with valid data remaining.') - self.senseidswanyps=self.db.get('senseidwanyps') #any ps value works here. + self.senseidswanyps=self.db.get('sense',path=['ps'],showurl=True).get('senseid') #any ps value works here. print(len(self.senseidswanyps),'senses with ps data found.') self.senseidsvalidwops=[] self.senseidsvalidwps=[] From 01b70a12b650bb7a4ab2463bfc1cd7ed88a9ed15 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:22:57 +0100 Subject: [PATCH 085/310] update guessanalang --- main.py | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/main.py b/main.py index 2d82a374..8ced9f5c 100755 --- a/main.py +++ b/main.py @@ -183,7 +183,7 @@ def __init__(self, parent, frame, nsyls=None): self.loadsettingsfile(setting='profiledata') """I think I need this before setting up regexs""" self.guessanalang() #needed for regexs - log.debug("analang guessed: {} (If you don't like this, change it in " + log.info("analang guessed: {} (If you don't like this, change it in " "the menus)".format(self.analang)) self.maxprofiles=5 # how many profiles to check before moving on to another ps self.maxpss=2 #don't automatically give more than two grammatical categories @@ -238,23 +238,11 @@ def notifyuserofextrasegments(self): """Guessing functions""" def guessanalang(self): #have this call set()? - langspriority=collections.Counter(self.db.get('lexemelang')+ - self.db.get('citationlang')).most_common() - try: - self.analang=langspriority[0][0] - log.debug(_("Analysis language with the most fields ({}): {} ({})" - "".format(langspriority[0][1],self.analang,langspriority))) - except: - self.analang=None - log.info(_("Are there any languages in this database? {}").format( - langspriority)) - return """if there's only one analysis language, use it.""" nlangs=len(self.db.analangs) log.debug(_("Found {} analangs: {}".format(nlangs,self.db.analangs))) - if nlangs == 1: # print('Only one analang in database!') + if nlangs == 1: self.analang=self.db.analangs[0] - self.analangdefault=self.db.analangs[0] #In case the above gets changed. log.debug(_('Only one analang in file; using it: ({})'.format( self.db.analangs[0]))) """If there are more than two analangs in the database, check if one @@ -265,19 +253,17 @@ def guessanalang(self): log.debug(_('Looks like I found an iso code for analang! ' '({})'.format(self.db.analangs[0]))) self.analang=self.db.analangs[0] #assume this is the iso code + self.analangdefault=self.db.analangs[0] #In case it gets changed. elif ((len(self.db.analangs[1]) == 3) and (len(self.db.analangs[0]) != 3)): log.debug(_('Looks like I found an iso code for analang! ' '({})'.format(self.db.analangs[1]))) self.analang=self.db.analangs[1] #assume this is the iso code + self.analangdefault=self.db.analangs[1] #In case it gets changed. else: - langspriority=collections.Counter(self.db.get('lexemelang')+ - self.db.get('citationlang')).most_common() - log.debug("All: {}".format(self.db.get('lexemelang')+ - self.db.get('citationlang'))) - log.debug(collections.Counter(self.db.get('lexemelang')+ - self.db.get('citationlang'))) - log.debug('Found the following analangs: {}'.format(langspriority)) + self.analang=self.db.analangs[0] + log.debug('Neither analang looks like an iso code, taking the ' + 'first one: {}'.format(langspriority)) else: #for three or more analangs, take the first plausible iso code for n in range(nlangs): if len(self.db.analangs[n]) == 3: @@ -285,6 +271,9 @@ def guessanalang(self): log.debug(_('Looks like I found an iso code for analang! ' '({})'.format(self.db.analangs[n]))) return + log.debug('None of more than three analangs look like an iso code, ' + 'taking the first one: {}'.format(langspriority)) + self.analang=self.db.analangs[0] def guessaudiolang(self): nlangs=len(self.db.audiolangs) """if there's only one audio language, use it.""" From c891ce08e07093f614419d68941e924401fe9afd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:34:42 +0100 Subject: [PATCH 086/310] clean up analangs --- lift.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lift.py b/lift.py index 573c9071..83c24450 100644 --- a/lift.py +++ b/lift.py @@ -741,27 +741,28 @@ def write(self,filename=None): pathlib.Path(filename).name, pathlib.Path(filename).parent, os.listdir(pathlib.Path(filename).parent))) def analangs(self): - log.log(1,_("Looking for analangs in lift file")) + """These are ordered by frequency in the database""" self.audiolangs=[] self.analangs=[] lxl=self.get('lexeme/form').get('lang') lcl=self.get('citation/form').get('lang') pronl=self.get('pronunciation/form').get('lang') - possibles=[i[0] for i in collections.Counter(lxl+lcl+pronl).most_common()] - log.info(_("Possible analysis language codes found: {}".format(possibles))) - for glang in set(['fr','en']) & set(possibles): - c=collections.Counter(lxl+lcl+pronl)[glang] + langsbycount=collections.Counter(lxl+lcl+pronl) + self.analangs=[i[0] for i in langsbycount.most_common()] + log.info(_("Possible analysis language codes found: {}".format( + self.analangs))) + for glang in set(['fr','en']) & set(self.analangs): + c=langsbycount[glang] if 0< c: """For Saxwe, and others who have fr or en encoding errors""" if c <= 10: - log.info("Only {} examples of LWC lang {} found " - "in {} field; is this correct?".format(c,glang,form)) - for lang in possibles: + log.info("Only {} examples of LWC lang {} found; is this " + "correct?".format(c,glang)) + for lang in self.analangs: if 'audio' in lang: log.debug(_("Audio language {} found.".format(lang))) self.audiolangs+=[lang] - else: - self.analangs+=[lang] + self.analangs.remove(lang) if self.audiolangs == []: log.debug(_('No audio languages found in Database; creating one ' 'for each analysis language.')) From 051b73ba96d0741d44fd22452c44931ae9234f85 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:34:56 +0100 Subject: [PATCH 087/310] sorting glosslangs --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 83c24450..f20ab66d 100644 --- a/lift.py +++ b/lift.py @@ -771,9 +771,10 @@ def analangs(self): log.info('Audio languages: {}'.format(self.audiolangs)) log.info('Analysis languages: {}'.format(self.analangs)) def glosslangs(self): + """These are ordered by frequency in the database""" g=self.get('gloss').get('lang') d=self.get('definition/form').get('lang') - self.glosslangs=list(dict.fromkeys(g+d)) + self.glosslangs=[i[0] for i in collections.Counter(g+d).most_common()] log.info(_("gloss languages found: {}".format(self.glosslangs))) def glossordefn(self,guid=None,senseid=None,lang='ALL',ps=None ,showurl=False): From 294ef28cc706bcd9cc6b1147ede955e1a1549a37 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 16:55:57 +0100 Subject: [PATCH 088/310] removed langspriority references --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 8ced9f5c..775defd6 100755 --- a/main.py +++ b/main.py @@ -263,7 +263,7 @@ def guessanalang(self): else: self.analang=self.db.analangs[0] log.debug('Neither analang looks like an iso code, taking the ' - 'first one: {}'.format(langspriority)) + 'first one: {}'.format(self.db.analangs)) else: #for three or more analangs, take the first plausible iso code for n in range(nlangs): if len(self.db.analangs[n]) == 3: @@ -272,7 +272,7 @@ def guessanalang(self): '({})'.format(self.db.analangs[n]))) return log.debug('None of more than three analangs look like an iso code, ' - 'taking the first one: {}'.format(langspriority)) + 'taking the first one: {}'.format(self.db.analangs)) self.analang=self.db.analangs[0] def guessaudiolang(self): nlangs=len(self.db.audiolangs) From bfc95ecb51cbf9876a177467609846f83d7d66c1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 17:07:27 +0100 Subject: [PATCH 089/310] redue logging --- lift.py | 100 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/lift.py b/lift.py index f20ab66d..b7ce41a9 100644 --- a/lift.py +++ b/lift.py @@ -1392,20 +1392,20 @@ def removedups(x): #This removes duplicates from a list return list(dict.fromkeys(x)) class LiftURL(): def get(self,what='node'): - log.debug(self.__dict__) + log.log(4,self.__dict__) n=self.base.findall(self.url) if n != []: - log.debug("found: {} (x{}), looking for {}".format(n[:1],len(n),what)) + log.log(4,"found: {} (x{}), looking for {}".format(n[:1],len(n),what)) what=self.unalias(what) if n == [] or what is None or what == 'node': return n elif what == 'text': r=[i.text for i in n] - log.debug(r) + log.log(4,r) return r else: r=[i.get(what) for i in n] - log.debug(r) + log.log(4,r) return r def build(self,tag,liftattr=None,myattr=None,attrs=None): buildanother=False @@ -1434,7 +1434,7 @@ def build(self,tag,liftattr=None,myattr=None,attrs=None): else: self.level['cur']+=1 self.level[self.alias.get(tag,tag)]=self.level['cur'] - log.debug("Path so far: {}".format(self.drafturl())) + log.log(4,"Path so far: {}".format(self.drafturl())) if buildanother: self.build(tag) def parent(self): @@ -1449,7 +1449,7 @@ def text(self,value): def form(self,value=None,lang=None): self.baselevel() self.kwargs['value']=self.kwargs.get(value,None) #location and tonevalue - log.debug("form kwargs: {}".format(self.kwargs)) + log.log(4,"form kwargs: {}".format(self.kwargs)) self.build("form","lang",lang) #OK if lang is None if value is not None: self.text("value") @@ -1564,10 +1564,10 @@ def lift(self): "happen; exiting!") exit() def bearchildrenof(self,parent): - log.debug("bearing children of {} ({})".format(parent, + log.log(4,"bearing children of {} ({})".format(parent, self.children[parent])) for i in self.children[parent]: - log.debug("bearchildrenof i: {}".format(i)) + log.log(4,"bearchildrenof i: {}".format(i)) self.maybeshow(i,parent) def levelup(self,target): while self.level.get(target,self.level['cur']+1) < self.level['cur']: @@ -1581,7 +1581,7 @@ def baselevel(self): self.levelup(target) return elif parents.index(target) < len(parents)-1: - log.debug("level {} not in {}; checking the next one...".format( + log.log(4,"level {} not in {}; checking the next one...".format( target,self.level)) else: log.error("last level {} (of {}) not in {}; this is a problem!" @@ -1593,18 +1593,18 @@ def maybeshowtarget(self,parent): # parent here is a node ancestor to the current origin, which may # or may not be an ancestor of targethead. If it is, show it. f=self.getfamilyof(parent,x=[]) - log.debug("Maybeshowtarget: {} (family: {})".format(parent,f)) + log.log(4,"Maybeshowtarget: {} (family: {})".format(parent,f)) if self.targethead in f: if parent in self.level: - log.debug("Maybeshowtarget: leveling up to {}".format(parent)) + log.log(4,"Maybeshowtarget: leveling up to {}".format(parent)) self.levelup(parent) else: - log.debug("Maybeshowtarget: showing {}".format(parent)) + log.log(4,"Maybeshowtarget: showing {}".format(parent)) self.show(parent) self.showtargetinhighestdecendance(parent) return True def showtargetinlowestancestry(self,nodename): - log.debug("Running showtargetinlowestancestry for {}/{} on {}".format( + log.log(4,"Running showtargetinlowestancestry for {}/{} on {}".format( self.targethead,self.targettail,nodename)) #If were still empty at this point, just do the target if we can if nodename == [] and self.targethead in self.children[self.basename]: @@ -1614,7 +1614,7 @@ def showtargetinlowestancestry(self,nodename): g=1 r=giveup=False while not r and giveup is False: - log.debug("Trying generation {}".format(g)) + log.log(4,"Trying generation {}".format(g)) gen=self.parentsof(gen) for p in gen: r=self.maybeshowtarget(p) @@ -1628,12 +1628,12 @@ def showtargetinlowestancestry(self,nodename): "an ancestor of {} (target) which is also an ancestor of " "{} (current node).".format(g,self.targethead,nodename)) def showtargetinhighestdecendance(self,nodename): - log.debug("Running showtargetinhighestdecendance for {} on {}".format( + log.log(4,"Running showtargetinhighestdecendance for {} on {}".format( self.targethead,nodename)) if nodename in self.children: children=self.children[nodename] else: - log.debug("Node {} has no children, so not looking further for " + log.log(4,"Node {} has no children, so not looking further for " "descendance.".format(nodename)) return grandchildren=[i for child in children @@ -1654,33 +1654,33 @@ def showtargetinhighestdecendance(self,nodename): if ggrandchild in self.children for i in self.children[ggrandchild] ] - log.debug("Looking for {} in children of {}: {}".format( + log.log(4,"Looking for {} in children of {}: {}".format( self.targethead,nodename,children)) - log.debug("Grandchildren of {}: {}".format(nodename,grandchildren)) - log.debug("Greatgrandchildren of {}: {}".format( + log.log(4,"Grandchildren of {}: {}".format(nodename,grandchildren)) + log.log(4,"Greatgrandchildren of {}: {}".format( nodename,greatgrandchildren)) if self.targethead in children: - log.debug("Showing '{}', child of {}".format(self.targethead,nodename)) + log.log(4,"Showing '{}', child of {}".format(self.targethead,nodename)) self.show(self.targethead,nodename) elif self.targethead in grandchildren: - log.debug("Found target ({}) in grandchildren of {}: {}".format( + log.log(4,"Found target ({}) in grandchildren of {}: {}".format( self.targethead,nodename,grandchildren)) for c in children: if c in self.children and self.targethead in self.children[c]: - log.debug("Showing '{}', nearest ancenstor".format(c)) + log.log(4,"Showing '{}', nearest ancenstor".format(c)) self.show(c,nodename) #others will get picked up below self.showtargetinhighestdecendance(c) elif self.targethead in greatgrandchildren: - log.debug("Found target ({}) in gr8grandchildren of {}: {}".format( + log.log(4,"Found target ({}) in gr8grandchildren of {}: {}".format( self.targethead,nodename,greatgrandchildren)) for c in children: for cc in grandchildren: if cc in self.children and self.targethead in self.children[cc]: - log.debug("Showing '{}', nearest ancenstor".format(c)) + log.log(4,"Showing '{}', nearest ancenstor".format(c)) self.show(c,nodename) #others will get picked up below self.showtargetinhighestdecendance(c) elif self.targethead in gggrandchildren: - log.info("Found target ({}) in gggrandchildren of {}: {}".format( + log.log(4,"Found target ({}) in gggrandchildren of {}: {}".format( self.targethead,nodename,gggrandchildren)) for c in children: for cc in grandchildren: @@ -1742,18 +1742,18 @@ def maketarget(self): Once the level of the lineage head is decided, the rest of the lineage is added.""" # Now operate on the head of the target lineage - log.debug("URL (before {} target): {}".format(self.target,self.drafturl())) + log.log(4,"URL (before {} target): {}".format(self.target,self.drafturl())) if self.getalias(self.targethead) not in self.level: #If the target hasn't been made yet. log.debug(self.url) i=self.currentnodename() - log.debug("URL base: {}; i: {}".format(self.basename,i)) + log.log(4,"URL base: {}; i: {}".format(self.basename,i)) if i is None: #if it is, skip down in any case. i=self.basename - log.debug("URL bit list: {}; i: {}".format(self.url,i)) + log.log(4,"URL bit list: {}; i: {}".format(self.url,i)) if type(i) == list: i=i[0] #This should be a string f=self.getfamilyof(i,x=[]) - log.debug("Target: {}; {} family: {}".format(self.targethead,i,f)) + log.log(4,"Target: {}; {} family: {}".format(self.targethead,i,f)) if self.targethead in f: self.showtargetinhighestdecendance(i) #should get targethead # return #only do this for the first you find (last placed). @@ -1765,9 +1765,9 @@ def maketarget(self): n=self.targetbits.index(b) bp=self.targetbits[n-1].split('[')[0]#just the node, not attrs afterbp=self.drafturl().split(self.unalias(bp)) - log.debug("b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) + log.log(4,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) if len(afterbp) <=1 or b not in afterbp[1]: - log.debug("showing target element {}: {} (of {})".format(n,b,bp)) + log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) self.levelup(bp) self.show(b,parent=bp) self.levelup(self.targetbits[-1])#leave last in target, whatever else @@ -1801,7 +1801,7 @@ def shouldshow(self,node): c=self.getfamilyof(node,x=[]) # This fn is not called by showtargetinhighestgeneration or maketarget if node == self.targethead: #do this later - log.debug("skipping node {}, in target:{}".format(node,self.target)) + log.log(4,"skipping node {}, in target:{}".format(node,self.target)) return False #not self.targetlastsibling() elif self.attrneeds(node,c): return True @@ -1812,68 +1812,68 @@ def shouldshow(self,node): else: return False def getfamilyof(self,node,x): - log.debug("running kwargshaschildrenof.gen on '{}'".format(node)) + log.log(4,"running kwargshaschildrenof.gen on '{}'".format(node)) if type(node) is str: node=[node] for i in node: - log.debug("running kwargshaschildrenof.gen on '{}'".format(i)) + log.log(4,"running kwargshaschildrenof.gen on '{}'".format(i)) if i is not '': ii=self.children.get(i,'') - log.debug("Found '{}' this time!".format(ii)) + log.log(4,"Found '{}' this time!".format(ii)) if ii is not '': x+=ii self.getfamilyof(ii,x) return x def pathneeds(self,node,children): path=self.path - log.debug("Path: {}; children: {}".format(path,children)) + log.log(4,"Path: {}; children: {}".format(path,children)) if node in path and node not in self.level: - log.debug("Parent ({}) in path: {}".format(node,path)) + log.log(4,"Parent ({}) in path: {}".format(node,path)) return True if children != []: childreninpath=set(children) & set(path) if childreninpath != set(): pathnotdone=childreninpath-set(self.level) if pathnotdone != set(): - log.debug("Found descendant of {} in path, which isn't " + log.log(4,"Found descendant of {} in path, which isn't " "already there: {}".format(node, pathnotdone)) return True return False def attrneeds(self,node,children): - log.debug("looking attr(s) of {} in {}".format([node]+children, + log.log(4,"looking for attr(s) of {} in {}".format([node]+children, self.attrs)) for n in [node]+children: if n in self.attrs: - log.debug("looking attr(s) of {} in {}".format(n,self.attrs)) + log.log(4,"looking for attr(s) of {} in {}".format(n,self.attrs)) common=set(self.attrs[n])&set(list(self.kwargs)+[self.what]) if common != set(): - log.debug("Found attr(s) {} requiring {}".format(common,n)) + log.log(4,"Found attr(s) {} requiring {}".format(common,n)) return True else: - log.debug("{} not found in {}".format(n,self.attrs.keys())) + log.log(4,"{} not found in {}".format(n,self.attrs.keys())) return False def kwargsneeds(self,node,children): if node in self.kwargs: - log.debug("Parent ({}) in kwargs: {}".format(node,self.kwargs)) + log.log(4,"Parent ({}) in kwargs: {}".format(node,self.kwargs)) return True if children != []: - log.debug("Looking for descendants of {} ({}) in kwargs: {}".format( + log.log(4,"Looking for descendants of {} ({}) in kwargs: {}".format( node,children,self.kwargs)) childreninkwargs=set(children) & set(self.kwargs) if childreninkwargs != set(): - log.debug("Found descendants of {} in kwargs: {}".format(node, + log.log(4,"Found descendants of {} in kwargs: {}".format(node, childreninkwargs)) pathnotdone=childreninkwargs-set(self.level) if pathnotdone != set(): - log.debug("Found descendants of {} in kwargs, which aren't " + log.log(4,"Found descendants of {} in kwargs, which aren't " "already there: ".format(node,pathnotdone)) return True return False def callerfn(self): return sys._getframe(2).f_code.co_name #2 gens since this is a fn, too def parentsof(self,nodenames): - log.debug("children: {}".format(self.children.items())) - log.debug("key pair: {}".format( + log.log(4,"children: {}".format(self.children.items())) + log.log(4,"key pair: {}".format( ' '.join([str(x) for x in self.children.items() if nodenames in x[1]]))) p=[] if type(nodenames) != list: @@ -1936,10 +1936,10 @@ def __init__(self, *args,**kwargs): self.setaliases() self.setattrsofnodes() self.bearchildrenof(basename) - log.debug("Making Target now.") + log.log(4,"Making Target now.") self.maketarget() self.makeurl() - log.debug("Final URL: {}".format(self.url)) + log.log(4,"Final URL: {}".format(self.url)) # self.printurl() """Functions I'm using, but not in a class""" def prettyprint(node): From 5b545474037b73525ca5ad92fb6aa22caf91b948 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 17:08:15 +0100 Subject: [PATCH 090/310] version bump --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 775defd6..42ccb6e5 100755 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ program={'name':'A→Z+T'} program['tkinter']=True program['production']=False #True for making screenshots -program['version']='0.8.6' #This is a string... +program['version']='0.8.7oop' #This is a string... program['url']='https://github.com/kent-rasmussen/azt' program['Email']='kent_rasmussen@sil.org' import platform From 94359381413e5d787d4f00ab858864e134573f75 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 17:19:57 +0100 Subject: [PATCH 091/310] streamline get entry from senseid --- lift.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lift.py b/lift.py index b7ce41a9..ff14f684 100644 --- a/lift.py +++ b/lift.py @@ -265,13 +265,7 @@ def addverificationnode(self,senseid,vtype): attrib={'type':"{} verification".format(vtype)}) return (vf,node) def getentrynode(self,senseid,showurl=False): - """Get the sense node""" - urlnattr=self.geturlnattr('entry',senseid=senseid) - url=urlnattr['url'] - if showurl==True: - log.info(url) - node=self.nodes.find(url) #this should always find just one node - return node + return self.get('entry',senseid=senseid).get() def getsensenode(self,senseid,showurl=False): """Get the sense node""" urlnattr=self.geturlnattr('senseid',senseid=senseid) From 9b7e2902fd2b180e5ae3929f2b551f4d21f5c69b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 17:20:07 +0100 Subject: [PATCH 092/310] reduce logging --- lift.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lift.py b/lift.py index ff14f684..c166b7b2 100644 --- a/lift.py +++ b/lift.py @@ -1404,7 +1404,7 @@ def get(self,what='node'): def build(self,tag,liftattr=None,myattr=None,attrs=None): buildanother=False noseparator=False - log.debug("building {}, @dict:{}, @{}={}, on top of {}".format(tag, + log.log(4,"building {}, @dict:{}, @{}={}, on top of {}".format(tag, attrs,liftattr,myattr, self.currentnodename())) b=tag if attrs is None: @@ -1531,7 +1531,7 @@ def show(self,nodename,parent=None): #call this directly if you know you want it else: args=list() for arg in args: - log.debug("show arg: {}".format(arg)) + log.log(4,"show arg: {}".format(arg)) if len(args) == 0: getattr(self,nodename)() else: @@ -1680,7 +1680,7 @@ def showtargetinhighestdecendance(self,nodename): for cc in grandchildren: for ccc in greatgrandchildren: if ccc in self.children and self.targethead in self.children[ccc]: - log.debug("Showing '{}', nearest ancenstor".format(c)) + log.log(4,"Showing '{}', nearest ancenstor".format(c)) self.show(c,nodename) #others will get picked up below self.showtargetinhighestdecendance(c) else: @@ -1696,7 +1696,7 @@ def nodesatlevel(self,levelname='cur'): def parsetargetlineage(self): if '/' in self.target: #if target lineage is given self.targetbits=self.target.split('/') - log.debug("{} : {}".format(self.target,self.targetbits)) + log.log(4,"{} : {}".format(self.target,self.targetbits)) self.targethead=self.targetbits[0] self.targettail=self.targetbits[1:] else: @@ -1738,7 +1738,7 @@ def maketarget(self): # Now operate on the head of the target lineage log.log(4,"URL (before {} target): {}".format(self.target,self.drafturl())) if self.getalias(self.targethead) not in self.level: #If the target hasn't been made yet. - log.debug(self.url) + log.log(4,self.url) i=self.currentnodename() log.log(4,"URL base: {}; i: {}".format(self.basename,i)) if i is None: #if it is, skip down in any case. @@ -1877,7 +1877,7 @@ def parentsof(self,nodenames): i.reverse() p+=i plist=list(dict.fromkeys(p)) - log.debug("parents of {}: {}".format(nodenames,plist)) + log.log(4,"parents of {}: {}".format(nodenames,plist)) return plist def setattrsofnodes(self): self.attrs={} #These are atttributes we ask for, which require the field From 4e7f843588566b7b536c8126545a535cca278a2a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 17:49:31 +0100 Subject: [PATCH 093/310] trim get sense node --- lift.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lift.py b/lift.py index c166b7b2..ad374cc2 100644 --- a/lift.py +++ b/lift.py @@ -267,13 +267,7 @@ def addverificationnode(self,senseid,vtype): def getentrynode(self,senseid,showurl=False): return self.get('entry',senseid=senseid).get() def getsensenode(self,senseid,showurl=False): - """Get the sense node""" - urlnattr=self.geturlnattr('senseid',senseid=senseid) - url=urlnattr['url'] - if showurl==True: - log.info(url) - node=self.nodes.find(url) #this should always find just one node - return node + return self.get('sense',senseid=senseid).get() def addexamplefields(self,**kwargs): # ,guid,senseid,analang,glosslang,glosslang2,forms, # fieldtype,location,fieldvalue,ps=None From ab0ef1ad1c86d8567d94ff320c6b27b3f9da7026 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 21 Oct 2021 17:49:54 +0100 Subject: [PATCH 094/310] cleaning addexamplefields --- lift.py | 51 +++++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/lift.py b/lift.py index ad374cc2..b66c961b 100644 --- a/lift.py +++ b/lift.py @@ -269,64 +269,47 @@ def getentrynode(self,senseid,showurl=False): def getsensenode(self,senseid,showurl=False): return self.get('sense',senseid=senseid).get() def addexamplefields(self,**kwargs): - # ,guid,senseid,analang,glosslang,glosslang2,forms, - # fieldtype,location,fieldvalue,ps=None - # This fuction will add an XML node to the lift tree, like a new - # example field. - # The program should know before calling this, that there isn't - # already the relevant node --since it is agnostic of what is already - # there. log.info(_("Adding values (in lift.py) : {}").format(kwargs)) - # showurl=kwargs.get('showurl',False) + #These should always be there: senseid=kwargs.get('senseid') location=kwargs.get('location') - node=self.getsensenode(senseid=senseid) - if node is None: - log.info("Sorry, this didn't return a node: {}".format(senseid)) - return - fieldtype=kwargs.get('fieldtype') - tonevalue=kwargs.get('fieldvalue') - # Logic to check if this example already here - # This function returns a text node (from any one of a number of - # example nodes, which match form, gloss and location) containing a - # tone sorting value, or None (if no example nodes match form, gloss - # and location) - #We're adding a node to kwargs here. - # exfieldvalue=self.get('examplebylocation',senseid=senseid,location=location) - exfieldvalue=lift.get('example/field/form/text', + fieldtype=kwargs.get('fieldtype') # ever not 'tone'? + exfieldvalue=self.get('example/field/form/text', path=['location','tonefield'], senseid=senseid, - fieldtype='tone',location=location, - # tonevalue=fieldvalue, - what='node') - # Do this for all duplicates, which should be removed later anyway. + fieldtype=fieldtype,location=location, + ).get('node') + # Set values for all duplicates, which should be removed later anyway. # I.e., don't leave inconsisted data in the database. + tonevalue=kwargs.get('fieldvalue') #don't test for this yet if len(exfieldvalue) > 0: for e in exfieldvalue: e.text=tonevalue else: #If not already there, make it. log.info("Didn't find that example already there, creating it...") + sensenode=self.getsensenode(senseid=senseid) + if sensenode is None: + log.info("Sorry, this didn't return a node: {}".format(senseid)) + return analang=kwargs.get('analang') - glosslang=kwargs.get('glosslang') - glosslang2=kwargs.get('glosslang2',None) - db=kwargs.get('db') + # glosslang=kwargs.get('glosslang') + # glosslang2=kwargs.get('glosslang2',None) + db=kwargs.get('db') #This an object with values forms=db.forms glosses=db.glosses glosslangs=db.glosslangs p=Node(node, tag='example') - p.makeformnode(analang,db.analang) + p.makeformnode(analang,forms[analang]) """Until I have reason to do otherwise, I'm going to assume these fields are being filled in in the glosslang language.""" - fieldgloss=Node(p,'translation',attrib={'type': - 'Frame translation'}) + fieldgloss=Node(p,'translation',attrib={'type':'Frame translation'}) for lang in glosslangs: if lang != None and hasattr(forms,lang): fieldgloss.makeformnode(lang,getattr(forms,lang)) exfieldvalue=p.makefieldnode(fieldtype,glosslang,gimmetext=True) p.makefieldnode('location',glosslang,text=location) p.makefieldnode('tone',glosslang,text=tonevalue) - # exfieldvalue.text=fieldvalue #change this *one* value, either way. - senseid=kwargs.get('senseid') + # senseid=kwargs.get('senseid') if 'guid' in kwargs: guid=kwargs.get('guid') self.updatemoddatetime(guid=guid,senseid=senseid) From a6937506e7cca0552e279cd6483cd98e826d3106 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 09:48:59 +0100 Subject: [PATCH 095/310] removing excess fns --- lift.py | 83 --------------------------------------------------------- 1 file changed, 83 deletions(-) diff --git a/lift.py b/lift.py index b66c961b..58eac077 100644 --- a/lift.py +++ b/lift.py @@ -806,26 +806,6 @@ def getguids(self): #get the number entries in a lift file. self.nguids=len(self.guids) #,guid,lang,fieldtype,location def nc(self): nounclasses="1 2 3 4 5 6 7 8 9 10 11 12 13 14" - # def nlist(self): #This variable gives lists, to iterate over. - # # prenasalized=['mb','mp','mbh','mv','mf','nd','ndz','ndj','nt','ndh','ng','ŋg','ŋg','nk','ngb','npk','ngy','nj','nch','ns','nz'] #(graphs that preceede a consonant) - # ntri=["ng'"] - # ndi=['mm','ny','ŋŋ'] - # nm=['m','m','M','n','n','ŋ','ŋ','ɲ'] - # nasals=ntri+ndi+nm - # actuals={} - # for lang in self.analangs: - # unsorted=self.inxyz(lang,nasals) - # """Make digraphs appear first, so they are matched if present""" - # actuals[lang]=sorted(unsorted,key=len, reverse=True) - # return actuals - # def glist(self): #This variable gives lists, to iterate over. - # glides=['ẅ','y','Y','w','W'] - # actuals={} - # for lang in self.analangs: - # unsorted=self.inxyz(lang,glides) #remove the symbols which are not in the data. - # """Make digraphs appear first, so they are matched if present""" - # actuals[lang]=sorted(unsorted,key=len, reverse=True) - # return actuals def clist(self): #This variable gives lists, to iterate over. log.log(2,"Creating CV lists from scratch") """These are all possible forms, that I have ever run across. @@ -967,30 +947,6 @@ def clist(self): #This variable gives lists, to iterate over. def slists(self): self.segmentsnotinregexes={} self.clist() - # def segmentin(self, lang, glyph): - # """This actually allows for dygraphs, etc., so I'm keeping it.""" - # """check each form and lexeme in the lift file (not all files - # use both).""" - # for form in self.citationforms[lang] + self.lexemes[lang]: - # if re.search(glyph,form): #see if the glyph is there - # return glyph #find it and stop looking, or return nothing - # def inxyz(self, lang, segmentlist): #This calls the above script for each character. - # actuals=list() - # for i in segmentlist: - # s=self.segmentin(lang,i) - # #log.info(s) #to see the following run per segment - # if s is not None: - # actuals.append(s) - # return list(dict.fromkeys(actuals)) - # def getguidformstosearchbyps(self,ps,lang=None): - # if lang is None: - # lang=self.analang - # self.guidformstosearch[lang][ps]={} #Erases all previous data!! - # for guid in self.get('guidbyps',lang=lang,ps=ps): - # form=self.get('citation',guid=guid,lang=lang,ps=ps) - # if len(form) == 0: #no items returned - # form=self.get('lexeme',guid=guid,lang=lang,ps=ps) - # self.guidformstosearch[lang][ps][guid]=form def getsenseidformstosearchbyps(self,ps,lang=None): if lang is None: lang=self.analang @@ -1000,39 +956,6 @@ def getsenseidformstosearchbyps(self,ps,lang=None): if len(form) == 0: #no items returned form=self.get('lexeme',senseid=senseid,lang=lang,ps=ps) self.senseidformstosearch[lang][ps][senseid]=form - # def getguidformstosearch(self): - # # import time - # """This outputs a dictionary of form {analang: {guid:form}*}*, where - # form is citation if available, or else lexeme. This is to be flexible - # for entries in process of analysis, and to have a dictionary to check - # with regexes for output.""" - # self.guidformstosearch={} - # self.senseidformstosearch={} - # for lang in self.analangs: - # self.guidformstosearch[lang]={} #This will erase all previous data!! - # self.senseidformstosearch[lang]={} - # for ps in self.pss: #I need to break this up. - # # start_time=time.time() - # self.getguidformstosearchbyps(ps,lang=lang) - # self.getsenseidformstosearchbyps(ps,lang=lang) - # #"n",str(time.time() - start_time),"seconds.") - # #log.info(self.guidformstosearch) - # def getformstosearchbyps(self,ps,lang=None): - # if lang is None: - # lang=self.analang - # self.formstosearch[lang][ps]={} #Erases all previous data!! - # #for guid in self.get('guidbynofield',lang=lang,ps=ps): - # # forms=self.citationorlexeme(lang=lang,ps=ps) - # """This actually needs this logic here, since formstosearch hasn't - # been made yet.""" - # forms=self.get('citation/form/text',analang=lang,ps=ps) - # # if len(forms) == 0: #no items returned, I should probably combine - # #this at some point, list(dict.fromkeys(form1+form2)) - # forms+=self.get('lexeme/form/text',analang=lang,ps=ps) - # # forms1=self.get('citation',lang=lang,ps=ps) - # # forms2=self.get('lexeme',lang=lang,ps=ps) - # # forms=list(dict.fromkeys(forms1+forms2)) - # self.formstosearch[lang][ps]=forms def getformstosearch(self): """This outputs a dictionary of form {analang: {guid:form}*}*, where form is citation if available, or else lexeme. This is to be flexible @@ -1097,12 +1020,6 @@ def pss(self): #get all POS values in the LIFT file p=list(dict.fromkeys(self.get('ps').get('value'))) log.info("Found these ps values: {}".format(p)) return p - #pss=list() - #for ps in self.nodes.findall(f"entry/sense/grammatical-info"): - # thisps=ps.attrib.get('value') - # if thisps not in pss and thisps is not None: - # pss.append(thisps) - #return pss #return the list """CONTINUE HERE: Making things work for the new lift.get() paradigm.""" def formsbyps(self,ps): #self is LIFT! #should be entriesbyps """This function just pulls all entries of a particular From 4e1efa29a42ab9328da53d501e9a5e85362953a4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 11:34:19 +0100 Subject: [PATCH 096/310] added morphtypes fn --- lift.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lift.py b/lift.py index 58eac077..88e61321 100644 --- a/lift.py +++ b/lift.py @@ -79,6 +79,7 @@ def __init__(self, filename,nsyls=None): self.findduplicateforms() self.findduplicateexamples() """Think through where this belongs; what classes/functions need it?""" + self.morphtypes=self.getmorphtypes() log.info("Language initialization done.") def geturlnattr(self, attribute, **kwargs): if attribute == 'attributes': @@ -1020,6 +1021,11 @@ def pss(self): #get all POS values in the LIFT file p=list(dict.fromkeys(self.get('ps').get('value'))) log.info("Found these ps values: {}".format(p)) return p + def getmorphtypes(self): #get all morph-type values in the LIFT file + m=collections.Counter(self.get('morphtype',showurl=True).get('value') + ).most_common() + log.info("Found these morph-type values: {}".format(m)) + return m """CONTINUE HERE: Making things work for the new lift.get() paradigm.""" def formsbyps(self,ps): #self is LIFT! #should be entriesbyps """This function just pulls all entries of a particular From 3184cf01bb667d202f0f2833041a7a0df28e0c35 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 11:34:47 +0100 Subject: [PATCH 097/310] options for debugging --- lift.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 88e61321..aa800176 100644 --- a/lift.py +++ b/lift.py @@ -2374,9 +2374,13 @@ def printurllog(lift): from logsetup import * log=logsetup(loglevel) # filename="/home/kentr/Assignment/Tools/WeSay/dkx/MazHidi_Lift.lift" - # filename="/home/kentr/Assignment/Tools/WeSay/gnd/gnd.lift.bak.txt" + # filename="/home/kentr/Assignment/Tools/WeSay/bse/SIL CAWL Wushi.lift" # filename="/home/kentr/Assignment/Tools/WeSay/bfj/bfj.lift" # filename="/home/kentr/Assignment/Tools/WeSay/gnd/gnd.lift" + # filename="/home/kentr/Assignment/Tools/WeSay/eto/eto.lift" + # filename="/home/kentr/Assignment/Tools/WeSay/tsp/TdN.lift" + # filename="/home/kentr/Assignment/Tools/WeSay/eto/eto.lift" + # filename="/home/kentr/Assignment/Tools/WeSay/bqg/Kusuntu.lift" filename="/home/kentr/Assignment/Tools/WeSay/CAWL_demo/SILCAWL.lift" lift=Lift(filename,nsyls=2) senseids=["begin_7c6fe6a9-9918-48a8-bc3a-e88e61efa8fa", @@ -2501,7 +2505,7 @@ def test(): # entries=lift.get("entry").get() # log.info(len(entries)) # log.info(entries[0].get('guid')) - printurllog(lift) + # printurllog(lift) quit() import timeit def timetest(): From 95a998f27798aeaea90179c5923440f0ade44feb Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 11:37:49 +0100 Subject: [PATCH 098/310] clean out comments --- lift.py | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/lift.py b/lift.py index aa800176..e074b243 100644 --- a/lift.py +++ b/lift.py @@ -797,14 +797,12 @@ def getlocations(self,guid=None,lang=None): #get all the field types in a given l=list(dict.fromkeys(self.get('example/locationfield').get('text'))) log.info('Locations found in Examples: {}'.format(l)) return l - def getsenseids(self): #get the number entries in a lift file. - self.senseids=self.get('sense').get('senseid') #,showurl=True - self.nsenseids=len(self.senseids) #,guid,lang,fieldtype,location - # log.info(self.nsenseids) - def getguids(self): #get the number entries in a lift file. - self.guids=self.get('entry').get('guid') #,showurl=True - # log.info(self.guids) - self.nguids=len(self.guids) #,guid,lang,fieldtype,location + def getsenseids(self): + self.senseids=self.get('sense').get('senseid') + self.nsenseids=len(self.senseids) + def getguids(self): + self.guids=self.get('entry').get('guid') + self.nguids=len(self.guids) def nc(self): nounclasses="1 2 3 4 5 6 7 8 9 10 11 12 13 14" def clist(self): #This variable gives lists, to iterate over. @@ -865,35 +863,16 @@ def clist(self): #This variable gives lists, to iterate over. # x[dconsvar]+=c[stype][nglyphs] # else: x[consvar]+=c[stype][nglyphs] - # s['g']={} - # x['NC']=['mbh','ndz','ndj','ndh','ngb','npk','ngy','nch','mb','mp', - # 'mv','mf','nd','nt','ng','ŋg','ŋg','nk','nj','ns','nz'] x['ʔ']=['ʔ', "ꞌ", #Latin Small Letter Saltillo "'", #Tag Apostrophe 'ʼ' #modifier letter apostrophe ] x['G']=['ẅ','y','Y','w','W'] - # x['CG']=list((char+g for char in x['C'] for g in x['G'])) x['N']=["ng'",'mm','ŋŋ','m','M','N','n','ŋ','ɲ'] #no longer:'ny', - # x['NC']=list((n+char for char in x['C'] for n in x['N'])) - # x['NCG']=list((n+char+g for char in x['C'] for n in x['N'] - # for g in x['G'])) """Non-Nasal/Glide Sonorants""" x['S']=['l','r'] x['Sdg']=['rh','wh'] - # x['CS']=list((char+s for char in x['C'] for s in x['S'])) - # x['NCS']=list((n+char+s for char in x['C'] for n in x['N'] - # for s in x['S'])) - # self.treatlabializepalatalizedasC=False - # if self.treatlabializepalatalizedasC==True: - # lp={} - # lp['lab']=list(char+'w' for char in c) - # lp['pal']=list(char+'y' for char in c) - # lp['labpal']=list(char+'y' for char in lp['lab']) - # lp['labpal']+=list(char+'w' for char in lp['pal']) - # for stype in sorted(lp.keys()): #larger graphs first - # c=lp[stype]+c x['V']=[ #decomposed first: #tilde (decomposed): @@ -927,11 +906,6 @@ def clist(self): #This variable gives lists, to iterate over. x['ː']=[":","ː"] # vowel length markers x['b']=['=','-'] #affix boundary markers x['o']=['<','<','>','>','›','»','‹','«',''] #macron here? - # """We need to address long and idiosyncratic vowel orthographies, - # especially for Cameroon. This should also include diacritics, together - # or separately.""" - # """At some point, we may want logic to include only certain - # elements in c. The first row is in pretty much any language.""" actuals={} log.log(3,'hypotheticals: {}'.format(x)) self.s={} #wipe out an existing dictionary From df25ac3ced1a8e0128019649f42709170cbd4d6c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 11:42:49 +0100 Subject: [PATCH 099/310] clean up --- lift.py | 55 +++++++++++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/lift.py b/lift.py index e074b243..a75e3334 100644 --- a/lift.py +++ b/lift.py @@ -310,12 +310,11 @@ def addexamplefields(self,**kwargs): exfieldvalue=p.makefieldnode(fieldtype,glosslang,gimmetext=True) p.makefieldnode('location',glosslang,text=location) p.makefieldnode('tone',glosslang,text=tonevalue) - # senseid=kwargs.get('senseid') if 'guid' in kwargs: guid=kwargs.get('guid') self.updatemoddatetime(guid=guid,senseid=senseid) else: - self.updatemoddatetime(senseid=kwargs['senseid']) + self.updatemoddatetime(senseid=senseid) if self.debug == True: log.info("add langform: {}".format(forms.analang)) log.info("add tone: {}".format(fieldvalue)) @@ -764,32 +763,32 @@ def glossordefn(self,guid=None,senseid=None,lang='ALL',ps=None for form in formsd: forms.append(rx.glossifydefn(form)) return forms - def citationorlexeme(self,guid=None,senseid=None,lang=None,ps=None - ,showurl=False): - """I think this was a nice idea, but unnecessary; ability to use guid - or senseid is more important.""" - # if guid is None: - # try: - # for guid in self.guidsvalidwps: - # return self.citationorlexeme(guid=guid,senseid=senseid, - # lang=lang,ps=ps, - # showurl=showurl) - # except: - # for guid in self.guids: - # return self.citationorlexeme(guid=guid,senseid=senseid, - # lang=lang,ps=ps, - # showurl=showurl) - # else: - forms=self.get('citation',guid=guid,senseid=senseid,analang=lang, - showurl=showurl, - ps=ps - ) #,showurl=True - if forms == []: #for the whole db this will not work if even one gloss is filled out - forms=self.get('lexeme',guid=guid,senseid=senseid,analang=lang, - showurl=showurl, - ps=ps - ) - return forms + # def citationorlexeme(self,guid=None,senseid=None,lang=None,ps=None + # ,showurl=False): + # """I think this was a nice idea, but unnecessary; ability to use guid + # or senseid is more important.""" + # # if guid is None: + # # try: + # # for guid in self.guidsvalidwps: + # # return self.citationorlexeme(guid=guid,senseid=senseid, + # # lang=lang,ps=ps, + # # showurl=showurl) + # # except: + # # for guid in self.guids: + # # return self.citationorlexeme(guid=guid,senseid=senseid, + # # lang=lang,ps=ps, + # # showurl=showurl) + # # else: + # forms=self.get('citation',guid=guid,senseid=senseid,analang=lang, + # showurl=showurl, + # ps=ps + # ) #,showurl=True + # if forms == []: #for the whole db this will not work if even one gloss is filled out + # forms=self.get('lexeme',guid=guid,senseid=senseid,analang=lang, + # showurl=showurl, + # ps=ps + # ) + # return forms def fields(self,guid=None,lang=None): #get all the field types in a given entry f=list(dict.fromkeys(self.get('field').get('type'))) return f From d6b4f4bd81d3053c41c48d49d66c20cc968a47b3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:20:35 +0100 Subject: [PATCH 100/310] allow show for retarget --- lift.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index a75e3334..c34d857b 100644 --- a/lift.py +++ b/lift.py @@ -105,13 +105,15 @@ def geturlnattr(self, attribute, **kwargs): log.log(2,'After removenone: {}'.format(url)) log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) return {'url':url,'attr':self.attribdict[attribute]['attr']} - def retarget(self,urlobj,target): + def retarget(self,urlobj,target,showurl=False): k=self.urlkey(urlobj.kwargs) urlobj.kwargs['retarget']=target k2=self.urlkey(urlobj.kwargs) if k2 not in self.urls: self.urls[k2]=copy.deepcopy(urlobj) self.urls[k2].retarget(target) + if showurl: + log.info("URL for retarget: {}".format(self.urls[k2].url)) return self.urls[k2] def urlkey(self,kwargs): kwargscopy=kwargs.copy() #for only differences that change the URL From cdb49769518e78a76a13274860a560b44fabc89c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:21:16 +0100 Subject: [PATCH 101/310] rename to addmodexamplefields --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index c34d857b..58c7773d 100644 --- a/lift.py +++ b/lift.py @@ -271,7 +271,7 @@ def getentrynode(self,senseid,showurl=False): return self.get('entry',senseid=senseid).get() def getsensenode(self,senseid,showurl=False): return self.get('sense',senseid=senseid).get() - def addexamplefields(self,**kwargs): + def addmodexamplefields(self,**kwargs): log.info(_("Adding values (in lift.py) : {}").format(kwargs)) #These should always be there: senseid=kwargs.get('senseid') From 2f6b569b43f2a132a3079cf1c54357a9804336a9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:21:52 +0100 Subject: [PATCH 102/310] fixed updatemoddatetime, now on entry and sense --- lift.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lift.py b/lift.py index 58c7773d..c9eebf72 100644 --- a/lift.py +++ b/lift.py @@ -635,17 +635,19 @@ def updateexfieldvalue(self,guid=None,senseid=None,analang=None, node.text=newfieldvalue #remove(example) self.updatemoddatetime(guid=guid,senseid=senseid) # self.write() - def updatemoddatetime(self,guid=None,senseid=None,analang=None, - glosslang=None,langform=None,glossform=None,fieldtype=None, - location=None,fieldvalue=None,ps=None, - newfieldvalue=None,showurl=False): + def updatemoddatetime(self,guid=None,senseid=None): """This updates the fieldvalue, ignorant of current value.""" - urlnattr=self.geturlnattr('entry',guid=guid,senseid=senseid) #just entry - url=urlnattr['url'] - if showurl==True: - log.info(url) - node=self.nodes.find(url) #this should always find just one node - node.attrib['dateModified']=getnow() + if senseid is not None: + surl=self.get('sense',senseid=senseid) #url object + for s in surl.get(): + s.attrib['dateModified']=getnow() #node + eurl=self.get('entry',senseid=senseid) #url object + for e in eurl.get(): + e.attrib['dateModified']=getnow() #node + elif guid is not None: #only if no senseid given + for e in self.get('entry',guid=guid).get(): + e.attrib['dateModified']=getnow() + self.write() def read(self): """this parses the lift file into an entire ElementTree tree, for reading or writing the LIFT file.""" From e691e0fc7a9f2c85e2a53193e45ef1b206fa8dd4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:22:17 +0100 Subject: [PATCH 103/310] remove excessive form --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index c9eebf72..be8fb005 100644 --- a/lift.py +++ b/lift.py @@ -1368,7 +1368,7 @@ def translation(self): self.kwargs['ftype']='Frame translation' self.kwargs['formtext']='translationvalue' self.build("translation","type","ftype") - self.form("translationvalue",'glosslang') + # self.form("translationvalue",'glosslang') def field(self): self.baselevel() self.build("field","type","ftype") From d9f71deeabdcd27f4d7717c78827d8695221343a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:22:33 +0100 Subject: [PATCH 104/310] add translation as glosslang field --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index be8fb005..3d011b0b 100644 --- a/lift.py +++ b/lift.py @@ -1580,7 +1580,7 @@ def parsetargetlineage(self): self.targethead=self.target self.targetbits=[self.targethead,] self.targettail=[] - if 'form' in self.targethead: + if 'form' in self.targethead and 'form' not in self.children[self.basename]: log.error("Looking for {} as the head of a target is going to " "cause problems, as it appears in too many places, and is likely " "to not give the desired results. Fix this, and try again. (whole " From 46e84ca10df33c1fdd9bde05c061200fe61e090b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:23:22 +0100 Subject: [PATCH 105/310] allow form as head if child of base (switched msgs with last) --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 3d011b0b..784ccc84 100644 --- a/lift.py +++ b/lift.py @@ -1415,7 +1415,7 @@ def show(self,nodename,parent=None): #call this directly if you know you want it getattr(self,nodename)(*args) def formargsbyparent(self,parent): args=list() - if parent in ['gloss', 'definition']: + if parent in ['gloss', 'definition','translation']: args.append(parent) args.append('glosslang') if parent in ['lexeme', 'citation', 'example']: From 87c3797564cc2894107fd394814b5658e6d0b8e3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:23:43 +0100 Subject: [PATCH 106/310] moved setchildren to be available earlier --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 784ccc84..3f2a19ee 100644 --- a/lift.py +++ b/lift.py @@ -1797,13 +1797,13 @@ def __init__(self, *args,**kwargs): log.info("LiftURL called with {}".format(kwargs)) self.kwargs=kwargs target=self.target=self.kwargs.pop('target','entry') # what do we want? + self.setchildren() self.parsetargetlineage() self.what=self.kwargs.pop('what','node') #This should always be there self.path=kwargs.pop('path',[]) self.url=[] self.level={'cur':0,basename:0} self.guid=self.senseid=self.attrdonothing - self.setchildren() self.setaliases() self.setattrsofnodes() self.bearchildrenof(basename) From 31a7ab7640cf57f92c75064c0b07698526e8fa12 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:24:04 +0100 Subject: [PATCH 107/310] doc --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 3f2a19ee..6f68a56b 100644 --- a/lift.py +++ b/lift.py @@ -134,6 +134,7 @@ def get(self, target, node=None, **kwargs): Never ask for just the form! give the parent, to get a particular form: lift.get("lexeme/form").get('text') lift.get("example/form").get('text') + lift.get("example/translation/form").get('text') lift.get("citation/form").get('text') just 1 of each pss: dict.fromkeys(lift.get("ps").get('value')) get tone value: From 181403d0fc550a816897a5b35e4c18a0b4b485de Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:40:15 +0100 Subject: [PATCH 108/310] updated addtoneUF --- lift.py | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/lift.py b/lift.py index 6f68a56b..660eeac8 100644 --- a/lift.py +++ b/lift.py @@ -473,29 +473,19 @@ def findduplicateexamples(self): "found in the lexicon.") # self.write() Not yet, anyway def addtoneUF(self,senseid,group,analang,guid=None,showurl=False): - urlnattr=self.geturlnattr('senseid',senseid=senseid) #give the sense. - url=urlnattr['url'] - if showurl==True: - log.info(url) - node=self.nodes.find(url) #this should always find just one node - if node is None: - log.info(' '.join("Sorry, this didn't return a node:",guid,senseid)) + node=self.get('sense',senseid=senseid).get() #give the sense. + if node == []: + log.info("Sorry, this didn't return a node: guid {}; senseid {}" + "".format(guid,senseid)) return - t=None - for field in node.findall('field'): - if field.get('type') == 'tone': - f=field.findall('form') - f2=field.find('form') - t=f2.find('text') - for fs in f: - t2=fs.find('text') - if t is None: - p=ET.SubElement(node, 'field',attrib={'type':'tone'}) - f=ET.SubElement(p,'form',attrib={'lang':analang}) - t=ET.SubElement(f,'text') - t.text=group + t=self.get('field/form/text',node=node[0],ftype='tone').get() + if t == []: + p=Node(node[0],'field',attrib={'type':'tone'}) + p.makeformnode(analang,text=group) + else: + t[0].text=group self.updatemoddatetime(guid=guid,senseid=senseid) - # self.write() + self.write() """ toneinfo for sense. """ From 6ab89dce47283dea44d751a69335e6d520e2a091 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:40:56 +0100 Subject: [PATCH 109/310] testing changes --- lift.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 660eeac8..9d0fa5f7 100644 --- a/lift.py +++ b/lift.py @@ -1779,6 +1779,7 @@ def setaliases(self): self.alias['lexical-unit']='lexeme' self.alias['grammatical-info']='ps' self.alias['id']='senseid' + self.alias['ftype']='fieldtype' def __init__(self, *args,**kwargs): self.base=kwargs['base'] if type(kwargs['base']) is Lift: @@ -2474,6 +2475,10 @@ def test(): # log.info(len(entries)) # log.info(entries[0].get('guid')) # printurllog(lift) + lift.addtoneUF(#guid='09926cec-8be1-4f66-964e-4fdd8fa75fdc', + senseid='continue, resume_d174612b-b3c0-4073-bff0-58fd098252a9',#senseids[0], + group='4',analang='en') + # lift.write() quit() import timeit def timetest(): @@ -2482,7 +2487,6 @@ def timetest(): print(out1) timetest() # log.info(lift.urls) - # lift.write() # log.info('\n'.join([str(x) for x in lift.urls.items()])) exit()# print('l:',l) showurl=True From 719d80b2ae9df99f2af890c77fdc708d72eea0f9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:41:33 +0100 Subject: [PATCH 110/310] update to addmodexamplefields --- main.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 42ccb6e5..c11f5352 100755 --- a/main.py +++ b/main.py @@ -4497,9 +4497,9 @@ def updatebysubchecksenseid(self,oldtonevalue,newtonevalue,verified=False): for senseid in senseids: """This updates the fieldvalue from 'fieldvalue' to 'newfieldvalue'.""" - self.db.updateexfieldvalue(senseid=senseid,fieldtype='tone', - location=self.name,fieldvalue=oldtonevalue, - newfieldvalue=newtonevalue) + self.db.addmodexamplefields(senseid=senseid,fieldtype='tone', + location=self.name,#fieldvalue=oldtonevalue, + fieldvalue=newtonevalue) self.db.modverificationnode(senseid=senseid,vtype=self.profile, add=add,rm=rm,addifrmd=True) self.db.write() #once done iterating over senseids @@ -4529,7 +4529,7 @@ def addtonefieldex(self,senseid,framed): self.name, senseid, guid)) - self.db.addexamplefields( #This should only mod if already there + self.db.addmodexamplefields( #This should only mod if already there guid=guid,senseid=senseid, analang=self.analang, glosslang=self.glosslang, @@ -8469,7 +8469,7 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): subcheck=self.subcheck log.info(_("Removing senseid {} from subcheck {}".format(senseid,subcheck))) #This should only *mod* if already there - self.db.addexamplefields(senseid=senseid, + self.db.addmodexamplefields(senseid=senseid, analang=self.analang, glosslang=self.glosslang, glosslang2=self.glosslang2, #OK if None From dae6e2f39f020693570b5ff54b331ad82b30ed89 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:41:46 +0100 Subject: [PATCH 111/310] allow addmodexamplefields outside of class --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index c11f5352..48c9e879 100755 --- a/main.py +++ b/main.py @@ -7652,7 +7652,7 @@ def addlink(self): self.db.addmediafields(self.node,self.filename,self.audiolang) def function(self): pass - def makefilenames(self,check=None,senseid=None): + def makefilenames(self=None,check=None,senseid=None): if self is not None: #i.e., this is called by class if self.test==True: return "test_{}_{}.wav".format(self.settings.fs, From 3b1a3f9633d4de1a47525b3334bbe943f390b22e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:42:36 +0100 Subject: [PATCH 112/310] remove geturlnattr from main.py --- main.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index 48c9e879..c8974f7d 100755 --- a/main.py +++ b/main.py @@ -7670,8 +7670,8 @@ def makefilenames(self=None,check=None,senseid=None): if None in [check, senseid]: return id=senseid - node=firstoflist(check.db.get('examplebylocation',senseid=senseid, - location=check.name)) + node=firstoflist(check.db.get('example',senseid=senseid, + location=check.name).get()) if node is None: # This should never be! log.error("Looks like a node came back 'None'; this may be " @@ -7694,17 +7694,21 @@ def makefilenames(self=None,check=None,senseid=None): log.error("Node{}cg: {}; tag:{}; attrib:{}; text:{}".format( nodes.index(node),ggchild,ggchild.tag, ggchild.attrib,ggchild.text)) - gloss=node.find(check.db.geturlnattr('glossofexample')['url']).text - form=node.find(check.db.geturlnattr('formofexample', - lang=check.analang)['url']).text - audio=node.find(check.db.geturlnattr('formofexample', - lang=check.audiolang)['url']) + gloss=unlist(check.db.get('translation/form/text',node=node, + glosslang=check.glosslang,showurl=True).get('text')) + form=unlist(check.db.get('form/text',node=node,showurl=True, + analang=check.analang).get('text')) + log.log(4,"gloss: {}".format(gloss)) + log.log(4,"form: {}".format(form)) + audio=check.db.get('example/form/text',node=node,showurl=True, + analang=check.audiolang).get('text') + log.log(4,"audio: {}".format(audio)) if gloss is None: gloss=t(check.db.get('gloss',senseid=senseid, glosslang=check.glosslang)) if form is None and node is not None: form=t(node.find(f"form[@lang='{check.analang}']/text")) - if audio is not None: + if audio != []: filenameURL=str(file.getdiredurl(check.audiodir,audio.text)) if file.exists(filenameURL): log.debug("Audio file found! using name: {}; diredname: {}" From 171a924ce65ac6b80e81e660371f37d8e5cf4631 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 14:43:13 +0100 Subject: [PATCH 113/310] for testing --- main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.py b/main.py index c8974f7d..63f365a1 100755 --- a/main.py +++ b/main.py @@ -222,6 +222,11 @@ def __init__(self, parent, frame, nsyls=None): log.info("Done initializing check; running first check check.") """Testing Zone""" #set None to make labels, else "raised" "groove" "sunken" "ridge" "flat" + # n=self.db.getsensenode() + # senseid="begin_7c6fe6a9-9918-48a8-bc3a-e88e61efa8fa" + # self.name='Progressive' + # RecordButtonFrame.makefilenames(check=self,senseid=senseid) + # log.info(n) self.mainlabelrelief() self.checkcheck() def notifyuserofextrasegments(self): From 15eac033e074d0389493f95f294d88ea93285cff Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 15:52:05 +0100 Subject: [PATCH 114/310] simplify updatemoddatetime call --- lift.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lift.py b/lift.py index 9d0fa5f7..208da70d 100644 --- a/lift.py +++ b/lift.py @@ -313,11 +313,7 @@ def addmodexamplefields(self,**kwargs): exfieldvalue=p.makefieldnode(fieldtype,glosslang,gimmetext=True) p.makefieldnode('location',glosslang,text=location) p.makefieldnode('tone',glosslang,text=tonevalue) - if 'guid' in kwargs: - guid=kwargs.get('guid') - self.updatemoddatetime(guid=guid,senseid=senseid) - else: - self.updatemoddatetime(senseid=senseid) + self.updatemoddatetime(senseid=senseid) if self.debug == True: log.info("add langform: {}".format(forms.analang)) log.info("add tone: {}".format(fieldvalue)) From d70c2bd67c6bc8f99126a7d42e0a5d8eca050fb2 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 15:52:37 +0100 Subject: [PATCH 115/310] make sure text is always string --- lift.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 208da70d..3dd52871 100644 --- a/lift.py +++ b/lift.py @@ -1189,9 +1189,11 @@ def makeformnode(self,lang,text=None,gimmetext=False): n=Node(self,'form',attrib={'lang':lang}) nn=Node(n,'text') if text is not None: - nn.text=text + nn.text=str(text) if gimmetext: return nn + def maketraitnode(self,type,value,gimmenode=False): + n=Node(self,'trait',attrib={'name':type, 'value':str(value)}) def __init__(self, parent, tag, attrib={}, **kwargs): super(Node, self).__init__(tag, attrib, **kwargs) parent.append(self) From 245d59a2c4f53263d3e074e9a93491d0252a7443 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 15:52:59 +0100 Subject: [PATCH 116/310] maketraitnode fn --- lift.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lift.py b/lift.py index 3dd52871..3d774283 100644 --- a/lift.py +++ b/lift.py @@ -1194,6 +1194,8 @@ def makeformnode(self,lang,text=None,gimmetext=False): return nn def maketraitnode(self,type,value,gimmenode=False): n=Node(self,'trait',attrib={'name':type, 'value':str(value)}) + if gimmenode: + return n def __init__(self, parent, tag, attrib={}, **kwargs): super(Node, self).__init__(tag, attrib, **kwargs) parent.append(self) From 7995d7da8ac7beaa7580ec6ce73d9961a6e059f9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 15:53:43 +0100 Subject: [PATCH 117/310] update addpronunciationfields --- lift.py | 54 ++++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/lift.py b/lift.py index 3d774283..b5cf94ba 100644 --- a/lift.py +++ b/lift.py @@ -516,41 +516,35 @@ def addmodcitationfields(self,entry,langform,lang): if t is None: t=ET.SubElement(form,'text') t.text=langform - def addpronunciationfields(self,guid,senseid,analang, - glosslang,glosslang2, - lang,forms, - # langform,glossform,gloss2form, - fieldtype, - location,fieldvalue,ps=None,showurl=False): + def addpronunciationfields(self,**kwargs): """This fuction will add an XML node to the lift tree, like a new pronunciation field.""" """The program should know before calling this, that there isn't already the relevant node.""" - # urlnattr=attributesettings(attribute,guid,analang,glosslang,lang,ps,form, - # fieldtype,location) - urlnattr=self.geturlnattr('guid',guid=guid) #just give me the entry. - url=urlnattr['url'] - if showurl==True: - log.info(url) - node=self.nodes.find(url) #this should always find just one node - # nodes=self.nodes.findall(url) #this is a list - p=ET.SubElement(node, 'pronunciation') - form=ET.SubElement(p,'form',attrib={'lang':analang}) - t=ET.SubElement(form,'text') - t.text=langform - field=ET.SubElement(p,'field',attrib={'type':fieldtype}) - form=ET.SubElement(field,'form',attrib={'lang':lang}) - t2=ET.SubElement(form,'text') - t2.text=fieldvalue - fieldgloss=ET.SubElement(p,'field',attrib={'type':'gloss'}) - form=ET.SubElement(fieldgloss,'form',attrib={'lang':glosslang}) - t3=ET.SubElement(form,'text') - t3.text=glossform - trait=ET.SubElement(p,'trait',attrib={'name':'location', 'value':location}) - self.updatemoddatetime(guid=guid,senseid=senseid) - # self.write() + guid=kwargs.get('guid',None) + senseid=kwargs.get('senseid',None) + if guid is not None: + node=self.get('entry',guid=guid,showurl=True).get()[0] + elif senseid is not None: + node=self.get('entry',senseid=senseid,showurl=True).get()[0] + analang=kwargs.get('analang') + glosslang=kwargs.get('glosslang') + langform=kwargs.get('langform') + glossform=kwargs.get('glossform') + fieldtype=kwargs.get('fieldtype','tone') + fieldvalue=kwargs.get('fieldvalue') + location=kwargs.get('location') + p=Node(node, 'pronunciation') + p.makeformnode(lang=analang,text=langform) + p.makefieldnode(type=fieldtype,lang=glosslang,text=fieldvalue) + p.makefieldnode(type='gloss',lang=glosslang,text=glossform) + p.maketraitnode(type='location',value=location) + if senseid is not None: + self.updatemoddatetime(senseid=senseid) + elif guid is not None: + self.updatemoddatetime(guid=guid) + self.write() """End here:""" #build up, or down? - #node.append('pronunciation') """
dìve
From c62a020d85ae70cf076c612e0ee5a26db39af735 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 15:54:21 +0100 Subject: [PATCH 118/310] testing --- lift.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/lift.py b/lift.py index b5cf94ba..0a41670d 100644 --- a/lift.py +++ b/lift.py @@ -2469,10 +2469,30 @@ def test(): # log.info(len(entries)) # log.info(entries[0].get('guid')) # printurllog(lift) - lift.addtoneUF(#guid='09926cec-8be1-4f66-964e-4fdd8fa75fdc', - senseid='continue, resume_d174612b-b3c0-4073-bff0-58fd098252a9',#senseids[0], - group='4',analang='en') - # lift.write() + # lift.addtoneUF(#guid='09926cec-8be1-4f66-964e-4fdd8fa75fdc', + # #senseids[0], + # group='4',analang='en') + lift.addpronunciationfields(#self,guid, + # senseid, + analang='en', + senseid='continue, resume_d174612b-b3c0-4073-bff0-58fd098252a9', + glosslang='fr',glosslang2=None, + lang='de',#forms, + langform="TestForm", + glossform="testgloss",#gloss2form, + fieldtype='tone', + location='Plural', + fieldvalue=45, + ps=None,showurl=False) + # lift.write() + # analang=kwargs.get('analang') + # glosslang=kwargs.get('glosslang') + # langform=kwargs.get('langform') + # glossform=kwargs.get('glossform') + # fieldtype=kwargs.get('fieldtype','tone') + # fieldvalue=kwargs.get('fieldvalue') + # location=kwargs.get('location') + quit() import timeit def timetest(): From cc55df1b0d1262a975c251f2fc02aa811629cc09 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 15:58:59 +0100 Subject: [PATCH 119/310] remove rmexfields --- lift.py | 33 --------------------------------- main.py | 8 ++++---- 2 files changed, 4 insertions(+), 37 deletions(-) diff --git a/lift.py b/lift.py index 0a41670d..aacabb40 100644 --- a/lift.py +++ b/lift.py @@ -559,39 +559,6 @@ def addpronunciationfields(self,**kwargs):
""" - def rmexfields(self,guid=None,senseid=None,analang=None, - glosslang=None,langform=None,glossform=None,fieldtype=None, - location=None,fieldvalue=None,ps=None,showurl=False): - #We need fieldvalue here to be able to remove 'NA'. - urlnattr=self.geturlnattr('senseid',senseid=senseid) #just give me the sense. - url=urlnattr['url'] - if showurl==True: - log.info(url) - node=self.nodes.find(url) #this should always find just one node - log.debug("removing LIFT fields location={},fieldtype={},fieldvalue={}" - "".format(location,fieldtype,fieldvalue)) - urlnattr2=self.geturlnattr('examplewfieldlocvaluefromsense', - location=location, - fieldtype=fieldtype,fieldvalue=fieldvalue - ) - url2=urlnattr2['url'] - if showurl==True: - log.info("url for examples: {} (n={}".format(url2,len(node.findall( - url2)))) - for example in node.findall(url2): - node.remove(example) - # """
1
""" - # """
Plural
""" - # for child in node: - # print (child.tag, child.attrib) - # for child in example: - # print ('child:',child.tag, child.attrib, child.text) - # for grandchild in child: - # print ('grandchild:',grandchild.tag, grandchild.attrib, grandchild.text) - # log.info("Continuing on to the next example node now:") - # log.info("Continuing again to the next example node now:") - self.updatemoddatetime(guid=guid,senseid=senseid) - # self.write() def updateexfieldvalue(self,guid=None,senseid=None,analang=None, glosslang=None,langform=None,glossform=None,fieldtype=None, location=None,fieldvalue=None,ps=None, diff --git a/main.py b/main.py index 63f365a1..a767bfd0 100755 --- a/main.py +++ b/main.py @@ -4710,10 +4710,10 @@ def tryNAgain(self): Label(self.runwindow.frame, text=text).grid(row=0,column=0) return for senseid in self.senseidstosort: #this is a ps-profile slice - self.db.rmexfields(senseid=senseid,fieldtype='tone', - location=self.name,fieldvalue='NA', - showurl=True - ) + self.db.addmodexamplefields(senseid=senseid,fieldtype='tone', + location=self.name,fieldvalue='', #just clear this + showurl=True + ) self.checkcheck() #redraw the table self.maybesort() #Because we want to go right into sorting... def getanotherskip(self,parent): From 945fc0e21a1195fcf3f267c7f14bda0c144a2017 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:01:19 +0100 Subject: [PATCH 120/310] remove redundant updateexfieldvalue --- lift.py | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/lift.py b/lift.py index aacabb40..5b97ae3e 100644 --- a/lift.py +++ b/lift.py @@ -559,30 +559,6 @@ def addpronunciationfields(self,**kwargs): """ - def updateexfieldvalue(self,guid=None,senseid=None,analang=None, - glosslang=None,langform=None,glossform=None,fieldtype=None, - location=None,fieldvalue=None,ps=None, - newfieldvalue=None,showurl=False): - """This updates the fieldvalue, based on current value. It assumes - there is a field already there; use addexamplefields if not""" - node=self.geturlnattr('exfieldvaluenode',senseid=senseid, - fieldtype=fieldtype, - location=location, - fieldvalue=fieldvalue - ) - # url=urlnattr['url'] - if showurl==True: - log.info(url) - # node=self.nodes.find(url) #this should always find just one node - # for value in node.findall(f"field[@type=location]/" - # f"form[text='{location}']" - # f"[@type='{fieldtype}']/" - # f"form[text='{fieldvalue}']/text"): - # # """
1
""" - # # """
Plural
""" - node.text=newfieldvalue #remove(example) - self.updatemoddatetime(guid=guid,senseid=senseid) - # self.write() def updatemoddatetime(self,guid=None,senseid=None): """This updates the fieldvalue, ignorant of current value.""" if senseid is not None: From ff2fe58974e3d5688ac1a8a2d051820e58b0f6a2 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:03:08 +0100 Subject: [PATCH 121/310] remove geturlnattr --- lift.py | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/lift.py b/lift.py index 5b97ae3e..0e4a77d8 100644 --- a/lift.py +++ b/lift.py @@ -81,30 +81,6 @@ def __init__(self, filename,nsyls=None): """Think through where this belongs; what classes/functions need it?""" self.morphtypes=self.getmorphtypes() log.info("Language initialization done.") - def geturlnattr(self, attribute, **kwargs): - if attribute == 'attributes': - return self.attribdict.keys() - if attribute not in self.attribdict: - log.info("Sorry, {} isn't defined yet. This is what's " - "available:".format(attribute)) - for line in list(self.attribdict.keys()): - try: - log.info(' '.join(line, '\t',self.attribdict[line]['cm'])) - except: - log.info('{}\tUNDOCUMENTED?!?!'.format(line)) - log.info("This is where that key was called; fix it, and try again:") - """I should also add/remove pronunciation or other systematic things here""" - url=self.attribdict[attribute]['url'] - for field in url[1]: - if field not in kwargs: - kwargs[field]=None - url=(url[0],kwargs) - url=buildurl(url) - log.log(2,'After buildurl: {}'.format(url)) - url=removenone(url) - log.log(2,'After removenone: {}'.format(url)) - log.log(1,'Ori: {}'.format(self.attribdict[attribute]['url'])) - return {'url':url,'attr':self.attribdict[attribute]['attr']} def retarget(self,urlobj,target,showurl=False): k=self.urlkey(urlobj.kwargs) urlobj.kwargs['retarget']=target From dc4b4c051deb90fdbbd6997afb46028e846b5b1f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:07:20 +0100 Subject: [PATCH 122/310] cleanup --- lift.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/lift.py b/lift.py index 0e4a77d8..b18bcb5d 100644 --- a/lift.py +++ b/lift.py @@ -259,9 +259,8 @@ def addmodexamplefields(self,**kwargs): senseid=senseid, fieldtype=fieldtype,location=location, ).get('node') - # Set values for all duplicates, which should be removed later anyway. - # I.e., don't leave inconsisted data in the database. - tonevalue=kwargs.get('fieldvalue') #don't test for this yet + # Set values for any duplicates, too. Don't leave inconsisted data. + tonevalue=kwargs.get('fieldvalue') #don't test for this above if len(exfieldvalue) > 0: for e in exfieldvalue: e.text=tonevalue @@ -272,8 +271,6 @@ def addmodexamplefields(self,**kwargs): log.info("Sorry, this didn't return a node: {}".format(senseid)) return analang=kwargs.get('analang') - # glosslang=kwargs.get('glosslang') - # glosslang2=kwargs.get('glosslang2',None) db=kwargs.get('db') #This an object with values forms=db.forms glosses=db.glosses @@ -290,12 +287,6 @@ def addmodexamplefields(self,**kwargs): p.makefieldnode('location',glosslang,text=location) p.makefieldnode('tone',glosslang,text=tonevalue) self.updatemoddatetime(senseid=senseid) - if self.debug == True: - log.info("add langform: {}".format(forms.analang)) - log.info("add tone: {}".format(fieldvalue)) - log.info("add gloss: {}".format(forms.glosslang)) - if glosslang2 != None: - log.info("add gloss2: {}".format(forms.glosslang2)) def forminnode(self,node,value): # Returns True if `value` is in *any* text node child of any form child # of node: [node/'form'/'text' = value] From 8ecaed91492eeeee18c532dc980bd1333e4788be Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:09:42 +0100 Subject: [PATCH 123/310] doc --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index b18bcb5d..636a51b4 100644 --- a/lift.py +++ b/lift.py @@ -288,8 +288,8 @@ def addmodexamplefields(self,**kwargs): p.makefieldnode('tone',glosslang,text=tonevalue) self.updatemoddatetime(senseid=senseid) def forminnode(self,node,value): - # Returns True if `value` is in *any* text node child of any form child - # of node: [node/'form'/'text' = value] + """Returns True if `value` is in *any* text node child of any form child + of node: [node/'form'/'text' = value] Is this needed?""" for f in node.findall('form'): for t in f.findall('text'): if t.text == value: From 09e188961176441753d7882e6995877c21489444 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:11:48 +0100 Subject: [PATCH 124/310] doc --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 636a51b4..dd355da1 100644 --- a/lift.py +++ b/lift.py @@ -296,6 +296,7 @@ def forminnode(self,node,value): return True return False def convertalltodecomposed(self): + """Do we want/need this? Not using anywhere...""" for form in self.nodes.findall('.//form'): if form.get('lang') in self.analangs: for t in form.findall('.//text'): From e67cd6ca4edd265f21486dc9ec852d4efa85bc8f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:17:32 +0100 Subject: [PATCH 125/310] removed old same as new fns --- lift.py | 103 -------------------------------------------------------- 1 file changed, 103 deletions(-) diff --git a/lift.py b/lift.py index dd355da1..02dc86fa 100644 --- a/lift.py +++ b/lift.py @@ -301,109 +301,6 @@ def convertalltodecomposed(self): if form.get('lang') in self.analangs: for t in form.findall('.//text'): t.text=rx.makeprecomposed(t.text) - def exampleisnotsameasnew(self, **kwargs): - # guid,senseid,analang, glosslang, glosslang2, forms, fieldtype, - # location,fieldvalue,example,ps=None, - # """This checks all the above information, to see if we're dealing with - # the same example or not. Stop and return nothing at first node that - # doesn't match (from form, translation and location). If they all match, - # then return the tone value node to change.""" - tonevalue='' # set now, will change later, or not... - log.info("Looking for bits that don't match") - showurl=kwargs.get('showurl',False) - db=kwargs.get('db') - log.info("kwargs: {}".format(kwargs)) - log.info("db: {}; forms: {}".format(db,db.forms)) - analang=db.analangs[0] - location=db.location - forms=db.forms - glosses=db.glosses - glosslangs=db.glosslangs - glosslang=kwargs.get('glosslang') - glosslang2=kwargs.get('glosslang2',None) - try: - example=kwargs.get('example') - except: - log.info("Hey! You gave me an empty example?!") - return - for node in example: - try: - log.info('Node: {} ; {}'.format(node.tag, - node.find('.//text').text)) - except: - log.info('Node: {} ; Likely no text node!'.format(node.tag)) - if (node.tag == 'form'): - if ((node.get('lang') == analang) - and (node.find('text').text != forms[analang])): - log.info('{} == {}; {} != {}'.format(node.get('lang'), - analang, node.find('text').text, forms[analang])) - return - elif ((node.tag == 'translation') and - (node.get('type') == 'Frame translation')): - for form in node.findall('form'): - l=form.get('lang') - if l is None: - log.info("translation lang empty; can't test it") - continue - glform=db.glosses[l] #getattr(glosses,l,None) - if (l in glosslangs and form.find('text').text != glform): - log.info('{} translation "{}" != "{}"'.format(l, - node.find('form/text').text, glform)) - return - elif (node.tag == 'field'): - if (node.get('type') == 'location'): - thislocation=node.find('form/text').text - if thislocation != location: #not node.find('form/text').text - log.info('location {} not {}'.format(thislocation,location)) - return - if (node.get('type') == 'tone'): - for form in node: - l=form.get('lang') - if l in glosslangs: - """This is set once per example, since this - function runs on an example node""" - tonevalue=form.find('text') - log.debug('tone value found: {}'.format( - tonevalue.text)) - else: - log.info("Not the same lang for tone form: {}" - "".format(l)) - return - else: - log.debug("Not sure what kind of node I'm dealing with! ({})" - "".format(node.tag)) - return tonevalue - def exampleissameasnew(self, **kwargs): - # ,guid,senseid,analang, glosslang,glosslang2,forms, fieldtype, - # location,fieldvalue,node,ps=None - """This looks for any example in the given sense node, with the same - form, gloss, and location values""" - # showurl=kwargs.get('showurl',False) - node=kwargs.get('node') - # analang=kwargs.get('analang') - # glosslang=kwargs.get('glosslang') - # location=kwargs.get('location') - db=kwargs.get('db') - # glosslang2=kwargs.get('glosslang2',None) - # try: - # example=kwargs.get('example') - log.info('Looking for an example node matching these form and gloss ' - 'elements: {}\n(from these: {})'.format(db.forms,db.__dict__)) - examples=node.findall('example') - for example in examples: - log.info(_("Looking at example {} ({} of {})").format(example, - examples.index(example)+1, len(examples))) - valuenode=self.exampleisnotsameasnew(**kwargs, example=example) - if valuenode is None: - log.debug('=> This is not the example we are looking ' - 'for: {}'.format(valuenode)) - continue - log.info(_("Found it? {}".format(type(valuenode)))) - # log.info(_("Found it? {}: {}".format(type(valuenode),valuenode.text))) - if isinstance(valuenode,ET.Element): #None: #i.e., they *are* the same node - log.info(_("Found it! {}: {}".format(type(valuenode), - valuenode.text))) - return valuenode #if you find the example, we're done looking def findduplicateforms(self): """This removes duplicate form nodes in lx or lc nodes, not much point. """ From a224ee13abb3863742df40275308eb504688eb6e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:17:44 +0100 Subject: [PATCH 126/310] cleanup --- lift.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lift.py b/lift.py index 02dc86fa..0324dfa9 100644 --- a/lift.py +++ b/lift.py @@ -316,7 +316,6 @@ def findduplicateforms(self): dup=True if not dup: log.info("No duplicate form fields were found in the lexicon.") - # self.write() Not doing any changes, anyway... def findduplicateexamples(self): dup=False senses=self.nodes.findall('entry/sense') @@ -332,7 +331,6 @@ def findduplicateexamples(self): if not dup: log.info("No duplicate examples (same sense and location) were " "found in the lexicon.") - # self.write() Not yet, anyway def addtoneUF(self,senseid,group,analang,guid=None,showurl=False): node=self.get('sense',senseid=senseid).get() #give the sense. if node == []: From 156f6b58188053717eb902a387fe1e18e5927a69 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:26:36 +0100 Subject: [PATCH 127/310] cleanup addmodcitationfields --- lift.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lift.py b/lift.py index 0324dfa9..fe7dcce0 100644 --- a/lift.py +++ b/lift.py @@ -371,14 +371,8 @@ def addmediafields(self,node, url,lang, showurl=False):#lang=Check.audiolang def addmodcitationfields(self,entry,langform,lang): citation=entry.find('citation') if citation is None: - citation=ET.SubElement(entry, 'citation') - form=citation.find("form[@lang='{lang}']".format(lang=lang)) - if form is None: - form=ET.SubElement(citation,'form',attrib={'lang':lang}) - t=form.find('text') - if t is None: - t=ET.SubElement(form,'text') - t.text=langform + citation=Node(entry, 'citation') + citation.makeformnode(lang=lang,text=langform) def addpronunciationfields(self,**kwargs): """This fuction will add an XML node to the lift tree, like a new pronunciation field.""" From 5d366c536f38f4c232ca0c57dcadb48deb94758f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 16:26:43 +0100 Subject: [PATCH 128/310] doc --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index fe7dcce0..49672c24 100644 --- a/lift.py +++ b/lift.py @@ -348,7 +348,7 @@ def addtoneUF(self,senseid,group,analang,guid=None,showurl=False): """
toneinfo for sense.
""" - def addmediafields(self,node, url,lang, showurl=False):#lang=Check.audiolang + def addmediafields(self,node, url,lang, showurl=False): """This fuction will add an XML node to the lift tree, like a new example field.""" """The program should know before calling this, that there isn't From 43a155678d9f0d2b27f757e37bd739febb9daad7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:06:44 +0100 Subject: [PATCH 129/310] move glossordefn to glosslang --- lift.py | 21 +++++++++++---------- main.py | 16 ++++++++-------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/lift.py b/lift.py index 49672c24..a1162515 100644 --- a/lift.py +++ b/lift.py @@ -532,18 +532,19 @@ def glosslangs(self): d=self.get('definition/form').get('lang') self.glosslangs=[i[0] for i in collections.Counter(g+d).most_common()] log.info(_("gloss languages found: {}".format(self.glosslangs))) - def glossordefn(self,guid=None,senseid=None,lang='ALL',ps=None - ,showurl=False): - if lang == None: #This allows for a specified None='give me nothing' - return - elif lang == 'ALL': - lang=None #this is how the script gives all, irrespective of lang. - forms=self.get('gloss',guid=guid,senseid=senseid,glosslang=lang,ps=ps, - showurl=showurl) #,showurl=True + def glossordefn(self,**kwargs): + ps=kwargs.get('ps',None) + guid=kwargs.get('guid',None) + senseid=kwargs.get('senseid',None) + glosslang=kwargs.get('glosslang',None) + showurl=kwargs.get('showurl',False) + forms=self.get('gloss/text',guid=guid,senseid=senseid, + glosslang=glosslang,ps=ps, + showurl=showurl).get('text') if forms == []: formsd=self.get('definition',guid=guid,senseid=senseid, - glosslang=lang, - showurl=showurl) + glosslang=glosslang, + showurl=showurl).get('text') forms=list() for form in formsd: forms.append(rx.glossifydefn(form)) diff --git a/main.py b/main.py index a767bfd0..ff079bbb 100755 --- a/main.py +++ b/main.py @@ -2246,8 +2246,8 @@ def getframeddata(self,source,noframe=False,notonegroup=False,truncdefn=False): ps=self.ps) for lang in [self.glosslang,self.glosslang2]: if lang is not None: - glosses[lang]=self.db.glossordefn(senseid=senseid,lang=lang, - ps=self.ps) + glosses[lang]=self.db.glossordefn(senseid=senseid, + glosslang=lang,ps=self.ps) #If frame is not defined (in self.name) this will output ALL values #for this sense! tonegroups=self.db.get('exfieldvalue', senseid=senseid, @@ -2322,10 +2322,10 @@ def getframedentry(self,guid): form=firstoflist(self.db.citationorlexeme(guid,lang=self.analang, ps=self.ps)) glosses[self.glosslang]=firstoflist(self.db.glossordefn(guid, - lang=self.glosslang, ps=self.ps)) + glosslang=self.glosslang, ps=self.ps)) if self.glosslang2 is not None: glosses[self.glosslang2]=firstoflist(self.db.glossordefn(guid, - lang=self.glosslang2,ps=self.ps)) + glosslang=self.glosslang2,ps=self.ps)) frame=self.toneframes[self.ps][self.name] if self.debug ==True: print(forms,glosses,frame) @@ -4879,11 +4879,11 @@ def unsort(): def printentryinfo(self,guid): outputs=[ nn(self.db.citationorlexeme(guid=guid)), - nn(self.db.glossordefn(guid=guid,lang=self.glosslang)) + nn(self.db.glossordefn(guid=guid,glosslang=self.glosslang)) ] if self.glosslang2 is not None: #only give this if the user wants it. outputs.append(nn(self.db.glossordefn(guid=guid, - lang=self.glosslang2))) + glosslang=self.glosslang2))) outputs.append(nn(self.db.get('pronunciationfieldvalue', fieldtype='tone', location=self.subcheck,guid=guid))) @@ -5034,13 +5034,13 @@ def showentryformstorecordpage(self): lang=self.analang)) sense['gloss']=firstoflist(self.db.glossordefn( guid=sense['guid'], - lang=self.glosslang + glosslang=self.glosslang ),othersOK=True) if ((hasattr(self,'glosslang2')) and (self.glosslang2 is not None)): sense['gloss2']=firstoflist(self.db.glossordefn( guid=sense['guid'], - lang=self.glosslang2 + glosslang=self.glosslang2 ),othersOK=True) if ((sense['gloss'] is None) and (('gloss2' in sense) and (sense['gloss2'] is None))): From 7acb6af8ebea23161aff5905b654df1be277bdb9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:07:16 +0100 Subject: [PATCH 130/310] clean --- lift.py | 116 ++++++-------------------------------------------------- 1 file changed, 12 insertions(+), 104 deletions(-) diff --git a/lift.py b/lift.py index a1162515..ab6917a6 100644 --- a/lift.py +++ b/lift.py @@ -549,32 +549,6 @@ def glossordefn(self,**kwargs): for form in formsd: forms.append(rx.glossifydefn(form)) return forms - # def citationorlexeme(self,guid=None,senseid=None,lang=None,ps=None - # ,showurl=False): - # """I think this was a nice idea, but unnecessary; ability to use guid - # or senseid is more important.""" - # # if guid is None: - # # try: - # # for guid in self.guidsvalidwps: - # # return self.citationorlexeme(guid=guid,senseid=senseid, - # # lang=lang,ps=ps, - # # showurl=showurl) - # # except: - # # for guid in self.guids: - # # return self.citationorlexeme(guid=guid,senseid=senseid, - # # lang=lang,ps=ps, - # # showurl=showurl) - # # else: - # forms=self.get('citation',guid=guid,senseid=senseid,analang=lang, - # showurl=showurl, - # ps=ps - # ) #,showurl=True - # if forms == []: #for the whole db this will not work if even one gloss is filled out - # forms=self.get('lexeme',guid=guid,senseid=senseid,analang=lang, - # showurl=showurl, - # ps=ps - # ) - # return forms def fields(self,guid=None,lang=None): #get all the field types in a given entry f=list(dict.fromkeys(self.get('field').get('type'))) return f @@ -2162,34 +2136,6 @@ def printurllog(lift): glosslang='en' pss=["Verb","Noun"] analang='bfj' - # b=LiftURL(bob='ḿe', - # # guid=guid, - # # senseid=senseid, - # # location=location, - # # glosslang=glosslang, - # # ps=ps, - # # base='sense', - # target="sense", - # # tonevalue=3, - # ) - # get entries: lift.get("entry") - # lift.get("entry",what='guid') - # get senses: lift.get("sense") - # lift.get("sense",what='id') - # get *all* pss: lift.get("ps",what='value') - # Never ask for just the form! give the parent, to get a particular form: - # lift.get("lexeme/form",what='text') - # lift.get("example/form",what='text') - # lift.get("citation/form",what='text') - # just 1 of each pss: dict.fromkeys(lift.get("ps",what='value')) - # get tone value: lift.get("text", location=location, path=['tonefield'], - # what='text') - # for ps in dict.fromkeys(lift.get("ps",what='value')): - # log.info(ps) - # for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"],what='text')): - # log.info(tonevalue) - # log.info('\n'.join([str(x) for x in lift.urls.items()])) - # exit() def test(): for fieldvalue in [2,2]: for location in locations: @@ -2231,60 +2177,19 @@ def test(): # tonevalue=fieldvalue, # what='node') return - # log.info(lift.get("example/form",what='text',ps=ps,#"sense", #target - # # tonevalue=tonevalue, - # # guid=guid,# - # path=['lexeme','tonefield'], senseid=senseid, - # # senseid=senseid, - # # showurl=True - # )) - # log.info(lift.get("citation/form",what='text',ps=ps,#"sense", #target - # # tonevalue=tonevalue, - # # guid=guid,# - # path=['lexeme','tonefield'], senseid=senseid, - # # senseid=senseid, - # # showurl=True - # )) - # log.info(lift.get("sense", #target - # # guid=guid, - # senseid=senseid, - # # showurl=True - # )) - # log.info(lift.get("text", #target - # ps=ps,# guid=guid, - # senseid=senseid, - # location=location, - # path=['tonefield'], - # what='text' - # # showurl=True - # )) - # path=['pronunciation'],# senseid=senseid, - # guid=guid, - # glosslang=glosslang, - # ps=ps, - # base='sense', - # tonevalue=3, - # ) - # test() - # entries=lift.get("entry").get() - # log.info(len(entries)) - # log.info(entries[0].get('guid')) - # printurllog(lift) - # lift.addtoneUF(#guid='09926cec-8be1-4f66-964e-4fdd8fa75fdc', - # #senseids[0], - # group='4',analang='en') - lift.addpronunciationfields(#self,guid, + g=lift.glossordefn(#self,guid, # senseid, analang='en', senseid='continue, resume_d174612b-b3c0-4073-bff0-58fd098252a9', glosslang='fr',glosslang2=None, - lang='de',#forms, - langform="TestForm", - glossform="testgloss",#gloss2form, - fieldtype='tone', - location='Plural', - fieldvalue=45, - ps=None,showurl=False) + lang='swh',#forms, + # langform="TestForm", + # glossform="testgloss",#gloss2form, + # fieldtype='tone', + # location='Plural', + # fieldvalue=45, + # ps=None, + showurl=True) # lift.write() # analang=kwargs.get('analang') # glosslang=kwargs.get('glosslang') @@ -2294,6 +2199,9 @@ def test(): # fieldvalue=kwargs.get('fieldvalue') # location=kwargs.get('location') + print(g) + for i in g: + print(i) quit() import timeit def timetest(): From 655a6159290260fb28dd3ba21045586aa32ba8d4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:08:24 +0100 Subject: [PATCH 131/310] doc --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index ab6917a6..3ad14d82 100644 --- a/lift.py +++ b/lift.py @@ -549,10 +549,10 @@ def glossordefn(self,**kwargs): for form in formsd: forms.append(rx.glossifydefn(form)) return forms - def fields(self,guid=None,lang=None): #get all the field types in a given entry + def fields(self,guid=None,lang=None): # all field types in a given entry f=list(dict.fromkeys(self.get('field').get('type'))) return f - def getlocations(self,guid=None,lang=None): #get all the field types in a given entry + def getlocations(self,guid=None,lang=None): # all field locations in a given entry l=list(dict.fromkeys(self.get('example/locationfield').get('text'))) log.info('Locations found in Examples: {}'.format(l)) return l From ecce9be44f4af66177b23694592aaa755a883d85 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:18:34 +0100 Subject: [PATCH 132/310] remove getsenseidformstosearchbyps --- lift.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lift.py b/lift.py index 3ad14d82..03fa1331 100644 --- a/lift.py +++ b/lift.py @@ -681,15 +681,6 @@ def clist(self): #This variable gives lists, to iterate over. def slists(self): self.segmentsnotinregexes={} self.clist() - def getsenseidformstosearchbyps(self,ps,lang=None): - if lang is None: - lang=self.analang - self.senseidformstosearch[lang][ps]={} #Erases all previous data!! - for senseid in self.get('senseidbyps',lang=lang,ps=ps): - form=self.get('citation',senseid=senseid,lang=lang,ps=ps) - if len(form) == 0: #no items returned - form=self.get('lexeme',senseid=senseid,lang=lang,ps=ps) - self.senseidformstosearch[lang][ps][senseid]=form def getformstosearch(self): """This outputs a dictionary of form {analang: {guid:form}*}*, where form is citation if available, or else lexeme. This is to be flexible From c013a1b1440b9ea31af22c8e9790daaebb58a25d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:19:06 +0100 Subject: [PATCH 133/310] joined single and multiple citation and lexeme fns --- lift.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/lift.py b/lift.py index 03fa1331..e0b96491 100644 --- a/lift.py +++ b/lift.py @@ -697,17 +697,24 @@ def getformstosearch(self): self.formstosearch[lang][ps]=list(dict.fromkeys(forms)) log.debug("Found the following forms to search: {}".format( self.formstosearch)) - def citationforms(self): #outputs generator object with each form in LIFT file. - """This produces a dictionary, of forms for each language.""" - output={} + def citation(self,**kwargs): + """This produces a list; specify senseid and analang as you like.""" + output=self.get('citation/form/text',kwargs).get('text') + return output + def citationforms(self): + output={} # This produces a dictionary, of forms for each language for lang in self.analangs: - output[lang]=self.get('citation/form/text',analang=lang).get('text') + output[lang]=self.citation(analang=lang).get('text') log.info("Found the following citation forms: {}".format(output)) return output + def lexeme(self,**kwargs): + """This produces a list; specify senseid and analang as you like.""" + output[lang]=self.get('lexeme/form/text',kwargs).get('text') + return output def lexemes(self): - output={} + output={} # This produces a dictionary, of forms for each language. for lang in self.analangs: - output[lang]=self.get('lexeme/form/text',analang=lang).get('text') + output[lang]=self.lexeme(analang=lang).get('text') log.info("Found the following lexemes: {}".format(output)) return output def extrasegments(self): From 2425be5f0ef317890d82ee2f2ffc37a2128fbefd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:22:47 +0100 Subject: [PATCH 134/310] split pss and ps --- lift.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index e0b96491..4aeecea2 100644 --- a/lift.py +++ b/lift.py @@ -748,8 +748,10 @@ def extrasegments(self): "complex segments which should be counted as a single " "segment.") log.info("--those may not be covered by your regexes.") + def ps(self,**kwargs): #get POS values, limited as you like + return self.get('ps',kwargs).get('value')) def pss(self): #get all POS values in the LIFT file - p=list(dict.fromkeys(self.get('ps').get('value'))) + p=list(dict.fromkeys(self.ps().get('value'))) log.info("Found these ps values: {}".format(p)) return p def getmorphtypes(self): #get all morph-type values in the LIFT file From 43989a6661cf99640cec747dc0f094ab36d6b213 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:25:47 +0100 Subject: [PATCH 135/310] removed unused fn --- lift.py | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/lift.py b/lift.py index 4aeecea2..868ec711 100644 --- a/lift.py +++ b/lift.py @@ -760,54 +760,6 @@ def getmorphtypes(self): #get all morph-type values in the LIFT file log.info("Found these morph-type values: {}".format(m)) return m """CONTINUE HERE: Making things work for the new lift.get() paradigm.""" - def formsbyps(self,ps): #self is LIFT! #should be entriesbyps - """This function just pulls all entries of a particular - grammatical category""" - """This function, and others like it, should pull from the profiles - data variable, which should be redesigned so it can recompile - quickly for changes in form.""" - output=[] - winfoentries=[] - x=0 - y=0 - z=0 - zz=0 - if ps is None: - entries=self.nodes.findall(f"entry") - #gi1=self.nodes.findall(f".//grammatical-info") - #log.info(' '.join('Entries found:',len(entries)))#for gi in entry.find(f"grammatical-info"): - #log.info(' '.join('Ps found:',len(gi1)))#for gi in entry.find(f"grammatical-info"): - for entry in entries: - gi=entry.find(f".//grammatical-info") #.get('value') - #if gi is not None and len(gi)>1: - # log.info(gi) - # log.info(' '.join(x,y,z,zz)) - # exit() - # x+=1 - if gi is None: #entry.find(f".//grammatical-info") is None: - # y+=1 - output+=[entry] #add this item to a list, not it's elements - #elif gi is not None: #entry.find(f".//grammatical-info") is not None: - # z+=1 - # log.info(type(gi)) - # log.info(gi.get('value')) - # log.info(len(gi)) - # winfoentries+=[entry] - #else: - # zz+=1 - # log.info("Huh?") - else: - #log.info(ps) - # for self.db.get('') - for entry in self.nodes.findall(f"entry/sense/grammatical-info[@value='{ps}']/../.."): - #log.info('Skipping this for now...') - output+=[entry] #add this item to a list, not it's elements - #log.info(' '.join('Entries without ps:',len(output))) - #log.info(' '.join('Entries with ps:',len(winfoentries))) - #log.info(' '.join('Total entries found (Should be 2468):',len(output)+len(winfoentries))) - #log.info(' '.join('multiple:',x,'no ps:',y,'wps',z,'totalps:',y+z,'huh:',zz)) - #exit() - return output #list of entry nodes def guidformsbyregex(self,regex,ps=None,analang=None): #self is LIFT! # from multiprocessing.dummy import Pool as ThreadPool """This function takes in a ps and compiled regex, From c658a7f9b58105d29880a7f4123cc27332d80a68 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:27:38 +0100 Subject: [PATCH 136/310] removed unused fn --- lift.py | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/lift.py b/lift.py index 868ec711..a39fc6f8 100644 --- a/lift.py +++ b/lift.py @@ -760,44 +760,6 @@ def getmorphtypes(self): #get all morph-type values in the LIFT file log.info("Found these morph-type values: {}".format(m)) return m """CONTINUE HERE: Making things work for the new lift.get() paradigm.""" - def guidformsbyregex(self,regex,ps=None,analang=None): #self is LIFT! - # from multiprocessing.dummy import Pool as ThreadPool - """This function takes in a ps and compiled regex, - and outputs a dictionary of {guid:form} form.""" - if analang is None: - analang=self.analang - #log.info(regex) - output={} - def checkformsbyps(self,analang,ps): - for form in self.formstosearch[analang][ps]: - if regex.search(form): #re.search(regex,form): #,showurl=True - for guid in self.get('guidbylexeme',form=form,ps=ps): - output[guid]=form - return output - if ps == 'All': #When I'm looking through each ps, not ps=None (e.g., invalid). - for ps in self.pss+[None]: - output.update(checkformsbyps(self,analang,ps)) #adds dict entries - return output - else: - output.update(checkformsbyps(self,analang,ps)) - return output - for entry in entries: - def debug(): - log.info(len(entry)) - log.info(str(entry.tag)) - log.info(str(entry.get('guid'))) - log.info(entry.attrib) #('value')) - log.info(str(entry.find('lexical-unit'))) - log.info(str(entry.find('citation'))) - log.info(str(entry.find('form'))) - log.info(self.get('lexeme',guid=entry.get('guid'))) - log.info(self.get('lexeme',guid=entry.get('guid'))[0]) - exit() - #debug() - """FIX THIS!!!""" - form=self.get('lexeme',guid=entry.get('guid')) #self.formbyid(entry.get('guid'))[0] #just looking for one at this point. - log.info("Apparently there are no/multiple forms for this entry...") - return output def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! """This function takes in a ps and compiled regex, and outputs a dictionary of {senseid:form} form.""" From 64c43b185fd6322f7b33b9ec2191d626f53c0555 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:58:29 +0100 Subject: [PATCH 137/310] reworked senseidformsbyregex --- lift.py | 38 +++++--------------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/lift.py b/lift.py index a39fc6f8..1d638813 100644 --- a/lift.py +++ b/lift.py @@ -762,39 +762,11 @@ def getmorphtypes(self): #get all morph-type values in the LIFT file """CONTINUE HERE: Making things work for the new lift.get() paradigm.""" def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! """This function takes in a ps and compiled regex, - and outputs a dictionary of {senseid:form} form.""" - # if analang is None: - # analang=self.analang - output={} - def checkformsbyps(self,analang,ps): - for form in self.formstosearch[analang][ps]: - if regex.search(form): #re.search(regex,form): #,showurl=True - for senseid in self.get('senseidbylexeme',form=form,ps=ps): - output[senseid]=form - return output - if ps == 'All': #When I'm looking through each ps, not ps=None (e.g., invalid). - for ps in self.pss+[None]: - output.update(checkformsbyps(self,analang,ps)) #adds dict entries - return output - else: - output.update(checkformsbyps(self,analang,ps)) - return output - for entry in entries: - def debug(): - log.info(len(entry)) - log.info(str(entry.tag)) - log.info(str(entry.get('guid'))) - log.info(entry.attrib) #('value')) - log.info(str(entry.find('lexical-unit'))) - log.info(str(entry.find('citation'))) - log.info(str(entry.find('form'))) - log.info(self.get('lexeme',guid=entry.get('guid'))) - log.info(self.get('lexeme',guid=entry.get('guid'))[0]) - exit() - #debug() - """FIX THIS!!!""" - form=self.get('lexeme',guid=entry.get('guid')) #self.formbyid(entry.get('guid'))[0] #just looking for one at this point. - log.info("Apparently there are no/multiple forms for this entry...") + and outputs a list/dictionary of senseid/{senseid:form} form.""" + output=[] #This is just a list of senseids now: (Do we need the dict?) + for form in self.formstosearch[analang][ps]: + if regex.search(form): + output+=self.formstosearch[analang][ps][form] return output def formbyid(self,guid,lang=None): #This is the language version, use without entry. """bring this logic into get()""" From abf4727bb641630ae6b63dd0bec4b99fbb7e3e1e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 17:59:16 +0100 Subject: [PATCH 138/310] rework forms to search to keep senseids for later --- lift.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index 1d638813..dd1b9627 100644 --- a/lift.py +++ b/lift.py @@ -690,11 +690,15 @@ def getformstosearch(self): for lang in self.analangs: self.formstosearch[lang]={} #This will erase all previous data!! for ps in self.pss+[None]: #I need to break this up. - forms=self.get('citation/form/text',analang=lang,ps=ps - ).get('text') - forms+=self.get('lexeme/form/text',analang=lang,ps=ps - ).get('text') - self.formstosearch[lang][ps]=list(dict.fromkeys(forms)) + self.formstosearch[lang][ps]={} + for s in self.get('sense',analang=lang,ps=ps).get('senseid'): + f=self.citation(senseid=s) + if f == []: + f=self.lexeme(senseid=s) + if f in self.formstosearch[lang][ps]: + self.formstosearch[lang][ps][f].append(s) + else: + self.formstosearch[lang][ps][f]=[s] log.debug("Found the following forms to search: {}".format( self.formstosearch)) def citation(self,**kwargs): From 3637254d48d419e930a29945475af8b45b7b9ec7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 18:01:23 +0100 Subject: [PATCH 139/310] removed unused (and unuseful!) fns --- lift.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/lift.py b/lift.py index dd1b9627..72ed0a50 100644 --- a/lift.py +++ b/lift.py @@ -772,21 +772,6 @@ def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! if regex.search(form): output+=self.formstosearch[analang][ps][form] return output - def formbyid(self,guid,lang=None): #This is the language version, use without entry. - """bring this logic into get()""" - form=self.get('citation',guid=guid,lang=lang) #self.nodes.findall(f"entry[@guid='{guid}']/citation/form[@lang='{self.xyz}']/text") - if form == []: #default to lexical form for missing citation forms. - form=self.get('lexeme',guid=guid,lang=lang) #form=self.nodes.findall(f"entry[@guid='{guid}']/lexical-unit/form[@lang='{self.xyz}']/text") - if form == []: - return None - #log.info(form) - return form #[0].text #print the text of the node above - def psbyid(self,guid): #This is the language version, use without entry. - #return self.nodes.find(f"entry[@guid='{guid}']/sense/grammatical-info").get('value') - #return ps.attrib.get('value') - ps=self.nodes.find(f"entry[@guid='{guid}']/sense/grammatical-info") - if ps is not None: - return ps.attrib.get('value') def formsnids(self): #outputs [guid, form] tuples for each entry in the lexicon. Is this more efficient than using idsbyformregex? for entry in self.nodes.findall(f"entry"): for form in entry.findall(f"./citation/form[@lang='{self.xyz}']/text"): #Not lexeme-unit..… From 4fdd04b67912e94fd33f62390b268ae215eafa5c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 22 Oct 2021 18:04:07 +0100 Subject: [PATCH 140/310] removed excess fns --- lift.py | 51 --------------------------------------------------- 1 file changed, 51 deletions(-) diff --git a/lift.py b/lift.py index 72ed0a50..2bb90912 100644 --- a/lift.py +++ b/lift.py @@ -772,57 +772,6 @@ def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! if regex.search(form): output+=self.formstosearch[analang][ps][form] return output - def formsnids(self): #outputs [guid, form] tuples for each entry in the lexicon. Is this more efficient than using idsbyformregex? - for entry in self.nodes.findall(f"entry"): - for form in entry.findall(f"./citation/form[@lang='{self.xyz}']/text"): #Not lexeme-unit..… - yield entry.get('guid'), form.text #print the text of the node above - #figure out how to filter this by part of speech - def idsbylexemeregex(self,regex): #outputs [guid, ps, form] tuples for each entry in the LIFT file lexeme which matches the regex. - for ps in pss(): #for each POS - for entry in self.nodes.findall(f"entry/sense/grammatical-info[@value='{ps}']/../.."): #for each entry - for form in entry.findall(f"./lexical-unit/form[@lang='{self.xyz}']/text"): #for each CITATION form this needs to see lexeme forms, too..… - #for form in entry.findall(f"./citation/form[@lang='{xyz}']/text"): #for each CITATION form this needs to see lexeme forms, too..… - # if re.search(regex,form.text): #check if the form matches the regex - if regex.search(form.text): #check if the form matches the regex - yield entry.get('guid'), ps, form.text #print the tuple (may want to augment this some day to include other things) - def idsbylexemeregexnps(self,ps,regex): #outputs [guid, ps, form] tuples for each entry in the LIFT file lexeme which matches the regex and ps. - """This puts out a dictionary with guid keys and (ps,form) tuples - for values. I need to rework this. I think not use it anymore...""" - output={} - for form in self.formstosearch[self.analang][ps]: - # form=self.formstosearch[self.analang][ps][guid] - # log.info(form) - if regex.search(form): - # if len(form) == 1 and regex.search(form): - output[guid]=form - return output - #exit() - - for entry in self.nodes.findall(f"entry/sense/grammatical-info[@value='{ps}']/../../lexical-unit/form[@lang='{self.analang}']/../.."): - form=entry.find(f"lexical-unit/form[@lang='{self.analang}']/text") - if regex.search(form.text): #re.search(regex,form.text): - output[entry.get('guid')]=(ps, form.text) - return output - def wordcountbyps(self,ps): - count=0 - if ps is None: - #entries= - #gi1=self.nodes.findall(f".//grammatical-info") - #log.info(' '.join('Entries found:',len(entries)))#for gi in entry.find(f"grammatical-info"): - #log.info(' '.join('Ps found:',len(gi1)))#for gi in entry.find(f"grammatical-info"): - for entry in self.nodes.findall(f"entry"): - #gi= #.get('value') - if entry.find(f".//grammatical-info") is None: #entry.find(f".//grammatical-info") is None: - # y+=1 - count+=1 - else: - for entry in self.nodes.findall(f"entry/sense/grammatical-info[@value='{ps}']/../.."): #for each entry - count+=1 - return count - def formsregex(self,regex): #UNUSED? outputs [guid, form] tuples where the form matches a regex. This might make sense for a tuple with lexeme-unit, citation, and plural. - for entry in formsnids(): - if regex.search(entry[1]): #check regex against the form part of the tuple output by formsnids - yield entry[0] #print id part of the tuple output by formsnids class Node(ET.Element): def makefieldnode(self,type,lang,text=None,gimmetext=False): n=Node(self,'field',attrib={'type':type}) From b4b15bc0eb4fadc7e8b88265d79b5a9ea38faa98 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 10:29:57 +0100 Subject: [PATCH 141/310] moved glossordefn --- lift.py | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lift.py b/lift.py index 2bb90912..45fad7bf 100644 --- a/lift.py +++ b/lift.py @@ -532,23 +532,6 @@ def glosslangs(self): d=self.get('definition/form').get('lang') self.glosslangs=[i[0] for i in collections.Counter(g+d).most_common()] log.info(_("gloss languages found: {}".format(self.glosslangs))) - def glossordefn(self,**kwargs): - ps=kwargs.get('ps',None) - guid=kwargs.get('guid',None) - senseid=kwargs.get('senseid',None) - glosslang=kwargs.get('glosslang',None) - showurl=kwargs.get('showurl',False) - forms=self.get('gloss/text',guid=guid,senseid=senseid, - glosslang=glosslang,ps=ps, - showurl=showurl).get('text') - if forms == []: - formsd=self.get('definition',guid=guid,senseid=senseid, - glosslang=glosslang, - showurl=showurl).get('text') - forms=list() - for form in formsd: - forms.append(rx.glossifydefn(form)) - return forms def fields(self,guid=None,lang=None): # all field types in a given entry f=list(dict.fromkeys(self.get('field').get('type'))) return f @@ -701,6 +684,23 @@ def getformstosearch(self): self.formstosearch[lang][ps][f]=[s] log.debug("Found the following forms to search: {}".format( self.formstosearch)) + def glossordefn(self,**kwargs): + ps=kwargs.get('ps',None) + guid=kwargs.get('guid',None) + senseid=kwargs.get('senseid',None) + glosslang=kwargs.get('glosslang',None) + showurl=kwargs.get('showurl',False) + forms=self.get('gloss/text',guid=guid,senseid=senseid, + glosslang=glosslang,ps=ps, + showurl=showurl).get('text') + if forms == []: + formsd=self.get('definition',guid=guid,senseid=senseid, + glosslang=glosslang, + showurl=showurl).get('text') + forms=list() + for form in formsd: + forms.append(rx.glossifydefn(form)) + return forms def citation(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" output=self.get('citation/form/text',kwargs).get('text') From f0e4a22cec2a8666b1f7b162b8cfe86f73575a27 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 10:30:07 +0100 Subject: [PATCH 142/310] standardized lexeme --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 45fad7bf..3b88c520 100644 --- a/lift.py +++ b/lift.py @@ -713,7 +713,7 @@ def citationforms(self): return output def lexeme(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" - output[lang]=self.get('lexeme/form/text',kwargs).get('text') + output=self.get('lexeme/form/text',kwargs).get('text') return output def lexemes(self): output={} # This produces a dictionary, of forms for each language. From 40383d5b096b7344a136106364ec4d063ad4669b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 10:30:39 +0100 Subject: [PATCH 143/310] updated lift fns --- main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index ff079bbb..969c9706 100755 --- a/main.py +++ b/main.py @@ -6315,11 +6315,11 @@ class FramedData(object): from the example. The info is formatted uniformly in either case.""" def parsesense(self,db,senseid,truncdefn=False): self.senseid=senseid - lexs=db.get('lexemenode',senseid=senseid) - cits=db.get('citationnode',senseid=senseid) + lexs=db.lexeme(senseid=senseid) + cits=db.citation(senseid=senseid) log.info("lex: {}, cit: {}".format(lexs,cits)) - defns=db.get('definitionnode',senseid=senseid) - glss=db.get('glossnode',senseid=senseid) + defns=db.definition(senseid=senseid) + glss=db.gloss(senseid=senseid) log.info("defns: {}, glss: {}".format(defns,glss)) for i in lexs+cits: # (later) citation nodes will overwrite lex nodes self.forms.getformfromnode(i) From 3051aec2bf94c4333058ddd03b4db01af09b5b88 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 10:52:22 +0100 Subject: [PATCH 144/310] clean up gloss and defn --- lift.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/lift.py b/lift.py index 3b88c520..7affeeff 100644 --- a/lift.py +++ b/lift.py @@ -684,22 +684,19 @@ def getformstosearch(self): self.formstosearch[lang][ps][f]=[s] log.debug("Found the following forms to search: {}".format( self.formstosearch)) + def gloss(self,**kwargs): + return self.get('gloss/text', kwargs).get('text') + def definition(self,**kwargs): + truncate=kwargs.pop('truncate',False) + forms=self.get('definition', kwargs).get('text') + if truncate: + forms=[rx.glossifydefn(f) for f in forms] + return forms def glossordefn(self,**kwargs): - ps=kwargs.get('ps',None) - guid=kwargs.get('guid',None) - senseid=kwargs.get('senseid',None) - glosslang=kwargs.get('glosslang',None) - showurl=kwargs.get('showurl',False) - forms=self.get('gloss/text',guid=guid,senseid=senseid, - glosslang=glosslang,ps=ps, - showurl=showurl).get('text') + forms=self.gloss(kwargs) if forms == []: - formsd=self.get('definition',guid=guid,senseid=senseid, - glosslang=glosslang, - showurl=showurl).get('text') - forms=list() - for form in formsd: - forms.append(rx.glossifydefn(form)) + kwargs['truncate']=True + forms=self.definition(kwargs) return forms def citation(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" From e309e6c176cfc9b880d75da83e7f528d6f7ae113 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 11:06:13 +0100 Subject: [PATCH 145/310] rename citationforms --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 7affeeff..455c525a 100644 --- a/lift.py +++ b/lift.py @@ -65,7 +65,7 @@ def __init__(self, filename,nsyls=None): self.getformstosearch() #sets: self.formstosearch[lang][ps] #no guids """This is very costly on boot time, so this one line is not used:""" # self.getguidformstosearch() #sets: self.guidformstosearch[lang][ps] - self.citationforms=self.citationforms() + self.citationforms=self.citations() self.lexemes=self.lexemes() self.locations=self.getlocations() self.defaults=[ #these are lift related defaults @@ -702,7 +702,7 @@ def citation(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" output=self.get('citation/form/text',kwargs).get('text') return output - def citationforms(self): + def citations(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.analangs: output[lang]=self.citation(analang=lang).get('text') From 09701b90975a8507984f58997b24357c189c88ae Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 11:06:27 +0100 Subject: [PATCH 146/310] update citation and lexeme --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 455c525a..23a6e925 100644 --- a/lift.py +++ b/lift.py @@ -705,17 +705,17 @@ def citation(self,**kwargs): def citations(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.analangs: - output[lang]=self.citation(analang=lang).get('text') + output[lang]=self.citation(analang=lang, kwargs).get('text') log.info("Found the following citation forms: {}".format(output)) return output def lexeme(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" output=self.get('lexeme/form/text',kwargs).get('text') return output - def lexemes(self): + def lexemes(self,**kwargs): output={} # This produces a dictionary, of forms for each language. for lang in self.analangs: - output[lang]=self.lexeme(analang=lang).get('text') + output[lang]=self.lexeme(analang=lang, kwargs).get('text') log.info("Found the following lexemes: {}".format(output)) return output def extrasegments(self): From d1e2235116ee1a533f6b1018791b791402293d69 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 11:06:46 +0100 Subject: [PATCH 147/310] update glosses and definitions --- lift.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lift.py b/lift.py index 23a6e925..fdd188bd 100644 --- a/lift.py +++ b/lift.py @@ -686,18 +686,36 @@ def getformstosearch(self): self.formstosearch)) def gloss(self,**kwargs): return self.get('gloss/text', kwargs).get('text') + def glosses(self,**kwargs): + output={} # This produces a dictionary, of forms for each language + for lang in self.glosslangs: + output[lang]=self.gloss(glosslang=lang, kwargs).get('text') + return output def definition(self,**kwargs): truncate=kwargs.pop('truncate',False) forms=self.get('definition', kwargs).get('text') if truncate: forms=[rx.glossifydefn(f) for f in forms] return forms + def definitions(self,**kwargs): + output={} # This produces a dictionary, of forms for each language + for lang in self.glosslangs: + output[lang]=self.definition(glosslang=lang, kwargs).get('text') + return output def glossordefn(self,**kwargs): forms=self.gloss(kwargs) if forms == []: kwargs['truncate']=True forms=self.definition(kwargs) return forms + def glossesordefns(self,**kwargs): + output={} # This produces a dictionary, of forms for each language + for lang in self.glosslangs: + output[lang]=self.gloss(kwargs) + if output[lang] == []: + kwargs['truncate']=True + forms=self.definition(kwargs) + return output def citation(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" output=self.get('citation/form/text',kwargs).get('text') From 098d463c481ad4242a8d1dd5277056998c71088d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:04:29 +0100 Subject: [PATCH 148/310] separate out framed data --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 969c9706..587edbe8 100755 --- a/main.py +++ b/main.py @@ -6303,7 +6303,7 @@ def frame(self,framedict,langs): #langs can/should be ordered """the frame only applies if there is a language value; I hope that's what we want...""" for l in [i for i in langs if i in framedict if i in self]: - self[l]=rx.framerx.sub(self[l],framedict[l]) + self.framed[l]=rx.framerx.sub(self[l],framedict[l]) def __init__(self): super(DictbyLang, self).__init__() class FramedData(object): From 3323d7a3c60ff6cd107da2dfcb010329fe078d29 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:04:51 +0100 Subject: [PATCH 149/310] parent dictionary of framed objects --- main.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/main.py b/main.py index 587edbe8..0971e884 100755 --- a/main.py +++ b/main.py @@ -6306,6 +6306,19 @@ def frame(self,framedict,langs): #langs can/should be ordered self.framed[l]=rx.framerx.sub(self[l],framedict[l]) def __init__(self): super(DictbyLang, self).__init__() +class FramedDataDict(dict): + def getframeddata(self, source, **kwargs): + if source not in self: + kwargs['db']=self.db + self[source]=FramedData(self,source,kwargs) + return self[source] + def __init__(self, check, **kwargs): + super(FramedDataDict, self).__init__() + self.frames=check.toneframes #[ps][name] + self.db=check.db + self.analangs=check.analangs + self.glosslangs=check.glosslangs + class FramedData(object): """This populates an object with attributes to format data for display, by senseid""" From 1b7ba5b212369faad6bbda8d4f5fe21ead9acab0 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:06:43 +0100 Subject: [PATCH 150/310] remove glosses, just use forms --- main.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 0971e884..c9f80691 100755 --- a/main.py +++ b/main.py @@ -6339,7 +6339,7 @@ def parsesense(self,db,senseid,truncdefn=False): for i in defns: #(later) gloss nodes will overwrite these defn nodes self.glosses.getformfromnode(i,truncate=truncdefn) #only trunc defns for i in glss: - self.glosses.getformfromnode(i) + self.forms[i]=glss[i] if not self.notonegroup and self.location is not None: self.tonegroups=self.db.get('exfieldvalue', senseid=senseid, fieldtype='tone', location=self.location) @@ -6355,7 +6355,7 @@ def parseexample(self,example): ((i.tag == 'gloss'))): for ii in i: if (ii.tag == 'form'): - self.glosses.getformfromnode(ii) + self.forms.getformfromnode(ii) #glosses elif ((i.tag == 'field') and (i.get('type') == 'tone') and not self.notonegroup): self.tonegroups=i.findall('form/text') #always be list of one @@ -6372,7 +6372,6 @@ def __init__(self, source, **kwargs): self.glosslangs=kwargs.pop('glosslangs') #to put data: self.forms=DictbyLang() - self.glosses=DictbyLang() #defaults to set upfront self.tonegroups=None self.tonegroup=None @@ -6427,9 +6426,9 @@ def __init__(self, source, **kwargs): self.formatted=' '.join(toformat) #put it all together # just for convenience: self.analang=self.forms[self.analangs[0]] - self.glosslang=self.glosses[self.glosslangs[0]] - if len(self.glosslangs) >1 and self.glosslangs[1] in self.glosses: - self.glosslang2=self.glosses[self.glosslangs[1]] + self.glosslang=self.forms[self.glosslangs[0]] + if len(self.glosslangs) >1 and self.glosslangs[1] in self.forms: + self.glosslang2=self.forms[self.glosslangs[1]] else: self.glosslang2=None class ExitFlag(object): From 5fa34687cb48ec1449878a2cd1963045809774f7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:07:17 +0100 Subject: [PATCH 151/310] preping for generalizing framed data with methods --- main.py | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/main.py b/main.py index c9f80691..22bbe70e 100755 --- a/main.py +++ b/main.py @@ -6359,17 +6359,19 @@ def parseexample(self,example): elif ((i.tag == 'field') and (i.get('type') == 'tone') and not self.notonegroup): self.tonegroups=i.findall('form/text') #always be list of one - def __init__(self, source, **kwargs): + def __init__(self, parent, source, **kwargs): super(FramedData, self).__init__() + self.frames=parent.frames + self.db=parent.db #kwargs.pop('db',None) #not needed for examples + self.analangs=parent.analangs + self.glosslangs=parent.glosslangs + #Generalize these, and manage with methods: noframe=kwargs.pop('noframe',False) self.notonegroup=kwargs.pop('notonegroup',False) truncdefn=kwargs.pop('truncdefn',False) - self.db=kwargs.pop('db',None) #not needed for examples self.location=kwargs.pop('location',None) #not needed for noframe self.frame=kwargs.pop('frame',None) #not needed for noframe #These really must be there, and ordered with first first - self.analangs=kwargs.pop('analangs') - self.glosslangs=kwargs.pop('glosslangs') #to put data: self.forms=DictbyLang() #defaults to set upfront @@ -6414,16 +6416,6 @@ def __init__(self, source, **kwargs): int(tonegroup) except: self.tonegroup=tonegroup #only for named groups - if not noframe: #Forms and glosses have to be strings, or the rx fails - self.forms.frame(self.frame,self.analangs) - self.glosses.frame(self.frame,self.glosslangs) - if self.tonegroup is None: #i.e., no named group was found above - toformat=DataList() - else: - toformat=DataList(self.tonegroup) - toformat.appendformsbylang(self.forms,self.analangs,quote=False) - toformat.appendformsbylang(self.glosses,self.glosslangs,quote=True) - self.formatted=' '.join(toformat) #put it all together # just for convenience: self.analang=self.forms[self.analangs[0]] self.glosslang=self.forms[self.glosslangs[0]] From 28ccc75eca7165f4d501b9ae25b416560b0ea3a1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:07:43 +0100 Subject: [PATCH 152/310] update tonegroups call --- main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 22bbe70e..ef040423 100755 --- a/main.py +++ b/main.py @@ -6341,8 +6341,11 @@ def parsesense(self,db,senseid,truncdefn=False): for i in glss: self.forms[i]=glss[i] if not self.notonegroup and self.location is not None: - self.tonegroups=self.db.get('exfieldvalue', senseid=senseid, - fieldtype='tone', location=self.location) + self.tonegroups=self.db.get('example/field/form/text', + senseid=senseid, + # fieldtype='tone', + path=['tonefield'] + location=self.location).get('text') else: log.error("Location isn't set, but you asked for a tonegoup...") def parseexample(self,example): From cf16cbaa1ba7b8d861d144eff2779b26e1d4f190 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:07:53 +0100 Subject: [PATCH 153/310] update parsesense --- main.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/main.py b/main.py index ef040423..29b8f779 100755 --- a/main.py +++ b/main.py @@ -6328,16 +6328,13 @@ class FramedData(object): from the example. The info is formatted uniformly in either case.""" def parsesense(self,db,senseid,truncdefn=False): self.senseid=senseid - lexs=db.lexeme(senseid=senseid) - cits=db.citation(senseid=senseid) - log.info("lex: {}, cit: {}".format(lexs,cits)) - defns=db.definition(senseid=senseid) - glss=db.gloss(senseid=senseid) - log.info("defns: {}, glss: {}".format(defns,glss)) - for i in lexs+cits: # (later) citation nodes will overwrite lex nodes - self.forms.getformfromnode(i) - for i in defns: #(later) gloss nodes will overwrite these defn nodes - self.glosses.getformfromnode(i,truncate=truncdefn) #only trunc defns + lexs=db.lexemes(senseid=senseid) + cits=db.citations(senseid=senseid) + glss=db.glossesordefns(senseid=senseid) + for i in lexs: # (later) citation nodes will overwrite lex nodes + self.forms[i]=lexs[i] + for i in cits: + self.forms[i]=cits[i] for i in glss: self.forms[i]=glss[i] if not self.notonegroup and self.location is not None: From bb57236b328aab8f3e32339de75a744bb8b881a7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Sat, 23 Oct 2021 12:08:18 +0100 Subject: [PATCH 154/310] new methods, to call as needed (leaving data in tact) --- main.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/main.py b/main.py index 29b8f779..2efe8d5d 100755 --- a/main.py +++ b/main.py @@ -6326,6 +6326,24 @@ class FramedData(object): times to display it. If source is a senseid, it pulls form/gloss/etc information from the entry. If source is an example, it pulls that info from the example. The info is formatted uniformly in either case.""" + def formatted(notonegroup=True,noframe=True): + if notonegroup: + toformat=DataList() + else: + toformat=DataList(self.tonegroup) + if noframe: + toformat.appendformsbylang(self.forms,self.analangs,quote=False) + toformat.appendformsbylang(self.forms,self.glosslangs,quote=True) + else: + toformat.appendformsbylang(self.framed,self.analangs,quote=False) + toformat.appendformsbylang(self.framed,self.glosslangs,quote=True) + return ' '.join(toformat) #put it all together + def setframe(self,frame): + self.frame=frame + self.framed() + def framed(self): + self.forms.frame(self.frame,self.analangs+self.glosslangs) + self.framed=self.forms.framed def parsesense(self,db,senseid,truncdefn=False): self.senseid=senseid lexs=db.lexemes(senseid=senseid) From 7829a65a80c3e555085656534e0a8abeab59327f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:20:52 +0100 Subject: [PATCH 155/310] fixed kwarg problems, excess .get() calls --- lift.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lift.py b/lift.py index fdd188bd..1d571a4c 100644 --- a/lift.py +++ b/lift.py @@ -685,55 +685,59 @@ def getformstosearch(self): log.debug("Found the following forms to search: {}".format( self.formstosearch)) def gloss(self,**kwargs): - return self.get('gloss/text', kwargs).get('text') + return self.get('gloss/text', **kwargs).get('text') def glosses(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.glosslangs: - output[lang]=self.gloss(glosslang=lang, kwargs).get('text') + kwargs['glosslang']=lang + output[lang]=self.gloss(**kwargs)#.get('text') return output def definition(self,**kwargs): truncate=kwargs.pop('truncate',False) - forms=self.get('definition', kwargs).get('text') + forms=self.get('definition', **kwargs).get('text') if truncate: forms=[rx.glossifydefn(f) for f in forms] return forms def definitions(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.glosslangs: - output[lang]=self.definition(glosslang=lang, kwargs).get('text') + kwargs['glosslang']=lang + output[lang]=self.definition(**kwargs) return output def glossordefn(self,**kwargs): - forms=self.gloss(kwargs) + forms=self.gloss(**kwargs) if forms == []: kwargs['truncate']=True - forms=self.definition(kwargs) + forms=self.definition(**kwargs) return forms def glossesordefns(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.glosslangs: - output[lang]=self.gloss(kwargs) + output[lang]=self.gloss(**kwargs) if output[lang] == []: kwargs['truncate']=True - forms=self.definition(kwargs) + forms=self.definition(**kwargs) return output def citation(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" - output=self.get('citation/form/text',kwargs).get('text') + output=self.get('citation/form/text',**kwargs).get('text') return output def citations(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.analangs: - output[lang]=self.citation(analang=lang, kwargs).get('text') + kwargs['analang']=lang + output[lang]=self.citation(**kwargs) #.get('text') log.info("Found the following citation forms: {}".format(output)) return output def lexeme(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" - output=self.get('lexeme/form/text',kwargs).get('text') + output=self.get('lexeme/form/text',**kwargs).get('text') return output def lexemes(self,**kwargs): output={} # This produces a dictionary, of forms for each language. for lang in self.analangs: - output[lang]=self.lexeme(analang=lang, kwargs).get('text') + kwargs['analang']=lang + output[lang]=self.lexeme(**kwargs) log.info("Found the following lexemes: {}".format(output)) return output def extrasegments(self): @@ -768,9 +772,9 @@ def extrasegments(self): "segment.") log.info("--those may not be covered by your regexes.") def ps(self,**kwargs): #get POS values, limited as you like - return self.get('ps',kwargs).get('value')) + return self.get('ps',**kwargs).get('value') def pss(self): #get all POS values in the LIFT file - p=list(dict.fromkeys(self.ps().get('value'))) + p=list(dict.fromkeys(self.ps())) log.info("Found these ps values: {}".format(p)) return p def getmorphtypes(self): #get all morph-type values in the LIFT file From c469c3cf42fa1557eeb34d8131ba60dea1a36897 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:22:00 +0100 Subject: [PATCH 156/310] clean up forms to search --- lift.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lift.py b/lift.py index 1d571a4c..f844c2d7 100644 --- a/lift.py +++ b/lift.py @@ -675,13 +675,14 @@ def getformstosearch(self): for ps in self.pss+[None]: #I need to break this up. self.formstosearch[lang][ps]={} for s in self.get('sense',analang=lang,ps=ps).get('senseid'): - f=self.citation(senseid=s) + f=self.citation(senseid=s,analang=lang) if f == []: - f=self.lexeme(senseid=s) - if f in self.formstosearch[lang][ps]: - self.formstosearch[lang][ps][f].append(s) - else: - self.formstosearch[lang][ps][f]=[s] + f=self.lexeme(senseid=s,analang=lang) + for fi in f: + if fi in self.formstosearch[lang][ps]: + self.formstosearch[lang][ps][fi].append(s) + else: + self.formstosearch[lang][ps][fi]=[s] log.debug("Found the following forms to search: {}".format( self.formstosearch)) def gloss(self,**kwargs): From 562334d319f1c4fab8fd9ae38bf6048378a01d96 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:22:25 +0100 Subject: [PATCH 157/310] add tonegroup method --- main.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.py b/main.py index 2efe8d5d..477640bc 100755 --- a/main.py +++ b/main.py @@ -6345,6 +6345,14 @@ def framed(self): self.forms.frame(self.frame,self.analangs+self.glosslangs) self.framed=self.forms.framed def parsesense(self,db,senseid,truncdefn=False): + def tonegroup(self): + if self.tonegroups is not None: # wanted&found + tonegroup=unlist(self.tonegroups) + if tonegroup is not None: + try: + int(tonegroup) + except: + self.tonegroup=tonegroup #only for named groups self.senseid=senseid lexs=db.lexemes(senseid=senseid) cits=db.citations(senseid=senseid) From e76ce7c4e698d2f625a3883756310fc268657f99 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:22:54 +0100 Subject: [PATCH 158/310] make noframe a class attribute --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 477640bc..8b7f269e 100755 --- a/main.py +++ b/main.py @@ -6405,7 +6405,7 @@ def __init__(self, parent, source, **kwargs): self.tonegroup=None """Build dual logic here. We use this to frame senses & examples""" if isinstance(source,lift.ET.Element): - noframe=True #Examples should already be framed + self.noframe=True #Examples should already be framed if self.db is not None: log.info("FYI: You specified database unnecessarily!") self.parseexample(source) #example element, not sense or entry: From b4c9d6fbb704a3c0166ab8ef85aed9d5027e7f4e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:23:50 +0100 Subject: [PATCH 159/310] add tonegroup method --- main.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/main.py b/main.py index 8b7f269e..153879a5 100755 --- a/main.py +++ b/main.py @@ -6435,13 +6435,6 @@ def __init__(self, parent, source, **kwargs): '\nFYI, I was looking for {}'.format(source)) return source """The following is the same for senses or examples""" - if self.tonegroups is not None: # wanted&found - tonegroup=unlist(self.tonegroups) - if tonegroup is not None: - try: - int(tonegroup) - except: - self.tonegroup=tonegroup #only for named groups # just for convenience: self.analang=self.forms[self.analangs[0]] self.glosslang=self.forms[self.glosslangs[0]] From 1a1542b1865797d282fd6b2ce16f571001670766 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:24:28 +0100 Subject: [PATCH 160/310] just use truncdefn everywhere --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 153879a5..e5bd1106 100755 --- a/main.py +++ b/main.py @@ -6425,7 +6425,7 @@ def __init__(self, parent, source, **kwargs): """ elif type(source) is str and len(source) >= 36:#senseid can be guid+form if self.db is not None: #pull from lift by senseid - self.parsesense(self.db,source,truncdefn=truncdefn) + self.parsesense(self.db,source) else: log.error("Can't pull entry ({}) w/o database!".format(source)) return From c1d69c2d9672773312feb65b50eba2a03fce255b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:24:45 +0100 Subject: [PATCH 161/310] methodize class --- main.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index e5bd1106..2530adac 100755 --- a/main.py +++ b/main.py @@ -6391,12 +6391,12 @@ def __init__(self, parent, source, **kwargs): self.db=parent.db #kwargs.pop('db',None) #not needed for examples self.analangs=parent.analangs self.glosslangs=parent.glosslangs - #Generalize these, and manage with methods: - noframe=kwargs.pop('noframe',False) - self.notonegroup=kwargs.pop('notonegroup',False) - truncdefn=kwargs.pop('truncdefn',False) - self.location=kwargs.pop('location',None) #not needed for noframe - self.frame=kwargs.pop('frame',None) #not needed for noframe + """Generalize these, and manage with methods:""" + # noframe=kwargs.pop('noframe',False) + # self.notonegroup=kwargs.pop('notonegroup',False) + # truncdefn=kwargs.pop('truncdefn',False) + # self.location=kwargs.pop('location',None) #not needed for noframe + # self.frame=kwargs.pop('frame',None) #not needed for noframe #These really must be there, and ordered with first first #to put data: self.forms=DictbyLang() From 9b02ba91cb978f30800d84bcb053c7a252772b92 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:25:02 +0100 Subject: [PATCH 162/310] fix syntax --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 2530adac..37191eb0 100755 --- a/main.py +++ b/main.py @@ -6367,7 +6367,7 @@ def tonegroup(self): self.tonegroups=self.db.get('example/field/form/text', senseid=senseid, # fieldtype='tone', - path=['tonefield'] + path=['tonefield'], location=self.location).get('text') else: log.error("Location isn't set, but you asked for a tonegoup...") From d8a0b13a8e66ab31d5093dbf9b0ad310f871684f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:25:23 +0100 Subject: [PATCH 163/310] bring in ps for senseid parses --- main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.py b/main.py index 37191eb0..cd6e78da 100755 --- a/main.py +++ b/main.py @@ -6353,7 +6353,9 @@ def tonegroup(self): int(tonegroup) except: self.tonegroup=tonegroup #only for named groups + def parsesense(self,db,senseid): self.senseid=senseid + self.ps=db.ps(senseid=senseid) lexs=db.lexemes(senseid=senseid) cits=db.citations(senseid=senseid) glss=db.glossesordefns(senseid=senseid) From 3b8da86a01546e699bc07c0011acd357dd3e5686 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:25:48 +0100 Subject: [PATCH 164/310] frame conditionally --- main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index cd6e78da..771fdbd4 100755 --- a/main.py +++ b/main.py @@ -6342,9 +6342,11 @@ def setframe(self,frame): self.frame=frame self.framed() def framed(self): - self.forms.frame(self.frame,self.analangs+self.glosslangs) - self.framed=self.forms.framed - def parsesense(self,db,senseid,truncdefn=False): + if not self.noframe: + self.forms.frame(self.frame,self.analangs+self.glosslangs) + self.framed=self.forms.framed + else: + self.framed=self.forms def tonegroup(self): if self.tonegroups is not None: # wanted&found tonegroup=unlist(self.tonegroups) From e3e1ec5a29ade816169b6e3803585bc6127b0cb3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:26:02 +0100 Subject: [PATCH 165/310] call frame on use --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 771fdbd4..9f99d60a 100755 --- a/main.py +++ b/main.py @@ -6339,7 +6339,7 @@ def formatted(notonegroup=True,noframe=True): toformat.appendformsbylang(self.framed,self.glosslangs,quote=True) return ' '.join(toformat) #put it all together def setframe(self,frame): - self.frame=frame + self.frame=self.frames[self.ps][frame] self.framed() def framed(self): if not self.noframe: From 4beb18cb4e0e6e600a8739bc2836f1f6cfef1834 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:26:21 +0100 Subject: [PATCH 166/310] cleanup --- main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main.py b/main.py index 9f99d60a..53e3f9f8 100755 --- a/main.py +++ b/main.py @@ -6318,7 +6318,6 @@ def __init__(self, check, **kwargs): self.db=check.db self.analangs=check.analangs self.glosslangs=check.glosslangs - class FramedData(object): """This populates an object with attributes to format data for display, by senseid""" From 7d75712f77f85b99affadb61d59c18fb66563c8d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 14:26:35 +0100 Subject: [PATCH 167/310] don't use truncdefn --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 53e3f9f8..61e36c7b 100755 --- a/main.py +++ b/main.py @@ -4134,7 +4134,7 @@ def testsorting(self): delattr(self,'groupselected') #reset this for each word! senseid=self.senseidsunsorted[0] progress=(str(self.senseidstosort.index(senseid)+1)+'/'+str(todo)) - framed=self.getframeddata(senseid,truncdefn=True) + framed=self.getframeddata(senseid) """After the first entry, sort by groups.""" log.debug('self.tonegroups: {}'.format(status['groups'])) Label(titles, text=progress, font=self.fonts['report'], anchor='w' From 1e76d1e916321cb8d26dfbed45a1285d2a9773bf Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:52:01 +0100 Subject: [PATCH 168/310] actually use the class --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 61e36c7b..6fc4d37f 100755 --- a/main.py +++ b/main.py @@ -219,6 +219,7 @@ def __init__(self, parent, frame, nsyls=None): # hasattr(self,'profile') and (self.profile is not None) and # hasattr(self,'name') and (self.name is not None)): # self.sortingstatus() #because this won't get set later #>checkdefaults? + self.datadict=FramedDataDict(self) log.info("Done initializing check; running first check check.") """Testing Zone""" #set None to make labels, else "raised" "groove" "sunken" "ridge" "flat" From ebc1d801a4da242260e2a6bd08ea464ef1c89cf4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:55:44 +0100 Subject: [PATCH 169/310] update from exfieldvalue --- main.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 6fc4d37f..52cff5ad 100755 --- a/main.py +++ b/main.py @@ -1701,8 +1701,8 @@ def updatestatuslift(self,name=None,subcheck=None,verified=False,refresh=True): subcheck=self.subcheck if name is None: name=self.name - senseids=self.db.get('senseidbyexfieldvalue',fieldtype='tone', - location=name,fieldvalue=subcheck) + senseids=self.db.get("sense", location=name, tonevalue=subcheck, + path=['tonefield']).get('senseid') value=self.verifictioncode(name,subcheck) if verified == True: add=value @@ -3644,10 +3644,9 @@ def senseidsincheck(self,senseids): return senseidstochange def getexsall(self,value): #This returns all the senseids with a given tone value - senseids=self.db.get('senseidbyexfieldvalue',location=self.name, - fieldtype='tone', - fieldvalue=value - ) + senseids=self.db.get("sense", location=self.name, path=['tonefield'], + tonevalue=value + ).get('text') senseidsincheck=self.senseidsincheck(senseids) return list(senseidsincheck) def getex(self,value,notonegroup=True,truncdefn=False,renew=False): @@ -4610,8 +4609,9 @@ def gettonegroups(self): log.log(3,"Looking for tone groups for {} frame".format(self.name)) tonegroups=[] for senseid in self.senseidstosort: #This is a ps-profile slice - tonegroup=self.db.get('exfieldvalue', senseid=senseid, - fieldtype='tone', location=self.name)#, showurl=True) + tonegroup=self.db.get("text", path=['tonefield'], + senseid=senseid, location=self.name + ).get('text') if unlist(tonegroup) in ['NA','','ALLOK', None]: log.error("tonegroup {} found in sense {} under location {}!" "".format(tonegroup,senseid,self.name)) @@ -4678,8 +4678,8 @@ def sortingstatus(self): self.senseidssorted=[] self.senseidsunsorted=[] for senseid in self.senseidstosort: - v=self.db.get('exfieldvalue',senseid=senseid,fieldtype='tone', - location=self.name) #because it's relevant to this + v=self.db.get("text", senseid=senseid, location=self.name, + path=['tonefield']).get('text') log.info("Found tone value: {}".format(v)) if unlist(v) in ['',None]: self.senseidsunsorted+=[senseid] @@ -5576,8 +5576,9 @@ def tonegroupsbyUFlocation(self,senseidsbygroup): for location in locations: #just make them all, delete empty later values[group][location]=list() for senseid in senseidsbygroup[group]: - groupvalue=self.db.get('exfieldvalue',senseid=senseid, - location=location,fieldtype='tone') + groupvalue=self.db.get("text", senseid=senseid, + location=location, path=['tonefield'] + ).get('text') if groupvalue != [None]: if unlist(groupvalue) not in values[group][location]: values[group][location]+=groupvalue @@ -5599,8 +5600,8 @@ def tonegroupsbysenseidlocation(self): for senseid in self.senseidstosort: output[senseid]={} for location in locations: - group=self.db.get('exfieldvalue',senseid=senseid, - location=location,fieldtype='tone') + group=self.db.get("text", senseid=senseid, location=location, + path=['tonefield']).get('text') if group != [None]: output[senseid][location]=group #Save this info by senseid log.info("Done collecting groups by location for each senseid.") @@ -8512,8 +8513,8 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): db=framed, fieldtype='tone',location=self.name, fieldvalue='') #this value should be the only change - tgroups=self.db.get('exfieldvalue', senseid=senseid, - fieldtype='tone', location=self.name) + tgroups=self.db.get("text", senseid=senseid, location=self.name, + path=['tonefield']).get('text') if type(tgroups) is list: if len(tgroups) > 1: log.error(_("Found {} tone values: {}".format(len(tgroups),tgroups))) From 70baa1afff7b2bb66df524476a326bde71f5cb16 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:56:02 +0100 Subject: [PATCH 170/310] just one analang --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 52cff5ad..e6ed82f5 100755 --- a/main.py +++ b/main.py @@ -6394,7 +6394,7 @@ def __init__(self, parent, source, **kwargs): super(FramedData, self).__init__() self.frames=parent.frames self.db=parent.db #kwargs.pop('db',None) #not needed for examples - self.analangs=parent.analangs + self.analang=parent.analang self.glosslangs=parent.glosslangs """Generalize these, and manage with methods:""" # noframe=kwargs.pop('noframe',False) From d600ed76a05326a219dbf608bb76dafa2238279c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:56:31 +0100 Subject: [PATCH 171/310] again --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index e6ed82f5..d7352ea7 100755 --- a/main.py +++ b/main.py @@ -6318,7 +6318,7 @@ def __init__(self, check, **kwargs): super(FramedDataDict, self).__init__() self.frames=check.toneframes #[ps][name] self.db=check.db - self.analangs=check.analangs + self.analang=check.analang self.glosslangs=check.glosslangs class FramedData(object): """This populates an object with attributes to format data for display, From be79916d5af3fcb004fc66cfe72dbe2aa0c6c5bd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:57:06 +0100 Subject: [PATCH 172/310] just citation --- main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index d7352ea7..d73480ee 100755 --- a/main.py +++ b/main.py @@ -1768,7 +1768,7 @@ def getprofileofsense(self,senseid): #Convert to iterate over local variables profileori=self.profile #We iterate across this here psori=self.ps #We iterate across this here - forms=self.db.citationorlexeme(senseid=senseid,lang=self.analang) + forms=self.db.citation(senseid=senseid,lang=self.analang) #orlexeme if forms == []: self.profile='Invalid' for self.ps in self.db.get('ps',senseid=senseid): @@ -2239,10 +2239,10 @@ def getframeddata(self,source,noframe=False,notonegroup=False,truncdefn=False): log.log(3,'36 character senseid string!') senseid=source output['senseid']=senseid - forms[self.analang]=self.db.citationorlexeme(senseid=senseid, + forms[self.analang]=self.db.citation(senseid=senseid,#orlexeme lang=self.analang, ps=self.ps) - forms[self.audiolang]=self.db.citationorlexeme(senseid=senseid, + forms[self.audiolang]=self.db.citation(senseid=senseid, #orlexeme lang=self.audiolang, ps=self.ps) for lang in [self.glosslang,self.glosslang2]: From b8296ef0654019892fe89e9fe1a620a20aac188d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:57:34 +0100 Subject: [PATCH 173/310] actually use the class --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index d73480ee..f154a701 100755 --- a/main.py +++ b/main.py @@ -4134,13 +4134,13 @@ def testsorting(self): delattr(self,'groupselected') #reset this for each word! senseid=self.senseidsunsorted[0] progress=(str(self.senseidstosort.index(senseid)+1)+'/'+str(todo)) - framed=self.getframeddata(senseid) + framed=self.datadict.getframeddata(senseid) """After the first entry, sort by groups.""" log.debug('self.tonegroups: {}'.format(status['groups'])) Label(titles, text=progress, font=self.fonts['report'], anchor='w' ).grid(column=1, row=0, sticky="ew") if 'formatted' in framed: - text=(framed['formatted']) + text=framed.formatted(noframe=False)#(framed['formatted']) #notonegroup=True, else: text=_("Sorry; I can't find {}".format(framed)) l=Label(self.runwindow.frame, text=text,font=self.fonts['readbig']) From ee58280719f019338bb26f86049ac007628b1079 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:58:29 +0100 Subject: [PATCH 174/310] bring formstosearch to check --- main.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index f154a701..cba155da 100755 --- a/main.py +++ b/main.py @@ -1783,6 +1783,12 @@ def getprofileofsense(self,senseid): self.profile='Invalid' for self.ps in self.db.get('ps',senseid=senseid): self.addtoprofilesbysense(senseid) + if ps not in self.formstosearch: + self.formstosearch[ps]={} + if form in self.formstosearch[ps]: + self.formstosearch[ps][form].append(s) + else: + self.formstosearch[ps][form]=[s] profile=self.profile self.profile=profileori self.ps=psori @@ -1793,6 +1799,7 @@ def getprofiles(self): self.profilesbysense['Invalid']=[] self.profiledguids=[] self.profiledsenseids=[] + self.formstosearch={} self.sextracted={} #Will store matching segments here for ps in self.db.pss: self.sextracted[ps]={} @@ -5243,6 +5250,15 @@ def next(): text=_("Continue to next syllable profile"), command=next).grid(row=1,column=0) self.donewpyaudio() + def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! + """make this a check method?""" + """This function takes in a ps and compiled regex, + and outputs a list/dictionary of senseid/{senseid:form} form.""" + output=[] #This is just a list of senseids now: (Do we need the dict?) + for form in self.formstosearch[ps]: + if regex.search(form): + output+=self.formstosearch[ps][form] + return output def getresults(self): self.getrunwindow() self.makeresultsframe() @@ -5280,7 +5296,7 @@ def getresults(self): # print(self.profilesbysense[self.ps][self.profile][0]) # print(self.db.citationorlexeme(self.profilesbysense[self.ps][self.profile][0])) # print(firstoflist(self.db.citationorlexeme(self.profilesbysense[self.ps][self.profile][0]))) - senseidstocheck=self.db.senseidformsbyregex(self.regex, + senseidstocheck=self.senseidformsbyregex(self.regex, self.analang, ps=self.ps) # senseidstocheck= filter(lambda x: self.regex.search( From 76db24f9cb3d26237c6a958bc486c2c0e27c750c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:59:19 +0100 Subject: [PATCH 175/310] remove formstosearch (to check) --- lift.py | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/lift.py b/lift.py index f844c2d7..790bd6d8 100644 --- a/lift.py +++ b/lift.py @@ -62,7 +62,6 @@ def __init__(self, filename,nsyls=None): self.glosslangs() #sets: self.glosslangs self.analangs() #sets: self.analangs, self.audiolangs self.pss=self.pss() #log.info(self.pss) - self.getformstosearch() #sets: self.formstosearch[lang][ps] #no guids """This is very costly on boot time, so this one line is not used:""" # self.getguidformstosearch() #sets: self.guidformstosearch[lang][ps] self.citationforms=self.citations() @@ -664,27 +663,28 @@ def clist(self): #This variable gives lists, to iterate over. def slists(self): self.segmentsnotinregexes={} self.clist() - def getformstosearch(self): - """This outputs a dictionary of form {analang: {guid:form}*}*, where - form is citation if available, or else lexeme. This is to be flexible - for entries in process of analysis, and to have a dictionary to check - with regexes for output.""" - self.formstosearch={} - for lang in self.analangs: - self.formstosearch[lang]={} #This will erase all previous data!! - for ps in self.pss+[None]: #I need to break this up. - self.formstosearch[lang][ps]={} - for s in self.get('sense',analang=lang,ps=ps).get('senseid'): - f=self.citation(senseid=s,analang=lang) - if f == []: - f=self.lexeme(senseid=s,analang=lang) - for fi in f: - if fi in self.formstosearch[lang][ps]: - self.formstosearch[lang][ps][fi].append(s) - else: - self.formstosearch[lang][ps][fi]=[s] - log.debug("Found the following forms to search: {}".format( - self.formstosearch)) + # def getformstosearch(self): + # """This outputs a dictionary of form {analang: {guid:form}*}*, where + # form is citation if available, or else lexeme. This is to be flexible + # for entries in process of analysis, and to have a dictionary to check + # with regexes for output.""" + # fts={} + # for lang in self.analangs: + # fts[lang]={} #This will erase all previous data!! + # for ps in self.pss+[None]: #I need to break this up. + # fts[lang][ps]={} + # for s in self.get('sense',analang=lang,ps=ps).get('senseid'): + # f=self.citation(senseid=s,analang=lang) + # # if f == []: + # # f=self.lexeme(senseid=s,analang=lang) + # for fi in f: + # if fi in fts[lang][ps]: + # fts[lang][ps][fi].append(s) + # else: + # fts[lang][ps][fi]=[s] + # log.debug("Found the following forms to search: {}".format( + # fts)) + # return fts def gloss(self,**kwargs): return self.get('gloss/text', **kwargs).get('text') def glosses(self,**kwargs): @@ -784,14 +784,6 @@ def getmorphtypes(self): #get all morph-type values in the LIFT file log.info("Found these morph-type values: {}".format(m)) return m """CONTINUE HERE: Making things work for the new lift.get() paradigm.""" - def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! - """This function takes in a ps and compiled regex, - and outputs a list/dictionary of senseid/{senseid:form} form.""" - output=[] #This is just a list of senseids now: (Do we need the dict?) - for form in self.formstosearch[analang][ps]: - if regex.search(form): - output+=self.formstosearch[analang][ps][form] - return output class Node(ET.Element): def makefieldnode(self,type,lang,text=None,gimmetext=False): n=Node(self,'field',attrib={'type':type}) From 1a1ee5b704cacab3c61702e5cee49ec87f5e11c0 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 16:59:41 +0100 Subject: [PATCH 176/310] make urls work even with apostraphes in ids --- lift.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 790bd6d8..bdb7531e 100644 --- a/lift.py +++ b/lift.py @@ -885,7 +885,10 @@ def build(self,tag,liftattr=None,myattr=None,attrs=None): for attr in attrs: if (None not in [attr,attrs[attr]] and attrs[attr] in self.kwargs and self.kwargs[attrs[attr]] is not None): - b+="[@{}='{}']".format(attr,self.kwargs[attrs[attr]]) + if "'" in self.kwargs[attrs[attr]]: + b+="[@{}=\"{}\"]".format(attr,self.kwargs[attrs[attr]]) + else: + b+="[@{}='{}']".format(attr,self.kwargs[attrs[attr]]) if ((liftattr is None or (liftattr in self.kwargs #no lift attribute and self.kwargs[liftattr] is None)) and tag == 'text' and myattr in self.kwargs #text value to match From 5d8de1b402db9c360b0496e43e51a010ebce6b5b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Tue, 26 Oct 2021 17:01:46 +0100 Subject: [PATCH 177/310] remove for now --- main.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index cba155da..c8b3b397 100755 --- a/main.py +++ b/main.py @@ -6456,13 +6456,13 @@ def __init__(self, parent, source, **kwargs): '\nFYI, I was looking for {}'.format(source)) return source """The following is the same for senses or examples""" - # just for convenience: - self.analang=self.forms[self.analangs[0]] - self.glosslang=self.forms[self.glosslangs[0]] - if len(self.glosslangs) >1 and self.glosslangs[1] in self.forms: - self.glosslang2=self.forms[self.glosslangs[1]] - else: - self.glosslang2=None + # # just for convenience: + # self.analang=self.forms[self.analangs[0]] + # self.glosslang=self.forms[self.glosslangs[0]] + # if len(self.glosslangs) >1 and self.glosslangs[1] in self.forms: + # self.glosslang2=self.forms[self.glosslangs[1]] + # else: + # self.glosslang2=None class ExitFlag(object): def istrue(self): # log.debug("Returning {} exitflag".format(self.value)) From 160d385366739fd7bf58f8d90e016e5ec094e885 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 09:59:36 +0100 Subject: [PATCH 178/310] Added D --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index c8b3b397..c2cf305c 100755 --- a/main.py +++ b/main.py @@ -167,7 +167,7 @@ def __init__(self, parent, frame, nsyls=None): self.invalidchars=[' ','...',')','(
'] #multiple characters not working. self.invalidregex='( |\.|,|\)|\()+' # self.profilelegit=['#','̃','C','N','G','S','V','o'] #In 'alphabetical' order - self.profilelegit=['#','̃','N','G','S','C','Ṽ','V','ʔ','d','b','o'] #'alphabetical' order + self.profilelegit=['#','̃','N','G','S','C','D','Ṽ','V','ʔ','d','b','o'] #'alphabetical' order """Are we OK without these?""" # self.guidtriage() #sets: self.guidswanyps self.guidswops self.guidsinvalid self.guidsvalid # self.guidtriagebyps() #sets self.guidsvalidbyps (dictionary keyed on ps) From bd8014f4daf10934a68ac72661f3e6dd0d5a2428 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 10:00:28 +0100 Subject: [PATCH 179/310] initialize glosslangs --- main.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index c2cf305c..6eedad21 100755 --- a/main.py +++ b/main.py @@ -219,6 +219,7 @@ def __init__(self, parent, frame, nsyls=None): # hasattr(self,'profile') and (self.profile is not None) and # hasattr(self,'name') and (self.name is not None)): # self.sortingstatus() #because this won't get set later #>checkdefaults? + self.guessglosslangs() #needed for the following self.datadict=FramedDataDict(self) log.info("Done initializing check; running first check check.") """Testing Zone""" @@ -310,17 +311,19 @@ def guessaudiolang(self): return def guessglosslangs(self): """if there's only one gloss language, use it.""" + if not hasattr(self,'glosslangs'): + self.glosslangs=[None,None] if len(self.db.glosslangs) == 1: log.info('Only one glosslang!') - self.glosslang=self.db.glosslangs[0] - self.glosslang2=None + self.glosslangs[0]=self.glosslang=self.db.glosslangs[0] + self.glosslangs[1]=self.glosslang2=None """if there are two or more gloss languages, just pick the first two, and the user can select something else later (the gloss languages are not for CV profile analaysis, but for info after checking, when this can be reset.""" elif len(self.db.glosslangs) > 1: - self.glosslang=self.db.glosslangs[0] - self.glosslang2=self.db.glosslangs[1] + self.glosslangs[0]=self.glosslang=self.db.glosslangs[0] + self.glosslangs[1]=self.glosslang2=self.db.glosslangs[1] else: print("Can't tell how many glosslangs!",len(self.db.glosslangs)) def getpss(self): @@ -1240,7 +1243,7 @@ def set(self,attribute,choice,window=None,refresh=True): from self.defaultstoclear[attribute]""" self.cleardefaults(attribute) if attribute in ['glosslang','glosslang2']: - pass #Nothing to change here + self.glosslangs=[self.glosslang,self.glosslang2] #Nothing else to change here elif attribute in ['analang', #do the last two cause problems? 'interpret','distinguish']: self.reloadprofiledata() From b372f035c146233bb49bff75044592a810d255d9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 10:01:16 +0100 Subject: [PATCH 180/310] reinstall citationorlexeme --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 6eedad21..77333f55 100755 --- a/main.py +++ b/main.py @@ -1771,7 +1771,7 @@ def getprofileofsense(self,senseid): #Convert to iterate over local variables profileori=self.profile #We iterate across this here psori=self.ps #We iterate across this here - forms=self.db.citation(senseid=senseid,lang=self.analang) #orlexeme + forms=self.db.citationorlexeme(senseid=senseid,analang=self.analang) if forms == []: self.profile='Invalid' for self.ps in self.db.get('ps',senseid=senseid): From 95ac0c80ad139d62cc4009cddc0fd1bfb06d399a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 10:01:40 +0100 Subject: [PATCH 181/310] use lift.ps --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 77333f55..7737c1a3 100755 --- a/main.py +++ b/main.py @@ -1774,7 +1774,7 @@ def getprofileofsense(self,senseid): forms=self.db.citationorlexeme(senseid=senseid,analang=self.analang) if forms == []: self.profile='Invalid' - for self.ps in self.db.get('ps',senseid=senseid): + for self.ps in self.db.ps(senseid=senseid): self.addtoprofilesbysense(senseid) self.ps=psori return None,'Invalid' @@ -1784,7 +1784,7 @@ def getprofileofsense(self,senseid): self.profile=self.profileofform(form) if not set(self.profilelegit).issuperset(self.profile): self.profile='Invalid' - for self.ps in self.db.get('ps',senseid=senseid): + for self.ps in self.db.ps(senseid=senseid): self.addtoprofilesbysense(senseid) if ps not in self.formstosearch: self.formstosearch[ps]={} From bdacd423b66faa435efb02d76ed4000a9ec21eed Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 10:01:58 +0100 Subject: [PATCH 182/310] make formstosearch work --- main.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index 7737c1a3..79517c77 100755 --- a/main.py +++ b/main.py @@ -1456,6 +1456,7 @@ def settingsbyfile(self): "scount", "sextracted", "profilesbysense", + "formstosearch" ]}, 'status':{ 'file':'statusfile', @@ -1786,12 +1787,12 @@ def getprofileofsense(self,senseid): self.profile='Invalid' for self.ps in self.db.ps(senseid=senseid): self.addtoprofilesbysense(senseid) - if ps not in self.formstosearch: - self.formstosearch[ps]={} - if form in self.formstosearch[ps]: - self.formstosearch[ps][form].append(s) + if self.ps not in self.formstosearch: + self.formstosearch[self.ps]={} + if form in self.formstosearch[self.ps]: + self.formstosearch[self.ps][form].append(senseid) else: - self.formstosearch[ps][form]=[s] + self.formstosearch[self.ps][form]=[senseid] profile=self.profile self.profile=profileori self.ps=psori From f33fb07f05a73b38e559c15cfbf505da8ebff8bc Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 10:02:49 +0100 Subject: [PATCH 183/310] reinstall citationorlexeme --- lift.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lift.py b/lift.py index bdb7531e..2614e3dc 100644 --- a/lift.py +++ b/lift.py @@ -719,6 +719,14 @@ def glossesordefns(self,**kwargs): kwargs['truncate']=True forms=self.definition(**kwargs) return output + def citationorlexeme(self,**kwargs): + """This produces a list; specify senseid and analang as you like.""" + output=self.citation(**kwargs) + if output == []: + output=self.lexeme(**kwargs) + log.info("Missing citation form; looking for lexeme form.({})" + "".format(kwargs)) + return output def citation(self,**kwargs): """This produces a list; specify senseid and analang as you like.""" output=self.get('citation/form/text',**kwargs).get('text') From c1a75fed9eb11b36a902204fcfec1b316d75c722 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 10:03:02 +0100 Subject: [PATCH 184/310] add similar notice for gloss/defn --- lift.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lift.py b/lift.py index 2614e3dc..96100736 100644 --- a/lift.py +++ b/lift.py @@ -708,6 +708,8 @@ def definitions(self,**kwargs): def glossordefn(self,**kwargs): forms=self.gloss(**kwargs) if forms == []: + log.info("Missing gloss form; looking for definition form.({})" + "".format(kwargs)) kwargs['truncate']=True forms=self.definition(**kwargs) return forms From 97b90ad5da5c418a6174ef94aadc7a726a85f996 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:32:05 +0100 Subject: [PATCH 185/310] update to new attributes --- lift.py | 8 ++++---- rx.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index 96100736..dbead2d8 100644 --- a/lift.py +++ b/lift.py @@ -64,8 +64,8 @@ def __init__(self, filename,nsyls=None): self.pss=self.pss() #log.info(self.pss) """This is very costly on boot time, so this one line is not used:""" # self.getguidformstosearch() #sets: self.guidformstosearch[lang][ps] - self.citationforms=self.citations() - self.lexemes=self.lexemes() + self.lcs=self.citations() + self.lxs=self.lexemes() self.locations=self.getlocations() self.defaults=[ #these are lift related defaults 'analang', @@ -761,7 +761,7 @@ def extrasegments(self): # nonwordforming=re.compile('[() \[\]\|,\-!@#$*?]') invalid=['(',')',' ','[',']','|',',','-','!','@','#','$','*','?' ,'\n'] - for form in [x for x in self.citationforms[lang]+self.lexemes[lang] + for form in [x for x in self.lcs[lang]+self.lxs[lang] if x != None]: for x in form: if ((x not in invalid) and @@ -836,7 +836,7 @@ def __init__(self, db, guid=None, *args, **kwargs): """get(self,attribute,guid=None,analang=None,glosslang=None,lang=None, ps=None,form=None,fieldtype=None,location=None,showurl=False)""" # self.lexeme=db.get('lexeme',guid=guid) #don't use this! - self.citation=db.citationorlexeme(guid=guid,lang=self.analang) + self.lc=db.citationorlexeme(guid=guid,lang=self.analang) self.gloss=db.glossordefn(guid=guid,lang=self.glosslang) self.gloss2=db.glossordefn(guid=guid,lang=self.glosslang2) # self.citation=get.citation(self,self.analang) diff --git a/rx.py b/rx.py index 64d4ad56..77d439b8 100644 --- a/rx.py +++ b/rx.py @@ -86,7 +86,7 @@ def segmentin(forms, glyph): def inxyz(db, lang, segmentlist): #This calls the above script for each character. start_time=time.time() #this enables boot time evaluation actuals=list() - forms=db.citationforms[lang] + db.lexemes[lang] + forms=db.lcs[lang] + db.lxs[lang] for i in segmentlist: s=segmentin(forms,i) #log.info(s) #to see the following run per segment From 90ac03356809659d336ae549634d31a3ef40b9cd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:32:33 +0100 Subject: [PATCH 186/310] grammatical fixes --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 79517c77..7191571e 100755 --- a/main.py +++ b/main.py @@ -6332,7 +6332,7 @@ class FramedDataDict(dict): def getframeddata(self, source, **kwargs): if source not in self: kwargs['db']=self.db - self[source]=FramedData(self,source,kwargs) + self[source]=FramedData(self,source,**kwargs) return self[source] def __init__(self, check, **kwargs): super(FramedDataDict, self).__init__() @@ -6347,7 +6347,7 @@ class FramedData(object): times to display it. If source is a senseid, it pulls form/gloss/etc information from the entry. If source is an example, it pulls that info from the example. The info is formatted uniformly in either case.""" - def formatted(notonegroup=True,noframe=True): + def formatted(self,notonegroup=True,noframe=True): if notonegroup: toformat=DataList() else: From a5475a093564d2d64d5601118ff3e7fd8e20ece7 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:33:03 +0100 Subject: [PATCH 187/310] return location to class init --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 7191571e..1bd5b33f 100755 --- a/main.py +++ b/main.py @@ -6416,11 +6416,11 @@ def __init__(self, parent, source, **kwargs): self.db=parent.db #kwargs.pop('db',None) #not needed for examples self.analang=parent.analang self.glosslangs=parent.glosslangs + self.location=kwargs.pop('location',None) #not needed for noframe """Generalize these, and manage with methods:""" # noframe=kwargs.pop('noframe',False) # self.notonegroup=kwargs.pop('notonegroup',False) # truncdefn=kwargs.pop('truncdefn',False) - # self.location=kwargs.pop('location',None) #not needed for noframe # self.frame=kwargs.pop('frame',None) #not needed for noframe #These really must be there, and ordered with first first #to put data: From 24c7c4ebc3fbe87e6af07930e02e5635e61120ef Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:33:36 +0100 Subject: [PATCH 188/310] new gettonegroup method --- main.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.py b/main.py index 1bd5b33f..bfbf64a6 100755 --- a/main.py +++ b/main.py @@ -6368,6 +6368,13 @@ def framed(self): self.framed=self.forms.framed else: self.framed=self.forms + def gettonegroup(self): + if self.location is not None: + self.tonegroups=self.db.get('example/field/form/text', + senseid=senseid, + # fieldtype='tone', + path=['tonefield'], + location=self.location).get('text') def tonegroup(self): if self.tonegroups is not None: # wanted&found tonegroup=unlist(self.tonegroups) @@ -6396,6 +6403,7 @@ def parsesense(self,db,senseid): location=self.location).get('text') else: log.error("Location isn't set, but you asked for a tonegoup...") + self.gettonegroup() def parseexample(self,example): self.senseid=None #We don't have access to this here for i in example: From 7ae62827e65835bc3be01abbd29e880e9b4b9f22 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:35:08 +0100 Subject: [PATCH 189/310] fix ps --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index bfbf64a6..d3f1744d 100755 --- a/main.py +++ b/main.py @@ -6385,7 +6385,6 @@ def tonegroup(self): self.tonegroup=tonegroup #only for named groups def parsesense(self,db,senseid): self.senseid=senseid - self.ps=db.ps(senseid=senseid) lexs=db.lexemes(senseid=senseid) cits=db.citations(senseid=senseid) glss=db.glossesordefns(senseid=senseid) @@ -6403,6 +6402,7 @@ def parsesense(self,db,senseid): location=self.location).get('text') else: log.error("Location isn't set, but you asked for a tonegoup...") + self.ps=unlist(db.ps(senseid=senseid)) #there should be just one self.gettonegroup() def parseexample(self,example): self.senseid=None #We don't have access to this here From f3ee930fc214acb4bc9ffeab49f5d82b9b2e9e61 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:56:44 +0100 Subject: [PATCH 190/310] join lists --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index d3f1744d..609b8fc5 100755 --- a/main.py +++ b/main.py @@ -6364,7 +6364,7 @@ def setframe(self,frame): self.framed() def framed(self): if not self.noframe: - self.forms.frame(self.frame,self.analangs+self.glosslangs) + self.forms.frame(self.frame,[self.analang]+self.glosslangs) self.framed=self.forms.framed else: self.framed=self.forms From 179468c731da8c84190bab4d4a6e998fb506f84b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:57:15 +0100 Subject: [PATCH 191/310] distinguish applyframe --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 609b8fc5..d617feab 100755 --- a/main.py +++ b/main.py @@ -6361,8 +6361,8 @@ def formatted(self,notonegroup=True,noframe=True): return ' '.join(toformat) #put it all together def setframe(self,frame): self.frame=self.frames[self.ps][frame] - self.framed() - def framed(self): + self.applyframe() + def applyframe(self): if not self.noframe: self.forms.frame(self.frame,[self.analang]+self.glosslangs) self.framed=self.forms.framed From 7223bc62763d33fffffabb86ec4bb4735edb33c9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:57:27 +0100 Subject: [PATCH 192/310] just one analang --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index d617feab..c9d7468b 100755 --- a/main.py +++ b/main.py @@ -6353,10 +6353,10 @@ def formatted(self,notonegroup=True,noframe=True): else: toformat=DataList(self.tonegroup) if noframe: - toformat.appendformsbylang(self.forms,self.analangs,quote=False) + toformat.appendformsbylang(self.forms,self.analang,quote=False) toformat.appendformsbylang(self.forms,self.glosslangs,quote=True) else: - toformat.appendformsbylang(self.framed,self.analangs,quote=False) + toformat.appendformsbylang(self.framed,self.analang,quote=False) toformat.appendformsbylang(self.framed,self.glosslangs,quote=True) return ' '.join(toformat) #put it all together def setframe(self,frame): From a55f2aa212d8d6d69f4378eefeb87fa2ddec6470 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:58:11 +0100 Subject: [PATCH 193/310] init with self.framed --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index c9d7468b..e54c9ec9 100755 --- a/main.py +++ b/main.py @@ -6328,6 +6328,7 @@ def frame(self,framedict,langs): #langs can/should be ordered self.framed[l]=rx.framerx.sub(self[l],framedict[l]) def __init__(self): super(DictbyLang, self).__init__() + self.framed={} class FramedDataDict(dict): def getframeddata(self, source, **kwargs): if source not in self: From 5d84b02a8a3bb3c8b4b29d2e5bcafc9ba44b57f1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:58:38 +0100 Subject: [PATCH 194/310] don't use empty data --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index e54c9ec9..f3a07863 100755 --- a/main.py +++ b/main.py @@ -6324,7 +6324,7 @@ def getformfromnode(self,node,truncate=False): def frame(self,framedict,langs): #langs can/should be ordered """the frame only applies if there is a language value; I hope that's what we want...""" - for l in [i for i in langs if i in framedict if i in self]: + for l in [i for i in langs if i in framedict if i in self and self[i] != []]: self.framed[l]=rx.framerx.sub(self[l],framedict[l]) def __init__(self): super(DictbyLang, self).__init__() From f2c25aaa58f4fecc2062b998aa7a924e0bb6627c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 11:58:54 +0100 Subject: [PATCH 195/310] set frame --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index f3a07863..3b2273bf 100755 --- a/main.py +++ b/main.py @@ -4146,6 +4146,7 @@ def testsorting(self): senseid=self.senseidsunsorted[0] progress=(str(self.senseidstosort.index(senseid)+1)+'/'+str(todo)) framed=self.datadict.getframeddata(senseid) + framed.setframe(self.name) """After the first entry, sort by groups.""" log.debug('self.tonegroups: {}'.format(status['groups'])) Label(titles, text=progress, font=self.fonts['report'], anchor='w' From 875576b05d110ce73930c6bf2880901c861e1c0a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 15:37:52 +0100 Subject: [PATCH 196/310] fix parent name --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index dbead2d8..a99a777c 100644 --- a/lift.py +++ b/lift.py @@ -274,7 +274,7 @@ def addmodexamplefields(self,**kwargs): forms=db.forms glosses=db.glosses glosslangs=db.glosslangs - p=Node(node, tag='example') + p=Node(sensenode, tag='example') p.makeformnode(analang,forms[analang]) """Until I have reason to do otherwise, I'm going to assume these fields are being filled in in the glosslang language.""" From a959a43821c06c33d575971f438d58c0678ec9a1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 15:38:32 +0100 Subject: [PATCH 197/310] unlist glosslang --- lift.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index a99a777c..4316dae1 100644 --- a/lift.py +++ b/lift.py @@ -282,9 +282,9 @@ def addmodexamplefields(self,**kwargs): for lang in glosslangs: if lang != None and hasattr(forms,lang): fieldgloss.makeformnode(lang,getattr(forms,lang)) - exfieldvalue=p.makefieldnode(fieldtype,glosslang,gimmetext=True) - p.makefieldnode('location',glosslang,text=location) - p.makefieldnode('tone',glosslang,text=tonevalue) + exfieldvalue=p.makefieldnode(fieldtype,glosslangs[0],gimmetext=True) + p.makefieldnode('location',glosslangs[0],text=location) + p.makefieldnode('tone',glosslangs[0],text=tonevalue) self.updatemoddatetime(senseid=senseid) def forminnode(self,node,value): """Returns True if `value` is in *any* text node child of any form child From f39214bcc75b95d288e03e2315c2557d36c32b65 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 15:38:50 +0100 Subject: [PATCH 198/310] limit defns to glosslang --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 4316dae1..9d261d4c 100644 --- a/lift.py +++ b/lift.py @@ -716,6 +716,7 @@ def glossordefn(self,**kwargs): def glossesordefns(self,**kwargs): output={} # This produces a dictionary, of forms for each language for lang in self.glosslangs: + kwargs['glosslang']=lang output[lang]=self.gloss(**kwargs) if output[lang] == []: kwargs['truncate']=True From 17927f43f3264518d1baffbe4b6b2ab07ee5a6e0 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 15:39:12 +0100 Subject: [PATCH 199/310] not using anymore --- lift.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lift.py b/lift.py index 9d261d4c..805a246a 100644 --- a/lift.py +++ b/lift.py @@ -272,7 +272,6 @@ def addmodexamplefields(self,**kwargs): analang=kwargs.get('analang') db=kwargs.get('db') #This an object with values forms=db.forms - glosses=db.glosses glosslangs=db.glosslangs p=Node(sensenode, tag='example') p.makeformnode(analang,forms[analang]) From 090950467628db14acf2bb8e2e09f7082f30068d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 16:07:18 +0100 Subject: [PATCH 200/310] space --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 805a246a..c829a42a 100644 --- a/lift.py +++ b/lift.py @@ -1104,7 +1104,7 @@ def showtargetinlowestancestry(self,nodename): if g>10: giveup=True if giveup is True: - log.error("Hey, I've looked back {} generations, and I don't see" + log.error("Hey, I've looked back {} generations, and I don't see " "an ancestor of {} (target) which is also an ancestor of " "{} (current node).".format(g,self.targethead,nodename)) def showtargetinhighestdecendance(self,nodename): From 2cc5d37fb22712da907d1e96199ce4d35e54f761 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:48:42 +0100 Subject: [PATCH 201/310] this should never be a list --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index c829a42a..32962997 100644 --- a/lift.py +++ b/lift.py @@ -246,7 +246,7 @@ def addverificationnode(self,senseid,vtype): def getentrynode(self,senseid,showurl=False): return self.get('entry',senseid=senseid).get() def getsensenode(self,senseid,showurl=False): - return self.get('sense',senseid=senseid).get() + return self.get('sense',senseid=senseid).get()[0] def addmodexamplefields(self,**kwargs): log.info(_("Adding values (in lift.py) : {}").format(kwargs)) #These should always be there: From 7c86be50076f5dd911d4031525d6664523983a04 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:48:57 +0100 Subject: [PATCH 202/310] better default --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 32962997..4288eada 100644 --- a/lift.py +++ b/lift.py @@ -252,7 +252,7 @@ def addmodexamplefields(self,**kwargs): #These should always be there: senseid=kwargs.get('senseid') location=kwargs.get('location') - fieldtype=kwargs.get('fieldtype') # ever not 'tone'? + fieldtype=kwargs.get('fieldtype','tone') # needed? ever not 'tone'? exfieldvalue=self.get('example/field/form/text', path=['location','tonefield'], senseid=senseid, From ec18d55c3dab5a4f0623c39a3cf0248d43448f8a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:49:15 +0100 Subject: [PATCH 203/310] give a tone value --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 4288eada..627b1767 100644 --- a/lift.py +++ b/lift.py @@ -281,7 +281,8 @@ def addmodexamplefields(self,**kwargs): for lang in glosslangs: if lang != None and hasattr(forms,lang): fieldgloss.makeformnode(lang,getattr(forms,lang)) - exfieldvalue=p.makefieldnode(fieldtype,glosslangs[0],gimmetext=True) + exfieldvalue=p.makefieldnode(fieldtype,glosslangs[0],text=tonevalue, + gimmetext=True) p.makefieldnode('location',glosslangs[0],text=location) p.makefieldnode('tone',glosslangs[0],text=tonevalue) self.updatemoddatetime(senseid=senseid) From fc15142e35b7a0146c950f724d8606eeaa066a1b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:49:36 +0100 Subject: [PATCH 204/310] write --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 627b1767..427049ce 100644 --- a/lift.py +++ b/lift.py @@ -285,6 +285,7 @@ def addmodexamplefields(self,**kwargs): gimmetext=True) p.makefieldnode('location',glosslangs[0],text=location) p.makefieldnode('tone',glosslangs[0],text=tonevalue) + self.write() self.updatemoddatetime(senseid=senseid) def forminnode(self,node,value): """Returns True if `value` is in *any* text node child of any form child From bb7d85d7e2b63a1fda1736261d86ab9ef7c09cbe Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:49:57 +0100 Subject: [PATCH 205/310] return text, not text node --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 427049ce..890d61b9 100644 --- a/lift.py +++ b/lift.py @@ -808,7 +808,7 @@ def makeformnode(self,lang,text=None,gimmetext=False): if text is not None: nn.text=str(text) if gimmetext: - return nn + return nn.text def maketraitnode(self,type,value,gimmenode=False): n=Node(self,'trait',attrib={'name':type, 'value':str(value)}) if gimmenode: From ef7b1acd9ab10246cdfd12f0a594895f146d3908 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:50:44 +0100 Subject: [PATCH 206/310] remove redundant --- lift.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lift.py b/lift.py index 890d61b9..177b3075 100644 --- a/lift.py +++ b/lift.py @@ -284,7 +284,6 @@ def addmodexamplefields(self,**kwargs): exfieldvalue=p.makefieldnode(fieldtype,glosslangs[0],text=tonevalue, gimmetext=True) p.makefieldnode('location',glosslangs[0],text=location) - p.makefieldnode('tone',glosslangs[0],text=tonevalue) self.write() self.updatemoddatetime(senseid=senseid) def forminnode(self,node,value): From 7a56225927e7037d8083a1b21b3a2c7fc8930a86 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:51:00 +0100 Subject: [PATCH 207/310] want attr, not text --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 3b2273bf..f95e4639 100755 --- a/main.py +++ b/main.py @@ -3657,7 +3657,7 @@ def getexsall(self,value): #This returns all the senseids with a given tone value senseids=self.db.get("sense", location=self.name, path=['tonefield'], tonevalue=value - ).get('text') + ).get('senseid') senseidsincheck=self.senseidsincheck(senseids) return list(senseidsincheck) def getex(self,value,notonegroup=True,truncdefn=False,renew=False): From 099f196da576596abe3073ac5cd86f50fa5e098c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:52:54 +0100 Subject: [PATCH 208/310] use framed methods --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index f95e4639..74548df5 100755 --- a/main.py +++ b/main.py @@ -3685,8 +3685,8 @@ def getex(self,value,notonegroup=True,truncdefn=False,renew=False): framed=self.getframeddata(senseid, notonegroup=notonegroup, truncdefn=truncdefn) - if (framed[self.glosslang] is not None): framed['senseid']=self.exs[value] + if framed.glosses() is not None: output['framed']=framed #this includes [n], above return output else: @@ -4817,7 +4817,7 @@ def unsort(): log.error("Apparently the framed example for tone group {} in " "frame {} came back {}".format(group,self.name,example)) return - text=(framed['formatted']) + text=framed.formatted() """This should maybe be brought up a level in frames?""" bf=Frame(parent) bf.grid(column=column, row=row, sticky=sticky) From f75ab88157e40a768ea28150f7e0a60605eb0ee0 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:55:23 +0100 Subject: [PATCH 209/310] update langs for user changes during sorting --- main.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/main.py b/main.py index 74548df5..6f7ef621 100755 --- a/main.py +++ b/main.py @@ -6331,17 +6331,22 @@ def __init__(self): super(DictbyLang, self).__init__() self.framed={} class FramedDataDict(dict): + def updatelangs(self): + self.analang=self.check.analang + self.glosslangs=self.check.glosslangs + log.debug("analang: {}; glosslangs: {}".format(self.analang,self.glosslangs)) def getframeddata(self, source, **kwargs): + self.updatelangs() if source not in self: kwargs['db']=self.db self[source]=FramedData(self,source,**kwargs) + else: + self[source].updatelangs() return self[source] def __init__(self, check, **kwargs): super(FramedDataDict, self).__init__() self.frames=check.toneframes #[ps][name] self.db=check.db - self.analang=check.analang - self.glosslangs=check.glosslangs class FramedData(object): """This populates an object with attributes to format data for display, by senseid""" @@ -6420,12 +6425,15 @@ def parseexample(self,example): elif ((i.tag == 'field') and (i.get('type') == 'tone') and not self.notonegroup): self.tonegroups=i.findall('form/text') #always be list of one + def updatelangs(self): + self.analang=self.parent.analang + self.glosslangs=self.parent.glosslangs + log.debug("analang: {}; glosslangs: {}".format(self.analang,self.glosslangs)) def __init__(self, parent, source, **kwargs): super(FramedData, self).__init__() self.frames=parent.frames + self.updatelangs() self.db=parent.db #kwargs.pop('db',None) #not needed for examples - self.analang=parent.analang - self.glosslangs=parent.glosslangs self.location=kwargs.pop('location',None) #not needed for noframe """Generalize these, and manage with methods:""" # noframe=kwargs.pop('noframe',False) From 699f43c0ba27093e4c6603b87426f913fc706e55 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:55:53 +0100 Subject: [PATCH 210/310] method to get glosses (or None) --- main.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main.py b/main.py index 6f7ef621..c3ebb4d0 100755 --- a/main.py +++ b/main.py @@ -6425,6 +6425,15 @@ def parseexample(self,example): elif ((i.tag == 'field') and (i.get('type') == 'tone') and not self.notonegroup): self.tonegroups=i.findall('form/text') #always be list of one + l=0 + for lang in self.glosslangs: + if lang in self.forms: + g[lang]=self.forms[lang] + l+=len(g[lang]) + if l >0: + return g + else: + return None def updatelangs(self): self.analang=self.parent.analang self.glosslangs=self.parent.glosslangs From e8c164f1f901af55825d5274ffc38183b0f3429b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:56:25 +0100 Subject: [PATCH 211/310] make noframe and parent available later --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index c3ebb4d0..255d40ff 100755 --- a/main.py +++ b/main.py @@ -6440,12 +6440,13 @@ def updatelangs(self): log.debug("analang: {}; glosslangs: {}".format(self.analang,self.glosslangs)) def __init__(self, parent, source, **kwargs): super(FramedData, self).__init__() + self.parent=parent self.frames=parent.frames self.updatelangs() self.db=parent.db #kwargs.pop('db',None) #not needed for examples self.location=kwargs.pop('location',None) #not needed for noframe + self.noframe=kwargs.pop('noframe',False) """Generalize these, and manage with methods:""" - # noframe=kwargs.pop('noframe',False) # self.notonegroup=kwargs.pop('notonegroup',False) # truncdefn=kwargs.pop('truncdefn',False) # self.frame=kwargs.pop('frame',None) #not needed for noframe From b674f9d294fe48d18e13725f7d28feb721a5fb30 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:56:40 +0100 Subject: [PATCH 212/310] method to get glosses (or None) --- main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.py b/main.py index 255d40ff..eabbd970 100755 --- a/main.py +++ b/main.py @@ -6425,6 +6425,8 @@ def parseexample(self,example): elif ((i.tag == 'field') and (i.get('type') == 'tone') and not self.notonegroup): self.tonegroups=i.findall('form/text') #always be list of one + def glosses(self): + g=DictbyLang() l=0 for lang in self.glosslangs: if lang in self.forms: From 0606e07a6f8c5f03ad8a04b6161a027d9f1d8830 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 17:58:26 +0100 Subject: [PATCH 213/310] cleanup parsesense --- main.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/main.py b/main.py index eabbd970..0bed8326 100755 --- a/main.py +++ b/main.py @@ -6392,24 +6392,12 @@ def tonegroup(self): self.tonegroup=tonegroup #only for named groups def parsesense(self,db,senseid): self.senseid=senseid - lexs=db.lexemes(senseid=senseid) - cits=db.citations(senseid=senseid) - glss=db.glossesordefns(senseid=senseid) - for i in lexs: # (later) citation nodes will overwrite lex nodes - self.forms[i]=lexs[i] - for i in cits: - self.forms[i]=cits[i] - for i in glss: - self.forms[i]=glss[i] - if not self.notonegroup and self.location is not None: - self.tonegroups=self.db.get('example/field/form/text', - senseid=senseid, - # fieldtype='tone', - path=['tonefield'], - location=self.location).get('text') - else: - log.error("Location isn't set, but you asked for a tonegoup...") self.ps=unlist(db.ps(senseid=senseid)) #there should be just one + self.forms[self.analang]=db.citationorlexeme(senseid=senseid, + analang=self.analang) + self.forms.update(db.glossesordefns(senseid=senseid)) + for f in self.forms: + self.forms[f]=unlist(self.forms[f]) self.gettonegroup() def parseexample(self,example): self.senseid=None #We don't have access to this here From 1585f20b683f77498092235a61fdc04a7f5c2500 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 18:05:03 +0100 Subject: [PATCH 214/310] make check available to methods --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 0bed8326..abf71778 100755 --- a/main.py +++ b/main.py @@ -6347,6 +6347,7 @@ def __init__(self, check, **kwargs): super(FramedDataDict, self).__init__() self.frames=check.toneframes #[ps][name] self.db=check.db + self.check=check class FramedData(object): """This populates an object with attributes to format data for display, by senseid""" From b1f86d76c0ef9515031509dda9ba7334e6dda0e4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 18:06:45 +0100 Subject: [PATCH 215/310] framed methods --- main.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index abf71778..078529b3 100755 --- a/main.py +++ b/main.py @@ -3682,10 +3682,7 @@ def getex(self,value,notonegroup=True,truncdefn=False,renew=False): log.info("Using stored value for ‘{}’ group: ‘{}’".format( value, self.exs[value])) senseid=self.exs[value] - framed=self.getframeddata(senseid, - notonegroup=notonegroup, - truncdefn=truncdefn) - framed['senseid']=self.exs[value] + framed=self.datadict.getframeddata(senseid) if framed.glosses() is not None: output['framed']=framed #this includes [n], above return output @@ -3695,9 +3692,8 @@ def getex(self,value,notonegroup=True,truncdefn=False,renew=False): return output for i in range(len(senseids)): #just keep trying until you succeed senseid=senseids[randint(0, len(senseids))-1] - framed=self.getframeddata(senseid,notonegroup=notonegroup, - truncdefn=truncdefn) - if (framed[self.glosslang] is not None): + framed=self.datadict.getframeddata(senseid) + if framed.glosses() is not None: """As soon as you find one with form and gloss, quit.""" self.exs[value]=senseid framed['senseid']=senseid @@ -4813,6 +4809,7 @@ def unsort(): del self.exs[group] del kwargs['renew'] framed=example['framed'] + framed.setframe(self.name) if framed is None: log.error("Apparently the framed example for tone group {} in " "frame {} came back {}".format(group,self.name,example)) From 2b7fbb6a0037384b28cb8ef317eb1198ef31dc5e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 18:07:05 +0100 Subject: [PATCH 216/310] update tone value call --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 078529b3..f8461c04 100755 --- a/main.py +++ b/main.py @@ -4555,8 +4555,8 @@ def addtonefieldex(self,senseid,framed): fieldvalue=self.groupselected #, # ps=None #,showurl=True ) - tonegroup=firstoflist(self.db.get('exfieldvalue', senseid=senseid, - fieldtype='tone', location=self.name)) + tonegroup=unlist(self.db.get("text", senseid=senseid, location=self.name, + path=['tonefield'],showurl=True).get('text')) if tonegroup != self.groupselected: log.error("Field addition failed! LIFT says {}, not {}.".format( tonegroup,self.groupselected)) From 226f6268bf062cb2bb8c6ce7fb2ebf849f77571e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 18:07:40 +0100 Subject: [PATCH 217/310] redunant framed['senseid --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index f8461c04..2f2ce387 100755 --- a/main.py +++ b/main.py @@ -3696,7 +3696,7 @@ def getex(self,value,notonegroup=True,truncdefn=False,renew=False): if framed.glosses() is not None: """As soon as you find one with form and gloss, quit.""" self.exs[value]=senseid - framed['senseid']=senseid + # framed['senseid']=senseid output['framed']=framed #this includes [n], above return output else: From f80f7df93e9bd442bcbb6ca5ba1557f068e4ba3b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 18:09:39 +0100 Subject: [PATCH 218/310] clean up kwargs processing --- main.py | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/main.py b/main.py index 2f2ce387..fd3e6717 100755 --- a/main.py +++ b/main.py @@ -4775,39 +4775,21 @@ def unsort(): row=row,column=column,label=label, alwaysrefreshable=alwaysrefreshable, font=font, playable=playable,renew=True,refreshcount=refreshcount,**kwargs) - if 'font' not in kwargs: - font=self.fonts['read'] - else: - font=kwargs['font'] - del kwargs['font'] - if 'anchor' not in kwargs: - kwargs['anchor']='w' - if 'notonegroup' not in kwargs: - notonegroup=True - else: - notonegroup=kwargs['notonegroup'] - del kwargs['notonegroup'] - if 'refreshcount' not in kwargs: - refreshcount=0 - else: - refreshcount=kwargs['refreshcount']+1 - del kwargs['refreshcount'] - if 'sticky' not in kwargs: - sticky="ew" - else: - sticky=kwargs['sticky'] - del kwargs['sticky'] - example=self.getex(group,notonegroup=notonegroup,truncdefn=True,renew=renew) + font=kwargs.pop('font',self.fonts['read']) + kwargs['anchor']=kwargs.get('anchor','w') + notonegroup=kwargs.pop('notonegroup',True) + refreshcount=kwargs.pop('refreshcount',-1)+1 + sticky=kwargs.pop('sticky',"ew") + example=self.getex(group,notonegroup=notonegroup,renew=renew) if example is None: log.error("Apparently the example for tone group {} in frame {} " "came back {}".format(group,self.name,example)) return - if 'renew' in kwargs: - if kwargs['renew'] == True: - log.info("Resetting tone group example ({}): {} of {} examples" - "".format(group,self.exs[group],example['n'])) - del self.exs[group] - del kwargs['renew'] + renew=kwargs.pop('renew',False) + if renew is True: + log.info("Resetting tone group example ({}): {} of {} examples" + "".format(group,self.exs[group],example['n'])) + del self.exs[group] framed=example['framed'] framed.setframe(self.name) if framed is None: From afbdb3c5a737cc41942bc65ababb656fe015a9af Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Wed, 27 Oct 2021 18:09:51 +0100 Subject: [PATCH 219/310] new framed call --- main.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/main.py b/main.py index fd3e6717..b6a98af1 100755 --- a/main.py +++ b/main.py @@ -4147,17 +4147,7 @@ def testsorting(self): log.debug('self.tonegroups: {}'.format(status['groups'])) Label(titles, text=progress, font=self.fonts['report'], anchor='w' ).grid(column=1, row=0, sticky="ew") - if 'formatted' in framed: - text=framed.formatted(noframe=False)#(framed['formatted']) #notonegroup=True, - else: - text=_("Sorry; I can't find {}".format(framed)) - l=Label(self.runwindow.frame, text=text,font=self.fonts['readbig']) - l.grid(column=1,row=1, sticky="w",pady=50) - l.wrap() - scroll.destroy() - self.runwindow.waitdone() - self.runwindow.wait_window(window=l) - return 1 + text=framed.formatted(noframe=False) entryview=Frame(self.runwindow.frame) self.sorting=Label(entryview, text=text,font=self.fonts['readbig']) entryview.grid(column=1, row=1, sticky="new") From 8d8840ae932bc850a09d9adb5f6f4e645d2ffa73 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:03:53 +0100 Subject: [PATCH 220/310] no semicolons, for XLP --- rx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rx.py b/rx.py index 77d439b8..9eca4fd7 100644 --- a/rx.py +++ b/rx.py @@ -18,7 +18,7 @@ def urlok(x): def id(x): x=x.replace('˥','4').replace('˦','3').replace('˧','2' ).replace('˨','1').replace('˩','0') - return re.sub('[][  .!=\(\),\'/?ꞌ\n:+]','_',x) #remove charcters that are invalid for ids + return re.sub('[][  .!=\(\),\'/?ꞌ\n:;+]','_',x) #remove charcters that are invalid for ids def tonerxs(): return (re.compile('[˥˦˧˨˩]+', re.UNICODE), re.compile(' ', re.UNICODE), From 6b3f34b6f040ffe366266c3def17a95875382112 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:05:08 +0100 Subject: [PATCH 221/310] fix lift specification for frameddata --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 177b3075..483d537c 100644 --- a/lift.py +++ b/lift.py @@ -117,7 +117,7 @@ def get(self, target, node=None, **kwargs): for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"]).get('text')): """ if node is None: - node=self + node=self.nodes what=kwargs.get('what','node') path=kwargs.get('path',[]) if type(path) is not list: From 66aec235ec7e39bd5bf8407d0fda7a79895d2a09 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:06:03 +0100 Subject: [PATCH 222/310] rebase when different base of same tag to be used --- lift.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 483d537c..c0a1794a 100644 --- a/lift.py +++ b/lift.py @@ -127,6 +127,14 @@ def get(self, target, node=None, **kwargs): k=self.urlkey(kwargs) if k not in self.urls: self.urls[k]=LiftURL(base=node,**kwargs) #needs base and target to be sensible; attribute? + else: + log.info("URL key found, using: {} ({})".format(k,self.urls[k].url)) + if self.urls[k].base == node: + log.info("Same base {}, moving on.".format(node)) + else: + log.info("Different base of same tag ({}; {}≠{}), rebasing." + "".format(node.tag,self.urls[k].base,node)) + self.urls[k].rebase(node) if showurl: log.info("Using URL {}".format(self.urls[k].url)) return self.urls[k] #These are LiftURL objects @@ -1209,6 +1217,14 @@ def unalias(self,nodename): return nodename #else def getalias(self,nodename): return self.alias.get(nodename,nodename) + def rebase(self,rebase): + """This just changes the node set from which the url draws. + because different bases (within the whole lift file) would result in + the same URL, but not the same data, we need to tell this object which + base (e.g. which example) to take data from. This method should *not* + change type of base (e.g. from example to sense); that is for retarget. + """ + self.base=rebase def retarget(self,target): self.url=[self.url] self.target=target @@ -1401,8 +1417,6 @@ def setaliases(self): self.alias['ftype']='fieldtype' def __init__(self, *args,**kwargs): self.base=kwargs['base'] - if type(kwargs['base']) is Lift: - self.base=kwargs['base'].nodes basename=self.basename=self.base.tag super(LiftURL, self).__init__() log.info("LiftURL called with {}".format(kwargs)) From b342d295d1212d7c3dd771d60a6971b813930b31 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:06:17 +0100 Subject: [PATCH 223/310] testing --- lift.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lift.py b/lift.py index c0a1794a..9e8be383 100644 --- a/lift.py +++ b/lift.py @@ -2041,6 +2041,19 @@ def test(): # tonevalue=fieldvalue, # what='node') return + for senseid in senseids: + exnode=lift.get('example',showurl=True,senseid=senseid, + location=locations[1]).get() + print('exnode:',exnode) + # if len(exnode)>0: + prettyprint(exnode) + for e in exnode: + # print('e:',e) + # prettyprint(e) + audio=lift.get('form/text',node=e,showurl=True,#en-Zxxx-x-audio + analang='en-Zxxx-x-audio').get('text') + print('audio:',audio) + exit() g=lift.glossordefn(#self,guid, # senseid, analang='en', From e0485639531e4177869e0cc0eb1722d5e01f31d9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:06:42 +0100 Subject: [PATCH 224/310] make room for UF tonefield --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 9e8be383..01d380e1 100644 --- a/lift.py +++ b/lift.py @@ -1398,7 +1398,7 @@ def setchildren(self): self.children['entry']=['lexeme','pronunciation','sense', 'citation','morphtype','trait'] self.children['sense']=['ps','definition','gloss', - 'example','field'] + 'example','tonefield','field'] self.children['example']=['form','translation','locationfield', 'tonefield','field'] self.children['field']=['form'] From 2a6aa3ff98412219c8fd90d8009d929ca54dad80 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:08:34 +0100 Subject: [PATCH 225/310] split out maketextnode --- lift.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 01d380e1..7c66eca1 100644 --- a/lift.py +++ b/lift.py @@ -811,11 +811,15 @@ def makefieldnode(self,type,lang,text=None,gimmetext=False): return nn def makeformnode(self,lang,text=None,gimmetext=False): n=Node(self,'form',attrib={'lang':lang}) - nn=Node(n,'text') + nn=n.maketextnode(text,gimmetext=gimmetext) #Node(n,'text') + if gimmetext: + return nn + def maketextnode(self,text=None,gimmetext=False): + n=Node(self,'text') if text is not None: - nn.text=str(text) + n.text=str(text) if gimmetext: - return nn.text + return n.text def maketraitnode(self,type,value,gimmenode=False): n=Node(self,'trait',attrib={'name':type, 'value':str(value)}) if gimmenode: From cee0d9cd20ccafe60bb0d5a79b49174d605b6fb5 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:08:42 +0100 Subject: [PATCH 226/310] update --- lift.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 7c66eca1..32b188bd 100644 --- a/lift.py +++ b/lift.py @@ -369,9 +369,8 @@ def addmediafields(self,node, url,lang, showurl=False): if possible.text == url: log.debug("This one is already here; not adding.") return - form=ET.SubElement(node,'form',attrib={'lang':lang}) - t=ET.SubElement(form,'text') - t.text=url + form=Node(node,'form',attrib={'lang':lang}) + t=form.maketextnode(text=url) prettyprint(node) """Can't really do this without knowing what entry or sense I'm in...""" self.write() From f54a1b571411359d5a840219871020eab2601cef Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:09:30 +0100 Subject: [PATCH 227/310] more info for when needed --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 32b188bd..b2d1859c 100644 --- a/lift.py +++ b/lift.py @@ -364,7 +364,8 @@ def addmediafields(self,node, url,lang, showurl=False): log.info("Adding {} value to {} location".format(url,node)) possibles=node.findall("form[@lang='{lang}']/text".format(lang=lang)) for possible in possibles: - log.debug(possibles.index(possible)) + log.debug("Checking possible: {} (index: {})".format(possible, + possibles.index(possible))) if hasattr(possible,'text'): if possible.text == url: log.debug("This one is already here; not adding.") From 4f90b0ce3f4802c37980f7e6b09abe207698dcbf Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 15:18:22 +0100 Subject: [PATCH 228/310] old framed is not framed.forms --- main.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/main.py b/main.py index b6a98af1..4289664d 100755 --- a/main.py +++ b/main.py @@ -3563,9 +3563,11 @@ def wordsbypsprofilechecksubcheck(self,parent='NoXLPparent'): self.subcheck=subcheckori def idXLP(self,framed): id='x' #string! - bits=[self.ps,self.profile,self.name,self.subcheck,framed[self.analang]] - if self.glosslang in framed and framed[self.glosslang] is not None: - bits+=framed[self.glosslang] + bits=[self.ps,self.profile,self.name,self.subcheck, + framed.forms[self.analang]] + for lang in self.glosslangs: + if lang in framed.forms and framed.forms[lang] is not None: + bits+=framed.forms[lang] for x in bits: if x is not None: id+=x @@ -3581,18 +3583,18 @@ def framedtoXLP(self,framed,parent,listword=False,groups=True): else: exx=xlp.Example(parent,id) #the id goes here... ex=xlp.Word(exx) #This doesn't have an id - if self.audiolang in framed: - url=file.getdiredrelURL(self.reporttoaudiorelURL,framed[self.audiolang]) - el=xlp.LinkedData(ex,self.analang,framed[self.analang],str(url)) + if self.audiolang in framed.forms: + url=file.getdiredrelURL(self.reporttoaudiorelURL, + framed.forms[self.audiolang]) + el=xlp.LinkedData(ex,self.analang,framed.forms[self.analang], + str(url)) else: - el=xlp.LangData(ex,self.analang,framed[self.analang]) if 'tonegroup' in framed and groups is True: #joined groups show each elt=xlp.LangData(ex,self.analang,framed['tonegroup']) - if self.glosslang in framed: - eg=xlp.Gloss(ex,self.glosslang,framed[self.glosslang]) - if ((self.glosslang2 != None) and (self.glosslang2 in framed) - and (framed[self.glosslang2] is not None)): - eg2=xlp.Gloss(ex,self.glosslang2,framed[self.glosslang2]) + el=xlp.LangData(ex,self.analang,framed.forms[self.analang]) + for lang in self.glosslangs: + if lang in framed.forms: + xlp.Gloss(ex,lang,framed.forms[lang]) def makecountssorted(self): # This iterates across self.profilesbysense to provide counts for each # ps-profile combination (aggravated for profile='Invalid') @@ -5314,9 +5316,9 @@ def makeimg(): col=0 for lang in [self.analang, self.glosslang, self.glosslang2]: col+=1 - if lang in framed: + if lang in framed.forms: Label(self.results.scroll.content, - text=framed[lang], font=font, + text=framed.forms[lang], font=font, anchor='w',padx=10).grid(row=i, column=col, sticky='w') if self.su==True: @@ -5660,8 +5662,8 @@ def examplestoXLP(examples,parent,groups=True): groups=True #show groups on all non-default reports for example in examples: framed=self.getframeddata(example,noframe=True) - if not (framed[self.analang] is None and - framed[self.glosslang] is None):#glosslang2? + if not (framed.forms[self.analang] is None and + framed.forms[self.glosslang] is None):#glosslang2? self.framedtoXLP(framed,parent=parent,listword=True, groups=groups) log.info("Starting report...") @@ -7819,8 +7821,8 @@ def __init__(self,parent,check,id=None,node=None,test=False,**kwargs): self.db=check.db self.node=node #This should never be more than one node... framed=kwargs.pop('framed',None) #Either this or the next two... - self.form=kwargs.pop('form',framed.analang) - self.gloss=kwargs.pop('gloss',framed.glosslang) + self.form=kwargs.pop('form',framed.forms[check.analang]) + self.gloss=kwargs.pop('gloss',framed.forms[check.glosslang]) self.id=id self.check=check try: From ed041ec2350778edae86093f7e858e63ef9bd890 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 21:46:21 +0100 Subject: [PATCH 229/310] getframeddata to datadict.getframeddata --- main.py | 66 +++++++++++++++++++++++---------------------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/main.py b/main.py index 4289664d..ca2c158c 100755 --- a/main.py +++ b/main.py @@ -876,9 +876,10 @@ def submitform(): vars[idn].set(id) else: vars[idn].set(0) - framed=self.getframeddata(id, noframe=True) - log.debug("forms: {}".format(framed['formatted'])) - CheckButton(scroll.content, text = framed['formatted'], + framed=self.datadict.getframeddata(id) + forms=framed.formatted(noframe=True) + log.debug("forms: {}".format(forms)) + CheckButton(scroll.content, text = forms, variable = vars[allpssensids.index(id)], onvalue = id, offvalue = 0, ).grid(row=row,column=0,sticky='ew') @@ -1007,7 +1008,8 @@ def chk(): db['before'][lang]['text']+'__'+db['after'][lang]['text']) senseid=self.gimmesenseid() # This needs self.toneframes - framed=self.getframeddata(senseid,truncdefn=True) #after defn above, before below! + framed=self.datadict.getframeddata(senseid) + framed.setframe(self.name) #At this point, remove this frame (in case we don't submit it) del self.toneframes[self.ps][self.name] self.name=self.nameori @@ -3494,8 +3496,7 @@ def wordsbypsprofilechecksubcheckp(self,parent='NoXLPparent',t="NoText!"): for senseid in matches: for typenum in self.typenumsRun: self.basicreported[typenum].add(senseid) - framed=self.getframeddata(senseid,noframe=True) - print('\t',framed['formatted']) + framed=self.datadict.getframeddata(senseid) self.framedtoXLP(framed,parent=ex,listword=True) def wordsbypsprofilechecksubcheck(self,parent='NoXLPparent'): """This function iterates across self.name and self.subcheck values @@ -4326,14 +4327,9 @@ def verifybutton(self,parent,senseid,row,column=0,label=False,**kwargs): kwargs['font']=kwargs.get('font',self.fonts['read']) kwargs['anchor']=kwargs.get('anchor','w') #This should be pulling from the example, as it is there already - framed=FramedData(senseid,db=self.db, - frame=self.toneframes[self.ps][self.name], - location=self.name, analangs=[self.analang], - glosslangs=[self.glosslang,self.glosslang2], - notonegroup=True,truncdefn=True) - # framed=self.getframeddata(senseid,notonegroup=True,truncdefn=True) - text=framed.formatted - # text=(framed['formatted']) + framed=self.datadict.getframeddata(senseid) + framed.setframe(self.name) + text=framed.formatted(notonegroup=True) if label==True: b=Label(parent, text=text, **kwargs @@ -4959,8 +4955,8 @@ def record(self): else: self.showentryformstorecord() def makelabelsnrecordingbuttons(self,parent,sense): - t=self.getframeddata(sense['nodetoshow'],noframe=True)[ - self.analang]#+'\t'+sense['gloss'] + framed=self.datadict.getframeddata(sense['nodetoshow']) + t=framed.formatted(noframe=True) for g in ['gloss','gloss2']: if (g in sense) and (sense[g] is not None): t+='\t‘'+sense[g] @@ -5129,10 +5125,8 @@ def setskip(event): ) progressl.grid(row=0,column=2,sticky='ne') """This is the title for each page: isolation form and glosses.""" - titleframed=FramedData(senseid,db=self.db, - location=self.name, analangs=[self.analang], - glosslangs=[self.glosslang,self.glosslang2], - noframe=True,notonegroup=True,truncdefn=True) + titleframed=self.datadict.getframeddata(senseid) + titleframed.setframe(self.name) if titleframed.analang is None: entryframe.destroy() #is this ever needed? continue @@ -5151,9 +5145,7 @@ def setskip(event): lift.examplehaslangform(example,self.audiolang) == True): continue """These should already be framed!""" - framed=FramedData(example,analangs=[self.analang], - glosslangs=[self.glosslang,self.glosslang2], - noframe=True,truncdefn=True) + framed=self.datadict.getframeddata(example) if framed.analang is None: # when? continue row+=1 @@ -5284,9 +5276,8 @@ def getresults(self): for senseid in senseidstocheck: #self.senseidformstosearch[lang][ps] # where self.regex(self.senseidformstosearch[lang][ps][senseid]): """This regex is compiled!""" - framed=self.getframeddata(senseid,noframe=True) - # if self.regex(framed[self.analang]): - o=framed['formatted'] + framed=self.datadict.getframeddata(senseid) + o=framed.formatted(noframe=True) self.framedtoXLP(framed,parent=ex,listword=True) if self.debug ==True: o=entry.lexeme,entry.citation,nn(entry.gloss), @@ -5661,7 +5652,7 @@ def examplestoXLP(examples,parent,groups=True): if not default: groups=True #show groups on all non-default reports for example in examples: - framed=self.getframeddata(example,noframe=True) + framed=self.datadict.getframeddata(example) if not (framed.forms[self.analang] is None and framed.forms[self.glosslang] is None):#glosslang2? self.framedtoXLP(framed,parent=parent,listword=True, @@ -5813,9 +5804,9 @@ def output(window,r,text): e1=xlp.Example(s1,id,heading=headtext) for senseid in toreport[group]: #This is for window/text output only, not in XLP file - framed=self.getframeddata(senseid,noframe=True, - notonegroup=True) - text=framed['formatted'] + framed=self.datadict.getframeddata(senseid) + # framed.setframe(self.name) #not needed here, I think + text=framed.formatted(noframe=True,notonegroup=True) #This is put in XLP file: examples=self.db.get('examplebylocation', location=location, @@ -5829,9 +5820,9 @@ def output(window,r,text): else: for senseid in toreport[group]: #groups[group]['senseids']: #This is for window/text output only, not in XLP file - framed=self.getframeddata(senseid,noframe=True, - notonegroup=True) - text=framed['formatted'] + framed=self.datadict.getframeddata(senseid) + # framed.setframe(self.name) #not needed here, I think + text=framed.formatted(noframe=True, notonegroup=True) #This is put in XLP file: examples=self.db.get('example',senseid=senseid) log.log(2,"{} examples found: {}".format(len(examples), @@ -8504,12 +8495,9 @@ def returndictndestroy(self,parent,values): #Spoiler: the parent dies! def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): #?This is the action of a verification button, so needs to be self contained. #merge with addtonefieldex - framed=FramedData(senseid,db=self.db, - frame=self.toneframes[self.ps][self.name], - analangs=[self.analang], location=self.name, - glosslangs=[self.glosslang,self.glosslang2], - truncdefn=True) #noframe=True,notonegroup=True, - # framed=self.getframeddata(senseid,truncdefn=True) + framed=self.datadict.getframeddata(senseid) + framed.setframe(self.name) + text=framed.formatted(noframe=False) if name is None: name=self.name if subcheck is None: From 0da9f9b7060a756cb9b8c226f55907af45fc9299 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 21:49:54 +0100 Subject: [PATCH 230/310] senseidformsbyregex is now in check --- main.py | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/main.py b/main.py index ca2c158c..28580300 100755 --- a/main.py +++ b/main.py @@ -3456,9 +3456,7 @@ def wordsbypsprofilechecksubcheckp(self,parent='NoXLPparent',t="NoText!"): self.buildregex() log.log(2,"self.regex: {}; self.regexCV: {}".format(self.regex, self.regexCV)) - matches=set(self.db.senseidformsbyregex(self.regex, - self.analang, - ps=self.ps).keys()) + matches=set(self.senseidformsbyregex(self.regex)) for typenum in self.typenumsRun: # this removes senses already reported (e.g., in V1=V2) matches-=self.basicreported[typenum] @@ -5218,14 +5216,13 @@ def next(): text=_("Continue to next syllable profile"), command=next).grid(row=1,column=0) self.donewpyaudio() - def senseidformsbyregex(self,regex,analang,ps=None): #self is LIFT! - """make this a check method?""" - """This function takes in a ps and compiled regex, + def senseidformsbyregex(self,regex,): + """This function takes in a compiled regex, and outputs a list/dictionary of senseid/{senseid:form} form.""" output=[] #This is just a list of senseids now: (Do we need the dict?) - for form in self.formstosearch[ps]: + for form in self.formstosearch[self.ps]: if regex.search(form): - output+=self.formstosearch[ps][form] + output+=self.formstosearch[self.ps][form] return output def getresults(self): self.getrunwindow() @@ -5260,16 +5257,7 @@ def getresults(self): for self.subcheck in self.s[self.analang][self.type]: log.debug('self.subcheck: {}'.format(self.subcheck)) self.buildregex() #It would be nice fo this to iterate through... - # for senseid in self.profilesbysense[self.ps][self.profile]: - # print(self.profilesbysense[self.ps][self.profile][0]) - # print(self.db.citationorlexeme(self.profilesbysense[self.ps][self.profile][0])) - # print(firstoflist(self.db.citationorlexeme(self.profilesbysense[self.ps][self.profile][0]))) - senseidstocheck=self.senseidformsbyregex(self.regex, - self.analang, - ps=self.ps) - # senseidstocheck= filter(lambda x: self.regex.search( - # firstoflist(self.db.citationorlexeme(x))), - # self.profilesbysense[self.ps][self.profile]) + senseidstocheck=self.senseidformsbyregex(self.regex) if len(senseidstocheck)>0: id=rx.id('x'+self.ps+self.profile+self.name+self.subcheck) ex=xlp.Example(si,id) From 3dd882dcc59df3bd10463cc4eea3c00064ecd9e4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 21:52:20 +0100 Subject: [PATCH 231/310] must .get() from URL object --- main.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 28580300..d5ee4227 100755 --- a/main.py +++ b/main.py @@ -4593,7 +4593,7 @@ def gettoneUFgroups(self): #obsolete? toneUFgroups+=self.db.get('toneUFfieldvalue', senseid=senseid, fieldtype='tone' # Including any lang at this point. # ,showurl=True - ) + ).get('text') self.toneUFgroups=list(dict.fromkeys(toneUFgroups)) def gettonegroups(self): # This depends on self.ps, self.profile, and self.name @@ -4996,7 +4996,7 @@ def showentryformstorecordpage(self): sense['column']=0 sense['row']=row sense['guid']=firstoflist(self.db.get('guidbysense', - senseid=senseid)) + senseid=senseid).get('guid')) if sense['guid'] in done: #only the first of multiple senses continue else: @@ -5006,10 +5006,10 @@ def showentryformstorecordpage(self): adjusted here...""" sense['lxnode']=firstoflist(self.db.get('lexemenode', guid=sense['guid'], - lang=self.analang)) sense['lcnode']=firstoflist(self.db.get('citationnode', + lang=self.analang).get()) guid=sense['guid'], - lang=self.analang)) + lang=self.analang).get()) sense['gloss']=firstoflist(self.db.glossordefn( guid=sense['guid'], glosslang=self.glosslang @@ -5027,12 +5027,12 @@ def showentryformstorecordpage(self): sense['plnode']=firstoflist(self.db.get('fieldnode', guid=sense['guid'], lang=self.analang, - fieldtype=self.db.pluralname)) + fieldtype=self.db.pluralname).get()) if self.db.imperativename is not None: sense['impnode']=firstoflist(self.db.get('fieldnode', guid=sense['guid'], lang=self.analang, - fieldtype=self.db.imperativename)) + fieldtype=self.db.imperativename).get()) if sense['lcnode'] is not None: sense['nodetoshow']=sense['lcnode'] else: @@ -5100,7 +5100,7 @@ def setskip(event): for senseid in senses: log.debug("Working on {} with skip: {}".format(senseid, self.runwindow.frame.skip)) - examples=self.db.get('example',senseid=senseid) + examples=self.db.get('example',senseid=senseid).get() if examples == []: log.debug(_("No examples! Add some, then come back.")) continue @@ -5796,9 +5796,8 @@ def output(window,r,text): # framed.setframe(self.name) #not needed here, I think text=framed.formatted(noframe=True,notonegroup=True) #This is put in XLP file: - examples=self.db.get('examplebylocation', - location=location, - senseid=senseid) + examples=self.db.get('example',location=location, + senseid=senseid).get() examplestoXLP(examples,e1,groups=False) if text not in textout: output(window,r,text) @@ -5812,7 +5811,7 @@ def output(window,r,text): # framed.setframe(self.name) #not needed here, I think text=framed.formatted(noframe=True, notonegroup=True) #This is put in XLP file: - examples=self.db.get('example',senseid=senseid) + examples=self.db.get('example',senseid=senseid).get() log.log(2,"{} examples found: {}".format(len(examples), examples)) if examples != []: @@ -7727,7 +7726,7 @@ def makefilenames(self=None,check=None,senseid=None): log.log(4,"audio: {}".format(audio)) if gloss is None: gloss=t(check.db.get('gloss',senseid=senseid, - glosslang=check.glosslang)) + glosslang=check.glosslang).get('text')) if form is None and node is not None: form=t(node.find(f"form[@lang='{check.analang}']/text")) if audio != []: From 4dff039a8ed5453932f3117bcf0516aeb0ea59ff Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 21:57:29 +0100 Subject: [PATCH 232/310] upgrade lift calls --- main.py | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/main.py b/main.py index d5ee4227..297e38b4 100755 --- a/main.py +++ b/main.py @@ -2153,7 +2153,7 @@ def gimmeguid(self): idsbyps=self.db.get('guidbyps',lang=self.analang,ps=self.ps) return idsbyps[randint(0, len(idsbyps))] def gimmesenseid(self): - idsbyps=self.db.get('senseidbyps',lang=self.analang,ps=self.ps) + idsbyps=self.db.get('sense',ps=self.ps).get('senseid') return idsbyps[randint(0, len(idsbyps)-1)] def framenamesbyps(self,ps): """Names for all tone frames defined for the language.""" @@ -3379,8 +3379,8 @@ def getC(self,window,event=None): def getlocations(self): self.locations=[] for senseid in self.senseidstosort: - for location in self.db.get('exfieldlocation', - senseid=senseid, fieldtype='tone'): + for location in [i for i in self.db.get('locationfield', + senseid=senseid, showurl=True).get('text') if i is not None]: self.locations+=[location] self.locations=list(dict.fromkeys(self.locations)) def topprofiles(self,x='ALL'): @@ -4572,14 +4572,8 @@ def getsenseidsbytoneUFgroups(self): """Still working on one ps-profile combo at a time.""" self.getidstosort() #just in case this changed for senseid in self.senseidstosort: #I should be able to make this a regex... - toneUFgroup=firstoflist(self.db.get('toneUFfieldvalue', senseid=senseid, - fieldtype='tone' # Including any lang at this point. - # ,showurl=True - )) - if toneUFgroup not in sorted: - sorted[toneUFgroup]=[senseid] - else: - sorted[toneUFgroup]+=[senseid] + toneUFgroup=firstoflist(self.db.get('tonefield', senseid=senseid, + ).get('text')) self.toneUFgroups=list(dict.fromkeys(sorted)) log.debug("UFtonegroups (getsenseidsbytoneUFgroups): {}".format( self.toneUFgroups)) @@ -4590,8 +4584,8 @@ def gettoneUFgroups(self): #obsolete? toneUFgroups=[] """Still working on one ps-profile combo at a time.""" for senseid in self.senseidstosort: #I should be able to make this a regex... - toneUFgroups+=self.db.get('toneUFfieldvalue', senseid=senseid, - fieldtype='tone' # Including any lang at this point. + toneUFgroups+=self.db.get('text', senseid=senseid, #toneUFfieldvalue + path=['tonefield'],#fieldtype='tone' # Including any lang at this point. # ,showurl=True ).get('text') self.toneUFgroups=list(dict.fromkeys(toneUFgroups)) @@ -4995,7 +4989,8 @@ def showentryformstorecordpage(self): sense={} sense['column']=0 sense['row']=row - sense['guid']=firstoflist(self.db.get('guidbysense', + sense['senseid']=senseid + sense['guid']=firstoflist(self.db.get('entry', senseid=senseid).get('guid')) if sense['guid'] in done: #only the first of multiple senses continue @@ -5004,10 +4999,10 @@ def showentryformstorecordpage(self): """These following two have been shifted down a level, and will now return a list of form elements, each. Something will need to be adjusted here...""" - sense['lxnode']=firstoflist(self.db.get('lexemenode', + sense['lxnode']=firstoflist(self.db.get('lexeme', guid=sense['guid'], - sense['lcnode']=firstoflist(self.db.get('citationnode', lang=self.analang).get()) + sense['lcnode']=firstoflist(self.db.get('citation', guid=sense['guid'], lang=self.analang).get()) sense['gloss']=firstoflist(self.db.glossordefn( @@ -5024,12 +5019,12 @@ def showentryformstorecordpage(self): (('gloss2' in sense) and (sense['gloss2'] is None))): continue #We can't save the file well anyway; don't bother if self.db.pluralname is not None: - sense['plnode']=firstoflist(self.db.get('fieldnode', + sense['plnode']=firstoflist(self.db.get('field', guid=sense['guid'], lang=self.analang, fieldtype=self.db.pluralname).get()) if self.db.imperativename is not None: - sense['impnode']=firstoflist(self.db.get('fieldnode', + sense['impnode']=firstoflist(self.db.get('field', guid=sense['guid'], lang=self.analang, fieldtype=self.db.imperativename).get()) @@ -5547,8 +5542,8 @@ def tonegroupsbyUFlocation(self,senseidsbygroup): for location in locations: #just make them all, delete empty later values[group][location]=list() for senseid in senseidsbygroup[group]: - groupvalue=self.db.get("text", senseid=senseid, - location=location, path=['tonefield'] + groupvalue=self.db.get("tonefield", senseid=senseid, + location=location, ).get('text') if groupvalue != [None]: if unlist(groupvalue) not in values[group][location]: @@ -5571,9 +5566,9 @@ def tonegroupsbysenseidlocation(self): for senseid in self.senseidstosort: output[senseid]={} for location in locations: - group=self.db.get("text", senseid=senseid, location=location, - path=['tonefield']).get('text') if group != [None]: + group=self.db.get("tonefield", senseid=senseid, + location=location).get('text') output[senseid][location]=group #Save this info by senseid log.info("Done collecting groups by location for each senseid.") return output @@ -7721,9 +7716,9 @@ def makefilenames(self=None,check=None,senseid=None): analang=check.analang).get('text')) log.log(4,"gloss: {}".format(gloss)) log.log(4,"form: {}".format(form)) - audio=check.db.get('example/form/text',node=node,showurl=True, - analang=check.audiolang).get('text') log.log(4,"audio: {}".format(audio)) + audio=check.db.get('form/text',node=node,showurl=True, + analang=check.audiolang).get('text') if gloss is None: gloss=t(check.db.get('gloss',senseid=senseid, glosslang=check.glosslang).get('text')) @@ -8498,8 +8493,6 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): db=framed, fieldtype='tone',location=self.name, fieldvalue='') #this value should be the only change - tgroups=self.db.get("text", senseid=senseid, location=self.name, - path=['tonefield']).get('text') if type(tgroups) is list: if len(tgroups) > 1: log.error(_("Found {} tone values: {}".format(len(tgroups),tgroups))) @@ -8510,6 +8503,8 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): log.info("Field removal succeeded! LIFT says '{}', = ''.".format(tgroup)) else: log.error("Field removal failed! LIFT says '{}', != ''.".format(tgroup)) + tgroups=self.db.get("tonefield", senseid=senseid, location=self.name + ).get('text') rm=self.verifictioncode(name,subcheck) self.db.modverificationnode(senseid,vtype=self.profile,rm=rm) self.db.write() #This is not iterated over From c36f71dfcbd7fc7b45ce3c25cf9bb6950ad88cc9 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 21:59:24 +0100 Subject: [PATCH 233/310] fix framed calls --- main.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/main.py b/main.py index 297e38b4..77218180 100755 --- a/main.py +++ b/main.py @@ -1013,7 +1013,6 @@ def chk(): #At this point, remove this frame (in case we don't submit it) del self.toneframes[self.ps][self.name] self.name=self.nameori - print(frame,framed) """Display framed data""" if hasattr(self.addwindow,'framechk'): self.addwindow.framechk.destroy() @@ -1032,9 +1031,8 @@ def chk(): padx=padx,pady=pady) for lang in langs: row+=1 - print('frame[{}]:'.format(lang),frame[lang]) tf[lang]=('form[{}]: {}'.format(lang,frame[lang])) - tfd[lang]=('(ex: '+framed[lang]+')') + tfd[lang]=('(ex: '+framed.forms.framed[lang]+')') l1=Label(self.addwindow.framechk, text=tf[lang], font=self.fonts['read'], @@ -3588,9 +3586,9 @@ def framedtoXLP(self,framed,parent,listword=False,groups=True): el=xlp.LinkedData(ex,self.analang,framed.forms[self.analang], str(url)) else: - if 'tonegroup' in framed and groups is True: #joined groups show each - elt=xlp.LangData(ex,self.analang,framed['tonegroup']) el=xlp.LangData(ex,self.analang,framed.forms[self.analang]) + if hasattr(framed,'tonegroup') and groups is True: #joined groups show each + elt=xlp.LangData(ex,self.analang,framed.tonegroup) for lang in self.glosslangs: if lang in framed.forms: xlp.Gloss(ex,lang,framed.forms[lang]) @@ -5123,7 +5121,7 @@ def setskip(event): if titleframed.analang is None: entryframe.destroy() #is this ever needed? continue - text=titleframed.formatted + text=titleframed.formatted(noframe=True,notonegroup=True) Label(entryframe, anchor='w', font=self.fonts['read'], text=text).grid(row=row, column=0,sticky='w') @@ -5144,7 +5142,7 @@ def setskip(event): row+=1 """If I end up pulling from example nodes elsewhere, I should probably make this a function, like getframeddata""" - text=framed.formatted + text=framed.formatted(noframe=True) rb=RecordButtonFrame(examplesframe,self,id=senseid,node=example, framed=framed, # form=nn(framed.analang), From d84b2178a4e11954c112b5f69605e74e0b8d6964 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Thu, 28 Oct 2021 21:59:40 +0100 Subject: [PATCH 234/310] notes update --- lift.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lift.py b/lift.py index b2d1859c..ad35e2b5 100644 --- a/lift.py +++ b/lift.py @@ -114,7 +114,9 @@ def get(self, target, node=None, **kwargs): just 1 of each pss: dict.fromkeys(lift.get("ps").get('value')) get tone value: lift.get("text", location=location, path=['tonefield']).get('text') + lift.get("tonefield", senseid=senseid, location=self.name).get('text') for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"]).get('text')): + location: lift.get('locationfield', senseid=senseid, showurl=True).get('text') """ if node is None: node=self.nodes From 1218961fe16eb644267d452759e1de67e5e1bc53 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:28:29 +0100 Subject: [PATCH 235/310] update notes on calls --- lift.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index ad35e2b5..ac11373f 100644 --- a/lift.py +++ b/lift.py @@ -112,10 +112,12 @@ def get(self, target, node=None, **kwargs): lift.get("example/translation/form").get('text') lift.get("citation/form").get('text') just 1 of each pss: dict.fromkeys(lift.get("ps").get('value')) - get tone value: - lift.get("text", location=location, path=['tonefield']).get('text') + get tone value (from example): + lift.get('example/tonefield', senseid=senseid).get('text') lift.get("tonefield", senseid=senseid, location=self.name).get('text') - for tonevalue in dict.fromkeys(lift.get('text',path=["tonefield"]).get('text')): + get tone value (from sense, UF): + lift.get('tonefield', senseid=senseid).get('text') + lift.get('sense/tonefield', senseid=senseids[0],showurl=True).get('text') location: lift.get('locationfield', senseid=senseid, showurl=True).get('text') """ if node is None: From 2d60973528beb56af33b760acb42108a240767db Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:29:18 +0100 Subject: [PATCH 236/310] update to correct target --- lift.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index ac11373f..1e8fa221 100644 --- a/lift.py +++ b/lift.py @@ -265,11 +265,8 @@ def addmodexamplefields(self,**kwargs): senseid=kwargs.get('senseid') location=kwargs.get('location') fieldtype=kwargs.get('fieldtype','tone') # needed? ever not 'tone'? - exfieldvalue=self.get('example/field/form/text', - path=['location','tonefield'], - senseid=senseid, - fieldtype=fieldtype,location=location, - ).get('node') + exfieldvalue=self.get("tonefield", senseid=senseid, location=location + ).get('node') # Set values for any duplicates, too. Don't leave inconsisted data. tonevalue=kwargs.get('fieldvalue') #don't test for this above if len(exfieldvalue) > 0: From 07ae09a364c320fd08eabde5fa4b0f6c0c6f9ac4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:29:36 +0100 Subject: [PATCH 237/310] update to forms --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 1e8fa221..92cd6834 100644 --- a/lift.py +++ b/lift.py @@ -288,8 +288,8 @@ def addmodexamplefields(self,**kwargs): fields are being filled in in the glosslang language.""" fieldgloss=Node(p,'translation',attrib={'type':'Frame translation'}) for lang in glosslangs: - if lang != None and hasattr(forms,lang): - fieldgloss.makeformnode(lang,getattr(forms,lang)) + if lang in forms: + fieldgloss.makeformnode(lang,forms[lang]) exfieldvalue=p.makefieldnode(fieldtype,glosslangs[0],text=tonevalue, gimmetext=True) p.makefieldnode('location',glosslangs[0],text=location) From 406269bafd89250cb0d35499c52e8664a12096cd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:30:52 +0100 Subject: [PATCH 238/310] update usage of duplicate examples --- lift.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lift.py b/lift.py index 92cd6834..01a7fc4e 100644 --- a/lift.py +++ b/lift.py @@ -332,11 +332,18 @@ def findduplicateexamples(self): examples=sense.findall('example/field[@type="location"]/' 'form[text="{}"]/../..'.format(l)) #'senselocations' if len(examples)>1: - log.info("Found multiple examples of the same location ({})" - " in the same sense: {}".format(l, - [x.find('form/text').text for x in examples])) + log.error("Found multiple/duplicate examples (of the same " + "location ({}) in the same sense: {})" + "".format(l,[x.find('form/text').text for x in examples])) + """Before implementing the following, we need a test for + presence of audio file link, and different tone values, + including which to preserve if different (i.e., not '')""" + # for e in examples[1:]: + # sense.remove(e) dup=True - if not dup: + if dup: + pass #not yet: self.write() + else: log.info("No duplicate examples (same sense and location) were " "found in the lexicon.") def addtoneUF(self,senseid,group,analang,guid=None,showurl=False): From 42f7c86967cbd6eb9731dc2461523772fe8f14dd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:31:41 +0100 Subject: [PATCH 239/310] make it explicit when this has been done --- lift.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 01a7fc4e..3acd81b8 100644 --- a/lift.py +++ b/lift.py @@ -1012,6 +1012,9 @@ def tonefield(self): self.baselevel() self.kwargs['ftype']='tone' self.kwargs['formtext']='tonevalue' + """I assume we will never use sense/tonefield and example/tonefield + in the same url...""" + self.level['tonefield']=self.level['cur'] #so this won't repeat self.field() self.form("tonevalue",'glosslang') def morphtype(self,attrs={}): @@ -1309,7 +1312,10 @@ def usage(self): def shouldshow(self,node): c=self.getfamilyof(node,x=[]) # This fn is not called by showtargetinhighestgeneration or maketarget - if node == self.targethead: #do this later + if node in self.level: + log.info("No (done already).") + return False + elif node == self.targethead: #do this later log.log(4,"skipping node {}, in target:{}".format(node,self.target)) return False #not self.targetlastsibling() elif self.attrneeds(node,c): From cc6254c8998917d7bad2ef8dbbd2981921e518cb Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:32:44 +0100 Subject: [PATCH 240/310] aliases for basenames --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 3acd81b8..1483ae43 100644 --- a/lift.py +++ b/lift.py @@ -1435,7 +1435,8 @@ def setaliases(self): self.alias['ftype']='fieldtype' def __init__(self, *args,**kwargs): self.base=kwargs['base'] - basename=self.basename=self.base.tag + self.setaliases() + basename=self.basename=self.getalias(self.base.tag) super(LiftURL, self).__init__() log.info("LiftURL called with {}".format(kwargs)) self.kwargs=kwargs From 6b3ce9c3ac28b8b3f9d2a236b434133df3d65f1d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:32:53 +0100 Subject: [PATCH 241/310] testing --- lift.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lift.py b/lift.py index 1483ae43..e7bd9fdf 100644 --- a/lift.py +++ b/lift.py @@ -2060,6 +2060,10 @@ def test(): # tonevalue=fieldvalue, # what='node') return + for subcheck in range(5): + lift.get("sense", location=locations[0], tonevalue=subcheck, + path=['tonefield'],showurl=True).get('senseid') + exit() for senseid in senseids: exnode=lift.get('example',showurl=True,senseid=senseid, location=locations[1]).get() From 04805498990bbb42de0c4e12b3233b95cd508162 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:33:07 +0100 Subject: [PATCH 242/310] aliases for basenames --- lift.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lift.py b/lift.py index e7bd9fdf..c1c76e04 100644 --- a/lift.py +++ b/lift.py @@ -1448,7 +1448,6 @@ def __init__(self, *args,**kwargs): self.url=[] self.level={'cur':0,basename:0} self.guid=self.senseid=self.attrdonothing - self.setaliases() self.setattrsofnodes() self.bearchildrenof(basename) log.log(4,"Making Target now.") From 7a01fb4963936c0c6747c1488ed35b773d4f926d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:34:03 +0100 Subject: [PATCH 243/310] tagonly --- lift.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index c1c76e04..becb3497 100644 --- a/lift.py +++ b/lift.py @@ -1219,10 +1219,12 @@ def parsetargetlineage(self): "to not give the desired results. Fix this, and try again. (whole " "target: {})".format(self.targethead,self.target)) exit() + def tagonly(self,nodename): + return nodename.split('[')[0] def currentnodename(self): last=self.url[-1:] if len(last)>0: - n=last[0].split('[')[0] + n=self.tagonly(last[0]) return self.getalias(n) def unalias(self,nodename): if nodename in self.alias.values(): @@ -1275,7 +1277,7 @@ def maketarget(self): if self.targettail is not None: for b in self.targettail: n=self.targetbits.index(b) - bp=self.targetbits[n-1].split('[')[0]#just the node, not attrs + bp=self.tagonly(self.targetbits[n-1]) #.split('[')[0]#just the node, not attrs afterbp=self.drafturl().split(self.unalias(bp)) log.log(4,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) if len(afterbp) <=1 or b not in afterbp[1]: From 95be2e96566f742c01e48a9aeb44bde318249c1e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:34:41 +0100 Subject: [PATCH 244/310] alias --- lift.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lift.py b/lift.py index becb3497..9da4bd13 100644 --- a/lift.py +++ b/lift.py @@ -1213,7 +1213,8 @@ def parsetargetlineage(self): self.targethead=self.target self.targetbits=[self.targethead,] self.targettail=[] - if 'form' in self.targethead and 'form' not in self.children[self.basename]: + if 'form' in self.targethead and 'form' not in self.children[ + self.getalias(self.basename)]: log.error("Looking for {} as the head of a target is going to " "cause problems, as it appears in too many places, and is likely " "to not give the desired results. Fix this, and try again. (whole " From b2e15f35cc93fbff4fb3829296fedfb0864ea4ec Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:34:52 +0100 Subject: [PATCH 245/310] documentaiton --- lift.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lift.py b/lift.py index 9da4bd13..baba646a 100644 --- a/lift.py +++ b/lift.py @@ -560,6 +560,7 @@ def getsenseids(self): def getguids(self): self.guids=self.get('entry').get('guid') self.nguids=len(self.guids) + """Set up""" def nc(self): nounclasses="1 2 3 4 5 6 7 8 9 10 11 12 13 14" def clist(self): #This variable gives lists, to iterate over. @@ -701,6 +702,7 @@ def slists(self): # log.debug("Found the following forms to search: {}".format( # fts)) # return fts + """Get stuff""" def gloss(self,**kwargs): return self.get('gloss/text', **kwargs).get('text') def glosses(self,**kwargs): @@ -1228,12 +1230,14 @@ def currentnodename(self): n=self.tagonly(last[0]) return self.getalias(n) def unalias(self,nodename): + """This returns the names used in the LIFT file""" if nodename in self.alias.values(): for k in self.alias: if self.alias[k] == nodename: return k return nodename #else def getalias(self,nodename): + """This returns the names I typically use""" return self.alias.get(nodename,nodename) def rebase(self,rebase): """This just changes the node set from which the url draws. @@ -1316,11 +1320,9 @@ def shouldshow(self,node): c=self.getfamilyof(node,x=[]) # This fn is not called by showtargetinhighestgeneration or maketarget if node in self.level: - log.info("No (done already).") return False elif node == self.targethead: #do this later - log.log(4,"skipping node {}, in target:{}".format(node,self.target)) - return False #not self.targetlastsibling() + return False elif self.attrneeds(node,c): return True elif self.kwargsneeds(node,c): From 0a91100f29627547fceb741b2aae6c5953e77b15 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:35:56 +0100 Subject: [PATCH 246/310] don't include None --- main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.py b/main.py index 77218180..66dcfe16 100755 --- a/main.py +++ b/main.py @@ -4572,6 +4572,11 @@ def getsenseidsbytoneUFgroups(self): for senseid in self.senseidstosort: #I should be able to make this a regex... toneUFgroup=firstoflist(self.db.get('tonefield', senseid=senseid, ).get('text')) + if toneUFgroup is not None: + if toneUFgroup not in sorted: + sorted[toneUFgroup]=[senseid] + else: + sorted[toneUFgroup]+=[senseid] self.toneUFgroups=list(dict.fromkeys(sorted)) log.debug("UFtonegroups (getsenseidsbytoneUFgroups): {}".format( self.toneUFgroups)) From a92dabc56c51c959a25cf129b78dfe587c1da835 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:38:35 +0100 Subject: [PATCH 247/310] update to new calls --- main.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 66dcfe16..2f069769 100755 --- a/main.py +++ b/main.py @@ -4570,8 +4570,8 @@ def getsenseidsbytoneUFgroups(self): """Still working on one ps-profile combo at a time.""" self.getidstosort() #just in case this changed for senseid in self.senseidstosort: #I should be able to make this a regex... - toneUFgroup=firstoflist(self.db.get('tonefield', senseid=senseid, - ).get('text')) + toneUFgroup=firstoflist(self.db.get('sense/tonefield', + senseid=senseid).get('text')) if toneUFgroup is not None: if toneUFgroup not in sorted: sorted[toneUFgroup]=[senseid] @@ -4587,10 +4587,8 @@ def gettoneUFgroups(self): #obsolete? toneUFgroups=[] """Still working on one ps-profile combo at a time.""" for senseid in self.senseidstosort: #I should be able to make this a regex... - toneUFgroups+=self.db.get('text', senseid=senseid, #toneUFfieldvalue - path=['tonefield'],#fieldtype='tone' # Including any lang at this point. - # ,showurl=True - ).get('text') + toneUFgroups+=self.db.get('sense/tonefield', senseid=senseid + ).get('text') self.toneUFgroups=list(dict.fromkeys(toneUFgroups)) def gettonegroups(self): # This depends on self.ps, self.profile, and self.name @@ -4600,9 +4598,8 @@ def gettonegroups(self): log.log(3,"Looking for tone groups for {} frame".format(self.name)) tonegroups=[] for senseid in self.senseidstosort: #This is a ps-profile slice - tonegroup=self.db.get("text", path=['tonefield'], - senseid=senseid, location=self.name - ).get('text') + tonegroup=self.db.get("example/tonefield", senseid=senseid, + location=self.name).get('text') if unlist(tonegroup) in ['NA','','ALLOK', None]: log.error("tonegroup {} found in sense {} under location {}!" "".format(tonegroup,senseid,self.name)) @@ -4669,10 +4666,10 @@ def sortingstatus(self): self.senseidssorted=[] self.senseidsunsorted=[] for senseid in self.senseidstosort: - v=self.db.get("text", senseid=senseid, location=self.name, - path=['tonefield']).get('text') + v=unlist(self.db.get("tonefield", senseid=senseid, + location=self.name).get('text')) log.info("Found tone value: {}".format(v)) - if unlist(v) in ['',None]: + if v in ['',None]: self.senseidsunsorted+=[senseid] else: self.senseidssorted+=[senseid] @@ -6325,10 +6322,7 @@ def applyframe(self): self.framed=self.forms def gettonegroup(self): if self.location is not None: - self.tonegroups=self.db.get('example/field/form/text', - senseid=senseid, - # fieldtype='tone', - path=['tonefield'], + self.tonegroups=self.db.get('tonefield', senseid=senseid, location=self.location).get('text') def tonegroup(self): if self.tonegroups is not None: # wanted&found From 8e15d0260854f43795be527286c227ce9c5facbb Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:38:59 +0100 Subject: [PATCH 248/310] add framed (for gloss/form info) --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 2f069769..bb069c97 100755 --- a/main.py +++ b/main.py @@ -4959,8 +4959,8 @@ def makelabelsnrecordingbuttons(self,parent,sense): t+='’' lxl=Label(parent, text=t) lcb=RecordButtonFrame(parent,self,id=sense['guid'], #reconfigure! - node=sense['nodetoshow'], - gloss=sense['gloss']) + framed=framed,node=sense['nodetoshow'], + gloss=sense['gloss']) lcb.grid(row=sense['row'],column=sense['column'],sticky='w') lxl.grid(row=sense['row'],column=sense['column']+1,sticky='w') def showentryformstorecordpage(self): From c07fa0f49611d1f8adfd69a165c370f70b6e679a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:39:13 +0100 Subject: [PATCH 249/310] update to glosslangs --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index bb069c97..eb94ac06 100755 --- a/main.py +++ b/main.py @@ -5288,7 +5288,7 @@ def makeimg(): # window=self.runwindow.frame, # row=i, column=0, font=font, command=self.picked) col=0 - for lang in [self.analang, self.glosslang, self.glosslang2]: + for lang in [self.analang]+self.glosslangs: col+=1 if lang in framed.forms: Label(self.results.scroll.content, From b3cc49f5571f2de51fb802f75dfabe191f167f38 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:40:36 +0100 Subject: [PATCH 250/310] convert to empty list --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index eb94ac06..1d14320e 100755 --- a/main.py +++ b/main.py @@ -5545,7 +5545,7 @@ def tonegroupsbyUFlocation(self,senseidsbygroup): groupvalue=self.db.get("tonefield", senseid=senseid, location=location, ).get('text') - if groupvalue != [None]: + if groupvalue != []: if unlist(groupvalue) not in values[group][location]: values[group][location]+=groupvalue log.log(3,"values[{}][{}]: {}".format(group,location, @@ -5566,9 +5566,9 @@ def tonegroupsbysenseidlocation(self): for senseid in self.senseidstosort: output[senseid]={} for location in locations: - if group != [None]: group=self.db.get("tonefield", senseid=senseid, location=location).get('text') + if group != []: output[senseid][location]=group #Save this info by senseid log.info("Done collecting groups by location for each senseid.") return output From 5c54023b835da3887a3d2cce5c7412b4f44b0f54 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:41:34 +0100 Subject: [PATCH 251/310] remove redundant --- main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main.py b/main.py index 1d14320e..dd03468e 100755 --- a/main.py +++ b/main.py @@ -6282,7 +6282,6 @@ def updatelangs(self): def getframeddata(self, source, **kwargs): self.updatelangs() if source not in self: - kwargs['db']=self.db self[source]=FramedData(self,source,**kwargs) else: self[source].updatelangs() From 55c89b3091bfa9aa89f7395a538cb80590a1ba90 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:42:01 +0100 Subject: [PATCH 252/310] get the tonegroup if you can, in any case --- main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.py b/main.py index dd03468e..4ba4d3c0 100755 --- a/main.py +++ b/main.py @@ -6351,8 +6351,7 @@ def parseexample(self,example): for ii in i: if (ii.tag == 'form'): self.forms.getformfromnode(ii) #glosses - elif ((i.tag == 'field') and (i.get('type') == 'tone') and - not self.notonegroup): + elif ((i.tag == 'field') and (i.get('type') == 'tone')): self.tonegroups=i.findall('form/text') #always be list of one def glosses(self): g=DictbyLang() From 9d274c3d8ac212db6b1685e486fcffdcfca91a42 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:42:46 +0100 Subject: [PATCH 253/310] this always comes from check now --- main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.py b/main.py index 4ba4d3c0..229e70f2 100755 --- a/main.py +++ b/main.py @@ -6389,8 +6389,6 @@ def __init__(self, parent, source, **kwargs): """Build dual logic here. We use this to frame senses & examples""" if isinstance(source,lift.ET.Element): self.noframe=True #Examples should already be framed - if self.db is not None: - log.info("FYI: You specified database unnecessarily!") self.parseexample(source) #example element, not sense or entry: """This is what we're pulling from: From bdf3527c7968fd14e8be7b0e6b04edcdbb09c45f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:43:47 +0100 Subject: [PATCH 254/310] no database worries --- main.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/main.py b/main.py index 229e70f2..02b798da 100755 --- a/main.py +++ b/main.py @@ -6405,11 +6405,7 @@ def __init__(self, parent, source, **kwargs): """ elif type(source) is str and len(source) >= 36:#senseid can be guid+form - if self.db is not None: #pull from lift by senseid - self.parsesense(self.db,source) - else: - log.error("Can't pull entry ({}) w/o database!".format(source)) - return + self.parsesense(self.db,source) else: log.error('Neither Element nor senseid was found!' '\nThis is almost certainly not what you want!' From 1b5a352fa6a88ccc62edc0b3182ca575368e8b38 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:46:23 +0100 Subject: [PATCH 255/310] reset this --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 02b798da..ad457df9 100755 --- a/main.py +++ b/main.py @@ -7671,6 +7671,7 @@ def makefilenames(self=None,check=None,senseid=None): check=self.check id=self.id gloss=self.gloss + audio=None else: #self is None, i.e., this method called on something else. if None in [check, senseid]: return From f33dee880df7f2213dc6ea5452b43a8ca8a9f39b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:47:10 +0100 Subject: [PATCH 256/310] unlist --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index ad457df9..e7cdcc1a 100755 --- a/main.py +++ b/main.py @@ -7709,6 +7709,7 @@ def makefilenames(self=None,check=None,senseid=None): log.log(4,"audio: {}".format(audio)) audio=check.db.get('form/text',node=node,showurl=True, analang=check.audiolang).get('text') + audio=unlist(audio) if gloss is None: gloss=t(check.db.get('gloss',senseid=senseid, glosslang=check.glosslang).get('text')) From d1591ad02c46a8b797449f19776cd7e684ffce78 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:47:50 +0100 Subject: [PATCH 257/310] update no audio check --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index e7cdcc1a..2c2db29b 100755 --- a/main.py +++ b/main.py @@ -7715,8 +7715,8 @@ def makefilenames(self=None,check=None,senseid=None): glosslang=check.glosslang).get('text')) if form is None and node is not None: form=t(node.find(f"form[@lang='{check.analang}']/text")) - if audio != []: - filenameURL=str(file.getdiredurl(check.audiodir,audio.text)) + if audio is not None: + filenameURL=str(file.getdiredurl(check.audiodir,audio)) if file.exists(filenameURL): log.debug("Audio file found! using name: {}; diredname: {}" "".format(audio.text, filenameURL)) From c8be8b7d031b28443264ac80d3ab461ecfd05786 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:48:12 +0100 Subject: [PATCH 258/310] more log --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 2c2db29b..5cffaff5 100755 --- a/main.py +++ b/main.py @@ -5684,6 +5684,7 @@ def examplestoXLP(examples,parent,groups=True): valuesbylocation=dictofchilddicts(groupvalues,remove=['NA',None]) log.debug("groups (tonegroupreport): {}".format(grouplist)) log.debug("locations (tonegroupreport): {}".format(locations)) + log.debug("valuesbylocation: {}".format(valuesbylocation)) r = open(self.tonereportfile, "w", encoding='utf-8') title=_("Tone Report") self.runwindow.title(title) From 99814d7888232ee23341eca18678dd0e057e2849 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:48:40 +0100 Subject: [PATCH 259/310] conform audio --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 5cffaff5..07d4952f 100755 --- a/main.py +++ b/main.py @@ -7720,8 +7720,8 @@ def makefilenames(self=None,check=None,senseid=None): filenameURL=str(file.getdiredurl(check.audiodir,audio)) if file.exists(filenameURL): log.debug("Audio file found! using name: {}; diredname: {}" - "".format(audio.text, filenameURL)) - return audio.text + "".format(audio, filenameURL)) + return audio else: log.debug("Audio link found, but no file found! Making options." "\n{}; diredname: {}".format(audio, filenameURL)) From 01cf1f8a369bd95f1450021b008941b77317fc70 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:49:43 +0100 Subject: [PATCH 260/310] update audio log --- main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 07d4952f..b3e3d1dc 100755 --- a/main.py +++ b/main.py @@ -7771,8 +7771,10 @@ def makefilenames(self=None,check=None,senseid=None): #test if any of the generated filenames are there for filename in filenames: filenameURL=str(file.getdiredurl(check.audiodir,filename)) + log.debug("Looking for Audio file: {}; filename possibilities: {}; " + "url:{}".format(filename, filenames, filenameURL)) if file.exists(filenameURL): - log.debug("Audio file found! using name: {}; diredname: {}; " + log.debug("Audiofile found! using name: {}; possibilities: {}; " "url:{}".format(filename, filenames, filenameURL)) return filename #if you don't find any, take the *last* values From 96648872a9b0e2729450e997dfc1a53954c42833 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:50:33 +0100 Subject: [PATCH 261/310] fix string fns --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index b3e3d1dc..bcc8f971 100755 --- a/main.py +++ b/main.py @@ -8187,7 +8187,7 @@ def firstoflist(l,othersOK=False,all=False,ignore=[None]): if all == True: #don't worry about othersOK yet if len(l) > 1: ox=[t(v) for v in l[:len(l)-2]] #Should probably always give text - l=ox+[' and '.join([t(v) for v in l[len(l)-2:]])] + l=ox+[' and '.join([t(v) for v in l[len(l)-2:] if v not in ignore])] # for i in range(int(len(output)/2))] else: l[0]=t(l[0]) #for lists of a single element @@ -8202,7 +8202,7 @@ def t(element): if type(element) is str: return element elif element is None: - return + return str(None) else: try: return element.text From 4f14be787f44dceaadb346c0f06e537524510443 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:51:15 +0100 Subject: [PATCH 262/310] rework tone results reponse --- main.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/main.py b/main.py index bcc8f971..845f572e 100755 --- a/main.py +++ b/main.py @@ -8486,17 +8486,8 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): glosslang2=self.glosslang2, #OK if None db=framed, fieldtype='tone',location=self.name, - fieldvalue='') #this value should be the only change - if type(tgroups) is list: - if len(tgroups) > 1: - log.error(_("Found {} tone values: {}".format(len(tgroups),tgroups))) - return - else: - tgroup=tgroups[0] - if tgroup == '' : - log.info("Field removal succeeded! LIFT says '{}', = ''.".format(tgroup)) - else: - log.error("Field removal failed! LIFT says '{}', != ''.".format(tgroup)) + fieldvalue='',showurl=True) #this value should be the only change + log.info("Checking that removal worked") tgroups=self.db.get("tonefield", senseid=senseid, location=self.name ).get('text') rm=self.verifictioncode(name,subcheck) From 6b20a43273810feffd5cc9713ac0aa7d9c59a7e5 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 11:51:40 +0100 Subject: [PATCH 263/310] rework tone results response --- main.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/main.py b/main.py index 845f572e..08114a21 100755 --- a/main.py +++ b/main.py @@ -8490,6 +8490,16 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): log.info("Checking that removal worked") tgroups=self.db.get("tonefield", senseid=senseid, location=self.name ).get('text') + if tgroups == []: + log.info("Field removal succeeded! LIFT says '{}', = []." + "".format(tgroups)) + elif len(tgroups) == 1: + tgroup=tgroups[0] + log.error("Field removal failed! LIFT says '{}', != [].".format(tgroup)) + elif len(tgroups) > 1: + log.error(_("Found {} tone values: {}; Fix this!".format(len(tgroups), + tgroups))) + return rm=self.verifictioncode(name,subcheck) self.db.modverificationnode(senseid,vtype=self.profile,rm=rm) self.db.write() #This is not iterated over From b9e080d54bede2d223bae5fde9648e0565c1937a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:07:26 +0100 Subject: [PATCH 264/310] migrate to tonefield/form/text, be explicit about parent as sense or example --- main.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/main.py b/main.py index 08114a21..45993817 100755 --- a/main.py +++ b/main.py @@ -4570,7 +4570,7 @@ def getsenseidsbytoneUFgroups(self): """Still working on one ps-profile combo at a time.""" self.getidstosort() #just in case this changed for senseid in self.senseidstosort: #I should be able to make this a regex... - toneUFgroup=firstoflist(self.db.get('sense/tonefield', + toneUFgroup=firstoflist(self.db.get('sense/tonefield/form/text', senseid=senseid).get('text')) if toneUFgroup is not None: if toneUFgroup not in sorted: @@ -4587,8 +4587,8 @@ def gettoneUFgroups(self): #obsolete? toneUFgroups=[] """Still working on one ps-profile combo at a time.""" for senseid in self.senseidstosort: #I should be able to make this a regex... - toneUFgroups+=self.db.get('sense/tonefield', senseid=senseid - ).get('text') + toneUFgroups+=self.db.get('sense/tonefield/form/text', + senseid=senseid).get('text') self.toneUFgroups=list(dict.fromkeys(toneUFgroups)) def gettonegroups(self): # This depends on self.ps, self.profile, and self.name @@ -4598,8 +4598,8 @@ def gettonegroups(self): log.log(3,"Looking for tone groups for {} frame".format(self.name)) tonegroups=[] for senseid in self.senseidstosort: #This is a ps-profile slice - tonegroup=self.db.get("example/tonefield", senseid=senseid, - location=self.name).get('text') + tonegroup=self.db.get("example/tonefield/form/text", + senseid=senseid, location=self.name).get('text') if unlist(tonegroup) in ['NA','','ALLOK', None]: log.error("tonegroup {} found in sense {} under location {}!" "".format(tonegroup,senseid,self.name)) @@ -5542,9 +5542,9 @@ def tonegroupsbyUFlocation(self,senseidsbygroup): for location in locations: #just make them all, delete empty later values[group][location]=list() for senseid in senseidsbygroup[group]: - groupvalue=self.db.get("tonefield", senseid=senseid, - location=location, - ).get('text') + groupvalue=self.db.get("example/tonefield/form/text", + senseid=senseid, location=location, + ).get('text') if groupvalue != []: if unlist(groupvalue) not in values[group][location]: values[group][location]+=groupvalue @@ -5566,8 +5566,8 @@ def tonegroupsbysenseidlocation(self): for senseid in self.senseidstosort: output[senseid]={} for location in locations: - group=self.db.get("tonefield", senseid=senseid, - location=location).get('text') + group=self.db.get("example/tonefield/form/text", + senseid=senseid,location=location,showurl=True).get('text') if group != []: output[senseid][location]=group #Save this info by senseid log.info("Done collecting groups by location for each senseid.") @@ -6322,8 +6322,8 @@ def applyframe(self): self.framed=self.forms def gettonegroup(self): if self.location is not None: - self.tonegroups=self.db.get('tonefield', senseid=senseid, - location=self.location).get('text') + self.tonegroups=self.db.get('example/tonefield/form/text', + senseid=senseid, location=self.location).get('text') def tonegroup(self): if self.tonegroups is not None: # wanted&found tonegroup=unlist(self.tonegroups) From 87a14f3c7cb1793e5b04d14d9c3e910711a52b0a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:08:15 +0100 Subject: [PATCH 265/310] improved examples --- lift.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lift.py b/lift.py index baba646a..2bdc2f37 100644 --- a/lift.py +++ b/lift.py @@ -113,12 +113,11 @@ def get(self, target, node=None, **kwargs): lift.get("citation/form").get('text') just 1 of each pss: dict.fromkeys(lift.get("ps").get('value')) get tone value (from example): - lift.get('example/tonefield', senseid=senseid).get('text') - lift.get("tonefield", senseid=senseid, location=self.name).get('text') + lift.get("example/tonefield/form/text",location=location).get('text') get tone value (from sense, UF): - lift.get('tonefield', senseid=senseid).get('text') - lift.get('sense/tonefield', senseid=senseids[0],showurl=True).get('text') - location: lift.get('locationfield', senseid=senseid, showurl=True).get('text') + lift.get('tonefield/form/text', senseid=senseid).get('text') + lift.get('sense/tonefield/form/text', senseid=senseid).get('text') + location: lift.get('locationfield', senseid=senseid).get('text') """ if node is None: node=self.nodes From 35aeb071a12422bd7efd576ee22ed2b65a716b5d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:09:01 +0100 Subject: [PATCH 266/310] lower logging --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 2bdc2f37..60ba753c 100644 --- a/lift.py +++ b/lift.py @@ -133,9 +133,9 @@ def get(self, target, node=None, **kwargs): else: log.info("URL key found, using: {} ({})".format(k,self.urls[k].url)) if self.urls[k].base == node: - log.info("Same base {}, moving on.".format(node)) + log.log(4,"Same base {}, moving on.".format(node)) else: - log.info("Different base of same tag ({}; {}≠{}), rebasing." + log.log(4,"Different base of same tag ({}; {}≠{}), rebasing." "".format(node.tag,self.urls[k].base,node)) self.urls[k].rebase(node) if showurl: From 66fc4b701ab91cc7ebc3cc164ec59f4f781ec853 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:09:55 +0100 Subject: [PATCH 267/310] fix text values --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index 60ba753c..38435f43 100644 --- a/lift.py +++ b/lift.py @@ -945,9 +945,9 @@ def parent(self): def entry(self): self.build("entry","guid","guid") self.bearchildrenof("entry") - def text(self,value): + def text(self,value=None): self.baselevel() - self.build("text",myattr="value") + self.build("text",myattr=value) def form(self,value=None,lang=None): self.baselevel() self.kwargs['value']=self.kwargs.get(value,None) #location and tonevalue From 13263d314155f4abf56b9874ec087ee1a2e0ee83 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:10:09 +0100 Subject: [PATCH 268/310] make tonefield recognizeable in url --- lift.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lift.py b/lift.py index 38435f43..b385919a 100644 --- a/lift.py +++ b/lift.py @@ -1437,6 +1437,7 @@ def setaliases(self): self.alias['grammatical-info']='ps' self.alias['id']='senseid' self.alias['ftype']='fieldtype' + self.alias["field[@type='tone']"]='tonefield' def __init__(self, *args,**kwargs): self.base=kwargs['base'] self.setaliases() From d2b067e0a613b8548263cdca93c458b7feb4f746 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:11:54 +0100 Subject: [PATCH 269/310] check for last (not second), in case there are multiple --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index b385919a..903633ab 100644 --- a/lift.py +++ b/lift.py @@ -1284,8 +1284,8 @@ def maketarget(self): bp=self.tagonly(self.targetbits[n-1]) #.split('[')[0]#just the node, not attrs afterbp=self.drafturl().split(self.unalias(bp)) log.log(4,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) - if len(afterbp) <=1 or b not in afterbp[1]: log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) + if len(afterbp) <=1 or b not in afterbp[-1]: self.levelup(bp) self.show(b,parent=bp) self.levelup(self.targetbits[-1])#leave last in target, whatever else From 8fe2cf1c52a1c72f8201360866b184733028a0ab Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:13:18 +0100 Subject: [PATCH 270/310] add logging for late --- lift.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lift.py b/lift.py index 903633ab..73ffc110 100644 --- a/lift.py +++ b/lift.py @@ -1279,13 +1279,17 @@ def maketarget(self): self.showtargetinlowestancestry(i) # Either way, we finish by making the target tail, and leveling up. if self.targettail is not None: + log.log(4,"Adding targettail {} to url: {}".format(self.targettail, + self.drafturl())) for b in self.targettail: + log.log(4,"Adding targetbit {} to url: {}".format(b,self.drafturl())) n=self.targetbits.index(b) bp=self.tagonly(self.targetbits[n-1]) #.split('[')[0]#just the node, not attrs afterbp=self.drafturl().split(self.unalias(bp)) log.log(4,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) if len(afterbp) <=1 or b not in afterbp[-1]: + log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) self.levelup(bp) self.show(b,parent=bp) self.levelup(self.targetbits[-1])#leave last in target, whatever else From 15fe012f56ab8854f540455e1513ea854031e695 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:14:01 +0100 Subject: [PATCH 271/310] set a level value for tonefield so it won't show for both sense and example --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 73ffc110..b9c25ed9 100644 --- a/lift.py +++ b/lift.py @@ -1015,7 +1015,7 @@ def tonefield(self): self.kwargs['formtext']='tonevalue' """I assume we will never use sense/tonefield and example/tonefield in the same url...""" - self.level['tonefield']=self.level['cur'] #so this won't repeat + self.level['tonefield']=self.level['cur']+1 #so this won't repeat self.field() self.form("tonevalue",'glosslang') def morphtype(self,attrs={}): From 7803fc6a0d6127a0c2b3c411f5e9fbae8f2678c4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:14:38 +0100 Subject: [PATCH 272/310] rework tonefield so tonevalue only shows when there, allow text node to be there or not --- lift.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index b9c25ed9..ad2864ad 100644 --- a/lift.py +++ b/lift.py @@ -1012,12 +1012,16 @@ def locationfield(self): def tonefield(self): self.baselevel() self.kwargs['ftype']='tone' - self.kwargs['formtext']='tonevalue' """I assume we will never use sense/tonefield and example/tonefield in the same url...""" self.level['tonefield']=self.level['cur']+1 #so this won't repeat self.field() - self.form("tonevalue",'glosslang') + if 'tonevalue' in self.kwargs: + self.kwargs['formtext']='tonevalue' + self.form("tonevalue",'glosslang') + else: #dont' force a text node with no text value + self.kwargs['formtext']=None + self.form(lang='glosslang') def morphtype(self,attrs={}): if 'morphtype' in self.kwargs: attrs={'name':"morph-type",'value':self.kwargs[morphtype]} From bdefb46428b5b3c5d5877cce1b60727a35bb9e8f Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:14:49 +0100 Subject: [PATCH 273/310] testing --- lift.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index ad2864ad..73984369 100644 --- a/lift.py +++ b/lift.py @@ -2073,8 +2073,10 @@ def test(): # what='node') return for subcheck in range(5): - lift.get("sense", location=locations[0], tonevalue=subcheck, - path=['tonefield'],showurl=True).get('senseid') + lift.get("sense/tonefield", + senseid=senseids[0],showurl=True).get('text') + # lift.get("sense", location=locations[0], tonevalue=subcheck, + # path=['tonefield'],showurl=True).get('senseid') exit() for senseid in senseids: exnode=lift.get('example',showurl=True,senseid=senseid, From 9dd7a258d2737dee5da0898477067490672c9222 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:16:01 +0100 Subject: [PATCH 274/310] test remove getframeddata --- main.py | 294 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 147 insertions(+), 147 deletions(-) diff --git a/main.py b/main.py index 45993817..ff7607b8 100755 --- a/main.py +++ b/main.py @@ -2180,153 +2180,153 @@ def framevaluesbynamepsprofile(self,ps,profile,name): l+=group return list(dict.fromkeys(l)) """Mediating between LIFT and the user""" - def getframeddata(self,source,noframe=False,notonegroup=False,truncdefn=False): - """This generates a dictionary of form {'form':outputform, - 'gloss':outputgloss} for display, by senseid""" - """Sometimes this script is called to make the example fields, other - times to display it. If source is a senseid, it pulls form/gloss/etc - information from the entry. If source is an example, it pulls that info - from the example. The info is formatted uniformly in either case.""" - output={} - log.log(2,"{} {}".format(source, type(source))) - log.log(2,'self.glosslang: {}'.format(self.glosslang)) - log.log(2,'self.glosslang2: {}'.format(self.glosslang2)) - """Just in case there's a problem later...""" - forms={} - glosses={} - gloss={} - tonegroups=None - """Build dual logic here:""" - if isinstance(source,lift.ET.Element): - #This is an example element, not a sense or entry element... - element=source - for node in element: - if (node.tag == 'form') and ((node.get('lang') == self.analang) - or (node.get('lang') == self.audiolang)): - forms[node.get('lang')]=node.findall('text') - if (((node.tag == 'translation') and - (node.get('type') == 'Frame translation')) or - ((node.tag == 'gloss') and - (node.get('lang') == self.glosslang))): - for subnode in node: - if (subnode.tag == 'form'): - glosses[subnode.get('lang')]=subnode.findall('text') - if ((node.tag == 'field') and (node.get('type') == 'tone')): - #This should always be only one value: - tonegroups=node.findall('form/text') - log.log(2,'forms: {}'.format(forms)) - for lang in glosses: - log.log(2,'gloss[{}]: {}'.format(lang,glosses[lang])) - """convert from lists to single items without loosing data, - then pull text from nodes""" - if self.analang in forms: - form=t(firstoflist(forms[self.analang])) - else: - form=None - if self.audiolang in forms: - voice=t(firstoflist(forms[self.audiolang])) - else: - voice=None - for lang in glosses: - if (lang == self.glosslang) or (lang == self.glosslang2): - gloss[lang]=t(firstoflist(glosses[lang])) - """This is what we're pulling from: - - ga təv - -
lieu (m), place (f) (pl)
-
- -
1
-
- -
Plural
-
-
- """ - elif (type(source) is str): # and (len(source) == 36): #source is sensedid - #some dbs have senseids with form info, too... - #Asking for a sense, you get all tone groups, if self.name isn't set - log.log(3,'36 character senseid string!') - senseid=source - output['senseid']=senseid - forms[self.analang]=self.db.citation(senseid=senseid,#orlexeme - lang=self.analang, - ps=self.ps) - forms[self.audiolang]=self.db.citation(senseid=senseid, #orlexeme - lang=self.audiolang, - ps=self.ps) - for lang in [self.glosslang,self.glosslang2]: - if lang is not None: - glosses[lang]=self.db.glossordefn(senseid=senseid, - glosslang=lang,ps=self.ps) - #If frame is not defined (in self.name) this will output ALL values - #for this sense! - tonegroups=self.db.get('exfieldvalue', senseid=senseid, - fieldtype='tone', location=self.name) - """convert from lists to single items without loosing data""" - form=firstoflist(forms[self.analang]) - voice=firstoflist(forms[self.audiolang]) - for lang in glosses: - gloss[lang]=firstoflist(glosses[lang]) - log.log(2,'gloss[{}]: {}'.format(lang,gloss[lang])) - else: - log.error('Neither Element nor senseid was found!' - '\nThis is almost certainly not what you want!' - '\nFYI, I was looking for {}'.format(source)) - return source - log.log(2,'form: {}'.format(form)) - for lang in gloss: - log.log(2,'gloss:'.format(gloss[lang])) - """The following is the same for senses or examples""" - if notonegroup == False: - #If I haven't defined self.name nor set notonegroup=True, this will - # throw an error on a senseid above. - tonegroup=t(firstoflist(tonegroups)) - log.log(2,'tonegroup: {}'.format(tonegroup)) - if tonegroup is not None: - try: - int(tonegroup) - except: - output['tonegroup']=tonegroup #this is only for named groups - if self.glosslang2 in gloss and (self.glosslang2 is None or - gloss[self.glosslang2] is None): - del gloss[self.glosslang2] #remove this now, and lose checks later - output[self.analang]=None - for lang in list(gloss.keys())+[self.glosslang]: - output[lang]=None - text=('noform','nogloss') - if noframe == False: - frame=self.toneframes[self.ps][self.name] - """Forms and glosses have to be strings, or the regex fails""" - if form is None: - form=nn(form) #'noform' - for lang in gloss: - if gloss[lang] is None: - gloss[lang]=nn(gloss[lang]) #'nogloss' - log.log(2,frame) - output[self.analang]=rx.framerx.sub(form,frame[self.analang]) - for lang in gloss: - """only give these if the frame has this gloss, *and* if - the gloss is in the data (user selection is above)""" - if ((lang in frame) and (lang in gloss) and ( - None not in [gloss[lang],frame[lang]])): - output[lang]=rx.framerx.sub(gloss[lang],frame[lang]) - else: - output[self.analang]=nn(form) #for non-segmental forms - for lang in gloss: - output[lang]=gloss[lang] - if voice is not None: - output[self.audiolang]=voice - text=[str(output[self.analang]),"‘"+str(output[self.glosslang])+"’"] - if self.glosslang2 in output and output[self.glosslang2] is not None: - text+=["‘"+str(output[self.glosslang2])+"’"] - if 'tonegroup' in output: - text=[str(output['tonegroup'])]+text - output['formatted']=' '.join(text) #used to be '\t'... - if None in output: - log.error("Apparently None is an output key! {}".format(output)) - return output + # def getframeddata(self,source,noframe=False,notonegroup=False,truncdefn=False): + # """This generates a dictionary of form {'form':outputform, + # 'gloss':outputgloss} for display, by senseid""" + # """Sometimes this script is called to make the example fields, other + # times to display it. If source is a senseid, it pulls form/gloss/etc + # information from the entry. If source is an example, it pulls that info + # from the example. The info is formatted uniformly in either case.""" + # output={} + # log.log(2,"{} {}".format(source, type(source))) + # log.log(2,'self.glosslang: {}'.format(self.glosslang)) + # log.log(2,'self.glosslang2: {}'.format(self.glosslang2)) + # """Just in case there's a problem later...""" + # forms={} + # glosses={} + # gloss={} + # tonegroups=None + # """Build dual logic here:""" + # if isinstance(source,lift.ET.Element): + # #This is an example element, not a sense or entry element... + # element=source + # for node in element: + # if (node.tag == 'form') and ((node.get('lang') == self.analang) + # or (node.get('lang') == self.audiolang)): + # forms[node.get('lang')]=node.findall('text') + # if (((node.tag == 'translation') and + # (node.get('type') == 'Frame translation')) or + # ((node.tag == 'gloss') and + # (node.get('lang') == self.glosslang))): + # for subnode in node: + # if (subnode.tag == 'form'): + # glosses[subnode.get('lang')]=subnode.findall('text') + # if ((node.tag == 'field') and (node.get('type') == 'tone')): + # #This should always be only one value: + # tonegroups=node.findall('form/text') + # log.log(2,'forms: {}'.format(forms)) + # for lang in glosses: + # log.log(2,'gloss[{}]: {}'.format(lang,glosses[lang])) + # """convert from lists to single items without loosing data, + # then pull text from nodes""" + # if self.analang in forms: + # form=t(firstoflist(forms[self.analang])) + # else: + # form=None + # if self.audiolang in forms: + # voice=t(firstoflist(forms[self.audiolang])) + # else: + # voice=None + # for lang in glosses: + # if (lang == self.glosslang) or (lang == self.glosslang2): + # gloss[lang]=t(firstoflist(glosses[lang])) + # """This is what we're pulling from: + # + #
ga təv
+ # + #
lieu (m), place (f) (pl)
+ #
+ # + #
1
+ #
+ # + #
Plural
+ #
+ #
+ # """ + # elif (type(source) is str): # and (len(source) == 36): #source is sensedid + # #some dbs have senseids with form info, too... + # #Asking for a sense, you get all tone groups, if self.name isn't set + # log.log(3,'36 character senseid string!') + # senseid=source + # output['senseid']=senseid + # forms[self.analang]=self.db.citation(senseid=senseid,#orlexeme + # lang=self.analang, + # ps=self.ps) + # forms[self.audiolang]=self.db.citation(senseid=senseid, #orlexeme + # lang=self.audiolang, + # ps=self.ps) + # for lang in [self.glosslang,self.glosslang2]: + # if lang is not None: + # glosses[lang]=self.db.glossordefn(senseid=senseid, + # glosslang=lang,ps=self.ps) + # #If frame is not defined (in self.name) this will output ALL values + # #for this sense! + # tonegroups=self.db.get('exfieldvalue', senseid=senseid, + # fieldtype='tone', location=self.name) + # """convert from lists to single items without loosing data""" + # form=firstoflist(forms[self.analang]) + # voice=firstoflist(forms[self.audiolang]) + # for lang in glosses: + # gloss[lang]=firstoflist(glosses[lang]) + # log.log(2,'gloss[{}]: {}'.format(lang,gloss[lang])) + # else: + # log.error('Neither Element nor senseid was found!' + # '\nThis is almost certainly not what you want!' + # '\nFYI, I was looking for {}'.format(source)) + # return source + # log.log(2,'form: {}'.format(form)) + # for lang in gloss: + # log.log(2,'gloss:'.format(gloss[lang])) + # """The following is the same for senses or examples""" + # if notonegroup == False: + # #If I haven't defined self.name nor set notonegroup=True, this will + # # throw an error on a senseid above. + # tonegroup=t(firstoflist(tonegroups)) + # log.log(2,'tonegroup: {}'.format(tonegroup)) + # if tonegroup is not None: + # try: + # int(tonegroup) + # except: + # output['tonegroup']=tonegroup #this is only for named groups + # if self.glosslang2 in gloss and (self.glosslang2 is None or + # gloss[self.glosslang2] is None): + # del gloss[self.glosslang2] #remove this now, and lose checks later + # output[self.analang]=None + # for lang in list(gloss.keys())+[self.glosslang]: + # output[lang]=None + # text=('noform','nogloss') + # if noframe == False: + # frame=self.toneframes[self.ps][self.name] + # """Forms and glosses have to be strings, or the regex fails""" + # if form is None: + # form=nn(form) #'noform' + # for lang in gloss: + # if gloss[lang] is None: + # gloss[lang]=nn(gloss[lang]) #'nogloss' + # log.log(2,frame) + # output[self.analang]=rx.framerx.sub(form,frame[self.analang]) + # for lang in gloss: + # """only give these if the frame has this gloss, *and* if + # the gloss is in the data (user selection is above)""" + # if ((lang in frame) and (lang in gloss) and ( + # None not in [gloss[lang],frame[lang]])): + # output[lang]=rx.framerx.sub(gloss[lang],frame[lang]) + # else: + # output[self.analang]=nn(form) #for non-segmental forms + # for lang in gloss: + # output[lang]=gloss[lang] + # if voice is not None: + # output[self.audiolang]=voice + # text=[str(output[self.analang]),"‘"+str(output[self.glosslang])+"’"] + # if self.glosslang2 in output and output[self.glosslang2] is not None: + # text+=["‘"+str(output[self.glosslang2])+"’"] + # if 'tonegroup' in output: + # text=[str(output['tonegroup'])]+text + # output['formatted']=' '.join(text) #used to be '\t'... + # if None in output: + # log.error("Apparently None is an output key! {}".format(output)) + # return output def getframedentry(self,guid): """This is most likely obsolete""" """This generates output for selection and verification, by ps""" From a9fc7913c80ec070e68ed5fc4c441e82161f399d Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:22:24 +0100 Subject: [PATCH 275/310] updateexfieldvalue --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index ff7607b8..e0174b11 100755 --- a/main.py +++ b/main.py @@ -4480,8 +4480,8 @@ def updatebysubchecksenseid(self,oldtonevalue,newtonevalue,verified=False): # containst the field value) in the lift file. # This is all the words in the database with the given # location:value correspondence (any ps/profile) - lst2=self.db.get('senseidbyexfieldvalue',fieldtype='tone', - location=self.name,fieldvalue=oldtonevalue) + lst2=self.db.get('sense',location=self.name,tonevalue=oldtonevalue + ).get('senseid') # We are agnostic of verification status of any given entry, so don't # use this to change names, not to mark verification status (do that # with self.updatestatuslift()) From 706deb20095c7579a5ae7eb486b1331005daec5a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:22:42 +0100 Subject: [PATCH 276/310] t --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index e0174b11..85e3ea9b 100755 --- a/main.py +++ b/main.py @@ -4477,7 +4477,7 @@ def verify(): sameness will be verified and recorded.""" def updatebysubchecksenseid(self,oldtonevalue,newtonevalue,verified=False): # This function updates the field value and verification status (which - # containst the field value) in the lift file. + # contains the field value) in the lift file. # This is all the words in the database with the given # location:value correspondence (any ps/profile) lst2=self.db.get('sense',location=self.name,tonevalue=oldtonevalue From 76b74c352cbb89d48b5bdcd5909e5eb51966ad00 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:22:58 +0100 Subject: [PATCH 277/310] fix indent --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index 73984369..f5480c3e 100644 --- a/lift.py +++ b/lift.py @@ -1291,7 +1291,7 @@ def maketarget(self): bp=self.tagonly(self.targetbits[n-1]) #.split('[')[0]#just the node, not attrs afterbp=self.drafturl().split(self.unalias(bp)) log.log(4,"b: {}; bp: {}; afterbp: {}".format(b,bp,afterbp)) - log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) + log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) if len(afterbp) <=1 or b not in afterbp[-1]: log.log(4,"showing target element {}: {} (of {})".format(n,b,bp)) self.levelup(bp) From 6c48f0939bef30a1fa837d169f581f67102728dd Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:23:07 +0100 Subject: [PATCH 278/310] testing --- lift.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index f5480c3e..5956e2ad 100644 --- a/lift.py +++ b/lift.py @@ -2073,8 +2073,9 @@ def test(): # what='node') return for subcheck in range(5): - lift.get("sense/tonefield", - senseid=senseids[0],showurl=True).get('text') + b=lift.get('sense',fieldtype='tone',location=locations[0], + tonevalue=subcheck,showurl=True).get('senseid') + print(b) # lift.get("sense", location=locations[0], tonevalue=subcheck, # path=['tonefield'],showurl=True).get('senseid') exit() From 6b396c6c8d4a2165ffed3fd8e8c2df6496b76dc1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:31:43 +0100 Subject: [PATCH 279/310] make sure senseid is there --- main.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 85e3ea9b..10d7fd2b 100755 --- a/main.py +++ b/main.py @@ -3683,6 +3683,7 @@ def getex(self,value,notonegroup=True,truncdefn=False,renew=False): senseid=self.exs[value] framed=self.datadict.getframeddata(senseid) if framed.glosses() is not None: + output['senseid']=senseid output['framed']=framed #this includes [n], above return output else: @@ -3695,7 +3696,7 @@ def getex(self,value,notonegroup=True,truncdefn=False,renew=False): if framed.glosses() is not None: """As soon as you find one with form and gloss, quit.""" self.exs[value]=senseid - # framed['senseid']=senseid + output['senseid']=senseid output['framed']=framed #this includes [n], above return output else: @@ -4785,7 +4786,7 @@ def unsort(): b.grid(column=1, row=0, sticky="ew", ipady=15) #Inside the buttons elif playable == True: url=RecordButtonFrame.makefilenames(None,self, #not Classy... - framed['senseid']) + example['senseid']) diredurl=str(file.getdiredurl(self.audiodir,url)) thefileisthere=file.exists(diredurl) log.info("fileisthere: {} ({})".format(diredurl,url)) From 7e1a79c128e70c10bd3904566a9a6997df6a4464 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:31:56 +0100 Subject: [PATCH 280/310] move audio call to where it is --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 10d7fd2b..bac0d64a 100755 --- a/main.py +++ b/main.py @@ -7708,9 +7708,9 @@ def makefilenames(self=None,check=None,senseid=None): analang=check.analang).get('text')) log.log(4,"gloss: {}".format(gloss)) log.log(4,"form: {}".format(form)) - log.log(4,"audio: {}".format(audio)) audio=check.db.get('form/text',node=node,showurl=True, analang=check.audiolang).get('text') + log.log(4,"audio: {}".format(audio)) audio=unlist(audio) if gloss is None: gloss=t(check.db.get('gloss',senseid=senseid, From dbb7b9dff1bd3d2832e7c68225a4dd2cfe5bedf3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 13:32:11 +0100 Subject: [PATCH 281/310] unnecessary, I think --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index bac0d64a..28e25654 100755 --- a/main.py +++ b/main.py @@ -7673,7 +7673,7 @@ def makefilenames(self=None,check=None,senseid=None): check=self.check id=self.id gloss=self.gloss - audio=None + # audio=None else: #self is None, i.e., this method called on something else. if None in [check, senseid]: return From 7fdfafed9347c94c62316254c37b94e1e0347608 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:16:05 +0100 Subject: [PATCH 282/310] new evaluatenode fn --- lift.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lift.py b/lift.py index 5956e2ad..b2f24e98 100644 --- a/lift.py +++ b/lift.py @@ -204,26 +204,27 @@ def addentry(self, showurl=False, **kwargs): self.getguids() self.getsenseids() return senseid - def modverificationnode(self,senseid,vtype,add=None,rm=None,addifrmd=False): - nodes=self.addverificationnode(senseid,vtype=vtype) - vf=nodes[0] - sensenode=nodes[1] - if vf is None: - log.info("Sorry, this didn't return a node: {}".format(senseid)) + def evaluatenode(self,node): + if node is None: + log.info("Sorry, this didn't return a node: {}".format(node)) return - if vf.text is not None: - log.log(2,"{}; {}".format(vf.text, type(vf.text))) + if node.text is not None: try: - l=ast.literal_eval(vf.text) + l=ast.literal_eval(node.text) except SyntaxError: #if the literal eval doesn't work, it's a string - l=vf.text - log.log(2,"{}; {}".format(l, type(l))) + l=node.text if type(l) != list: #in case eval worked, but didn't produce a list log.log(2,"One item: {}; {}".format(l, type(l))) l=[l,] else: log.log(2,"empty verification list found") l=list() + return l + def modverificationnode(self,senseid,vtype,add=None,rms=[],addifrmd=False): + nodes=self.addverificationnode(senseid,vtype=vtype) + vf=nodes[0] + sensenode=nodes[1] + l=self.evaluatenode(vf) changed=False if rm != None and rm in l: i=l.index(rm) #be ready to replace From ba7f23ea32a97b18daaf35fc6f1a3cf9425a2741 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:16:19 +0100 Subject: [PATCH 283/310] getverificationnodevaluebyframe --- lift.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lift.py b/lift.py index b2f24e98..e598015f 100644 --- a/lift.py +++ b/lift.py @@ -245,6 +245,19 @@ def modverificationnode(self,senseid,vtype,add=None,rms=[],addifrmd=False): sensenode.remove(vf) else: log.log(2,"Not removing empty node") + def getverificationnodevaluebyframe(self,senseid,vtype,frame): + nodes=self.addverificationnode(senseid,vtype=vtype) + vf=nodes[0] + # sensenode=nodes[1] + l=self.evaluatenode(vf) + log.info("text: {}; vf: {}".format(l,vf)) + values=[] + if l is not None: + for field in l: + log.info("field value: {}".format(field)) + if frame in field: + values.append(field) + return values def addverificationnode(self,senseid,vtype): node=self.getsensenode(senseid=senseid) if node is None: From afa0179d173b8cc1dc7c1feea8ccbf394a603c72 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:16:33 +0100 Subject: [PATCH 284/310] fix tonefield --- lift.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lift.py b/lift.py index e598015f..9bbb0cad 100644 --- a/lift.py +++ b/lift.py @@ -278,8 +278,8 @@ def addmodexamplefields(self,**kwargs): senseid=kwargs.get('senseid') location=kwargs.get('location') fieldtype=kwargs.get('fieldtype','tone') # needed? ever not 'tone'? - exfieldvalue=self.get("tonefield", senseid=senseid, location=location - ).get('node') + exfieldvalue=self.get("example/tonefield/form/text", senseid=senseid, + location=location).get('node') # Set values for any duplicates, too. Don't leave inconsisted data. tonevalue=kwargs.get('fieldvalue') #don't test for this above if len(exfieldvalue) > 0: From d1fc5bf4af3ba0d0e8336ad097eae216f82cf5c3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:17:02 +0100 Subject: [PATCH 285/310] make room for multiple removes --- lift.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lift.py b/lift.py index 9bbb0cad..e3310af9 100644 --- a/lift.py +++ b/lift.py @@ -226,12 +226,12 @@ def modverificationnode(self,senseid,vtype,add=None,rms=[],addifrmd=False): sensenode=nodes[1] l=self.evaluatenode(vf) changed=False - if rm != None and rm in l: - i=l.index(rm) #be ready to replace - l.remove(rm) - changed=True - else: - i=len(l) + i=len(l) + for rm in rms: + if rm != None and rm in l: + i=l.index(rm) #be ready to replace + l.remove(rm) + changed=True if (add != None and add not in l #if there, v-if rmd, or not changing and (addifrmd == False or changed == True)): l.insert(i,add) #put where removed from, if done. From 492f503e0fe34a94d4ddebcc2ccf1208812e08e3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:17:21 +0100 Subject: [PATCH 286/310] log --- lift.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lift.py b/lift.py index e3310af9..a814493c 100644 --- a/lift.py +++ b/lift.py @@ -225,6 +225,8 @@ def modverificationnode(self,senseid,vtype,add=None,rms=[],addifrmd=False): vf=nodes[0] sensenode=nodes[1] l=self.evaluatenode(vf) + log.log(2,"{}; {}".format(vf.text, type(vf.text))) + log.log(2,"{}; {}".format(l, type(l))) changed=False i=len(l) for rm in rms: From 49892f5dbe44492992550a3094a85660f55f53e4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:18:39 +0100 Subject: [PATCH 287/310] don't mod verify lift nodes on joinT --- main.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/main.py b/main.py index 28e25654..7a524fbd 100755 --- a/main.py +++ b/main.py @@ -4345,12 +4345,6 @@ def verifybutton(self,parent,senseid,row,column=0,label=False,**kwargs): ipady=15 #Inside the buttons... ) def joinT(self): - def verify(): - groups=self.status[self.type][self.ps][self.profile][self.name][ - 'groups'] - for group in groups: - self.updatestatuslift(self.name,group,verified=True) - self.db.write() #after iterating log.info("Running joinT!") """This window shows up after sorting, or maybe after verification, to allow the user to join groups that look the same. I think before @@ -4423,7 +4417,6 @@ def verify(): if self.groupselected == "ALLOK": print(f"User selected ‘{oktext}’, moving on.") delattr(self,'groupselected') - verify() return 0 else: group1=self.groupselected @@ -4454,7 +4447,6 @@ def verify(): if self.groupselected == "ALLOK": print(f"User selected ‘{oktext}’, moving on.") delattr(self,'groupselected') - verify() return 0 else: msg=_("Now we're going to move group ‘{0}’ into " From 257f9ae5e3f27cc16237aa17d8ee19e22ef64ef4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:19:17 +0100 Subject: [PATCH 288/310] fix tonefield --- main.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index 7a524fbd..b0d6a672 100755 --- a/main.py +++ b/main.py @@ -4532,8 +4532,8 @@ def addtonefieldex(self,senseid,framed): fieldvalue=self.groupselected #, # ps=None #,showurl=True ) - tonegroup=unlist(self.db.get("text", senseid=senseid, location=self.name, - path=['tonefield'],showurl=True).get('text')) + tonegroup=unlist(self.db.get("example/tonefield/form/text", + senseid=senseid, location=self.name).get('text')) if tonegroup != self.groupselected: log.error("Field addition failed! LIFT says {}, not {}.".format( tonegroup,self.groupselected)) @@ -4659,7 +4659,7 @@ def sortingstatus(self): self.senseidssorted=[] self.senseidsunsorted=[] for senseid in self.senseidstosort: - v=unlist(self.db.get("tonefield", senseid=senseid, + v=unlist(self.db.get("example/tonefield/form/text", senseid=senseid, location=self.name).get('text')) log.info("Found tone value: {}".format(v)) if v in ['',None]: @@ -8481,9 +8481,9 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): fieldtype='tone',location=self.name, fieldvalue='',showurl=True) #this value should be the only change log.info("Checking that removal worked") - tgroups=self.db.get("tonefield", senseid=senseid, location=self.name - ).get('text') - if tgroups == []: + tgroups=self.db.get("example/tonefield/form/text", senseid=senseid, + location=self.name).get('text') + if tgroups in [[],'']: log.info("Field removal succeeded! LIFT says '{}', = []." "".format(tgroups)) elif len(tgroups) == 1: From df166c32465805c8078b50e8207149251fdf43cc Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:19:55 +0100 Subject: [PATCH 289/310] multiple rms for modverificationnode --- main.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index b0d6a672..15ef8152 100755 --- a/main.py +++ b/main.py @@ -1710,12 +1710,16 @@ def updatestatuslift(self,name=None,subcheck=None,verified=False,refresh=True): value=self.verifictioncode(name,subcheck) if verified == True: add=value - rm=None + rms=[] else: add=None - rm=value + rms=[value] for senseid in self.senseidsincheck(senseids): #only for this ps-profile - self.db.modverificationnode(senseid,vtype=self.profile,add=add,rm=rm) + rms+=self.db.getverificationnodevaluebyframe(senseid, + vtype=self.profile, frame=name) + log.info("Removing {}".format(rms)) + self.db.modverificationnode(senseid,vtype=self.profile,add=add, + rms=rms) if refresh == True: self.db.write() #for when not iterated over, or on last repeat def updatestatus(self,subcheck=None,verified=False,refresh=True): @@ -4491,7 +4495,7 @@ def updatebysubchecksenseid(self,oldtonevalue,newtonevalue,verified=False): location=self.name,#fieldvalue=oldtonevalue, fieldvalue=newtonevalue) self.db.modverificationnode(senseid=senseid,vtype=self.profile, - add=add,rm=rm,addifrmd=True) + add=add,rms=[rm],addifrmd=True) self.db.write() #once done iterating over senseids def addtonegroup(self): log.info("Adding a tone group!") @@ -8494,7 +8498,7 @@ def removesenseidfromsubcheck(self,parent,senseid,name=None,subcheck=None): tgroups))) return rm=self.verifictioncode(name,subcheck) - self.db.modverificationnode(senseid,vtype=self.profile,rm=rm) + self.db.modverificationnode(senseid,vtype=self.profile,rms=[rm]) self.db.write() #This is not iterated over self.markunsortedsenseid(senseid) #This is just for self.status['sorted'] parent.destroy() #.runwindow.resetframe() From 1e1031a859995daea15e7c1d6069b6b61e41e15c Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:20:25 +0100 Subject: [PATCH 290/310] to lift status first --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 15ef8152..896fa663 100755 --- a/main.py +++ b/main.py @@ -4463,11 +4463,11 @@ def joinT(self): self.status[self.type][self.ps][self.profile][ self.name]['groups'].remove(group1) self.subcheck=group1 + self.updatestatuslift(refresh=False) #done above self.updatestatus(refresh=False) #not verified=True --since joined. - # self.updatestatuslift(refresh=False) #done above self.subcheck=self.groupselected + self.updatestatuslift() #done above self.updatestatus() #not verified=True --since joined. - # self.updatestatuslift() #done above self.maybesort() #go back to verify, etc. """'These are all different' doesn't need to be saved anywhere, as this can happen at any time. Just move on to verification, where each group's From 69d1d096d2431bb1aa68fcbc259b05f439b8250a Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:21:44 +0100 Subject: [PATCH 291/310] verify in LIFT at the end of verifyT --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 896fa663..fe8d85b8 100755 --- a/main.py +++ b/main.py @@ -4312,6 +4312,7 @@ def verifyT(self,menu=False): elif self.groupselected == "ALLOK": log.debug("User selected ‘{}’, moving on.".format(oktext)) self.updatestatus(verified=True) + self.updatestatuslift(self.name,self.subcheck,verified=True) # self.checkcheck() #now after verifyT is done else: log.debug("User did NOT select ‘{}’, assuming we'll come " From 29645da8e3356a9ad1691eb456f465421d614fe5 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:22:02 +0100 Subject: [PATCH 292/310] remove excess fns --- main.py | 175 -------------------------------------------------------- 1 file changed, 175 deletions(-) diff --git a/main.py b/main.py index fe8d85b8..92b290d5 100755 --- a/main.py +++ b/main.py @@ -2184,181 +2184,6 @@ def framevaluesbynamepsprofile(self,ps,profile,name): l+=group return list(dict.fromkeys(l)) """Mediating between LIFT and the user""" - # def getframeddata(self,source,noframe=False,notonegroup=False,truncdefn=False): - # """This generates a dictionary of form {'form':outputform, - # 'gloss':outputgloss} for display, by senseid""" - # """Sometimes this script is called to make the example fields, other - # times to display it. If source is a senseid, it pulls form/gloss/etc - # information from the entry. If source is an example, it pulls that info - # from the example. The info is formatted uniformly in either case.""" - # output={} - # log.log(2,"{} {}".format(source, type(source))) - # log.log(2,'self.glosslang: {}'.format(self.glosslang)) - # log.log(2,'self.glosslang2: {}'.format(self.glosslang2)) - # """Just in case there's a problem later...""" - # forms={} - # glosses={} - # gloss={} - # tonegroups=None - # """Build dual logic here:""" - # if isinstance(source,lift.ET.Element): - # #This is an example element, not a sense or entry element... - # element=source - # for node in element: - # if (node.tag == 'form') and ((node.get('lang') == self.analang) - # or (node.get('lang') == self.audiolang)): - # forms[node.get('lang')]=node.findall('text') - # if (((node.tag == 'translation') and - # (node.get('type') == 'Frame translation')) or - # ((node.tag == 'gloss') and - # (node.get('lang') == self.glosslang))): - # for subnode in node: - # if (subnode.tag == 'form'): - # glosses[subnode.get('lang')]=subnode.findall('text') - # if ((node.tag == 'field') and (node.get('type') == 'tone')): - # #This should always be only one value: - # tonegroups=node.findall('form/text') - # log.log(2,'forms: {}'.format(forms)) - # for lang in glosses: - # log.log(2,'gloss[{}]: {}'.format(lang,glosses[lang])) - # """convert from lists to single items without loosing data, - # then pull text from nodes""" - # if self.analang in forms: - # form=t(firstoflist(forms[self.analang])) - # else: - # form=None - # if self.audiolang in forms: - # voice=t(firstoflist(forms[self.audiolang])) - # else: - # voice=None - # for lang in glosses: - # if (lang == self.glosslang) or (lang == self.glosslang2): - # gloss[lang]=t(firstoflist(glosses[lang])) - # """This is what we're pulling from: - # - #
ga təv
- # - #
lieu (m), place (f) (pl)
- #
- # - #
1
- #
- # - #
Plural
- #
- #
- # """ - # elif (type(source) is str): # and (len(source) == 36): #source is sensedid - # #some dbs have senseids with form info, too... - # #Asking for a sense, you get all tone groups, if self.name isn't set - # log.log(3,'36 character senseid string!') - # senseid=source - # output['senseid']=senseid - # forms[self.analang]=self.db.citation(senseid=senseid,#orlexeme - # lang=self.analang, - # ps=self.ps) - # forms[self.audiolang]=self.db.citation(senseid=senseid, #orlexeme - # lang=self.audiolang, - # ps=self.ps) - # for lang in [self.glosslang,self.glosslang2]: - # if lang is not None: - # glosses[lang]=self.db.glossordefn(senseid=senseid, - # glosslang=lang,ps=self.ps) - # #If frame is not defined (in self.name) this will output ALL values - # #for this sense! - # tonegroups=self.db.get('exfieldvalue', senseid=senseid, - # fieldtype='tone', location=self.name) - # """convert from lists to single items without loosing data""" - # form=firstoflist(forms[self.analang]) - # voice=firstoflist(forms[self.audiolang]) - # for lang in glosses: - # gloss[lang]=firstoflist(glosses[lang]) - # log.log(2,'gloss[{}]: {}'.format(lang,gloss[lang])) - # else: - # log.error('Neither Element nor senseid was found!' - # '\nThis is almost certainly not what you want!' - # '\nFYI, I was looking for {}'.format(source)) - # return source - # log.log(2,'form: {}'.format(form)) - # for lang in gloss: - # log.log(2,'gloss:'.format(gloss[lang])) - # """The following is the same for senses or examples""" - # if notonegroup == False: - # #If I haven't defined self.name nor set notonegroup=True, this will - # # throw an error on a senseid above. - # tonegroup=t(firstoflist(tonegroups)) - # log.log(2,'tonegroup: {}'.format(tonegroup)) - # if tonegroup is not None: - # try: - # int(tonegroup) - # except: - # output['tonegroup']=tonegroup #this is only for named groups - # if self.glosslang2 in gloss and (self.glosslang2 is None or - # gloss[self.glosslang2] is None): - # del gloss[self.glosslang2] #remove this now, and lose checks later - # output[self.analang]=None - # for lang in list(gloss.keys())+[self.glosslang]: - # output[lang]=None - # text=('noform','nogloss') - # if noframe == False: - # frame=self.toneframes[self.ps][self.name] - # """Forms and glosses have to be strings, or the regex fails""" - # if form is None: - # form=nn(form) #'noform' - # for lang in gloss: - # if gloss[lang] is None: - # gloss[lang]=nn(gloss[lang]) #'nogloss' - # log.log(2,frame) - # output[self.analang]=rx.framerx.sub(form,frame[self.analang]) - # for lang in gloss: - # """only give these if the frame has this gloss, *and* if - # the gloss is in the data (user selection is above)""" - # if ((lang in frame) and (lang in gloss) and ( - # None not in [gloss[lang],frame[lang]])): - # output[lang]=rx.framerx.sub(gloss[lang],frame[lang]) - # else: - # output[self.analang]=nn(form) #for non-segmental forms - # for lang in gloss: - # output[lang]=gloss[lang] - # if voice is not None: - # output[self.audiolang]=voice - # text=[str(output[self.analang]),"‘"+str(output[self.glosslang])+"’"] - # if self.glosslang2 in output and output[self.glosslang2] is not None: - # text+=["‘"+str(output[self.glosslang2])+"’"] - # if 'tonegroup' in output: - # text=[str(output['tonegroup'])]+text - # output['formatted']=' '.join(text) #used to be '\t'... - # if None in output: - # log.error("Apparently None is an output key! {}".format(output)) - # return output - def getframedentry(self,guid): - """This is most likely obsolete""" - """This generates output for selection and verification, by ps""" - glosses={} - form=firstoflist(self.db.citationorlexeme(guid,lang=self.analang, - ps=self.ps)) - glosses[self.glosslang]=firstoflist(self.db.glossordefn(guid, - glosslang=self.glosslang, ps=self.ps)) - if self.glosslang2 is not None: - glosses[self.glosslang2]=firstoflist(self.db.glossordefn(guid, - glosslang=self.glosslang2,ps=self.ps)) - frame=self.toneframes[self.ps][self.name] - if self.debug ==True: - print(forms,glosses,frame) - outputform=None - outputgloss={} - outputform=rx.framerx.sub(form,frame[self.analang]) - for lang in glosses: - if (lang != self.glosslang2) or (self.glosslang2 is not None): - outputgloss[lang]=rx.framerx.sub(glosses[lang], - frame[lang]) - printoutput=(' ',outputform, - "‘"+str(outputgloss[self.glosslang])+"’") - if self.glosslang2 is not None: - printoutput+="‘"+str(outputgloss[self.glosslang2])+"’" - print(printoutput) - return {self.analang:outputform,self.glosslang:outputgloss, - self.glosslang2:outputgloss} def senseidtriage(self): # import time # print("Doing senseid triage... This takes awhile...") From adced35e38df9290df1d6c0b572157a245310b27 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:56:52 +0100 Subject: [PATCH 293/310] mark this for singletons, too --- main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main.py b/main.py index 92b290d5..89b2351d 100755 --- a/main.py +++ b/main.py @@ -4060,6 +4060,7 @@ def verifyT(self,menu=False): senseids=self.getexsall(self.subcheck) if len(senseids) <2: self.updatestatus(verified=True) + self.updatestatuslift(self.name,self.subcheck,verified=True) # self.checkcheck() #now after verifyT is done log.info("Group ‘{}’ only has {} example; marking verified and " "continuing.".format(self.subcheck,len(senseids))) From 9eb70090d95b9ec61dcf2def8faaf0d447e0cdc2 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 17:57:12 +0100 Subject: [PATCH 294/310] examples are framed --- lift.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lift.py b/lift.py index a814493c..96847043 100644 --- a/lift.py +++ b/lift.py @@ -295,7 +295,7 @@ def addmodexamplefields(self,**kwargs): return analang=kwargs.get('analang') db=kwargs.get('db') #This an object with values - forms=db.forms + forms=db.framed #because this should always be framed glosslangs=db.glosslangs p=Node(sensenode, tag='example') p.makeformnode(analang,forms[analang]) From f53e6ab58b2d4cc2a441a6f672be9053f72f4bc4 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:01:49 +0100 Subject: [PATCH 295/310] change default to framed --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 89b2351d..168787eb 100755 --- a/main.py +++ b/main.py @@ -6123,7 +6123,7 @@ class FramedData(object): times to display it. If source is a senseid, it pulls form/gloss/etc information from the entry. If source is an example, it pulls that info from the example. The info is formatted uniformly in either case.""" - def formatted(self,notonegroup=True,noframe=True): + def formatted(self,notonegroup=True,noframe=False): if notonegroup: toformat=DataList() else: From fb8d1ef2feefddd628e29f7f8a885d100fb3d23b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:02:19 +0100 Subject: [PATCH 296/310] new noframe method --- main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 168787eb..bbd5e17d 100755 --- a/main.py +++ b/main.py @@ -6132,18 +6132,22 @@ def formatted(self,notonegroup=True,noframe=False): toformat.appendformsbylang(self.forms,self.analang,quote=False) toformat.appendformsbylang(self.forms,self.glosslangs,quote=True) else: + if not hasattr(self,framed): + self.noframe() #Assume no frame if not excplicitly applied toformat.appendformsbylang(self.framed,self.analang,quote=False) toformat.appendformsbylang(self.framed,self.glosslangs,quote=True) return ' '.join(toformat) #put it all together def setframe(self,frame): self.frame=self.frames[self.ps][frame] self.applyframe() + def noframe(self): + self.framed=self.forms def applyframe(self): if not self.noframe: self.forms.frame(self.frame,[self.analang]+self.glosslangs) self.framed=self.forms.framed else: - self.framed=self.forms + self.noframe() def gettonegroup(self): if self.location is not None: self.tonegroups=self.db.get('example/tonefield/form/text', From f8755d06043c5c7a67ba247d077304733743928b Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:02:36 +0100 Subject: [PATCH 297/310] note --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index bbd5e17d..3dd87f03 100755 --- a/main.py +++ b/main.py @@ -5083,7 +5083,7 @@ def getresults(self): for senseid in senseidstocheck: #self.senseidformstosearch[lang][ps] # where self.regex(self.senseidformstosearch[lang][ps][senseid]): """This regex is compiled!""" - framed=self.datadict.getframeddata(senseid) + framed=self.datadict.getframeddata(senseid) #not framed! o=framed.formatted(noframe=True) self.framedtoXLP(framed,parent=ex,listword=True) if self.debug ==True: From a86d6665f1565d62de73219c33c721e86f852bb1 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:07:30 +0100 Subject: [PATCH 298/310] fix syntax --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index 3dd87f03..e431ede2 100755 --- a/main.py +++ b/main.py @@ -6132,7 +6132,7 @@ def formatted(self,notonegroup=True,noframe=False): toformat.appendformsbylang(self.forms,self.analang,quote=False) toformat.appendformsbylang(self.forms,self.glosslangs,quote=True) else: - if not hasattr(self,framed): + if not hasattr(self,'framed'): self.noframe() #Assume no frame if not excplicitly applied toformat.appendformsbylang(self.framed,self.analang,quote=False) toformat.appendformsbylang(self.framed,self.glosslangs,quote=True) From a54d91b5171763dc9645ae35147bbe8e2e18f8cf Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:21:25 +0100 Subject: [PATCH 299/310] updates to changelog/roadmap --- CHANGELOG.md | 17 +++++++++++++++++ ROADMAP.md | 13 ++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa17d2df..d8f614c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # A→Z+T Changelog +# Version 0.8.7 +- give warning if user is going to undo analysis regroupings +- mark a sensid to sort again without losing the sound file attached to it. +- major overhaul to LIFT urls, including class to generate them and catalog to store them +- major overhaul to framed data, including class to generate and catalog to store +- Added comparison group button for rename framed group window (to help with transcriptions) +- added actual groups by datapoint for non-default tone reports +- Reworked and multiple improvements to naming groups: + - playable buttons + - praat link to sound file + - comparison button(s) + - navigation buttons to continue through groups +- added interpretation of glottal stop into sdistinctions. +- added settings for interpretation of trigraphs and digraphs +- multiple fixes to segment interpretation settings +- set up mail of bug report, and links to webpage documentation + # Version 0.8.6 - reworked buttons and UI on transcription window - comparison option for transcription window diff --git a/ROADMAP.md b/ROADMAP.md index 03d76a2b..c86137f6 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,6 @@ ## release stoppers - put image creation after splash creation? -- give warning if user is going to undo analysis regroupings - check out why tooltips aren't working before first refresh ## Documentation @@ -18,6 +17,8 @@ - make font changes more general, tied to +/- ## Simplify (non-OOP related) +- Set means for user to check verification stage again. This will require invalidating all the data to be redone (not currently implimented). + - Once done, there is currently no AZT way to redo it. - on import, check for entries without: - citation, copy over from lexical-unit (all langs) - gloss, copy over from definitions (truncate, all langs) @@ -38,7 +39,6 @@ - transcribe (but not sort, etc) ## Migrate further toward OOP -- mark a sensid to sort again without losing the sound file attached to it. - distinguish between frames to do for sorting (with unsorted data) and frames to do for other tasks... - make 'next' go to next frame, if done sorting, or not, as appropriate - make tone analysis one thing, and tone report another thing, and call analysis if not done since data was last added/modified (store this info somewhere, clear after analysis completes) @@ -104,13 +104,7 @@ - add progress of recording (on its own tab?) ## For Future Versions -- Add comparison group button for rename framed group window (to help with transcriptions) -- consider adding actual groups by datapoint for non-default tone reports - - I.e., which data points are different -- think through ease of use questions: - - How to make naming groups straightforward from the main interface? - implement XML2XLP.txt (to produce PDF without further user input) -- add interpretation of glottal stop into sdistinctions. - fix zip problem on Windows: "OSError: [Errno 22] Invalid argument: 'log_-:.7z'" - extra space being added for None forms in Frame construction - Sort out why not all nouns show in ad hoc selection list. @@ -177,11 +171,8 @@ - widen "Do" menu item (give all a minimum width) ## For some time -- set up mail of bug report (better than WeSay) - look into having hg commit changes to verification status file - don't track checkdefaults? (make per user file?) -- Set means for user to check verification stage again. - - Once done, there is currently no AZT way to redo it. - Look up how to get real required heights and widths, availablexy isn't working correctly. - fix reconfigure scrolling window frame problem (remove need for if self.configured <1:) - constrain frames with less data, to only scroll as needed. From d2d977bbbd31c24db57e0af04aa7338458d71905 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:29:53 +0100 Subject: [PATCH 300/310] new glosslangs class --- main.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/main.py b/main.py index e431ede2..e8ae4d93 100755 --- a/main.py +++ b/main.py @@ -6075,6 +6075,19 @@ def appendformsbylang(self,forms,langs,quote=False): def __init__(self, *args): super(DataList, self).__init__() self.extend(args) +class Glosslangs(DataList): + """docstring for Glosslangs.""" + def lang1(self,lang): + if len(self) >1 and self[1] == lang: + self.pop(1) + self[0]=lang + def lang2(self,lang): + if len(self) >0 and self[0] != lang: + self[0]=lang + def __init__(self, *args): + super(Glosslangs, self).__init__() + self.extend(args) + class DictbyLang(dict): """docstring for DictbyLang.""" def getformfromnode(self,node,truncate=False): From 66c311bbf56950f45fe2997fb23ff8b286f98034 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:31:42 +0100 Subject: [PATCH 301/310] first commit wih Glosslangs --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index e8ae4d93..cfe5ea0f 100755 --- a/main.py +++ b/main.py @@ -312,7 +312,7 @@ def guessaudiolang(self): def guessglosslangs(self): """if there's only one gloss language, use it.""" if not hasattr(self,'glosslangs'): - self.glosslangs=[None,None] + self.glosslangs=Glosslangs(None,None) if len(self.db.glosslangs) == 1: log.info('Only one glosslang!') self.glosslangs[0]=self.glosslang=self.db.glosslangs[0] From 2b3d8ed322a63ee75a59b6d088d55e88d4b14808 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Fri, 29 Oct 2021 18:48:04 +0100 Subject: [PATCH 302/310] additions to Glosslangs --- main.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index cfe5ea0f..1844dd53 100755 --- a/main.py +++ b/main.py @@ -6077,13 +6077,20 @@ def __init__(self, *args): self.extend(args) class Glosslangs(DataList): """docstring for Glosslangs.""" - def lang1(self,lang): + def lang1(self,lang=None): + if lang is None: + return self[0] if len(self) >1 and self[1] == lang: self.pop(1) self[0]=lang - def lang2(self,lang): + def lang2(self,lang=None): + if lang is None and len(self) >1: + return self[1] if len(self) >0 and self[0] != lang: self[0]=lang + def rm(self,lang): + """This could be either position, and if lang1 will promote lang2""" + self.remove(lang) def __init__(self, *args): super(Glosslangs, self).__init__() self.extend(args) From b028e437be01948ed2de21cd3a91ead343b2fa76 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 12:34:45 +0100 Subject: [PATCH 303/310] correct version and set production for videos, prep for next release --- main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 1844dd53..fd895511 100755 --- a/main.py +++ b/main.py @@ -3,8 +3,8 @@ """This file runs the actual GUI for lexical file manipulation/checking""" program={'name':'A→Z+T'} program['tkinter']=True -program['production']=False #True for making screenshots -program['version']='0.8.7oop' #This is a string... +program['production']=True#False #True for making screenshots +program['version']='0.8.6oop' #This is a string... program['url']='https://github.com/kent-rasmussen/azt' program['Email']='kent_rasmussen@sil.org' import platform From 9848860f2ee00d75229df20732794c8b160cb4a3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 12:35:08 +0100 Subject: [PATCH 304/310] reverify fn and menu item --- main.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/main.py b/main.py index fd895511..122754db 100755 --- a/main.py +++ b/main.py @@ -4013,6 +4013,21 @@ def testsorting(self): return 1 # this should only happen on Exit self.marksortedsenseid(senseid) self.runwindow.resetframe() + def reverify(self): + log.info("Reverifying a framed tone group, at user request: {}-{}" + "".format(self.name,self.subcheck)) + checkswframes=self.status[self.type][self.ps][self.profile] + if self.name is None or self.name not in checkswframes: + self.getcheck() #guess=True + done=self.status[self.type][self.ps][self.profile][self.name]['done'] + if self.subcheck is None or self.subcheck not in done: + self.getsubcheck()#guess=True + if self.subcheck == None: + log.info("I asked for a framed tone group, but didn't get one.") + return + if self.subcheck in done: + done.remove(self.subcheck) + self.maybesort() def verifyT(self,menu=False): log.info("Running verifyT!") """Show entries each in a row, users mark those that are different, and we @@ -6754,6 +6769,9 @@ def _setmenus(self,event=None): command=lambda x=check:Check.tryNAgain(x)) advancedmenu.add_cascade(label=_("Redo"), menu=redomenu) advancedmenu.add_cascade(label=_("Add other"), menu=filemenu) + redomenu.add_command( + label=_("Verification of current framed group"), + command=lambda x=check:Check.reverify(x)) redomenu.add_command( label=_("Digraph and Trigraph settings (Restart)"), command=lambda x=check:Check.askaboutpolygraphs(x)) From 55ac420efe7d1861777300ac4f38fef71b6f587e Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 12:35:56 +0100 Subject: [PATCH 305/310] distinguish on main screen between no frames defined and none selected --- main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 122754db..b327317c 100755 --- a/main.py +++ b/main.py @@ -2426,8 +2426,11 @@ def button(opts,text,fn=None,column=opts['labelcolumn'],**kwargs): t=(_("Checking {},").format(self.typedict[self.type]['pl'])) proselabel(opts,t,cmd='gettype',parent=tf) opts['columnplus']=1 - if self.name not in self.toneframes[self.ps]: - t=_("no defined tone frame yet.") + if len(self.toneframes[self.ps]) == 0: + t=_("no tone frames defined.") + self.name=None + elif self.name not in self.toneframes[self.ps]: + t=_("no tone frame selected.") self.name=None else: t=(_("working on ‘{}’ tone frame").format(self.name)) From 925cf59d57a3ca2b6b165f5f4137a9b4503a6f88 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 12:36:23 +0100 Subject: [PATCH 306/310] allow for recording to take default if there, else none (needed for testing with no framed data) --- main.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index b327317c..855ae737 100755 --- a/main.py +++ b/main.py @@ -7657,8 +7657,14 @@ def __init__(self,parent,check,id=None,node=None,test=False,**kwargs): self.db=check.db self.node=node #This should never be more than one node... framed=kwargs.pop('framed',None) #Either this or the next two... - self.form=kwargs.pop('form',framed.forms[check.analang]) - self.gloss=kwargs.pop('gloss',framed.forms[check.glosslang]) + if framed is not None: + formdefault=framed.forms[check.analang] + glossdefault=framed.forms[check.glosslang] + else: + formdefault=None + glossdefault=None + self.form=kwargs.pop('form',formdefault) + self.gloss=kwargs.pop('gloss',glossdefault) self.id=id self.check=check try: From 7dffe785d0b253c90fe6e932d3eea6e6e2cb67ea Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 12:37:21 +0100 Subject: [PATCH 307/310] update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8f614c8..c45dd3ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # A→Z+T Changelog # Version 0.8.7 +- added referify data for current subgroup - give warning if user is going to undo analysis regroupings - mark a sensid to sort again without losing the sound file attached to it. - major overhaul to LIFT urls, including class to generate them and catalog to store them From b26d5627c75637681ada58f767d37f7826d173a3 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 13:22:36 +0100 Subject: [PATCH 308/310] help about clarity on capacity --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 855ae737..d8bb138f 100755 --- a/main.py +++ b/main.py @@ -6828,7 +6828,8 @@ def helpabout(self): "allows the user to record a word in each of the frames where " "it has been sorted, storing the recorded audio file in a " "directory, with links to each file in the dictionary database." - " Recordings can be made up to 192khz/32float.\nFor help with " + " Recordings can be made up to 192khz/32float, according to " + "your recording equipment's capacity.\nFor help with " "this tool, please check out the documentation at " "{url} or write me at " "{Email}.".format(name=self.program['name'], From 4331e9d2ebb545310fd57e6d816a563c8a266284 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 13:38:28 +0100 Subject: [PATCH 309/310] separated out contacts and added links to about --- main.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/main.py b/main.py index d8bb138f..3de65588 100755 --- a/main.py +++ b/main.py @@ -6829,12 +6829,11 @@ def helpabout(self): "it has been sorted, storing the recorded audio file in a " "directory, with links to each file in the dictionary database." " Recordings can be made up to 192khz/32float, according to " - "your recording equipment's capacity.\nFor help with " - "this tool, please check out the documentation at " - "{url} or write me at " - "{Email}.".format(name=self.program['name'], - url=self.program['url'], - Email=self.program['Email'])) + "your recording equipment's capacity.").format( + name=self.program['name']) + webtext=_("For help with this tool, please check out the documentation " + "at {url} ").format(url=self.program['url']) + mailtext=_("or write me at {}.").format(self.program['Email']) Label(window.frame, text=title, font=self.fonts['title'],anchor='c',padx=50 ).grid(row=0,column=0,sticky='we') @@ -6843,9 +6842,19 @@ def helpabout(self): Label(f.content, image=self.photo['small'],text='', bg=self.theme['background'] ).grid(row=0,column=0,sticky='we') - l=Label(f.content, text=text, pady=50, padx=50, + l=Label(f.content, text=text, padx=50, + wraplength=int(self.winfo_screenwidth()/2) + ).grid(row=1,column=0,pady=(50,0),sticky='we') + webl=Label(f.content, text=webtext, padx=50,#pady=50, wraplength=int(self.winfo_screenwidth()/2) - ).grid(row=1,column=0,sticky='we') + ) + webl.grid(row=2,column=0,sticky='we') + maill=Label(f.content, text=mailtext, padx=50,#pady=50, + wraplength=int(self.winfo_screenwidth()/2) + ) + maill.grid(row=3,column=0,sticky='we') + webl.bind("", lambda e: openweburl(self.program['url'])) + maill.bind("", lambda e: openweburl(self.program['Email'])) def maketitle(self): title=_("{name} Dictionary and Orthography Checker").format( name=self.program['name']) From 1ff36c3b8844828038d02a1bcf41238f82e97949 Mon Sep 17 00:00:00 2001 From: Kent Rasmussen Date: Mon, 1 Nov 2021 13:40:46 +0100 Subject: [PATCH 310/310] fixed mail url --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 3de65588..4fa2edf5 100755 --- a/main.py +++ b/main.py @@ -6854,7 +6854,8 @@ def helpabout(self): ) maill.grid(row=3,column=0,sticky='we') webl.bind("", lambda e: openweburl(self.program['url'])) - maill.bind("", lambda e: openweburl(self.program['Email'])) + murl='mailto:{}?subject= A→Z+T question'.format(self.program['Email']) + maill.bind("", lambda e: openweburl(murl)) def maketitle(self): title=_("{name} Dictionary and Orthography Checker").format( name=self.program['name'])