Never thought it would be so boring to code that part

This commit is contained in:
Olivier Keshavjee 2016-03-09 13:20:52 +01:00
parent 518d4c7201
commit 97903b2781
2 changed files with 58 additions and 30 deletions

View file

@ -5,7 +5,7 @@
# Aims at providing a plain-text way of saving a project # Aims at providing a plain-text way of saving a project
# (except for some elements), allowing collaborative work # (except for some elements), allowing collaborative work
# versioning and third-partty editing. # versioning and third-partty editing.
import os import os, shutil
import string import string
import zipfile import zipfile
@ -80,6 +80,8 @@ def saveProject(zip=None):
zip = False zip = False
# Fixme # Fixme
print("\n\n", "Saving to:", "zip" if zip else "folder")
# List of files to be written # List of files to be written
files = [] files = []
# List of files to be removed # List of files to be removed
@ -204,8 +206,9 @@ def saveProject(zip=None):
# In an outline folder # In an outline folder
mdl = mw.mdlOutline mdl = mw.mdlOutline
for filename, content in exportOutlineItem(mdl.rootItem): f, r = exportOutlineItem(mdl.rootItem)
files.append((filename, content)) files += f
removes += r
# World (mw.mdlWorld) # World (mw.mdlWorld)
# Either in an XML file, or in lots of plain texts? # Either in an XML file, or in lots of plain texts?
@ -259,24 +262,36 @@ def saveProject(zip=None):
else: else:
dir = os.path.dirname(project) dir = os.path.dirname(project)
folder = os.path.splitext(os.path.basename(project))[0] folder = os.path.splitext(os.path.basename(project))[0]
print("Saving to folder", folder) print("\nSaving to folder", folder)
for path in removes: for path in removes:
if path not in [p for p,c in files]: if path not in [p for p,c in files]:
filename = os.path.join(dir, folder, path) filename = os.path.join(dir, folder, path)
print("* Removing", filename) print("* Removing", filename)
os.remove(filename) if os.path.isdir(filename):
cache.pop(path) shutil.rmtree(filename)
# FIXME: when deleting a folder, there are still files in "removes".
# FIXME: if user copied custom files in the directory, they will be lost.
# need to find a way to rename instead of remove.
# FIXME: items removed have to be removed (not just the renamed)
else: # elif os.path.exists(filename)
os.remove(filename)
cache.pop(path, 0)
for path, content in files: for path, content in files:
filename = os.path.join(dir, folder, path) filename = os.path.join(dir, folder, path)
os.makedirs(os.path.dirname(filename), exist_ok=True) os.makedirs(os.path.dirname(filename), exist_ok=True)
print("* Saving file", filename) # print("* Saving file", filename)
# TODO: the first time it saves, it will overwrite everything, since it's not yet in cache. # TODO: the first time it saves, it will overwrite everything, since it's not yet in cache.
# Or we have to cache while loading. # Or we have to cache while loading.
if not path in cache or cache[path] != content: if not path in cache or cache[path] != content:
print("* Saving file", filename)
print(" Not in cache or changed: we write") print(" Not in cache or changed: we write")
mode = "w"+ ("b" if type(content) == bytes else "") mode = "w"+ ("b" if type(content) == bytes else "")
with open(filename, mode) as f: with open(filename, mode) as f:
@ -284,7 +299,8 @@ def saveProject(zip=None):
cache[path] = content cache[path] = content
else: else:
print(" In cache, and identical. Do nothing.") pass
# print(" In cache, and identical. Do nothing.")
def addWorldItem(root, mdl, parent=QModelIndex()): def addWorldItem(root, mdl, parent=QModelIndex()):
@ -375,13 +391,17 @@ def addPlotItem(root, mdl, parent=QModelIndex()):
def exportOutlineItem(root): def exportOutlineItem(root):
""" """
Takes an outline item, and returns an array of (`filename`, `content`) sets, representing the whole tree Takes an outline item, and returns two lists:
of items converted to mmd. 1. of (`filename`, `content`), representing the whole tree of files to be written, in multimarkdown.
2. of `filename`, representing files to be removed.
@param root: OutlineItem @param root: OutlineItem
@return: (str, str) @return: [(str, str)], [str]
""" """
r = []
files = []
removes = []
path = "outline" path = "outline"
k=0 k=0
@ -389,25 +409,38 @@ def exportOutlineItem(root):
spath = os.path.join(path, *outlineItemPath(child)) spath = os.path.join(path, *outlineItemPath(child))
k += 1 k += 1
# Has the item been renamed?
# If so, we mark the old file for removal
if "Herod_dies" in spath:
print(child.title(), spath, "<==", child.lastPath)
if child.lastPath and spath != child.lastPath:
removes.append(child.lastPath)
print(child.title(), "has been renamed (", child.lastPath, "", spath, ")")
print(" → We remove:", child.lastPath)
child.lastPath = spath
if child.type() == "folder": if child.type() == "folder":
fpath = os.path.join(spath, "folder.txt") fpath = os.path.join(spath, "folder.txt")
content = outlineToMMD(child) content = outlineToMMD(child)
r.append((fpath, content)) files.append((fpath, content))
elif child.type() in ["txt", "t2t"]: elif child.type() in ["txt", "t2t"]:
content = outlineToMMD(child) content = outlineToMMD(child)
r.append((spath, content)) files.append((spath, content))
elif child.type() in ["html"]: elif child.type() in ["html"]:
# Convert first # FIXME: Convert first
pass pass
else: else:
print("Unknown type") print("Unknown type")
r += exportOutlineItem(child) f, r = exportOutlineItem(child)
files += f
removes += r
return r return files, removes
def outlineItemPath(item): def outlineItemPath(item):
# Root item # Root item

View file

@ -400,19 +400,6 @@ class outlineModel(QAbstractItemModel):
self.rootItem = outlineItem(model=self, xml=ET.tostring(root), ID="0") self.rootItem = outlineItem(model=self, xml=ET.tostring(root), ID="0")
self.rootItem.checkIDs() self.rootItem.checkIDs()
def pathToIndex(self, index, path=""):
# FIXME: Use item's ID instead of rows
if not index.isValid():
return ""
if index.parent().isValid():
path = self.pathToIndex(index.parent())
if path:
path = "{},{}".format(path, str(index.row()))
else:
path = str(index.row())
return path
def indexFromPath(self, path): def indexFromPath(self, path):
path = path.split(",") path = path.split(",")
item = self.rootItem item = self.rootItem
@ -431,6 +418,8 @@ class outlineItem():
self._model = model self._model = model
self.defaultTextType = None self.defaultTextType = None
self.IDs = [] # used by root item to store unique IDs self.IDs = [] # used by root item to store unique IDs
self.lastPath = "" # used by loadSave version_1 to remember which files the items comes from,
# in case it is renamed / removed
if title: if title:
self._data[Outline.title] = title self._data[Outline.title] = title
@ -758,6 +747,9 @@ class outlineItem():
revItem.set("text", r[1]) revItem.set("text", r[1])
item.append(revItem) item.append(revItem)
# Saving lastPath
item.set("lastPath", self.lastPath)
for i in self.childItems: for i in self.childItems:
item.append(ET.XML(i.toXML())) item.append(ET.XML(i.toXML()))
@ -773,6 +765,9 @@ class outlineItem():
# else: # else:
self.setData(Outline.__members__[k].value, str(root.attrib[k])) self.setData(Outline.__members__[k].value, str(root.attrib[k]))
if "lastPath" in root.attrib:
self.lastPath = root.attrib["lastPath"]
for child in root: for child in root:
if child.tag == "outlineItem": if child.tag == "outlineItem":
item = outlineItem(self._model, xml=ET.tostring(child), parent=self) item = outlineItem(self._model, xml=ET.tostring(child), parent=self)