Compare commits

...

10 Commits

@ -1,39 +1,39 @@
-----BEGIN CERTIFICATE-----
MIIG0zCCBLugAwIBAgIJAOOv2BdszSOVMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD
VQQGEwJGUjERMA8GA1UEBxMIU29tZUNpdHkxHzAdBgNVBAoTFkNvZ25pdGl2ZSBD
cnlwdG9ncmFwaHkxEzARBgNVBAsTCkNDcnlwdG9WUE4xEzARBgNVBAMTCkNDcnlw
dG9WUE4xEzARBgNVBCkTCkNDcnlwdG9WUE4xHzAdBgkqhkiG9w0BCQEWEGNlcnRA
Y2NyeXB0by5vcmcwHhcNMTMwODEzMTgxOTQ4WhcNMjMwODExMTgxOTQ4WjCBoTEL
MAkGA1UEBhMCRlIxETAPBgNVBAcTCFNvbWVDaXR5MR8wHQYDVQQKExZDb2duaXRp
dmUgQ3J5cHRvZ3JhcGh5MRMwEQYDVQQLEwpDQ3J5cHRvVlBOMRMwEQYDVQQDEwpD
Q3J5cHRvVlBOMRMwEQYDVQQpEwpDQ3J5cHRvVlBOMR8wHQYJKoZIhvcNAQkBFhBj
ZXJ0QGNjcnlwdG8ub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
xvkZj62nUvSjEPs1qBokLd8bBpBlLj6RGgJpfPqS/kKF0s1HpcYZynIcqP6Dw/Pi
LFcTE1STzgFfcEdKLmZAH+JCFVpc9mRTXEifouBk+2j3MG9+j2GTXHCK5FMkcJWQ
o4YihO2UOLz8qz4yn3dmy0zP1UmqxB2SayYXhwT2+pDSTkBCP6YtRURVVNIVRM7A
72hBUJ2dUgKHMTsBJSQj/11rRJ6wW6yUt0NtEcDUbdgrq0BibHq8zzCkl3vGl20M
2UCXPNKavP1aapoDGWLSxZgJ9nkFUfWbjWjHuuBw8cjQ7OV7SLiBXqLNJdcCshDA
OlwaPS4atao73rliE8bWAsGiwJZ+WXnGNJAr/6BwEtOizc6hr92S8lHOrlEWz3/F
h2+L/GI97KMM+pfxlTd8j4dbBpDIXv2vlpYOQ97EbYSbWv7fmYZ2BxxgljATBPfA
hA/y7GEfTodC/mkyZO8R2joBxcbQRu7AjsL30AOiE0GepUQNqhlbhEePvm28C9Rn
OHm4zaqQLo3BJzlP23N9sn4cMZYMiPnx+eCDv+UW7Y+xHVz0GSjlO1IkZ5lTu2fR
IbONfLYDGcByOBaLmo3oD60grw552COTAYDMlu2h8zQV0gPhJziO/txDapoBuNeX
XUdzzp1l6GFTsqIKs6ATleJ4n/S4OQe/kicZkCdYZ3kCAwEAAaOCAQowggEGMB0G
A1UdDgQWBBTWsE0h2/8fw8SbrhvXny8aBL/KTTCB1gYDVR0jBIHOMIHLgBTWsE0h
2/8fw8SbrhvXny8aBL/KTaGBp6SBpDCBoTELMAkGA1UEBhMCRlIxETAPBgNVBAcT
CFNvbWVDaXR5MR8wHQYDVQQKExZDb2duaXRpdmUgQ3J5cHRvZ3JhcGh5MRMwEQYD
VQQLEwpDQ3J5cHRvVlBOMRMwEQYDVQQDEwpDQ3J5cHRvVlBOMRMwEQYDVQQpEwpD
Q3J5cHRvVlBOMR8wHQYJKoZIhvcNAQkBFhBjZXJ0QGNjcnlwdG8ub3JnggkA46/Y
F2zNI5UwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAMQsLBf8TPFkh
/cnsh+E2N5YCqoeiYwLfPlqo3DwVaDoD8w5NovbIj+O6Z31FkTbt2Zotky6BQMCz
5wfuPa1WPuU2kARqS+4LA8FOd1tH4+xqGE6lgkqQuKGJEhi4J4wBg0yKvS4GxZ0+
ZXw+fWZSGDPR8WlKVfAR6DEuPIgJqIo0hIWbMgKsmqDzxevWg+Y8C9X0VjLwaSX+
dcC9N+ztYFKkzP4yOba8vFjYBmAYzaxwloUmm+iaTD/jrik9kqjd6grNh8bQa/0N
hzoa0UL8qgnorusvzo85B/I+cavS37djAeoZ1Oilerp39HS5yjvtbI/ijKW6Wp0l
aYCQ6e9f6Ka9cMfVwDJ+aow3rp0MJG0ilP+mS+ouE/R4tnAfVXrlh5X7tsGanByu
LtXIbRrLGcCmmNLtdZ2lRVi3BRRKQu5G/6WkvjslBU27CcvKnTtT7FmtKg9564rB
NCRawVf3veelwmVdnmkKd6Ka05ymJrm3ZU03+41ilSiqecFRFqz/+urdYkmynJtq
E4hNy013h6rooKnNXrMDMuTJqPTa0xJTM+74+JQwEZETSW7TdAGVrqRnJXdXn8Zi
17Gr351BJNOBWvyk8MPBKLM24e0qX+4NykQCT8Whhj4YQ/wzvwx2ayKAfoJYd74s
9ZCg4dyZMObBjkw08am0H6W6pe9umaY=
MIIG0zCCBLugAwIBAgIUEEze40yQlf+q4ncb8IuqnOd/hNQwDQYJKoZIhvcNAQEL
BQAwgZkxCzAJBgNVBAYTAkZSMR8wHQYDVQQKExZDb2duaXRpdmUgQ3J5cHRvZ3Jh
cGh5MRMwEQYDVQQLEwpDQ3J5cHRvVlBOMR4wHAYDVQQDExVDQ3J5cHRvVlBOIFJv
b3QgdjIgQ0ExEzARBgNVBCkTCkNDcnlwdG9WUE4xHzAdBgkqhkiG9w0BCQEWEGNl
cnRAY2NyeXB0by5vcmcwIBcNMjIwNDI1MTU1NTE4WhgPMjEyMjA0MDExNTU1MTha
MIGZMQswCQYDVQQGEwJGUjEfMB0GA1UEChMWQ29nbml0aXZlIENyeXB0b2dyYXBo
eTETMBEGA1UECxMKQ0NyeXB0b1ZQTjEeMBwGA1UEAxMVQ0NyeXB0b1ZQTiBSb290
IHYyIENBMRMwEQYDVQQpEwpDQ3J5cHRvVlBOMR8wHQYJKoZIhvcNAQkBFhBjZXJ0
QGNjcnlwdG8ub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA12zS
Z0Y3poiQLgmW6yWBOcyGFsDkBqalVKAMpzioW6ph91MExfwTnsUtZ1V/rJ74RGCi
c8vF97/frZg7XtmFavdLJkq9NMDLtJ4xHapBjtr6AP8pkWeo4KLfN4YiujUEYMI/
lzugASzdMDVVA8cUitE5jU+qWZKcSYGHZOvY/6EscyvhdtyfSs9+jkzgQdAL1YLw
GcXJe5yocl1Nt+6XnnQcdvvVmmEy1s1AoVW73721qEh5vIXjnRr0SEeqAlD1JiuS
fN09SoMSHawi2g+LiOZY0IoIEMzCWkcbEBjQszcvZyMiR9/vm19x0T2VycHUBgkv
VZgMdryiLFJ+CiVydaMSvUN6IootUkzF/xe3EhQEToWz/MM/YTFI8spVR4tXzxgw
f91BPhENuMVC+JtUfo6q5x9XFlmJT81SFTgW+lo7dBbnL3yh3yIcN5yMEdBJty9k
YVxHGGT6jx5CfGPP4J8/70MhrDG22+qQ28b/SYTOdmzimKMdsPnqku2TGJoxXluf
ROlN1iyk+1Ry4AexzpbB2I0Apd1n+6udo2Vv+atTeV7sE7ajxUhyzfZj1kIARUi0
T3ZNTsdvqyrfTWCNYggjXOPpPGOk3bcX6jUAXZ4fjsVg9i13BNghso2NVcepGYMZ
eYSfaSmzY7A85Qa4xwXuN2FxbXPsFsXYtuPimpMCAwEAAaOCAQ0wggEJMB0GA1Ud
DgQWBBQz/6L/JOGHHSLYUbnhfVRLGyUxaTCB2QYDVR0jBIHRMIHOgBQz/6L/JOGH
HSLYUbnhfVRLGyUxaaGBn6SBnDCBmTELMAkGA1UEBhMCRlIxHzAdBgNVBAoTFkNv
Z25pdGl2ZSBDcnlwdG9ncmFwaHkxEzARBgNVBAsTCkNDcnlwdG9WUE4xHjAcBgNV
BAMTFUNDcnlwdG9WUE4gUm9vdCB2MiBDQTETMBEGA1UEKRMKQ0NyeXB0b1ZQTjEf
MB0GCSqGSIb3DQEJARYQY2VydEBjY3J5cHRvLm9yZ4IUEEze40yQlf+q4ncb8Iuq
nOd/hNQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAG/F9/E6aq04M
TUNUUfAGh4MTgEXd+DnMEUOoSk30mhqbQ/a7FafHn3WREvqlnIfiE7Ysi3DGjGQX
YicooaUYdB4oUy2o853wvxTDinlt8O766VdCl3b3lgHDWYOkwGPJ4uG+xQuBm4XG
S4sEZukvE7hfxOhHQWZlkwvg+x34M3oDogWgInFQveCQnIZ9Dz3dF2eCvPtdA8IV
I4S5KtM/DLXLhRWbmuc3vVE2c6l0y1gtLeX8s1Yw2B0748cinNH7tobWJ71b1sYL
WMvX0G6uL+q67zdZmD12lnjzNWKKQHPVVD+L9yFhn1QAEExrbGzmaKUIGwZmxtD1
H48YOcx2UgeAfeUPEfVfKBVvNrG68DizlM4iCmZ5T/L7sqDtlHYnbGigbMSspNdM
IQSpsyjKtq9hQwu+3BTkyg6yiWHuS+IxHf7ngSf8hxX/3caz3YX3AlruE2mRLJ+x
AVfSxf+jfDWyAh5gogx3CrZuyBd5USab1dDllGlUUto4ozZDT9sIhRf2UV4Wvj1K
eXdWqevSgT6a6bVrtYLQqfItuhR04g3rJu7iu7sjiiE5qSgOdxBtcPy4eXbmIyo5
BCExfyI1eG4CJtnuSX/0RL/Mz9ouxXwDUKnCRh1z5BUZrsVT9hs1jR6kRk6rEmLt
8ssASXZQQRu3iDXj33uhMGfghoy6KGg=
-----END CERTIFICATE-----

@ -3,7 +3,7 @@ import binascii
from collections import OrderedDict
from django.contrib.auth.hashers import BasePasswordHasher
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
class LegacyPasswordHasher(BasePasswordHasher):

@ -3,6 +3,7 @@ from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.views.generic.base import RedirectView
import django_lcore
import django_lcore.urls
from lambdainst import views as account_views

@ -7,12 +7,10 @@ from markdown.extensions.toc import TocExtension
from django.http import HttpResponseNotFound
from django.shortcuts import render
from django.conf import settings
from django.utils.translation import ugettext as _, get_language
from django.utils.translation import gettext as _, get_language
from django import http
from django.utils.http import is_safe_url
from django.utils.translation import (
LANGUAGE_SESSION_KEY, check_for_language,
)
from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.translation import check_for_language
from django.template.loader import TemplateDoesNotExist, get_template, select_template
from django.template import Template
from django.template.response import TemplateResponse
@ -61,17 +59,24 @@ def set_lang(request):
""" django.views.i18n.set_language() with GET """
next = request.GET.get('next', request.GET.get('next'))
if not is_safe_url(url=next, allowed_hosts={request.get_host()}):
if not url_has_allowed_host_and_scheme(url=next, allowed_hosts={request.get_host()}):
next = request.META.get('HTTP_REFERER')
if not is_safe_url(url=next, allowed_hosts={request.get_host()}):
if not url_has_allowed_host_and_scheme(url=next, allowed_hosts={request.get_host()}):
next = '/'
response = http.HttpResponseRedirect(next)
lang_code = request.GET.get('lang', None)
if lang_code and check_for_language(lang_code):
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN)
response.set_cookie(
settings.LANGUAGE_COOKIE_NAME,
lang_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
secure=settings.LANGUAGE_COOKIE_SECURE,
httponly=settings.LANGUAGE_COOKIE_HTTPONLY,
samesite=settings.LANGUAGE_COOKIE_SAMESITE,
)
return response

@ -1,7 +1,7 @@
from django import template
from django.utils.html import format_html
from downloads.models import Version, Platform
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
register = template.Library()

@ -5,7 +5,7 @@ from django.contrib import admin
from django.contrib import messages
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.utils.html import format_html
import django_lcore
import lcoreapi
@ -43,14 +43,13 @@ class VPNUserInline(admin.StackedInline):
if not object.referrer:
return "-"
s = make_user_link(object.referrer) + " "
if object.referrer_used:
s += _("(rewarded)")
status = _("(rewarded)")
else:
s += _("(not rewarded)")
return s
status = _("(not rewarded)")
return format_html("{} {}", make_user_link(object.referrer), status)
referrer_a.allow_tags = True
referrer_a.short_description = _("Referrer")
def is_paid(self, object):
@ -81,7 +80,7 @@ class UserAdmin(UserAdmin):
),
)
readonly_fields = ("last_login", "date_joined", "links")
actions = (django_lcore.core_sync_action,)
actions = (django_lcore.admin.core_sync_action,)
def is_paid(self, object):
return object.vpnuser.is_paid

@ -1,7 +1,7 @@
import base64
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.utils.safestring import mark_safe

@ -2,7 +2,7 @@ import random
from datetime import timedelta
from django.db import models, IntegrityError
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.utils import timezone
from django_lcore.core import (
LcoreUserProfileMethods,
@ -65,13 +65,6 @@ class VPNUser(models.Model, BaseSubUser, LcoreUserProfileMethods):
self.referrer_used = True
self.save()
@property
def subscr_is_failing(self):
margin = timedelta(hours=24)
if self.expiration < timezone.now() + margin:
return True
return False
def lcore_sync(self):
if VPN_AUTH_STORAGE == "inst":
return

@ -1,6 +1,6 @@
import json
import uuid
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.conf import settings

@ -1,4 +1,4 @@
from django.utils.translation import ugettext, ungettext
from django.utils.translation import gettext, ngettext
from django.template import Library
from django.utils.html import avoid_wrapping
from django.utils import formats
@ -11,7 +11,7 @@ def bwformat(bps):
try:
bps = float(bps)
except (TypeError, ValueError, UnicodeDecodeError):
value = ungettext("%(bw)d bps", "%(bw)d bps", 0) % {"bw": 0}
value = ngettext("%(bw)d bps", "%(bw)d bps", 0) % {"bw": 0}
return avoid_wrapping(value)
filesize_number_format = lambda value: formats.number_format(round(value, 1), -1)
@ -23,16 +23,16 @@ def bwformat(bps):
P = 1 * 10 ** 15
if bps < K:
value = ungettext("%(size)d bps", "%(size)d bps", bps) % {"size": bps}
value = ngettext("%(size)d bps", "%(size)d bps", bps) % {"size": bps}
elif bps < M:
value = ugettext("%s Kbps") % filesize_number_format(bps / K)
value = gettext("%s Kbps") % filesize_number_format(bps / K)
elif bps < G:
value = ugettext("%s Mbps") % filesize_number_format(bps / M)
value = gettext("%s Mbps") % filesize_number_format(bps / M)
elif bps < T:
value = ugettext("%s Gbps") % filesize_number_format(bps / G)
value = gettext("%s Gbps") % filesize_number_format(bps / G)
elif bps < P:
value = ugettext("%s Tbps") % filesize_number_format(bps / T)
value = gettext("%s Tbps") % filesize_number_format(bps / T)
else:
value = ugettext("%s Pbps") % filesize_number_format(bps / P)
value = gettext("%s Pbps") % filesize_number_format(bps / P)
return avoid_wrapping(value)

@ -22,7 +22,7 @@ from django.http import (
)
from django.shortcuts import redirect, render
from django.utils import timezone
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from django.template.loader import render_to_string
from django_countries import countries
import django_lcore
@ -195,7 +195,8 @@ def index(request):
context = dict(
title=_("Account"),
ref_url=ref_url,
subscription=request.user.vpnuser.get_subscription(),
active_subscription=request.user.vpnuser.get_active_subscription(),
last_subscription=request.user.vpnuser.get_last_subscription(),
backends=sorted(ACTIVE_BACKENDS.values(), key=lambda x: x.backend_display_name),
subscr_backends=sorted(
(b for b in ACTIVE_BACKENDS.values() if b.backend_has_recurring),

@ -5,7 +5,7 @@ msgid ""
msgstr ""
"Project-Id-Version: unnamed project\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-09-14 20:19+0000\n"
"POT-Creation-Date: 2022-05-19 19:04+0000\n"
"PO-Revision-Date: 2021-09-14 22:21+0200\n"
"Last-Translator: alice <alice@ccrypto.org>\n"
"Language-Team: French <alice@ccrypto.org>\n"
@ -30,7 +30,7 @@ msgstr ""
msgid "hash"
msgstr ""
#: ccvpn/views.py:56
#: ccvpn/views.py:54
msgid "Live Chat"
msgstr "Chat Live"
@ -38,27 +38,27 @@ msgstr "Chat Live"
msgid "Download {} v{}"
msgstr "Télécharger {} v{}"
#: lambdainst/admin.py:48
#: lambdainst/admin.py:47
msgid "(rewarded)"
msgstr ""
#: lambdainst/admin.py:50
#: lambdainst/admin.py:49
msgid "(not rewarded)"
msgstr ""
#: lambdainst/admin.py:54
#: lambdainst/admin.py:53
msgid "Referrer"
msgstr ""
#: lambdainst/admin.py:60 lambdainst/admin.py:90
#: lambdainst/admin.py:59 lambdainst/admin.py:89
msgid "Is paid?"
msgstr "Est payé?"
#: lambdainst/admin.py:69
#: lambdainst/admin.py:68
msgid "Important dates"
msgstr "Dates importantes"
#: lambdainst/admin.py:71
#: lambdainst/admin.py:70
msgid "Permissions"
msgstr "Permissions"
@ -287,14 +287,6 @@ msgstr ""
msgid "Other"
msgstr "Autre"
#: templates/base_help.html:73
msgid "Advanced"
msgstr "Avancé"
#: templates/base_help.html:77
msgid "Tor"
msgstr "Tor"
#: templates/ccvpn/chat.html:9
#, python-format
msgid ""
@ -391,7 +383,28 @@ msgstr "Payez par carte, PayPal, ou 40+ cryptomonnaies."
msgid "Sign up & try for a week for free"
msgstr "Créez un compte et essayez gratuitement"
#: templates/ccvpn/index.html:74
#: templates/ccvpn/index.html:66
msgid "No CC required, 3€/month after 7 days"
msgstr "Abonnez-vous pour 3€/mois après 7 jours"
#: templates/ccvpn/index.html:71
msgid "CCrypto is a non-profit organization."
msgstr "CCrypto est une association à but non lucratif."
#: templates/ccvpn/index.html:72
msgid ""
"As such, we pledge that we will never sell your personal information, "
"exploit your trust or data, or get acquired by a company without such "
"boundaries. Your payments will go exclusively towards funding our services "
"and staff, or to other non-profits."
msgstr ""
"À ce titre, nous promettons ne jamais vendre vos données personnelles, "
"exploiter votre traffic ou votre confiance, ou laisser une entreprise sans "
"de tels principes nous racheter. Vos paiements seront exclusivement utilisés "
"pour financer notre service et rémunérer notre équipe, ou reversés à "
"d'autres associations."
#: templates/ccvpn/index.html:84
msgid "more on our infrastructure"
msgstr "plus sur notre infrastructure"
@ -477,93 +490,99 @@ msgstr "ACTIF"
msgid "INACTIVE"
msgstr "INACTIF"
#: templates/lambdainst/account.html:34 templates/lambdainst/account.html:73
#: templates/lambdainst/account.html:34 templates/lambdainst/account.html:77
msgid "Subscription"
msgstr "Abonnement"
#: templates/lambdainst/account.html:37
#, python-format
msgid ""
"<b>FAILING</b> since %(since)s. (%(backend)s)<br /> Please cancel and "
"subscribe again if you need to switch to another payment method."
msgstr ""
"<b>ERREUR</b> depuis %(since)s. (%(backend)s)<br />\n"
"Veuillez annuler et vous réabonner pour changer de méthode ou carte de "
"paiement."
#: templates/lambdainst/account.html:42
#, python-format
msgid "<b>ACTIVE</b>. Renews on %(until)s via %(backend)s."
msgstr "<b>ACTIF</b>. Renouvellement: %(until)s via %(backend)s"
#: templates/lambdainst/account.html:45
#: templates/lambdainst/account.html:40
msgid "cancel"
msgstr "annuler"
#: templates/lambdainst/account.html:53
#: templates/lambdainst/account.html:43
msgid "<b>CANCELLED</b>. You can subscribe again below."
msgstr "<b>ANNULLÉ</b>. Vous pouvez vous réabonnez plus bas."
#: templates/lambdainst/account.html:45
msgid "<b>Last payment failed</b>, likely because your card expired."
msgstr "<b>Échec du dernier paiement</b>, votre carte a probablement expirée."
#: templates/lambdainst/account.html:46
msgid "You can update your subscription below."
msgstr "Vous pouvez mettre à jour votre souscription plus bas."
#: templates/lambdainst/account.html:48
msgid "Pending"
msgstr "En attente"
#: templates/lambdainst/account.html:57
msgid "Expiration"
msgstr "Expiration"
#: templates/lambdainst/account.html:57
#: templates/lambdainst/account.html:61
#, python-format
msgid "(%(left)s left)"
msgstr "(%(left)s restant)"
#: templates/lambdainst/account.html:81
#: templates/lambdainst/account.html:85
msgid "Pay every"
msgstr "Payer tous les"
#: templates/lambdainst/account.html:83 templates/lambdainst/account.html:84
#: templates/lambdainst/account.html:85 templates/lambdainst/account.html:122
#: templates/lambdainst/account.html:123 templates/lambdainst/account.html:124
#: templates/lambdainst/account.html:87 templates/lambdainst/account.html:88
#: templates/lambdainst/account.html:89 templates/lambdainst/account.html:126
#: templates/lambdainst/account.html:127 templates/lambdainst/account.html:128
msgid "months"
msgstr "mois"
#: templates/lambdainst/account.html:90 templates/lambdainst/account.html:129
#: templates/lambdainst/account.html:94 templates/lambdainst/account.html:133
msgid "by"
msgstr "par"
#: templates/lambdainst/account.html:102
#: templates/lambdainst/account.html:106
msgid "Subscribe"
msgstr "S'abonner"
#: templates/lambdainst/account.html:104
#: templates/lambdainst/account.html:108
msgid "You can cancel the recurring payment at any time."
msgstr "Vous pouvez annuler le paiement récurrent à n'importe quel moment."
#: templates/lambdainst/account.html:111
#: templates/lambdainst/account.html:115
msgid "One-time payment"
msgstr "Paiement ponctuel"
#: templates/lambdainst/account.html:119
#: templates/lambdainst/account.html:123
msgid "Add"
msgstr "Ajouter"
#: templates/lambdainst/account.html:121
#: templates/lambdainst/account.html:125
msgid "month"
msgstr "mois"
#: templates/lambdainst/account.html:141
#: templates/lambdainst/account.html:145
msgid "Buy Now"
msgstr "Payer"
#: templates/lambdainst/account.html:143
#: templates/lambdainst/account.html:147
msgid "If you still have time, the first payment will be delayed."
msgstr "S'il vous reste du temps, le premier paiement sera reporté."
#: templates/lambdainst/account.html:150
#: templates/lambdainst/account.html:154
msgid "Coupon"
msgstr "Coupon"
#: templates/lambdainst/account.html:157
#: templates/lambdainst/account.html:161
msgid "Code"
msgstr "Code"
#: templates/lambdainst/account.html:163
#: templates/lambdainst/account.html:167
msgid "Use"
msgstr "Utiliser"
#: templates/lambdainst/account.html:165
#: templates/lambdainst/account.html:169
msgid ""
"Our coupons are alphanumeric codes that give you a fixed duration of VPN "
"access."
@ -571,11 +590,11 @@ msgstr ""
"Nos coupons sont des codes alphanumériques qui donnent une durée fixe "
"d'accès au VPN."
#: templates/lambdainst/account.html:166
#: templates/lambdainst/account.html:170
msgid "They can be single or multi use."
msgstr "À usage unique ou multiple."
#: templates/lambdainst/account.html:178
#: templates/lambdainst/account.html:182
msgid ""
"Please recommend us to your friends and on social media! We do not advertise "
"and rely on you to help us grow and improve our services."
@ -583,7 +602,7 @@ msgstr ""
"Recommandez-nous à vos amis et sur les réseaux sociaux! Nous ne faisons pas "
"de publicité et comptons sur vous pour nous aider à améliorer nos services."
#: templates/lambdainst/account.html:183
#: templates/lambdainst/account.html:187
msgid ""
"Every subscription through this link will grant you 1&nbsp;month of VPN "
"access:"
@ -1001,19 +1020,19 @@ msgstr "Importez la configuration dans WireGuard."
#: templates/pages/_install_base.html:45
msgid ""
"On Android and iOS, open the app and scan the <a href=\"/account/wireguard"
"\">QR code from your account</a>"
"On Android and iOS, open the app and scan the <a href=\"/account/"
"wireguard\">QR code from your account</a>"
msgstr ""
"Sur Android et iOS, ouvrez l'app et scannez le <a href=\"/account/wireguard"
"\">code QR disponible dans votre compte</a>"
"Sur Android et iOS, ouvrez l'app et scannez le <a href=\"/account/"
"wireguard\">code QR disponible dans votre compte</a>"
#: templates/pages/_install_base.html:51
msgid ""
"On Windows, mac OS and Linux, import a configuration file <a href=\"/account/"
"wireguard\">downloaded from your account</a>"
msgstr ""
"Sur Windows, mac OS, et Linux, importez le fichier de configuration <a href="
"\"/account/wireguard\">à télécharger dans votre compte</a>"
"Sur Windows, mac OS, et Linux, importez le fichier de configuration <a "
"href=\"/account/wireguard\">à télécharger dans votre compte</a>"
#: templates/pages/_install_base.html:61
#: templates/pages/install-android.html:31
@ -1071,8 +1090,8 @@ msgstr ""
#: templates/pages/help.html:29
msgid ""
"If you need to contact us, the fastest and most secure way is to use <a href="
"\"/tickets/\"><em>Tickets</em></a> for technical or billing issues."
"If you need to contact us, the fastest and most secure way is to use <a "
"href=\"/tickets/\"><em>Tickets</em></a> for technical or billing issues."
msgstr ""
"Si vous devez nous contacter, le moyen le plus rapide est <a href=\"/tickets/"
"\"><em>les tickets</em></a> pour les questions technique en rapport à votre "
@ -1269,8 +1288,8 @@ msgid ""
"Pick one in the <a href=\"%(url)s\">server list</a>, or <code>%(gw)s</code> "
"for a random server."
msgstr ""
"Choisissez dans la <a href=\"%(url)s\">liste de serveurs</a> ou <code>"
"%(gw)s</code> pour un serveur aléatoire."
"Choisissez dans la <a href=\"%(url)s\">liste de serveurs</a> ou "
"<code>%(gw)s</code> pour un serveur aléatoire."
#: templates/pages/install-linux.html:79
msgid "Type"
@ -1593,8 +1612,8 @@ msgstr ""
#: templates/pages/install-windows.html:84
msgid ""
"In <a href=\"/account/config\">your account</a>, download a .ovpn "
"configuration file, and copy it into <code>C:\\Program Files\\OpenVPN\\config"
"\\</code>."
"configuration file, and copy it into <code>C:\\Program "
"Files\\OpenVPN\\config\\</code>."
msgstr ""
"Dans <a href=\"/account/config\">votre compte</a>, téléchargez le fichier ."
"ovpn et copiez le dans <code>C:\\Program Files\\OpenVPN\\config\\</code>."
@ -1673,6 +1692,10 @@ msgstr ""
"Voudriez-vous nous dire pourquoi, ou laisser un retour pour nous permettre "
"d'améliorer notre service ? C'est optionel."
#: templates/payments/cancel_subscr.html:27
msgid "You do not have any active subscription to cancel."
msgstr "Vous n'avez pas d'abonnement à annuller."
#: templates/payments/order-pay.html:5 templates/payments/success.html:12
msgid "Payment"
msgstr "Paiement"

795
poetry.lock generated

File diff suppressed because it is too large Load Diff

@ -5,30 +5,31 @@ description = ""
authors = ["CCrypto <code@ccrypto.org>"]
[tool.poetry.dependencies]
python = ">=3.7,<4.0"
django = "^3.0"
python = ">=3.8,<4.0"
django = "^4.0.0"
jsonfield = "^3.1"
django_countries = "^7"
markdown = "^3.1"
requests = "^2.21"
pygal = "^2.4"
pytz = "^2021.1"
pygal = "^3.0"
pytz = "^2022.1"
stripe = "^2.24"
django-constance = {version = "^2.7",extras = ["database"]}
lcoreapi = {git = "https://git.packetimpact.net/lvpn/lcoreapi.git", tag = "v1.1.1"}
pygments = "^2.3"
psycopg2-binary = "^2.8"
python-frontmatter = "^1"
django-tinymce4-lite = "^1.7"
django-tinymce4-widget = "^6.3"
django-admin-list-filter-dropdown = "^1.0"
django-lcore = {git = "https://git.packetimpact.net/lvpn/django-lcore.git"}
django-pipayments = {git = "git@git.packetimpact.net:lvpn/django-pipayments.git", branch = "main"}
#django-pipayments = {path = "../lvpn/django-pipayments", develop=true}
celery = "^5"
django-celery-beat = "^2.0.0"
redis = "^3.5.3"
django-celery-beat = {git="https://github.com/celery/django-celery-beat",rev="10123d357567ae31f241f89d98561220887799ae"}
redis = "^4.3"
flower = "^1"
django-extensions = "^3.1.3"
tzdata = "^2022.1"
[tool.poetry.dev-dependencies]
pylint = "^2.3"

@ -731,6 +731,15 @@ ul.errorlist {
margin: auto;
}
p.home-whyus {
width: 47%;
margin: auto;
border: 2px solid #1c619a;
padding: 0.5em 1em;
background: #f8F8FF;
}
@media screen and (max-width: 80em) {
.homepage .features {
margin-left: 0;
@ -764,11 +773,20 @@ a.home-signup-button {
font-size: 1.1em;
font-weight: 600;
}
a.home-signup-button .subtext {
font-size: 0.7em;
font-weight: normal;
display: block;
opacity: 0.85;
}
@media screen and (max-width: 48em) {
.home-signup-button {
min-width: 50%;
}
p.home-whyus {
width: 90%;
}
}
@ -1236,6 +1254,9 @@ div.ticket-message-private {
.homepage h2 {
text-shadow: 0px 0px 5px #ffd99f50;
}
p.home-whyus {
background: #22222b;
}
.content-box {
background: #272727;

@ -63,9 +63,19 @@
<p class="home-signup">
<a href="/account/signup" class="home-signup-button button inverted">
{% trans 'Sign up & try for a week for free' %}
<span class="subtext">{% trans "No CC required, 3€/month after 7 days" %}</span>
</a>
</p>
<p class="home-whyus">
<b>{% trans "CCrypto is a non-profit organization." %}</b><br />
{% blocktrans trimmed %}
As such, we pledge that we will never sell your personal information, exploit your trust or data,
or get acquired by a company without such boundaries.
Your payments will go exclusively towards funding our services and staff, or to other non-profits.
{% endblocktrans %}
</p>
<div class="locations">
<object id="map" data="{% static 'img/world.svg' %}" type="image/svg+xml"></object>
{{gateway_locations|json_script:"locations-data"}}

@ -33,23 +33,26 @@
<tr>
<td>{% trans "Subscription" %}</td>
<td>
{% if subscription.status == 'active' and request.user.vpnuser.subscr_is_failing %}
{% blocktrans trimmed with since=subscription.next_renew|default:user.vpnuser.expiration|date:'Y-m-d' backend=subscription.backend.backend_verbose_name %}
<b>FAILING</b> since {{since}}. ({{backend}})<br />
Please cancel and subscribe again if you need to switch to another payment method.
{% endblocktrans %}
(<a href="{% url 'payments:cancel_subscr' %}">{% trans "cancel" %}</a>)
{% elif subscription.status == 'active' %}
{% blocktrans trimmed with until=subscription.next_renew|default:user.vpnuser.expiration|date:'Y-m-d' backend=subscription.backend.backend_verbose_name %}
{% if active_subscription %}
{% blocktrans trimmed with until=active_subscription.next_renew|default:user.vpnuser.expiration|date:'Y-m-d' backend=active_subscription.backend.backend_verbose_name %}
<b>ACTIVE</b>. Renews on {{until}} via {{backend}}.
{% endblocktrans %}
(<a href="{% url 'payments:cancel_subscr' %}">{% trans "cancel" %}</a>)
{% elif last_subscription %}
{% if last_subscription.status == 'cancelled' %}
{% trans "<b>CANCELLED</b>. You can subscribe again below." %}
{% elif last_subscription.status == 'error' %}
{% trans "<b>Last payment failed</b>, likely because your card expired." %}
{% trans "You can update your subscription below." %}
{% elif last_subscription.status == 'new' %}
{% trans "Pending" %}
{% endif %}
{% else %}
-
{% endif %}
</td>
</tr>
{% if not subscription or subscription.status != 'active' %}
{% if not active_subscription %}
<tr>
<td>{% trans "Expiration" %}</td>
<td>
@ -66,7 +69,7 @@
</div>
{% if not subscription %}
{% if not active_subscription %}
<div class="content-box account-fund">
<div class="account-payment-box account-payment-tabs">
<div class="account-payment-tab">

@ -24,7 +24,7 @@
</fieldset>
</form>
{% else %}
<p>You do not have any active subscription to cancel.</p>
<p>{% trans "You do not have any active subscription to cancel." %}</p>
{% endif %}
</div>
{% endblock %}

@ -1,7 +1,7 @@
from django.contrib import admin
from django.shortcuts import resolve_url
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.utils import formats
from .models import Ticket, TicketMessage, TicketNotifyAddress

@ -1,6 +1,6 @@
from django import forms
from .models import TicketMessage, CATEGORY_CHOICES
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class NewTicketForm(forms.Form):

@ -1,6 +1,6 @@
from django.db import models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.template.loader import get_template
from django.core.mail import send_mail

@ -3,7 +3,7 @@ from django.contrib.auth.decorators import login_required
from django.http.response import HttpResponseNotFound
from django.utils import timezone
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.utils.translation import ugettext as _
from django.utils.translation import gettext as _
from ccvpn.common import get_client_ip
from .models import Ticket, TicketMessage

Loading…
Cancel
Save