Private
Public Access
1
0

Merge branch 'release/v21.2.2'

This commit is contained in:
2024-05-23 13:52:17 +02:00
11 changed files with 106 additions and 159 deletions

1
.gitignore vendored
View File

@@ -69,4 +69,5 @@ config.yaml
/py2/
/py38/
/py39/
/py39b/
/django2/

View File

@@ -18,6 +18,8 @@ from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.contrib.admin.widgets import AdminDateWidget
from django.forms.widgets import SelectDateWidget, HiddenInput
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV3
from django.utils import timezone, translation
from django.forms import ModelForm, Select
@@ -235,11 +237,16 @@ class SearchForm(forms.Form):
# simple form for Contact page. Sends email to info@rowsandall.com
class EmailForm(forms.Form):
firstname = forms.CharField(max_length=255)
lastname = forms.CharField(max_length=255)
firstname = forms.CharField(max_length=255, label="First Name")
lastname = forms.CharField(max_length=255, required=False, label="Last Name")
email = forms.EmailField()
subject = forms.CharField(max_length=255)
message = forms.CharField(widget=forms.Textarea())
captcha = ReCaptchaField(widget=ReCaptchaV3(
attrs={
'required_score': 0.85,
}
))
disqualificationreasons = (

View File

@@ -3700,7 +3700,7 @@ class Workout(models.Model):
elements = dict(
date = self.date.strftime('%Y-%m-%d'),
name = self.name,
distance = str(self.distance),
distance = str(self.distance)+'m',
ownerfirst = self.user.user.first_name,
ownerlast = self.user.user.last_name,
duration = self.duration.strftime("%H:%M:%S"),
@@ -3727,7 +3727,7 @@ class Workout(models.Model):
if self.workouttype not in ['water','rower']:
try:
stri = u'{date} {name} {distance}m {duration} {workouttype} {ownerfirst} {ownerlast}'.format(
stri = u'{date} {name} {distance} {duration} {workouttype} {ownerfirst} {ownerlast}'.format(
**elements
)
except ValueError:
@@ -3736,7 +3736,7 @@ class Workout(models.Model):
return "No workout"
else:
try:
stri = u'{date} {name} {distance}m {duration} {workouttype} {boattype} {ownerfirst} {ownerlast}'.format(
stri = u'{date} {name} {distance} {duration} {workouttype} {boattype} {ownerfirst} {ownerlast}'.format(
**elements
)
except (ValueError, AttributeError):

View File

@@ -1,136 +1,80 @@
{% extends "newbase.html" %}
{% block title %}Contact Us{% endblock title %}
{% block main %}
<h1>Contact us through email</h1>
<ul class="main-content">
<li class="grid_2">
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form method="post" action="/rowers/email/send/" id="contactform">{% csrf_token %}
<p>
<table>
<tr><td>
<label>Name <span class="required">*</span></label>
<span class="span">
</td><td>
<input name= "firstname" class="inputtext" maxlength="255" size="12" />
<label>First</label>
</td></tr>
<tr><td>
</span>
<span class="span">
</td><td>
<input name= "lastname" class="inputtext" maxlength="255" size="18" />
<label>Last</label>
</span>
</td></tr>
<tr><td>
<label>Email Address <span class="required">*</span></label>
</td><td>
<input name="email" class="inputtext" type="text" maxlength="255" size="35" />
</td></tr>
<tr><td>
<label>Subject <span class="required">*</span></label>
</td><td>
<input name="subject" class="inputtext" type="text" maxlength="255" size="45" />
</td></tr>
</table>
<table>
<input type="hidden" name="g-recaptcha-response" id='recaptcha'>
</td></tr>
<tr><td>
<label>Message <span class="required">*</span></label>
</td><td>
<textarea name="message" class="inputtextarea" rows="11" cols="45"></textarea>
</td></tr>
<tr><td>
<input type="submit" name="submitform" value="Send Message" />
</td></tr>
</table>
</p>
</form>
<li class="grid_2">
<h1>Contact us through email</h1>
{% if form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form method="post" action="/rowers/email/send/" id="contactform">{% csrf_token %}
<p>
<table>
{{ form.as_table }}
</table>
<input type="submit" name="submitform" value="Send Message" />
</p>
</form>
</li>
<li class="grid_2">
<h1>Bug reporting, feature requests</h1>
<p>
Bug reports and feature requests can be done through our BitBucket page. Please check on the following link if your bug or issue is a known one. Feel free to file any feature request.
<ul>
<li><a href="https://bitbucket.org/sanderroosendaal/rowsandall/issues">BitBucket Issue list (click here to go report an issue or request a feature)</a></li>
</ul>
</p>
<h1>Bug reporting, feature requests</h1>
<p>
Bug reports and feature requests can be done through our BitBucket page. Please check on the following link if your bug or issue is a known one. Feel free to file any feature request.
<ul>
<li><a href="https://bitbucket.org/sanderroosendaal/rowsandall/issues">BitBucket Issue list (click here to go report an issue or request a feature)</a></li>
</ul>
</p>
</li>
<li class="grid_2">
<h1>Facebook Group</h1>
<h1>Facebook Group</h1>
<p>We run a facebook group where you can post questions and report problems,
especially if you think the wider user community benefits from the answers.</p>
<ul>
<li><a href="https://www.facebook.com/groups/rowsandall/">https://www.facebook.com/groups/rowsandall/</a></li>
</ul>
</li>
<p>We run a facebook group where you can post questions and report problems,
especially if you think the wider user community benefits from the answers.</p>
<ul>
<li><a href="https://www.facebook.com/groups/rowsandall/">https://www.facebook.com/groups/rowsandall/</a></li>
</ul>
</li>
<li class="grid_2">
<h1>Twitter</h1>
<p>You can also check me on Twitter:
<ul>
<li><a href="https://twitter.com/rowsandall">https://twitter.com/rowsandall</a>
</ul>
When the site is down, this is the appropriate channel to look for apologies, updates, and offer help.
</p>
</li>
<li class="grid_2">
<h1>Twitter</h1>
<li class="grid_2">
<h1>Rowsandall s.r.o.</h1>
<p><strong>Rowsandall s.r.o.</strong><br />
Nov&eacute; sady 988/2<br />
602 00 Brno<br />
Czech Republic<br />
IČ: 070 48 572<br />
DIČ: CZ 070 48 572 (Nejsme plátce DPH)<br />
Datová schránka: 7897syr<br />
Email: <a href="mailto:info@rowsandall.com">info@rowsandall.com</a><br />
The company is registered in the business register at the
Regional Court in Brno (Společnost je zapsána v obchodním rejstříku vedeném u Krajského soudu v Brně, oddíl C, vložka 105845)<br/>
</p>
</li>
</ul>
{% endblock %}
<p>You can also check me on Twitter:
<ul>
<li><a href="https://twitter.com/rowsandall">https://twitter.com/rowsandall</a>
</ul>
When the site is down, this is the appropriate channel to look for apologies, updates, and offer help.
</p>
</li>
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
<li class="grid_2">
<h1>Rowsandall s.r.o.</h1>
<p><strong>Rowsandall s.r.o.</strong><br />
Nov&eacute; sady 988/2<br />
602 00 Brno<br />
Czech Republic<br />
IČ: 070 48 572<br />
DIČ: CZ 070 48 572 (Nejsme plátce DPH)<br />
Datová schránka: 7897syr<br />
Email: <a href="mailto:info@rowsandall.com">info@rowsandall.com</a><br />
The company is registered in the business register at the
Regional Court in Brno (Společnost je zapsána v obchodním rejstříku vedeném u Krajského soudu v Brně, oddíl C, vložka 105845)<br/>
</p>
</li>
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_help.html' %}
{% endblock %}
{% block scripts %}
<script src="https://www.google.com/recaptcha/api.js?render=6LdRtMwUAAAAAGcKcFc28pGvmEb1wwDY27i0AX8B"></script>
<script>
// 3
grecaptcha.ready(function() {
// 4
$('#contactform').submit(function(e){
var form = this;
// 5
e.preventDefault()
grecaptcha.execute('6LdRtMwUAAAAAGcKcFc28pGvmEb1wwDY27i0AX8B', {action: 'contactform'}).then(function(token) {
// 6
$('#recaptcha').val(token)
// 7
form.submit()
});
})
});
</script>
{% endblock %}

View File

@@ -42,12 +42,7 @@ class ListWorkoutTest(TestCase):
rowerplan='coach')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(len(workouttypes), user=self.r)
i = 0
for workouttype in workouttypes:
self.user_workouts[i].workouttype = workouttype[0]
self.user_workouts[i].save()
i = i+1
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
self.factory = RequestFactory()
self.password = faker.word()

View File

@@ -6,6 +6,7 @@ from __future__ import unicode_literals
from .statements import *
from django.http import Http404
from django_recaptcha.client import RecaptchaResponse
from rowers.views import get_workout
@@ -69,7 +70,10 @@ class SimpleViewTest(TestCase):
response = self.c.get(url)
self.assertIn(response.status_code, [403, 404])
def test_sendmail(self):
@patch("django_recaptcha.fields.client.submit")
def test_sendmail(self, mocked_submit):
mocked_submit.return_value = RecaptchaResponse(is_valid=True, extra_data={"score":0.95})
login = self.c.login(username=self.u.username, password=self.password)
self.assertTrue(login)
@@ -80,18 +84,20 @@ class SimpleViewTest(TestCase):
'lastname': 'Doe',
'email': 'roosendaalsander@gmail.com',
'subject': 'testing',
'botcheck': True,
'captcha': 'sdsdsdsdsdsdss',
'g-recaptcha-response': 'PASSED',
'message': faker.text()}
form = EmailForm(form_data)
self.assertTrue(form.is_valid())
response = self.c.post(url, form_data, follow=True)
self.assertEqual(response.status_code, 200)
self.assertRedirects(response,
expected_url='/rowers/email/',
expected_url='/rowers/email/thankyou/',
status_code=302, target_status_code=200)
def test_getworkout(self):

Binary file not shown.

View File

@@ -134,7 +134,7 @@
175,220,rower_favoritecharts_view,See favorite charts,TRUE,302,pro,200,302,pro,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
176,222,workout_workflow_config2_view,configure workflow,TRUE,302,basic,200,302,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,FALSE,FALSE,
177,224,workflow_default_view,resets workflow to default,TRUE,302,basic,302,302,FALSE,403,403,FALSE,302,403,FALSE,FALSE,FALSE,TRUE,TRUE,
178,225,sendmail,feedback form,TRUE,302,basic,302,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
178,225,sendmail,feedback form,TRUE,200,basic,200,302,FALSE,200,302,FALSE,200,302,FALSE,FALSE,FALSE,TRUE,TRUE,
180,232,laboratory_view,lab,TRUE,302,basic,200,302,basic,403,403,coach,200,403,FALSE,TRUE,FALSE,TRUE,TRUE,
181,233,errormessage_view,not used,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
182,237,payment_confirm_view,confirm payment,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE,
1 id view function anonymous anonymous_response own own_response own_nonperm member member_response member_nonperm coachee coachee_response coachee_nonperm is_staff userid workoutid dotest realtest kwargs
134 175 220 rower_favoritecharts_view See favorite charts TRUE 302 pro 200 302 pro 403 403 coach 200 403 FALSE TRUE FALSE TRUE TRUE
135 176 222 workout_workflow_config2_view configure workflow TRUE 302 basic 200 302 basic 403 403 coach 200 403 FALSE TRUE FALSE FALSE FALSE
136 177 224 workflow_default_view resets workflow to default TRUE 302 basic 302 302 FALSE 403 403 FALSE 302 403 FALSE FALSE FALSE TRUE TRUE
137 178 225 sendmail feedback form TRUE 302 200 basic 302 200 302 FALSE 200 302 FALSE 200 302 FALSE FALSE FALSE TRUE TRUE
138 180 232 laboratory_view lab TRUE 302 basic 200 302 basic 403 403 coach 200 403 FALSE TRUE FALSE TRUE TRUE
139 181 233 errormessage_view not used TRUE 200 basic 200 302 basic 200 302 coach 200 302 FALSE FALSE FALSE FALSE FALSE
140 182 237 payment_confirm_view confirm payment TRUE 200 basic 200 302 basic 200 302 coach 200 302 FALSE FALSE FALSE FALSE FALSE

View File

@@ -763,7 +763,8 @@ urlpatterns = [
re_path(r'^email/send/$', views.sendmail, name='sendmail'),
re_path(r'^email/thankyou/$',
TemplateView.as_view(template_name='thankyou.html'), name='thankyou'),
re_path(r'^email/$', TemplateView.as_view(template_name='email.html'), name='email'),
re_path(r'^email/$', views.sendmail, name='sendmail'),
# TemplateView.as_view(template_name='email.html'), name='email'),
re_path(r'^about', TemplateView.as_view(
template_name='about_us.html'), name='about'),
re_path(r'^brochure/$', TemplateView.as_view(template_name='brochure.html'),

View File

@@ -1271,23 +1271,10 @@ def add_defaultfavorites(r):
# Shows email form and sends it if submitted
def sendmail(request):
form = EmailForm()
if request.method == 'POST':
# test recaptcha
response_string = request.POST.get('g-recaptcha-response')
# replace below with settings
recaptcha_secret = RECAPTCHA_SITE_SECRET
url = 'https://www.google.com/recaptcha/api/siteverify'
data = {
'secret': recaptcha_secret,
'response': response_string,
}
response = requests.post(url, data=data, verify=True)
success = False
if response.status_code == 200:
success = response.json().get('success')
form = EmailForm(request.POST)
if form.is_valid() and success: # pragma: no cover
if form.is_valid(): # pragma: no cover
firstname = form.cleaned_data['firstname']
lastname = form.cleaned_data['lastname']
email = form.cleaned_data['email']
@@ -1314,14 +1301,15 @@ def sendmail(request):
request, "Something went wrong trying to send the form")
return HttpResponseRedirect('/rowers/email/thankyou/')
else:
if not success:
messages.error(request, 'Bots are not welcome')
else: # pragma: no cover
messages.error(
request, 'Something went wrong. Please try again')
return HttpResponseRedirect('/rowers/email/')
else:
return HttpResponseRedirect('/rowers/email/')
if "captcha" in form.errors:
messages.error(request,"Bots are not welcome")
return HttpResponseRedirect(reverse("sendmail"))
return render(request,'email.html',
{
'form': form
})
def keyvalue_get_default(key, options, def_options): # pragma: no cover

View File

@@ -82,6 +82,7 @@ INSTALLED_APPS = [
'rules',
'taggit',
'boatmovers',
'django_recaptcha',
]
AUTHENTICATION_BACKENDS = (
@@ -611,9 +612,13 @@ except KeyError:
try:
RECAPTCHA_SITE_KEY = CFG['recaptcha_site_key']
RECAPTCHA_SITE_SECRET = CFG['recaptcha_site_secret']
RECAPTCHA_PUBLIC_KEY = CFG['recaptcha_site_key']
RECAPTCHA_PRIVATE_KEY = CFG['recaptcha_site_secret']
except KeyError: # pragma: no cover
RECAPTCHA_SITE_KEY = ''
RECAPTCHA_SITE_SECRET = ''
RECAPTCHA_PUBLIC_KEY = ''
RECAPTCHA_PRIVATE_KEY = ''
GEOIP_PATH = STATIC_ROOT