terom@64: """ terom@64: Per-directory gallery state terom@64: """ terom@12: terom@64: import filesystem, image, html terom@12: terom@76: from utils import lazy_load, lazy_load_iter terom@64: terom@76: import math terom@76: terom@76: class Folder (filesystem.Directory) : terom@12: """ terom@64: A Folder is a filesystem Directory that contains any number of other Folders and Images. terom@12: """ terom@12: terom@118: def iter_config_files (self) : terom@118: """ terom@118: Iterate over the possible config files for this dir terom@118: """ terom@118: terom@118: yield self.subfile('degal.cfg') terom@118: yield self.subdir('.degal').subfile('cfg') terom@118: terom@76: def __init__ (self, *args, **kwargs) : terom@76: super(Folder, self).__init__(*args, **kwargs) terom@12: terom@118: # find config terom@118: for file in self.iter_config_files() : terom@118: if file.exists() : terom@118: # yay! More configuration! terom@118: self.config = self.config.load(file.path) terom@118: terom@118: break terom@118: terom@118: # load some info from title? terom@118: if self.config and self.config.title : terom@118: self.title = self.config.title terom@118: terom@118: # disable it so it won't be used by children terom@118: # XXX: figure out a better way of doing this terom@118: self.config.title = None terom@118: terom@118: @lazy_load terom@118: def title (self) : terom@118: """ terom@118: Find the title for this dir terom@118: """ terom@118: terom@118: # default terom@118: return self.name.title() terom@118: terom@118: @lazy_load terom@118: def description (self) : terom@118: """ terom@118: Find the descriptive text for this dir terom@118: """ terom@118: terom@118: # default terom@118: return None terom@118: terom@64: @lazy_load terom@64: def preview_dir (self) : terom@64: """ terom@64: Load and return the Directory for previews terom@64: """ terom@64: terom@64: return self.subdir(self.config.preview_dir, create=True) terom@12: terom@64: @lazy_load terom@64: def thumb_dir (self) : terom@64: """ terom@64: Load and return the Directory for thumbs terom@64: """ terom@64: terom@64: return self.subdir(self.config.thumb_dir, create=True) terom@64: terom@64: @lazy_load_iter terom@64: def subnodes (self) : terom@64: """ terom@64: Load and return an ordered list of child-Nodes terom@64: """ terom@64: terom@76: return super(Folder, self).subnodes(skip_dotfiles=True, sort=True) terom@64: terom@64: @lazy_load_iter terom@64: def subfolders (self) : terom@64: """ terom@64: Load and return an ordered list of sub-Folders terom@64: """ terom@90: terom@90: # filter out valid subfolders terom@90: for node in self.subnodes : terom@90: # skip non-dirs terom@90: if not node.is_dir() : terom@90: continue terom@64: terom@90: # skip the previews/thumbs dirs terom@90: if node.name in (self.config.preview_dir, self.config.thumb_dir) : terom@90: continue terom@90: terom@90: # ok terom@90: yield Folder(node) terom@64: terom@64: @lazy_load_iter terom@64: def images (self) : terom@64: """ terom@64: Load and return an ordered/linked list of sub-Images terom@64: """ terom@64: terom@64: prev = None terom@64: terom@64: for node in self.subnodes : terom@64: # skip non-relevant ones terom@76: if not node.is_file() or not self.config.is_image(filesystem.File(node)) : terom@64: continue terom@64: terom@64: # create new terom@77: img = image.Image(node) terom@64: terom@64: # link up terom@64: if prev : terom@76: img.prev = prev terom@64: prev.next = img terom@64: terom@64: # yield the linked-up prev terom@64: yield prev terom@64: terom@64: # continue terom@64: prev = img terom@64: terom@64: # and the last one terom@64: if prev : terom@64: yield prev terom@64: terom@64: @property terom@64: def page_count (self) : terom@64: """ terom@64: Returns the number of pages needed to show this folder's images terom@64: """ terom@64: terom@76: return int(math.ceil(len(self.images) / float(self.config.images_per_page))) terom@64: terom@64: def images_for_page (self, page) : terom@64: """ terom@64: Returns the list of Images to be displayed for the given page, if any terom@64: """ terom@64: terom@64: # offset to first image terom@64: offset = page * self.config.images_per_page terom@64: terom@64: # slice terom@64: return self.images[offset : offset + self.config.images_per_page] terom@119: terom@119: @property terom@119: def html (self) : terom@119: """ terom@119: Path to default page terom@119: """ terom@64: terom@119: return self.html_page() terom@119: terom@119: def html_page (self, page=0) : terom@64: """ terom@64: Returns the File representing the .html for the given page terom@64: """ terom@64: terom@64: if page : terom@64: return self.subfile("index_%d.html" % page) terom@64: terom@64: else : terom@64: return self.subfile("index.html") terom@64: terom@85: def index_images (self, for_update=True) : terom@64: """ terom@85: Return a series of Images inside of this folder. terom@70: terom@85: If `for_update` is given, only images that are stale will be returned. terom@64: """ terom@64: terom@85: for image in self.images : terom@85: if for_update and not image.stale() : terom@85: # skip terom@85: continue terom@64: terom@85: yield image terom@85: