def watch(rootpath): import time import sys from pelican.utils import folder_watcher from .build import write_site, TEMPLATE_DIR, SITE_ROOT_DIR, POST_DIR, SITE_DIR from .server import get_server watchers = { 'posts': folder_watcher(POST_DIR, ['.md']), 'root': folder_watcher(SITE_ROOT_DIR, ['']), 'templates': folder_watcher(TEMPLATE_DIR, ['.html']), } server_thread = get_server(path=SITE_DIR) server_thread.daemon = True server_thread.start() logger.info('AutoReload setup') try: while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if any(modified.values()): print('\nModified: {}. re-generating...'.format(', '.join( k for k, v in modified.items() if v))) write_site({'rootpath': rootpath}) except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception: logger.exception( 'Failed to rgenerate website. Eating, will try again.') finally: time.sleep(.5) # sleep to avoid cpu load except Exception as e: logger.exception('Failed to rgenerate website. Exiting.') sys.exit(getattr(e, 'exitcode', 1))
def watch(rootpath): import time import sys from pelican.utils import folder_watcher from .build import write_site, TEMPLATE_DIR, SITE_ROOT_DIR, POST_DIR, SITE_DIR from .server import get_server watchers = { 'posts': folder_watcher(POST_DIR, ['.md']), 'root': folder_watcher(SITE_ROOT_DIR, ['']), 'templates': folder_watcher(TEMPLATE_DIR, ['.html']), } server_thread = get_server(path=SITE_DIR) server_thread.daemon = True server_thread.start() logger.info('AutoReload setup') try: while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if any(modified.values()): print('\nModified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) write_site({'rootpath': rootpath}) except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception: logger.exception('Failed to rgenerate website. Eating, will try again.') finally: time.sleep(.5) # sleep to avoid cpu load except Exception as e: logger.exception('Failed to rgenerate website. Exiting.') sys.exit(getattr(e, 'exitcode', 1))
def test_watchers(self): # Test if file changes are correctly detected # Make sure to handle not getting any files correctly. dirname = os.path.join(os.path.dirname(__file__), 'content') folder_watcher = utils.folder_watcher(dirname, ['rst']) path = os.path.join(dirname, 'article_with_metadata.rst') file_watcher = utils.file_watcher(path) # first check returns True self.assertEqual(next(folder_watcher), True) self.assertEqual(next(file_watcher), True) # next check without modification returns False self.assertEqual(next(folder_watcher), False) self.assertEqual(next(file_watcher), False) # after modification, returns True t = time.time() os.utime(path, (t, t)) self.assertEqual(next(folder_watcher), True) self.assertEqual(next(file_watcher), True) # file watcher with None or empty path should return None self.assertEqual(next(utils.file_watcher('')), None) self.assertEqual(next(utils.file_watcher(None)), None) empty_path = os.path.join(os.path.dirname(__file__), 'empty') try: os.mkdir(empty_path) os.mkdir(os.path.join(empty_path, "empty_folder")) shutil.copy(__file__, empty_path) # if no files of interest, returns None watcher = utils.folder_watcher(empty_path, ['rst']) self.assertEqual(next(watcher), None) except OSError: self.fail("OSError Exception in test_files_changed test") finally: shutil.rmtree(empty_path, True)
def setup(self): config_file = self.args.settings if config_file is None and os.path.isfile(DEFAULT_CONFIG_NAME): config_file = DEFAULT_CONFIG_NAME self.settings = read_settings(config_file, override=get_config(self.args)) cls = self.settings['PELICAN_CLASS'] if isinstance(cls, six.string_types): module, cls_name = cls.rsplit('.', 1) module = __import__(module) cls = getattr(module, cls_name) self.pelican = cls(self.settings) readers = Readers(self.settings) self.watchers = {'content': folder_watcher(self.pelican.path, readers.extensions, self.pelican.ignore_files), 'theme': folder_watcher(self.pelican.theme, [''], self.pelican.ignore_files), 'settings': file_watcher(self.args.settings)} for static_path in self.settings.get("STATIC_PATHS", []): # use a prefix to avoid overriding standard watchers above self.watchers['[static]%s' % static_path] = folder_watcher( os.path.join(self.pelican.path, static_path), [''], self.pelican.ignore_files) if next(self.watchers['content']) is None: logger.warning('No valid files found in content.') if next(self.watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.')
def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = { 'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings) } try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican, settings = get_instance(args) if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning( 'Empty theme folder. Using `basic` theme.') pelican.run() except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning( 'Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: # localized systems have errors in native language if locale is set # so convert the message to unicode with the correct encoding msg = str(e) if not six.PY3: msg = msg.decode(locale.getpreferredencoding()) logger.critical(msg) if (args.verbosity == logging.DEBUG): raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() init(args.verbosity) pelican = get_instance(args) watchers = {'content': folder_watcher(pelican.path, pelican.markup, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and `settings`' ' for changes. ---') while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican = get_instance(args) if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning( 'Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: # localized systems have errors in native language if locale is set # so convert the message to unicode with the correct encoding msg = str(e) if not six.PY3: msg = msg.decode(locale.getpreferredencoding(False)) logger.critical(msg) if (args.verbosity == logging.DEBUG): raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = { 'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings) } old_static = settings.get("STATIC_PATHS", []) for static_path in old_static: # use a prefix to avoid possible overriding of standard watchers above watchers['[static]%s' % static_path] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') def _ignore_cache(pelican_obj): if pelican_obj.settings['AUTORELOAD_IGNORE_CACHE']: pelican_obj.settings['LOAD_CONTENT_CACHE'] = False while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} original_load_cache = settings['LOAD_CONTENT_CACHE'] if modified['settings']: pelican, settings = get_instance(args) original_load_cache = settings['LOAD_CONTENT_CACHE'] _ignore_cache(pelican) # Adjust static watchers if there are any changes new_static = settings.get("STATIC_PATHS", []) # Added static paths # Add new watchers and set them as modified for static_path in set(new_static).difference( old_static): static_key = '[static]%s' % static_path watchers[static_key] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) modified[static_key] = next(watchers[static_key]) # Removed static paths # Remove watchers and modified values for static_path in set(old_static).difference( new_static): static_key = '[static]%s' % static_path watchers.pop(static_key) modified.pop(static_key) # Replace old_static with the new one old_static = new_static if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` ' 'theme.') pelican.run() # restore original caching policy pelican.settings[ 'LOAD_CONTENT_CACHE'] = original_load_cache except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning('Caught exception "%s". Reloading.', e) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: logger.critical('%s', e) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = {'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} for static_path in settings.get("STATIC_PATHS", []): watchers[static_path] = folder_watcher(static_path, [''], pelican.ignore_files) try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') def _ignore_cache(pelican_obj): if pelican_obj.settings['AUTORELOAD_IGNORE_CACHE']: pelican_obj.settings['LOAD_CONTENT_CACHE'] = False while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} original_load_cache = settings['LOAD_CONTENT_CACHE'] if modified['settings']: pelican, settings = get_instance(args) original_load_cache = settings['LOAD_CONTENT_CACHE'] _ignore_cache(pelican) if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` ' 'theme.') pelican.run() # restore original caching policy pelican.settings['LOAD_CONTENT_CACHE'] = original_load_cache except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning( 'Caught exception "%s". Reloading.', e) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: logger.critical('%s', e) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = {'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} old_static = settings.get("STATIC_PATHS", []) for static_path in old_static: # use a prefix to avoid possible overriding of standard watchers above watchers['[static]%s' % static_path] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican, settings = get_instance(args) # Adjust static watchers if there are any changes new_static = settings.get("STATIC_PATHS", []) # Added static paths # Add new watchers and set them as modified new_watchers = set(new_static).difference(old_static) for static_path in new_watchers: static_key = '[static]%s' % static_path watchers[static_key] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) modified[static_key] = next(watchers[static_key]) # Removed static paths # Remove watchers and modified values old_watchers = set(old_static).difference(new_static) for static_path in old_watchers: static_key = '[static]%s' % static_path watchers.pop(static_key) modified.pop(static_key) # Replace old_static with the new one old_static = new_static if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` ' 'theme.') pelican.run() except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): raise logger.warning( 'Caught exception "%s". Reloading.', e) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: logger.critical('%s', e) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() logs_dedup_min_level = getattr(logging, args.logs_dedup_min_level) init_logging(args.verbosity, args.fatal, logs_dedup_min_level=logs_dedup_min_level) logger.debug('Pelican version: %s', __version__) logger.debug('Python version: %s', sys.version.split()[0]) try: pelican, settings = get_instance(args) readers = Readers(settings) reader_descs = sorted(set(['%s (%s)' % (type(r).__name__, ', '.join(r.file_extensions)) for r in readers.readers.values() if r.enabled])) watchers = {'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} old_static = settings.get("STATIC_PATHS", []) for static_path in old_static: # use a prefix to avoid possible overriding of standard watchers # above watchers['[static]%s' % static_path] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) if args.autoreload and args.listen: excqueue = multiprocessing.Queue() p1 = multiprocessing.Process( target=autoreload, args=(watchers, args, old_static, reader_descs, excqueue)) p2 = multiprocessing.Process( target=listen, args=(settings.get('BIND'), settings.get('PORT'), settings.get("OUTPUT_PATH"), excqueue)) p1.start() p2.start() exc = excqueue.get() p1.terminate() p2.terminate() logger.critical(exc) elif args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') autoreload(watchers, args, old_static, reader_descs) elif args.listen: listen(settings.get('BIND'), settings.get('PORT'), settings.get("OUTPUT_PATH")) else: if next(watchers['content']) is None: logger.warning( 'No valid files found in content for ' + 'the active readers:\n' + '\n'.join(reader_descs)) if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: logger.critical('%s', e) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1))
def autoreload(watchers, args, old_static, reader_descs, excqueue=None): while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican, settings = get_instance(args) # Adjust static watchers if there are any changes new_static = settings.get("STATIC_PATHS", []) # Added static paths # Add new watchers and set them as modified new_watchers = set(new_static).difference(old_static) for static_path in new_watchers: static_key = '[static]%s' % static_path watchers[static_key] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) modified[static_key] = next(watchers[static_key]) # Removed static paths # Remove watchers and modified values old_watchers = set(old_static).difference(new_static) for static_path in old_watchers: static_key = '[static]%s' % static_path watchers.pop(static_key) modified.pop(static_key) # Replace old_static with the new one old_static = new_static if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning( 'No valid files found in content for ' + 'the active readers:\n' + '\n'.join(reader_descs)) if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` ' 'theme.') pelican.run() except KeyboardInterrupt as e: logger.warning("Keyboard interrupt, quitting.") if excqueue is not None: excqueue.put(traceback.format_exception_only(type(e), e)[-1]) return except Exception as e: if (args.verbosity == logging.DEBUG): if excqueue is not None: excqueue.put( traceback.format_exception_only(type(e), e)[-1]) else: raise logger.warning( 'Caught exception "%s". Reloading.', e) finally: time.sleep(.5) # sleep to avoid cpu load
def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = {'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} for static_path in settings.get("STATIC_PATHS", []): watchers[static_path] = folder_watcher(static_path, [''], pelican.ignore_files) try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') first_run = True # load cache on first run while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} original_load_cache = settings['LOAD_CONTENT_CACHE'] if modified['settings']: pelican, settings = get_instance(args) if not first_run: original_load_cache = settings['LOAD_CONTENT_CACHE'] # invalidate cache pelican.settings['LOAD_CONTENT_CACHE'] = False if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` ' 'theme.') elif modified['theme']: # theme modified, needs full rebuild -> no cache if not first_run: # but not on first run pelican.settings['LOAD_CONTENT_CACHE'] = False pelican.run() first_run = False # restore original caching policy pelican.settings['LOAD_CONTENT_CACHE'] = original_load_cache except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning( 'Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: # localized systems have errors in native language if locale is set # so convert the message to unicode with the correct encoding msg = str(e) if not six.PY3: msg = msg.decode(locale.getpreferredencoding()) logger.critical(msg) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() logs_dedup_min_level = getattr(logging, args.logs_dedup_min_level) init_logging(args.verbosity, args.fatal, logs_dedup_min_level=logs_dedup_min_level) logger.debug('Pelican version: %s', __version__) logger.debug('Python version: %s', sys.version.split()[0]) try: pelican, settings = get_instance(args) readers = Readers(settings) reader_descs = sorted(set(['%s (%s)' % (type(r).__name__, ', '.join(r.file_extensions)) for r in readers.readers.values() if r.enabled])) watchers = {'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} old_static = settings.get("STATIC_PATHS", []) for static_path in old_static: # use a prefix to avoid possible overriding of standard watchers # above watchers['[static]%s' % static_path] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican, settings = get_instance(args) # Adjust static watchers if there are any changes new_static = settings.get("STATIC_PATHS", []) # Added static paths # Add new watchers and set them as modified new_watchers = set(new_static).difference(old_static) for static_path in new_watchers: static_key = '[static]%s' % static_path watchers[static_key] = folder_watcher( os.path.join(pelican.path, static_path), [''], pelican.ignore_files) modified[static_key] = next(watchers[static_key]) # Removed static paths # Remove watchers and modified values old_watchers = set(old_static).difference(new_static) for static_path in old_watchers: static_key = '[static]%s' % static_path watchers.pop(static_key) modified.pop(static_key) # Replace old_static with the new one old_static = new_static if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning( 'No valid files found in content for ' + 'the active readers:\n' + '\n'.join(reader_descs)) if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` ' 'theme.') pelican.run() except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): raise logger.warning( 'Caught exception "%s". Reloading.', e) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning( 'No valid files found in content for ' + 'the active readers:\n' + '\n'.join(reader_descs)) if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: logger.critical('%s', e) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() init(args.verbosity) pelican = get_instance(args) watchers = { 'content': folder_watcher(pelican.path, pelican.markup, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings) } # Watch for changes of the TEMPLATE_PAGES. Don't include these # inside `watchers`, as they could appear as a subdirectory of the # pelican.path. Since later the filenames are used in a # dictionary, the order in which the file is checked would be # unpredictable. template_watchers = {} if pelican.settings['TEMPLATE_PAGES']: dirs, extensions = directories_from_template_pages(pelican) for d in dirs: template_watchers[d] = folder_watcher(d, extensions, pelican.ignore_files) try: if args.autoreload: print( ' --- AutoReload Mode: Monitoring `content`, `theme` and `settings`' ' for changes. ---') while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican = get_instance(args) should_regenerate = False if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning( 'Empty theme folder. Using `basic` theme.') should_regenerate |= True # Check the template watchers modified = { k: next(v) for k, v in template_watchers.items() } if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) should_regenerate |= True if should_regenerate: pelican.run() except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning( 'Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: # localized systems have errors in native language if locale is set # so convert the message to unicode with the correct encoding msg = str(e) if not six.PY3: msg = msg.decode(locale.getpreferredencoding(False)) logger.critical(msg) if (args.verbosity == logging.DEBUG): raise else: sys.exit(getattr(e, 'exitcode', 1))
def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = { "content": folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), "theme": folder_watcher(pelican.theme, [""], pelican.ignore_files), "settings": file_watcher(args.settings), } for static_path in settings.get("STATIC_PATHS", []): watchers[static_path] = folder_watcher(static_path, [""], pelican.ignore_files) try: if args.autoreload: print(" --- AutoReload Mode: Monitoring `content`, `theme` and" " `settings` for changes. ---") def _ignore_cache(pelican_obj): if pelican_obj.settings["AUTORELOAD_IGNORE_CACHE"]: pelican_obj.settings["LOAD_CONTENT_CACHE"] = False while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} original_load_cache = settings["LOAD_CONTENT_CACHE"] if modified["settings"]: pelican, settings = get_instance(args) original_load_cache = settings["LOAD_CONTENT_CACHE"] print(pelican.settings["AUTORELOAD_IGNORE_CACHE"]) _ignore_cache(pelican) if any(modified.values()): print( "\n-> Modified: {}. re-generating...".format(", ".join(k for k, v in modified.items() if v)) ) if modified["content"] is None: logger.warning("No valid files found in content.") if modified["theme"] is None: logger.warning("Empty theme folder. Using `basic` " "theme.") pelican.run() # restore original caching policy pelican.settings["LOAD_CONTENT_CACHE"] = original_load_cache except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if args.verbosity == logging.DEBUG: logger.critical(e.args) raise logger.warning('Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(0.5) # sleep to avoid cpu load else: if next(watchers["content"]) is None: logger.warning("No valid files found in content.") if next(watchers["theme"]) is None: logger.warning("Empty theme folder. Using `basic` theme.") pelican.run() except Exception as e: # localized systems have errors in native language if locale is set # so convert the message to unicode with the correct encoding msg = str(e) if not six.PY3: msg = msg.decode(locale.getpreferredencoding()) logger.critical(msg) if args.verbosity == logging.DEBUG: raise else: sys.exit(getattr(e, "exitcode", 1))