示例#1
0
文件: document.py 项目: pbehnke/doku
class Document(db.Model, DateMixin):
    """Document Model
    """

    __tablename__ = "doku_document"
    id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)

    name = db.Column(db.String(255), unique=False, nullable=False)
    public = db.Column(db.Boolean)
    template_id = db.Column(
        db.Integer, db.ForeignKey("doku_template.id"), nullable=True
    )

    template = db.relationship("Template", back_populates="documents")
    variables = db.relationship(
        "Variable", cascade="all,delete", back_populates="document"
    )

    recent_variable = db.relationship(
        "Variable", order_by="desc(Variable.last_updated)", lazy="dynamic"
    )

    def __str__(self):
        return self.name

    @property
    def html(self):
        return self.template.source

    @property
    def filename(self):
        return "_".join(self.name.split()).lower()

    def render(self):
        return self.template.render(self.variables)
示例#2
0
文件: template.py 项目: pbehnke/doku
class Stylesheet(db.Model, DateMixin):
    """Stylesheet Model

    This model is used in conjunction with the :class:`Template` model.
    While the Template model provides the Jinja2 (HTML) template, this
    model will serve the stylesheet. Separating both types will help us
    achieve a more modular templating engine with base styles and custom
    styles that can be changed globally.
    """

    __tablename__ = "doku_stylesheet"
    id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)

    name = db.Column(db.String(255), unique=False, nullable=False)
    source = db.Column(db.UnicodeText, nullable=True)

    base_templates = db.relationship("Template", back_populates="base_style")
    templates = db.relationship("Template",
                                secondary=template_stylesheet_relation,
                                back_populates="styles")

    MAX_CONTENT_LENGTH = 125000

    def __str__(self):
        return self.name

    @property
    def as_css(self) -> CSS:
        return CSS(string=self.source)
示例#3
0
class User(db.Model):
    """User Model
    """

    __tablename__ = "doku_user"
    id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)

    username = db.Column(db.String(48), nullable=False, unique=True)
    email = db.Column(db.String(48), unique=True, nullable=False)
    password = db.Column(db.LargeBinary, nullable=False)

    def __init__(self, *args, **kwargs):
        if "password" in kwargs:
            self.set_password(kwargs.pop("password"))
        super().__init__(*args, **kwargs)

    @staticmethod
    def _hash_password(password):
        return generate_password_hash(password.encode(),
                                      salt_length=12).encode()

    def set_password(self, password):
        self.password = self._hash_password(password)

    def check_password(self, password):
        return check_password_hash(self.password.decode(), password)

    def authenticate(self, request):
        pass
示例#4
0
文件: template.py 项目: pbehnke/doku
class Template(db.Model, DateMixin):
    """Template Model

    Used to store Jinja2 templates that can be populated with various
    variables.
    Styles are implemented using relations to the :class:`Stylesheet`
    model. For each template there is a :attr:`base_style`, which
    corresponds to a global stylesheet for multi-document presets.
    """

    __tablename__ = "doku_template"
    id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)

    name = db.Column(db.String(255), unique=False, nullable=False)
    base_style_id = db.Column(db.Integer,
                              db.ForeignKey("doku_stylesheet.id"),
                              nullable=True)
    source = db.Column(db.UnicodeText, nullable=True, default=DEFAULT_TEMPLATE)

    documents = db.relationship("Document", back_populates="template")
    base_style = db.relationship("Stylesheet", back_populates="base_templates")
    styles = db.relationship("Stylesheet",
                             secondary=template_stylesheet_relation,
                             back_populates="templates")

    def __str__(self):
        return self.name

    @property
    @functools.lru_cache(maxsize=512)
    def available_fields(self):
        env = Environment()
        content = env.parse(self.source)
        return meta.find_undeclared_variables(content)

    def render(self, variables):
        stylesheets = [
            style.as_css for style in self.styles if style.source is not None
        ]
        if self.base_style.source is not None:
            stylesheets = [self.base_style.as_css] + stylesheets
        template = Jinja2Template(self.source)
        context: dict = {
            var.name: var.compiled_content
            for var in variables
            if not var.is_list or var.parent_id is not None
        }
        context.update(
            {var.name: var.as_list
             for var in variables if var.is_list})
        source = template.render(**context)
        if "codehilite" in source:
            stylesheets.append(CSS(string=HtmlFormatter().get_style_defs()))
        html = HTML(string=source, base_url=".", url_fetcher=url_fetcher)
        return html.write_pdf(stylesheets=stylesheets)
示例#5
0
class Resource(db.Model, DateMixin):
    """Resource Model
    """

    __tablename__ = "doku_resource"
    id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)

    name = db.Column(db.String(255), unique=False, nullable=False)
    filename = db.Column(db.String(255), unique=True, nullable=False)

    @property
    def url(self):
        return url_for("resources.view", resource_id=self.id)
示例#6
0
文件: document.py 项目: pbehnke/doku
class Variable(db.Model, DateMixin):
    """Variable

    Used to store the actual markdown content of a document.

    As we work with Jinja2 templates for out :class:`Template` class,
    they are basically passed as a context.
    """

    AUTO_UPDATE = [
        "name",
        "use_markdown",
        "css_class",
        "content",
        "document_id",  # Used for empty children
    ]

    __tablename__ = "doku_variable"
    id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)

    name = db.Column(db.String(255), unique=False, nullable=False)
    use_markdown = db.Column(db.Boolean, default=True)
    css_class = db.Column(db.String(255), unique=False, nullable=True, default="")
    content = db.Column(db.UnicodeText, nullable=False, default="")
    compiled_content = db.Column(db.UnicodeText, nullable=False, default="")
    document_id = db.Column(
        db.Integer, db.ForeignKey("doku_document.id"), nullable=False
    )
    parent_id = db.Column(db.Integer, db.ForeignKey("doku_variable.id"), nullable=True)

    children = db.relationship(
        "Variable",
        cascade="all,delete",
        backref=db.backref("parent", remote_side=[id]),
        order_by=func.lower(name),
    )
    document = db.relationship("Document", back_populates="variables")

    @property
    def used(self) -> bool:
        if self.parent_id is not None:
            return True
        return self.name in self.document.template.available_fields

    @property
    def is_list(self) -> bool:
        return self.name.endswith("_list")

    @property
    def as_list(self) -> List[str]:
        if not self.is_list:
            raise ValueError(f"{self.name} is not a list")
        return [var.compiled_content for var in self.children]
示例#7
0
文件: template.py 项目: pbehnke/doku
from doku.utils.weasyfetch import url_fetcher

DEFAULT_TEMPLATE = """<html>
<head>
  <title>{{ title }}</title>
  <meta charset="utf-8">
</head>
<body>
  {{ body }}
</body>
</html>"""

template_stylesheet_relation = db.Table(
    "doku_template_stylesheet_relation",
    db.Model.metadata,
    db.Column("template_id", db.Integer, db.ForeignKey("doku_template.id")),
    db.Column("style_id", db.Integer, db.ForeignKey("doku_stylesheet.id")),
)


class Template(db.Model, DateMixin):
    """Template Model

    Used to store Jinja2 templates that can be populated with various
    variables.
    Styles are implemented using relations to the :class:`Stylesheet`
    model. For each template there is a :attr:`base_style`, which
    corresponds to a global stylesheet for multi-document presets.
    """

    __tablename__ = "doku_template"