Added new data models for plots with use of new file io

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
This commit is contained in:
TheJackiMonster 2021-05-04 23:04:53 +02:00
parent 5239598a91
commit dfe6cdece2
No known key found for this signature in database
GPG key ID: D850A5F772E880F9
6 changed files with 257 additions and 115 deletions

24
bin/test_io.py Normal file
View file

@ -0,0 +1,24 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import sys
realpath = os.path.realpath(__file__)
sys.path.insert(1, os.path.join(os.path.dirname(realpath), '..'))
import manuskript.io as io
import manuskript.data as data
path = os.path.join(sys.path[1], "sample-projects/book-of-acts/settings.txt")
settings = io.JsonFile(path)
result = settings.load()
print(result)
plots = data.Plots(os.path.join(sys.path[1], "sample-projects/book-of-acts/plots.xml"))
plots.load()
plots.save()

View file

@ -0,0 +1,5 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from manuskript.data.unique_id import UniqueIDHost, UniqueID
from manuskript.data.plots import Plots, PlotLine, PlotStep

185
manuskript/data/plots.py Normal file
View file

@ -0,0 +1,185 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from lxml import etree
from enum import Enum, unique
from manuskript.data.unique_id import UniqueIDHost, UniqueID
from manuskript.io.xmlFile import XmlFile
@unique
class PlotImportance(Enum):
MINOR = 0
SECONDARY = 1
MAIN = 2
class PlotStep:
def __init__(self, plot, UID: UniqueID, name: str, meta: str = "", summary: str = ""):
self.plot = plot
self.UID = UID
self.name = name
self.meta = meta
self.summary = summary
def save(self):
self.plot.save()
class PlotLine:
def __init__(self, plots, UID: UniqueID, name: str, importance: PlotImportance = PlotImportance.MINOR):
self.plots = plots
self.host = UniqueIDHost()
self.UID = UID
self.name = name
self.importance = importance
self.characters = list()
self.description = ""
self.result = ""
self.steps = list()
def addStep(self, name: str, meta: str = "", summary: str = ""):
step = PlotStep(self, self.host.newID(), name, meta, summary)
self.steps.append(step)
return step
def loadStep(self, ID: int, name: str, meta: str = "", summary: str = ""):
step = PlotStep(self, self.host.loadID(ID), name, meta, summary)
self.steps.append(step)
return step
def removeStep(self, step: PlotStep):
self.host.removeID(step.UID)
self.steps.remove(step)
def __iter__(self):
return self.steps.__iter__()
def save(self):
self.plots.save()
class Plots:
def __init__(self, path):
self.file = XmlFile(path)
self.host = UniqueIDHost()
self.lines = dict()
def addLine(self, name: str, importance: PlotImportance = PlotImportance.MINOR):
line = PlotLine(self, self.host.newID(), name, importance)
self.lines[line.UID.value] = line
return line
def loadLine(self, ID: int, name: str, importance: PlotImportance = PlotImportance.MINOR):
line = PlotLine(self, self.host.loadID(ID), name, importance)
self.lines[line.UID.value] = line
return line
def removeLine(self, line: PlotLine):
self.host.removeID(line.UID)
self.lines.pop(line.UID.value)
def __iter__(self):
return self.lines.values().__iter__()
@classmethod
def loadPlotStep(cls, line: PlotLine, element: etree.Element):
ID = element.get("ID")
if ID is None:
return
line.loadStep(
int(ID),
element.get("name"),
element.get("meta"),
element.get("summary")
)
@classmethod
def loadPlotLine(cls, plots, element: etree.Element):
ID = element.get("ID")
if ID is None:
return
importance = PlotImportance(int(element.get("importance", 0)))
line = plots.loadLine(int(ID), element.get("name"), importance)
line.description = element.get("description")
line.result = element.get("result")
for characterID in element.get("characters", "").split(','):
#TODO: Character loadings/adding should link to models!
try:
line.characters.append(int(characterID))
except ValueError:
continue
for child in element.findall("step"):
cls.loadPlotStep(line, child)
@classmethod
def loadPlots(cls, plots, root: etree.Element):
plots.host.reset()
plots.lines.clear()
for element in root.findall("plot"):
cls.loadPlotLine(plots, element)
def load(self):
tree = self.file.load()
Plots.loadPlots(self, tree.getroot())
@classmethod
def saveElementAttribute(cls, element: etree.Element, name: str, value):
if value is None:
return
str_value = str(value)
if len(str_value) > 0:
element.set(name, str_value)
@classmethod
def savePlotStep(cls, step: PlotStep, parent: etree.Element):
element = etree.SubElement(parent, "step")
cls.saveElementAttribute(element, "name", step.name)
cls.saveElementAttribute(element, "ID", step.UID.value)
cls.saveElementAttribute(element, "meta", step.meta)
cls.saveElementAttribute(element, "summary", step.summary)
@classmethod
def savePlotLine(cls, line: PlotLine, root: etree.Element):
element = etree.SubElement(root, "plot")
characters = ",".join([str(characterID) for characterID in line.characters])
cls.saveElementAttribute(element, "name", line.name)
cls.saveElementAttribute(element, "ID", line.UID.value)
cls.saveElementAttribute(element, "importance", line.importance.value)
cls.saveElementAttribute(element, "characters", characters)
cls.saveElementAttribute(element, "description", line.description)
cls.saveElementAttribute(element, "result", line.result)
for step in line:
cls.savePlotStep(step, element)
@classmethod
def savePlots(cls, plots):
root = etree.Element("root")
for line in plots.lines.values():
cls.savePlotLine(line, root)
return root
def save(self):
tree = etree.ElementTree(Plots.savePlots(self))
self.file.save(tree)

View file

@ -0,0 +1,43 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
class UniqueID:
def __init__(self, host, value: int):
self.host = host
self.value = value
def __str__(self):
return str(self.value)
class UniqueIDHost:
def __init__(self):
self.counter = 0
self.uids = dict()
def reset(self):
self.counter = 0
self.uids.clear()
def newID(self):
uid = UniqueID(self, self.counter)
self.counter = self.counter + 1
self.uids[uid.value] = uid
return uid
def loadID(self, value: int):
if value in self.uids:
raise ValueError("ID not unique: " + str(value))
uid = UniqueID(self, value)
self.counter = max(self.counter, uid.value + 1)
self.uids[uid.value] = uid
return uid
def removeID(self, uid: UniqueID):
if uid.host != self:
raise ValueError("ID not bound to host!")
self.uids.pop(uid.value)

View file

@ -5,7 +5,6 @@ from manuskript.io.textFile import TextFile
from manuskript.io.jsonFile import JsonFile
from manuskript.io.xmlFile import XmlFile
from manuskript.io.opmlFile import OpmlFile
from manuskript.io.plotsFile import PlotsFile
extensions = {
".txt": TextFile,

View file

@ -1,114 +0,0 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from lxml import etree
from manuskript.io.xmlFile import XmlFile
class PlotStep:
def __init__(self, name, ID, meta="", summary=""):
self.name = name
self.ID = ID
self.meta = meta
self.summary = summary
class PlotItem:
def __init__(self, name, ID, importance, description, result):
self.name = name
self.ID = ID
self.importance = importance
self.characters = []
self.description = description
self.result = result
self.steps = []
class PlotsFile(XmlFile):
@classmethod
def loadPlot(cls, element):
plotID = element.get("ID")
if plotID is None:
return None
plot = PlotItem(
element.get("name"),
int(plotID),
int(element.get("importance", 0)),
element.get("description"),
element.get("result")
)
for characterID in element.get("characters", "").split(','):
try:
plot.characters.append(int(characterID))
except ValueError:
continue
for child in element.findall("step"):
stepID = child.get("ID")
if stepID is None:
continue
step = PlotStep(
child.get("name"),
int(stepID),
child.get("meta"),
child.get("summary")
)
plot.steps.append(step)
return plot
def load(self):
tree = XmlFile.load(self)
root = tree.getroot()
plots = []
for element in root.findall("plot"):
plots.append(PlotsFile.loadPlot(element))
return plots
@classmethod
def saveElementAttribute(cls, element, name, value):
if value is None:
return
element.set(name, str(value))
@classmethod
def savePlot(cls, parent, plot):
element = etree.SubElement(parent, "plot")
cls.saveElementAttribute(element, "name", plot.name)
cls.saveElementAttribute(element, "ID", plot.ID)
cls.saveElementAttribute(element, "importance", plot.importance)
cls.saveElementAttribute(element, "characters", ",".join([str(characterID) for characterID in plot.characters]))
cls.saveElementAttribute(element, "description", plot.description)
cls.saveElementAttribute(element, "result", plot.result)
for step in plot.steps:
child = etree.SubElement(element, "step")
cls.saveElementAttribute(child, "name", step.name)
cls.saveElementAttribute(child, "ID", step.ID)
cls.saveElementAttribute(child, "meta", step.meta)
cls.saveElementAttribute(child, "summary", step.summary)
def save(self, plots):
root = etree.Element("root")
for plot in plots:
PlotsFile.savePlot(root, plot)
tree = etree.ElementTree(root)
XmlFile.save(self, tree)