From d957197f5b5f13ed4d7745c5d1d63c407ea3a394 Mon Sep 17 00:00:00 2001 From: wanze Date: Fri, 14 Jan 2022 22:55:18 +0800 Subject: [PATCH] add a lightweight work mode to autoreload function. --- pelican/__init__.py | 67 ++++++++++++++++++++++++++++++++++++--------- pelican/utils.py | 26 +++++++++++++++++- 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index 99aa2776..95631b37 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -79,8 +79,10 @@ class Pelican: self.settings['PLUGINS'] = [get_plugin_name(p) for p in self.plugins] - def run(self): + def run(self, modified=None): """Run the generators and return""" + modified = modified if modified is not None else [] + limited_mode = self._is_limited_mode(modified=modified) start_time = time.time() context = self.settings.copy() @@ -91,16 +93,26 @@ class Pelican: context['static_content'] = {} context['localsiteurl'] = self.settings['SITEURL'] - generators = [ - cls( - context=context, - settings=self.settings, - path=self.path, - theme=self.theme, - output_path=self.output_path, - ) for cls in self._get_generator_classes() - ] - + if limited_mode: + generators = [ + cls( + context=context, + settings=self.settings, + path=self.path, + theme=self.theme, + output_path=self.output_path, + ) for cls in self._get_generator_classes_limited(modified) + ] + else: + generators = [ + cls( + context=context, + settings=self.settings, + path=self.path, + theme=self.theme, + output_path=self.output_path, + ) for cls in self._get_generator_classes() + ] # Delete the output directory if (1) the appropriate setting is True # and (2) that directory is not the parent of the source directory if (self.delete_outputdir @@ -127,6 +139,11 @@ class Pelican: signals.finalized.send(self) + if limited_mode: + console.print('Done: Processed in {:.2f} seconds.'\ + .format(time.time() - start_time)) + return + articles_generator = next(g for g in generators if isinstance(g, ArticlesGenerator)) pages_generator = next(g for g in generators @@ -210,6 +227,29 @@ class Pelican: return generators + def _is_limited_mode(self, modified=None): + """ + only modified the template pages or static files + """ + modified = modified if modified is not None else [] + limited_set = {'template_pages', '[static]theme_static'} + limited_set.update(['[static]{}'.format(path) + for path in self.settings.get('STATIC_PATHS',[])]) + if modified and set(modified).issubset(limited_set): + return True + else: + return False + def _get_generator_classes_limited(self, modified=None): + modified = modified if modified is not None else [] + discovered_generators = [] + if self.settings["TEMPLATE_PAGES"]: + if 'template_pages' in modified: + discovered_generators.append(TemplatePagesGenerator) + # limited mode maybe not support some plugin + if any(m.startswith('[static]') for m in modified): + discovered_generators.append(StaticGenerator) + return discovered_generators + def _get_writer(self): writers = [w for _, w in signals.get_writer.send(self) if isinstance(w, type)] num_writers = len(writers) @@ -453,9 +493,10 @@ def autoreload(args, excqueue=None): watcher.update_watchers(settings) if any(modified.values()): + modified_keys = [k for k, v in modified.items() if v] console.print('\n-> Modified: {}. re-generating...'.format( - ', '.join(k for k, v in modified.items() if v))) - pelican.run() + ', '.join(modified_keys))) + pelican.run(modified=modified_keys) except KeyboardInterrupt: if excqueue is not None: diff --git a/pelican/utils.py b/pelican/utils.py index 17667078..3eb3fc1d 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -765,6 +765,7 @@ class FileSystemWatcher: self._extensions = None self._content_path = None self._theme_path = None + self._template_pages_settings = None self._ignore_files = None if settings is not None: @@ -774,11 +775,14 @@ class FileSystemWatcher: new_extensions = set(self.reader_class(settings).extensions) new_content_path = settings.get('PATH', '') new_theme_path = settings.get('THEME', '') + new_template_pages_settings = settings.get('TEMPLATE_PAGES', {}) new_ignore_files = set(settings.get('IGNORE_FILES', [])) extensions_changed = new_extensions != self._extensions content_changed = new_content_path != self._content_path theme_changed = new_theme_path != self._theme_path + template_pages_changed = new_template_pages_settings != \ + self._template_pages_settings ignore_changed = new_ignore_files != self._ignore_files # Refresh content watcher if related settings changed @@ -791,10 +795,19 @@ class FileSystemWatcher: # Refresh theme watcher if related settings changed if theme_changed or ignore_changed: self.add_watcher('theme', - new_theme_path, + os.path.join(new_theme_path, 'templates'), [''], new_ignore_files) + # Add Template_Pages to watcher + if template_pages_changed or ignore_changed: + for src in new_template_pages_settings: + full_src = os.path.join(new_content_path, src) + self.add_watcher('template_pages', + full_src, + [''], + new_ignore_files) + # Watch STATIC_PATHS old_static_watchers = set(key for key in self.watchers @@ -811,6 +824,16 @@ class FileSystemWatcher: if key in old_static_watchers: old_static_watchers.remove(key) + for path in settings.get('THEME_STATIC_PATHS', []): + key = '[static]theme_static' + if ignore_changed or (key not in self.watchers): + self.add_watcher(key, + os.path.join(new_theme_path, path), + [''], + new_ignore_files) + if key in old_static_watchers: + old_static_watchers.remove(key) + # cleanup removed static watchers for key in old_static_watchers: del self.watchers[key] @@ -820,6 +843,7 @@ class FileSystemWatcher: self._extensions = new_extensions self._content_path = new_content_path self._theme_path = new_theme_path + self._template_pages_settings = new_template_pages_settings self._ignore_files = new_ignore_files def check(self):