Private
Public Access
1
0

Merge branch 'release/v12.02'

This commit is contained in:
Sander Roosendaal
2020-03-30 22:07:44 +02:00
10 changed files with 147 additions and 9 deletions

View File

@@ -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()

View File

@@ -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:

View File

@@ -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)

View File

@@ -37,8 +37,15 @@
</table>
{% endfor %}
<p>
<form enctype="multipart/form-data" action="/rowers/access/share/" method="post">
{% csrf_token %}
<input name="url" value="{{ request.path }}{{ timeperiod }}/" type="hidden">
<label for="id_ndays">Number of days link is valid:</label>
<input name="ndays" id="id_ndays" type="number" step="1" value="7">
<input type="submit" value="create shareable link">
</form>
</p>
{% endblock %}

View File

@@ -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 %}
<meta property="og:image" content="http://rowsandall.com/{{ racelogo.filename|spacetohtml }}" />
<meta property="og:image:secure_url" content="https://rowsandall.com/{{ racelogo.filename |spacetohtml }}" />
<meta property="og:image:width" content="{{ racelogo.width }}" />
<meta property="og:image:height" content="{{ racelogo.height }}" />
{% endblock %}
{% block image_src %}
<link rel="image_src" href="/{{ racelogo.filename |spacetohtml }}" />
{% endblock %}
{% endif %}
{% block main %}
<h1>Sharing link created.</h1>
<p>The link is <a href="{{ base_url }}{% url 'sharedPage' key.pk %}">{{ base_url }}{% url 'sharedPage' key.pk %}</a>. It will be valid until {{ key.expiration_date|date:"l, N dS" }} at {{ key.expiration_date|time:"g:i a" }}.</p>
{% endblock %}
{% block sidebar %}
{% include 'menu_racing.html' %}
{% endblock %}

View File

@@ -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

View File

@@ -721,6 +721,8 @@ urlpatterns = [
name='plannedsession_comment_view'),
re_path(r'^sessions/print/user/(?P<userid>\d+)/$',views.plannedsessions_print_view,
name='plannedsessions_print_view'),
re_path(r'^sessions/print/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\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<userid>\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<key>\w+)/$', views.sharedPage, name="sharedPage"),
]
if settings.DEBUG:

View File

@@ -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':

View File

@@ -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(

View File

@@ -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 doesnt 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")