示例#1
0
 def __init__(self):
     Observable.__init__(self)
     self.path = ""
     self.categories = []
     self.category_id_counter = IdCounter()
     self.events = []
     self.event_id_counter = IdCounter()
     self.displayed_period = None
     self.hidden_categories = []
     self.save_disabled = False
     from timelinelib.time.gregoriantime import GregorianTimeType
     self.time_type = GregorianTimeType()
     self.readonly = False
     self.importing = False
示例#2
0
文件: ics.py 项目: sk/gnumed
 def __init__(self, path):
     Observable.__init__(self)
     self.path = path
     self.event_id_counter = IdCounter()
     self.cals = []
     self.import_timeline(self.path)
示例#3
0
文件: ics.py 项目: sk/gnumed
class IcsTimeline(Observable):

    def __init__(self, path):
        Observable.__init__(self)
        self.path = path
        self.event_id_counter = IdCounter()
        self.cals = []
        self.import_timeline(self.path)

    def get_time_type(self):
        return GregorianTimeType()

    def is_read_only(self):
        return True

    def supported_event_data(self):
        return []

    def search(self, search_string):
        return generic_event_search(self._get_events(), search_string)

    def get_events(self, time_period):
        def decider(event):
            return event.inside_period(time_period)
        return self._get_events(decider)

    def get_all_events(self):
        def decider(event):
            return True
        return self._get_events(decider)

    def get_first_event(self):
        events = self._get_events()
        if events:
            return min(events, key=lambda x: x.time_period.start_time)
        else:
            return None

    def get_last_event(self):
        events = self._get_events()
        if events:
            return max(events, key=lambda x: x.time_period.end_time)
        else:
            return None

    def save_event(self, event):
        pass

    def delete_event(self, event_or_id):
        pass

    def get_categories(self):
        return []

    def save_category(self, category):
        pass

    def delete_category(self, category_or_id):
        pass

    def load_view_properties(self, view_properties):
        pass

    def save_view_properties(self, view_properties):
        pass

    def find_event_with_id(self, id):
        events = self._get_events()
        for e in events:
            if e.id == id:
                return e
        return None

    def _get_events(self, decider_fn=None):
        self.events = []
        for cal in self.cals:
            for event in cal.walk("VEVENT"):
                start, end = extract_start_end(event)
                txt = ""
                if event.has_key("summary"):
                    txt = event["summary"]
                elif event.has_key("description"):
                    txt = event["description"]
                else:
                    txt == "Unknown"
                e = Event(self.get_time_type(), start, end, txt)
                e.set_id(event["timeline_id"])
                if event.has_key("description"):
                    e.set_data("description", event["description"])
                if decider_fn is None or decider_fn(e):
                    self.events.append(e)
        return self.events

    def import_timeline(self, path):
        try:
            ics_file = open(path, "rb")
            try:
                file_contents = ics_file.read()
                try:
                    cal = Calendar.from_ical(file_contents)
                    for event in cal.walk("VEVENT"):
                        event["timeline_id"] = self.event_id_counter.get_next()
                    self.cals.append(cal)
                except Exception, pe:
                    msg1 = _("Unable to read timeline data from '%s'.")
                    msg2 = "\n\n" + ex_msg(pe)
                    raise TimelineIOError((msg1 % abspath(path)) + msg2)
            finally:
                ics_file.close()
        except IOError, e:
            msg = _("Unable to read from file '%s'.")
            whole_msg = (msg + "\n\n%s") % (abspath(self.path), e)
            raise TimelineIOError(whole_msg)
示例#4
0
class MemoryDB(Observable):
    def __init__(self):
        Observable.__init__(self)
        self.path = ""
        self.categories = []
        self.category_id_counter = IdCounter()
        self.events = []
        self.event_id_counter = IdCounter()
        self.displayed_period = None
        self.hidden_categories = []
        self.save_disabled = False
        from timelinelib.time.gregoriantime import GregorianTimeType
        self.time_type = GregorianTimeType()
        self.readonly = False
        self.importing = False

    def get_time_type(self):
        return self.time_type

    def is_read_only(self):
        return self.readonly

    def set_readonly(self):
        self.readonly = True

    def supported_event_data(self):
        return ["description", "icon", "alert", "hyperlink", "progress"]

    def search(self, search_string):
        return generic_event_search(self.events, search_string)

    def get_events(self, time_period):
        def include_event(event):
            if not event.inside_period(time_period):
                return False
            return True

        return [e for e in self.events if include_event(e)]

    def get_all_events(self):
        return list(self.events)

    def get_first_event(self):
        if len(self.events) == 0:
            return None
        e = min(self.events, key=lambda e: e.time_period.start_time)
        return e

    def get_last_event(self):
        if len(self.events) == 0:
            return None
        e = max(self.events, key=lambda e: e.time_period.end_time)
        return e

    def save_event(self, event):
        if (event.category is not None
                and event.category not in self.categories):
            raise TimelineIOError("Event's category not in db.")
        if event not in self.events:
            if event.has_id():
                raise TimelineIOError("Event with id %s not found in db." %
                                      event.id)
            self.events.append(event)
            event.set_id(self.event_id_counter.get_next())
            if event.is_subevent():
                self._register_subevent(event)
        self._save_if_not_disabled()
        self._notify(STATE_CHANGE_ANY)

    def _register_subevent(self, subevent):
        container_events = [
            event for event in self.events if event.is_container()
        ]
        containers = {}
        for container in container_events:
            key = container.cid()
            containers[key] = container
        try:
            container = containers[subevent.cid()]
            container.register_subevent(subevent)
        except:
            id = subevent.cid()
            if id == 0:
                id = self._get_max_container_id(container_events) + 1
                subevent.set_cid(id)
            name = "[%d]Container" % id
            container = Container(subevent.time_type,
                                  subevent.time_period.start_time,
                                  subevent.time_period.end_time, name)
            self.save_event(container)
            self._register_subevent(subevent)
            pass

    def _get_max_container_id(self, container_events):
        id = 0
        for event in container_events:
            if id < event.cid():
                id = event.cid()
        return id

    def _unregister_subevent(self, subevent):
        container_events = [
            event for event in self.events if event.is_container()
        ]
        containers = {}
        for container in container_events:
            containers[container.cid()] = container
        try:
            container = containers[subevent.cid()]
            container.unregister_subevent(subevent)
            if len(container.events) == 0:
                self.events.remove(container)
        except:
            pass

    def delete_event(self, event_or_id):
        if isinstance(event_or_id, Event):
            event = event_or_id
        else:
            event = self.find_event_with_id(event_or_id)
        if event in self.events:
            if event.is_subevent():
                self._unregister_subevent(event)
            if event.is_container():
                for subevent in event.events:
                    self.events.remove(subevent)
            self.events.remove(event)
            event.set_id(None)
            self._save_if_not_disabled()
            self._notify(STATE_CHANGE_ANY)
        else:
            raise TimelineIOError("Event not in db.")

    def get_categories(self):
        return list(self.categories)

    def get_containers(self):
        containers = [event for event in self.events if event.is_container()]
        return containers

    def save_category(self, category):
        if (category.parent is not None
                and category.parent not in self.categories):
            raise TimelineIOError("Parent category not in db.")
        self._ensure_no_circular_parent(category)
        if not category in self.categories:
            if self.importing:
                if not self._category_name_exists(category):
                    self._append_category(category)
            else:
                self._append_category(category)
        self._save_if_not_disabled()
        self._notify(STATE_CHANGE_CATEGORY)

    def _category_name_exists(self, category):
        return self._get_category_by_name(category) is not None

    def _append_category(self, category):
        if category.has_id():
            raise TimelineIOError("Category with id %s not found in db." %
                                  category.id)
        self.categories.append(category)
        category.set_id(self.event_id_counter.get_next())

    def _get_category_by_name(self, category):
        for cat in self.categories:
            if cat.name == category.name:
                return cat

    def delete_category(self, category_or_id):
        if isinstance(category_or_id, Category):
            category = category_or_id
        else:
            category = self._find_category_with_id(category_or_id)
        if category in self.categories:
            if category in self.hidden_categories:
                self.hidden_categories.remove(category)
            self.categories.remove(category)
            category.set_id(None)
            # Loop to update parent attribute on children
            for cat in self.categories:
                if cat.parent == category:
                    cat.parent = category.parent
            # Loop to update category for events
            for event in self.events:
                if event.category == category:
                    event.category = category.parent
            self._save_if_not_disabled()
            self._notify(STATE_CHANGE_CATEGORY)
        else:
            raise TimelineIOError("Category not in db.")

    def load_view_properties(self, view_properties):
        view_properties.displayed_period = self.displayed_period
        for cat in self.categories:
            visible = cat not in self.hidden_categories
            view_properties.set_category_visible(cat, visible)

    def save_view_properties(self, view_properties):
        if view_properties.displayed_period is not None:
            if not view_properties.displayed_period.is_period():
                raise TimelineIOError(_("Displayed period must be > 0."))
            self.displayed_period = view_properties.displayed_period
        self.hidden_categories = []
        for cat in self.categories:
            if not view_properties.is_category_visible(cat):
                self.hidden_categories.append(cat)
        self._save_if_not_disabled()

    def disable_save(self):
        self.save_disabled = True

    def enable_save(self, call_save=True):
        if self.save_disabled == True:
            self.save_disabled = False
            if call_save == True:
                self._save_if_not_disabled()

    def place_event_after_event(self, event_to_place, target_event):
        if (event_to_place == target_event):
            return
        self.events.remove(event_to_place)
        new_index = self.events.index(target_event) + 1
        self.events.insert(new_index, event_to_place)

    def place_event_before_event(self, event_to_place, target_event):
        if (event_to_place == target_event):
            return
        self.events.remove(event_to_place)
        new_index = self.events.index(target_event)
        self.events.insert(new_index, event_to_place)

    def _ensure_no_circular_parent(self, cat):
        parent = cat.parent
        while parent is not None:
            if parent == cat:
                raise TimelineIOError("Circular category parent.")
            else:
                parent = parent.parent

    def find_event_with_id(self, id):
        for e in self.events:
            if e.id == id:
                return e
        return None

    def _find_category_with_id(self, id):
        for c in self.categories:
            if c.id == id:
                return c
        return None

    def _save_if_not_disabled(self):
        if self.save_disabled == False:
            self._save()

    def _get_displayed_period(self):
        """
        Inheritors can call this method to get the displayed period used in
        load_view_properties and save_view_properties.
        """
        return self.displayed_period

    def _set_displayed_period(self, period):
        """
        Inheritors can call this method to set the displayed period used in
        load_view_properties and save_view_properties.
        """
        self.displayed_period = period

    def _get_hidden_categories(self):
        """
        Inheritors can call this method to get the hidden categories used in
        load_view_properties and save_view_properties.
        """
        return self.hidden_categories

    def _set_hidden_categories(self, hidden_categories):
        """
        Inheritors can call this method to set the hidden categories used in
        load_view_properties and save_view_properties.
        """
        self.hidden_categories = []
        for cat in hidden_categories:
            if cat not in self.categories:
                raise ValueError("Category '%s' not in db." % cat.name)
            self.hidden_categories.append(cat)

    def _save(self):
        """
        Inheritors can override this method to save this db to persistent
        storage.

        Called whenever this db changes.
        """
        pass
示例#5
0
文件: ics.py 项目: jeromecc/gnumed
 def __init__(self, path):
     Observable.__init__(self)
     self.path = path
     self.event_id_counter = IdCounter()
     self.cals = []
     self.import_timeline(self.path)
示例#6
0
文件: ics.py 项目: jeromecc/gnumed
class IcsTimeline(Observable):
    def __init__(self, path):
        Observable.__init__(self)
        self.path = path
        self.event_id_counter = IdCounter()
        self.cals = []
        self.import_timeline(self.path)

    def get_time_type(self):
        return GregorianTimeType()

    def is_read_only(self):
        return True

    def supported_event_data(self):
        return []

    def search(self, search_string):
        return generic_event_search(self._get_events(), search_string)

    def get_events(self, time_period):
        def decider(event):
            return event.inside_period(time_period)

        return self._get_events(decider)

    def get_all_events(self):
        def decider(event):
            return True

        return self._get_events(decider)

    def get_first_event(self):
        events = self._get_events()
        if events:
            return min(events, key=lambda x: x.time_period.start_time)
        else:
            return None

    def get_last_event(self):
        events = self._get_events()
        if events:
            return max(events, key=lambda x: x.time_period.end_time)
        else:
            return None

    def save_event(self, event):
        pass

    def delete_event(self, event_or_id):
        pass

    def get_categories(self):
        return []

    def save_category(self, category):
        pass

    def delete_category(self, category_or_id):
        pass

    def load_view_properties(self, view_properties):
        pass

    def save_view_properties(self, view_properties):
        pass

    def find_event_with_id(self, id):
        events = self._get_events()
        for e in events:
            if e.id == id:
                return e
        return None

    def _get_events(self, decider_fn=None):
        self.events = []
        for cal in self.cals:
            for event in cal.walk("VEVENT"):
                start, end = extract_start_end(event)
                txt = ""
                if event.has_key("summary"):
                    txt = event["summary"]
                elif event.has_key("description"):
                    txt = event["description"]
                else:
                    txt == "Unknown"
                e = Event(self.get_time_type(), start, end, txt)
                e.set_id(event["timeline_id"])
                if event.has_key("description"):
                    e.set_data("description", event["description"])
                if decider_fn is None or decider_fn(e):
                    self.events.append(e)
        return self.events

    def import_timeline(self, path):
        try:
            ics_file = open(path, "rb")
            try:
                file_contents = ics_file.read()
                try:
                    cal = Calendar.from_ical(file_contents)
                    for event in cal.walk("VEVENT"):
                        event["timeline_id"] = self.event_id_counter.get_next()
                    self.cals.append(cal)
                except Exception, pe:
                    msg1 = _("Unable to read timeline data from '%s'.")
                    msg2 = "\n\n" + ex_msg(pe)
                    raise TimelineIOError((msg1 % abspath(path)) + msg2)
            finally:
                ics_file.close()
        except IOError, e:
            msg = _("Unable to read from file '%s'.")
            whole_msg = (msg + "\n\n%s") % (abspath(self.path), e)
            raise TimelineIOError(whole_msg)