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 StringIO
     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 = "  "
     31  INDENT2 = "    "
     32  INDENT3 = "      "
     33
     34
     35 -def export_db_to_timeline_xml(db, path):
     36      Exporter(db).export(path)
     37
     38
     39 -def wrap_in_tag(func, name, indent=""):
     40      def wrapper(*args, **kwargs):
     41          dbfile = args[1]  # 1st argument is self, 2nd argument is dbfile
     42          dbfile.write(indent)
     43          dbfile.write("<")
     44          dbfile.write(name)
     45          dbfile.write(">\n")
     46          func(*args, **kwargs)
     47          dbfile.write(indent)
     48          dbfile.write("</")
     49          dbfile.write(name)
     50          dbfile.write(">\n")
     51      return wrapper
     52
     53
     54 -class Exporter(object):
     55
     56 -    def __init__(self, db):
     57          self.db = db
     58
     59 -    def export(self, path):
     60          safe_write(path, ENCODING, self._write_xml_doc)
     61
     62 -    def _time_string(self, time):
     63          return self.db.get_time_type().time_string(time)
     64
     65 -    def _write_xml_doc(self, xmlfile):
     66          xmlfile.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n")
     67          self._write_timeline(xmlfile)
     68
     69 -    def _write_timeline(self, xmlfile):
     70          write_simple_tag(xmlfile, "version", get_full_version(), INDENT1)
     71          write_simple_tag(xmlfile, "timetype", self.db.get_time_type().get_name(), INDENT1)
     72          if len(self.db.get_all_eras()) > 0:
     73              self._write_eras(xmlfile)
     74          self._write_categories(xmlfile)
     75          self._write_events(xmlfile)
     76          self._write_view(xmlfile)
     77          self._write_now_value(xmlfile)
     78      _write_timeline = wrap_in_tag(_write_timeline, "timeline")
     79
     80 -    def _write_categories(self, xmlfile):
     81          def write_with_parent(categories, parent):
     82              for cat in categories:
     83                  if cat._get_parent() == parent:
     84                      self._write_category(xmlfile, cat)
     85                      write_with_parent(categories, cat)
     86          write_with_parent(self.db.get_categories(), None)
     87      _write_categories = wrap_in_tag(_write_categories, "categories", INDENT1)
     88
     89 -    def _write_category(self, xmlfile, cat):
     90          write_simple_tag(xmlfile, "name", cat.get_name(), INDENT3)
     91          write_simple_tag(xmlfile, "color", color_string(cat.get_color()), INDENT3)
     92          write_simple_tag(xmlfile, "progress_color", color_string(cat.get_progress_color()), INDENT3)
     93          write_simple_tag(xmlfile, "done_color", color_string(cat.get_done_color()), INDENT3)
     94          write_simple_tag(xmlfile, "font_color", color_string(cat.get_font_color()), INDENT3)
     95          if cat._get_parent():
     96              write_simple_tag(xmlfile, "parent", cat._get_parent().get_name(), INDENT3)
     97      _write_category = wrap_in_tag(_write_category, "category", INDENT2)
     98
     99 -    def _write_events(self, xmlfile):
    100          all_events = self.db.get_all_events()
    101          containers = [event for event in all_events if event.is_container()]
    102          rest = [event for event in all_events if not event.is_container()]
    103          for evt in containers + rest:
    104              self._write_event(xmlfile, evt)
    105      _write_events = wrap_in_tag(_write_events, "events", INDENT1)
    106
    107 -    def _write_event(self, xmlfile, evt):
    108          write_simple_tag(xmlfile, "start",
    109                           self._time_string(evt.get_time_period().start_time), INDENT3)
    110          write_simple_tag(xmlfile, "end",
    111                           self._time_string(evt.get_time_period().end_time), INDENT3)
    112          if evt.is_container():
    113              write_simple_tag(xmlfile, "text", "[%d]%s" % (evt.id, evt.get_text()), INDENT3)
    114          elif evt.is_subevent():
    115              write_simple_tag(xmlfile, "text", "(%d)%s" % (evt.container.id, evt.get_text()), INDENT3)
    116          else:
    117              text = evt.get_text()
    118              if self._text_starts_with_container_tag(evt.get_text()):
    119                  text = self._add_leading_space_to_text(evt.get_text())
    120              write_simple_tag(xmlfile, "text", text, INDENT3)
    121          if evt.get_data("progress") is not None:
    122              write_simple_tag(xmlfile, "progress", "%s" % evt.get_data("progress"), INDENT3)
    123          write_simple_tag(xmlfile, "fuzzy", "%s" % evt.get_fuzzy(), INDENT3)
    124          write_simple_tag(xmlfile, "locked", "%s" % evt.get_locked(), INDENT3)
    125          write_simple_tag(xmlfile, "ends_today", "%s" % evt.get_ends_today(), INDENT3)
    126          if evt.get_category() is not None:
    127              write_simple_tag(xmlfile, "category", evt.get_category().get_name(), INDENT3)
    128          if evt.get_data("description") is not None:
    129              write_simple_tag(xmlfile, "description", evt.get_data("description"), INDENT3)
    130          alert = evt.get_data("alert")
    131          if alert is not None:
    132              write_simple_tag(xmlfile, "alert", alert_string(self.db.get_time_type(), alert),
    133                               INDENT3)
    134          hyperlink = evt.get_data("hyperlink")
    135          if hyperlink is not None:
    136              write_simple_tag(xmlfile, "hyperlink", hyperlink, INDENT3)
    137          if evt.get_data("icon") is not None:
    138              icon_text = icon_string(evt.get_data("icon"))
    139              write_simple_tag(xmlfile, "icon", icon_text, INDENT3)
    140          default_color = evt.get_data("default_color")
    141          if default_color is not None:
    142              write_simple_tag(xmlfile, "default_color", color_string(default_color), INDENT3)
    143          if evt.is_milestone():
    144              write_simple_tag(xmlfile, "milestone", "True", INDENT3)
    145      _write_event = wrap_in_tag(_write_event, "event", INDENT2)
    146
    147 -    def _write_eras(self, xmlfile):
    148          for era in self.db.get_all_eras():
    149              self._write_era(xmlfile, era)
    150      _write_eras = wrap_in_tag(_write_eras, "eras", INDENT1)
    151
    152 -    def _write_era(self, xmlfile, era):
    153          write_simple_tag(xmlfile, "name", era.get_name(), INDENT3)
    154          write_simple_tag(xmlfile, "start", self._time_string(era.get_time_period().start_time), INDENT3)
    155          write_simple_tag(xmlfile, "end", self._time_string(era.get_time_period().end_time), INDENT3)
    156          write_simple_tag(xmlfile, "color", color_string(era.get_color()), INDENT3)
    157          write_simple_tag(xmlfile, "ends_today", "%s" % era.ends_today(), INDENT3)
    158      _write_era = wrap_in_tag(_write_era, "era", INDENT2)
    159
    160 -    def _text_starts_with_container_tag(self, text):
    161          if len(text) > 0:
    162              return text[0] in ('(', '[')
    163          else:
    164              return False
    165
    166 -    def _add_leading_space_to_text(self, text):
    167          return " %s" % text
    168
    169 -    def _write_view(self, xmlfile):
    170          if self.db.get_displayed_period() is not None:
    171              self._write_displayed_period(xmlfile)
    172          self._write_hidden_categories(xmlfile)
    173      _write_view = wrap_in_tag(_write_view, "view", INDENT1)
    174
    175
    176 -    def _write_displayed_period(self, xmlfile):
    177          period = self.db.get_displayed_period()
    178          write_simple_tag(xmlfile, "start",
    179                           self._time_string(period.start_time), INDENT3)
    180          write_simple_tag(xmlfile, "end",
    181                           self._time_string(period.end_time), INDENT3)
    182      _write_displayed_period = wrap_in_tag(_write_displayed_period,
    183                                            "displayed_period", INDENT2)
    184
    185 -    def _write_hidden_categories(self, xmlfile):
    186          for cat in self.db.get_hidden_categories():
    187              write_simple_tag(xmlfile, "name", cat.get_name(), INDENT3)
    188      _write_hidden_categories = wrap_in_tag(_write_hidden_categories,
    189                                             "hidden_categories", INDENT2)
    190
    191 -    def _write_now_value(self, xmlfile):
    192          if self.db.get_time_type().supports_saved_now():
    193              time = self.db.get_time_type().time_string(self.db.time_type.now())
    194              write_simple_tag(xmlfile, "now", time, INDENT1)
    195
    196
    197 -def write_simple_tag(xmlfile, name, content, indent=""):
    198      xmlfile.write(indent)
    199      xmlfile.write("<")
    200      xmlfile.write(name)
    201      xmlfile.write(">")
    202      xmlfile.write(xmlescape(content))
    203      xmlfile.write("</")
    204      xmlfile.write(name)
    205      xmlfile.write(">\n")
    206
    207
    208 -def color_string(color):
    209      return "%i,%i,%i" % color
    210
    211
    212 -def icon_string(bitmap):
    213      output = StringIO.StringIO()
    214      image = wx.ImageFromBitmap(bitmap)
    215      image.SaveStream(output, wx.BITMAP_TYPE_PNG)
    216      return base64.b64encode(output.getvalue())
    217
    218
    219 -def alert_string(time_type, alert):
    220      time, text = alert
    221      time_string = time_type.time_string(time)
    222      return "%s;%s" % (time_string, text)
    223