Package Gnumed :: Package timelinelib :: Package db :: Package backends :: Module ics |
[frames] | no frames]

# Source Code for Module Gnumed.timelinelib.db.backends.ics

      1  # Copyright (C) 2009, 2010, 2011  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 datetime import date
     20  from datetime import datetime
     21  from os.path import abspath
     22  import os.path
     23
     24  from icalendar import Calendar
     25
     26  from timelinelib.db.exceptions import TimelineIOError
     27  from timelinelib.db.objects import Event
     28  from timelinelib.db.observer import Observable
     29  from timelinelib.db.search import generic_event_search
     30  from timelinelib.db.utils import IdCounter
     31  from timelinelib.time import PyTimeType
     32  from timelinelib.utils import ex_msg
     33
     34
     35 -class IcsTimeline(Observable):
     36
     37 -    def __init__(self, path):
     38          Observable.__init__(self)
     39          self.path = path
     40          self.event_id_counter = IdCounter()
     41          self._load_data()
     42
     43 -    def get_time_type(self):
     44          return PyTimeType()
     45
     46 -    def is_read_only(self):
     47          return True
     48
     49 -    def supported_event_data(self):
     50          return []
     51
     52 -    def search(self, search_string):
     53          return generic_event_search(self._get_events(), search_string)
     54
     55 -    def get_events(self, time_period):
     56          def decider(event):
     57              return event.inside_period(time_period)
     58          return self._get_events(decider)
     59
     60 -    def get_all_events(self):
     61          def decider(event):
     62              return True
     63          return self._get_events(decider)
     64
     65 -    def get_first_event(self):
     66          events = self._get_events()
     67          if events:
     68              return min(events, key=lambda x: x.time_period.start_time)
     69          else:
     70              return None
     71
     72 -    def get_last_event(self):
     73          events = self._get_events()
     74          if events:
     75              return max(events, key=lambda x: x.time_period.end_time)
     76          else:
     77              return None
     78
     79 -    def save_event(self, event):
     80          pass
     81
     82 -    def delete_event(self, event_or_id):
     83          pass
     84
     85 -    def get_categories(self):
     86          return []
     87
     88 -    def save_category(self, category):
     89          pass
     90
     91 -    def delete_category(self, category_or_id):
     92          pass
     93
     94 -    def load_view_properties(self, view_properties):
     95          pass
     96
     97 -    def save_view_properties(self, view_properties):
     98          pass
     99
    100 -    def find_event_with_id(self, id):
    101          events = self._get_events()
    102          for e in events:
    103              if e.id == id:
    104                  return e
    105          return None
    106
    107 -    def _get_events(self, decider_fn=None):
    108          events = []
    109          for event in self.cal.walk("VEVENT"):
    110              start, end = extract_start_end(event)
    111              txt = ""
    112              if event.has_key("summary"):
    113                  txt = event["summary"]
    114              e = Event(self.get_time_type(), start, end, txt)
    115              e.set_id(event["timeline_id"])
    116              if decider_fn is None or decider_fn(e):
    117                  events.append(e)
    118          return events
    119
    120 -    def _load_data(self):
    121          self.cal = Calendar()
    122          try:
    123              file = open(self.path, "rb")
    124              try:
    125                  file_contents = file.read()
    126                  try:
    127                      self.cal = Calendar.from_string(file_contents)
    128                      for event in self.cal.walk("VEVENT"):
    129                          event["timeline_id"] = self.event_id_counter.get_next()
    130                  except Exception, pe:
    131                      msg1 = _("Unable to read timeline data from '%s'.")
    132                      msg2 = "\n\n" + ex_msg(pe)
    133                      raise TimelineIOError((msg1 % abspath(self.path)) + msg2)
    134              finally:
    135                  file.close()
    136          except IOError, e:
    137              msg = _("Unable to read from file '%s'.")
    138              whole_msg = (msg + "\n\n%s") % (abspath(self.path), e)
    139              raise TimelineIOError(whole_msg)
    140
    141
    142 -def extract_start_end(vevent):
    143      start = convert_to_datetime(vevent.decoded("dtstart"))
    144      if vevent.has_key("dtend"):
    145          end = convert_to_datetime(vevent.decoded("dtend"))
    146      elif vevent.has_key("duration"):
    147          end = start + vevent.decoded("duration")
    148      else:
    149          end = convert_to_datetime(vevent.decoded("dtstart"))
    150      return (start, end)
    151
    152
    153 -def convert_to_datetime(d):
    154      if isinstance(d, datetime):
    155          return datetime(d.year, d.month, d.day, d.hour, d.minute, d.second)
    156      elif isinstance(d, date):
    157          return datetime(d.year, d.month, d.day)
    158      else:
    159          raise TimelineIOError("Unknown date.")
    160