You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
9.1 KiB
199 lines
9.1 KiB
#!/usr/bin/env python3 |
|
# -*- coding: utf-8 -*- |
|
|
|
""" |
|
Script to generate the gitea landing page for git.friendi.ca with strings |
|
from the translation files. The generated 'home.tmpl' then has to be |
|
placed into the 'custom/templates' directory of the gitea installation. |
|
|
|
Authors: |
|
* Tobias Diekershoff <tobias.diekershoff(@)gmx.net> |
|
|
|
Copyright (c) 2018 |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
of this software and associated documentation files (the "Software"), to deal |
|
in the Software without restriction, including without limitation the rights |
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
copies of the Software, and to permit persons to whom the Software is |
|
furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included in all |
|
copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
SOFTWARE. |
|
""" |
|
import gettext |
|
import os |
|
|
|
# define dummy _ function for pygettext to find the translate-able strings |
|
def _(message): return message |
|
|
|
# constant strings for the webpage |
|
str_collection = _("Collection of the git repositories of the <a href='https://friendi.ca' target='_new'>Friendica</a> project.") |
|
str_header1 = _("Easy to install") |
|
str_box1 = _("All you need is PHP and a MySQL database. Installation can be done via file upload, git or docker.") |
|
str_header2 = _("Free Software") |
|
str_box2 = _("Friendica is Free Software, licensed under the terms of the AGPLv3 (or later). The entire source code is hosted at <a href='https://git.friendi.ca/friendica/friendica'>git.friendi.ca</a>. Join us by contributing to make this project even better. Don't be shy to <a href='https://git.friendi.ca/friendica/friendica/src/branch/develop/doc/Developers-Intro.md'>be a contributor</a>!") |
|
str_header3 = _("Decentralization") |
|
str_box3 = _("Decentralized architecture with no central authority or ownership. Relationships can be made across any compatible system, creating a network of Internet scale made up of smaller sites. Seamless wall-to-wall posts and remote comments, even across different network nodes.") |
|
str_header4 = _("Interoperability") |
|
str_box4 = _("Friendica has build in support for the ActivityPub (e.g. Hubzilla, Mastodon, Pleroma, Pixelfed, Socialhome), OStatus (e.g. GNU social) and diaspora* (e.g. diaspora*) protocol. With additional addons you can bridge to more networks like pump.io, Twitter and others.") |
|
# we don't need the dummy anymore |
|
del _ |
|
|
|
# which translations do we have? and where to find them |
|
myDomain = "messages" |
|
languageDirectory = 'lang' |
|
fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), languageDirectory) |
|
# once there are translations, this list is used to hold the lng-codes |
|
# of the available translations. Later in the script, when the home.tmpl |
|
# is created, we'll loop over all these languages. |
|
translations = ['de-DE', 'nl-NL', 'it-IT', 'pl-PL', 'cs-CZ', 'en-GB', |
|
'ja-JA', 'ca-ES', 'es-ES', 'fi-FI', 'fr-FR', 'hu-HU', 'ru-RU', 'da-DK'] |
|
count = len(translations) |
|
languages = {} |
|
# read in all the available translation for later usage |
|
for lng in translations: |
|
l = gettext.translation(domain=myDomain, localedir=fn, languages=[lng]) |
|
languages[lng] = l |
|
# for the beginning and ending of the if ... else if ... else cascade |
|
ifelse = {0: '\n{{if eq .Lang "{{lngcode}}"}}\n', count: '\n{{else}}\n'} |
|
# The icons from font awesome used for the four info box titles |
|
icons = {'ul' : '<i class="octicon octicon-rocket"></i>', |
|
'ur' : '<i class="octicon octicon-code"></i>', |
|
'll' : '<i class="octicon octicon-globe"></i>', |
|
'lr' : '<i class="octicon octicon-organization"></i>'} |
|
# header block of the template |
|
templateHead = """{{template "base/head" .}} |
|
<div class="home"> |
|
<div class="ui stackable middle very relaxed page grid"> |
|
<div class="sixteen wide center aligned centered column"> |
|
<div> |
|
<img class="logo" src="{{AppSubUrl}}/assets/img/friendica-128.png" /> |
|
</div> |
|
<div class="hero"> |
|
<h1 class="ui icon header title"> |
|
Friendica |
|
</h1> |
|
""" |
|
# template for the subtitle in the header |
|
templateCollection = " <h2>{{CollectionOfRepositories}}</h2>" |
|
# closing the header |
|
templateMedium = """ |
|
</div> |
|
</div> |
|
</div> |
|
""" |
|
# The info boxes, there are four in total, this template holds 2 divs (left and right) |
|
templateInfoBox = """ <div class="ui stackable middle very relaxed page grid"> |
|
<div class="eight wide center column"> |
|
<h1 class="hero ui icon header"> |
|
{{Licon}} {{Lheader}} |
|
</h1> |
|
<p class="large"> |
|
{{Lbody}} |
|
</p> |
|
</div> |
|
<div class="eight wide center column"> |
|
<h1 class="hero ui icon header"> |
|
{{Ricon}} {{Rheader}} |
|
</h1> |
|
<p class="large"> |
|
{{Rbody}} |
|
</p> |
|
</div> |
|
</div> |
|
""" |
|
# closing the page |
|
templateFooter = """</div> |
|
{{template "base/footer" .}} |
|
""" |
|
|
|
# templates and preparation done, generate the home.tmpl file containing all ready languages |
|
with open('custom/templates/home.tmpl', mode='w', encoding='utf-8') as outFile: |
|
outFile.write(templateHead) |
|
if count: |
|
for i in range(count+1): |
|
try: |
|
# for all languages except the default |
|
lng = translations[i] |
|
l = languages[translations[i]] |
|
_ = l.gettext |
|
l.install() |
|
outString = _(str_collection) |
|
except: |
|
# last entry in the cascade is the default (EN) language |
|
lng = 'en' |
|
outString = str_collection |
|
if i in [0, count]: |
|
# opening and ending of the if ... else if ... else cascade need special treatment |
|
outFile.write(ifelse[i].replace('{{lngcode}}', lng)) |
|
else: |
|
outFile.write('\n{{else if eq .Lang "{{lngcode}}"}}\n'.replace('{{lngcode}}', lng)) |
|
outFile.write(templateCollection.replace("{{CollectionOfRepositories}}", outString)) |
|
outFile.write('\n{{end}}\n') |
|
else: |
|
# if not, we just take the line for the base language |
|
outFile.write(templateCollection.replace("{{CollectionOfRepositories}}", str_collection)) |
|
outFile.write(templateMedium) |
|
# now add the info boxes in all translations and the base language |
|
if count: |
|
for i in range(count+1): |
|
try: |
|
lng = translations[i] |
|
l = languages[translations[i]] |
|
_ = l.gettext |
|
l.install() |
|
except: |
|
lng = 'en' |
|
if i in [0, count]: |
|
# opening and ending of the if ... else if ... else cascade need special treatment |
|
outFile.write(ifelse[i].replace('{{lngcode}}', lng)) |
|
else: |
|
outFile.write('\n{{else if eq .Lang "{{lngcode}}"}}\n'.replace('{{lngcode}}', lng)) |
|
if not i == count: |
|
# a translation |
|
# upper row of info boxes |
|
tmpText = templateInfoBox.replace('{{Licon}}', icons['ul']).replace('{{Ricon}}', icons['ur']) |
|
tmpText = tmpText.replace('{{Lheader}}', _(str_header1)).replace('{{Rheader}}', _(str_header2)) |
|
tmpText = tmpText.replace('{{Lbody}}', _(str_box1)).replace('{{Rbody}}', _(str_box2)) |
|
outFile.write(tmpText) |
|
# lower row of info boxes |
|
tmpText = templateInfoBox.replace('{{Licon}}', icons['ll']).replace('{{Ricon}}', icons['lr']) |
|
tmpText = tmpText.replace('{{Lheader}}', _(str_header3)).replace('{{Rheader}}', _(str_header4)) |
|
tmpText = tmpText.replace('{{Lbody}}', _(str_box3)).replace('{{Rbody}}', _(str_box4)) |
|
outFile.write(tmpText) |
|
else: |
|
# finally the default language |
|
# upper row of info boxes |
|
tmpText = templateInfoBox.replace('{{Licon}}', icons['ul']).replace('{{Ricon}}', icons['ur']) |
|
tmpText = tmpText.replace('{{Lheader}}', str_header1).replace('{{Rheader}}', str_header2) |
|
tmpText = tmpText.replace('{{Lbody}}', str_box1).replace('{{Rbody}}', str_box2) |
|
outFile.write(tmpText) |
|
# lower row of info boxes |
|
tmpText = templateInfoBox.replace('{{Licon}}', icons['ll']).replace('{{Ricon}}', icons['lr']) |
|
tmpText = tmpText.replace('{{Lheader}}', str_header3).replace('{{Rheader}}', str_header4) |
|
tmpText = tmpText.replace('{{Lbody}}', str_box3).replace('{{Rbody}}', str_box4) |
|
outFile.write(tmpText) |
|
outFile.write('\n{{end}}\n') |
|
else: |
|
# if not, it is only the base language |
|
# upper row of info boxes |
|
tmpText = templateInfoBox.replace('{{Licon}}', icons['ul']).replace('{{Ricon}}', icons['ur']) |
|
tmpText = tmpText.replace('{{Lheader}}', str_header1).replace('{{Rheader}}', str_header2) |
|
tmpText = tmpText.replace('{{Lbody}}', str_box1).replace('{{Rbody}}', str_box2) |
|
outFile.write(tmpText) |
|
# lower row of info boxes |
|
tmpText = templateInfoBox.replace('{{Licon}}', icons['ll']).replace('{{Ricon}}', icons['lr']) |
|
tmpText = tmpText.replace('{{Lheader}}', str_header3).replace('{{Rheader}}', str_header4) |
|
tmpText = tmpText.replace('{{Lbody}}', str_box3).replace('{{Rbody}}', str_box4) |
|
outFile.write(tmpText) |
|
outFile.write(templateFooter) |
|
outFile.close()
|
|
|