Changeset 3609
- Timestamp:
- 10/10/08 22:13:10 (3 months ago)
- Location:
- trunk/beacon/src
- Files:
-
- 11 modified
-
db.py (modified) (5 diffs)
-
file.py (modified) (12 diffs)
-
fusefs.py (modified) (1 diff)
-
item.py (modified) (17 diffs)
-
media.py (modified) (8 diffs)
-
server/cdrom.py (modified) (3 diffs)
-
server/controller.py (modified) (6 diffs)
-
server/monitor.py (modified) (1 diff)
-
server/parser.py (modified) (1 diff)
-
server/server.py (modified) (2 diffs)
-
utils.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/beacon/src/db.py
r3604 r3609 71 71 # url is stored in the name (remote items in directory) 72 72 return Item(dbid, data['name'], data, parent, parent._beacon_media) 73 74 73 # generate url based on name and parent url 75 74 url = parent.url … … 88 87 Create a file or directory 89 88 """ 90 return File(data, parent, overlay, isdir) 89 if isinstance(data, str): 90 # fake item, there is no database entry 91 id = None 92 filename = parent.filename + data 93 data = { 'name': data } 94 if parent and parent._beacon_id: 95 data['parent_type'], data['parent_id'] = parent._beacon_id 96 media = parent._beacon_media 97 if isdir: 98 filename += '/' 99 elif isinstance(parent, File): 100 # db data 101 id = (data['type'], data['id']) 102 media = parent._beacon_media 103 filename = parent.filename + data['name'] 104 if isdir: 105 filename += '/' 106 elif not data['name']: 107 # root directory 108 id = (data['type'], data['id']) 109 media = parent 110 parent = None 111 filename = media.mountpoint 112 else: 113 raise ValueError('unable to create File item from %s', data) 114 return File(id, filename, data, parent, media, overlay, isdir) 91 115 92 116 … … 104 128 a directory, make it an Item, not a File. 105 129 """ 106 if (data.get('name').find('://') > 0) or (parent and not parent.isdir ()):130 if (data.get('name').find('://') > 0) or (parent and not parent.isdir): 107 131 return create_item(data, parent) 108 132 return create_file(data, parent, overlay, isdir) … … 278 302 # file deleted 279 303 i = items[pos] 280 if not i.isdir ()and not i.isfile():304 if not i.isdir and not i.isfile(): 281 305 # A remote URL in the directory 282 306 pos += 1 … … 300 324 # deleted files at the end 301 325 for i in items[pos+1-len(items):]: 302 if not i.isdir ()and not i.isfile():326 if not i.isdir and not i.isfile(): 303 327 # A remote URL in the directory 304 328 continue -
trunk/beacon/src/file.py
r3475 r3609 66 66 """ 67 67 68 def __init__(self, data, parent, overlay=False, isdir=False): 69 if isinstance(data, str): 70 # fake item, there is no database entry 71 id = None 72 filename = parent.filename + data 73 data = { 'name': data } 74 if parent and parent._beacon_id: 75 data['parent_type'], data['parent_id'] = parent._beacon_id 76 media = parent._beacon_media 77 if isdir: 78 filename += '/' 79 elif isinstance(parent, File): 80 # db data 81 id = (data['type'], data['id']) 82 media = parent._beacon_media 83 filename = parent.filename + data['name'] 84 if isdir: 85 filename += '/' 86 elif not data['name']: 87 # root directory 88 id = (data['type'], data['id']) 89 media = parent 90 parent = None 91 filename = media.mountpoint 92 else: 93 raise ValueError('unable to create File item from %s', data) 94 68 def __init__(self, id, filename, data, parent, media, overlay=False, isdir=False): 95 69 Item.__init__(self, id, 'file://' + filename, data, parent, media) 96 70 if self._beacon_data.get('scheme'): 97 71 # file uses a special scheme like dvd 98 72 self.url = self._beacon_data.get('scheme') + '://' + filename 99 100 73 self._beacon_overlay = overlay 101 74 self._beacon_isdir = isdir … … 109 82 self._beacon_islink = True 110 83 111 112 # -------------------------------------------------------------------------113 # Public API114 # -------------------------------------------------------------------------115 116 84 def list(self, recursive=False): 117 85 """ … … 120 88 @returns: InProgress object of a kaa.beacon.Query 121 89 """ 122 # This function is not used internally 123 return self._beacon_controller().query(parent=self, recursive=recursive) 124 90 # Note: this function is not used internally 91 return self._beacon_controller.query(parent=self, recursive=recursive) 125 92 126 93 def scan(self): 127 94 """ 128 95 Request the item to be scanned. 129 Returns either False if not connected or an InProgress object. 130 """ 131 # This function is only used by client.py used internally 132 result = self._beacon_controller()._beacon_parse(self) 96 97 @returns: False if not connected or an InProgress object. 98 """ 99 # Note: this function is not used by the server 100 result = self._beacon_controller._beacon_parse(self) 133 101 if isinstance(result, kaa.InProgress): 134 102 result.connect_once(self._beacon_database_update) 135 103 return result 136 137 138 def __repr__(self):139 """140 Convert object to string (usefull for debugging)141 """142 s = '<beacon.File %s' % self.filename143 if not self.url.startswith('file://'):144 s = '<beacon.File %s' % self.url145 if self._beacon_data.get('mtime') == None:146 s += ' (new)'147 else:148 s += ' (type=%s)' % str(self._beacon_data.get('type'))149 return s + '>'150 151 152 # -------------------------------------------------------------------------153 # Internal API154 # -------------------------------------------------------------------------155 104 156 105 def _beacon_listdir(self, cache=False): … … 165 114 # three seconds ago 166 115 return self._beacon_listdir_cache[1:] 167 168 116 # FIXME: this could block for everything except media 1. So this 169 117 # should be done in the hwmon process. But the server doesn't like … … 175 123 # No overlay 176 124 overlay_results = [] 177 178 125 try: 179 126 # Try to list the directory. If that fails for some reason, … … 184 131 self._beacon_listdir_cache = time.time(), [], {} 185 132 return [], {} 186 187 133 results_file_map = {} 188 134 timer = time.time() 189 190 135 for is_overlay, prefix, results in \ 191 136 ((False, self.filename, fs_results), … … 207 152 continue 208 153 results_file_map[r] = (r, fullpath, is_overlay, statinfo) 209 210 154 # We want to avoid lambda on large data sets, so we sort the keys, 211 155 # which is just a list of files. This is the common case that sort() … … 218 162 return result, results_file_map 219 163 220 164 @property 221 165 def _beacon_mtime(self): 222 166 """ … … 241 185 except (OSError, IOError): 242 186 return mtime 243 244 187 # Normal file 245 188 fullname = self._beacon_data['name'] … … 249 192 ext = basename[pos:] 250 193 basename = basename[:pos] 251 252 194 # FIXME: move this logic to kaa.metadata. The best way would be to 253 195 # use the info modules for that kind of information, but we may not … … 263 205 # cover 264 206 special_exts = ( '.png', '.jpg' ) 265 266 207 listdir_file_map = self._beacon_parent._beacon_listdir(cache=True)[1] 267 208 # calculate the new modification time … … 278 219 mtime += fname[3][stat.ST_MTIME] 279 220 return mtime 221 222 def __repr__(self): 223 """ 224 Convert object to string (usefull for debugging) 225 """ 226 s = '<beacon.File %s' % self.filename 227 if not self.url.startswith('file://'): 228 s = '<beacon.File %s' % self.url 229 if self._beacon_data.get('mtime') == None: 230 s += ' (new)' 231 else: 232 s += ' (type=%s)' % str(self._beacon_data.get('type')) 233 return s + '>' -
trunk/beacon/src/fusefs.py
r3079 r3609 87 87 self._query_update_time = int(time.time()) 88 88 for item in self._query: 89 if not item.isfile() and not item.isdir ():89 if not item.isfile() and not item.isdir: 90 90 # no file or dir, we can't link to it 91 91 continue -
trunk/beacon/src/item.py
r3475 r3609 50 50 url: unique url of the item 51 51 filename: empty string 52 isdir: False 53 isfile: False 54 scanned: True if the item is scanned 52 55 53 56 Functions: … … 56 59 __setitem__: set an attribute 57 60 keys: return all known attributes of the item 58 scanned: return True if the item is scanned59 61 list: return list of subitems 60 isdir: return False61 isfile: return False62 62 63 63 Do not access attributes starting with _beacon outside kaa.beacon … … 68 68 self.url = url 69 69 self.filename = '' 70 71 70 # internal data 72 71 self._beacon_id = _beacon_id … … 81 80 self._beacon_name = data['name'] 82 81 83 84 # -------------------------------------------------------------------------85 # Public API86 # -------------------------------------------------------------------------87 88 82 def get(self, key, default=None): 89 83 """ … … 95 89 if key.startswith('tmp:'): 96 90 return self._beacon_tmpdata.get(key[4:], default) 97 98 91 if key == 'parent': 99 92 return self._beacon_parent 100 101 93 if key == 'media': 102 94 return self._beacon_media 103 104 95 if key == 'read_only': 105 96 # FIXME: this is not correct, a directory can also be 106 97 # read only on a rw filesystem. 107 98 return self._beacon_media.get('volume.read_only', default) 108 109 99 if key in ('image', 'thumbnail'): 110 100 image = self._beacon_data.get('image') … … 122 112 if key == 'image': 123 113 return image 124 125 114 if key == 'thumbnail': 126 115 return Thumbnail(image, self._beacon_media) 127 128 129 116 if key == 'title': 130 117 t = self._beacon_data.get('title') … … 135 122 self._beacon_data['title'] = t 136 123 return t 137 138 124 result = self._beacon_data.get(key, default) 139 125 if result is None: … … 141 127 return result 142 128 143 144 129 def __getitem__(self, key): 145 130 return self.get(key) 146 147 131 148 132 def __setitem__(self, key, value): … … 157 141 self._beacon_data[key] = value 158 142 if not self._beacon_changes: 159 self._beacon_controller ()._beacon_update(self)143 self._beacon_controller._beacon_update(self) 160 144 self._beacon_changes[key] = value 161 145 162 163 146 def keys(self): 164 147 """ … … 166 149 """ 167 150 return self._beacon_data.keys() + self._beacon_tmpdata.keys() 168 169 151 170 152 def has_key(self, key): … … 175 157 key in self._beacon_tmpdata.keys() 176 158 177 159 @property 178 160 def scanned(self): 179 161 """ 180 ReturnTrue if the item is in the database and fully scanned.162 True if the item is in the database and fully scanned. 181 163 """ 182 164 return self._beacon_id is not None 183 165 166 @property 167 def isdir(self): 168 """ 169 True if the item is a directory. 170 """ 171 return self._beacon_isdir 172 173 @property 174 def isfile(self): 175 """ 176 True if the item is a regular file. 177 """ 178 return not self._beacon_isdir and self.filename != '' 184 179 185 180 def list(self): … … 195 190 # FIXME: return empty Query object 196 191 return result 197 return self._beacon_controller().query(parent=self) 198 199 200 def isdir(self): 201 """ 202 Return if the item is a directory. 203 """ 204 return self._beacon_isdir 205 206 207 def isfile(self): 208 """ 209 Return if the item is a regular file. 210 """ 211 return not self._beacon_isdir and self.filename != '' 212 192 return self._beacon_controller.query(parent=self) 213 193 214 194 def delete(self): … … 216 196 Delete item from the database (does not work on files) 217 197 """ 218 return self._beacon_controller().delete_item(self) 219 198 return self._beacon_controller.delete_item(self) 220 199 221 200 def scan(self): … … 225 204 return False 226 205 227 228 def get_ancestors(self):206 @property 207 def ancestors(self): 229 208 """ 230 209 Return an iterator to walk through the parents. 231 210 """ 232 211 return ParentIterator(self) 233 234 235 # -------------------------------------------------------------------------236 # Internal API237 # -------------------------------------------------------------------------238 212 239 213 def _beacon_database_update(self, data): … … 247 221 self._beacon_data[key] = value 248 222 249 223 @property 250 224 def _beacon_controller(self): 251 225 """ 252 226 Get the controller (the client or the server) 253 227 """ 254 return self._beacon_media. get_controller()255 256 228 return self._beacon_media._beacon_controller 229 230 @property 257 231 def _beacon_mtime(self): 258 232 """ … … 261 235 return None 262 236 263 264 237 def __repr__(self): 265 238 """ … … 267 240 """ 268 241 return '<beacon.Item %s>' % self.url 269 270 242 271 243 -
trunk/beacon/src/media.py
r3071 r3609 52 52 def __init__(self, id, controller): 53 53 log.info('new media %s', id) 54 self._ controller = controller54 self._beacon_controller = controller 55 55 self.id = id 56 56 # needed by server. … … 58 58 59 59 60 def get_controller(self):61 """62 Get the controller (the client or the server)63 """64 return self._controller65 66 67 60 def eject(self): 68 61 """ 69 62 Eject the media. 70 63 """ 71 self._ controller.eject(self)64 self._beacon_controller.eject(self) 72 65 73 66 … … 85 78 self.mountpoint += '/' 86 79 # get basic information from database 87 media = self._ controller._beacon_media_information(self)80 media = self._beacon_controller._beacon_media_information(self) 88 81 if isinstance(media, kaa.InProgress): 89 82 # This will happen for the client because in the client … … 151 144 152 145 153 def _get_beacon_media(self): 146 @property 147 def _beacon_media(self): 154 148 """ 155 149 Get _beacon_media which is this object itself. To avoid circular … … 157 151 """ 158 152 return self 159 160 _beacon_media = property(_get_beacon_media, None, None, "media reference")161 162 153 163 154 … … 169 160 self._dict = dict() 170 161 self._idlist = [] 171 self._ controller = None162 self._beacon_controller = None 172 163 173 164 … … 178 169 for media in self._dict.keys()[:]: 179 170 self.remove(media) 180 self._ controller = controller171 self._beacon_controller = controller 181 172 182 173 … … 186 177 Add a media. 187 178 """ 188 if not self._ controller:179 if not self._beacon_controller: 189 180 raise RuntimeError('not connected to database') 190 181 if id in self._dict: 191 182 yield self._dict.get(id) 192 media = Media(id, self._ controller)183 media = Media(id, self._beacon_controller) 193 184 async = media.update(prop) 194 185 if isinstance(async, kaa.InProgress): -
trunk/beacon/src/server/cdrom.py
r3608 r3609 34 34 import os 35 35 import sys 36 import re 36 37 import array 37 38 import struct … … 70 71 import kaa.metadata 71 72 72 from ..utils import fstab73 74 73 # get logging object 75 74 log = logging.getLogger('beacon.hal') … … 82 81 83 82 _rom_drives = [] 83 84 def fstab(): 85 """ 86 Read /etc/fstab into a list of (device, mountpoint, type, options) 87 """ 88 if not os.path.isfile('/etc/fstab'): 89 return [] 90 result = [] 91 regexp = re.compile('([^ \t]*)[ \t]*([^ \t]*)[ \t]*([^ \t]*)[ \t]*([^ \t]*)') 92 fd = open('/etc/fstab') 93 for line in fd.readlines(): 94 if line.find('#') >= 0: 95 line = line[:line.find('#')] 96 line = line.strip() 97 if not line: 98 continue 99 if not regexp.match(line): 100 continue 101 device, mountpoint, type, options = regexp.match(line).groups() 102 device = os.path.realpath(device) 103 result.append((device, mountpoint, type, options)) 104 fd.close() 105 return result 106 84 107 85 108 @kaa.threaded('beacon.cdrom') -
trunk/beacon/src/server/controller.py
r3608 r3609 51 51 self.hwmon = devices.HardwareMonitor(handler, db, rootfs) 52 52 53 # Item callbacks54 55 53 def _beacon_parse(self, item): 56 54 """ 57 55 Parse an item 56 Called by Item objects 58 57 """ 59 58 return parse(self._db, item) 60 61 59 62 60 @kaa.coroutine() … … 64 62 """ 65 63 Timed callback to write all changes to the db. 64 Called by Item objects 66 65 """ 67 66 while self._db.read_lock.is_locked(): … … 75 74 self._db.commit() 76 75 77 78 76 def _beacon_update(self, item): 79 77 """ 80 78 Mark item as changed to be updated in the db. 79 Called by Item objects 81 80 """ 82 81 if not self._changed: … … 85 84 self._changed.append(item) 86 85 87 88 86 def query(self, **query): 89 87 """ 90 88 Database query. 89 Called by Item objects 91 90 """ 92 91 return self._db.query(**query)
