Gnumed.timelinelib.dataexport.timelinexml

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