Exemple #1
0
 def realHarmonic(self,dist):
     qs = self.model().data(self.contextIndex, Qt.DisplayRole).toString()
     word = unicode(qs) # get python string
     wordLen = len(word) # save a few cycles in the test below
     harmList = []
     for i in range(IMC.wordCensus.size()):
         word2 = unicode(IMC.wordCensus.getWord(i))
         if dist >= abs(wordLen - len(word2)): # There's a chance of a match
             if dist >= edit_distance(word,word2): # test it
                 harmList.append(word2) # one hit is on the word itself
     if 1 < len(harmList) : # got at least 1 other
         self.panelRef.tableModel.beginResetModel()
         self.panelRef.listFilter = harmList
         self.panelRef.tableModel.endResetModel()
         self.panelRef.rowCountLabel.setNum(self.panelRef.proxy.rowCount())
     else:
         pqMsgs.infoMsg(
             "There are no words in edit distance {0} edit of {1}".format(dist,word)
         )
Exemple #2
0
 def similarWords(self):
     qch = QChar(u'-')
     qcp = QChar(u"'")
     wordOriginal = self.model().data(self.contextIndex, Qt.DisplayRole).toString()
     word = QString(wordOriginal)
     word.remove(qch)
     word.remove(qcp)
     h1list = []
     for i in range(IMC.wordCensus.size()):
         word1 = IMC.wordCensus.getWord(i)
         word2 = QString(word1) # force a copy!
         word2.remove(qch) # otherwise this would affect the word
         word2.remove(qcp) # in the census list
         if 0 == word.compare(word2,Qt.CaseInsensitive):
             h1list.append(unicode(word1)) # one hit on word itself
     if 1 < len(h1list): # got at least 1 other
         self.panelRef.tableModel.beginResetModel()
         self.panelRef.listFilter = h1list
         self.panelRef.tableModel.endResetModel()
         self.panelRef.rowCountLabel.setNum(self.panelRef.proxy.rowCount())
     else:
         pqMsgs.infoMsg("There are no words similar to {0}".format(unicode(wordOriginal)))
Exemple #3
0
def checkForUpdates():
    # Step one, read the code display for the master
    page = slurp('https://github.com/tallforasmurf/PPQT')
    if page is None:
        pqMsgs.warningMsg('Unable to contact Github',
                          'Perhaps try again later?')
        return

    # the embedded URLs usable.
    hit = reGetMasterSHA.search(page)
    if hit is None:
        pqMsgs.warningMsg('Github page format not as expected',
                          'Probable bug, update not available')
        return
    masterSHA = hit.group(1)
    page = re.sub(masterSHA, 'master', page)

    # Step three, make a list of all the "blobs" mentioned, which is just
    # all the committed modules, pqXXX.py and pqHelp.html. Ignoring the
    # extras -- the extras folder appears as a "tree" item and we could
    # follow it and list all the blobs extras/* but we are not.
    blobs = reBlobLine.findall(page)
    # blobs is a list of 4-tuples, the (/1, /2, /3, /4) from reBlobLine above
    # Now make a dict with 3-item values,
    # { modname:[ None, masterhash, masterURL] } where None will be filled
    # in with the local hash value shortly.
    blobTab = {}
    for blob in blobs:
        blobURL = u'https://raw.github.com' + blob[0] + u'/' + blob[1]
        blobName = blob[3]
        blobHash = blob[2]
        blobTab[blobName] = [None, blobHash, blobURL]

    # Look for the file modulehash.txt and if it exists, use it to fill
    # in the local hashes it lists. We do not distribute so it doesn't
    # show up in the github listing. We want the local hash to reflect
    # the actual local files, which might have been diddled locally.
    mhPath = os.path.join(IMC.appBasePath, 'modulehashes.txt')
    try:
        mhFile = open(mhPath, 'r')
        for line in mhFile:
            [modname, localhash] = line.split()
            if modname in blobTab:
                blobTab[modname][0] = localhash
    except:
        # presumably the file doesn't exist
        pass

    # Run through the blobTab and try to get hash values for any
    # modules that don't have a local hash yet (because modulehashes
    # didn't exist -- or didn't list them because they're new to us).
    for modName in blobTab:
        if blobTab[modName][0] is None:
            modPath = os.path.join(IMC.appBasePath, modName)
            try:
                modFile = open(modPath, 'r')
                modText = modFile.read()
                hasher = initializedSHA1.copy()
                hasher.update(str(len(modText)))
                hasher.update(b'\000')
                hasher.update(modText)
                blobTab[modName][0] = hasher.hexdigest()
            except:
                # presumably modname doesn't exist (new module?)
                pass

    # Run through the blobTab and make a new table, updaTab, listing
    # the members where localhash differs from master hash.
    updaTab = {}
    for modName in blobTab:
        if blobTab[modName][0] != blobTab[modName][1]:
            updaTab[modName] = blobTab[modName]

    # If there are no names left in the updaTab, the app is up to date!
    if len(updaTab) == 0:
        pqMsgs.infoMsg('PPQT is up to date.')
        return

    # There are one or more modules needing updating. Ask the user
    # if we should proceed.
    ans = pqMsgs.okCancelMsg(
        '{0} module(s) can be updated.'.format(len(updaTab)),
        'Shall we proceed?')
    if not ans:
        pqMsgs.infoMsg('PPQT remains unchanged.')
        return

    # User said OK to do it. Read the text of the updated modules from
    # github and save it in the updaTab.
    for modName in updaTab:
        page = slurp(updaTab[modName][2])
        if page is None:
            pqMsgs.warningMsg('Some problem reading update modules',
                              'PPQT is unchanged.')
            return
        updaTab[modName].append(page)

    # All update texts read correctly. Now open each for writing,
    # appending the file object to the updaTab entry.
    for modName in updaTab:
        try:
            modPath = os.path.join(IMC.appBasePath, modName)
            modFile = open(modPath, 'w')
            updaTab[modName].append(modFile)
        except Exception:
            pqMsgs.warningMsg('Updated modules are not writable'
                              'PPQT is unchanged.')
            return

    # All files open for writing and text is ready. Write them.
    for modName in updaTab:
        try:
            modFile = updaTab[modName][4]
            modFile.write(updaTab[modName][3])
            modFile.flush()
            os.fsync(modFile.fileno())
            modFile.close()
        except Exception as e:
            # This is the bad case: some amount of writing done but not
            # all of it complete. PPQT is in an inconsistent state.
            pqMsgs.warningMsg(
                'Error writing updated module(s)!',
                'PPQT is in an inconsistent state\nDownload a complete new copy'
            )
            return

    # All updates complete. Record local hashes in modulehashes.txt
    try:
        mhFile = open(mhPath, 'w')
        for modName in blobTab:
            mhFile.write(modName + ' ' + blobTab[modName][1] + '\n')
        mhFile.close()
    except Exception as e:
        pass

    pqMsgs.infoMsg('Updates applied.',
                   'Changes take effect when PPQT is restarted.')
    return
Exemple #4
0
def checkForUpdates():
    # Step one, read the code display for the master
    page = slurp('https://github.com/tallforasmurf/PPQT')
    if page is None:
        pqMsgs.warningMsg('Unable to contact Github',
                          'Perhaps try again later?')
        return

    # the embedded URLs usable.
    hit = reGetMasterSHA.search(page)
    if hit is None:
        pqMsgs.warningMsg('Github page format not as expected',
                          'Probable bug, update not available')
        return
    masterSHA = hit.group(1)
    page = re.sub(masterSHA,'master',page)

    # Step three, make a list of all the "blobs" mentioned, which is just
    # all the committed modules, pqXXX.py and pqHelp.html. Ignoring the
    # extras -- the extras folder appears as a "tree" item and we could
    # follow it and list all the blobs extras/* but we are not.
    blobs = reBlobLine.findall(page)
    # blobs is a list of 4-tuples, the (/1, /2, /3, /4) from reBlobLine above
    # Now make a dict with 3-item values,
    # { modname:[ None, masterhash, masterURL] } where None will be filled
    # in with the local hash value shortly.
    blobTab = {}
    for blob in blobs:
        blobURL = u'https://raw.github.com' + blob[0] + u'/' + blob[1]
        blobName = blob[3]
        blobHash = blob[2]
        blobTab[blobName] =[None,blobHash,blobURL]

    # Look for the file modulehash.txt and if it exists, use it to fill
    # in the local hashes it lists. We do not distribute so it doesn't
    # show up in the github listing. We want the local hash to reflect
    # the actual local files, which might have been diddled locally.
    mhPath = os.path.join(IMC.appBasePath,'modulehashes.txt')
    try:
        mhFile = open(mhPath,'r')
        for line in mhFile:
            [modname, localhash] = line.split()
            if modname in blobTab:
                blobTab[modname][0] = localhash
    except:
        # presumably the file doesn't exist
        pass

    # Run through the blobTab and try to get hash values for any
    # modules that don't have a local hash yet (because modulehashes
    # didn't exist -- or didn't list them because they're new to us).
    for modName in blobTab:
        if blobTab[modName][0] is None:
            modPath = os.path.join(IMC.appBasePath,modName)
            try:
                modFile = open(modPath,'r')
                modText = modFile.read()
                hasher = initializedSHA1.copy()
                hasher.update(str(len(modText)))
                hasher.update(b'\000')
                hasher.update(modText)
                blobTab[modName][0] = hasher.hexdigest()
            except:
                # presumably modname doesn't exist (new module?)
                pass

    # Run through the blobTab and make a new table, updaTab, listing
    # the members where localhash differs from master hash.
    updaTab = {}
    for modName in blobTab:
        if blobTab[modName][0] != blobTab[modName][1] :
            updaTab[modName] = blobTab[modName]

    # If there are no names left in the updaTab, the app is up to date!
    if len(updaTab) == 0:
        pqMsgs.infoMsg('PPQT is up to date.')
        return

    # There are one or more modules needing updating. Ask the user
    # if we should proceed.
    ans = pqMsgs.okCancelMsg('{0} module(s) can be updated.'.format(len(updaTab)),
                       'Shall we proceed?')
    if not ans:
        pqMsgs.infoMsg('PPQT remains unchanged.')
        return

    # User said OK to do it. Read the text of the updated modules from
    # github and save it in the updaTab.
    for modName in updaTab:
        page = slurp(updaTab[modName][2])
        if page is None:
            pqMsgs.warningMsg('Some problem reading update modules',
                              'PPQT is unchanged.')
            return
        updaTab[modName].append(page)

    # All update texts read correctly. Now open each for writing,
    # appending the file object to the updaTab entry.
    for modName in updaTab:
        try:
            modPath = os.path.join(IMC.appBasePath,modName)
            modFile = open(modPath, 'w')
            updaTab[modName].append(modFile)
        except Exception:
            pqMsgs.warningMsg('Updated modules are not writable'
                              'PPQT is unchanged.')
            return

    # All files open for writing and text is ready. Write them.
    for modName in updaTab:
        try:
            modFile = updaTab[modName][4]
            modFile.write(updaTab[modName][3])
            modFile.flush()
            os.fsync(modFile.fileno())
            modFile.close()
        except Exception as e:
            # This is the bad case: some amount of writing done but not
            # all of it complete. PPQT is in an inconsistent state.
            pqMsgs.warningMsg('Error writing updated module(s)!',
                              'PPQT is in an inconsistent state\nDownload a complete new copy')
            return

    # All updates complete. Record local hashes in modulehashes.txt
    try:
        mhFile = open(mhPath,'w')
        for modName in blobTab:
            mhFile.write(modName + ' ' + blobTab[modName][1] + '\n')
        mhFile.close()
    except Exception as e:
        pass

    pqMsgs.infoMsg('Updates applied.',
                   'Changes take effect when PPQT is restarted.')
    return
Exemple #5
0
 def loadMetadata(self,metaStream):
     sectionRE = QRegExp( u"\{\{(" + '|'.join (
         ['PAGETABLE','CHARCENSUS','WORDCENSUS','BOOKMARKS',
          'NOTES','GOODWORDS','BADWORDS','CURSOR','VERSION',
          'STALECENSUS','NEEDSPELLCHECK','ENCODING', 'DOCHASH', 'MAINDICT'] ) \
                          + u")(.*)\}\}",
         Qt.CaseSensitive)
     metaVersion = 0 # base version
     while not metaStream.atEnd() :
         qline = metaStream.readLine().trimmed()
         if qline.isEmpty() : continue # allow blank lines between sections
         if sectionRE.exactMatch(qline) : # section start
             section = sectionRE.cap(1)
             argument = unicode(sectionRE.cap(2).trimmed())
             endsec = QString(u"{{/" + section + u"}}")
             if section == u"VERSION":
                 if len(argument) != 0 :
                     metaVersion = int(argument)
                 continue # no more data after {{VERSION x }}
             elif section == u"STALECENSUS" :
                 if argument == u"TRUE" :
                     IMC.staleCensus = IMC.staleCensusLoaded
                 continue # no more data after {{STALECENSUS x}}
             elif section == u"NEEDSPELLCHECK" :
                 if argument == u"TRUE" :
                     IMC.needSpellCheck = True
                 continue # no more data after {{NEEDSPELLCHECK x}}
             elif section == u"ENCODING" :
                 IMC.bookSaveEncoding = QString(argument)
                 continue
             elif section == u"MAINDICT" :
                 IMC.bookMainDict = QString(argument)
                 continue
             elif section == u"DOCHASH" :
                 IMC.metaHash = argument
                 continue
             elif section == u"PAGETABLE":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (not qline.isEmpty()):
                     IMC.pageTable.metaStringIn(qline)
                     qline = metaStream.readLine()
                 continue
             elif section == u"CHARCENSUS":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (not qline.isEmpty()):
                     # can't just .split the char census, the first
                     # char is the char being counted and it can be a space.
                     str = unicode(qline)
                     parts = str[2:].split(' ')
                     IMC.charCensus.append(QString(str[0]),int(parts[0]),int(parts[1]))
                     qline = metaStream.readLine()
                 continue
             elif section == u"WORDCENSUS":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (not qline.isEmpty()):
                     parts = unicode(qline).split(' ')
                     IMC.wordCensus.append(QString(parts[0]),int(parts[1]),int(parts[2]))
                     qline = metaStream.readLine()
                 continue
             elif section == u"BOOKMARKS":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (not qline.isEmpty()):
                     parts = unicode(qline).split(' ')
                     tc = QTextCursor(self.document() )
                     tc.setPosition(int(parts[1]))
                     if len(parts) == 3 : # early versions didn't save anchor
                         tc.movePosition(int(parts[2]),QTextCursor.KeepAnchor)
                     self.bookMarkList[int(parts[0])] = tc
                     qline = metaStream.readLine()
                 continue
             elif section == u"NOTES":
                 e = IMC.notesEditor
                 e.setUndoRedoEnabled(False)
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and not metaStream.atEnd():
                     if qline.startsWith(u"\xfffd"): # escaped {{
                         qline.remove(0,1)
                     e.appendPlainText(qline)
                     qline = metaStream.readLine()
                 e.setUndoRedoEnabled(True)
                 continue
             elif section == u"GOODWORDS" :
                 # not going to bother checking for endsec return,
                 # if it isn't that then we will shortly fail anyway
                 w = IMC.goodWordList.load(metaStream,endsec)
                 continue
             elif section == u"BADWORDS" :
                 w = IMC.badWordList.load(metaStream,endsec)
                 continue
             elif section == u"CURSOR" : # restore selection as of save
                 p1p2 = argument.split(' ')
                 tc = QTextCursor(self.document())
                 tc.setPosition(int(p1p2[0]),QTextCursor.MoveAnchor)
                 tc.setPosition(int(p1p2[1]),QTextCursor.KeepAnchor)
                 self.setTextCursor(tc)
             else:
                 # this can't happen; section is text captured by the RE
                 # and we have accounted for all possibilities
                 raise AssertionError, "impossible metadata"
         else: # Non-blank line that doesn't match sectionRE?
             pqMsgs.infoMsg(
                 "Unexpected line in metadata: {0}".format(pqMsgs.trunc(qline,20)),
                     "Metadata may be incomplete, suggest quit")
             break
Exemple #6
0
 def loadMetadata(self, metaStream):
     sectionRE = QRegExp( u"\{\{(" + '|'.join (
         ['PAGETABLE','CHARCENSUS','WORDCENSUS','BOOKMARKS',
          'NOTES','GOODWORDS','BADWORDS','CURSOR','VERSION',
          'STALECENSUS','NEEDSPELLCHECK','ENCODING', 'DOCHASH', 'MAINDICT'] ) \
                          + u")(.*)\}\}",
         Qt.CaseSensitive)
     metaVersion = 0  # base version
     while not metaStream.atEnd():
         qline = metaStream.readLine().trimmed()
         if qline.isEmpty(): continue  # allow blank lines between sections
         if sectionRE.exactMatch(qline):  # section start
             section = sectionRE.cap(1)
             argument = unicode(sectionRE.cap(2).trimmed())
             endsec = QString(u"{{/" + section + u"}}")
             if section == u"VERSION":
                 if len(argument) != 0:
                     metaVersion = int(argument)
                 continue  # no more data after {{VERSION x }}
             elif section == u"STALECENSUS":
                 if argument == u"TRUE":
                     IMC.staleCensus = IMC.staleCensusLoaded
                 continue  # no more data after {{STALECENSUS x}}
             elif section == u"NEEDSPELLCHECK":
                 if argument == u"TRUE":
                     IMC.needSpellCheck = True
                 continue  # no more data after {{NEEDSPELLCHECK x}}
             elif section == u"ENCODING":
                 IMC.bookSaveEncoding = QString(argument)
                 continue
             elif section == u"MAINDICT":
                 IMC.bookMainDict = QString(argument)
                 continue
             elif section == u"DOCHASH":
                 IMC.metaHash = argument
                 continue
             elif section == u"PAGETABLE":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (
                         not qline.isEmpty()):
                     IMC.pageTable.metaStringIn(qline)
                     qline = metaStream.readLine()
                 continue
             elif section == u"CHARCENSUS":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (
                         not qline.isEmpty()):
                     # can't just .split the char census, the first
                     # char is the char being counted and it can be a space.
                     str = unicode(qline)
                     parts = str[2:].split(' ')
                     IMC.charCensus.append(QString(str[0]), int(parts[0]),
                                           int(parts[1]))
                     qline = metaStream.readLine()
                 continue
             elif section == u"WORDCENSUS":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (
                         not qline.isEmpty()):
                     parts = unicode(qline).split(' ')
                     IMC.wordCensus.append(QString(parts[0]), int(parts[1]),
                                           int(parts[2]))
                     qline = metaStream.readLine()
                 continue
             elif section == u"BOOKMARKS":
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)) and (
                         not qline.isEmpty()):
                     parts = unicode(qline).split(' ')
                     tc = QTextCursor(self.document())
                     tc.setPosition(int(parts[1]))
                     if len(parts
                            ) == 3:  # early versions didn't save anchor
                         tc.movePosition(int(parts[2]),
                                         QTextCursor.KeepAnchor)
                     self.bookMarkList[int(parts[0])] = tc
                     qline = metaStream.readLine()
                 continue
             elif section == u"NOTES":
                 e = IMC.notesEditor
                 e.setUndoRedoEnabled(False)
                 qline = metaStream.readLine()
                 while (not qline.startsWith(endsec)
                        ) and not metaStream.atEnd():
                     if qline.startsWith(u"\xfffd"):  # escaped {{
                         qline.remove(0, 1)
                     e.appendPlainText(qline)
                     qline = metaStream.readLine()
                 e.setUndoRedoEnabled(True)
                 continue
             elif section == u"GOODWORDS":
                 # not going to bother checking for endsec return,
                 # if it isn't that then we will shortly fail anyway
                 w = IMC.goodWordList.load(metaStream, endsec)
                 continue
             elif section == u"BADWORDS":
                 w = IMC.badWordList.load(metaStream, endsec)
                 continue
             elif section == u"CURSOR":  # restore selection as of save
                 p1p2 = argument.split(' ')
                 tc = QTextCursor(self.document())
                 tc.setPosition(int(p1p2[0]), QTextCursor.MoveAnchor)
                 tc.setPosition(int(p1p2[1]), QTextCursor.KeepAnchor)
                 self.setTextCursor(tc)
             else:
                 # this can't happen; section is text captured by the RE
                 # and we have accounted for all possibilities
                 raise AssertionError, "impossible metadata"
         else:  # Non-blank line that doesn't match sectionRE?
             pqMsgs.infoMsg(
                 "Unexpected line in metadata: {0}".format(
                     pqMsgs.trunc(qline, 20)),
                 "Metadata may be incomplete, suggest quit")
             break