Private
Public Access
1
0

Merge branch 'release/v22.1.0'

This commit is contained in:
2024-06-01 17:39:08 +02:00
10 changed files with 94 additions and 6 deletions
+14
View File
@@ -0,0 +1,14 @@
from rules.permissions import ObjectPermissionBackend
from rowers.models import User
class MyObjectPermissionBackend(ObjectPermissionBackend):
def user_can_authenticate(self, user):
return getattr(user, "is_active", True)
def get_user(self, user_id):
try:
user = User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
return user if self.user_can_authenticate(user) else None
+10
View File
@@ -1213,6 +1213,7 @@ class ForceCurveMultipleCompareForm(forms.Form):
bulkactions = ( bulkactions = (
('remove','remove'), ('remove','remove'),
('export','export'), ('export','export'),
('rower assign','rower assign'),
) )
destinations = ( destinations = (
('C2','C2'), ('C2','C2'),
@@ -1230,6 +1231,15 @@ class ExportChoices(forms.Form):
choices=destinations, label='Destination', required=False, initial='strava' choices=destinations, label='Destination', required=False, initial='strava'
) )
class AssignChoices(forms.Form):
remove_workout = forms.BooleanField(initial=False, required=False)
destination = forms.ModelMultipleChoiceField(label='Rowers', required=False,
queryset=Rower.objects.filter(), widget=forms.CheckboxSelectMultiple())
def __init__(self, *args, **kwargs):
super(AssignChoices, self).__init__(*args, **kwargs)
self.fields['destination'].queryset = Rower.objects.filter()
class WorkoutMultipleCompareForm(forms.Form): class WorkoutMultipleCompareForm(forms.Form):
workouts = forms.ModelMultipleChoiceField( workouts = forms.ModelMultipleChoiceField(
queryset=Workout.objects.filter(), queryset=Workout.objects.filter(),
+44
View File
@@ -324,6 +324,50 @@ def summaryfromsplitdata(splitdata, data, filename, sep='|', workouttype='rower'
return sums, sa, results return sums, sa, results
@app.task
def handle_assignworkouts(workouts, rowers, remove_workout, debug=False, **kwargs):
for workout in workouts:
uploadoptions = {
'secret': UPLOAD_SERVICE_SECRET,
'title': workout.name,
'boattype': workout.boattype,
'workouttype': workout.workouttype,
'inboard': workout.inboard,
'oarlength': workout.oarlength,
'summary': workout.summary,
'elapsedTime': 3600.*workout.duration.hour+60*workout.duration.minute+workout.duration.second,
'totalDistance': workout.distance,
'useImpeller': workout.impeller,
'seatNumber': workout.seatnumber,
'boatName': workout.boatname,
'portStarboard': workout.empowerside,
}
for rower in rowers:
failed = False
csvfilename = 'media/{code}.csv'.format(code=uuid4().hex[:16])
try:
with open(csvfilename,'wb') as f:
shutil.copy(workout.csvfilename,csvfilename)
except FileNotFoundError:
try:
with open(csvfilename,'wb') as f:
csvfilename = csvfilename+'.gz'
shutil.copy(workout.csvfilename+'.gz', csvfilename)
except:
failed = True
if not failed:
uploadoptions['user'] = rower.user.id
uploadoptions['file'] = csvfilename
session = requests.session()
newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'}
session.headers.update(newHeaders)
response = session.post(UPLOAD_SERVICE_URL, json=uploadoptions)
print(response.text)
if remove_workout:
workout.delete()
return 1
@app.task @app.task
def handle_post_workout_api(uploadoptions, debug=False, **kwargs): # pragma: no cover def handle_post_workout_api(uploadoptions, debug=False, **kwargs): # pragma: no cover
session = requests.session() session = requests.session()
@@ -23,6 +23,11 @@
{{ exportchoice.as_p }} {{ exportchoice.as_p }}
</p> </p>
{% endif %} {% endif %}
{% if action == 'rower assign' %}
<p>
{{ assignchoices.as_p }}
</p>
{% endif %}
</li> </li>
<li class="grid_2"> <li class="grid_2">
{% csrf_token %} {% csrf_token %}
+1 -1
View File
@@ -770,7 +770,7 @@ def team_rowers(user): # pragma: no cover
teams = Team.objects.filter(manager=user) teams = Team.objects.filter(manager=user)
members = Rower.objects.filter( members = Rower.objects.filter(
team__in=teams).distinct().order_by( team__in=teams).distinct().order_by(
"user__last_name", "user__last_name").exclude( "user__last_name", "user__first_name").exclude(
rowerplan='freecoach') rowerplan='freecoach')
return members return members
except TypeError: except TypeError:
Binary file not shown.
+2 -2
View File
@@ -2,7 +2,7 @@ from django.utils.encoding import force_bytes, force_str
from rowers.tokens import account_activation_token from rowers.tokens import account_activation_token
from django.contrib.sites.shortcuts import get_current_site from django.contrib.sites.shortcuts import get_current_site
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.contrib.auth.backends import ModelBackend
from rowers.views.statements import * from rowers.views.statements import *
from django.core.mail import EmailMessage from django.core.mail import EmailMessage
@@ -817,7 +817,7 @@ def useractivate(request, uidb64, token): # pragma: no cover
messages.info( messages.info(
request, 'Thank you for your email confirmation. You are now signed in to your account.') request, 'Thank you for your email confirmation. You are now signed in to your account.')
login(request, user, backend=settings.AUTHENTICATION_BACKENDS[0]) login(request, user, backend='django.contrib.auth.backends.ModelBackend')
url = reverse('workouts_view') url = reverse('workouts_view')
# if user.rower.rowerplan == 'freecoach': # if user.rower.rowerplan == 'freecoach':
# url+='?next=/rowers/me/teams' # url+='?next=/rowers/me/teams'
+3 -1
View File
@@ -116,7 +116,8 @@ from rowers.forms import (
StravaChartForm, FitnessFitForm, PerformanceManagerForm, StravaChartForm, FitnessFitForm, PerformanceManagerForm,
TrainingPlanBillingForm, InstantPlanSelectForm, TrainingPlanBillingForm, InstantPlanSelectForm,
TrainingZonesForm, InstrokeForm, InStrokeMultipleCompareForm, TrainingZonesForm, InstrokeForm, InStrokeMultipleCompareForm,
ForceCurveMultipleCompareForm, PlanByRscoreForm ForceCurveMultipleCompareForm, PlanByRscoreForm,
AssignChoices,
) )
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
@@ -267,6 +268,7 @@ from rowers.tasks import (
handle_send_email_instantplan_notification, handle_send_email_instantplan_notification,
handle_nk_async_workout, handle_nk_async_workout,
check_tp_workout_id, check_tp_workout_id,
handle_assignworkouts,
) )
from scipy.signal import savgol_filter from scipy.signal import savgol_filter
+13
View File
@@ -2031,6 +2031,12 @@ def workouts_bulk_actions(request):
'Export to {destination} of workout {id} failed'.format( 'Export to {destination} of workout {id} failed'.format(
id=encoder.encode_hex(w.id), id=encoder.encode_hex(w.id),
destination=destination)) destination=destination))
elif action == 'rower assign':
assignchoices = AssignChoices(request.POST)
if assignchoices.is_valid():
remove_workout = assignchoices.cleaned_data['remove_workout']
rowers = assignchoices.cleaned_data['destination']
_ = myqueue(queuehigh, handle_assignworkouts, workouts, rowers, remove_workout)
url = reverse('workouts_view') url = reverse('workouts_view')
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
else: # pragma: no cover else: # pragma: no cover
@@ -2041,6 +2047,12 @@ def workouts_bulk_actions(request):
exportchoice = ExportChoices() exportchoice = ExportChoices()
actionform = WorkoutBulkActions() actionform = WorkoutBulkActions()
actionform.fields["action"].initial = action actionform.fields["action"].initial = action
assignchoices = AssignChoices()
teams = Team.objects.filter(manager=request.user)
assignchoices.fields["destination"].queryset = Rower.objects.filter(
team__in=teams
).distinct().order_by("user__last_name", "user__first_name").exclude(rowerplan='freecoach')
assignchoices.fields["destination"].initial = []
form = WorkoutMultipleCompareForm() form = WorkoutMultipleCompareForm()
form.fields["workouts"].queryset = Workout.objects.filter(id__in=[w.id for w in workouts]) form.fields["workouts"].queryset = Workout.objects.filter(id__in=[w.id for w in workouts])
form.fields["workouts"].initial = workouts form.fields["workouts"].initial = workouts
@@ -2049,6 +2061,7 @@ def workouts_bulk_actions(request):
{'action':action, {'action':action,
'exportchoice':exportchoice, 'exportchoice':exportchoice,
'actionform':actionform, 'actionform':actionform,
'assignchoices': assignchoices,
'form':form, 'form':form,
'workouts':workouts}) 'workouts':workouts})
+2 -2
View File
@@ -90,10 +90,10 @@ INSTALLED_APPS = [
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
#'oauth2_provider.backends.OAuth2Backend', #'oauth2_provider.backends.OAuth2Backend',
# Uncomment following if you want to access the admin # Uncomment following if you want to access the admin
'rules.permissions.ObjectPermissionBackend',
'django.contrib.auth.backends.ModelBackend',
'django.contrib.auth.backends.ModelBackend', 'django.contrib.auth.backends.ModelBackend',
'django.contrib.auth.backends.RemoteUserBackend', 'django.contrib.auth.backends.RemoteUserBackend',
'rowers.backends.MyObjectPermissionBackend',
#'rules.permissions.ObjectPermissionBackend',
) )
MIDDLEWARE = [ MIDDLEWARE = [