Package Gnumed :: Package timelinelib :: Package db
[frames] | no frames]

Source Code for Package Gnumed.timelinelib.db

  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  import os.path 
 20   
 21  from timelinelib.db.backends.memory import MemoryDB 
 22  from timelinelib.db.backends.tutorial import create_in_memory_tutorial_db 
 23  from timelinelib.db.exceptions import TimelineIOError 
 24  from timelinelib.db.objects import Category 
 25  from timelinelib.db.objects import Event 
 26  from timelinelib.db.objects import TimePeriod 
 27  from timelinelib.drawing.viewproperties import ViewProperties 
 28   
 29   
30 -def db_open(path, use_wide_date_range=False):
31 """ 32 Create timeline database that can read and write timeline data from and to 33 persistent storage identified by path. 34 35 Throw a TimelineIOError exception if not able to read from the given path. 36 37 Valid values for path: 38 39 - special string ":tutorial:" 40 - string with suffix .timeline 41 - string with suffix .ics 42 - string denoting a directory 43 """ 44 if path == ":tutorial:": 45 return create_in_memory_tutorial_db() 46 elif os.path.isdir(path): 47 from timelinelib.db.backends.dir import DirTimeline 48 return DirTimeline(path) 49 elif path.endswith(".timeline"): 50 if (os.path.exists(path) and 51 file_starts_with(path, "# Written by Timeline ")): 52 # Convert file db to xml db 53 from timelinelib.db.backends.file import FileTimeline 54 from timelinelib.db.backends.xmlfile import XmlTimeline 55 file_db = FileTimeline(path) 56 xml_db = XmlTimeline(path, load=False, 57 use_wide_date_range=use_wide_date_range) 58 copy_db(file_db, xml_db) 59 return xml_db 60 else: 61 from timelinelib.db.backends.xmlfile import XmlTimeline 62 return XmlTimeline(path, use_wide_date_range=use_wide_date_range) 63 elif path.endswith(".ics"): 64 try: 65 import icalendar 66 except ImportError: 67 raise TimelineIOError(_("Could not find iCalendar Python package. It is required for working with ICS files. See the Timeline website or the INSTALL file for instructions how to install it.")) 68 else: 69 from timelinelib.db.backends.ics import IcsTimeline 70 return IcsTimeline(path) 71 else: 72 msg_template = (_("Unable to open timeline '%s'.") + "\n\n" + 73 _("Unknown format.")) 74 raise TimelineIOError(msg_template % path)
75 76
77 -def file_starts_with(path, start):
78 return read_first_line(path).startswith(start)
79 80
81 -def read_first_line(path):
82 try: 83 f = open(path) 84 try: 85 line = f.readline() 86 return line 87 finally: 88 f.close() 89 except IOError: 90 raise TimelineIOError("Unable to read data from '%s'." % path)
91 92
93 -def copy_db(from_db, to_db):
94 """ 95 Copy all content from one db to another. 96 97 to_db is assumed to have no categories (conflicting category names are not 98 handled). 99 """ 100 if isinstance(to_db, MemoryDB): 101 to_db.disable_save() 102 # Copy categories (parent attribute fixed later) 103 cat_map = {} 104 for cat in from_db.get_categories(): 105 # name, color, and visible all immutable so safe to copy 106 new_cat = Category(cat.name, cat.color, None, cat.visible) 107 cat_map[cat.name] = new_cat 108 to_db.save_category(new_cat) 109 # Fix parent attribute 110 for cat in from_db.get_categories(): 111 if cat.parent is not None: 112 cat_map[cat.name].parent = cat_map[cat.parent.name] 113 # Copy events 114 for event in from_db.get_all_events(): 115 cat = None 116 if event.category is not None: 117 cat = cat_map[event.category.name] 118 # start_time, end_time, and text all immutable so safe to copy 119 new_event = Event(to_db.get_time_type(), event.time_period.start_time, 120 event.time_period.end_time, 121 event.text, 122 cat) 123 # description immutable so safe to copy 124 if event.get_data("description") is not None: 125 new_event.set_data("description", event.get_data("description")) 126 # icon immutable in practice (since never modified) so safe to copy 127 if event.get_data("icon") is not None: 128 new_event.set_data("icon", event.get_data("icon")) 129 to_db.save_event(new_event) 130 # Copy view properties (ViewProperties is specific to db so we need to copy 131 # like this instead of just using load/save_view_properties in db). 132 from_vp = ViewProperties() 133 from_db.load_view_properties(from_vp) 134 to_vp = ViewProperties() 135 for from_cat in from_db.get_categories(): 136 cat = cat_map[from_cat.name] 137 visible = from_vp.category_visible(from_cat) 138 to_vp.set_category_visible(cat, visible) 139 if from_vp.displayed_period is not None: 140 # start_time and end_time immutable so safe to copy 141 start = from_vp.displayed_period.start_time 142 end = from_vp.displayed_period.end_time 143 to_vp.displayed_period = TimePeriod(to_db.get_time_type(), start, end) 144 to_db.save_view_properties(to_vp) 145 # Save 146 if isinstance(to_db, MemoryDB): 147 to_db.enable_save()
148