import os localDir = os.path.join(os.getcwd(), os.path.dirname(__file__)) from dejavu import Arena, LOGMEMORIZE, Schema, Unit, UnitProperty, warehouse arena = Arena() from PIL import Image __all__ = ['arena', 'Library', 'Resource', 'Tag', 'PinximusSchema'] class Library(Unit): """A library of Pinximus Resources.""" Name = UnitProperty() Path = UnitProperty() def register_resources(self): if not self.Path or not os.path.exists(self.Path): return selfpath = os.path.normpath(self.Path) box = self.sandbox for root, dirs, files in os.walk(selfpath): root = os.path.normpath(root) if "/." in root or r"\." in root: # Skip any directory that starts with "." continue if not root.startswith(selfpath): raise ValueError("Illegal path '%s'" % root) # Assert the thumbnail subfolder thumbpath = os.path.join(root, ".pinximus") if not os.path.exists(thumbpath): os.makedirs(thumbpath) subpath = root[len(selfpath):].strip(r"\/") for name in files: self.register_resource(os.path.join(root, name)) box.flush_all() def on_memorize(self): self.register_resources() def register_resource(self, path): """Assert that the Resource at 'path' is registered.""" box = self.sandbox respath = path[len(self.Path):].strip(r"\/") res = box.unit(Resource, LibraryID=self.ID, Path=respath) if res is None: res = Resource(LibraryID=self.ID, Path=respath) try: img = Image.open(path) except: res.IsImage = False else: res.IsImage = True res.Width, res.Height = img.size box.memorize(res) if res.IsImage: # Force creation of the thumbnail. res.thumbpath() class Resource(Unit): """A Pinximus resource (usually an image).""" LibraryID = UnitProperty(int, index=True) Path = UnitProperty() Width = UnitProperty(int) Height = UnitProperty(int) IsImage = UnitProperty(bool) def name(self): return self.Path.split(r"\/")[-1] def tags(self): return [unit.Value for unit in self.Tag()] def set_tags(self, tagvaluelist): avail, rem = warehouse(self.Tag(), Tag) for tagvalue in tagvaluelist: tag = avail.next() tag.ResourceID = self.ID tag.Value = tagvalue if not tag.sandbox: self.sandbox.memorize(tag) for tag in rem: tag.forget() def fullpath(self): return os.path.join(self.Library().Path, self.Path) def PILImage(self): img = None if self.IsImage: try: img = Image.open(self.fullpath()) except: arena.log("Couldn't load image at %s" % self.fullpath(), LOGMEMORIZE) return img def _get_image(self): """Return the PIL.Image object for self.""" img = self.PILImage() if img is not None: self.Width, self.Height = img.size return img image = property(_get_image, doc="The PIL.Image object for self.") def thumbpath(self): """Return the path for our thumbnail (creating as needed).""" if self.IsImage: head, tail = os.path.split(self.fullpath()) path = os.path.join(head, ".pinximus", tail) if not os.path.exists(path): thumb = self.image.copy() thumb.thumbnail((100, 100), Image.ANTIALIAS) thumb.save(path, thumb.format) return path else: import pinximus path, ext = os.path.splitext(self.Path) icon = pinximus.config['Icons'].get(ext, "default.gif") return os.path.join(localDir, "static", icon) class Tag(Unit): """A tag on a particular Resource.""" ResourceID = UnitProperty(int, index=True) Value = UnitProperty() Resource.one_to_many(u'ID', Tag, u'ResourceID') Library.one_to_many(u'ID', Resource, u'LibraryID') class PinximusSchema(Schema): latest = 1