Package Gnumed :: Package timelinelib :: Package dataexport :: Module timelinexml
[frames] | no frames]

Source Code for Module Gnumed.timelinelib.dataexport.timelinexml

  1  # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018  Rickard Lindberg, Roger Lindberg 
  2  # 
  3  # This file is part of Timeline. 
  4  # 
  5  # Timeline is free software: you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation, either version 3 of the License, or 
  8  # (at your option) any later version. 
  9  # 
 10  # Timeline is distributed in the hope that it will be useful, 
 11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  # GNU General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with Timeline.  If not, see <http://www.gnu.org/licenses/>. 
 17   
 18   
 19  from xml.sax.saxutils import escape as xmlescape 
 20  import base64 
 21  import io 
 22   
 23  import wx 
 24   
 25  from timelinelib.db.utils import safe_write 
 26  from timelinelib.meta.version import get_full_version 
 27   
 28   
 29  ENCODING = "utf-8" 
 30  INDENT1 = " " * 2 
 31  INDENT2 = " " * 4 
 32  INDENT3 = " " * 6 
 33  INDENT4 = " " * 8 
 34   
 35   
36 -def export_db_to_timeline_xml(db, path):
37 Exporter(db).export(path)
38 39
40 -def wrap_in_tag(func, name, indent=""):
41 def wrapper(*args, **kwargs): 42 dbfile = args[1] # 1st argument is self, 2nd argument is dbfile 43 dbfile.write(indent) 44 dbfile.write("<") 45 dbfile.write(name) 46 dbfile.write(">\n") 47 func(*args, **kwargs) 48 dbfile.write(indent) 49 dbfile.write("</") 50 dbfile.write(name) 51 dbfile.write(">\n")
52 return wrapper 53 54
55 -class Exporter(object):
56
57 - def __init__(self, db):
58 self.db = db
59
60 - def export(self, path):
61 safe_write(path, ENCODING, self._write_xml_doc)
62
63 - def _time_string(self, time):
64 return self.db.get_time_type().time_string(time)
65
66 - def _write_xml_doc(self, xmlfile):
67 xmlfile.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n") 68 self._write_timeline(xmlfile)
69
70 - def _write_timeline(self, xmlfile):
71 write_simple_tag(xmlfile, "version", get_full_version(), INDENT1) 72 write_simple_tag(xmlfile, "timetype", self.db.get_time_type().get_name(), INDENT1) 73 if len(self.db.get_all_eras()) > 0: 74 self._write_eras(xmlfile) 75 self._write_categories(xmlfile) 76 self._write_events(xmlfile) 77 self._write_view(xmlfile) 78 self._write_now_value(xmlfile)
79 _write_timeline = wrap_in_tag(_write_timeline, "timeline") 80
81 - def _write_categories(self, xmlfile):
82 def write_with_parent(categories, parent): 83 for cat in categories: 84 if cat._get_parent() == parent: 85 self._write_category(xmlfile, cat) 86 write_with_parent(categories, cat)
87 write_with_parent(self.db.get_categories(), None)
88 _write_categories = wrap_in_tag(_write_categories, "categories", INDENT1) 89
90 - def _write_category(self, xmlfile, cat):
91 write_simple_tag(xmlfile, "name", cat.get_name(), INDENT3) 92 write_simple_tag(xmlfile, "color", color_string(cat.get_color()), INDENT3) 93 write_simple_tag(xmlfile, "progress_color", color_string(cat.get_progress_color()), INDENT3) 94 write_simple_tag(xmlfile, "done_color", color_string(cat.get_done_color()), INDENT3) 95 write_simple_tag(xmlfile, "font_color", color_string(cat.get_font_color()), INDENT3) 96 if cat._get_parent(): 97 write_simple_tag(xmlfile, "parent", cat._get_parent().get_name(), INDENT3)
98 _write_category = wrap_in_tag(_write_category, "category", INDENT2) 99
100 - def _write_events(self, xmlfile):
101 all_events = self.db.get_all_events() 102 containers = [event for event in all_events if event.is_container()] 103 rest = [event for event in all_events if not event.is_container()] 104 for evt in containers + rest: 105 self._write_event(xmlfile, evt)
106 _write_events = wrap_in_tag(_write_events, "events", INDENT1) 107
108 - def _write_event(self, xmlfile, evt):
109 write_simple_tag(xmlfile, "start", 110 self._time_string(evt.get_time_period().start_time), INDENT3) 111 write_simple_tag(xmlfile, "end", 112 self._time_string(evt.get_time_period().end_time), INDENT3) 113 if evt.is_container(): 114 write_simple_tag(xmlfile, "text", "[%d]%s" % (evt.id, evt.get_text()), INDENT3) 115 elif evt.is_subevent(): 116 write_simple_tag(xmlfile, "text", "(%d)%s" % (evt.container.id, evt.get_text()), INDENT3) 117 else: 118 text = evt.get_text() 119 if self._text_starts_with_container_tag(evt.get_text()): 120 text = self._add_leading_space_to_text(evt.get_text()) 121 write_simple_tag(xmlfile, "text", text, INDENT3) 122 if evt.get_data("progress") is not None: 123 write_simple_tag(xmlfile, "progress", "%s" % evt.get_data("progress"), INDENT3) 124 write_simple_tag(xmlfile, "fuzzy", "%s" % evt.get_fuzzy(), INDENT3) 125 write_simple_tag(xmlfile, "locked", "%s" % evt.get_locked(), INDENT3) 126 write_simple_tag(xmlfile, "ends_today", "%s" % evt.get_ends_today(), INDENT3) 127 if evt.get_category() is not None: 128 write_simple_tag(xmlfile, "category", evt.get_category().get_name(), INDENT3) 129 if evt.get_categories(): 130 self._write_event_categories(xmlfile, evt) 131 if evt.get_data("description") is not None: 132 write_simple_tag(xmlfile, "description", evt.get_data("description"), INDENT3) 133 alert = evt.get_data("alert") 134 if alert is not None: 135 write_simple_tag(xmlfile, "alert", alert_string(self.db.get_time_type(), alert), 136 INDENT3) 137 hyperlink = evt.get_data("hyperlink") 138 if hyperlink is not None: 139 write_simple_tag(xmlfile, "hyperlink", hyperlink, INDENT3) 140 if evt.get_data("icon") is not None: 141 icon_text = icon_string(evt.get_data("icon")) 142 write_simple_tag(xmlfile, "icon", icon_text, INDENT3) 143 default_color = evt.get_data("default_color") 144 if default_color is not None: 145 write_simple_tag(xmlfile, "default_color", color_string(default_color), INDENT3) 146 if evt.is_milestone(): 147 write_simple_tag(xmlfile, "milestone", "True", INDENT3)
148 _write_event = wrap_in_tag(_write_event, "event", INDENT2) 149
150 - def _write_event_categories(self, xmlfile, event):
151 for category in event.get_categories(): 152 write_simple_tag(xmlfile, "category", category.get_name(), INDENT4)
153 _write_event_categories = wrap_in_tag(_write_event_categories, "categories", INDENT3) 154
155 - def _write_eras(self, xmlfile):
156 for era in self.db.get_all_eras(): 157 self._write_era(xmlfile, era)
158 _write_eras = wrap_in_tag(_write_eras, "eras", INDENT1) 159
160 - def _write_era(self, xmlfile, era):
161 write_simple_tag(xmlfile, "name", era.get_name(), INDENT3) 162 write_simple_tag(xmlfile, "start", self._time_string(era.get_time_period().start_time), INDENT3) 163 write_simple_tag(xmlfile, "end", self._time_string(era.get_time_period().end_time), INDENT3) 164 write_simple_tag(xmlfile, "color", color_string(era.get_color()), INDENT3) 165 write_simple_tag(xmlfile, "ends_today", "%s" % era.ends_today(), INDENT3)
166 _write_era = wrap_in_tag(_write_era, "era", INDENT2) 167
168 - def _text_starts_with_container_tag(self, text):
169 if len(text) > 0: 170 return text[0] in ('(', '[') 171 else: 172 return False
173
174 - def _add_leading_space_to_text(self, text):
175 return " %s" % text
176
177 - def _write_view(self, xmlfile):
178 if self.db.get_displayed_period() is not None: 179 self._write_displayed_period(xmlfile) 180 self._write_hidden_categories(xmlfile)
181 _write_view = wrap_in_tag(_write_view, "view", INDENT1) 182 183
184 - def _write_displayed_period(self, xmlfile):
185 period = self.db.get_displayed_period() 186 write_simple_tag(xmlfile, "start", 187 self._time_string(period.start_time), INDENT3) 188 write_simple_tag(xmlfile, "end", 189 self._time_string(period.end_time), INDENT3)
190 _write_displayed_period = wrap_in_tag(_write_displayed_period, 191 "displayed_period", INDENT2) 192
193 - def _write_hidden_categories(self, xmlfile):
194 for cat in self.db.get_hidden_categories(): 195 write_simple_tag(xmlfile, "name", cat.get_name(), INDENT3)
196 _write_hidden_categories = wrap_in_tag(_write_hidden_categories, 197 "hidden_categories", INDENT2) 198
199 - def _write_now_value(self, xmlfile):
200 if self.db.get_time_type().supports_saved_now(): 201 time = self.db.get_time_type().time_string(self.db.time_type.now()) 202 write_simple_tag(xmlfile, "now", time, INDENT1)
203 204
205 -def write_simple_tag(xmlfile, name, content, indent=""):
206 xmlfile.write(indent) 207 xmlfile.write("<") 208 xmlfile.write(name) 209 xmlfile.write(">") 210 xmlfile.write(xmlescape(content)) 211 xmlfile.write("</") 212 xmlfile.write(name) 213 xmlfile.write(">\n")
214 215
216 -def color_string(color):
217 return "%i,%i,%i" % color[:3]
218 219
220 -def icon_string(bitmap):
221 output = io.StringIO() 222 image = wx.ImageFromBitmap(bitmap) 223 image.SaveStream(output, wx.BITMAP_TYPE_PNG) 224 return base64.b64encode(output.getvalue())
225 226
227 -def alert_string(time_type, alert):
228 time, text = alert 229 time_string = time_type.time_string(time) 230 return "%s;%s" % (time_string, text)
231