Changeset 3614
- Timestamp:
- 11/10/08 12:12:01 (3 months ago)
- Location:
- trunk/beacon
- Files:
-
- 9 modified
-
doc/epydoc (modified) (1 diff)
-
src/__init__.py (modified) (8 diffs)
-
src/client.py (modified) (1 diff)
-
src/file.py (modified) (1 diff)
-
src/item.py (modified) (1 diff)
-
src/media.py (modified) (1 diff)
-
src/query.py (modified) (6 diffs)
-
src/server/server.py (modified) (1 diff)
-
src/thumbnail.py (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/beacon/doc/epydoc
r3611 r3614 37 37 # Don't examine in any way the modules whose dotted name match this 38 38 # regular expression pattern. 39 exclude: server, query, media, db, file, item, _libthumb, client, utils 39 exclude: server, query, media, db, file, item, _libthumb, client, utils, thumbnail 40 40 41 41 # Don't perform introspection on the modules whose dotted name match this -
trunk/beacon/src/__init__.py
r3611 r3614 32 32 """ 33 33 kaa.beacon 34 34 ========== 35 36 @group Internal Classes: Thumbnail, Item, File, Query, Media 35 37 @group Server: connect, launch 36 38 @group Query: query, get, monitor, register_filter, wrap 37 39 @group Media Handling: list_media, delete_media 38 @group Database Manipulation: add_item, register_file_type_attrs, register_track_type_attrs, get_db_info 40 @group Database Manipulation: add_item, register_inverted_index, 41 register_file_type_attrs, register_track_type_attrs, get_db_info 42 @group Thumbnailing: THUMBNAIL_NORMAL, THUMBNAIL_LARGE 43 @group kaa.db Variables: ATTR_SIMPLE, ATTR_SEARCHABLE, ATTR_IGNORE_CASE, ATTR_INDEXED, 44 ATTR_INDEXED_IGNORE_CASE, ATTR_INVERTED_INDEX 39 45 """ 40 46 41 47 __all__ = [ 'connect', 'launch', 'get', 'query', 'monitor', 'add_item', 'wrap', 42 'register_file_type_attrs', 'register_track_type_attrs', 'get_db_info', 43 'list_media', 'delete_media', 'register_filter', 'Item', 'Query', 'Media', 44 'File', 'VERSION', 'THUMBNAIL_NORMAL', 'THUMBNAIL_LARGE' ] 48 'register_file_type_attrs', 'register_track_type_attrs', 49 'register_inverted_index', 'get_db_info', 'list_media', 'delete_media', 50 'register_filter', 'Item', 'Query', 'Media', 'File', 'Thumbnail', 51 'VERSION', 'THUMBNAIL_NORMAL', 'THUMBNAIL_LARGE', 'QExpr', 'ATTR_SIMPLE', 52 'ATTR_SEARCHABLE', 'ATTR_IGNORE_CASE', 'ATTR_INDEXED', 53 'ATTR_INDEXED_IGNORE_CASE', 'ATTR_INVERTED_INDEX' ] 45 54 46 55 # python imports … … 61 70 from thumbnail import LARGE as THUMBNAIL_LARGE 62 71 from thumbnail import Thumbnail 63 from query import register_filter, wrap, Query64 72 from item import Item 65 73 from file import File … … 109 117 return _client 110 118 111 112 119 def launch(autoshutdown=False, verbose='none'): 113 120 """ … … 132 139 return connect() 133 140 141 def query(**args): 142 """ 143 Query the database. This function will raise an exception if the 144 client is not connected and the server is not running for a connect. 145 146 @returns: InProgress 147 @rtype: L{Query} 148 """ 149 if not _client: 150 connect() 151 return _client.query(**args) 134 152 135 153 def get(filename): … … 145 163 return _client.get(filename) 146 164 147 148 def query(**args):149 """150 Query the database. This function will raise an exception if the151 client is not connected and the server is not running for a connect.152 153 @returns: InProgress154 @rtype: L{Query}155 """156 if not _client:157 connect()158 return _client.query(**args)159 160 161 165 def monitor(directory): 162 166 """ … … 169 173 connect() 170 174 return _client.monitor(directory) 171 172 173 def add_item(url, type, parent, **kwargs):174 """175 Add an item to the database (not to be used for files).176 """177 if not _client:178 connect()179 return _client.add_item(url, type, parent, **kwargs)180 181 182 def register_file_type_attrs(name, **kwargs):183 """184 Register new attrs and types for files.185 """186 if not _client:187 connect()188 return _client.register_file_type_attrs(name, **kwargs)189 190 191 def register_track_type_attrs(name, **kwargs):192 """193 Register new attrs and types for files.194 """195 if not _client:196 connect()197 return _client.register_track_type_attrs(name, **kwargs)198 199 200 def get_db_info():201 """202 Gets statistics about the database.203 204 @return: basic database information205 """206 if not _client:207 connect()208 return _client.get_db_info()209 210 175 211 176 def list_media(): … … 222 187 return _client._db.medialist 223 188 224 225 189 def delete_media(id): 226 190 """ … … 234 198 kaa.main.step() 235 199 return _client.delete_media(id) 200 201 def add_item(url, type, parent, **kwargs): 202 """ 203 Add an item to the database. This function can be used to add an Item 204 as subitem to another. You can not add files that do not exist to a 205 directory, but it is possible to add an Item with a http url to a directory 206 or a meta item with http items as children. 207 208 @param url: url of the Item, can not be file: 209 @param type: item type 210 @param parent: parent item 211 @param kwargs: addition keyword/value arguments for the db 212 @returns: new created item 213 @rtype: L{Item} 214 """ 215 if not _client: 216 connect() 217 return _client.add_item(url, type, parent, **kwargs) 218 219 def register_inverted_index(name, min=None, max=None, split=None, ignore=None): 220 """ 221 Registers a new inverted index with the database. An inverted index 222 maps arbitrary terms to objects and allows you to query based on one 223 or more terms. If the inverted index already exists with the given 224 parameters, no action is performed. See kaa.db for details. 225 """ 226 if not _client: 227 connect() 228 return _client.register_inverted_index(name, min, max, split, ignore) 229 230 def register_file_type_attrs(type_name, indexes=[], **attrs): 231 """ 232 Registers one or more object attributes and/or multi-column 233 indexes for the given type name. This function modifies the 234 database as needed to accommodate new indexes and attributes, 235 either by creating the object's tables (in the case of a new 236 object type) or by altering the object's tables to add new columns 237 or indexes. 238 239 Previously registered attributes may be updated in limited ways 240 (e.g. by adding an index to the attribute). If the attributes 241 and indexes specified have not changed from previous invocations, 242 no changes will be made to the database. Therefore an application 243 should always call this function on startup if it needs attributes 244 not defined by beacon already. 245 246 @param type_name: is the name of the type the attributes and 247 indexes apply to (e.g. 'dir' or 'image'). 248 @param indexes: a list of tuples, where each tuple contains 2 or 249 more strings, where each string references a registered 250 attribute. This is used for creating a multi-column index on 251 these attributes, which is useful for speeding up queries 252 involving these attributes. 253 @param attrs: where each keyword value is a tuple of 2 to 4 items 254 in length and in the form (name, flags, ivtidx, split): 255 - name: The name of the attribute; cannot conflict with any of the 256 values in RESERVED_ATTRIBUTES. 257 - flags: A bitmask of ATTR_* flags. 258 - ivtidx: Name of the previously registered inverted index used for 259 this attribute, only if flags contains ATTR_INVERTED_INDEX. 260 - split: Function or regular expression used to split string-based 261 values for this attributes into separate terms for indexing. 262 @note: currently indexes and attributes can only be added, not 263 removed. That is, once an attribute or indexes is added, it 264 lives forever. 265 """ 266 if not _client: 267 connect() 268 return _client.register_file_type_attrs(type_name, indexes, **attrs) 269 270 def register_track_type_attrs(type_name, indexes=[], **attrs): 271 """ 272 Register new attrs and types for tracks. See L{register_file_type_attrs} 273 for details. The only difference between this two functions is that this 274 adds C{track_} to the type name. 275 """ 276 if not _client: 277 connect() 278 return _client.register_track_type_attrs(type_name, indexes, **attrs) 279 280 def get_db_info(): 281 """ 282 Gets statistics about the database. 283 284 @return: basic database information 285 """ 286 if not _client: 287 connect() 288 return _client.get_db_info() 289 290 # import some more functions and classes we expose to the API 291 # It is done at the end of this file to force a better order of the 292 # functions for epydoc 293 from query import register_filter, wrap, Query -
trunk/beacon/src/client.py
r3611 r3614 171 171 172 172 173 def register_inverted_index(self, name, *args, **kwargs):173 def register_inverted_index(self, name, min=None, max=None, split=None, ignore=None): 174 174 """ 175 175 Register new inverted index. 176 176 """ 177 177 if self.status != DISCONNECTED: 178 self.rpc('db.register_inverted_index', name, *args, **kwargs)179 180 181 def register_file_type_attrs(self, name, **kwargs):178 self.rpc('db.register_inverted_index', name, min, max, split, ignore) 179 180 181 def register_file_type_attrs(self, type_name, indexes=[], **attrs): 182 182 """ 183 183 Register new attrs and types for files. 184 184 """ 185 185 if self.status != DISCONNECTED: 186 self.rpc('db.register_file_type_attrs', name, **kwargs)187 188 189 def register_track_type_attrs(self, name, **kwargs):190 """ 191 Register new attrs and types for files.192 """ 193 if self.status != DISCONNECTED: 194 self.rpc('db.register_track_type_attrs', name, **kwargs)186 self.rpc('db.register_file_type_attrs', type_name, indexes, **attrs) 187 188 189 def register_track_type_attrs(self, type_name, indexes=[], **attrs): 190 """ 191 Register new attrs and types for tracks. 192 """ 193 if self.status != DISCONNECTED: 194 self.rpc('db.register_track_type_attrs', type_name, indexes, **attrs) 195 195 196 196 -
trunk/beacon/src/file.py
r3611 r3614 47 47 class File(Item): 48 48 """ 49 A file based database item. 49 A File-based Database Item. 50 51 see L{Item} for a list of available attributes. 50 52 51 53 @ivar url: unique url of the item -
trunk/beacon/src/item.py
r3611 r3614 45 45 class Item(object): 46 46 """ 47 A database item. 47 A Database Item 48 =============== 49 50 The following attributes are available. If more are needed please call 51 L{register_file_type_attrs} or L{register_track_type_attrs}. 52 53 Directories (type = C{dir}) 54 - C{name} (str, searchable, inverted_index: 'keywords') 55 - C{overlay} (bool, simple) 56 - C{media} (int, searchable, indexed) 57 - C{image} (int, simple) 58 - C{mtime} (int, simple) 59 - C{title} (unicode, simple) 60 - C{artist} (unicode, simple) 61 - C{album} (unicode, simple) 62 - C{length} (float, simple), length in seconds of all items in that directory 63 64 Items and Files (type = C{file} and all media types) 65 - C{name} (str, searchable, inverted_index: 'keywords') 66 - C{overlay} (bool, simple) 67 - C{media} (int, searchable, indexed) 68 - C{image} (int, simple) 69 - C{mtime} (int, simple) 70 71 Video Items (type = C{video}) 72 - C{title} (unicode, searchable, ignore_case, inverted_index: 'keywords'), 73 - C{width} (int, simple) 74 - C{height} (int, simple) 75 - C{length} (float, simple) 76 - C{scheme} (str, simple) 77 - C{description} (unicode, simple) 78 - C{timestamp} (int, searchable) 79 80 Audio Items (type = C{audio}) 81 - C{title} (unicode, searchable, ignore_case, inverted_index: 'keywords') 82 - C{artist} (unicode, searchable, indexed, ignore_case, inverted_index: 'keywords') 83 - C{album} (unicode, searchable, ignore_case, inverted_index: 'keywords') 84 - C{genre} (unicode, searchable, indexed, ignore_case) 85 - C{samplerate} (int, simple) 86 - C{length} (float, simple) 87 - C{bitrate} (int, simple) 88 - C{trackno} (int, simple) 89 - C{userdate} (unicode, simple) 90 - C{description} (unicode, simple) 91 - C{timestamp} (int, searchable) 92 93 Image Items (type = C{image}) 94 - C{width} (int, searchable) 95 - C{height} (int, searchable) 96 - C{comment} (unicode, searchable, ignore_case, inverted_index: 'keywords') 97 - C{rotation} (int, simple) 98 - C{author} (unicode, simple) 99 - C{timestamp} (int, searchable) 100 101 DVD Track Items (type = C{dvd}) 102 - C{length} (float, simple) 103 - C{audio} (list, simple) 104 - C{chapters} (int, simple) 105 - C{subtitles} (list, simple) 106 107 VCD Track Items (type = C{vcd}) 108 - C{audio} (list, simple) 109 110 Audio CD Track Items (type = C{cdda}) 111 - C{title} (unicode, searchable, inverted_index: 'keywords') 112 - C{artist} (unicode, searchable, indexed, inverted_index: 'keywords') 48 113 49 114 @ivar url: unique url of the item -
trunk/beacon/src/media.py
r3611 r3614 49 49 """ 50 50 Media object for a specific mount point. 51 52 The following attributes are available. 53 54 - C{name} (str, searchable | inverted_index: 'keywords') 55 - C{content} (str, simple) 56 57 @note: Objects are created by the hardware monitor subsystem, do not create 58 Media objects from outside beacon. 51 59 """ 52 60 def __init__(self, id, controller): 53 61 """ 54 62 Create a media object 55 56 @note: Objects are created by the hardware monitor subsystem, do not create57 Media objects from outside beacon.58 63 """ 59 64 log.info('new media %s', id) -
trunk/beacon/src/query.py
r3475 r3614 47 47 48 48 def register_filter(name, function): 49 """ 50 Register a filter for L{Query} or L{wrap} to process a list of items. 51 52 @param name: unique name for the filter 53 @param function: filter function 54 """ 49 55 _query_filter[name] = function 50 56 51 57 52 58 def wrap(items, filter): 59 """ 60 Wrap the given list of items with the given filter function 61 62 @param items: list of items 63 @param filter: name of the filter, see L{register_filter} 64 """ 53 65 if not filter in _query_filter: 54 66 raise AttributeError('unknown filter') … … 59 71 """ 60 72 Query object for the client. Created by Client.query() 73 74 This object feels like a list, you can iterate over the results, 75 access items based on position and get the length of the 76 results. 77 78 @group Internal API: __init__, __del__, __repr__, __inprogress__ 79 @note: A Query is created by Client.query(), do not create Query objects 80 from outside beacon. 61 81 """ 62 82 NEXT_ID = 1 63 83 64 84 def __init__(self, client, **query): 65 66 # FIXME: add a complete signal on first scan 85 """ 86 Create a Query object and start the query on the client 87 """ 67 88 # FIXME: progress and up-to-date seems not used 68 self.signals = { 69 'changed' : kaa.Signal(), 70 'progress' : kaa.Signal(), 71 'up-to-date': kaa.Signal(), 72 } 89 self.signals = kaa.Signals('changed', 'progress', 'up-to-date') 73 90 self.id = Query.NEXT_ID 74 91 Query.NEXT_ID += 1 75 76 92 # public variables 77 93 self.monitoring = False … … 103 119 """ 104 120 Turn on/off query monitoring 121 122 @param status: True to turn on monitoring, False to turn it off. 105 123 """ 106 124 if self.monitoring == status: … … 132 150 """ 133 151 Iterate through the results. 152 153 @returns: Iterator 154 @rtype: L{Item} or L{File} 134 155 """ 135 156 return self.result.__iter__() 136 157 137 158 138 def __getitem__(self, key): 139 """ 140 Get a specific item in the results. 141 list. 142 """ 143 return self.result[key] 159 def __getitem__(self, pos): 160 """ 161 Get a specific item in the results list. 162 163 @returns: Item on that position in the list 164 @rtype: L{Item} or L{File} 165 @raises IndexError: result list is shorten than pos 166 """ 167 return self.result[pos] 144 168 145 169 … … 147 171 """ 148 172 Get index of an item in the results. This function will raise an 149 exception if the item is not in the results or if the query object is 150 still invalid. 173 exception if the item is not in the results. 151 174 """ 152 175 return self.result.index(item) … … 163 186 """ 164 187 Get the result. 188 189 @param filter: filter function set by L{register_filter} to use on the 190 result. If a filter is used the result type may be different. 191 @returns: (filtered) query result 192 @rtype: list of L{Item} or L{File} 165 193 """ 166 194 if filter == None: -
trunk/beacon/src/server/server.py
r3609 r3614 237 237 238 238 @kaa.rpc.expose('db.register_inverted_index') 239 def register_inverted_index(self, name, *args, **kwargs):239 def register_inverted_index(self, name, min=None, max=None, split=None, ignore=None): 240 240 """ 241 241 Register new inverted index. The basics are already in the db by the 242 242 __init__ function of this class. 243 243 """ 244 return self._db.register_inverted_index(name, *args, **kwargs)244 return self._db.register_inverted_index(name, min, max, split, ignore) 245 245 246 246 247 247 @kaa.rpc.expose('db.register_file_type_attrs') 248 def register_file_type_attrs(self, name, **kwargs):248 def register_file_type_attrs(self, type_name, indexes=[], **attrs): 249 249 """ 250 250 Register new attrs and types for files. The basics are already 251 251 in the db by the __init__ function of this class. 252 252 """ 253 return self._db.register_object_type_attrs( name, **kwargs)253 return self._db.register_object_type_attrs(type_name, indexes, **attrs) 254 254 255 255 256 256 @kaa.rpc.expose('db.register_track_type_attrs') 257 def register_track_type_attrs(self, name, **kwargs):258 """ 259 Register new attrs and types for files. The basics are already257 def register_track_type_attrs(self, type_name, indexes=[], **attrs): 258 """ 259 Register new attrs and types for tracks. The basics are already 260 260 in the db by the __init__ function of this class. 261 261 """ 262 return self._db.register_object_type_attrs('track_%s' % name, **kwargs) 262 type_name = 'track_%s' % type_name 263 return self._db.register_object_type_attrs(type_name, indexes, **attrs) 263 264 264 265 -
trunk/beacon/src/thumbnail.py
r3396 r3614 7 7 # ----------------------------------------------------------------------------- 8 8 # kaa.beacon - A virtual filesystem with metadata 9 # Copyright (C) 2006 Dirk Meyer9 # Copyright (C) 2006-2008 Dirk Meyer 10 10 # 11 11 # First Edition: Dirk Meyer <dischi@freevo.org> … … 77 77 78 78 class Thumbnail(object): 79 79 """ 80 Thumbnail handling. This objects is a wrapper for full size image path names. 81 82 @note: A Thumbnail object is created by an L{Item}, do not create Thumbnail objects 83 from outside beacon. 84 """ 80 85 # priority for creating 81 86 PRIORITY_HIGH = 0 … … 87 92 NORMAL = 'normal' 88 93 89 next_id = 094 _next_id = 0 90 95 91 96 def __init__(self, name, media, url=None): 97 """ 98 Create Thumbnail handler 99 100 @param name: full, absolute path name of the image file 101 @param media: beacon Media object to determine the thumbnailing directory 102 @param url: url to store in the thumbnail 103 """ 92 104 if not name.startswith('/'): 93 105 # FIXME: realpath should not be needed here because … … 105 117 self._thumbnail = media.thumbnails + '/%s/' + md5.md5(self.url).hexdigest() 106 118 107 108 119 def get(self, type='any', check_mtime=False): 120 """ 121 Get the filename to the thumbnail. 122 123 @param type: THUMBNAIL_NORMAL, THUMBNAIL_LARGE or 'any' 124 @param check_mtime: Check the file modification time against the information 125 stored in the thumbnail. If the file has changed, the thumbnail will not be 126 returned. 127 @returns: full path to thumbnail file or None 128 """ 109 129 if check_mtime: 110 130 image = self.get(type) … … 117 137 # mtime check failed, return no image 118 138 return None 119 120 139 if type == 'any': 121 140 image = self.get(LARGE, check_mtime) … … 131 150 return None 132 151 133 134 152 def set(self, image, type='both'): 153 """ 154 Set the thumbnail 155 156 @param image: Image containing the thumbnail 157 @type image: kaa.Imlib2 image object 158 @param type: THUMBNAIL_NORMAL, THUMBNAIL_LARGE or 'both' 159 """ 135 160 if type == 'both': 136 161 self.set(image, NORMAL) 137 self.set(image, LARGE) 138 return 139 162 return self.set(image, LARGE) 140 163 dest = '%s/%s' % (self.destdir, type) 141 142 164 i = self._thumbnail % type + '.png' 143 165 png(self.name, i, SIZE[type], image._image) 144 166 log.info('store %s', i) 145 167 146 147 168 def exists(self, check_mtime=False): 169 """ 170 Check if a thumbnail exists. This function checks normal and large sized 171 thumbnails as well as the fail directory for previous attempts to create 172 a thumbnail for this file. 173 174 @param check_mtime: check the file and thumbnail modification time if a 175 thumbnail is valid. 176 """ 148 177 return self.get(NORMAL, check_mtime) or self.get(LARGE, check_mtime) \ 149 178 or self.get('fail/beacon', check_mtime) 150 179 151 152 180 def is_failed(self): 181 """ 182 Check if thumbnailing failed before. Failed attempts are stored in the 183 fail/beacon subdirectory. 184 """ 153 185 return self.get('fail/beacon') 154 186 155 156 187 def create(self, type=NORMAL, priority=None): 188 """ 189 Create a thumbnail. 190 191 @param type: one of THUMBNAIL_NORMAL and THUMBNAIL_LARGE 192 @param priority: priority how important the thumbnail is. The thumbnail 193 process will handle the thumbnail generation based on this priority. 194 If you loose all references to this thumbnail object, the priority will 195 automatically set to the lowest value (2). 196 197 Maximum value is 0, default 1. 198 """ 157 199 if priority is None: 158 200
