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 %}
-
-
+
+
+
{% 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':