From db4d16e8d9cb0bf24a21b730c1920aa20820626f Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 30 Mar 2020 21:56:04 +0200 Subject: [PATCH 1/2] working but not passing test_analysis --- rowers/models.py | 13 +++++ rowers/plannedsessions.py | 6 ++- rowers/rower_rules.py | 3 ++ rowers/templates/plannedsessions_print.html | 11 +++- rowers/templates/share.html | 42 +++++++++++++++ rowers/templatetags/rowerfilters.py | 7 +++ rowers/urls.py | 4 ++ rowers/views/planviews.py | 8 +-- rowers/views/statements.py | 57 ++++++++++++++++++++- 9 files changed, 143 insertions(+), 8 deletions(-) create mode 100644 rowers/templates/share.html diff --git a/rowers/models.py b/rowers/models.py index 2b6a9ac1..d0968637 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -3730,3 +3730,16 @@ class VideoAnalysis(models.Model): def __str__(self): return self.name + + + +class ShareKey(models.Model): + location = models.TextField() # absolute path + token = models.CharField(max_length=40, primary_key=True) + creation_date = models.DateTimeField(auto_now_add=True) + expiration_seconds = models.BigIntegerField() + + + @property + def expired(self): + return self.creation_date + datetime.timedelta(self.expiration_seconds) < timezone.now() diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 1064db19..978faa69 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -713,8 +713,10 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring='', if not timeperiod: timeperiod = defaulttimeperiod - startdatestring = request.GET.get('startdate') - enddatestring = request.GET.get('enddate') + if startdatestring == '': + startdatestring = request.GET.get('startdate') + if enddatestring == '': + enddatestring = request.GET.get('enddate') if startdatestring and enddatestring: try: diff --git a/rowers/rower_rules.py b/rowers/rower_rules.py index f26287eb..ff4e5ed1 100644 --- a/rowers/rower_rules.py +++ b/rowers/rower_rules.py @@ -195,6 +195,9 @@ def can_add_session(user): @rules.predicate def can_plan(user): + if user.is_anonymous: + return False + return user.rower.rowerplan in ['plan','coach','freecoach'] # checks if rower is coach of user (or is user himself) diff --git a/rowers/templates/plannedsessions_print.html b/rowers/templates/plannedsessions_print.html index f09bb13e..22f7ddc3 100644 --- a/rowers/templates/plannedsessions_print.html +++ b/rowers/templates/plannedsessions_print.html @@ -37,8 +37,15 @@ {% endfor %} - - +

+

+ {% csrf_token %} + + + + +
+

{% endblock %} diff --git a/rowers/templates/share.html b/rowers/templates/share.html new file mode 100644 index 00000000..0e758cf6 --- /dev/null +++ b/rowers/templates/share.html @@ -0,0 +1,42 @@ +{% extends "newbase.html" %} +{% load staticfiles %} +{% load rowerfilters %} +{% load leaflet_tags %} + +{% block meta %} +{% leaflet_js %} +{% leaflet_css %} +{% endblock %} + +{% block title %}Share Page{% endblock %} + +{% block scripts %} +{% include "monitorjobs.html" %} +{% endblock %} + +{% block og_title %}{{ race.name }}{% endblock %} +{% block description %}Virtual Rowing Race {{ race.name }}{% endblock %} + +{% if racelogo %} +{% block og_image %} + + + + +{% endblock %} +{% block image_src %} + +{% endblock %} +{% endif %} + +{% block main %} + + +

Sharing link created.

+

The link is {{ base_url }}{% url 'sharedPage' key.pk %}. It will be valid until {{ key.expiration_date|date:"l, N dS" }} at {{ key.expiration_date|time:"g:i a" }}.

+ +{% endblock %} + +{% block sidebar %} +{% include 'menu_racing.html' %} +{% endblock %} diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index 60b02cbd..615dc989 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -56,6 +56,13 @@ def sigdig(value, digits = 3): fmtstr = "%.0f" return fmtstr % (round(value, places)) +@register.filter +def pickle(dc): + s = dict() + for key, value in dc.items(): + s[key] = value + + return s @register.filter(is_safe=True, needs_autoescape=True) @stringfilter diff --git a/rowers/urls.py b/rowers/urls.py index 44d4748a..a616e32c 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -721,6 +721,8 @@ urlpatterns = [ name='plannedsession_comment_view'), re_path(r'^sessions/print/user/(?P\d+)/$',views.plannedsessions_print_view, name='plannedsessions_print_view'), + re_path(r'^sessions/print/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.plannedsessions_print_view, + name='plannedsessions_print_view'), re_path(r'^sessions/sendcalendar/$',views.plannedsessions_icsemail_view, name='plannedsessions_coach_icsemail_view'), re_path(r'^sessions/sendcalendar/user/(?P\d+)/$',views.plannedsessions_icsemail_view, @@ -747,6 +749,8 @@ urlpatterns = [ # URLS to be created re_path(r'^help/$',TemplateView.as_view(template_name='help.html'), name='help'), re_path(r'^workout/api/upload/',views.workout_upload_api,name='workout_upload_api'), + re_path(r'^access/share/$',views.createShareURL, name="sharedURL"), + re_path(r'^access/(?P\w+)/$', views.sharedPage, name="sharedPage"), ] if settings.DEBUG: diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index f7613d76..19b0a183 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -1183,14 +1183,16 @@ def plannedsessions_view(request, 'unmatchedworkouts':unmatchedworkouts, }) -@login_required() -def plannedsessions_print_view(request,userid=0): +@allow_shares +#@login_required() +def plannedsessions_print_view(request,userid=0,startdatestring='',enddatestring=''): r = getrequestplanrower(request,userid=userid) - startdate,enddate = get_dates_timeperiod(request) + startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring, + enddatestring=enddatestring) try: trainingplan = TrainingPlan.objects.filter( diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 1e912a3a..01599ae1 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -83,6 +83,7 @@ from django.core.exceptions import PermissionDenied from django.template import RequestContext from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.conf import settings +from django.urls import resolve from django.utils.datastructures import MultiValueDictKeyError from django.utils import timezone,translation from django.core.mail import send_mail, BadHeaderError @@ -112,7 +113,7 @@ from rowers.models import ( RaceLogo,RowerBillingAddressForm,PaidPlan, AlertEditForm, ConditionEditForm, PlannedSessionComment,CoachRequest,CoachOffer, - VideoAnalysis + VideoAnalysis,ShareKey, ) from rowers.models import ( RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm, @@ -251,11 +252,62 @@ from rq.exceptions import NoSuchJobError from rq.registry import StartedJobRegistry from rq import Queue,cancel_job +from django.utils.crypto import get_random_string + from django.core.cache import cache from django_mailbox.models import Message,Mailbox,MessageAttachment from rules.contrib.views import permission_required, objectgetter +# creating shareable views +def allow_shares(view_func): + def sharify(request, *args, **kwargs): + shared = kwargs.get('__shared', None) + if shared is not None: + del kwargs["__shared"] + request.session['shared'] = True + return view_func(request, *args, **kwargs) + else: return login_required(view_func)(request, *args, **kwargs) + return sharify + +class SharifyError(Exception): + pass + +def sharedPage(request, key): + try: + try: + shareKey = ShareKey.objects.get(pk=key) + except: + raise SharifyError + if shareKey.expired: + raise SharifyError + func, args, kwargs = resolve(shareKey.location) + kwargs["__shared"] = True + return func(request, *args, **kwargs) + except SharifyError: + raise Http404 # or add a more detailed error page. This either means that the key doesn’t exist or is expired. + +def createShareURL(request): + if request.method == 'POST': + url = request.POST['url'] + ndays = int(request.POST['ndays']) + key = ShareKey.objects.create(pk=get_random_string(40), + expiration_seconds=60*60*24*ndays, + location = url) + key.save() + return render(request, 'share.html', {"key":key}) + else: + raise Http404 + +def createShareModel(request, model_id): + task = MyModel.objects.get(pk=model_id) + key = ShareKey.objects.create(pk=get_random_string(40), + expiration_seconds=60*60*24, # 1 day + location = task.get_absolute_url(), + ) + key.save() + return render(request, 'share.html', {"key":key}) + # Utility to get stroke data in a JSON response class JSONResponse(HttpResponse): def __init__(self, data, **kwargs): @@ -439,6 +491,9 @@ def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False): except Rower.DoesNotExist: raise Http404("Rower doesn't exist") + if 'shared' in request.session and request.session['shared']: + return r + if r.user != request.user and not can_plan_user(request.user,r ): request.session['rowerid'] = r.id raise PermissionDenied("You have no access to this user") From b290aab7b6bb38a6eed08094351c3f849efdc552 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 30 Mar 2020 22:06:56 +0200 Subject: [PATCH 2/2] bla --- rowers/views/analysisviews.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py index bc6e5e60..717cc709 100644 --- a/rowers/views/analysisviews.py +++ b/rowers/views/analysisviews.py @@ -319,7 +319,10 @@ def trendflexdata(workouts, options,userid=0): today = datetime.date.today() - datadf['days ago'] = list(map(lambda x : x.days, datadf.date - today)) + try: + datadf['days ago'] = list(map(lambda x : x.days, datadf.date - today)) + except TypeError: + datadf['days ago'] = 0 if groupby != 'date':