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

Source Code for Module Gnumed.timelinelib.db.backends.dir

  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  """ 
 20  Implementation of read-only timeline database where events show modification 
 21  times of files in a directory. 
 22  """ 
 23   
 24   
 25  import os 
 26  import os.path 
 27  import colorsys 
 28  from datetime import datetime 
 29  from datetime import timedelta 
 30  import time 
 31   
 32  import wx 
 33   
 34  from timelinelib.db.backends.memory import MemoryDB 
 35  from timelinelib.db.exceptions import TimelineIOError 
 36  from timelinelib.db.objects import Category 
 37  from timelinelib.db.objects import Event 
 38   
 39   
40 -class DirTimeline(MemoryDB):
41
42 - def __init__(self, path):
43 MemoryDB.__init__(self) 44 self._load(path)
45
46 - def is_read_only(self):
47 """Override MemoryDB's read-only attribute.""" 48 return True
49
50 - def _load(self, dir_path):
51 """ 52 Load timeline data from the given directory. 53 54 Each file inside the directory (at any level) becomes an event where 55 the text is the file name and the time is the modification time for 56 the file. 57 58 For each sub-directory a category is created and all events (files) 59 belong the category (directory) in which they are. 60 """ 61 if not os.path.exists(dir_path): 62 # Nothing to load 63 return 64 if not os.path.isdir(dir_path): 65 # Nothing to load 66 return 67 try: 68 self.disable_save() 69 color_ranges = {} # Used to color categories 70 color_ranges[dir_path] = (0.0, 1.0, 1.0) 71 all_cats = [] 72 parents = {} 73 for (dirpath, dirnames, filenames) in os.walk(dir_path): 74 # Assign color ranges 75 range = (rstart, rend, b) = color_ranges[dirpath] 76 step = (rend - rstart) / (len(dirnames) + 1) 77 next_start = rstart + step 78 new_b = b - 0.2 79 if new_b < 0: 80 new_b = 0 81 for dir in dirnames: 82 next_end = next_start + step 83 color_ranges[os.path.join(dirpath, dir)] = (next_start, 84 next_end, new_b) 85 next_start = next_end 86 # Create the stuff 87 p = parents.get(os.path.normpath(os.path.join(dirpath, "..")), 88 None) 89 cat = Category(dirpath, (233, 233, 233), None, False, parent=p) 90 parents[os.path.normpath(dirpath)] = cat 91 all_cats.append(cat) 92 self.save_category(cat) 93 for file in filenames: 94 path_inner = os.path.join(dirpath, file) 95 evt = self._event_from_path(path_inner) 96 self.save_event(evt) 97 # Hide all categories but the first 98 self._set_hidden_categories(all_cats[1:]) 99 # Set colors and change names 100 for cat in self.get_categories(): 101 cat.color = self._color_from_range(color_ranges[cat.name]) 102 cat.name = os.path.basename(cat.name) 103 self.save_category(cat) 104 except Exception, e: 105 msg = _("Unable to read from file '%s'.") % dir_path 106 whole_msg = "%s\n\n%s" % (msg, e) 107 raise TimelineIOError(whole_msg) 108 finally: 109 self.enable_save(call_save=False)
110
111 - def _event_from_path(self, file_path):
112 stat = os.stat(file_path) 113 # st_atime (time of most recent access), 114 # st_mtime (time of most recent content modification), 115 # st_ctime (platform dependent; time of most recent metadata change on 116 # Unix, or the time of creation on Windows): 117 start_time = datetime.fromtimestamp(int(stat.st_mtime)) 118 end_time = start_time 119 if start_time > end_time: 120 start_time, end_time = end_time, start_time 121 text = os.path.basename(file_path) 122 category = self._category_from_path(file_path) 123 evt = Event(self.get_time_type(), start_time, end_time, text, category) 124 return evt
125
126 - def _category_from_path(self, file_path):
127 for cat in self.get_categories(): 128 if cat.name == os.path.dirname(file_path): 129 return cat 130 return None
131
132 - def _category_from_name(self, name):
133 for cat in self.get_categories(): 134 if cat.name == name: 135 return cat 136 return None
137
138 - def _color_from_range(self, range):
139 (rstart, rend, b) = range 140 (r, g, b) = colorsys.hsv_to_rgb(rstart, b, 1) 141 return (r*255, g*255, b*255)
142