Esempio n. 1
0
def upload_sftp(input_path, output_path, rm_remote=False):
    ssh_config = StatikConfig(input_path).remote['sftp']

    t = paramiko.Transport((ssh_config['server'], 22))

    t.connect(username=ssh_config['username'], password=ssh_config['password'])
    logger.info('Connecting to %s...' % ssh_config['server'])

    sftp = paramiko.SFTPClient.from_transport(t)
    logger.info('Connected to %s...' % ssh_config['server'])

    if rm_remote:
        path = ssh_config['dir-base'] + ssh_config['dir-root']
        rm_r(sftp, path)

    for root, dirs, files in os.walk(output_path):
        for f in files:
            localpath = root + '/' + f
            dirname = root.replace(output_path, ssh_config['dir-root'], 1)
            remotepath = dirname + '/' + f
            logger.info('Publishing: %s' % (ssh_config['dir-base'] + remotepath))
            try:
                mkdir_p(sftp, ssh_config['dir-base'] + dirname)
            except:
                pass
            sftp.put(localpath, ssh_config['dir-base'] + remotepath)

    sftp.close()
    logger.info('Connection closed.')
Esempio n. 2
0
def watch(project_path, output_path, host='0.0.0.0', port=8000, min_reload_time=2.0):
    """Watches the given project path for filesystem changes, and automatically rebuilds the project when
    changes are detected. Also serves an HTTP server on the given host/port.

    Args:
        project_path: The path to the Statik project to be watched.
        output_path: The path into which to write the output files.
        host: The host IP/hostname to which to bind when serving output files.
        port: The port to which to bind when serving output files.
        min_reload_time: The minimum time (in seconds) between reloads when files change.
    """
    _project_path, config_file = get_project_config_file(project_path, StatikProject.CONFIG_FILE)
    watcher = StatikWatcher(config_file, output_path, min_reload_time=min_reload_time)
    # generate once-off before starting the server
    watcher.generate()

    config = StatikConfig(config_file)
    watch_folders = [
        StatikProject.MODELS_DIR,
        StatikProject.DATA_DIR,
        StatikProject.TEMPLATES_DIR,
        StatikProject.VIEWS_DIR,
        StatikProject.TEMPLATETAGS_DIR,
        config.assets_src_path,
    ]
    watch_folders = [f if os.path.isabs(f) else os.path.join(_project_path, f) for f in watch_folders]
    server = Server()
    for f in watch_folders:
        server.watch(f, func=watcher.generator_factory(f))

    logger.info("Serving content from %s at http://%s:%d" % (output_path, host, port))
    server.serve(root=output_path, host=host, port=port)
    logger.info("Stopped server")
Esempio n. 3
0
 def test_empty_config(self):
     config = StatikConfig(from_string="")
     self.assertEqual("Untitled project", config.project_name)
     self.assertEqual("/", config.base_path)
     self.assertEqual("assets", config.assets_src_path)
     self.assertEqual("assets", config.assets_dest_path)
     self.assertIsNone(config.theme)
Esempio n. 4
0
 def test_string_config(self):
     config = StatikConfig(from_string=TEST_CONFIG)
     self.assertEqual("Test Project", config.project_name)
     self.assertEqual("/blog/", config.base_path)
     self.assertEqual("src_static", config.assets_src_path)
     self.assertEqual("dest_static", config.assets_dest_path)
     self.assertEqual('The global value', config.context_static['some_project_var'])
     self.assertEqual('session.query(User).filter(User.active == True).all()', config.context_dynamic['users'])
Esempio n. 5
0
 def test_file_config(self):
     test_path = os.path.dirname(os.path.realpath(__file__))
     config = StatikConfig(
         os.path.join(test_path, os.pardir, 'integration', 'data-simple',
                      'config.yml'))
     self.assertEqual("Unit Test Project", config.project_name)
     self.assertEqual("/", config.base_path)
     self.assertIsNone(config.theme)
Esempio n. 6
0
 def test_markdown_extension_config(self):
     config = StatikConfig(from_string=TEST_MARKDOWN_EXTENSIONS_CONFIG)
     self.assertEqual("Test Project", config.project_name)
     self.assertEqual("/", config.base_path)
     # check for our custom markdown extension config
     expected_extensions = copy(MarkdownConfig.DEFAULT_MARKDOWN_EXTENSIONS)
     expected_extensions.append("markdown.extensions.codehilite")
     self.assertEqual(expected_extensions, config.markdown_config.extensions)
     self.assertEqual({"markdown.extensions.toc": {"permalink": True}}, config.markdown_config.extension_config)
Esempio n. 7
0
    def test_string_config(self):
        config = StatikConfig(from_string=TEST_CONFIG)
        self.assertEqual("Test Project", config.project_name)
        self.assertEqual("/blog/", config.base_path)
        self.assertEqual("src_static", config.assets_src_path)
        self.assertEqual("dest_static", config.assets_dest_path)
        self.assertEqual('The global value', config.context_static['some_project_var'])
        self.assertEqual('session.query(User).filter(User.active == True).all()', config.context_dynamic['users'])
        self.assertIsNone(config.theme)

        self.assertFalse(config.markdown_config.enable_permalinks)
        self.assertIsNone(config.markdown_config.permalink_class)
        self.assertIsNone(config.markdown_config.permalink_title)
Esempio n. 8
0
    def test_markdown_config(self):
        config = StatikConfig(from_string=TEST_MARKDOWN_CONFIG)
        self.assertEqual("Test Project", config.project_name)
        self.assertEqual("/blog/", config.base_path)
        self.assertEqual("src_static", config.assets_src_path)
        self.assertEqual("dest_static", config.assets_dest_path)
        self.assertEqual('The global value', config.context_static['some_project_var'])
        self.assertEqual('session.query(User).filter(User.active == True).all()', config.context_dynamic['users'])
        self.assertIsNone(config.theme)

        # now check the markdown config
        self.assertTrue(config.markdown_config.enable_permalinks)
        self.assertEqual("permalink", config.markdown_config.permalink_class)
        self.assertEqual("Permalink to this heading", config.markdown_config.permalink_title)
        # check the default markdown extensions
        self.assertEqual(MarkdownConfig.DEFAULT_MARKDOWN_EXTENSIONS, config.markdown_config.extensions)
Esempio n. 9
0
 def test_themed_config(self):
     config = StatikConfig(from_string=TEST_THEMED_CONFIG)
     self.assertEqual("Themed Test Project", config.project_name)
     self.assertEqual("mytheme", config.theme)
Esempio n. 10
0
 def test_invalid_config(self):
     with self.assertRaises(MissingParameterError):
         StatikConfig()
Esempio n. 11
0
    def generate(self, output_path=None, in_memory=False):
        """Executes the Statik project generator.

        Args:
            output_path: The path to which to write output files.
            in_memory: Whether or not to generate the results in memory. If True, this will generate the output
                result as a dictionary. If False, this will write the output to files in the output_path.

        Returns:
            If in_memory is True, this returns a dictionary containing the actual generated static content. If
            in_memory is False, this returns an integer indicating the number of files generated in the
            output path.
        """
        result = dict() if in_memory else 0
        try:
            if output_path is None and not in_memory:
                raise ValueError(
                    "If project is not to be generated in-memory, an output path must be specified"
                )

            self.config = self.config or StatikConfig(self.config_file_path)

            if self.config.encoding is not None:
                logger.debug("Using encoding: %s" % self.config.encoding)
            else:
                logger.debug("Using encoding: %s" % self.config.encoding)

            self.models = self.load_models()
            self.template_engine = StatikTemplateEngine(self)

            self.views = self.load_views()
            if len(self.views) == 0:
                raise NoViewsError("Project has no views configured")

            self.db = self.load_db_data(self.models)
            self.project_context = self.load_project_context()

            in_memory_result = self.process_views()

            if in_memory:
                result = in_memory_result
            else:
                # dump the in-memory output to files
                file_count = self.dump_in_memory_result(
                    in_memory_result, output_path)
                logger.info('Wrote %d output file(s) to folder: %s' %
                            (file_count, output_path))
                # copy any assets across, recursively
                self.copy_assets(output_path)
                result = file_count

        finally:
            try:
                # make sure to destroy the database engine (to provide for the possibility of database engine
                # reloads when watching for changes)
                if self.db is not None:
                    self.db.shutdown()

            except Exception as e:
                logger.exception("Unable to clean up properly: %s" % e)

        return result
Esempio n. 12
0
    def generate(self, output_path=None, in_memory=False):
        """Executes the Statik project generator.

        Args:
            output_path: The path to which to write output files.
            in_memory: Whether or not to generate the results in memory. If True, this will
                generate the output result as a dictionary. If False, this will write the output
                to files in the output_path.

        Returns:
            If in_memory is True, this returns a dictionary containing the actual generated static
            content. If in_memory is False, this returns an integer indicating the number of files
            generated in the output path.
        """
        result = dict() if in_memory else 0
        logger.info("Generating Statik build...")
        try:
            if output_path is None and not in_memory:
                raise InternalError(
                    "If project is not to be generated in-memory, an output path must be specified"
                )

            self.error_context.update(filename=self.config_file_path)
            self.config = self.config or StatikConfig(self.config_file_path)

            if self.config.encoding is not None:
                logger.debug("Using encoding: %s", self.config.encoding)
            else:
                logger.debug("Using encoding: %s", self.config.encoding)
            self.error_context.clear()

            self.models = self.load_models()
            self.template_engine = StatikTemplateEngine(self)

            self.views = self.load_views()
            if not self.views:
                raise NoViewsError()

            self.db = self.load_db_data(self.models)
            self.project_context = self.load_project_context()

            in_memory_result = self.process_views()

            if in_memory:
                result = in_memory_result
            else:
                # dump the in-memory output to files
                file_count = self.dump_in_memory_result(in_memory_result, output_path)
                logger.info('Wrote %d output file(s) to folder: %s', file_count, output_path)
                # copy any assets across, recursively
                self.copy_assets(output_path)
                result = file_count
            
            logger.info("Success!")

        except StatikError as exc:
            logger.debug(traceback.format_exc())
            logger.error(exc.render())
            # re-raise the error to stop execution
            raise exc
        
        except Exception as exc:
            logger.debug(traceback.format_exc())
            _exc = StatikError(
                message="Failed to build project. Run Statik in verbose mode (-v) to see " +
                    "additional traceback information about this error.",
                orig_exc=exc,
                context=self.error_context
            )
            logger.error(_exc.render())
            raise _exc

        finally:
            try:
                # make sure to destroy the database engine (to provide for the possibility of
                # database engine reloads when watching for changes)
                if self.db is not None:
                    self.db.shutdown()

            except Exception as e:
                logger.exception("Unable to clean up properly: %s", e)

        return result
Esempio n. 13
0
 def test_invalid_config(self):
     with self.assertRaises(ValueError):
         StatikConfig()