Example #1
0
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))
Example #2
0
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))
Example #3
0
    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)
Example #4
0
    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)
Example #5
0
    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.')
Example #6
0
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))
Example #7
0
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))
Example #8
0
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))
Example #9
0
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))
Example #10
0
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))
Example #11
0
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))
Example #12
0
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
Example #13
0
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))
Example #14
0
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))
Example #15
0
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))
Example #16
0
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))