def createContent(self, exporter, exportType, insToken): """ Handle an insertion and create the appropriate content. exporter -- Exporter object calling the handler exportType -- string describing the export type insToken -- insertion token to create content for An insertion token has the following member variables: key: insertion key (unistring) value: value of an insertion (unistring) appendices: sequence of strings with the appendices Meaning and type of return value is solely defined by the type of the calling exporter. For HtmlExporter a unistring is returned with the HTML code to insert instead of the insertion. """ if not insToken.value: # Nothing in, nothing out return "" if self.extAppExe == "": # No path to Gnuplot executable -> show message return '<pre>' + _('[Please set path to Gnuplot executable]') +\ '</pre>' # Get exporters temporary file set (manages creation and deletion of # temporary files) tfs = exporter.getTempFileSet() pythonUrl = (exportType != "html_previewWX") dstFullPath = tfs.createTempFile("", ".png", relativeTo="") url = tfs.getRelativeUrl(None, dstFullPath, pythonUrl=pythonUrl) baseDir = os.path.dirname( exporter.getMainControl().getWikiConfigPath()) # Prepend source code with appropriate settings for PNG output srcCode = ("set terminal png\nset output '%s'\n" % dstFullPath) + \ insToken.value # Retrieve quoted content of the insertion bstr = lineendToOs(mbcsEnc(srcCode, "replace")[0]) # Store token content in a temporary file srcfilepath = createTempFile(bstr, ".gpt") try: cmdline = subprocess.list2cmdline((self.extAppExe, srcfilepath)) # Run external application # childIn, childOut, childErr = os.popen3(cmdline, "b") popenObject = subprocess.Popen(cmdline, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE) childErr = popenObject.stderr # See http://bytes.com/topic/python/answers/634409-subprocess-handle-invalid-error # why this is necessary popenObject.stdin.close() popenObject.stdout.close() if "noerror" in [a.strip() for a in insToken.appendices]: childErr.read() errResponse = b"" else: errResponse = childErr.read() childErr.close() finally: os.unlink(srcfilepath) if errResponse != b"": errResponse = mbcsDec(errResponse, "replace")[0] return '<pre>' + _('[Gnuplot error: %s]') % errResponse +\ '</pre>' # Return appropriate HTML code for the image if exportType == "html_previewWX": # Workaround for internal HTML renderer return ('<img src="%s" border="0" align="bottom" alt="gnuplot" />' ' ') % url else: return '<img src="%s" border="0" align="bottom" alt="gnuplot" />' \ % url
def createContent(self, exporter, exportType, insToken): """ Handle an insertion and create the appropriate content. exporter -- Exporter object calling the handler exportType -- string describing the export type insToken -- insertion token to create content for An insertion token has the following member variables: key: insertion key (unistring) value: value of an insertion (unistring) appendices: sequence of strings with the appendices Meaning and type of return value is solely defined by the type of the calling exporter. For HtmlExporter a unistring is returned with the HTML code to insert instead of the insertion. """ bstr = urllib.quote(mbcsEnc(insToken.value, "replace")[0]) if not bstr: # Nothing in, nothing out return u"" if self.extAppExe == "": # No path to MimeTeX executable -> show message return u'<pre>' + _(u'[Please set path to MimeTeX executable]') + \ '</pre>' # Prepare CGI environment. MimeTeX needs only "QUERY_STRING" environment # variable os.environ["QUERY_STRING"] = bstr cmdline = subprocess.list2cmdline((self.extAppExe,)) # childIn, childOut = os.popen2(cmdline, "b") # Run MimeTeX process popenObject = subprocess.Popen(cmdline, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) childOut = popenObject.stdout # See http://bytes.com/topic/python/answers/634409-subprocess-handle-invalid-error # why this is necessary popenObject.stdin.close() popenObject.stderr.close() # Read stdout of process entirely response = childOut.read() childOut.close() # Cut off HTTP header (may need changes for non-Windows OS) try: response = response[(response.index("\n\n") + 2):] except ValueError: return u'<pre>' + _(u'[Invalid response from MimeTeX]') + \ '</pre>' # Get exporters temporary file set (manages creation and deletion of # temporary files) tfs = exporter.getTempFileSet() # Create .gif file out of returned data and retrieve URL for the file pythonUrl = (exportType != "html_previewWX") url = tfs.createTempUrl(response, ".gif", pythonUrl=pythonUrl) # Return appropriate HTML code for the image if exportType == "html_previewWX": # Workaround for internal HTML renderer return (u'<img src="%s" border="0" align="bottom" alt="formula" />' u' ') % url else: return u'<img src="%s" border="0" align="bottom" alt="formula" />' \ % url
def createContent(self, exporter, exportType, insToken): """ Handle an insertion and create the appropriate content. exporter -- Exporter object calling the handler exportType -- string describing the export type insToken -- insertion token to create content for An insertion token has the following member variables: key: insertion key (unistring) value: value of an insertion (unistring) appendices: sequence of strings with the appendices Meaning and type of return value is solely defined by the type of the calling exporter. For HtmlExporter a unistring is returned with the HTML code to insert instead of the insertion. """ bstr = urllib.parse.quote(mbcsEnc(insToken.value, "replace")[0]) if not bstr: # Nothing in, nothing out return "" if self.extAppExe == "": # No path to MimeTeX executable -> show message return '<pre>' + _('[Please set path to MimeTeX executable]') + \ '</pre>' # Prepare CGI environment. MimeTeX needs only "QUERY_STRING" environment # variable os.environ["QUERY_STRING"] = bstr cmdline = subprocess.list2cmdline((self.extAppExe, )) # childIn, childOut = os.popen2(cmdline, "b") # Run MimeTeX process popenObject = subprocess.Popen(cmdline, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) childOut = popenObject.stdout # See http://bytes.com/topic/python/answers/634409-subprocess-handle-invalid-error # why this is necessary popenObject.stdin.close() popenObject.stderr.close() # Read stdout of process entirely response = childOut.read() childOut.close() # Cut off HTTP header (may need changes for non-Windows OS) try: response = response[(response.index(b"\n\n") + 2):] except ValueError: return '<pre>' + _('[Invalid response from MimeTeX]') + \ '</pre>' # Get exporters temporary file set (manages creation and deletion of # temporary files) tfs = exporter.getTempFileSet() # Create .gif file out of returned data and retrieve URL for the file pythonUrl = (exportType != "html_previewWX") url = tfs.createTempUrl(response, ".gif", pythonUrl=pythonUrl) # Return appropriate HTML code for the image if exportType == "html_previewWX": # Workaround for internal HTML renderer return ('<img src="%s" border="0" align="bottom" alt="formula" />' ' ') % url else: return '<img src="%s" border="0" align="bottom" alt="formula" />' \ % url
def createContent(self, exporter, exportType, insToken): """ Handle an insertion and create the appropriate content. exporter -- Exporter object calling the handler exportType -- string describing the export type insToken -- insertion token to create content for An insertion token has the following member variables: key: insertion key (unistring) value: value of an insertion (unistring) appendices: sequence of strings with the appendices Meaning and type of return value is solely defined by the type of the calling exporter. For HtmlExporter a unistring is returned with the HTML code to insert instead of the insertion. """ if not insToken.value: # Nothing in, nothing out return u"" if self.extAppExe == "": # No path to Gnuplot executable -> show message return u'<pre>' + _(u'[Please set path to Gnuplot executable]') +\ u'</pre>' # Get exporters temporary file set (manages creation and deletion of # temporary files) tfs = exporter.getTempFileSet() pythonUrl = (exportType != "html_previewWX") dstFullPath = tfs.createTempFile("", ".png", relativeTo="") url = tfs.getRelativeUrl(None, dstFullPath, pythonUrl=pythonUrl) baseDir = os.path.dirname(exporter.getMainControl().getWikiConfigPath()) # Prepend source code with appropriate settings for PNG output srcCode = ("set terminal png\nset output '%s'\n" % dstFullPath) + \ insToken.value # Retrieve quoted content of the insertion bstr = lineendToOs(mbcsEnc(srcCode, "replace")[0]) # Store token content in a temporary file srcfilepath = createTempFile(bstr, ".gpt") try: cmdline = subprocess.list2cmdline((self.extAppExe, srcfilepath)) # Run external application # childIn, childOut, childErr = os.popen3(cmdline, "b") popenObject = subprocess.Popen(cmdline, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE) childErr = popenObject.stderr # See http://bytes.com/topic/python/answers/634409-subprocess-handle-invalid-error # why this is necessary popenObject.stdin.close() popenObject.stdout.close() if u"noerror" in [a.strip() for a in insToken.appendices]: childErr.read() errResponse = "" else: errResponse = childErr.read() childErr.close() finally: os.unlink(srcfilepath) if errResponse != "": errResponse = mbcsDec(errResponse, "replace")[0] return u'<pre>' + _(u'[Gnuplot error: %s]') % errResponse +\ u'</pre>' # Return appropriate HTML code for the image if exportType == "html_previewWX": # Workaround for internal HTML renderer return (u'<img src="%s" border="0" align="bottom" alt="gnuplot" />' u' ') % url else: return u'<img src="%s" border="0" align="bottom" alt="gnuplot" />' \ % url
def updateDatabase(connwrap, dataDir, pagefileSuffix): """ Update a database from an older version to current (checkDatabaseFormat() should have returned 1 before calling this function) """ connwrap.commit() indices = connwrap.execSqlQuerySingleColumn( "select INDEX_NAME from __indices__") tables = connwrap.execSqlQuerySingleColumn( "select TABLE_NAME from __table_names__") indices = map(string.upper, indices) tables = map(string.upper, tables) # updatedTables = [] if not "SETTINGS" in tables: # We are prior WikidPad 1.2beta2 (which writes format version 0) if "WIKIWORDPROPS_PKEY" in indices: # print "dropping index wikiwordprops_pkey" connwrap.execSql("drop index wikiwordprops_pkey") # if "WIKIWORDPROPS_WORD" not in indices: # print "creating index wikiwordprops_word" # connwrap.execSql("create index wikiwordprops_word on wikiwordprops(word)") # if "WIKIRELATIONS_WORD" not in indices: # print "creating index wikirelations_word" # connwrap.execSql("create index wikirelations_word on wikirelations(word)") if "REGISTRATION" in tables: connwrap.execSql("drop table registration") # Update search_views searches = connwrap.execSqlQuerySingleColumn( "select search from search_views") changeTableSchema(connwrap, "search_views", TABLE_DEFINITIONS["search_views"]) for search in searches: searchOp = SearchReplaceOperation() searchOp.searchStr = search searchOp.wikiWide = True searchOp.booleanOp = True try: # Raises exception if search is invalid searchOp.rebuildSearchOpTree() except: continue datablock = searchOp.getPackedSettings() connwrap.execSql( "insert into search_views(title, datablock) "+\ "values (?, ?)", (searchOp.getTitle(), datablock)) formatver = 0 changeTableSchema(connwrap, "settings", TABLE_DEFINITIONS["settings"]) # Write initial format versions for key, value in ( ("formatver", "0"), # Version of database format the data was written ("writecompatver", "0"), # Lowest format version which is write compatible ("readcompatver", "0"), # Lowest format version which is read compatible ("branchtag", "WikidPad") # Tag of the WikidPad branch ): setSettingsValue(connwrap, key, value) # --- WikiPad 1.20beta2 reached (formatver=0, writecompatver=0, # readcompatver=0) --- formatver = getSettingsInt(connwrap, "formatver") if formatver == 0: # From formatver 0 to 1, all filenames with brackets are renamed # to have no brackets filenames = glob.glob(join(mbcsEnc(dataDir, "replace")[0], '*.wiki')) for fn in filenames: fn = mbcsDec(fn, "replace")[0] bn = basename(fn) newbname = removeBracketsFilename(bn) if bn == newbname: continue newname = mbcsEnc(join(dataDir, newbname), "replace")[0] if exists(pathEnc(newname)): # A file with the designated new name of fn already exists # -> do nothing continue try: rename(fn, newname) except (IOError, OSError): pass formatver = 1 # --- WikiPad 1.20beta3 reached (formatver=1, writecompatver=1, # readcompatver=1) --- if formatver == 1: # remove brackets from all wikiwords in database # table wikiwords dataIn = connwrap.execSqlQuery( "select word, created, modified from wikiwords") connwrap.execSql("drop table wikiwords") connwrap.commit() changeTableSchema(connwrap, "wikiwords", TABLE_DEFINITIONS["wikiwords"]) rebuildIndices(connwrap) uniqueCtl = {} for w, c, m in dataIn: w = oldWikiWordToLabel(w) if not uniqueCtl.has_key(w): connwrap.execSqlInsert( "wikiwords", ("word", "created", "modified", "presentationdatablock"), (w, c, m, "")) # connwrap.execSql("insert into wikiwords(word, created, modified) " # "values (?, ?, ?)", (w, c, m)) uniqueCtl[w] = None # table wikirelations dataIn = connwrap.execSqlQuery( "select word, relation, created from wikirelations") connwrap.execSql("drop table wikirelations") connwrap.commit() changeTableSchema(connwrap, "wikirelations", TABLE_DEFINITIONS["wikirelations"]) rebuildIndices(connwrap) uniqueCtl = {} for w, r, c in dataIn: w, r = oldWikiWordToLabel(w), oldWikiWordToLabel(r) if not uniqueCtl.has_key((w, r)): connwrap.execSqlInsert("wikirelations", ("word", "relation", "created"), (w, r, c)) # connwrap.execSql("insert into wikirelations(word, relation, created) " # "values (?, ?, ?)", (w, r, c)) uniqueCtl[(w, r)] = None # table wikiwordprops dataIn = connwrap.execSqlQuery( "select word, key, value from wikiwordprops") connwrap.execSql("drop table wikiwordprops") connwrap.commit() changeTableSchema(connwrap, "wikiwordprops", TABLE_DEFINITIONS["wikiwordprops_PRE2_1alpha01"]) rebuildIndices(connwrap) for w, k, v in dataIn: connwrap.execSqlInsert("wikiwordprops", ("word", "key", "value"), (oldWikiWordToLabel(w), k, v), tableDefault="wikiwordprops_PRE2_1alpha01") # connwrap.execSql("insert into wikiwordprops(word, key, value) " # "values (?, ?, ?)", (oldWikiWordToLabel(w), k, v)) # table todos dataIn = connwrap.execSqlQuery("select word, todo from todos") connwrap.execSql("drop table todos") connwrap.commit() changeTableSchema(connwrap, "todos", TABLE_DEFINITIONS["todos_PRE2_1alpha01"]) rebuildIndices(connwrap) for w, t in dataIn: connwrap.execSqlInsert("todos", ("word", "todo"), (oldWikiWordToLabel(w), t), tableDefault="todos_PRE2_1alpha01") # connwrap.execSql("insert into todos(word, todo) " # "values (?, ?)", (oldWikiWordToLabel(w), t)) formatver = 2 # --- WikiPad 1.6beta2 reached (formatver=2, writecompatver=2, # readcompatver=2) --- if formatver == 2: changeTableSchema(connwrap, "wikiwords", TABLE_DEFINITIONS["wikiwords"]) # --- WikiPad 1.8beta1 reached (formatver=3, writecompatver=3, # readcompatver=2) --- formatver = 3 if formatver == 3: # Update "wikiwords" schema and create new tables for tn in ("wikiwords", "wikiwordmatchterms", "datablocks", "datablocksexternal", "defaultvalues"): changeTableSchema(connwrap, tn, TABLE_DEFINITIONS[tn]) # (Re)fill "defaultvalues" and read them into connection wrapper connwrap.fillDefaultValues() connwrap.readDefaultValues() # Transfer "search_views" data to "datablocks" table searches = connwrap.execSqlQuery( "select title, datablock from search_views", strConv=(True, False)) for title, data in searches: connwrap.execSql( "insert into datablocks(unifiedname, data) "+\ "values (?, ?)", (u"savedsearch/" + title, data)) connwrap.execSql("drop table search_views") allWords = connwrap.execSqlQuerySingleColumn( "select word from wikiwords") # Divide into functional and wiki pages wikiWords = [] funcWords = [] for w in allWords: if w.startswith('['): funcWords.append(w) else: wikiWords.append(w) # Fill the new fields in table "wikiwords" for wikiWord in wikiWords: filename = wikiWord + pagefileSuffix fullPath = join(dataDir, filename) try: # We don't use coarsening here for the FSB because a different # coarsening setting can't exist for the old wiki format filesig = getFileSignatureBlock(fullPath) except (IOError, WindowsError): traceback.print_exc() continue connwrap.execSql( "update wikiwords set filepath = ?, " "filenamelowercase = ?, filesignature = ? " "where word = ?", (filename, filename.lower(), filesig, wikiWord)) # Move functional pages to new table "datablocksexternal" and rename them for funcWord in funcWords: if funcWord not in (u"[TextBlocks]", u"[PWL]", u"[CCBlacklist]"): continue # Error ?! unifName = u"wiki/" + funcWord[1:-1] fullPath = join(dataDir, funcWord + pagefileSuffix) icf = iterCompatibleFilename(unifName, u".data") for i in range( 10): # Actual "while True", but that's too dangerous newFilename = icf.next() newPath = join(dataDir, newFilename) if exists(pathEnc(newPath)): # A file with the designated new name of fn already exists # -> do nothing continue try: rename(pathEnc(fullPath), pathEnc(newPath)) # We don't use coarsening here for the FSB because a different # coarsening setting can't exist for the old wiki format connwrap.execSqlInsert( "datablocksexternal", ("unifiedname", "filepath", "filenamelowercase", "filesignature"), (unifName, newFilename, newFilename.lower(), getFileSignatureBlock(newPath))) connwrap.execSql("delete from wikiwords where word = ?", (funcWord, )) break except (IOError, OSError): traceback.print_exc() continue # --- WikiPad 2.0alpha1 reached (formatver=4, writecompatver=4, # readcompatver=4) --- formatver = 4 if formatver == 4: # (Re)fill "defaultvalues" and read them into connection wrapper connwrap.fillDefaultValues() connwrap.readDefaultValues() # Recreate table "todos" with new schema connwrap.execSql("drop table todos") changeTableSchema(connwrap, "todos", TABLE_DEFINITIONS["todos"]) # Rename table "wikiwordprops" to "wikiwordattrs" changeTableSchema(connwrap, "wikiwordattrs", TABLE_DEFINITIONS["wikiwordattrs"]) connwrap.execSql("insert into wikiwordattrs(word, key, value) " "select word, key, value from wikiwordprops") connwrap.execSql("drop table wikiwordprops") for tn in ("wikirelations", "wikiwordmatchterms"): changeTableSchema(connwrap, tn, TABLE_DEFINITIONS[tn]) # Mark all wikiwords to need a rebuild connwrap.execSql("update wikiwords set metadataprocessed=0") formatver = 5 # --- WikiPad 2.1alpha.1 reached (formatver=5, writecompatver=5, # readcompatver=5) --- # Write format information for key, value in ( ("formatver", str(VERSION_DB)), # Version of database format the data was written ("writecompatver", str(VERSION_WRITECOMPAT) ), # Lowest format version which is write compatible ("readcompatver", str(VERSION_READCOMPAT) ), # Lowest format version which is read compatible ("branchtag", "WikidPad"), # Tag of the WikidPad branch ("locale", "-" ) # Locale for cached wordnormcase column. '-': column invalid ): setSettingsValue(connwrap, key, value) rebuildIndices(connwrap) connwrap.commit()
def updateDatabase(connwrap, dataDir, pagefileSuffix): """ Update a database from an older version to current (checkDatabaseFormat() should have returned 1 before calling this function) """ connwrap.commit() indices = connwrap.execSqlQuerySingleColumn("select INDEX_NAME from __indices__") tables = connwrap.execSqlQuerySingleColumn("select TABLE_NAME from __table_names__") indices = map(string.upper, indices) tables = map(string.upper, tables) # updatedTables = [] if not "SETTINGS" in tables: # We are prior WikidPad 1.2beta2 (which writes format version 0) if "WIKIWORDPROPS_PKEY" in indices: # print "dropping index wikiwordprops_pkey" connwrap.execSql("drop index wikiwordprops_pkey") # if "WIKIWORDPROPS_WORD" not in indices: # print "creating index wikiwordprops_word" # connwrap.execSql("create index wikiwordprops_word on wikiwordprops(word)") # if "WIKIRELATIONS_WORD" not in indices: # print "creating index wikirelations_word" # connwrap.execSql("create index wikirelations_word on wikirelations(word)") if "REGISTRATION" in tables: connwrap.execSql("drop table registration") # Update search_views searches = connwrap.execSqlQuerySingleColumn( "select search from search_views") changeTableSchema(connwrap, "search_views", TABLE_DEFINITIONS["search_views"]) for search in searches: searchOp = SearchReplaceOperation() searchOp.searchStr = search searchOp.wikiWide = True searchOp.booleanOp = True try: # Raises exception if search is invalid searchOp.rebuildSearchOpTree() except: continue datablock = searchOp.getPackedSettings() connwrap.execSql( "insert into search_views(title, datablock) "+\ "values (?, ?)", (searchOp.getTitle(), datablock)) formatver = 0 changeTableSchema(connwrap, "settings", TABLE_DEFINITIONS["settings"]) # Write initial format versions for key, value in ( ("formatver", "0"), # Version of database format the data was written ("writecompatver", "0"), # Lowest format version which is write compatible ("readcompatver", "0"), # Lowest format version which is read compatible ("branchtag", "WikidPad") # Tag of the WikidPad branch ): setSettingsValue(connwrap, key, value) # --- WikiPad 1.20beta2 reached (formatver=0, writecompatver=0, # readcompatver=0) --- formatver = getSettingsInt(connwrap, "formatver") if formatver == 0: # From formatver 0 to 1, all filenames with brackets are renamed # to have no brackets filenames = glob.glob(join(mbcsEnc(dataDir, "replace")[0], '*.wiki')) for fn in filenames: fn = mbcsDec(fn, "replace")[0] bn = basename(fn) newbname = removeBracketsFilename(bn) if bn == newbname: continue newname = mbcsEnc(join(dataDir, newbname), "replace")[0] if exists(pathEnc(newname)): # A file with the designated new name of fn already exists # -> do nothing continue try: rename(fn, newname) except (IOError, OSError): pass formatver = 1 # --- WikiPad 1.20beta3 reached (formatver=1, writecompatver=1, # readcompatver=1) --- if formatver == 1: # remove brackets from all wikiwords in database # table wikiwords dataIn = connwrap.execSqlQuery( "select word, created, modified from wikiwords") connwrap.execSql("drop table wikiwords") connwrap.commit() changeTableSchema(connwrap, "wikiwords", TABLE_DEFINITIONS["wikiwords"]) rebuildIndices(connwrap) uniqueCtl = {} for w, c, m in dataIn: w = oldWikiWordToLabel(w) if not uniqueCtl.has_key(w): connwrap.execSqlInsert("wikiwords", ("word", "created", "modified", "presentationdatablock"), (w, c, m, "")) # connwrap.execSql("insert into wikiwords(word, created, modified) " # "values (?, ?, ?)", (w, c, m)) uniqueCtl[w] = None # table wikirelations dataIn = connwrap.execSqlQuery( "select word, relation, created from wikirelations") connwrap.execSql("drop table wikirelations") connwrap.commit() changeTableSchema(connwrap, "wikirelations", TABLE_DEFINITIONS["wikirelations"]) rebuildIndices(connwrap) uniqueCtl = {} for w, r, c in dataIn: w, r = oldWikiWordToLabel(w), oldWikiWordToLabel(r) if not uniqueCtl.has_key((w, r)): connwrap.execSqlInsert("wikirelations", ("word", "relation", "created"), (w, r, c)) # connwrap.execSql("insert into wikirelations(word, relation, created) " # "values (?, ?, ?)", (w, r, c)) uniqueCtl[(w, r)] = None # table wikiwordprops dataIn = connwrap.execSqlQuery( "select word, key, value from wikiwordprops") connwrap.execSql("drop table wikiwordprops") connwrap.commit() changeTableSchema(connwrap, "wikiwordprops", TABLE_DEFINITIONS["wikiwordprops_PRE2_1alpha01"]) rebuildIndices(connwrap) for w, k, v in dataIn: connwrap.execSqlInsert("wikiwordprops", ("word", "key", "value"), (oldWikiWordToLabel(w), k, v), tableDefault="wikiwordprops_PRE2_1alpha01") # connwrap.execSql("insert into wikiwordprops(word, key, value) " # "values (?, ?, ?)", (oldWikiWordToLabel(w), k, v)) # table todos dataIn = connwrap.execSqlQuery( "select word, todo from todos") connwrap.execSql("drop table todos") connwrap.commit() changeTableSchema(connwrap, "todos", TABLE_DEFINITIONS["todos_PRE2_1alpha01"]) rebuildIndices(connwrap) for w, t in dataIn: connwrap.execSqlInsert("todos", ("word", "todo"), (oldWikiWordToLabel(w), t), tableDefault="todos_PRE2_1alpha01") # connwrap.execSql("insert into todos(word, todo) " # "values (?, ?)", (oldWikiWordToLabel(w), t)) formatver = 2 # --- WikiPad 1.6beta2 reached (formatver=2, writecompatver=2, # readcompatver=2) --- if formatver == 2: changeTableSchema(connwrap, "wikiwords", TABLE_DEFINITIONS["wikiwords"]) # --- WikiPad 1.8beta1 reached (formatver=3, writecompatver=3, # readcompatver=2) --- formatver = 3 if formatver == 3: # Update "wikiwords" schema and create new tables for tn in ("wikiwords", "wikiwordmatchterms", "datablocks", "datablocksexternal", "defaultvalues"): changeTableSchema(connwrap, tn, TABLE_DEFINITIONS[tn]) # (Re)fill "defaultvalues" and read them into connection wrapper connwrap.fillDefaultValues() connwrap.readDefaultValues() # Transfer "search_views" data to "datablocks" table searches = connwrap.execSqlQuery( "select title, datablock from search_views", strConv=(True, False)) for title, data in searches: connwrap.execSql( "insert into datablocks(unifiedname, data) "+\ "values (?, ?)", (u"savedsearch/" + title, data)) connwrap.execSql("drop table search_views") allWords = connwrap.execSqlQuerySingleColumn("select word from wikiwords") # Divide into functional and wiki pages wikiWords = [] funcWords = [] for w in allWords: if w.startswith('['): funcWords.append(w) else: wikiWords.append(w) # Fill the new fields in table "wikiwords" for wikiWord in wikiWords: filename = wikiWord + pagefileSuffix fullPath = join(dataDir, filename) try: # We don't use coarsening here for the FSB because a different # coarsening setting can't exist for the old wiki format filesig = getFileSignatureBlock(fullPath) except (IOError, WindowsError): traceback.print_exc() continue connwrap.execSql("update wikiwords set filepath = ?, " "filenamelowercase = ?, filesignature = ? " "where word = ?", (filename, filename.lower(), filesig, wikiWord)) # Move functional pages to new table "datablocksexternal" and rename them for funcWord in funcWords: if funcWord not in (u"[TextBlocks]", u"[PWL]", u"[CCBlacklist]"): continue # Error ?! unifName = u"wiki/" + funcWord[1:-1] fullPath = join(dataDir, funcWord + pagefileSuffix) icf = iterCompatibleFilename(unifName, u".data") for i in range(10): # Actual "while True", but that's too dangerous newFilename = icf.next() newPath = join(dataDir, newFilename) if exists(pathEnc(newPath)): # A file with the designated new name of fn already exists # -> do nothing continue try: rename(pathEnc(fullPath), pathEnc(newPath)) # We don't use coarsening here for the FSB because a different # coarsening setting can't exist for the old wiki format connwrap.execSqlInsert("datablocksexternal", ("unifiedname", "filepath", "filenamelowercase", "filesignature"), (unifName, newFilename, newFilename.lower(), getFileSignatureBlock(newPath))) connwrap.execSql("delete from wikiwords where word = ?", (funcWord,)) break except (IOError, OSError): traceback.print_exc() continue # --- WikiPad 2.0alpha1 reached (formatver=4, writecompatver=4, # readcompatver=4) --- formatver = 4 if formatver == 4: # (Re)fill "defaultvalues" and read them into connection wrapper connwrap.fillDefaultValues() connwrap.readDefaultValues() # Recreate table "todos" with new schema connwrap.execSql("drop table todos") changeTableSchema(connwrap, "todos", TABLE_DEFINITIONS["todos"]) # Rename table "wikiwordprops" to "wikiwordattrs" changeTableSchema(connwrap, "wikiwordattrs", TABLE_DEFINITIONS["wikiwordattrs"]) connwrap.execSql("insert into wikiwordattrs(word, key, value) " "select word, key, value from wikiwordprops") connwrap.execSql("drop table wikiwordprops") for tn in ("wikirelations", "wikiwordmatchterms"): changeTableSchema(connwrap, tn, TABLE_DEFINITIONS[tn]) # Mark all wikiwords to need a rebuild connwrap.execSql("update wikiwords set metadataprocessed=0") formatver = 5 # --- WikiPad 2.1alpha.1 reached (formatver=5, writecompatver=5, # readcompatver=5) --- # Write format information for key, value in ( ("formatver", str(VERSION_DB)), # Version of database format the data was written ("writecompatver", str(VERSION_WRITECOMPAT)), # Lowest format version which is write compatible ("readcompatver", str(VERSION_READCOMPAT)), # Lowest format version which is read compatible ("branchtag", "WikidPad"), # Tag of the WikidPad branch ("locale", "-") # Locale for cached wordnormcase column. '-': column invalid ): setSettingsValue(connwrap, key, value) rebuildIndices(connwrap) connwrap.commit()