mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-06-13 16:34:34 +12:00
Never thought it would be so boring to code that part
This commit is contained in:
parent
518d4c7201
commit
97903b2781
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue