Skip to content

Commit

Permalink
feat: add legal documents in PDF
Browse files Browse the repository at this point in the history
- these can be automatically generated from wllegal
- added download to the pages
  • Loading branch information
nijel committed Nov 14, 2024
1 parent 0c4dbd1 commit 2b9fe1a
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 2 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ profile = "django"

[tool.djlint.per-file-ignores]
"weblate_web/invoices/templates/invoice-template.html" = "H031"
"weblate_web/legal/templates/pdf/base.html" = "H030,H031"
# False positives for crypto URLs
"weblate_web/templates/donate.html" = "D018"
# Use language-less URLs in notifications
Expand Down
47 changes: 47 additions & 0 deletions weblate_web/legal/management/commands/generate_terms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#
# Copyright © Michal Čihař <[email protected]>
#
# This file is part of Weblate <https://weblate.org/>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#

from pathlib import Path

Check warning on line 20 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L20

Added line #L20 was not covered by tests

from django.core.management.base import BaseCommand
from django.template.loader import render_to_string

Check warning on line 23 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L22-L23

Added lines #L22 - L23 were not covered by tests

from weblate_web.pdf import render_pdf

Check warning on line 25 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L25

Added line #L25 was not covered by tests

HOSTED_ACCOUNT = "Hosted Weblate account"

Check warning on line 27 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L27

Added line #L27 was not covered by tests

OUT_DIR = Path(__file__).parent.parent.parent / "static"

Check warning on line 29 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L29

Added line #L29 was not covered by tests


class Command(BaseCommand):
help = "generates legal PDFs"
client = None

Check warning on line 34 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L32-L34

Added lines #L32 - L34 were not covered by tests

def handle(self, *args, **options):
render_pdf(

Check warning on line 37 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L36-L37

Added lines #L36 - L37 were not covered by tests
html=render_to_string(
"pdf/terms.html", {"title": "General Terms and Conditions"}
),
output=OUT_DIR / "Weblate_General_Terms_and_Conditions.pdf",
)

render_pdf(

Check warning on line 44 in weblate_web/legal/management/commands/generate_terms.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/legal/management/commands/generate_terms.py#L44

Added line #L44 was not covered by tests
html=render_to_string("pdf/privacy.html", {"title": "Privacy Policy"}),
output=OUT_DIR / "Weblate_Privacy_Policy.pdf",
)
Binary file not shown.
Binary file not shown.
22 changes: 22 additions & 0 deletions weblate_web/legal/templates/pdf/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link href="legal:pdf/legal.css" media="print" rel="stylesheet">
<title>Weblate {{ title }}</title>
<meta name="dcterms.created" content="{% now "c" %}">
<meta name="author" content="Weblate s.r.o.">
</head>

<body>
<header>
<img class="logo" src="invoices:invoice-logo.svg" alt="Weblate">
</header>

<h1>{{ title }}</h1>

{% block content %}
{% endblock content %}

</body>
</html>
117 changes: 117 additions & 0 deletions weblate_web/legal/templates/pdf/legal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
@page {
margin: 3.5cm 1cm 3cm 1cm;
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
}
}

html,
a {
color: #14213d;
font-family: Source Sans Pro;
font-size: 11pt;
line-height: 1.6;
}
body {
margin: 0;
padding: 0;
}
header {
display: block;
padding-bottom: 1.3cm;
position: fixed;
left: 0;
right: 0;
top: -2.5cm;
height: 2.5cm;
}

h1 {
font-size: 18pt;
padding-top: 3mm;
}
img {
position: absolute;
max-width: 30%;
margin: 0;
padding: 0;
right: 0;
}
.tos {
counter-reset: tos_chapter;
}

.tos h2::before {
counter-increment: tos_chapter;
content: counter(tos_chapter) ". ";
}

.tos h2 {
counter-reset: tos_item;
}

.tos p.item,
.tos p.subitem,
.tos p.subsubitem {
position: relative;
}
.tos p,
.tos dl {
padding: 0 3.5em;
}
.tos p.item {
counter-reset: tos_subitem;
}
.tos p.subitem {
counter-reset: tos_subsubitem;
}
.tos p.subsubitem {
padding: 0 4.2em;
}

.tos p.item::before {
counter-increment: tos_item;
content: counter(tos_chapter) "." counter(tos_item) ". ";
position: absolute;
left: 0;
}

.tos p.subitem::before {
counter-increment: tos_subitem;
content: counter(tos_chapter) "." counter(tos_item) "." counter(tos_subitem)
". ";
position: absolute;
left: 0;
}

.tos p.subsubitem::before {
counter-increment: tos_subsubitem;
content: counter(tos_chapter) "." counter(tos_item) "." counter(tos_subitem)
"." counter(tos_subsubitem) ". ";
position: absolute;
left: 0;
}

.tos ol {
counter-reset: tos_list;
padding: 0 5em;
}
.tos ol > li {
list-style: none;
position: relative;
}
.tos ol > li:before {
counter-increment: tos_list;
content: counter(tos_list, lower-alpha) ") ";
position: absolute;
left: -1.4em;
}

.tos a {
color: #2eccaa;
text-decoration: underline;
}

.tos a:hover {
text-decoration: none;
}
5 changes: 5 additions & 0 deletions weblate_web/legal/templates/pdf/privacy.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{% extends "pdf/base.html" %}

{% block content %}
<div class="tos">{% include "legal/documents/privacy.html" with hide_english=True %}</div>
{% endblock content %}
7 changes: 7 additions & 0 deletions weblate_web/legal/templates/pdf/terms.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% extends "pdf/base.html" %}

{% block content %}
<div class="tos">
{% include "legal/documents/tos.html" with hide_english=True privacy_url="https://weblate.org/privacy/" %}
</div>
{% endblock content %}
8 changes: 6 additions & 2 deletions weblate_web/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,19 @@
from weasyprint.text.fonts import FontConfiguration

INVOICES_URL = "invoices:"
LEGAL_URL = "legal:"
STATIC_URL = "static:"
TEMPLATES_PATH = Path(__file__).parent / "invoices" / "templates"
INVOICES_TEMPLATES_PATH = Path(__file__).parent / "invoices" / "templates"
LEGAL_TEMPLATES_PATH = Path(__file__).parent / "legal" / "templates"


def url_fetcher(url: str) -> dict[str, str | bytes]:
path_obj: Path
result: dict[str, str | bytes]
if url.startswith(INVOICES_URL):
path_obj = TEMPLATES_PATH / url.removeprefix(INVOICES_URL)
path_obj = INVOICES_TEMPLATES_PATH / url.removeprefix(INVOICES_URL)
elif url.startswith(LEGAL_URL):
path_obj = LEGAL_TEMPLATES_PATH / url.removeprefix(LEGAL_URL)

Check warning on line 40 in weblate_web/pdf.py

View check run for this annotation

Codecov / codecov/patch

weblate_web/pdf.py#L40

Added line #L40 was not covered by tests
elif url.startswith(STATIC_URL):
fullname = url.removeprefix(STATIC_URL)
match = finders.find(fullname)
Expand Down
2 changes: 2 additions & 0 deletions weblate_web/templates/privacy.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% extends "base.html" %}

{% load i18n %}
{% load static %}

{% block content %}
<section class="content">
Expand All @@ -23,6 +24,7 @@ <h1 class="section-title min-m">
{% if LANGUAGE_CODE != "en" %}
<a href="https://weblate.org/en/privacy/" class="button inline">{% trans "View English version" %}</a>
{% endif %}
<a href="{% static "Weblate_Privacy_Policy.pdf" %}" class="button inline">{% trans "Download as PDF" %}</a>
</div>
</div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions weblate_web/templates/terms.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{% extends "base.html" %}

{% load i18n %}
{% load static %}

{% block content %}
<section class="content">
Expand All @@ -23,6 +24,8 @@ <h1 class="section-title min-m">
{% if LANGUAGE_CODE != "en" %}
<a href="https://weblate.org/en/terms/" class="button inline">{% trans "View English version" %}</a>
{% endif %}
<a href="{% static "Weblate_General_Terms_and_Conditions.pdf" %}"
class="button inline">{% trans "Download as PDF" %}</a>
</div>
</div>
</div>
Expand Down

0 comments on commit 2b9fe1a

Please sign in to comment.