diff --git a/ccvpn/settings.py b/ccvpn/settings.py
index 21cf7d6..4e4bad4 100644
--- a/ccvpn/settings.py
+++ b/ccvpn/settings.py
@@ -44,6 +44,7 @@ INSTALLED_APPS = (
'lambdainst',
'payments',
'tickets',
+ 'downloads',
'constance',
'constance.backends.database',
)
@@ -94,8 +95,6 @@ LOGOUT_URL = 'account:logout'
LOGIN_REDIRECT_URL = 'account:index'
LOGOUT_REDIRECT_URL = '/'
-PAGES_DIR = BASE_DIR + '/pages/'
-
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'ccvpn.passwords.LegacyPasswordHasher',
diff --git a/ccvpn/views.py b/ccvpn/views.py
index 31b48b9..95eb04b 100644
--- a/ccvpn/views.py
+++ b/ccvpn/views.py
@@ -5,6 +5,7 @@ import markdown
from markdown.extensions.codehilite import CodeHiliteExtension
from django.http import HttpResponseNotFound
from django.shortcuts import render
+from django.views.decorators.cache import cache_page
from django.conf import settings
from django.utils.translation import ugettext as _, get_language
from django import http
@@ -12,12 +13,14 @@ from django.utils.http import is_safe_url
from django.utils.translation import (
LANGUAGE_SESSION_KEY, check_for_language,
)
+from django.template.loader import TemplateDoesNotExist, get_template
from constance import config
+from downloads.models import Version
from .common import get_price_float
-md = markdown.Markdown(extensions=[
+MARKDOWN = markdown.Markdown(extensions=[
'markdown.extensions.toc',
'markdown.extensions.meta',
CodeHiliteExtension(noclasses=True),
@@ -59,18 +62,15 @@ def set_lang(request):
return response
+@cache_page(5 * 60)
def page(request, name):
if not re.match('^[a-z0-9_-]{1,50}$', name):
return HttpResponseNotFound()
- basename = settings.PAGES_DIR + '/' + name
-
- username = request.user.username
-
- page_replace = {
- 'USERNAME': username or '[username]',
- }
+ basename = 'pages/' + name
+ # For "pages", entire files are translated. We try the most
+ # specific first
files = [
basename + '.' + get_language() + '.md',
basename + '.en.md',
@@ -78,18 +78,17 @@ def page(request, name):
]
for file in files:
- if not os.path.isfile(file):
+ try:
+ template = get_template(file)
+ except TemplateDoesNotExist:
continue
- with open(file, encoding='utf8') as fh:
- page = fh.read()
- for s, r in page_replace.items():
- page = page.replace('{' + s + '}', r)
- page = md.convert(page)
+ page_md = template.render(None, request)
+ page_html = MARKDOWN.convert(page_md)
+ title = MARKDOWN.Meta.get('title', [None])[0]
- title = md.Meta.get('title', [None])[0]
- ctx = dict(content=page, title=title)
- return render(request, 'ccvpn/page.html', ctx)
+ ctx = dict(content=page_html, title=title)
+ return render(request, 'ccvpn/page.html', ctx)
return HttpResponseNotFound()
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 9438b44..f8dcb67 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-04-12 16:03+0000\n"
+"POT-Creation-Date: 2019-05-14 18:25+0000\n"
"PO-Revision-Date: 2016-04-07 01:32+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -27,10 +27,14 @@ msgstr ""
msgid "hash"
msgstr ""
-#: ccvpn/views.py:37 templates/tickets/layout.html:11
+#: ccvpn/views.py:39 templates/tickets/layout.html:11
msgid "Live Chat"
msgstr "Chat Live"
+#: downloads/templatetags/dltags.py:19
+msgid "Download {} v{}"
+msgstr "Télécharger {} v{}"
+
#: lambdainst/admin.py:23
msgid "Code must be [a-zA-Z0-9]"
msgstr ""
@@ -260,19 +264,19 @@ msgstr "Config"
msgid "Status"
msgstr "État"
-#: payments/admin.py:9
+#: payments/admin.py:11
msgid "Mark as cancelled (do not actually cancel)"
msgstr "Marquer comme annulé (n'annule pas)"
-#: payments/admin.py:22 payments/admin.py:77
+#: payments/admin.py:36 payments/admin.py:91
msgid "Payment Data"
msgstr "Données de paiement"
-#: payments/admin.py:45
+#: payments/admin.py:59
msgid "Amount"
msgstr "Montant"
-#: payments/admin.py:49
+#: payments/admin.py:63
msgid "Paid amount"
msgstr "Montant payé"
@@ -318,16 +322,14 @@ msgid "Bitcoin with CoinBase"
msgstr "Bitcoin avec CoinBase"
#: payments/backends/coingate.py:24
-#, fuzzy
-#| msgid "Coinbase"
msgid "CoinGate"
-msgstr "Coinbase"
+msgstr "CoinGate"
#: payments/backends/coingate.py:25
msgid "Cryptocurrencies"
msgstr "Cryptomonnaies"
-#: payments/backends/coingate.py:106
+#: payments/backends/coingate.py:109
msgid "Confirming transaction"
msgstr "Confirmation de la transaction"
@@ -343,82 +345,70 @@ msgstr ""
"En attente de la confirmation par Paypal... Cette étape peut durer quelques "
"minutes..."
-#: payments/backends/stripe.py:11
+#: payments/backends/stripe.py:10
msgid "Stripe"
msgstr "Stripe"
-#: payments/backends/stripe.py:12
+#: payments/backends/stripe.py:11
msgid "Credit Card"
msgstr "Carte"
-#: payments/backends/stripe.py:118
-msgid "No payment information was received."
-msgstr "Aucune information de paiement reçue."
-
-#: payments/backends/stripe.py:135
-msgid "The payment has been refunded or rejected."
-msgstr "Le paiement a été remboursé ou rejeté."
-
-#: payments/backends/stripe.py:143
-msgid "The paid amount is under the required amount."
-msgstr "La montant payé est inférieur au montant requis."
-
-#: payments/models.py:16 payments/models.py:30
+#: payments/models.py:19 payments/models.py:33
msgid "Waiting for payment"
msgstr "En attente du paiement"
-#: payments/models.py:17
+#: payments/models.py:20
msgid "Confirmed"
msgstr "Confirmé"
-#: payments/models.py:18 payments/models.py:32
+#: payments/models.py:21 payments/models.py:35
msgid "Cancelled"
msgstr "Annullé"
-#: payments/models.py:19
+#: payments/models.py:22
msgid "Rejected by processor"
msgstr "Rejeté"
-#: payments/models.py:20
+#: payments/models.py:23
msgid "Payment processing failed"
msgstr "Traitement échoué"
-#: payments/models.py:29
+#: payments/models.py:32
msgid "Created"
msgstr "Crée"
-#: payments/models.py:31
+#: payments/models.py:34
msgid "Active"
msgstr "Actif"
-#: payments/models.py:33
+#: payments/models.py:36
msgid "Error"
msgstr "Error"
-#: payments/models.py:37
+#: payments/models.py:40
msgid "Every 3 months"
msgstr "Tous les 3 mois"
-#: payments/models.py:38
+#: payments/models.py:41
msgid "Every 6 months"
msgstr "Tous les 6 mois"
-#: payments/models.py:39
+#: payments/models.py:42
msgid "Every year"
msgstr "Tous les ans"
-#: payments/views.py:141
+#: payments/views.py:144
msgid ""
"Error subscribing. It usually means you don't have enough money available."
msgstr ""
"Il y a une erreur à l'inscription. C'est le plus souvent un manque de fonds "
"sur la carte."
-#: payments/views.py:144
+#: payments/views.py:147
msgid "Subscribed!"
msgstr "Abonné!"
-#: payments/views.py:183
+#: payments/views.py:185
msgid "Subscription cancelled!"
msgstr "Abonnement annulé!"
@@ -549,19 +539,24 @@ msgstr "Créez un compte et profitez de l'essai gratuit"
#: templates/ccvpn/index.html:72
msgid "Hide your IP address to disrupt tracking and geolocation."
-msgstr "Cachez votre adresse IP pour perturber le traçage et la localisation."
+msgstr ""
+"Cachez votre adresse IP pour perturber le traçage et la localisation."
#: templates/ccvpn/index.html:75
msgid ""
"Protect your privacy on insecure networks with AES GCM 256 bits, RSA "
"4096 bits."
-msgstr "Protégez votre vie privée avec un chiffrement AES GCM 256 bits, RSA 4096 bits."
+msgstr ""
+"Protégez votre vie privée avec un chiffrement AES GCM 256 bits, RSA "
+"4096 bits."
#: templates/ccvpn/index.html:79
msgid ""
"Get a clean and neutral access without censorship, interception, or "
"manipulation."
-msgstr "Un accès propre et neutre qui ne censure pas et ne manipule pas votre connection."
+msgstr ""
+"Un accès propre et neutre qui ne censure pas et ne manipule pas votre "
+"connection."
#: templates/ccvpn/index.html:82
msgid "Bypass firewalls in restricted network environments."
@@ -571,15 +566,17 @@ msgstr "Contournez les firewalls sur les réseaux restraints."
msgid ""
"Transparently compress your traffic to save data and gain speed on "
"slow connections."
-msgstr "Compressez votre traffic> pour économiser des données et améliorer"
-"les performances."
+msgstr ""
+"Compressez votre traffic> pour économiser des données et améliorerles "
+"performances."
#: templates/ccvpn/index.html:90
msgid ""
"Get IPv6 connectivity on IPv4-only networks or where IPv6 is not "
"equally supported."
-msgstr "Profitez de l'IPv6 même sur les réseaux qui ne supportent pas "
-"ou mal l'IPv6."
+msgstr ""
+"Profitez de l'IPv6 même sur les réseaux qui ne supportent pas ou mal "
+"l'IPv6."
#: templates/ccvpn/page.html:8
msgid "Help"
diff --git a/static/css/style.css b/static/css/style.css
index df5d3a1..b0b1c38 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -402,6 +402,11 @@ ul.errorlist {
margin: 1.5em 0;
}
+.download-button {
+ text-align: center;
+ margin-top: 0.5em;
+}
+
/***************************************************/
/********************* Home Page */
diff --git a/pages/faq.en.md b/templates/pages/faq.en.md
similarity index 100%
rename from pages/faq.en.md
rename to templates/pages/faq.en.md
diff --git a/pages/faq.fr.md b/templates/pages/faq.fr.md
similarity index 100%
rename from pages/faq.fr.md
rename to templates/pages/faq.fr.md
diff --git a/pages/help.en.md b/templates/pages/help.en.md
similarity index 100%
rename from pages/help.en.md
rename to templates/pages/help.en.md
diff --git a/pages/help.fr.md b/templates/pages/help.fr.md
similarity index 100%
rename from pages/help.fr.md
rename to templates/pages/help.fr.md
diff --git a/pages/install-android.en.md b/templates/pages/install-android.en.md
similarity index 100%
rename from pages/install-android.en.md
rename to templates/pages/install-android.en.md
diff --git a/pages/install-android.fr.md b/templates/pages/install-android.fr.md
similarity index 100%
rename from pages/install-android.fr.md
rename to templates/pages/install-android.fr.md
diff --git a/pages/install-chromeos.en.md b/templates/pages/install-chromeos.en.md
similarity index 100%
rename from pages/install-chromeos.en.md
rename to templates/pages/install-chromeos.en.md
diff --git a/pages/install-chromeos.fr.md b/templates/pages/install-chromeos.fr.md
similarity index 100%
rename from pages/install-chromeos.fr.md
rename to templates/pages/install-chromeos.fr.md
diff --git a/pages/install-gnulinux.en.md b/templates/pages/install-gnulinux.en.md
similarity index 100%
rename from pages/install-gnulinux.en.md
rename to templates/pages/install-gnulinux.en.md
diff --git a/pages/install-gnulinux.fr.md b/templates/pages/install-gnulinux.fr.md
similarity index 100%
rename from pages/install-gnulinux.fr.md
rename to templates/pages/install-gnulinux.fr.md
diff --git a/pages/install-osx.en.md b/templates/pages/install-osx.en.md
similarity index 100%
rename from pages/install-osx.en.md
rename to templates/pages/install-osx.en.md
diff --git a/pages/install-osx.fr.md b/templates/pages/install-osx.fr.md
similarity index 100%
rename from pages/install-osx.fr.md
rename to templates/pages/install-osx.fr.md
diff --git a/pages/install-windows.en.md b/templates/pages/install-windows.en.md
similarity index 88%
rename from pages/install-windows.en.md
rename to templates/pages/install-windows.en.md
index 4b5db6c..6b9708f 100644
--- a/pages/install-windows.en.md
+++ b/templates/pages/install-windows.en.md
@@ -1,11 +1,11 @@
Title: Install on Windows
+{% load dltags %}
-With CCVPNGUI (recommended, simple)
+With CCVPN GUI (recommended, simple)
-------------
-CCVPNGUI is made for CCrypto VPN and contains everything it needs. Just download and run:
-
-[(sig)](https://dl.ccrypto.org/ccvpngui/releases/ccvpngui-1.0.0-1.exe.asc)
+CCVPN GUI is made for CCrypto VPN and contains everything it needs.
+{% download_button "ccvpngui" "windows" %}
The installer will ask if you want to create a desktop icon.
Once installed, you will only have to right click the icon in the notification
diff --git a/pages/install-windows.fr.md b/templates/pages/install-windows.fr.md
similarity index 89%
rename from pages/install-windows.fr.md
rename to templates/pages/install-windows.fr.md
index c9f3c37..a2c28df 100644
--- a/pages/install-windows.fr.md
+++ b/templates/pages/install-windows.fr.md
@@ -1,11 +1,11 @@
Title: Installation sous Windows
+{% load dltags %}
-Avec CCVPNGUI (recommandé, simple)
+Avec CCVPN GUI (recommandé, simple)
-------------
-CCVPNGUI est fait pour CCrypto VPN et contient tout ce qu'il faut. Téléchargez et lancez juste :
-
-[(sig)](https://dl.ccrypto.org/ccvpngui/releases/ccvpngui-1.0.0-1.exe.asc)
+CCVPN GUI est fait pour CCrypto VPN et contient tout ce qu'il faut.
+{% download_button "ccvpngui" "windows" %}
À l'installation, il vous sera proposé d'installer une icône sur le bureau.
Vous aurez ensuite à faire un clic-droit sur l'icône dans la zone de notification,
diff --git a/pages/nop2p.en.md b/templates/pages/nop2p.en.md
similarity index 100%
rename from pages/nop2p.en.md
rename to templates/pages/nop2p.en.md
diff --git a/pages/privacy.en.md b/templates/pages/privacy.en.md
similarity index 100%
rename from pages/privacy.en.md
rename to templates/pages/privacy.en.md
diff --git a/pages/self-diagnosis.en.md b/templates/pages/self-diagnosis.en.md
similarity index 100%
rename from pages/self-diagnosis.en.md
rename to templates/pages/self-diagnosis.en.md
diff --git a/pages/self-diagnosis.fr.md b/templates/pages/self-diagnosis.fr.md
similarity index 100%
rename from pages/self-diagnosis.fr.md
rename to templates/pages/self-diagnosis.fr.md
diff --git a/pages/tos.en.md b/templates/pages/tos.en.md
similarity index 100%
rename from pages/tos.en.md
rename to templates/pages/tos.en.md