This commit is contained in:
		
							
								
								
									
										1
									
								
								__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
from .search import *  # NOQA
 | 
			
		||||
							
								
								
									
										123
									
								
								search.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								search.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
			
		||||
"""
 | 
			
		||||
Search
 | 
			
		||||
======
 | 
			
		||||
 | 
			
		||||
A Pelican plugin to generate an index for static site searches.
 | 
			
		||||
 | 
			
		||||
Copyright (c) Justin Mayer
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from codecs import open
 | 
			
		||||
from inspect import cleandoc
 | 
			
		||||
from json import dumps
 | 
			
		||||
import logging
 | 
			
		||||
import os.path
 | 
			
		||||
from shutil import which
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
from jinja2.filters import do_striptags as striptags
 | 
			
		||||
 | 
			
		||||
from pelican import signals
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SearchSettingsGenerator:
 | 
			
		||||
    def __init__(self, context, settings, path, theme, output_path, *null):
 | 
			
		||||
        self.output_path = output_path
 | 
			
		||||
        self.context = context
 | 
			
		||||
        self.content = settings.get("PATH")
 | 
			
		||||
        self.tpages = settings.get("TEMPLATE_PAGES")
 | 
			
		||||
        self.search_mode = settings.get("SEARCH_MODE", "output")
 | 
			
		||||
        self.html_selector = settings.get("SEARCH_HTML_SELECTOR", "main")
 | 
			
		||||
 | 
			
		||||
    def build_search_index(self, search_settings_path):
 | 
			
		||||
        if not which("stork"):
 | 
			
		||||
            raise Exception("Stork must be installed and available on $PATH.")
 | 
			
		||||
        try:
 | 
			
		||||
            output = subprocess.run(
 | 
			
		||||
                [
 | 
			
		||||
                    "stork",
 | 
			
		||||
                    "build",
 | 
			
		||||
                    "--input",
 | 
			
		||||
                    search_settings_path,
 | 
			
		||||
                    "--output",
 | 
			
		||||
                    f"{self.output_path}/search-index.st",
 | 
			
		||||
                ],
 | 
			
		||||
                capture_output=True,
 | 
			
		||||
                encoding="utf-8",
 | 
			
		||||
                check=True,
 | 
			
		||||
            )
 | 
			
		||||
        except subprocess.CalledProcessError as e:
 | 
			
		||||
            raise Exception("".join(["Search plugin reported ", e.stdout, e.stderr]))
 | 
			
		||||
 | 
			
		||||
        return output.stdout
 | 
			
		||||
 | 
			
		||||
    def generate_output(self, writer):
 | 
			
		||||
        search_settings_path = os.path.join(self.output_path, "search.toml")
 | 
			
		||||
 | 
			
		||||
        pages = self.context["pages"] + self.context["articles"]
 | 
			
		||||
 | 
			
		||||
        for article in self.context["articles"]:
 | 
			
		||||
            pages += article.translations
 | 
			
		||||
 | 
			
		||||
        input_files = ""
 | 
			
		||||
 | 
			
		||||
        # Generate list of articles and pages to index
 | 
			
		||||
        for page in pages:
 | 
			
		||||
            if self.search_mode == "output":
 | 
			
		||||
                page_to_index = page.save_as
 | 
			
		||||
            if self.search_mode == "source":
 | 
			
		||||
                page_to_index = page.relative_source_path
 | 
			
		||||
            input_file = f"""
 | 
			
		||||
                [[input.files]]
 | 
			
		||||
                path = "{page_to_index}"
 | 
			
		||||
                url = "/{page.url}"
 | 
			
		||||
                title = {dumps(striptags(page.title))}
 | 
			
		||||
            """
 | 
			
		||||
            input_files = "".join([input_files, input_file])
 | 
			
		||||
 | 
			
		||||
        # Generate list of *template* pages to index (if any)
 | 
			
		||||
        for tpage in self.tpages:
 | 
			
		||||
            if self.search_mode == "output":
 | 
			
		||||
                tpage_to_index = self.tpages[tpage]
 | 
			
		||||
            if self.search_mode == "source":
 | 
			
		||||
                tpage_to_index = tpage
 | 
			
		||||
            input_file = f"""
 | 
			
		||||
                [[input.files]]
 | 
			
		||||
                path = "{tpage_to_index}"
 | 
			
		||||
                url = "{self.tpages[tpage]}"
 | 
			
		||||
                title = ""
 | 
			
		||||
            """
 | 
			
		||||
            input_files = "".join([input_files, input_file])
 | 
			
		||||
 | 
			
		||||
        # Assemble the search settings file
 | 
			
		||||
        if self.search_mode == "output":
 | 
			
		||||
            base_dir = self.output_path
 | 
			
		||||
        if self.search_mode == "source":
 | 
			
		||||
            base_dir = self.content
 | 
			
		||||
        search_settings = cleandoc(
 | 
			
		||||
            f"""
 | 
			
		||||
                [input]
 | 
			
		||||
                base_directory = "{base_dir}"
 | 
			
		||||
                html_selector = "{self.html_selector}"
 | 
			
		||||
                {input_files}
 | 
			
		||||
            """
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # Write the search settings file to disk
 | 
			
		||||
        with open(search_settings_path, "w", encoding="utf-8") as fd:
 | 
			
		||||
            fd.write(search_settings)
 | 
			
		||||
 | 
			
		||||
        # Build the search index
 | 
			
		||||
        build_log = self.build_search_index(search_settings_path)
 | 
			
		||||
        build_log = "".join(["Search plugin reported ", build_log])
 | 
			
		||||
        logger.error(build_log) if "error" in build_log else logger.debug(build_log)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_generators(generators):
 | 
			
		||||
    return SearchSettingsGenerator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def register():
 | 
			
		||||
    signals.get_generators.connect(get_generators)
 | 
			
		||||
		Reference in New Issue
	
	Block a user