Source code for webpub1c.apache_config

import os
import re
from typing import Optional, Iterator, List

import jinja2

from .common import VRDConfig, default_templates_env, files_encoding, urlpath_join
from .webpublication import WebPublication


[docs] class ApacheConfig: """apache config""" start_tag: str = "# --- WEBPUB1C PUBLICATION START:" end_tag: str = "# --- WEBPUB1C PUBLICATION END:" def __init__( self, filename: str, vrd_path: str, dir_path: str, url_base: str, vrd_params: Optional[VRDConfig] = None, templates_env: Optional[jinja2.Environment] = None, ): self.filename: str = filename self.vrd_path: str = vrd_path self.dir_path: str = dir_path self.url_base: str = url_base self.vrd_params: Optional[VRDConfig] = vrd_params if templates_env is None: self.templates_env = default_templates_env else: self.templates_env = templates_env
[docs] def is_valid(self) -> bool: return os.path.isfile(self.filename)
def _check(self): if not self.is_valid(): raise ValueError("invalid apache config") @property def text(self) -> str: self._check() with open(self.filename, "r", encoding=files_encoding) as f: txt: str = f.read() return txt
[docs] def has_1cws_module(self) -> bool: ws_expr = re.compile(r"^LoadModule\s_1cws_module\s.*$", re.M) result: bool = ws_expr.search(self.text) is not None return result
[docs] def add_1cws_module(self, module_filename: str): if self.has_1cws_module(): return with open(self.filename, "a", encoding=files_encoding) as f: f.write(f'\nLoadModule _1cws_module "{module_filename}"\n')
@property def publications(self) -> Iterator[str]: start_expr = re.compile( r"^{}\s(.+)$".format(re.escape(ApacheConfig.start_tag)), re.M ) for match in start_expr.finditer(self.text): yield match.group(1).strip()
[docs] def iter(self) -> Iterator[WebPublication]: start_pub = re.compile(r"^{}\s".format(re.escape(ApacheConfig.start_tag))) start_name = re.compile(r"^{}\s(.+)$".format(re.escape(ApacheConfig.start_tag))) end_pub = re.compile(r"^{}\s".format(re.escape(ApacheConfig.end_tag))) is_pub_started: bool = False cur_pub_name: str = "" cur_pub_lines: List[str] = [] lines: List[str] = self.text.splitlines(keepends=True) for line in lines: if is_pub_started: if end_pub.match(line): if 0 == len(cur_pub_lines): raise ValueError("can't parse config :(") publication = WebPublication.from_config( cur_pub_name, "".join(cur_pub_lines), templates_env=self.templates_env, ) yield publication cur_pub_name = "" cur_pub_lines.clear() is_pub_started = False else: cur_pub_lines.append(line) continue if start_pub.match(line): is_pub_started = True match = start_name.match(line) if match is None: raise ValueError("can't parse config :(") cur_pub_name = match.group(1).strip()
[docs] def is_publicated(self, ibname: str) -> bool: return ibname in self.publications
[docs] def create_publication( self, ibname: str, url_path: Optional[str] = None, infobase_filepath="", force: bool = False, ) -> WebPublication: if self.is_publicated(ibname) and not force: raise KeyError(f'infobase "{ibname}" already publicated') publication = WebPublication( ibname, vrd_params=self.vrd_params, templates_env=self.templates_env, infobase_filepath=infobase_filepath, ) publication.generate_paths(self.dir_path, self.vrd_path, self.url_base) if url_path is not None: publication.url_path = urlpath_join(self.url_base, url_path) if not (force or publication.is_ok_to_create()): raise ValueError(f"can't create publication: {publication.describe()}") publication.create(force) return publication
[docs] def add_publication(self, publication: WebPublication, force: bool = False) -> None: if self.is_publicated(publication.name): if force: self.remove_publication(publication.name, destroy=False) else: raise KeyError(f'infobase "{publication.name}" already publicated') pub_cfg = publication.to_config() with open(self.filename, "a", encoding=files_encoding) as f: f.write(f"\n{ApacheConfig.start_tag} {publication.name}\n") f.write(pub_cfg) f.write(f"\n{ApacheConfig.end_tag} {publication.name}")
[docs] def get_publication(self, ibname: str) -> Optional[WebPublication]: if not self.is_publicated(ibname): return None start_pub = re.compile( r"^{}\s{}".format(re.escape(ApacheConfig.start_tag), re.escape(ibname)) ) end_pub = re.compile( r"^{}\s{}".format(re.escape(ApacheConfig.end_tag), re.escape(ibname)) ) is_pub_started: bool = False pub_lines: List[str] = [] lines: List[str] = self.text.splitlines(keepends=True) for line in lines: if is_pub_started: if end_pub.match(line): break else: pub_lines.append(line) continue if start_pub.match(line): is_pub_started = True if 0 == len(pub_lines): raise ValueError("can't parse config :(") publication = WebPublication.from_config( ibname, "".join(pub_lines), templates_env=self.templates_env ) return publication
[docs] def remove_publication( self, ibname: str, destroy: bool = True, force: bool = False ): if not self.is_publicated(ibname): raise KeyError(f'infobase "{ibname}" not publicated') start_pub = re.compile( r"^{}\s{}".format(re.escape(ApacheConfig.start_tag), re.escape(ibname)) ) end_pub = re.compile( r"^{}\s{}".format(re.escape(ApacheConfig.end_tag), re.escape(ibname)) ) is_pub_started: bool = False # filter lines for new config and publication pub_lines: List[str] = [] new_lines: List[str] = [] lines: List[str] = self.text.splitlines(keepends=True) for line in lines: if is_pub_started: if end_pub.match(line): is_pub_started = False # remove last empty line if len(new_lines) > 0: if new_lines[-1].strip() == "": new_lines.pop() else: pub_lines.append(line) continue if start_pub.match(line): is_pub_started = True continue new_lines.append(line) # remove vrd and directory if destroy: publication = WebPublication.from_config(ibname, "".join(pub_lines)) publication.remove(force) # write new config with open(self.filename, "w", encoding=files_encoding) as f: f.write("".join(new_lines))