Exemple #1
0
def db_open(path, timetype=None):
    """
    Create timeline database that can read and write timeline data from and to
    persistent storage identified by path.

    Throw a TimelineIOError exception if not able to read from the given path.

    Valid values for path:

      - special string ":tutorial:"
      - string with suffix .timeline
      - string with suffix .ics
      - string denoting a directory
    """
    if path == ":tutorial:":
        return open_gregorian_tutorial_timeline(path)
    elif path == ":numtutorial:":
        return open_numeric_tutorial_timeline(path)
    elif os.path.isdir(path):
        return open_directory_timeline(path)
    elif path.endswith(".timeline"):
        return db_open_timeline(path, timetype)
    elif path.endswith(".ics"):
        return db_open_ics(path)
    else:
        msg_template = (_("Unable to open timeline '%s'.") + "\n\n" +
                        _("Unknown format."))
        raise TimelineIOError(msg_template % path)
Exemple #2
0
 def _read_calendar_object(self, file_contents):
     try:
         return Calendar.from_ical(file_contents)
     except Exception as pe:
         msg1 = _("Unable to read calendar data.")
         msg2 = "\n\n" + ex_msg(pe)
         raise TimelineIOError(msg1 + msg2)
Exemple #3
0
 def _convert_to_datetime(self, d):
     if isinstance(d, datetime):
         return GregorianDateTime(d.year, d.month, d.day, d.hour, d.minute, d.second).to_time()
     elif isinstance(d, date):
         return GregorianDateTime.from_ymd(d.year, d.month, d.day).to_time()
     else:
         raise TimelineIOError("Unknown date.")
Exemple #4
0
 def save_events(self, events):
     try:
         with self.transaction("Save events"):
             for event in events:
                 event.db = self
                 event.save()
     except Exception as e:
         raise TimelineIOError("Saving event failed: %s" % e)
Exemple #5
0
def db_open_timeline(path, timetype=None):
    if (os.path.exists(path)
            and file_starts_with(path, "# Written by Timeline ")):
        raise TimelineIOError(
            _("You are trying to open an old file with a new version of timeline. Please install version 0.21.1 of timeline to convert it to the new format."
              ))
    else:
        return db_open_newtype_timeline(path, timetype)
Exemple #6
0
 def delete_event(self, event_or_id):
     try:
         if isinstance(event_or_id, Event):
             event = event_or_id
         else:
             event = self.find_event_with_id(event_or_id)
         event.db = self
         event.delete()
     except Exception as e:
         raise TimelineIOError("Deleting event failed: %s" % e)
Exemple #7
0
 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_category_ids = []
     for cat in self.get_categories():
         if not view_properties.is_category_visible(cat):
             self._hidden_category_ids.append(cat.id)
     self._save()
Exemple #8
0
def read_first_line(path):
    try:
        f = open(path)
        try:
            line = f.readline()
            return line
        finally:
            f.close()
    except IOError:
        raise TimelineIOError("Unable to read data from '%s'." % path)
Exemple #9
0
def db_open_ics(path):
    try:
        import icalendar
        from timelinelib.wxgui.dialogs.importics.view import ImportIcsDialog
    except ImportError:
        raise TimelineIOError(
            _("Could not find iCalendar Python package. It is required for working with ICS files."
              ))
    else:
        from timelinelib.dataimport.ics import import_db_from_ics
        return import_db_from_ics(path, ImportIcsDialog)
Exemple #10
0
 def _read_file_content(self, path):
     ics_file = None
     try:
         ics_file = open(path, "rb")
         return ics_file.read()
     except IOError as e:
         msg = _("Unable to read from file '%s'.")
         whole_msg = (msg + "\n\n%s") % (abspath(path), e)
         raise TimelineIOError(whole_msg)
     finally:
         if ics_file is not None:
             ics_file.close()
Exemple #11
0
 def delete_category(self, category_or_id):
     try:
         if isinstance(category_or_id, Category):
             category = category_or_id
         else:
             with self._query() as query:
                 category = query.get_category(category_or_id)
         if category.id in self._hidden_category_ids:
             self._hidden_category_ids.remove(category.id)
         category.db = self
         category.delete()
     except Exception as e:
         raise TimelineIOError("Deleting category failed: %s" % e)
Exemple #12
0
 def _load(self):
     try:
         # _parse_version will create the rest of the schema dynamically
         partial_schema = Tag("timeline", SINGLE, None,
                              [Tag("version", SINGLE, self._parse_version)])
         tmp_dict = {
             "partial_schema": partial_schema,
             "category_map": {},
             "hidden_categories": [],
         }
         parse(self.path, partial_schema, tmp_dict)
     except Exception as e:
         msg = _("Unable to read timeline data from '%s'.")
         whole_msg = (msg + "\n\n%s") % (abspath(self.path), ex_msg(e))
         raise TimelineIOError(whole_msg)
Exemple #13
0
def _load(db, dir_path):
    """
    Load timeline data from the given directory.

    Each filename inside the directory (at any level) becomes an event where
    the text is the filename name and the time is the modification time for
    the filename.

    For each sub-directory a category is created and all events (files)
    belong the category (directory) in which they are.
    """
    if not os.path.exists(dir_path):
        # Nothing to load
        return
    if not os.path.isdir(dir_path):
        # Nothing to load
        return
    try:
        color_ranges = {}  # Used to color categories
        color_ranges[dir_path] = (0.0, 1.0, 1.0)
        all_cats = []
        parents = {}
        for (dirpath, dirnames, filenames) in os.walk(dir_path):
            # Assign color ranges
            (rstart, rend, b) = color_ranges[dirpath]
            step = (rend - rstart) / (len(dirnames) + 1)
            next_start = rstart + step
            new_b = b - 0.2
            if new_b < 0:
                new_b = 0
            for dirname in dirnames:
                next_end = next_start + step
                color_ranges[os.path.join(dirpath,
                                          dirname)] = (next_start, next_end,
                                                       new_b)
                next_start = next_end
            # Create the stuff
            p = parents.get(os.path.normpath(os.path.join(dirpath, "..")),
                            None)
            cat = Category().update(dirpath, (233, 233, 233), None, parent=p)
            parents[os.path.normpath(dirpath)] = cat
            all_cats.append(cat)
            db.save_category(cat)
            for filename in filenames:
                path_inner = os.path.join(dirpath, filename)
                evt = _event_from_path(db, path_inner)
                db.save_event(evt)
        # Hide all categories but the first
        db.set_hidden_categories(all_cats[1:])
        # Set colors and change names
        used_names = []
        for cat in db.get_categories():
            cat.color = _color_from_range(color_ranges[cat.name])
            cat.name = get_unique_cat_name(os.path.basename(cat.name),
                                           used_names)
            db.save_category(cat)
    except Exception as e:
        msg = _("Unable to read from filename '%s'.") % dir_path
        whole_msg = "%s\n\n%s" % (msg, e)
        print(whole_msg)
        raise TimelineIOError(whole_msg)
Exemple #14
0
 def save_category(self, category):
     try:
         category.db = self
         category.save()
     except Exception as e:
         raise TimelineIOError("Saving category failed: %s" % e)
Exemple #15
0
 def delete_era(self, era):
     try:
         era.db = self
         era.delete()
     except Exception as e:
         raise TimelineIOError("Deleting Era failed: %s" % e)
Exemple #16
0
 def save_era(self, era):
     try:
         era.db = self
         era.save()
     except Exception as e:
         raise TimelineIOError("Saving Era failed: %s" % e)
Exemple #17
0
 def raise_error(specific_msg, cause_exception):
     err_general = _("Unable to save timeline data to '%s'. File left unmodified.") % path
     err_template = "%s\n\n%%s\n\n%%s" % err_general
     raise TimelineIOError(err_template % (to_unicode(specific_msg), to_unicode(cause_exception)))