def __init__(self, source_dir, config=None): self.source_dir = os.path.abspath(source_dir) self.config = LazygalConfig() logging.info(_("Trying loading user config %s") % USER_CONFIG_PATH) self.config.read(USER_CONFIG_PATH) sourcedir_configfile = os.path.join(source_dir, SOURCEDIR_CONFIGFILE) if os.path.isfile(sourcedir_configfile): logging.info(_("Loading root config %s") % sourcedir_configfile) try: self.config.read(sourcedir_configfile) except LazygalConfigDeprecated: logging.error(_("'%s' uses a deprecated syntax: please refer to lazygal.conf(5) manual page.") % sourcedir_configfile) sys.exit(1) if config is not None: # Supplied config self.config.load(config) if self.config.getboolean('runtime', 'quiet'): logging.getLogger().setLevel(logging.ERROR) if self.config.getboolean('runtime', 'debug'): logging.getLogger().setLevel(logging.DEBUG) GExiv2.log_set_level(GExiv2.LogLevel.INFO) self.clean_dest = self.config.getboolean('global', 'clean-destination') self.force_gen_pages = self.config.getboolean('global', 'force-gen-pages') self.set_theme(self.config.get('global', 'theme')) self.dir_flattening_depth = self.config.getint('global', 'dir-flattening-depth') self.__statistics = None
class Album(object): def __init__(self, source_dir, config=None): self.source_dir = os.path.abspath(source_dir) self.config = LazygalConfig() logging.info(_("Trying loading user config %s") % USER_CONFIG_PATH) self.config.read(USER_CONFIG_PATH) sourcedir_configfile = os.path.join(source_dir, SOURCEDIR_CONFIGFILE) if os.path.isfile(sourcedir_configfile): logging.info(_("Loading root config %s") % sourcedir_configfile) try: self.config.read(sourcedir_configfile) except LazygalConfigDeprecated: logging.error(_("'%s' uses a deprecated syntax: please refer to lazygal.conf(5) manual page.") % sourcedir_configfile) sys.exit(1) if config is not None: # Supplied config self.config.load(config) if self.config.getboolean('runtime', 'quiet'): logging.getLogger().setLevel(logging.ERROR) if self.config.getboolean('runtime', 'debug'): logging.getLogger().setLevel(logging.DEBUG) GExiv2.log_set_level(GExiv2.LogLevel.INFO) self.clean_dest = self.config.getboolean('global', 'clean-destination') self.force_gen_pages = self.config.getboolean('global', 'force-gen-pages') self.set_theme(self.config.get('global', 'theme')) self.dir_flattening_depth = self.config.getint('global', 'dir-flattening-depth') self.__statistics = None def set_theme(self, theme=tpl.DEFAULT_THEME): self.theme = tpl.Theme(os.path.join(DATAPATH, 'themes'), theme) def _str_humanize(self, text): dash_replaced = text.replace('_', ' ') return dash_replaced def is_in_sourcetree(self, path): return pathutils.is_subdir_of(self.source_dir, path) def cleanup(self, file_path): text = '' if self.clean_dest and not os.path.isdir(file_path): os.unlink(file_path) text = '' else: text = _('you should ') logging.info(_(' %sRM %s') % (text, file_path)) def generate_default_metadata(self): """ Generate default metadata files if no exists. """ logging.debug(_("Generating metadata in %s") % self.source_dir) for root, dirnames, filenames in pathutils.walk(self.source_dir): filenames.sort() # This is required for the ignored files # checks to be reliable. source_dir = sourcetree.Directory(root, [], filenames, self) logging.info(_("[Entering %%ALBUMROOT%%/%s]") % source_dir.strip_root()) logging.debug("(%s)" % source_dir.path) metadata.DefaultMetadata(source_dir, self).make() def stats(self): if self.__statistics is None: self.__statistics = { 'total' : 0, 'bydir' : {} } for root, dirnames, filenames in pathutils.walk(self.source_dir): dir_medias = len([f for f in filenames\ if sourcetree.MediaHandler.is_known_media(f)]) self.__statistics['total'] = self.__statistics['total']\ + dir_medias self.__statistics['bydir'][root] = dir_medias return self.__statistics def generate(self, dest_dir=None, progress=None): if dest_dir is None: dest_dir = self.config.getstr('global', 'output-directory') else: dest_dir = dest_dir.decode(sys.getfilesystemencoding()) sane_dest_dir = os.path.abspath(os.path.expanduser(dest_dir)) pub_url = self.config.getstr('global', 'puburl') check_all_dirs = self.config.getboolean('runtime', 'check-all-dirs') if self.is_in_sourcetree(sane_dest_dir): raise ValueError(_("Fatal error, web gallery directory is within source tree.")) logging.debug(_("Generating to %s") % sane_dest_dir) if pub_url: feed = genpage.WebalbumFeed(self, sane_dest_dir, pub_url) else: feed = None dir_heap = {} for root, dirnames, filenames in pathutils.walk(self.source_dir): if root in dir_heap: subdirs, subgals = dir_heap[root] del dir_heap[root] # No need to keep it there else: subdirs = [] subgals = [] checked_dir = sourcetree.File(root, self) if checked_dir.should_be_skipped(): logging.debug(_("(%s) has been skipped") % checked_dir.path) continue if checked_dir.path == os.path.join(sane_dest_dir, DEST_SHARED_DIRECTORY_NAME): logging.error(_("(%s) has been skipped because its name collides with the shared material directory name") % checked_dir.path) continue logging.info(_("[Entering %%ALBUMROOT%%/%s]") % checked_dir.strip_root()) logging.debug("(%s)" % checked_dir.path) source_dir = sourcetree.Directory(root, subdirs, filenames, self) destgal = WebalbumDir(source_dir, subgals, self, sane_dest_dir, progress) if source_dir.is_album_root(): # Use root config tpl vars for shared files tpl_vars = destgal.tpl_vars if source_dir.get_all_medias_count() < 1: logging.debug(_("(%s) and childs have no known medias, skipped") % source_dir.path) continue if not source_dir.is_album_root(): container_dirname = os.path.dirname(root) if container_dirname not in dir_heap: dir_heap[container_dirname] = ([], []) container_subdirs, container_subgals = dir_heap[container_dirname] container_subdirs.append(source_dir) container_subgals.append(destgal) if feed and source_dir.is_album_root(): feed.set_title(source_dir.human_name) md = destgal.source_dir.metadata.get() if 'album_description' in md.keys(): feed.set_description(md['album_description']) destgal.register_output(feed.path) if feed: feed.push_dir(destgal) destgal.register_feed(feed) if check_all_dirs: destgal.make() elif destgal.needs_build(): destgal.make(force=True) # avoid another needs_build() call in make() else: if progress is not None: progress.media_done(len(destgal.medias)) logging.debug(_(" SKIPPED because of mtime, touch source or use --check-all-dirs to override.")) # Force some memory cleanups, this is usefull for big albums. del destgal gc.collect() if progress is not None: progress.dir_done() logging.info(_("[Leaving %%ALBUMROOT%%/%s]") % source_dir.strip_root()) if feed: feed.make() # Force to check for unexpected files SharedFiles(self, sane_dest_dir, tpl_vars).make(True)