From db7c224beb2c47b4d7593b35784ed1430d69b1d7 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 10 Dec 2019 17:33:00 +0100 Subject: [PATCH 01/57] google gauge working --- rowers/templates/embedded_video.html | 17 +++-- static/js/videogauges.js | 92 +++++++++++----------------- 2 files changed, 48 insertions(+), 61 deletions(-) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 69641929..e957f6fd 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -29,6 +29,8 @@ {% block meta %} {% leaflet_js %} {% leaflet_css %} + + - - {% endlanguage %} {% endblock %} diff --git a/static/js/videogauges.js b/static/js/videogauges.js index f6c068e4..0b6395d7 100644 --- a/static/js/videogauges.js +++ b/static/js/videogauges.js @@ -1,60 +1,42 @@ -// var opts = { -// lines: 12, -// angle: 0.15, -// lineWidth: 0.44, -// pointer: { -// length: 0.9, -// strokeWidth: 0.035, -// color: '#000000' -// }, -// limitMax: 'false', -// // percentColors: [[0.0, "#a9d70b" ], [0.50, "#a9d70b"], [1.0, "#a9d70b"]], // !!!! -// strokeColor: '#E0E0E0', -// generateGradient: true -// }; -// var target = document.getElementById('angles'); -// var gauge = new Gauge(target).setOptions(opts); -// gauge.maxValue = 90; -// gauge.minValue = -90; -// gauge.animationSpeed = 5; -// gauge.set(-75); +google.charts.load('current', {'packages':['gauge']}); +google.charts.setOnLoadCallback(drawSPMChart); -// https://github.com/bernii/gauge.js/issues/193 +var spmdata = [ + ['Label', 'Value'], + ['SPM', 21.0], + +]; + +var spmoptions = { + min:0, max: 50, + width: 400, height: 120, + greenFrom: 20, greenTo: 30, + yellowFrom: 30,yellowTo: 40, + redFrom: 40, redTo: 50, + majorTicks: ['0','10','20','30','40','50'], + minorTicks: 10 +}; + +var data = null; +var spmchart = null; + +// SPM chart +function drawSPMChart() { + + data = new google.visualization.arrayToDataTable(spmdata); -var opts = { - angle: 0, // The span of the gauge arc - lineWidth: 0.2, // The line thickness - radiusScale: 0.89, // Relative radius - pointer: { - length: 0.54, // // Relative to gauge radius - strokeWidth: 0.053, // The thickness - color: '#000000' // Fill color - }, - limitMax: false, // If false, max value increases automatically if value > maxValue - limitMin: false, // If true, the min value of the gauge will be fixed - colorStart: '#6FADCF', // Colors - colorStop: '#8FC0DA', // just experiment with them - strokeColor: '#E0E0E0', // to see which ones work best for you - generateGradient: true, - highDpiSupport: true, // High resolution support - staticZones: [ - {strokeStyle: "#00FF00", min: 0, max: 2}, // Greem - {strokeStyle: "#0000FF", min: 2, max: 3}, // Blue` - {strokeStyle: "#00FFFF", min: 3, max: 4}, // Cyan - {strokeStyle: "#FFDD00", min: 4, max: 5}, // Orange - {strokeStyle: "#FF0000", min: 5, max: 6} // Red - ], - }; - var target = document.getElementById('basic'); // your canvas element - var gaugeboatspeed = new Gauge(target).setOptions(opts); // create sexy gauge! - gaugeboatspeed.maxValue = 6; // set max gauge value - gaugeboatspeed.setMinValue(0); // Prefer setter over gauge.minValue = 0 - gaugeboatspeed.animationSpeed = 10; // set animation speed (32 is default value) - gaugeboatspeed.set(0); // set actual value + spmchart = new google.visualization.Gauge(document.getElementById('basic')); -// Define set_basic(values) so that gauges can be set by metricsgroups - function set_basic() { - gaugeboatspeed.set(boatspeed_now); - } + // spmchart.draw(data, spmoptions); + + // Define set_basic(values) so that gauges can be set by metricsgroups + +}; + +var spmchart; +function set_basic() { + data.setCell(0,1,spm_now); + spmchart.draw(data, spmoptions) +} From 557a7fa6e29d86f6139b2b33e5cc3d251999e0d1 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 10 Dec 2019 22:07:19 +0100 Subject: [PATCH 02/57] playing with gauges --- rowers/templates/embedded_video.html | 36 +++++++++++-- rowers/templatetags/rowerfilters.py | 65 +++++++++++----------- static/js/videogauges.js | 81 +++++++++++++++++++++++++--- 3 files changed, 136 insertions(+), 46 deletions(-) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index e957f6fd..97196d18 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -254,7 +254,7 @@ function copyText() { // catchangle = ctch[Math.round(datatime)]; {% for id, metric in metrics.items %} {{ id }}_now = {{ id }}_values[Math.round(datatime)]; - // console.log(datatime,{{ id }}_now, "{{ metric.name }}") + // console.log(datatime,{{ id }},{{ id }}_now, "{{ metric.name }}") {% endfor %} @@ -374,11 +374,21 @@ function copyText() { {{ metric.unit }} {% endfor %} - {% for group in metricsgroups %} -
  • -
    + +
      + {% if 'basic' in metricsgroups %} +
    • +
    • - {% endfor %} +
    • +
      +
    • + {% endif %} + {% if 'forcepower' in metricsgroups %} +
    • +
      +
    • + {% endif %}
  • @@ -394,6 +404,22 @@ function copyText() { {% endlanguage %} diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index 5c1c70ca..648e0d80 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -121,7 +121,26 @@ def is_coach(rower,rowers): return True +@register.filter +def waterpower(x,rower): + return int(x*(100-rower.otwslack)/100.) +@register.filter +def round20(x): + return int(20.*(1+int(int(x)/20))) + +@register.filter +def round100(x): + return int(100.*(1+int(int(x)/100))) + +@register.filter +def majorticks(maxval): + ticks = range(1+int(maxval/100.)) + newticks =[] + for t in ticks: + newticks.append(t*100) + + return newticks def strfdeltah(tdelta): hours, rest = divmod(tdelta.seconds,3600) diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index a916a5f2..2df72fc8 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -84,7 +84,7 @@ MIDDLEWARE = [ 'django.middleware.common.CommonMiddleware', 'django.middleware.common.BrokenLinkEmailsMiddleware', 'django.middleware.gzip.GZipMiddleware', - 'htmlmin.middleware.HtmlMinifyMiddleware', +# 'htmlmin.middleware.HtmlMinifyMiddleware', # 'htmlmin.middleware.MarkRequestMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.security.SecurityMiddleware', diff --git a/static/js/videogauges.js b/static/js/videogauges.js index 8b18f129..31da7567 100644 --- a/static/js/videogauges.js +++ b/static/js/videogauges.js @@ -2,15 +2,18 @@ google.charts.load('current', {'packages':['gauge']}); google.charts.setOnLoadCallback(drawSPMChart); google.charts.setOnLoadCallback(drawSpeedChart); google.charts.setOnLoadCallback(drawPowerChart); +google.charts.setOnLoadCallback(drawHRChart); + +console.log('initializing data'); var spmdata = [ ['Label', 'Value'], - ['SPM', 21.0], + ['SPM', 21], ]; var speeddata = [ ['Label', 'Value'], - ['V m/s', 0.0], + ['V m/s', 0], ]; var powerdata = [ @@ -18,6 +21,21 @@ var powerdata = [ ['PWR',150], ] +var hrdata = [ + ['Label','Value'], + ['HR',110], +] + +var hroptions = { + min: 100, max: 200, + width: 400, height: 120, + greenFrom: 100, greenTo: 135, + yellowFrom: 135,yellowTo: 157, + redFrom: 157, redTo: 200, + minorTicks: 5 +}; + + var spmoptions = { min:0, max: 50, width: 400, height: 120, @@ -58,13 +76,16 @@ var datapower = null; // SPM chart function drawSPMChart() { - + console.log('first draw SPM chart'); dataspm = new google.visualization.arrayToDataTable(spmdata); - + try { spmchart = new google.visualization.Gauge(document.getElementById('basic_spm')); + spmchart.draw(dataspm,spmoptions); +} catch(err) { +} // spmchart.draw(data, spmoptions); // Define set_basic(values) so that gauges can be set by metricsgroups @@ -75,13 +96,35 @@ function drawSPMChart() { function drawSpeedChart() { dataspeed = new google.visualization.arrayToDataTable(speeddata); + try { speedchart = new google.visualization.Gauge(document.getElementById('basic_boatspeed')); + speedchart.draw(dataspeed,speedoptions); +} catch(err) { + +} } // Power chart function drawPowerChart() { datapower = new google.visualization.arrayToDataTable(powerdata); + try { powerchart = new google.visualization.Gauge(document.getElementById('forcepower_power')); + powerchart.draw(datapower,poweroptions) +} catch(err) { + +} + +} + +// Power chart +function drawHRChart() { + datahr = new google.visualization.arrayToDataTable(hrdata); + try { + hrchart = new google.visualization.Gauge(document.getElementById('athlete_hr')); + hrchart.draw(datahr,hroptions); +} catch(err) { + console.log('no hr div'); +} } @@ -94,7 +137,10 @@ function set_basic() { } function set_athlete() { - + datahr.setCell(0,1,hr_now); + try { + hrchart.draw(datahr,hroptions); + } catch(err) {} } function set_stroke() { @@ -103,5 +149,7 @@ function set_stroke() { function set_forcepower() { datapower.setCell(0,1,power_now); + try { powerchart.draw(datapower,poweroptions); +} catch(err) {} } From 04ffc15f240e0dd0c5d65acbf3f5a4d54afc86b6 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 11 Dec 2019 00:33:53 +0100 Subject: [PATCH 04/57] small improvements HR gauge --- rowers/templates/embedded_video.html | 2 +- rowers/templatetags/rowerfilters.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index fa7eacaa..f4dae1e7 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -462,7 +462,7 @@ function copyText() { hroptions.yellowTo = {{ rower.an }} hroptions.redFrom = {{ rower.an }} hroptions.redTo = {{ rower.max }} - hroptions.majorTicks = {{ rower.max|round20|majorticks }} + hroptions.majorTicks = {{ rower.max|round20|hrmajorticks:rower.rest }} hr_now = hr_values[0]; set_athlete(); {% endif %} diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index 648e0d80..b7f3be2f 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -142,6 +142,16 @@ def majorticks(maxval): return newticks +@register.filter +def hrmajorticks(maxval,minval): + ticks = range(int((maxval-minval)/20.)-1) + newticks =[] + for t in ticks: + newticks.append(100+t*20) + + print(newticks) + return newticks + def strfdeltah(tdelta): hours, rest = divmod(tdelta.seconds,3600) minutes,seconds = divmod(rest,60) From 00f7a5a3ef07ee139ac08601ce0b9edd62402d8a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 11 Dec 2019 15:17:20 +0100 Subject: [PATCH 05/57] stroke angle chart prototype --- rowers/metrics.py | 2 +- rowers/templates/embedded_video.html | 11 +++++ static/js/videogauges.js | 72 ++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/rowers/metrics.py b/rowers/metrics.py index 242cfe56..fbcee514 100644 --- a/rowers/metrics.py +++ b/rowers/metrics.py @@ -258,7 +258,7 @@ rowingmetrics = ( 'ax_min': 0, 'ax_max': 30, 'default': 0, - 'sigfigs': 0, + 'sigfigs': 1, 'mode':'water', 'type': 'pro', 'group': 'stroke'}), diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index f4dae1e7..4327f266 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -394,8 +394,14 @@ function copyText() {
  • {% endif %} + {% if 'stroke' in metricsgroups %} +
  • +
    +
  • + {% endif %} +
  • {% if analysis and user.is_authenticated and user == analysis.workout.user.user %}

    @@ -411,6 +417,7 @@ function copyText() { $(document).ready( function() { $(window).load(function() { // initialize data fields + console.log('initializing first value of data'); {% for id, metric in metrics.items %} {{ id }}_now = {{ id }}_values[0]; document.getElementById("{{ id }}").innerHTML = {{ id }}_now; @@ -466,6 +473,10 @@ function copyText() { hr_now = hr_values[0]; set_athlete(); {% endif %} + {% if 'stroke' in metricsgroups %} + anglesoptions.PieStartAngle = 90+catch_now; + set_stroke(); + {% endif %} // cookie reader function createCookie(name,value,days) { diff --git a/static/js/videogauges.js b/static/js/videogauges.js index 31da7567..42ac8ff9 100644 --- a/static/js/videogauges.js +++ b/static/js/videogauges.js @@ -1,10 +1,9 @@ -google.charts.load('current', {'packages':['gauge']}); +google.charts.load('current', {'packages':['gauge','corechart']}); google.charts.setOnLoadCallback(drawSPMChart); google.charts.setOnLoadCallback(drawSpeedChart); google.charts.setOnLoadCallback(drawPowerChart); google.charts.setOnLoadCallback(drawHRChart); - -console.log('initializing data'); +google.charts.setOnLoadCallback(drawStrokeAngleChart); var spmdata = [ ['Label', 'Value'], @@ -26,6 +25,33 @@ var hrdata = [ ['HR',110], ] +var angledata = [ + ['Angle', 'deg'], + ['slip', 10 ], + ['load', 50], + ['unload', 50], + ['wash', 10], + ['recovery',240 ] +] + +var anglesoptions = { + title: 'Stroke Angles', + legend: 'none', + pieHole: 0.5, + chartArea: { width: "100%" }, + pieStartAngle: 35, + pieSliceText: 'value', + pieSliceTextStyle: {color:'black',fontSize:12}, + slices: { + 0: { color: 'lightblue' }, + 1: { color: 'lightgreen' }, + 2: { color: 'yellow'}, + 3: { color: 'orange'}, + 4: { color: 'transparent', textStyle: {color:'transparent'}} + } +}; + + var hroptions = { min: 100, max: 200, width: 400, height: 120, @@ -73,6 +99,7 @@ var spmchart = null; var speedchart = null; var powerchart = null; var datapower = null; +var dataangles = null; // SPM chart function drawSPMChart() { @@ -116,16 +143,28 @@ function drawPowerChart() { } -// Power chart +// HR chart function drawHRChart() { datahr = new google.visualization.arrayToDataTable(hrdata); try { - hrchart = new google.visualization.Gauge(document.getElementById('athlete_hr')); - hrchart.draw(datahr,hroptions); -} catch(err) { - console.log('no hr div'); + hrchart = new google.visualization.Gauge(document.getElementById('athlete_hr')); + hrchart.draw(datahr,hroptions); + } catch(err) { + console.log('no hr div'); + } + } +// Stroke angle chart +function drawStrokeAngleChart() { + dataangles = new google.visualization.arrayToDataTable(angledata); + try { + angleschart = new google.visualization.PieChart(document.getElementById('stroke_angles')); + angleschart.draw(dataangles,anglesoptions); + } catch(err) { + console.log('no angles div'); + } + } function set_basic() { @@ -144,7 +183,22 @@ function set_athlete() { } function set_stroke() { - + var piestartangle = 90+catch_now; + var load = Math.max(-catch_now-slip_now+peakforceangle_now); + var unload = Math.max(finish_now-wash_now-peakforceangle_now) ; + var recovery = Math.max(360+catch_now-finish_now); + // console.log('load ',load,'; unload ',unload,'; recovery ',recovery,'; pie start angle ',piestartangle); + dataangles.setCell(0,1,slip_now); + dataangles.setCell(1,1,load); + dataangles.setCell(2,1,unload); + dataangles.setCell(3,1,wash_now); + dataangles.setCell(4,1,recovery); + anglesoptions.pieStartAngle = piestartangle; + try { + angleschart.draw(dataangles,anglesoptions); + } catch(err) { + console.log('failed: ',err); + } } function set_forcepower() { From 0681d17717f8e67be6c760ea2b1db2168c767771 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 11 Dec 2019 20:50:41 +0100 Subject: [PATCH 06/57] stroke angles only for water workouts --- rowers/templates/embedded_video.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 4327f266..8e19b6c9 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -395,10 +395,12 @@ function copyText() {

  • {% endif %} {% if 'stroke' in metricsgroups %} + {% if workout.workouttype == 'water' %}
  • {% endif %} + {% endif %} @@ -474,9 +476,11 @@ function copyText() { set_athlete(); {% endif %} {% if 'stroke' in metricsgroups %} + {% if workout.workouttype == 'water'} anglesoptions.PieStartAngle = 90+catch_now; set_stroke(); {% endif %} + {% endif %} // cookie reader function createCookie(name,value,days) { From e5db9b0f75d4c8caebeff146b0a7a2d49dbc51e9 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 11 Dec 2019 23:06:12 +0100 Subject: [PATCH 07/57] correct error --- rowers/templates/embedded_video.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 8e19b6c9..8e7666f9 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -476,7 +476,7 @@ function copyText() { set_athlete(); {% endif %} {% if 'stroke' in metricsgroups %} - {% if workout.workouttype == 'water'} + {% if workout.workouttype == 'water' %} anglesoptions.PieStartAngle = 90+catch_now; set_stroke(); {% endif %} From 3a981417bef4e2cea63df7544e91fb13d853569a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 10:15:35 +0100 Subject: [PATCH 08/57] adding cumulative distance to allowed metrics --- rowers/metrics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowers/metrics.py b/rowers/metrics.py index 242cfe56..3e08f76e 100644 --- a/rowers/metrics.py +++ b/rowers/metrics.py @@ -15,7 +15,7 @@ from math import log10 nometrics = [ 'originalvelo', - 'cumdist', +# 'cumdist', 'strokes_slsh_min', ' WorkPerStroke (joules)', ' activityIdx', From c97ac0e6fd73a8657da2617e530f2920ced6dc4e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 16:55:57 +0100 Subject: [PATCH 09/57] added non-tested Dockerfile & updated video gauges --- Dockerfile | 7 +++++++ rowers/templates/embedded_video.html | 11 +++++++++++ 2 files changed, 18 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..3cf83085 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3-alpine +COPY requirements.txt ./ +WORKDIR /usr/src/app/ +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +EXPOSE 8000 +CMD ["python", "./manage.py", "runserver"] diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index f31fc280..7d66b3de 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -411,6 +411,17 @@ function copyText() {

    {% endif %} +
  • +

    We're building Gauges to show the video data based on the + Google charts API. + You can contribute by developing your own gauge in + JSFiddle like + this example. + Please send us the link to the JSFiddle example by email using the + Contact Form and we'll discuss the possibilities + with you. +

    +
  •  

    From 45d1823b7067af98d2dea7e07cdf4d5d542e0d91 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 17:00:29 +0100 Subject: [PATCH 10/57] updated Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3cf83085..fd6a80c9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM python:3-alpine -COPY requirements.txt ./ +COPY ./requirements.txt ./ WORKDIR /usr/src/app/ RUN pip install --no-cache-dir -r requirements.txt COPY . . From 9e55cb496cf01d84919b4113ab702f94f736984f Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 20:31:07 +0100 Subject: [PATCH 11/57] removing old power calc --- rowers/models.py | 6 +++--- rowers/tasks.py | 14 ++++---------- rowers/views/workoutviews.py | 8 ++++---- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index d73bb683..47b6d629 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -3202,12 +3202,12 @@ class WorkoutForm(ModelForm): # Used for the rowing physics calculations class AdvancedWorkoutForm(ModelForm): - quick_calc = forms.BooleanField(initial=True,required=False) - go_service = forms.BooleanField(initial=False,required=False,label='Experimental') + #quick_calc = forms.BooleanField(initial=True,required=False) + #go_service = forms.BooleanField(initial=False,required=False,label='Experimental') class Meta: model = Workout - fields = ['boattype','weightvalue','quick_calc'] + fields = ['boattype','weightvalue'] class RowerExportForm(ModelForm): class Meta: diff --git a/rowers/tasks.py b/rowers/tasks.py index 9f31af9b..0a097d19 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -1516,19 +1516,11 @@ def handle_otwsetpower(self,f1, boattype, weightvalue, else: debug = False - if 'quick_calc' in kwargs: - usetable = kwargs['quick_calc'] - else: - usetable = False - - if 'go_service' in kwargs: - goservice = kwargs['go_service'] - else: - goservice = False - kwargs['jobid'] = job_id + + weightvalue = float(weightvalue) # check what the real file name is @@ -1569,6 +1561,8 @@ def handle_otwsetpower(self,f1, boattype, weightvalue, progressurl += "/rowers/record-progress/" progressurl += job_id+'/' + goservice = True + if goservice: # do something (this should return from go service) with grpc.insecure_channel( diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index e50c618e..eea37716 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -2623,8 +2623,8 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""): form = AdvancedWorkoutForm(request.POST) if form.is_valid(): - quick_calc = form.cleaned_data['quick_calc'] - go_service = form.cleaned_data['go_service'] + #quick_calc = form.cleaned_data['quick_calc'] + #go_service = form.cleaned_data['go_service'] boattype = form.cleaned_data['boattype'] weightvalue = form.cleaned_data['weightvalue'] w.boattype = boattype @@ -2669,8 +2669,8 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""): first_name,last_name,emailaddress,encoder.decode_hex(id), ps=[r.p0,r.p1,r.p2,r.p3], ratio=r.cpratio, - quick_calc = quick_calc, - go_service=go_service, + # quick_calc = quick_calc, + # go_service=go_service, emailbounced = r.emailbounced ) From 11e4a2cc1018de4e7b82889e3c847c88ef6f36d0 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 21:45:43 +0100 Subject: [PATCH 12/57] adding .dockerignore --- .dockerignore | 1 + Dockerfile | 9 +- rowsandall_workouts_2017-09-28_2018-09-28.csv | 434 ------------------ 3 files changed, 7 insertions(+), 437 deletions(-) create mode 100644 .dockerignore delete mode 100644 rowsandall_workouts_2017-09-28_2018-09-28.csv diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..5ceb3864 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +venv diff --git a/Dockerfile b/Dockerfile index fd6a80c9..09dc421d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,10 @@ -FROM python:3-alpine -COPY ./requirements.txt ./ +FROM debian +RUN apt-get update && apt-get install \ + -y --no-install-recommends python3 python3-virtualenv +RUN python3 -m virtualenv --python=/usr/bin/python3 /opt/venv +COPY ./requirements.txt /usr/src/app/ WORKDIR /usr/src/app/ -RUN pip install --no-cache-dir -r requirements.txt +RUN . /opt/venv/bin/activate && pip install -r requirements.txt COPY . . EXPOSE 8000 CMD ["python", "./manage.py", "runserver"] diff --git a/rowsandall_workouts_2017-09-28_2018-09-28.csv b/rowsandall_workouts_2017-09-28_2018-09-28.csv deleted file mode 100644 index b767fb45..00000000 --- a/rowsandall_workouts_2017-09-28_2018-09-28.csv +++ /dev/null @@ -1,434 +0,0 @@ -,Stroke Data CSV,Stroke Data TCX,TRIMP Training Load,TSS Training Load,date,distance (m),duration ,name,notes,timezone,type,weight (kg),weight category -0,https://rowsandall.com/rowers/workout/2542/emailcsv,https://rowsandall.com/rowers/workout/2542/emailtcx,0,0,1970-01-01 00:00:00+00:00,9578,00:47:55.400000,Test Auto Sync Pro User,,Europe/Prague,rower,80.0,lwt -1,https://rowsandall.com/rowers/workout/2500/emailcsv,https://rowsandall.com/rowers/workout/2500/emailtcx,0,0,2014-02-26 20:32:33+00:00,65,00:00:02,Sample Workout JSON,,UTC,water,80.0,lwt -2,https://rowsandall.com/rowers/workout/3033/emailcsv,https://rowsandall.com/rowers/workout/3033/emailtcx,95,264,2015-06-02 06:29:02+00:00,14002,00:59:37.700000,Test P,,Europe/Prague,water,80.0,hwt -3,https://rowsandall.com/rowers/workout/2501/emailcsv,https://rowsandall.com/rowers/workout/2501/emailtcx,0,0,2016-04-02 08:15:08+00:00,10269,01:05:24,Completed a workout (generic) 6.35 mi on 04/02/16,,Europe/Prague,water,80.0,lwt -4,https://rowsandall.com/rowers/workout/2408/emailcsv,https://rowsandall.com/rowers/workout/2408/emailtcx,0,0,2016-07-30 08:40:36+00:00,1001,00:03:41,Comparison,,Europe/Berlin,rower,80.0,lwt -5,https://rowsandall.com/rowers/workout/3032/emailcsv,https://rowsandall.com/rowers/workout/3032/emailtcx,0,0,2016-07-31 12:35:01+00:00,1111,00:04:32.700000,,,Europe/Prague,water,80.0,hwt -6,https://rowsandall.com/rowers/workout/2572/emailcsv,https://rowsandall.com/rowers/workout/2572/emailtcx,0,0,2016-11-28 08:37:02+00:00,499,00:01:58,BC,,Europe/Prague,rower,80.0,lwt -7,https://rowsandall.com/rowers/workout/2379/emailcsv,https://rowsandall.com/rowers/workout/2379/emailtcx,0,0,2017-10-27 16:14:42+00:00,742,00:02:25,Test Weba,,Europe/Prague,water,80.0,lwt -8,https://rowsandall.com/rowers/workout/2380/emailcsv,https://rowsandall.com/rowers/workout/2380/emailtcx,0,0,2017-10-27 16:14:42+00:00,742,00:02:25,Test Weba,,Europe/Belgrade,water,80.0,lwt -9,https://rowsandall.com/rowers/workout/2521/emailcsv,https://rowsandall.com/rowers/workout/2521/emailtcx,0,0,2017-11-09 09:15:32+00:00,49842,02:19:37,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -10,https://rowsandall.com/rowers/workout/2524/emailcsv,https://rowsandall.com/rowers/workout/2524/emailtcx,0,0,2017-11-09 09:15:32+00:00,49842,02:19:37,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -11,https://rowsandall.com/rowers/workout/2527/emailcsv,https://rowsandall.com/rowers/workout/2527/emailtcx,0,0,2017-11-09 09:15:32+00:00,49842,02:19:37,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -12,https://rowsandall.com/rowers/workout/2531/emailcsv,https://rowsandall.com/rowers/workout/2531/emailtcx,0,0,2017-11-09 09:15:32+00:00,49842,02:19:37,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -13,https://rowsandall.com/rowers/workout/2523/emailcsv,https://rowsandall.com/rowers/workout/2523/emailtcx,0,0,2017-11-09 15:15:32+00:00,0,02:28:28,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -14,https://rowsandall.com/rowers/workout/2526/emailcsv,https://rowsandall.com/rowers/workout/2526/emailtcx,0,0,2017-11-09 15:15:32+00:00,0,02:28:28,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -15,https://rowsandall.com/rowers/workout/2529/emailcsv,https://rowsandall.com/rowers/workout/2529/emailtcx,0,0,2017-11-09 15:15:32+00:00,0,02:28:28,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -16,https://rowsandall.com/rowers/workout/2533/emailcsv,https://rowsandall.com/rowers/workout/2533/emailtcx,0,0,2017-11-09 15:15:32+00:00,0,02:28:28,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -17,https://rowsandall.com/rowers/workout/2520/emailcsv,https://rowsandall.com/rowers/workout/2520/emailtcx,0,0,2017-11-09 18:15:32+00:00,10016,01:06:03,Polar Import,,Europe/Helsinki,rower,80.0,lwt -18,https://rowsandall.com/rowers/workout/2522/emailcsv,https://rowsandall.com/rowers/workout/2522/emailtcx,0,0,2017-11-09 18:15:32+00:00,10016,01:06:03,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -19,https://rowsandall.com/rowers/workout/2525/emailcsv,https://rowsandall.com/rowers/workout/2525/emailtcx,0,0,2017-11-09 18:15:32+00:00,10016,01:06:03,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -20,https://rowsandall.com/rowers/workout/2528/emailcsv,https://rowsandall.com/rowers/workout/2528/emailtcx,0,0,2017-11-09 18:15:32+00:00,10016,01:06:03,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -21,https://rowsandall.com/rowers/workout/2532/emailcsv,https://rowsandall.com/rowers/workout/2532/emailtcx,0,0,2017-11-09 18:15:32+00:00,10016,01:06:03,Import from Polar Flow,imported through email,Europe/Helsinki,water,80.0,lwt -22,https://rowsandall.com/rowers/workout/2494/emailcsv,https://rowsandall.com/rowers/workout/2494/emailtcx,0,0,2017-11-12 10:25:00+00:00,10526,00:44:01.700000,Race,,Europe/Rome,water,80.0,lwt -23,https://rowsandall.com/rowers/workout/2496/emailcsv,https://rowsandall.com/rowers/workout/2496/emailtcx,0,0,2017-11-12 10:25:00+00:00,10526,00:44:01.700000,Race,,Europe/Rome,water,80.0,lwt -24,https://rowsandall.com/rowers/workout/2497/emailcsv,https://rowsandall.com/rowers/workout/2497/emailtcx,0,0,2017-11-12 10:25:00+00:00,10526,00:44:01.700000,SpdCoach 2,,Europe/Rome,rower,80.0,lwt -25,https://rowsandall.com/rowers/workout/2498/emailcsv,https://rowsandall.com/rowers/workout/2498/emailtcx,0,0,2017-11-12 10:25:00+00:00,10526,00:44:01.700000,boat speed test,,Europe/Rome,water,80.0,lwt -26,https://rowsandall.com/rowers/workout/2499/emailcsv,https://rowsandall.com/rowers/workout/2499/emailtcx,0,0,2017-11-12 10:25:00+00:00,10526,00:44:01.700000,Boat Speed test 2,,Europe/Rome,water,80.0,lwt -27,https://rowsandall.com/rowers/workout/2724/emailcsv,https://rowsandall.com/rowers/workout/2724/emailtcx,0,0,2018-01-01 09:27:47+00:00,5000,00:18:37,C2 Import Workout from 2018-01-01 09:27:47+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -28,https://rowsandall.com/rowers/workout/2723/emailcsv,https://rowsandall.com/rowers/workout/2723/emailtcx,0,0,2018-01-01 09:48:09+00:00,2963,00:13:29,C2 Import Workout from 2018-01-01 09:48:09+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -29,https://rowsandall.com/rowers/workout/2722/emailcsv,https://rowsandall.com/rowers/workout/2722/emailtcx,0,0,2018-01-02 18:22:08+00:00,14183,00:59:49.900000,C2 Import Workout from 2018-01-02 18:22:08+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -30,https://rowsandall.com/rowers/workout/2721/emailcsv,https://rowsandall.com/rowers/workout/2721/emailtcx,0,0,2018-01-03 16:24:47+00:00,4821,00:20:04.500000,C2 Import Workout from 2018-01-03 16:24:47+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -31,https://rowsandall.com/rowers/workout/2720/emailcsv,https://rowsandall.com/rowers/workout/2720/emailtcx,0,0,2018-01-03 16:46:19+00:00,2000,00:07:07.500000,C2 Import Workout from 2018-01-03 16:46:19+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -32,https://rowsandall.com/rowers/workout/2719/emailcsv,https://rowsandall.com/rowers/workout/2719/emailtcx,0,0,2018-01-03 16:57:04+00:00,2997,00:13:35.100000,C2 Import Workout from 2018-01-03 16:57:04+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -33,https://rowsandall.com/rowers/workout/2718/emailcsv,https://rowsandall.com/rowers/workout/2718/emailtcx,0,0,2018-01-06 13:59:30+00:00,4722,00:20:06.200000,C2 Import Workout from 2018-01-06 13:59:30+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -34,https://rowsandall.com/rowers/workout/2717/emailcsv,https://rowsandall.com/rowers/workout/2717/emailtcx,0,0,2018-01-06 14:20:43+00:00,1171,00:04:00,C2 Import Workout from 2018-01-06 14:20:43+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -35,https://rowsandall.com/rowers/workout/2716/emailcsv,https://rowsandall.com/rowers/workout/2716/emailtcx,0,0,2018-01-06 14:25:53+00:00,8006,00:36:13.600000,C2 Import Workout from 2018-01-06 14:25:53+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -36,https://rowsandall.com/rowers/workout/2715/emailcsv,https://rowsandall.com/rowers/workout/2715/emailtcx,0,0,2018-01-07 14:03:51+00:00,2520,00:10:42.700000,C2 Import Workout from 2018-01-07 14:03:51+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -37,https://rowsandall.com/rowers/workout/2714/emailcsv,https://rowsandall.com/rowers/workout/2714/emailtcx,0,0,2018-01-07 14:18:45+00:00,9996,00:42:35.100000,C2 Import Workout from 2018-01-07 14:18:45+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -38,https://rowsandall.com/rowers/workout/2713/emailcsv,https://rowsandall.com/rowers/workout/2713/emailtcx,0,0,2018-01-09 18:22:19+00:00,5267,00:22:34.200000,C2 Import Workout from 2018-01-09 18:22:19+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -39,https://rowsandall.com/rowers/workout/2712/emailcsv,https://rowsandall.com/rowers/workout/2712/emailtcx,0,0,2018-01-09 18:46:20+00:00,1000,00:03:21.400000,C2 Import Workout from 2018-01-09 18:46:20+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -40,https://rowsandall.com/rowers/workout/2711/emailcsv,https://rowsandall.com/rowers/workout/2711/emailtcx,0,0,2018-01-09 18:51:03+00:00,2300,00:10:04.500000,C2 Import Workout from 2018-01-09 18:51:03+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -41,https://rowsandall.com/rowers/workout/2710/emailcsv,https://rowsandall.com/rowers/workout/2710/emailtcx,0,0,2018-01-12 16:09:10+00:00,2008,00:08:39.100000,C2 Import Workout from 2018-01-12 16:09:10+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -42,https://rowsandall.com/rowers/workout/2709/emailcsv,https://rowsandall.com/rowers/workout/2709/emailtcx,0,0,2018-01-12 16:19:00+00:00,500,00:01:33.400000,C2 Import Workout from 2018-01-12 16:19:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -43,https://rowsandall.com/rowers/workout/2708/emailcsv,https://rowsandall.com/rowers/workout/2708/emailtcx,0,0,2018-01-12 16:21:06+00:00,2002,00:09:25.600000,C2 Import Workout from 2018-01-12 16:21:06+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -44,https://rowsandall.com/rowers/workout/2707/emailcsv,https://rowsandall.com/rowers/workout/2707/emailtcx,0,0,2018-01-12 16:31:08+00:00,100,00:00:17.600000,C2 Import Workout from 2018-01-12 16:31:08+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -45,https://rowsandall.com/rowers/workout/2706/emailcsv,https://rowsandall.com/rowers/workout/2706/emailtcx,0,0,2018-01-12 16:31:58+00:00,2011,00:08:56.600000,C2 Import Workout from 2018-01-12 16:31:58+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -46,https://rowsandall.com/rowers/workout/2705/emailcsv,https://rowsandall.com/rowers/workout/2705/emailtcx,0,0,2018-01-13 12:40:00+00:00,2000,00:06:55.800000,C2 Import Workout from 2018-01-13 12:40:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -47,https://rowsandall.com/rowers/workout/2704/emailcsv,https://rowsandall.com/rowers/workout/2704/emailtcx,0,0,2018-01-16 18:40:49+00:00,2007,00:08:30.800000,C2 Import Workout from 2018-01-16 18:40:49+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -48,https://rowsandall.com/rowers/workout/2703/emailcsv,https://rowsandall.com/rowers/workout/2703/emailtcx,0,0,2018-01-16 18:50:09+00:00,333,00:01:00,C2 Import Workout from 2018-01-16 18:50:09+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -49,https://rowsandall.com/rowers/workout/2702/emailcsv,https://rowsandall.com/rowers/workout/2702/emailtcx,0,0,2018-01-16 18:51:41+00:00,6820,00:31:22.200000,C2 Import Workout from 2018-01-16 18:51:41+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -50,https://rowsandall.com/rowers/workout/2701/emailcsv,https://rowsandall.com/rowers/workout/2701/emailtcx,0,0,2018-01-16 19:24:23+00:00,2008,00:09:01.100000,C2 Import Workout from 2018-01-16 19:24:23+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -51,https://rowsandall.com/rowers/workout/2700/emailcsv,https://rowsandall.com/rowers/workout/2700/emailtcx,0,0,2018-01-18 19:01:45+00:00,2007,00:08:27.600000,C2 Import Workout from 2018-01-18 19:01:45+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -52,https://rowsandall.com/rowers/workout/2699/emailcsv,https://rowsandall.com/rowers/workout/2699/emailtcx,0,0,2018-01-18 19:10:50+00:00,6918,00:29:14.200000,C2 Import Workout from 2018-01-18 19:10:50+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -53,https://rowsandall.com/rowers/workout/2698/emailcsv,https://rowsandall.com/rowers/workout/2698/emailtcx,0,0,2018-01-18 19:40:40+00:00,1217,00:06:11.100000,C2 Import Workout from 2018-01-18 19:40:40+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -54,https://rowsandall.com/rowers/workout/2697/emailcsv,https://rowsandall.com/rowers/workout/2697/emailtcx,0,0,2018-01-18 19:47:32+00:00,6697,00:29:16.700000,C2 Import Workout from 2018-01-18 19:47:32+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -55,https://rowsandall.com/rowers/workout/2696/emailcsv,https://rowsandall.com/rowers/workout/2696/emailtcx,0,0,2018-01-18 20:17:58+00:00,1997,00:09:10.700000,C2 Import Workout from 2018-01-18 20:17:58+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -56,https://rowsandall.com/rowers/workout/2692/emailcsv,https://rowsandall.com/rowers/workout/2692/emailtcx,0,0,2018-01-19 00:00:00+00:00,200,00:02:00.200000,C2 Import Workout from 2018-01-19 00:00:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -57,https://rowsandall.com/rowers/workout/2693/emailcsv,https://rowsandall.com/rowers/workout/2693/emailtcx,0,0,2018-01-19 00:00:00+00:00,200,00:01:55,C2 Import Workout from 2018-01-19 00:00:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -58,https://rowsandall.com/rowers/workout/2694/emailcsv,https://rowsandall.com/rowers/workout/2694/emailtcx,0,0,2018-01-19 00:00:00+00:00,200,00:02:00,C2 Import Workout from 2018-01-19 00:00:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -59,https://rowsandall.com/rowers/workout/2695/emailcsv,https://rowsandall.com/rowers/workout/2695/emailtcx,0,0,2018-01-19 00:00:00+00:00,200,00:01:10,C2 Import Workout from 2018-01-19 00:00:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -60,https://rowsandall.com/rowers/workout/2691/emailcsv,https://rowsandall.com/rowers/workout/2691/emailtcx,0,0,2018-01-20 13:22:31+00:00,19381,01:20:39.100000,C2 Import Workout from 2018-01-20 13:22:31+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -61,https://rowsandall.com/rowers/workout/2690/emailcsv,https://rowsandall.com/rowers/workout/2690/emailtcx,0,0,2018-01-24 18:55:23+00:00,210,00:01:43.400000,C2 Import Workout from 2018-01-24 18:55:23+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -62,https://rowsandall.com/rowers/workout/2689/emailcsv,https://rowsandall.com/rowers/workout/2689/emailtcx,0,0,2018-01-24 18:59:06+00:00,2110,00:08:42.700000,C2 Import Workout from 2018-01-24 18:59:06+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -63,https://rowsandall.com/rowers/workout/2688/emailcsv,https://rowsandall.com/rowers/workout/2688/emailtcx,0,0,2018-01-24 19:08:04+00:00,6081,00:25:10,C2 Import Workout from 2018-01-24 19:08:04+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -64,https://rowsandall.com/rowers/workout/2687/emailcsv,https://rowsandall.com/rowers/workout/2687/emailtcx,0,0,2018-01-24 19:24:18+00:00,14426,01:00:12.600000,C2 Import Workout from 2018-01-24 19:24:18+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -65,https://rowsandall.com/rowers/workout/2686/emailcsv,https://rowsandall.com/rowers/workout/2686/emailtcx,0,0,2018-01-27 13:23:26+00:00,14981,01:01:39.600000,C2 Import Workout from 2018-01-27 13:23:26+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -66,https://rowsandall.com/rowers/workout/2685/emailcsv,https://rowsandall.com/rowers/workout/2685/emailtcx,0,0,2018-01-27 14:25:07+00:00,18338,01:15:22.800000,C2 Import Workout from 2018-01-27 14:25:07+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -67,https://rowsandall.com/rowers/workout/2684/emailcsv,https://rowsandall.com/rowers/workout/2684/emailtcx,0,0,2018-02-03 14:20:18+00:00,12181,00:51:46,C2 Import Workout from 2018-02-03 14:20:18+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -68,https://rowsandall.com/rowers/workout/2683/emailcsv,https://rowsandall.com/rowers/workout/2683/emailtcx,0,0,2018-02-06 17:54:01+00:00,7210,00:31:09,C2 Import Workout from 2018-02-06 17:54:01+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -69,https://rowsandall.com/rowers/workout/2682/emailcsv,https://rowsandall.com/rowers/workout/2682/emailtcx,0,0,2018-02-10 09:10:14+00:00,3040,00:12:47.200000,C2 Import Workout from 2018-02-10 09:10:14+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -70,https://rowsandall.com/rowers/workout/2681/emailcsv,https://rowsandall.com/rowers/workout/2681/emailtcx,0,0,2018-02-10 09:23:52+00:00,9305,00:40:50.900000,C2 Import Workout from 2018-02-10 09:23:52+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -71,https://rowsandall.com/rowers/workout/2680/emailcsv,https://rowsandall.com/rowers/workout/2680/emailtcx,0,0,2018-02-10 10:06:00+00:00,2009,00:09:04.200000,C2 Import Workout from 2018-02-10 10:06:00+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -72,https://rowsandall.com/rowers/workout/2679/emailcsv,https://rowsandall.com/rowers/workout/2679/emailtcx,0,0,2018-02-11 16:57:32+00:00,14430,01:01:23,C2 Import Workout from 2018-02-11 16:57:32+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -73,https://rowsandall.com/rowers/workout/2335/emailcsv,https://rowsandall.com/rowers/workout/2335/emailtcx,0,0,2018-02-12 05:02:06+00:00,3872,00:27:12.200000,SpdCoach 1,,America/Los_Angeles,water,80.0,lwt -74,https://rowsandall.com/rowers/workout/2338/emailcsv,https://rowsandall.com/rowers/workout/2338/emailtcx,0,0,2018-02-12 05:02:06+00:00,9336,09:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -75,https://rowsandall.com/rowers/workout/2339/emailcsv,https://rowsandall.com/rowers/workout/2339/emailtcx,0,0,2018-02-12 05:02:06+00:00,7522,09:41:48.200000,Joined Workout,,America/Los_Angeles,water,80.0,lwt -76,https://rowsandall.com/rowers/workout/2341/emailcsv,https://rowsandall.com/rowers/workout/2341/emailtcx,0,0,2018-02-12 05:02:06+00:00,9336,09:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -77,https://rowsandall.com/rowers/workout/2342/emailcsv,https://rowsandall.com/rowers/workout/2342/emailtcx,0,0,2018-02-12 05:02:06+00:00,9336,09:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -78,https://rowsandall.com/rowers/workout/2343/emailcsv,https://rowsandall.com/rowers/workout/2343/emailtcx,0,0,2018-02-12 05:02:06+00:00,9336,09:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -79,https://rowsandall.com/rowers/workout/2410/emailcsv,https://rowsandall.com/rowers/workout/2410/emailtcx,0,0,2018-02-12 05:02:06+00:00,3872,00:27:12.200000,Test,,America/Los_Angeles,water,80.0,lwt -80,https://rowsandall.com/rowers/workout/2414/emailcsv,https://rowsandall.com/rowers/workout/2414/emailtcx,0,0,2018-02-12 05:02:06+00:00,9336,09:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -81,https://rowsandall.com/rowers/workout/2416/emailcsv,https://rowsandall.com/rowers/workout/2416/emailtcx,0,0,2018-02-12 05:02:06+00:00,3872,00:27:12.200000,Test aaaa,,America/Los_Angeles,water,80.0,lwt -82,https://rowsandall.com/rowers/workout/2417/emailcsv,https://rowsandall.com/rowers/workout/2417/emailtcx,0,0,2018-02-12 05:02:06+00:00,9336,09:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -83,https://rowsandall.com/rowers/workout/2418/emailcsv,https://rowsandall.com/rowers/workout/2418/emailtcx,0,0,2018-02-12 05:02:06+00:00,3872,00:27:12.200000,Test i,,America/Los_Angeles,water,80.0,lwt -84,https://rowsandall.com/rowers/workout/2419/emailcsv,https://rowsandall.com/rowers/workout/2419/emailtcx,0,0,2018-02-12 05:02:06+00:00,11394,09:42:05.500000,Joined Workout,,America/Los_Angeles,water,80.0,lwt -85,https://rowsandall.com/rowers/workout/2420/emailcsv,https://rowsandall.com/rowers/workout/2420/emailtcx,0,0,2018-02-12 13:55:06+00:00,3872,00:27:12.200000,Test ii,,America/Los_Angeles,water,80.0,lwt -86,https://rowsandall.com/rowers/workout/2421/emailcsv,https://rowsandall.com/rowers/workout/2421/emailtcx,0,0,2018-02-12 13:55:06+00:00,350236,00:49:05.500000,Joined Workout,,America/Los_Angeles,water,80.0,lwt -87,https://rowsandall.com/rowers/workout/2344/emailcsv,https://rowsandall.com/rowers/workout/2344/emailtcx,0,0,2018-02-12 14:02:06+00:00,3872,00:27:12.200000,SpdCoach Sessions,imported through email,America/Los_Angeles,water,80.0,lwt -88,https://rowsandall.com/rowers/workout/2347/emailcsv,https://rowsandall.com/rowers/workout/2347/emailtcx,0,0,2018-02-12 14:02:06+00:00,9336,00:58:35,Joined Workout,imported through email,America/Los_Angeles,water,80.0,lwt -89,https://rowsandall.com/rowers/workout/2411/emailcsv,https://rowsandall.com/rowers/workout/2411/emailtcx,0,0,2018-02-12 14:02:06+00:00,3872,00:27:12.200000,Test 2,,America/Los_Angeles,water,80.0,lwt -90,https://rowsandall.com/rowers/workout/2415/emailcsv,https://rowsandall.com/rowers/workout/2415/emailtcx,0,0,2018-02-12 14:02:06+00:00,9336,00:58:35,Joined Workout,,America/Los_Angeles,water,80.0,lwt -91,https://rowsandall.com/rowers/workout/2430/emailcsv,https://rowsandall.com/rowers/workout/2430/emailtcx,0,0,2018-02-12 14:02:06+00:00,3872,00:27:12.200000,Water,,America/Los_Angeles,water,80.0,lwt -92,https://rowsandall.com/rowers/workout/2445/emailcsv,https://rowsandall.com/rowers/workout/2445/emailtcx,0,0,2018-02-12 14:02:06+00:00,3872,00:27:12.200000,Test P,imported through email,America/Los_Angeles,water,80.0,lwt -93,https://rowsandall.com/rowers/workout/2449/emailcsv,https://rowsandall.com/rowers/workout/2449/emailtcx,0,0,2018-02-12 14:02:06+00:00,3872,00:27:12.200000,Water 2x,imported through email,America/Los_Angeles,water,80.0,lwt -94,https://rowsandall.com/rowers/workout/2412/emailcsv,https://rowsandall.com/rowers/workout/2412/emailtcx,0,0,2018-02-12 14:22:01+00:00,3650,00:14:53.200000,Test 3,,America/Los_Angeles,water,80.0,lwt -95,https://rowsandall.com/rowers/workout/2336/emailcsv,https://rowsandall.com/rowers/workout/2336/emailtcx,0,0,2018-02-12 14:29:01+00:00,3650,00:14:53.200000,SpdCoach 2," -Summary for your location at 2018-02-12T14:55:00Z: Temperature 9.0C/48.2F. Wind: 2.5 m/s (5.0 kt). Wind Bearing: 280.0 degrees",America/Los_Angeles,water,80.0,lwt -96,https://rowsandall.com/rowers/workout/2340/emailcsv,https://rowsandall.com/rowers/workout/2340/emailtcx,0,0,2018-02-12 14:29:01+00:00,5464,00:31:40,Joined Workout,,America/Los_Angeles,water,80.0,lwt -97,https://rowsandall.com/rowers/workout/2345/emailcsv,https://rowsandall.com/rowers/workout/2345/emailtcx,0,0,2018-02-12 14:29:01+00:00,3650,00:14:53.200000,SpdCoach Sessions (2),imported through email,America/Los_Angeles,water,80.0,lwt -98,https://rowsandall.com/rowers/workout/2433/emailcsv,https://rowsandall.com/rowers/workout/2433/emailtcx,0,0,2018-02-12 14:29:01+00:00,3650,00:14:53.200000,Test,,America/Los_Angeles,rower,80.0,lwt -99,https://rowsandall.com/rowers/workout/2442/emailcsv,https://rowsandall.com/rowers/workout/2442/emailtcx,0,0,2018-02-12 14:29:01+00:00,3650,00:14:53.200000,Water,imported through email,America/Los_Angeles,water,80.0,lwt -100,https://rowsandall.com/rowers/workout/2444/emailcsv,https://rowsandall.com/rowers/workout/2444/emailtcx,0,0,2018-02-12 14:29:01+00:00,3650,00:14:53.200000,SpdCoach 2,imported through email,America/Los_Angeles,water,80.0,lwt -101,https://rowsandall.com/rowers/workout/2337/emailcsv,https://rowsandall.com/rowers/workout/2337/emailtcx,0,0,2018-02-12 14:49:02+00:00,1814,00:11:39,SpdCoach 3,,America/Los_Angeles,water,80.0,lwt -102,https://rowsandall.com/rowers/workout/2346/emailcsv,https://rowsandall.com/rowers/workout/2346/emailtcx,0,0,2018-02-12 14:49:02+00:00,1814,00:11:39,SpdCoach Sessions (3),imported through email,America/Los_Angeles,water,80.0,lwt -103,https://rowsandall.com/rowers/workout/2413/emailcsv,https://rowsandall.com/rowers/workout/2413/emailtcx,0,0,2018-02-12 14:49:02+00:00,1814,00:11:39,Test 4,,America/Los_Angeles,water,80.0,lwt -104,https://rowsandall.com/rowers/workout/2443/emailcsv,https://rowsandall.com/rowers/workout/2443/emailtcx,0,0,2018-02-12 14:49:02+00:00,1814,00:11:39,water weer,imported through email,America/Los_Angeles,water,80.0,lwt -105,https://rowsandall.com/rowers/workout/2678/emailcsv,https://rowsandall.com/rowers/workout/2678/emailtcx,0,0,2018-02-12 18:39:42+00:00,2014,00:08:37.700000,C2 Import Workout from 2018-02-12 18:39:42+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -106,https://rowsandall.com/rowers/workout/2677/emailcsv,https://rowsandall.com/rowers/workout/2677/emailtcx,0,0,2018-02-12 18:49:03+00:00,10562,00:46:12.400000,C2 Import Workout from 2018-02-12 18:49:03+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -107,https://rowsandall.com/rowers/workout/2676/emailcsv,https://rowsandall.com/rowers/workout/2676/emailtcx,0,0,2018-02-12 19:36:43+00:00,1998,00:09:39.800000,C2 Import Workout from 2018-02-12 19:36:43+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -108,https://rowsandall.com/rowers/workout/2675/emailcsv,https://rowsandall.com/rowers/workout/2675/emailtcx,0,0,2018-02-15 18:16:50+00:00,12440,00:51:41.500000,C2 Import Workout from 2018-02-15 18:16:50+00:00,imported from Concept2 log,UTC,rower,80.0,lwt -109,https://rowsandall.com/rowers/workout/2674/emailcsv,https://rowsandall.com/rowers/workout/2674/emailtcx,0,0,2018-02-15 19:08:28+00:00,14477,01:00:21.800000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -110,https://rowsandall.com/rowers/workout/2673/emailcsv,https://rowsandall.com/rowers/workout/2673/emailtcx,0,0,2018-02-16 14:24:03+00:00,3012,00:12:58.800000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -111,https://rowsandall.com/rowers/workout/2672/emailcsv,https://rowsandall.com/rowers/workout/2672/emailtcx,0,0,2018-02-16 14:37:40+00:00,5277,00:23:00,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -112,https://rowsandall.com/rowers/workout/2671/emailcsv,https://rowsandall.com/rowers/workout/2671/emailtcx,0,0,2018-02-16 15:01:29+00:00,1036,00:05:03.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -113,https://rowsandall.com/rowers/workout/2670/emailcsv,https://rowsandall.com/rowers/workout/2670/emailtcx,0,0,2018-02-16 15:07:03+00:00,5113,00:23:22,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -114,https://rowsandall.com/rowers/workout/2669/emailcsv,https://rowsandall.com/rowers/workout/2669/emailtcx,0,0,2018-02-16 15:34:40+00:00,1259,00:05:48.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -115,https://rowsandall.com/rowers/workout/2668/emailcsv,https://rowsandall.com/rowers/workout/2668/emailtcx,0,0,2018-02-18 13:30:59+00:00,13541,00:56:07.300000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -116,https://rowsandall.com/rowers/workout/2667/emailcsv,https://rowsandall.com/rowers/workout/2667/emailtcx,0,0,2018-02-20 18:08:13+00:00,2008,00:08:36.300000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -117,https://rowsandall.com/rowers/workout/2666/emailcsv,https://rowsandall.com/rowers/workout/2666/emailtcx,0,0,2018-02-20 18:17:17+00:00,10914,00:48:06.100000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -118,https://rowsandall.com/rowers/workout/2665/emailcsv,https://rowsandall.com/rowers/workout/2665/emailtcx,0,0,2018-02-20 19:06:36+00:00,1513,00:07:37.300000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -119,https://rowsandall.com/rowers/workout/2381/emailcsv,https://rowsandall.com/rowers/workout/2381/emailtcx,0,0,2018-02-21 06:26:01+00:00,6119,00:27:20.200000,3x2km Racice,,Europe/Prague,water,80.0,lwt -120,https://rowsandall.com/rowers/workout/2384/emailcsv,https://rowsandall.com/rowers/workout/2384/emailtcx,0,0,2018-02-22 09:32:01+00:00,8000,00:35:08.500000,8k trial,,Europe/Prague,water,80.0,lwt -121,https://rowsandall.com/rowers/workout/2664/emailcsv,https://rowsandall.com/rowers/workout/2664/emailtcx,0,0,2018-02-22 18:40:03+00:00,11481,00:49:17.400000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -122,https://rowsandall.com/rowers/workout/2663/emailcsv,https://rowsandall.com/rowers/workout/2663/emailtcx,0,0,2018-02-23 15:12:10+00:00,2008,00:08:44.800000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -123,https://rowsandall.com/rowers/workout/2383/emailcsv,https://rowsandall.com/rowers/workout/2383/emailtcx,0,0,2018-02-23 15:17:03+00:00,5918,00:25:10.700000,Horin,,Europe/Prague,water,80.0,lwt -124,https://rowsandall.com/rowers/workout/2662/emailcsv,https://rowsandall.com/rowers/workout/2662/emailtcx,0,0,2018-02-23 15:21:44+00:00,8804,00:39:58,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -125,https://rowsandall.com/rowers/workout/2661/emailcsv,https://rowsandall.com/rowers/workout/2661/emailtcx,0,0,2018-02-23 16:02:23+00:00,2008,00:09:05,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -126,https://rowsandall.com/rowers/workout/2385/emailcsv,https://rowsandall.com/rowers/workout/2385/emailtcx,0,0,2018-02-24 11:58:09+00:00,17045,01:35:59,Washington,,America/New_York,water,80.0,lwt -127,https://rowsandall.com/rowers/workout/2660/emailcsv,https://rowsandall.com/rowers/workout/2660/emailtcx,0,0,2018-02-24 15:07:07+00:00,14544,01:01:04.500000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -128,https://rowsandall.com/rowers/workout/2386/emailcsv,https://rowsandall.com/rowers/workout/2386/emailtcx,0,0,2018-02-25 12:24:59+00:00,6182,00:26:24.400000,9x500m/70sec,,Europe/Prague,rower,80.0,lwt -129,https://rowsandall.com/rowers/workout/2659/emailcsv,https://rowsandall.com/rowers/workout/2659/emailtcx,0,0,2018-02-25 14:15:13+00:00,16623,01:22:28,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -130,https://rowsandall.com/rowers/workout/2400/emailcsv,https://rowsandall.com/rowers/workout/2400/emailtcx,0,0,2018-02-25 22:45:28+00:00,4175,00:25:07.700000,Test CP,,Europe/Prague,rower,80.0,lwt -131,https://rowsandall.com/rowers/workout/2387/emailcsv,https://rowsandall.com/rowers/workout/2387/emailtcx,0,0,2018-02-27 13:19:44+00:00,2206,00:10:00,StatsError,,Europe/Prague,rower,80.0,lwt -132,https://rowsandall.com/rowers/workout/2658/emailcsv,https://rowsandall.com/rowers/workout/2658/emailtcx,0,0,2018-02-27 16:32:56+00:00,13549,00:56:44.900000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -133,https://rowsandall.com/rowers/workout/2657/emailcsv,https://rowsandall.com/rowers/workout/2657/emailtcx,0,0,2018-03-03 13:50:12+00:00,2012,00:08:42.700000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -134,https://rowsandall.com/rowers/workout/2656/emailcsv,https://rowsandall.com/rowers/workout/2656/emailtcx,0,0,2018-03-03 14:00:26+00:00,6270,00:26:41.700000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -135,https://rowsandall.com/rowers/workout/2655/emailcsv,https://rowsandall.com/rowers/workout/2655/emailtcx,0,0,2018-03-03 14:27:41+00:00,999,00:05:44.100000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -136,https://rowsandall.com/rowers/workout/2395/emailcsv,https://rowsandall.com/rowers/workout/2395/emailtcx,0,0,2018-03-03 14:33:51+00:00,6098,00:26:35.400000,Flex chart not working,,Europe/Prague,rower,80.0,lwt -137,https://rowsandall.com/rowers/workout/2654/emailcsv,https://rowsandall.com/rowers/workout/2654/emailtcx,0,0,2018-03-03 14:33:51+00:00,6098,00:26:35.400000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -138,https://rowsandall.com/rowers/workout/2653/emailcsv,https://rowsandall.com/rowers/workout/2653/emailtcx,0,0,2018-03-03 15:01:34+00:00,1559,00:07:16.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -139,https://rowsandall.com/rowers/workout/2392/emailcsv,https://rowsandall.com/rowers/workout/2392/emailtcx,0,0,2018-03-05 13:51:23+00:00,13802,01:06:00,Mike's average workout,,Europe/Prague,rower,80.0,lwt -140,https://rowsandall.com/rowers/workout/2396/emailcsv,https://rowsandall.com/rowers/workout/2396/emailtcx,0,0,2018-03-05 13:51:23+00:00,4058,00:17:00,Mike's average workout (1),,Europe/Prague,rower,80.0,lwt -141,https://rowsandall.com/rowers/workout/2397/emailcsv,https://rowsandall.com/rowers/workout/2397/emailtcx,0,0,2018-03-05 14:08:23+00:00,9738,00:49:00,Mike's average workout (2),,Europe/Prague,rower,80.0,lwt -142,https://rowsandall.com/rowers/workout/2389/emailcsv,https://rowsandall.com/rowers/workout/2389/emailtcx,0,0,2018-03-05 17:48:31+00:00,7022,00:29:44.400000,test,wat een kutsessie,Europe/Prague,rower,80.0,lwt -143,https://rowsandall.com/rowers/workout/2652/emailcsv,https://rowsandall.com/rowers/workout/2652/emailtcx,0,0,2018-03-05 17:48:31+00:00,7022,00:29:45.900000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -144,https://rowsandall.com/rowers/workout/2390/emailcsv,https://rowsandall.com/rowers/workout/2390/emailtcx,0,0,2018-03-05 17:50:46+00:00,5019,00:31:27.500000,,,Europe/Prague,rower,80.0,lwt -145,https://rowsandall.com/rowers/workout/2651/emailcsv,https://rowsandall.com/rowers/workout/2651/emailtcx,0,0,2018-03-08 18:34:05+00:00,2010,00:08:38.700000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -146,https://rowsandall.com/rowers/workout/2650/emailcsv,https://rowsandall.com/rowers/workout/2650/emailtcx,0,0,2018-03-08 18:43:29+00:00,10444,00:46:52.300000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -147,https://rowsandall.com/rowers/workout/2649/emailcsv,https://rowsandall.com/rowers/workout/2649/emailtcx,0,0,2018-03-08 19:31:31+00:00,269,00:01:42,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -148,https://rowsandall.com/rowers/workout/2398/emailcsv,https://rowsandall.com/rowers/workout/2398/emailtcx,0,0,2018-03-09 11:52:48+00:00,4160,00:13:00,test template,"Dit zijn de notes -Sommige zinnen zijn heel heel heel heel heel heel heel heel lang Sommige zinnen zijn heel heel heel heel heel heel heel heel lang Sommige zinnen zijn heel heel heel heel heel heel heel heel lang Sommige zinnen zijn heel heel heel heel heel heel heel heel lang -LAngwoordzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz",Europe/Prague,rower,80.0,lwt -149,https://rowsandall.com/rowers/workout/2399/emailcsv,https://rowsandall.com/rowers/workout/2399/emailtcx,0,0,2018-03-09 11:59:13+00:00,4160,00:13:00,Test P,,Europe/Prague,rower,80.0,lwt -150,https://rowsandall.com/rowers/workout/2401/emailcsv,https://rowsandall.com/rowers/workout/2401/emailtcx,0,0,2018-03-13 07:32:40+00:00,6479,00:30:27.300000,high power values?,,Europe/Prague,rower,80.0,lwt -151,https://rowsandall.com/rowers/workout/2648/emailcsv,https://rowsandall.com/rowers/workout/2648/emailtcx,0,0,2018-03-13 18:18:31+00:00,2009,00:08:30,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -152,https://rowsandall.com/rowers/workout/2404/emailcsv,https://rowsandall.com/rowers/workout/2404/emailtcx,0,0,2018-03-13 18:28:00.900000+00:00,9996,00:40:00,C2 Rower Timed. 10.0,"C2 Rower Timed. 10.0km, 40.00 min. (PainSled)",Europe/Prague,rower,80.0,lwt -153,https://rowsandall.com/rowers/workout/2405/emailcsv,https://rowsandall.com/rowers/workout/2405/emailtcx,0,0,2018-03-13 18:28:00.900000+00:00,10850,00:45:32.400000,C2 Rower Timed. 10.0,"C2 Rower Timed. 10.0km, 40.00 min. (PainSled)",Europe/Prague,rower,80.0,lwt -154,https://rowsandall.com/rowers/workout/2647/emailcsv,https://rowsandall.com/rowers/workout/2647/emailtcx,0,0,2018-03-13 18:28:01+00:00,10864,00:46:12.800000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -155,https://rowsandall.com/rowers/workout/2646/emailcsv,https://rowsandall.com/rowers/workout/2646/emailtcx,0,0,2018-03-13 19:15:15+00:00,1015,00:05:05.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -156,https://rowsandall.com/rowers/workout/2645/emailcsv,https://rowsandall.com/rowers/workout/2645/emailtcx,0,0,2018-03-13 19:18:21+00:00,2009,00:08:29.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,hwt -157,https://rowsandall.com/rowers/workout/2644/emailcsv,https://rowsandall.com/rowers/workout/2644/emailtcx,0,0,2018-03-13 19:28:00+00:00,9996,00:40:00,Imported workout,imported from Concept2 log,UTC,rower,80.0,hwt -158,https://rowsandall.com/rowers/workout/2402/emailcsv,https://rowsandall.com/rowers/workout/2402/emailtcx,0,0,2018-03-13 21:15:46+00:00,1311,00:13:04.100000,Stroke Count,,Europe/Prague,rower,80.0,lwt -159,https://rowsandall.com/rowers/workout/2403/emailcsv,https://rowsandall.com/rowers/workout/2403/emailtcx,0,0,2018-03-14 19:33:20+00:00,10850,00:45:32.400000,4x10min,,Europe/Prague,rower,80.0,lwt -160,https://rowsandall.com/rowers/workout/2406/emailcsv,https://rowsandall.com/rowers/workout/2406/emailtcx,0,0,2018-03-15 06:22:52+00:00,336,00:01:00,Test 1 minute,,Europe/Prague,rower,80.0,lwt -161,https://rowsandall.com/rowers/workout/2422/emailcsv,https://rowsandall.com/rowers/workout/2422/emailtcx,0,0,2018-03-15 06:22:52+00:00,8136,23:59:59.900000,Joined Workout,,Europe/Prague,rower,80.0,lwt -162,https://rowsandall.com/rowers/workout/2407/emailcsv,https://rowsandall.com/rowers/workout/2407/emailtcx,0,0,2018-03-15 06:23:09+00:00,7800,00:30:00,Thirty Dirty,,Europe/Prague,rower,80.0,lwt -163,https://rowsandall.com/rowers/workout/2434/emailcsv,https://rowsandall.com/rowers/workout/2434/emailtcx,0,0,2018-03-15 06:25:09+00:00,7800,23:59:59.900000,30 min,,Europe/Prague,rower,80.0,lwt -164,https://rowsandall.com/rowers/workout/2643/emailcsv,https://rowsandall.com/rowers/workout/2643/emailtcx,0,0,2018-03-15 18:48:48+00:00,2013,00:08:36.700000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -165,https://rowsandall.com/rowers/workout/2425/emailcsv,https://rowsandall.com/rowers/workout/2425/emailtcx,0,0,2018-03-15 18:58:08+00:00,10169,00:44:31.200000,Joined Workout,,Europe/Prague,rower,80.0,lwt -166,https://rowsandall.com/rowers/workout/2438/emailcsv,https://rowsandall.com/rowers/workout/2438/emailtcx,0,0,2018-03-15 18:58:08+00:00,8157,00:34:21.600000,Test,imported through email,Europe/Prague,rower,80.0,lwt -167,https://rowsandall.com/rowers/workout/2642/emailcsv,https://rowsandall.com/rowers/workout/2642/emailtcx,0,0,2018-03-15 18:58:08+00:00,8157,00:34:21.500000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -168,https://rowsandall.com/rowers/workout/2423/emailcsv,https://rowsandall.com/rowers/workout/2423/emailtcx,0,0,2018-03-15 18:58:08.620390+00:00,8157,00:34:21.600000,6x4min,,Europe/Prague,rower,80.0,lwt -169,https://rowsandall.com/rowers/workout/2431/emailcsv,https://rowsandall.com/rowers/workout/2431/emailtcx,0,0,2018-03-15 18:58:08.620390+00:00,8157,00:34:21.600000,Indoor,,Europe/Prague,rower,80.0,lwt -170,https://rowsandall.com/rowers/workout/2432/emailcsv,https://rowsandall.com/rowers/workout/2432/emailtcx,0,0,2018-03-15 18:58:08.620390+00:00,8157,00:34:21.600000,test,,Europe/Prague,rower,80.0,lwt -171,https://rowsandall.com/rowers/workout/2435/emailcsv,https://rowsandall.com/rowers/workout/2435/emailtcx,0,0,2018-03-15 18:58:08.620390+00:00,8157,00:34:21.600000,Test,,Europe/Prague,rower,80.0,lwt -172,https://rowsandall.com/rowers/workout/2436/emailcsv,https://rowsandall.com/rowers/workout/2436/emailtcx,0,0,2018-03-15 18:58:08.620390+00:00,8157,00:34:21.600000,r,,Europe/Prague,rower,80.0,lwt -173,https://rowsandall.com/rowers/workout/2437/emailcsv,https://rowsandall.com/rowers/workout/2437/emailtcx,0,0,2018-03-15 18:58:08.620390+00:00,8157,00:34:21.600000,a,,Europe/Prague,rower,80.0,lwt -174,https://rowsandall.com/rowers/workout/2440/emailcsv,https://rowsandall.com/rowers/workout/2440/emailtcx,0,0,2018-03-15 19:33:15+00:00,2012,00:09:24.300000,another one,imported through email,Europe/Prague,rower,80.0,lwt -175,https://rowsandall.com/rowers/workout/2641/emailcsv,https://rowsandall.com/rowers/workout/2641/emailtcx,0,0,2018-03-15 19:33:15+00:00,2012,00:09:24.300000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -176,https://rowsandall.com/rowers/workout/2424/emailcsv,https://rowsandall.com/rowers/workout/2424/emailtcx,0,0,2018-03-15 19:33:15.009331+00:00,2012,00:09:24.400000,6x4min,,Europe/Prague,rower,80.0,lwt -177,https://rowsandall.com/rowers/workout/2429/emailcsv,https://rowsandall.com/rowers/workout/2429/emailtcx,0,0,2018-03-16 12:04:52+00:00,9595,00:54:45,Joined Workout,,America/New_York,rower,80.0,lwt -178,https://rowsandall.com/rowers/workout/2426/emailcsv,https://rowsandall.com/rowers/workout/2426/emailtcx,0,0,2018-03-16 12:09:23+00:00,9269,00:50:14,Test P,,America/New_York,rower,80.0,lwt -179,https://rowsandall.com/rowers/workout/2428/emailcsv,https://rowsandall.com/rowers/workout/2428/emailtcx,0,0,2018-03-16 12:09:23+00:00,9269,00:50:14,,,America/New_York,rower,80.0,lwt -180,https://rowsandall.com/rowers/workout/2427/emailcsv,https://rowsandall.com/rowers/workout/2427/emailtcx,0,0,2018-03-16 13:00:52+00:00,326,00:04:03,Water Workout,,America/New_York,water,80.0,lwt -181,https://rowsandall.com/rowers/workout/2640/emailcsv,https://rowsandall.com/rowers/workout/2640/emailtcx,0,0,2018-03-17 14:14:56+00:00,15231,01:03:19.100000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -182,https://rowsandall.com/rowers/workout/2639/emailcsv,https://rowsandall.com/rowers/workout/2639/emailtcx,0,0,2018-03-18 14:03:27+00:00,3876,00:16:16.200000,Imported workout,imported from Concept2 log,UTC,slides,80.0,lwt -183,https://rowsandall.com/rowers/workout/2638/emailcsv,https://rowsandall.com/rowers/workout/2638/emailtcx,0,0,2018-03-18 14:20:52+00:00,6000,00:22:17.500000,Imported workout,imported from Concept2 log,UTC,slides,80.0,lwt -184,https://rowsandall.com/rowers/workout/2637/emailcsv,https://rowsandall.com/rowers/workout/2637/emailtcx,0,0,2018-03-18 14:44:46+00:00,4163,00:19:13.200000,Imported workout,imported from Concept2 log,UTC,slides,80.0,lwt -185,https://rowsandall.com/rowers/workout/2636/emailcsv,https://rowsandall.com/rowers/workout/2636/emailtcx,0,0,2018-03-22 18:38:59+00:00,2007,00:08:43.800000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -186,https://rowsandall.com/rowers/workout/2635/emailcsv,https://rowsandall.com/rowers/workout/2635/emailtcx,0,0,2018-03-22 18:48:29+00:00,6770,00:29:38.200000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -187,https://rowsandall.com/rowers/workout/2634/emailcsv,https://rowsandall.com/rowers/workout/2634/emailtcx,0,0,2018-03-22 19:18:50+00:00,2010,00:08:46.700000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -188,https://rowsandall.com/rowers/workout/2633/emailcsv,https://rowsandall.com/rowers/workout/2633/emailtcx,0,0,2018-03-24 09:20:07+00:00,15446,01:22:56.300000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -189,https://rowsandall.com/rowers/workout/2451/emailcsv,https://rowsandall.com/rowers/workout/2451/emailtcx,0,0,2018-03-25 09:59:12+00:00,29000,01:50:13,test,,Europe/Zurich,rower,80.0,lwt -190,https://rowsandall.com/rowers/workout/2452/emailcsv,https://rowsandall.com/rowers/workout/2452/emailtcx,0,0,2018-03-25 09:59:12+00:00,29000,01:50:13,Background processing test,imported through email,Europe/Zurich,water,80.0,lwt -191,https://rowsandall.com/rowers/workout/2632/emailcsv,https://rowsandall.com/rowers/workout/2632/emailtcx,0,0,2018-03-25 14:29:09+00:00,6664,00:46:07,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -192,https://rowsandall.com/rowers/workout/2453/emailcsv,https://rowsandall.com/rowers/workout/2453/emailtcx,0,0,2018-03-29 13:45:00+00:00,2000,07:25:00,test api,string,UTC,water,80.0,lwt -193,https://rowsandall.com/rowers/workout/2454/emailcsv,https://rowsandall.com/rowers/workout/2454/emailtcx,0,0,2018-04-02 11:02:55+00:00,3848,00:22:14.200000,RP3 curve,,Europe/Prague,rower,80.0,lwt -194,https://rowsandall.com/rowers/workout/2455/emailcsv,https://rowsandall.com/rowers/workout/2455/emailtcx,0,0,2018-04-02 11:04:18+00:00,3848,00:22:14.200000,,,Europe/Prague,rower,80.0,lwt -195,https://rowsandall.com/rowers/workout/2631/emailcsv,https://rowsandall.com/rowers/workout/2631/emailtcx,0,0,2018-04-03 14:34:01+00:00,2822,00:14:43.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -196,https://rowsandall.com/rowers/workout/2630/emailcsv,https://rowsandall.com/rowers/workout/2630/emailtcx,0,0,2018-04-03 14:50:01+00:00,7505,00:39:46.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -197,https://rowsandall.com/rowers/workout/2456/emailcsv,https://rowsandall.com/rowers/workout/2456/emailtcx,0,0,2018-04-03 15:50:52+00:00,7200,00:37:44,In Stroke,,Europe/Prague,water,80.0,lwt -198,https://rowsandall.com/rowers/workout/2457/emailcsv,https://rowsandall.com/rowers/workout/2457/emailtcx,0,0,2018-04-03 15:50:52+00:00,7200,00:37:44,In Stroke 2,,Europe/Prague,water,80.0,lwt -199,https://rowsandall.com/rowers/workout/2629/emailcsv,https://rowsandall.com/rowers/workout/2629/emailtcx,0,0,2018-04-04 18:30:27+00:00,27,00:00:03.200000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -200,https://rowsandall.com/rowers/workout/2628/emailcsv,https://rowsandall.com/rowers/workout/2628/emailtcx,0,0,2018-04-04 19:00:43+00:00,8309,00:48:07.400000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -201,https://rowsandall.com/rowers/workout/2458/emailcsv,https://rowsandall.com/rowers/workout/2458/emailtcx,0,0,2018-04-07 07:41:02+00:00,10568,01:06:08.800000,2x3km fail,,Europe/Prague,water,80.0,lwt -202,https://rowsandall.com/rowers/workout/2460/emailcsv,https://rowsandall.com/rowers/workout/2460/emailtcx,0,0,2018-04-07 07:41:02+00:00,10568,01:06:08.800000,Update,,Europe/Prague,water,80.0,lwt -203,https://rowsandall.com/rowers/workout/2627/emailcsv,https://rowsandall.com/rowers/workout/2627/emailtcx,0,0,2018-04-07 07:41:02+00:00,2243,00:12:20.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -204,https://rowsandall.com/rowers/workout/2626/emailcsv,https://rowsandall.com/rowers/workout/2626/emailtcx,0,0,2018-04-07 07:55:02+00:00,3167,00:16:59.800000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -205,https://rowsandall.com/rowers/workout/2625/emailcsv,https://rowsandall.com/rowers/workout/2625/emailtcx,0,0,2018-04-07 08:14:02+00:00,2977,00:14:58,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -206,https://rowsandall.com/rowers/workout/2623/emailcsv,https://rowsandall.com/rowers/workout/2623/emailtcx,0,0,2018-04-07 08:33:03+00:00,2180,00:14:07.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -207,https://rowsandall.com/rowers/workout/2622/emailcsv,https://rowsandall.com/rowers/workout/2622/emailtcx,0,0,2018-04-10 17:38:22+00:00,11703,00:48:59.500000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -208,https://rowsandall.com/rowers/workout/2621/emailcsv,https://rowsandall.com/rowers/workout/2621/emailtcx,0,0,2018-04-10 18:27:53+00:00,17284,01:11:55.500000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -209,https://rowsandall.com/rowers/workout/2620/emailcsv,https://rowsandall.com/rowers/workout/2620/emailtcx,0,0,2018-04-11 18:37:27+00:00,10122,01:15:44.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -210,https://rowsandall.com/rowers/workout/2619/emailcsv,https://rowsandall.com/rowers/workout/2619/emailtcx,0,0,2018-04-12 16:17:02+00:00,10408,00:53:45.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -211,https://rowsandall.com/rowers/workout/2618/emailcsv,https://rowsandall.com/rowers/workout/2618/emailtcx,0,0,2018-04-15 08:34:05+00:00,11129,01:03:38,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -212,https://rowsandall.com/rowers/workout/2617/emailcsv,https://rowsandall.com/rowers/workout/2617/emailtcx,0,0,2018-04-18 13:43:04+00:00,1942,00:10:55.300000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -213,https://rowsandall.com/rowers/workout/2616/emailcsv,https://rowsandall.com/rowers/workout/2616/emailtcx,0,0,2018-04-18 13:57:01+00:00,7979,00:36:10.600000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -214,https://rowsandall.com/rowers/workout/2615/emailcsv,https://rowsandall.com/rowers/workout/2615/emailtcx,0,0,2018-04-18 14:49:06+00:00,1512,00:08:27.600000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -215,https://rowsandall.com/rowers/workout/2614/emailcsv,https://rowsandall.com/rowers/workout/2614/emailtcx,0,0,2018-04-20 15:51:41+00:00,9748,01:06:50.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -216,https://rowsandall.com/rowers/workout/2613/emailcsv,https://rowsandall.com/rowers/workout/2613/emailtcx,0,0,2018-04-21 15:38:04+00:00,5254,00:27:02.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -217,https://rowsandall.com/rowers/workout/2612/emailcsv,https://rowsandall.com/rowers/workout/2612/emailtcx,0,0,2018-04-22 07:15:01+00:00,12282,01:08:28.600000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -218,https://rowsandall.com/rowers/workout/2471/emailcsv,https://rowsandall.com/rowers/workout/2471/emailtcx,0,0,2018-04-23 11:00:00+00:00,1017,00:03:55.200000,7x150min/1min,,America/New_York,water,80.0,lwt -219,https://rowsandall.com/rowers/workout/2472/emailcsv,https://rowsandall.com/rowers/workout/2472/emailtcx,0,0,2018-04-23 11:00:00+00:00,1017,00:03:55.200000,7x15min test 2,,America/New_York,water,80.0,lwt -220,https://rowsandall.com/rowers/workout/2473/emailcsv,https://rowsandall.com/rowers/workout/2473/emailtcx,0,0,2018-04-23 11:00:00+00:00,1017,00:03:55.200000,7x150min/1min,,America/New_York,water,80.0,lwt -221,https://rowsandall.com/rowers/workout/2474/emailcsv,https://rowsandall.com/rowers/workout/2474/emailtcx,0,0,2018-04-23 11:00:00+00:00,1017,00:03:55,test firmware,,America/New_York,water,80.0,lwt -222,https://rowsandall.com/rowers/workout/2478/emailcsv,https://rowsandall.com/rowers/workout/2478/emailtcx,0,0,2018-04-23 11:00:00+00:00,1017,00:03:55.200000,Firmware 2,,America/New_York,water,80.0,lwt -223,https://rowsandall.com/rowers/workout/2611/emailcsv,https://rowsandall.com/rowers/workout/2611/emailtcx,0,0,2018-04-23 17:46:25+00:00,13558,00:58:11.900000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -224,https://rowsandall.com/rowers/workout/2465/emailcsv,https://rowsandall.com/rowers/workout/2465/emailtcx,0,0,2018-04-23 20:42:00+00:00,8000,00:36:01.500000,Racice,,Europe/Prague,water,80.0,lwt -225,https://rowsandall.com/rowers/workout/2610/emailcsv,https://rowsandall.com/rowers/workout/2610/emailtcx,0,0,2018-04-24 12:12:03+00:00,2959,00:16:42.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -226,https://rowsandall.com/rowers/workout/2609/emailcsv,https://rowsandall.com/rowers/workout/2609/emailtcx,0,0,2018-04-24 12:32:00+00:00,7516,00:38:49.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -227,https://rowsandall.com/rowers/workout/2466/emailcsv,https://rowsandall.com/rowers/workout/2466/emailtcx,0,0,2018-04-24 13:35:30+00:00,9420,00:48:00,,,Europe/Prague,water,80.0,lwt -228,https://rowsandall.com/rowers/workout/2608/emailcsv,https://rowsandall.com/rowers/workout/2608/emailtcx,0,0,2018-04-25 17:50:26+00:00,10171,01:12:33.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -229,https://rowsandall.com/rowers/workout/2470/emailcsv,https://rowsandall.com/rowers/workout/2470/emailtcx,0,0,2018-04-25 22:59:01+00:00,4159,00:26:43.200000,SpeedCoach 7x150m,,America/New_York,water,80.0,lwt -230,https://rowsandall.com/rowers/workout/2607/emailcsv,https://rowsandall.com/rowers/workout/2607/emailtcx,0,0,2018-04-26 16:18:01+00:00,2016,00:12:30.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -231,https://rowsandall.com/rowers/workout/2606/emailcsv,https://rowsandall.com/rowers/workout/2606/emailtcx,0,0,2018-04-26 16:33:00+00:00,4605,00:22:35.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -232,https://rowsandall.com/rowers/workout/2605/emailcsv,https://rowsandall.com/rowers/workout/2605/emailtcx,0,0,2018-04-26 16:56:03+00:00,1301,00:07:07.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -233,https://rowsandall.com/rowers/workout/2604/emailcsv,https://rowsandall.com/rowers/workout/2604/emailtcx,0,0,2018-04-28 08:02:01+00:00,11924,01:18:20.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -234,https://rowsandall.com/rowers/workout/2469/emailcsv,https://rowsandall.com/rowers/workout/2469/emailtcx,0,0,2018-04-29 07:22:01+00:00,8040,00:50:06,Test P,,America/New_York,water,80.0,lwt -235,https://rowsandall.com/rowers/workout/2603/emailcsv,https://rowsandall.com/rowers/workout/2603/emailtcx,0,0,2018-04-29 07:22:01+00:00,8040,00:50:05.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -236,https://rowsandall.com/rowers/workout/2559/emailcsv,https://rowsandall.com/rowers/workout/2559/emailtcx,0,0,2018-05-03 16:02:08+00:00,10909,01:00:35,Intervals Tests (6),imported through email,Europe/Amsterdam,water,80.0,lwt -237,https://rowsandall.com/rowers/workout/2602/emailcsv,https://rowsandall.com/rowers/workout/2602/emailtcx,0,0,2018-05-04 05:47:04+00:00,3472,00:18:53.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -238,https://rowsandall.com/rowers/workout/2479/emailcsv,https://rowsandall.com/rowers/workout/2479/emailtcx,0,0,2018-05-04 06:07:04+00:00,5997,00:25:53.900000,Zip test,imported through email,Europe/Prague,water,80.0,lwt -239,https://rowsandall.com/rowers/workout/2481/emailcsv,https://rowsandall.com/rowers/workout/2481/emailtcx,0,0,2018-05-04 06:07:04+00:00,5997,00:25:53.900000,Zip test 2,imported through email,Europe/Prague,water,80.0,lwt -240,https://rowsandall.com/rowers/workout/2483/emailcsv,https://rowsandall.com/rowers/workout/2483/emailtcx,0,0,2018-05-04 06:07:04+00:00,5997,00:25:53.900000,Test Zip 3,imported through email,Europe/Prague,water,80.0,lwt -241,https://rowsandall.com/rowers/workout/2601/emailcsv,https://rowsandall.com/rowers/workout/2601/emailtcx,0,0,2018-05-04 06:07:04+00:00,5997,00:25:53.900000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -242,https://rowsandall.com/rowers/workout/2860/emailcsv,https://rowsandall.com/rowers/workout/2860/emailtcx,0,0,2018-05-04 06:07:04+00:00,5997,00:25:53.900000,Zip test,"imported through email - from speedcoach2v2.15 via rowsandall.com",Europe/Prague,water,80.0,hwt -243,https://rowsandall.com/rowers/workout/2600/emailcsv,https://rowsandall.com/rowers/workout/2600/emailtcx,0,0,2018-05-04 06:35:04+00:00,1009,00:06:44.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -244,https://rowsandall.com/rowers/workout/2599/emailcsv,https://rowsandall.com/rowers/workout/2599/emailtcx,0,0,2018-05-05 07:06:02+00:00,11180,01:01:01.600000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -245,https://rowsandall.com/rowers/workout/2598/emailcsv,https://rowsandall.com/rowers/workout/2598/emailtcx,0,0,2018-05-05 08:11:04+00:00,1152,00:06:56.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -246,https://rowsandall.com/rowers/workout/2597/emailcsv,https://rowsandall.com/rowers/workout/2597/emailtcx,0,0,2018-05-07 15:41:06+00:00,11019,01:00:40.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -247,https://rowsandall.com/rowers/workout/2490/emailcsv,https://rowsandall.com/rowers/workout/2490/emailtcx,0,0,2018-05-10 09:11:24+00:00,15263,01:39:34,Naarden goed,,Europe/Amsterdam,water,80.0,lwt -248,https://rowsandall.com/rowers/workout/2491/emailcsv,https://rowsandall.com/rowers/workout/2491/emailtcx,0,0,2018-05-10 09:11:24+00:00,7378,00:44:59,Naarden goed (1),,Europe/Amsterdam,water,80.0,lwt -249,https://rowsandall.com/rowers/workout/2492/emailcsv,https://rowsandall.com/rowers/workout/2492/emailtcx,0,0,2018-05-10 09:56:24+00:00,7876,00:54:33,Naarden goed (2),,Europe/Amsterdam,water,80.0,lwt -250,https://rowsandall.com/rowers/workout/2596/emailcsv,https://rowsandall.com/rowers/workout/2596/emailtcx,0,0,2018-05-10 16:15:02+00:00,11983,01:01:26,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -251,https://rowsandall.com/rowers/workout/2485/emailcsv,https://rowsandall.com/rowers/workout/2485/emailtcx,0,0,2018-05-10 16:55:01+00:00,8000,00:36:01.500000,6k,,Europe/Prague,water,80.0,lwt -252,https://rowsandall.com/rowers/workout/2486/emailcsv,https://rowsandall.com/rowers/workout/2486/emailtcx,0,0,2018-05-10 16:55:01+00:00,8000,00:36:01.500000,Racice 2,,Europe/Prague,water,80.0,lwt -253,https://rowsandall.com/rowers/workout/2488/emailcsv,https://rowsandall.com/rowers/workout/2488/emailtcx,0,0,2018-05-11 07:02:52+00:00,15364,01:22:34,Naarden 1,,Europe/Amsterdam,water,80.0,lwt -254,https://rowsandall.com/rowers/workout/2504/emailcsv,https://rowsandall.com/rowers/workout/2504/emailtcx,0,0,2018-05-12 10:01:00+00:00,16814,01:42:53,DC,"Summary for your location at 2018-05-12T12:52:00Z: Temperature 21.1C/69.9F. Wind: 3.0 m/s (6.0 kt). Wind Bearing: 30.0 degrees -Summary for your location at 2018-05-12T10:52:00Z: Temperature 19.4C/66.9F. Wind: 3.0 m/s (6.0 kt). Wind Bearing: 40.0 degrees -Summary for your location at 2018-05-12T11:52:00Z: Temperature 20.6C/69.0F. Wind: 3.6 m/s (7.0 kt). Wind Bearing: 20.0 degrees -Summary for your location at 2018-05-12T10:52:26+00:00: Clear. Temperature 64.52F/18.0C. Wind: 0.96 m/s. Wind Bearing: 29 degrees",America/New_York,water,80.0,lwt -255,https://rowsandall.com/rowers/workout/2931/emailcsv,https://rowsandall.com/rowers/workout/2931/emailtcx,0,0,2018-05-12 14:22:12+00:00,6510,00:46:56,Test P,,Europe/Bratislava,water,80.0,hwt -256,https://rowsandall.com/rowers/workout/2513/emailcsv,https://rowsandall.com/rowers/workout/2513/emailtcx,0,0,2018-05-13 07:57:02+00:00,4605,00:35:11.700000,Quad,,Europe/Bratislava,water,80.0,lwt -257,https://rowsandall.com/rowers/workout/2595/emailcsv,https://rowsandall.com/rowers/workout/2595/emailtcx,0,0,2018-05-13 07:57:02+00:00,4605,00:35:11.600000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -258,https://rowsandall.com/rowers/workout/2502/emailcsv,https://rowsandall.com/rowers/workout/2502/emailtcx,0,0,2018-05-13 09:22:49+00:00,973,00:03:53.900000,Completed a workout (generic) 0.6 mi on 05/13/18,,Europe/Bratislava,water,80.0,lwt -259,https://rowsandall.com/rowers/workout/2503/emailcsv,https://rowsandall.com/rowers/workout/2503/emailtcx,0,0,2018-05-13 09:22:49+00:00,973,00:03:53.900000,Completed a workout (generic) 0.6 mi on 05/13/18,,Europe/Bratislava,water,80.0,lwt -260,https://rowsandall.com/rowers/workout/2594/emailcsv,https://rowsandall.com/rowers/workout/2594/emailtcx,0,0,2018-05-13 16:50:32+00:00,2723,00:27:17.200000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -261,https://rowsandall.com/rowers/workout/2593/emailcsv,https://rowsandall.com/rowers/workout/2593/emailtcx,0,0,2018-05-13 16:51:01+00:00,5929,00:43:44.500000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -262,https://rowsandall.com/rowers/workout/2855/emailcsv,https://rowsandall.com/rowers/workout/2855/emailtcx,0,0,2018-05-14 13:53:04+00:00,6091,00:25:00.200000,Hradiste," - from csv via rowsandall.com",Europe/Prague,water,80.0,lwt -263,https://rowsandall.com/rowers/workout/2963/emailcsv,https://rowsandall.com/rowers/workout/2963/emailtcx,0,0,2018-05-14 13:53:04+00:00,6091,00:25:00.200000,Hradiste," - from csv via rowsandall.com",Europe/Prague,water,80.0,hwt -264,https://rowsandall.com/rowers/workout/2493/emailcsv,https://rowsandall.com/rowers/workout/2493/emailtcx,0,0,2018-05-15 10:35:00+00:00,10526,00:44:01.700000,Turin,,Europe/Rome,water,80.0,lwt -265,https://rowsandall.com/rowers/workout/2489/emailcsv,https://rowsandall.com/rowers/workout/2489/emailtcx,0,0,2018-05-17 17:40:00+00:00,15364,01:22:34,Naarden 2,,Europe/Amsterdam,water,80.0,lwt -266,https://rowsandall.com/rowers/workout/2464/emailcsv,https://rowsandall.com/rowers/workout/2464/emailtcx,0,0,2018-05-18 13:02:00+00:00,6091,00:25:00.200000,Hradiste,"Failed to download METAR data -Failed to download METAR data -Failed to download METAR data -Failed to download METAR data -Failed to download METAR data",Europe/Prague,water,80.0,lwt -267,https://rowsandall.com/rowers/workout/2505/emailcsv,https://rowsandall.com/rowers/workout/2505/emailtcx,0,0,2018-05-19 11:55:34+00:00,14274,01:12:33.600000,Roos,,America/New_York,water,80.0,lwt -268,https://rowsandall.com/rowers/workout/2506/emailcsv,https://rowsandall.com/rowers/workout/2506/emailtcx,0,0,2018-05-19 11:55:34+00:00,7384,00:33:59.800000,Roos (1),,America/New_York,water,80.0,lwt -269,https://rowsandall.com/rowers/workout/2507/emailcsv,https://rowsandall.com/rowers/workout/2507/emailtcx,0,0,2018-05-19 12:29:34+00:00,6885,00:38:32.200000,Roos (2),,America/New_York,water,80.0,lwt -270,https://rowsandall.com/rowers/workout/2511/emailcsv,https://rowsandall.com/rowers/workout/2511/emailtcx,0,0,2018-05-27 10:17:01+00:00,10663,00:59:29.700000,Test P,,Europe/Prague,water,80.0,lwt -271,https://rowsandall.com/rowers/workout/2518/emailcsv,https://rowsandall.com/rowers/workout/2518/emailtcx,0,0,2018-05-27 10:17:01+00:00,10663,00:59:29.700000,dubbel,,Europe/Prague,water,80.0,lwt -272,https://rowsandall.com/rowers/workout/2592/emailcsv,https://rowsandall.com/rowers/workout/2592/emailtcx,0,0,2018-05-27 10:17:01+00:00,10663,00:59:29.600000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -273,https://rowsandall.com/rowers/workout/2591/emailcsv,https://rowsandall.com/rowers/workout/2591/emailtcx,0,0,2018-05-28 15:11:01+00:00,9642,00:56:16.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -274,https://rowsandall.com/rowers/workout/2514/emailcsv,https://rowsandall.com/rowers/workout/2514/emailtcx,0,0,2018-05-30 18:05:25+00:00,11237,01:04:45.500000,Eight,imported through email,Europe/Prague,water,80.0,lwt -275,https://rowsandall.com/rowers/workout/2516/emailcsv,https://rowsandall.com/rowers/workout/2516/emailtcx,0,0,2018-05-30 18:05:25+00:00,11237,01:04:45.500000,Twee Zonder,imported through email,Europe/Prague,water,80.0,lwt -276,https://rowsandall.com/rowers/workout/2590/emailcsv,https://rowsandall.com/rowers/workout/2590/emailtcx,0,0,2018-05-30 18:05:25+00:00,11237,01:04:45.500000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -277,https://rowsandall.com/rowers/workout/2512/emailcsv,https://rowsandall.com/rowers/workout/2512/emailtcx,0,0,2018-05-31 16:30:07+00:00,8837,00:47:42.500000,Test,,Europe/Prague,water,80.0,lwt -278,https://rowsandall.com/rowers/workout/2589/emailcsv,https://rowsandall.com/rowers/workout/2589/emailtcx,0,0,2018-05-31 16:30:07+00:00,8837,00:47:42.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -279,https://rowsandall.com/rowers/workout/2508/emailcsv,https://rowsandall.com/rowers/workout/2508/emailtcx,0,0,2018-06-01 07:57:02+00:00,4605,00:35:11.700000,Piestany,,Europe/Bratislava,water,80.0,lwt -280,https://rowsandall.com/rowers/workout/2510/emailcsv,https://rowsandall.com/rowers/workout/2510/emailtcx,0,0,2018-06-01 08:02:02+00:00,3975,00:30:08.700000,Piestany (2),,Europe/Bratislava,water,80.0,lwt -281,https://rowsandall.com/rowers/workout/2509/emailcsv,https://rowsandall.com/rowers/workout/2509/emailtcx,0,0,2018-06-01 11:30:07+00:00,8837,00:47:42.500000,Test,,Europe/Prague,water,80.0,lwt -282,https://rowsandall.com/rowers/workout/2569/emailcsv,https://rowsandall.com/rowers/workout/2569/emailtcx,0,0,2018-06-01 15:00:00+00:00,11237,01:04:45.500000,Acht Intervals,,Europe/Prague,water,80.0,lwt -283,https://rowsandall.com/rowers/workout/2588/emailcsv,https://rowsandall.com/rowers/workout/2588/emailtcx,0,0,2018-06-02 17:00:07+00:00,12511,01:07:58,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -284,https://rowsandall.com/rowers/workout/2587/emailcsv,https://rowsandall.com/rowers/workout/2587/emailtcx,0,0,2018-06-03 07:57:02+00:00,10830,01:04:35.900000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -285,https://rowsandall.com/rowers/workout/2586/emailcsv,https://rowsandall.com/rowers/workout/2586/emailtcx,0,0,2018-06-03 15:50:25+00:00,6125,00:48:38.600000,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -286,https://rowsandall.com/rowers/workout/2535/emailcsv,https://rowsandall.com/rowers/workout/2535/emailtcx,0,0,2018-06-05 13:07:02+00:00,0,00:05:01,Test - Delete,,Europe/Prague,rower,80.0,lwt -287,https://rowsandall.com/rowers/workout/2536/emailcsv,https://rowsandall.com/rowers/workout/2536/emailtcx,0,0,2018-06-05 13:07:02+00:00,0,00:05:01,Test Sync - Delete," - from tcx via rowsandall.com",Europe/Prague,rower,80.0,lwt -288,https://rowsandall.com/rowers/workout/2537/emailcsv,https://rowsandall.com/rowers/workout/2537/emailtcx,0,0,2018-06-05 13:07:02+00:00,0,00:05:01,Test P," - from tcx via rowsandall.com",Europe/Prague,rower,80.0,lwt -289,https://rowsandall.com/rowers/workout/2538/emailcsv,https://rowsandall.com/rowers/workout/2538/emailtcx,0,0,2018-06-05 13:07:02+00:00,0,00:05:01,Test P,imported through email,Europe/Prague,rower,80.0,lwt -290,https://rowsandall.com/rowers/workout/2539/emailcsv,https://rowsandall.com/rowers/workout/2539/emailtcx,0,0,2018-06-05 13:07:02+00:00,0,00:05:01,Test P,"imported through email - from tcx via rowsandall.com",Europe/Prague,rower,80.0,lwt -291,https://rowsandall.com/rowers/workout/2540/emailcsv,https://rowsandall.com/rowers/workout/2540/emailtcx,0,0,2018-06-05 13:07:02+00:00,0,00:05:01,Workout from Background Queue,imported through email,Europe/Prague,rower,80.0,lwt -292,https://rowsandall.com/rowers/workout/2624/emailcsv,https://rowsandall.com/rowers/workout/2624/emailtcx,0,0,2018-06-05 13:51:01.900000+00:00,12744,01:08:22.100000,imported through ema,imported through email,Europe/Prague,water,80.0,lwt -293,https://rowsandall.com/rowers/workout/2534/emailcsv,https://rowsandall.com/rowers/workout/2534/emailtcx,0,0,2018-06-05 14:05:02+00:00,0,00:01:33,Import from Polar Flow,imported through email,Europe/Prague,rower,80.0,lwt -294,https://rowsandall.com/rowers/workout/2519/emailcsv,https://rowsandall.com/rowers/workout/2519/emailtcx,0,0,2018-06-05 14:09:57+00:00,0,00:03:38,TCX from Polar API,,Europe/Prague,water,80.0,lwt -295,https://rowsandall.com/rowers/workout/2546/emailcsv,https://rowsandall.com/rowers/workout/2546/emailtcx,0,0,2018-06-05 15:51:01+00:00,12744,01:08:22.200000,8x glad,,Europe/Prague,water,80.0,lwt -296,https://rowsandall.com/rowers/workout/2547/emailcsv,https://rowsandall.com/rowers/workout/2547/emailtcx,0,0,2018-06-05 15:51:01+00:00,12746,01:08:22.200000,1x glad,,Europe/Prague,c-boat,80.0,lwt -297,https://rowsandall.com/rowers/workout/2548/emailcsv,https://rowsandall.com/rowers/workout/2548/emailtcx,0,68,2018-06-05 15:51:01+00:00,12744,01:08:22.200000,1x glad,,Europe/Prague,water,80.0,lwt -298,https://rowsandall.com/rowers/workout/2549/emailcsv,https://rowsandall.com/rowers/workout/2549/emailtcx,0,0,2018-06-05 15:51:01+00:00,12746,01:08:22.200000,test,,Europe/Prague,water,80.0,lwt -299,https://rowsandall.com/rowers/workout/2550/emailcsv,https://rowsandall.com/rowers/workout/2550/emailtcx,0,0,2018-06-05 15:51:01+00:00,12746,01:08:22.200000,test tcx,,Europe/Prague,water,80.0,lwt -300,https://rowsandall.com/rowers/workout/2552/emailcsv,https://rowsandall.com/rowers/workout/2552/emailtcx,0,0,2018-06-05 15:51:01+00:00,6522,00:33:00,8x glad (1),,Europe/Prague,water,80.0,lwt -301,https://rowsandall.com/rowers/workout/2585/emailcsv,https://rowsandall.com/rowers/workout/2585/emailtcx,0,0,2018-06-05 15:51:01+00:00,12744,01:08:22.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -302,https://rowsandall.com/rowers/workout/2553/emailcsv,https://rowsandall.com/rowers/workout/2553/emailtcx,0,0,2018-06-05 16:24:01+00:00,6213,00:35:19.500000,8x glad (2),,Europe/Prague,water,80.0,lwt -303,https://rowsandall.com/rowers/workout/2584/emailcsv,https://rowsandall.com/rowers/workout/2584/emailtcx,0,0,2018-06-06 17:40:24+00:00,5273,00:42:59,Imported workout,imported from Concept2 log,UTC,rower,80.0,lwt -304,https://rowsandall.com/rowers/workout/2545/emailcsv,https://rowsandall.com/rowers/workout/2545/emailtcx,0,0,2018-06-08 07:25:33+00:00,1994,00:01:59.400000,Test,,Europe/Prague,rower,80.0,hwt -305,https://rowsandall.com/rowers/workout/2560/emailcsv,https://rowsandall.com/rowers/workout/2560/emailtcx,0,0,2018-06-11 15:21:01+00:00,10369,00:56:21.400000,Intervals Tests (7),imported through email,Europe/Prague,water,80.0,lwt -306,https://rowsandall.com/rowers/workout/2568/emailcsv,https://rowsandall.com/rowers/workout/2568/emailtcx,0,11,2018-06-11 15:21:01+00:00,10369,00:56:21.400000,3/2/1," - 5x5min/5min - 5x5min/5min",Europe/Prague,water,80.0,lwt -307,https://rowsandall.com/rowers/workout/2583/emailcsv,https://rowsandall.com/rowers/workout/2583/emailtcx,0,0,2018-06-11 15:21:01+00:00,10369,00:56:21.400000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -308,https://rowsandall.com/rowers/workout/2554/emailcsv,https://rowsandall.com/rowers/workout/2554/emailtcx,0,0,2018-06-13 14:18:19+00:00,16543,01:30:01.300000,Intervals Tests,,America/New_York,rower,80.0,lwt -309,https://rowsandall.com/rowers/workout/2555/emailcsv,https://rowsandall.com/rowers/workout/2555/emailtcx,0,0,2018-06-13 14:18:35+00:00,12205,01:03:29.500000,Intervals Tests (2),,America/New_York,rower,80.0,lwt -310,https://rowsandall.com/rowers/workout/2556/emailcsv,https://rowsandall.com/rowers/workout/2556/emailtcx,0,0,2018-06-13 14:18:48+00:00,9016,00:48:28.100000,Intervals Tests (3)," - 9x1km",America/New_York,rower,80.0,lwt -311,https://rowsandall.com/rowers/workout/2557/emailcsv,https://rowsandall.com/rowers/workout/2557/emailtcx,0,0,2018-06-13 14:19:01+00:00,4789,00:22:05,Intervals Tests (4),,America/New_York,rower,80.0,lwt -312,https://rowsandall.com/rowers/workout/2558/emailcsv,https://rowsandall.com/rowers/workout/2558/emailtcx,0,0,2018-06-13 14:19:19+00:00,0,00:22:54,Intervals Tests (5),,Europe/Prague,rower,80.0,lwt -313,https://rowsandall.com/rowers/workout/2582/emailcsv,https://rowsandall.com/rowers/workout/2582/emailtcx,0,0,2018-06-13 16:11:02+00:00,4191,00:23:36.400000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -314,https://rowsandall.com/rowers/workout/2581/emailcsv,https://rowsandall.com/rowers/workout/2581/emailtcx,0,0,2018-06-15 08:05:04+00:00,7301,00:39:44.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -315,https://rowsandall.com/rowers/workout/2580/emailcsv,https://rowsandall.com/rowers/workout/2580/emailtcx,0,0,2018-06-16 08:04:00+00:00,5182,00:40:48.100000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -316,https://rowsandall.com/rowers/workout/2579/emailcsv,https://rowsandall.com/rowers/workout/2579/emailtcx,0,0,2018-06-16 13:17:06+00:00,8196,00:52:10.500000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -317,https://rowsandall.com/rowers/workout/2950/emailcsv,https://rowsandall.com/rowers/workout/2950/emailtcx,0,0,2018-06-17 10:23:24+00:00,6004,01:00:54,Lunch Run,,Europe/Vienna,water,80.0,hwt -318,https://rowsandall.com/rowers/workout/2954/emailcsv,https://rowsandall.com/rowers/workout/2954/emailtcx,0,0,2018-06-17 10:23:24+00:00,6004,01:00:54,Lunch Run,,Europe/Vienna,water,80.0,hwt -319,https://rowsandall.com/rowers/workout/3035/emailcsv,https://rowsandall.com/rowers/workout/3035/emailtcx,0,17,2018-06-17 10:23:24+00:00,6004,01:00:54,Lunch Run, ,Europe/Vienna,other,80.0,hwt -320,https://rowsandall.com/rowers/workout/2578/emailcsv,https://rowsandall.com/rowers/workout/2578/emailtcx,0,0,2018-06-18 16:05:05+00:00,10313,00:55:54.900000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -321,https://rowsandall.com/rowers/workout/2948/emailcsv,https://rowsandall.com/rowers/workout/2948/emailtcx,0,0,2018-06-18 16:05:05+00:00,10313,00:55:54,Steady,,Europe/Prague,water,80.0,hwt -322,https://rowsandall.com/rowers/workout/2952/emailcsv,https://rowsandall.com/rowers/workout/2952/emailtcx,0,0,2018-06-18 16:05:05+00:00,10313,00:55:54,Steady,,Europe/Prague,water,80.0,hwt -323,https://rowsandall.com/rowers/workout/2573/emailcsv,https://rowsandall.com/rowers/workout/2573/emailtcx,0,0,2018-06-19 05:57:02+00:00,10437,00:56:06.900000,Pink,,Europe/Prague,water,80.0,lwt -324,https://rowsandall.com/rowers/workout/2577/emailcsv,https://rowsandall.com/rowers/workout/2577/emailtcx,0,0,2018-06-19 05:57:02+00:00,10437,00:56:06.900000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -325,https://rowsandall.com/rowers/workout/2946/emailcsv,https://rowsandall.com/rowers/workout/2946/emailtcx,0,0,2018-06-19 05:57:04+00:00,10437,00:56:04,3x6min,,Europe/Prague,water,80.0,hwt -326,https://rowsandall.com/rowers/workout/2570/emailcsv,https://rowsandall.com/rowers/workout/2570/emailtcx,0,0,2018-06-19 15:11:14.220000+00:00,7538,00:56:14.600000,Test,,Europe/Vienna,water,80.0,lwt -327,https://rowsandall.com/rowers/workout/2571/emailcsv,https://rowsandall.com/rowers/workout/2571/emailtcx,0,0,2018-06-20 18:24:08+00:00,7538,00:56:14.500000,Ritmo,,Europe/Vienna,water,80.0,lwt -328,https://rowsandall.com/rowers/workout/2858/emailcsv,https://rowsandall.com/rowers/workout/2858/emailtcx,0,0,2018-06-22 04:33:02.500000+00:00,3344,00:16:55.700000,imported through ema,imported through email,Europe/Prague,water,80.0,hwt -329,https://rowsandall.com/rowers/workout/2576/emailcsv,https://rowsandall.com/rowers/workout/2576/emailtcx,0,0,2018-06-22 05:41:04+00:00,9298,00:50:44,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -330,https://rowsandall.com/rowers/workout/2944/emailcsv,https://rowsandall.com/rowers/workout/2944/emailtcx,0,0,2018-06-22 05:41:04+00:00,9298,00:50:44,Steady,,Europe/Prague,water,80.0,hwt -331,https://rowsandall.com/rowers/workout/2575/emailcsv,https://rowsandall.com/rowers/workout/2575/emailtcx,0,0,2018-06-22 06:33:01+00:00,3344,00:16:55.700000,Imported workout,imported from Concept2 log,UTC,water,80.0,lwt -332,https://rowsandall.com/rowers/workout/2942/emailcsv,https://rowsandall.com/rowers/workout/2942/emailtcx,27,11,2018-06-22 06:33:02+00:00,3344,00:16:54,Steady (2),,Europe/Prague,water,80.0,hwt -333,https://rowsandall.com/rowers/workout/2940/emailcsv,https://rowsandall.com/rowers/workout/2940/emailtcx,0,0,2018-06-22 10:45:04+00:00,7540,00:56:14,test delete,,Europe/Vienna,water,80.0,hwt -334,https://rowsandall.com/rowers/workout/2725/emailcsv,https://rowsandall.com/rowers/workout/2725/emailtcx,0,0,2018-06-22 12:17:56+00:00,15642,01:15:00,Mike," - 3x20min/5min",Europe/Prague,water,80.0,lwt -335,https://rowsandall.com/rowers/workout/2726/emailcsv,https://rowsandall.com/rowers/workout/2726/emailtcx,0,0,2018-06-22 12:17:56+00:00,15642,01:15:00,Mike test,,Europe/Prague,water,80.0,lwt -336,https://rowsandall.com/rowers/workout/2848/emailcsv,https://rowsandall.com/rowers/workout/2848/emailtcx,0,0,2018-06-24 05:34:07+00:00,10194,00:57:48.900000,Imported,,Europe/Prague,water,80.0,lwt -337,https://rowsandall.com/rowers/workout/2849/emailcsv,https://rowsandall.com/rowers/workout/2849/emailtcx,0,0,2018-06-24 05:34:07.200000+00:00,10194,00:57:48.900000,Imported,,Europe/Prague,water,80.0,lwt -338,https://rowsandall.com/rowers/workout/2957/emailcsv,https://rowsandall.com/rowers/workout/2957/emailtcx,0,0,2018-06-24 05:34:07.200000+00:00,10194,00:57:48.900000,Imported,,Europe/Prague,water,80.0,hwt -339,https://rowsandall.com/rowers/workout/2938/emailcsv,https://rowsandall.com/rowers/workout/2938/emailtcx,0,0,2018-06-24 07:34:07+00:00,10194,00:57:43,Double,,Europe/Prague,water,80.0,hwt -340,https://rowsandall.com/rowers/workout/3059/emailcsv,https://rowsandall.com/rowers/workout/3059/emailtcx,0,0,2018-06-26 15:06:01+00:00,10393,01:00:55.900000,C2 Import Workout from 2018-06-26 15:06:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -341,https://rowsandall.com/rowers/workout/2936/emailcsv,https://rowsandall.com/rowers/workout/2936/emailtcx,42,30,2018-06-26 15:06:04+00:00,5651,00:31:24,Sprintervals,,Europe/Prague,water,80.0,hwt -342,https://rowsandall.com/rowers/workout/2934/emailcsv,https://rowsandall.com/rowers/workout/2934/emailtcx,0,0,2018-06-26 15:38:08+00:00,1056,00:05:12,Sprintervals (2),,Europe/Brussels,water,80.0,hwt -343,https://rowsandall.com/rowers/workout/2932/emailcsv,https://rowsandall.com/rowers/workout/2932/emailtcx,0,0,2018-06-26 15:44:06+00:00,3684,00:22:50,Sprintervals (3),,Europe/Prague,water,80.0,hwt -344,https://rowsandall.com/rowers/workout/2959/emailcsv,https://rowsandall.com/rowers/workout/2959/emailtcx,160,38,2018-06-30 05:31:02.200000+00:00,13878,01:21:16.600000,," - from speedcoach2v2.15 via rowsandall.com",Europe/Prague,water,80.0,hwt -345,https://rowsandall.com/rowers/workout/2958/emailcsv,https://rowsandall.com/rowers/workout/2958/emailtcx,0,0,2018-06-30 07:31:01+00:00,13878,01:21:16.600000,C2 Import Workout from 2018-06-30 07:31:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -346,https://rowsandall.com/rowers/workout/3030/emailcsv,https://rowsandall.com/rowers/workout/3030/emailtcx,80,6031,2018-07-01 11:57:30+00:00,12879,00:57:00,Ride to pub, ,Europe/Prague,other,80.0,hwt -347,https://rowsandall.com/rowers/workout/3031/emailcsv,https://rowsandall.com/rowers/workout/3031/emailtcx,0,0,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Test P,,Europe/Prague,water,80.0,hwt -348,https://rowsandall.com/rowers/workout/3058/emailcsv,https://rowsandall.com/rowers/workout/3058/emailtcx,0,0,2018-07-02 16:21:01+00:00,2858,00:15:40.600000,C2 Import Workout from 2018-07-02 16:21:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -349,https://rowsandall.com/rowers/workout/3063/emailcsv,https://rowsandall.com/rowers/workout/3063/emailtcx,120,79,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Test Strava Export,,Europe/Prague,water,80.0,hwt -350,https://rowsandall.com/rowers/workout/3064/emailcsv,https://rowsandall.com/rowers/workout/3064/emailtcx,120,79,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Test Strava Export,,Europe/Prague,water,80.0,hwt -351,https://rowsandall.com/rowers/workout/3065/emailcsv,https://rowsandall.com/rowers/workout/3065/emailtcx,0,0,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Test Strava Export,,Europe/Prague,water,80.0,hwt -352,https://rowsandall.com/rowers/workout/3066/emailcsv,https://rowsandall.com/rowers/workout/3066/emailtcx,120,79,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Test Strava Export,,Europe/Prague,water,80.0,hwt -353,https://rowsandall.com/rowers/workout/3068/emailcsv,https://rowsandall.com/rowers/workout/3068/emailtcx,0,0,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Should be exported To Strava,,Europe/Prague,water,80.0,hwt -354,https://rowsandall.com/rowers/workout/3070/emailcsv,https://rowsandall.com/rowers/workout/3070/emailtcx,120,79,2018-07-02 16:21:01+00:00,12532,01:09:16.500000,Should Not Be Exported To Strava,,Europe/Prague,water,80.0,hwt -355,https://rowsandall.com/rowers/workout/3057/emailcsv,https://rowsandall.com/rowers/workout/3057/emailtcx,0,0,2018-07-02 16:40:02+00:00,2001,00:08:29,C2 Import Workout from 2018-07-02 16:40:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -356,https://rowsandall.com/rowers/workout/3056/emailcsv,https://rowsandall.com/rowers/workout/3056/emailtcx,0,0,2018-07-02 16:50:02+00:00,2136,00:09:16.200000,C2 Import Workout from 2018-07-02 16:50:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -357,https://rowsandall.com/rowers/workout/3055/emailcsv,https://rowsandall.com/rowers/workout/3055/emailtcx,0,0,2018-07-02 17:01:02+00:00,2058,00:08:38.800000,C2 Import Workout from 2018-07-02 17:01:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -358,https://rowsandall.com/rowers/workout/3008/emailcsv,https://rowsandall.com/rowers/workout/3008/emailtcx,22,0,2018-07-02 17:01:05+00:00,2058,00:08:35,2ks with focus (4),,Europe/Prague,water,80.0,hwt -359,https://rowsandall.com/rowers/workout/3028/emailcsv,https://rowsandall.com/rowers/workout/3028/emailtcx,22,0,2018-07-02 17:01:05+00:00,2058,00:08:35,2ks with focus (4),,Europe/Prague,water,80.0,hwt -360,https://rowsandall.com/rowers/workout/3054/emailcsv,https://rowsandall.com/rowers/workout/3054/emailtcx,0,0,2018-07-02 17:11:02+00:00,2149,00:09:47.300000,C2 Import Workout from 2018-07-02 17:11:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -361,https://rowsandall.com/rowers/workout/3006/emailcsv,https://rowsandall.com/rowers/workout/3006/emailtcx,27,0,2018-07-02 17:11:05+00:00,2149,00:09:44,2ks with focus (5),,Europe/Prague,water,80.0,hwt -362,https://rowsandall.com/rowers/workout/3026/emailcsv,https://rowsandall.com/rowers/workout/3026/emailtcx,27,0,2018-07-02 17:11:05+00:00,2149,00:09:44,2ks with focus (5),,Europe/Prague,water,80.0,hwt -363,https://rowsandall.com/rowers/workout/3053/emailcsv,https://rowsandall.com/rowers/workout/3053/emailtcx,0,0,2018-07-02 17:24:02+00:00,1328,00:06:15.500000,C2 Import Workout from 2018-07-02 17:24:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -364,https://rowsandall.com/rowers/workout/3004/emailcsv,https://rowsandall.com/rowers/workout/3004/emailtcx,10,0,2018-07-02 17:24:05+00:00,1328,00:06:12,2ks with focus (6),,Europe/Prague,water,80.0,hwt -365,https://rowsandall.com/rowers/workout/3024/emailcsv,https://rowsandall.com/rowers/workout/3024/emailtcx,10,0,2018-07-02 17:24:05+00:00,1328,00:06:12,2ks with focus (6),,Europe/Prague,water,80.0,hwt -366,https://rowsandall.com/rowers/workout/2964/emailcsv,https://rowsandall.com/rowers/workout/2964/emailtcx,0,0,2018-07-04 15:06:42+00:00,7350,00:31:07,Test,,Europe/Prague,rower,80.0,hwt -367,https://rowsandall.com/rowers/workout/2965/emailcsv,https://rowsandall.com/rowers/workout/2965/emailtcx,0,103,2018-07-04 16:19:01+00:00,10471,01:00:27.200000,Test TRIMP,,Europe/Prague,water,80.0,hwt -368,https://rowsandall.com/rowers/workout/2966/emailcsv,https://rowsandall.com/rowers/workout/2966/emailtcx,0,98,2018-07-04 16:19:01+00:00,10471,01:00:27.200000,Test Rscore,,Europe/Prague,water,80.0,hwt -369,https://rowsandall.com/rowers/workout/3052/emailcsv,https://rowsandall.com/rowers/workout/3052/emailtcx,0,0,2018-07-04 16:19:01+00:00,10471,01:00:27.100000,C2 Import Workout from 2018-07-04 16:19:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -370,https://rowsandall.com/rowers/workout/2967/emailcsv,https://rowsandall.com/rowers/workout/2967/emailtcx,0,96,2018-07-04 16:19:02+00:00,10471,01:00:26,Startjes," - from csv via rowsandall.com",Europe/Prague,water,80.0,hwt -371,https://rowsandall.com/rowers/workout/3002/emailcsv,https://rowsandall.com/rowers/workout/3002/emailtcx,0,98,2018-07-04 16:19:02+00:00,10471,01:00:26,Startjes,,Europe/Prague,water,80.0,hwt -372,https://rowsandall.com/rowers/workout/3022/emailcsv,https://rowsandall.com/rowers/workout/3022/emailtcx,0,98,2018-07-04 16:19:02+00:00,10471,01:00:26,Startjes,,Europe/Prague,water,80.0,hwt -373,https://rowsandall.com/rowers/workout/3051/emailcsv,https://rowsandall.com/rowers/workout/3051/emailtcx,0,0,2018-07-07 07:43:02+00:00,2874,00:16:39.700000,C2 Import Workout from 2018-07-07 07:43:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -374,https://rowsandall.com/rowers/workout/3000/emailcsv,https://rowsandall.com/rowers/workout/3000/emailtcx,17,0,2018-07-07 07:43:03+00:00,2874,00:16:38,2x race prep,,Europe/Prague,water,80.0,hwt -375,https://rowsandall.com/rowers/workout/3020/emailcsv,https://rowsandall.com/rowers/workout/3020/emailtcx,17,0,2018-07-07 07:43:03+00:00,2874,00:16:38,2x race prep,,Europe/Prague,water,80.0,hwt -376,https://rowsandall.com/rowers/workout/3050/emailcsv,https://rowsandall.com/rowers/workout/3050/emailtcx,0,0,2018-07-07 08:01:01+00:00,743,00:02:45.500000,C2 Import Workout from 2018-07-07 08:01:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -377,https://rowsandall.com/rowers/workout/2998/emailcsv,https://rowsandall.com/rowers/workout/2998/emailtcx,2,0,2018-07-07 08:01:02+00:00,743,00:02:44,2x race prep (2),,Europe/Prague,bike,80.0,hwt -378,https://rowsandall.com/rowers/workout/3018/emailcsv,https://rowsandall.com/rowers/workout/3018/emailtcx,2,0,2018-07-07 08:01:02+00:00,743,00:02:44,2x race prep (2),,Europe/Prague,water,80.0,hwt -379,https://rowsandall.com/rowers/workout/3049/emailcsv,https://rowsandall.com/rowers/workout/3049/emailtcx,0,0,2018-07-07 08:05:03+00:00,2827,00:15:21.800000,C2 Import Workout from 2018-07-07 08:05:03+00:00,imported from Concept2 log,UTC,water,80.0,lwt -380,https://rowsandall.com/rowers/workout/2996/emailcsv,https://rowsandall.com/rowers/workout/2996/emailtcx,21,0,2018-07-07 08:05:06+00:00,2827,00:15:18,2x race prep (3),,Europe/Prague,water,80.0,hwt -381,https://rowsandall.com/rowers/workout/3016/emailcsv,https://rowsandall.com/rowers/workout/3016/emailtcx,21,0,2018-07-07 08:05:06+00:00,2827,00:15:18,2x race prep (3),,Europe/Prague,water,80.0,hwt -382,https://rowsandall.com/rowers/workout/3048/emailcsv,https://rowsandall.com/rowers/workout/3048/emailtcx,0,0,2018-07-07 08:22:01+00:00,749,00:03:12.500000,C2 Import Workout from 2018-07-07 08:22:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -383,https://rowsandall.com/rowers/workout/2994/emailcsv,https://rowsandall.com/rowers/workout/2994/emailtcx,4,0,2018-07-07 08:22:02+00:00,749,00:03:11,2x race prep (4),,Europe/Prague,water,80.0,hwt -384,https://rowsandall.com/rowers/workout/3014/emailcsv,https://rowsandall.com/rowers/workout/3014/emailtcx,4,0,2018-07-07 08:22:02+00:00,749,00:03:11,2x race prep (4),,Europe/Prague,water,80.0,hwt -385,https://rowsandall.com/rowers/workout/3047/emailcsv,https://rowsandall.com/rowers/workout/3047/emailtcx,0,0,2018-07-07 08:27:03+00:00,2058,00:11:55.800000,C2 Import Workout from 2018-07-07 08:27:03+00:00,imported from Concept2 log,UTC,water,80.0,lwt -386,https://rowsandall.com/rowers/workout/2992/emailcsv,https://rowsandall.com/rowers/workout/2992/emailtcx,13,14,2018-07-07 08:27:06+00:00,2058,00:11:52,2x race prep (5),,Europe/Prague,water,75.0,hwt -387,https://rowsandall.com/rowers/workout/3012/emailcsv,https://rowsandall.com/rowers/workout/3012/emailtcx,13,15,2018-07-07 08:27:06+00:00,2058,00:11:52,2x race prep (5),,Europe/Prague,water,80.0,hwt -388,https://rowsandall.com/rowers/workout/2969/emailcsv,https://rowsandall.com/rowers/workout/2969/emailtcx,100,116,2018-07-08 13:17:02+00:00,10372,01:00:18.100000,HRTSS,,Europe/Prague,water,80.0,hwt -389,https://rowsandall.com/rowers/workout/3046/emailcsv,https://rowsandall.com/rowers/workout/3046/emailtcx,0,0,2018-07-08 13:17:02+00:00,10372,01:00:18,C2 Import Workout from 2018-07-08 13:17:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -390,https://rowsandall.com/rowers/workout/3034/emailcsv,https://rowsandall.com/rowers/workout/3034/emailtcx,0,0,2018-07-08 13:17:08+00:00,10372,01:00:12,Tempovky,,Europe/Prague,water,80.0,hwt -391,https://rowsandall.com/rowers/workout/3045/emailcsv,https://rowsandall.com/rowers/workout/3045/emailtcx,0,0,2018-07-13 13:08:00+00:00,2481,00:13:41,C2 Import Workout from 2018-07-13 13:08:00+00:00,imported from Concept2 log,UTC,water,80.0,lwt -392,https://rowsandall.com/rowers/workout/3044/emailcsv,https://rowsandall.com/rowers/workout/3044/emailtcx,0,0,2018-07-13 13:23:01+00:00,4085,00:22:09.200000,C2 Import Workout from 2018-07-13 13:23:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -393,https://rowsandall.com/rowers/workout/3043/emailcsv,https://rowsandall.com/rowers/workout/3043/emailtcx,0,0,2018-07-14 08:59:02+00:00,7051,00:50:00.500000,C2 Import Workout from 2018-07-14 08:59:02+00:00,imported from Concept2 log,UTC,water,80.0,lwt -394,https://rowsandall.com/rowers/workout/3042/emailcsv,https://rowsandall.com/rowers/workout/3042/emailtcx,0,0,2018-07-14 13:33:00+00:00,4471,00:51:42.100000,C2 Import Workout from 2018-07-14 13:33:00+00:00,imported from Concept2 log,UTC,water,80.0,lwt -395,https://rowsandall.com/rowers/workout/3041/emailcsv,https://rowsandall.com/rowers/workout/3041/emailtcx,0,0,2018-07-14 15:48:01+00:00,4486,00:56:58.100000,C2 Import Workout from 2018-07-14 15:48:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -396,https://rowsandall.com/rowers/workout/3040/emailcsv,https://rowsandall.com/rowers/workout/3040/emailtcx,0,0,2018-07-15 06:10:01+00:00,4233,00:29:17,C2 Import Workout from 2018-07-15 06:10:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -397,https://rowsandall.com/rowers/workout/3039/emailcsv,https://rowsandall.com/rowers/workout/3039/emailtcx,0,0,2018-07-15 09:01:01+00:00,4978,00:41:45,C2 Import Workout from 2018-07-15 09:01:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -398,https://rowsandall.com/rowers/workout/3038/emailcsv,https://rowsandall.com/rowers/workout/3038/emailtcx,0,0,2018-07-18 05:00:01+00:00,11159,00:59:58,C2 Import Workout from 2018-07-18 05:00:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -399,https://rowsandall.com/rowers/workout/3037/emailcsv,https://rowsandall.com/rowers/workout/3037/emailtcx,0,0,2018-07-20 09:29:01+00:00,8436,00:45:44.500000,C2 Import Workout from 2018-07-20 09:29:01+00:00,imported from Concept2 log,UTC,water,80.0,lwt -400,https://rowsandall.com/rowers/workout/3036/emailcsv,https://rowsandall.com/rowers/workout/3036/emailtcx,0,0,2018-07-21 05:13:03+00:00,9639,00:54:19.500000,C2 Import Workout from 2018-07-21 05:13:03+00:00,imported from Concept2 log,UTC,water,80.0,lwt -401,https://rowsandall.com/rowers/workout/3061/emailcsv,https://rowsandall.com/rowers/workout/3061/emailtcx,77,43,2018-08-17 05:16:03+00:00,8315,00:45:11.400000,Brnenske 2k,,Europe/Prague,water,80.0,hwt -402,https://rowsandall.com/rowers/workout/3075/emailcsv,https://rowsandall.com/rowers/workout/3075/emailtcx,83,28,2018-08-18 07:54:04+00:00,9590,00:55:08,Technique 2x, ,Europe/Prague,water,80.0,hwt -403,https://rowsandall.com/rowers/workout/3074/emailcsv,https://rowsandall.com/rowers/workout/3074/emailtcx,94,17,2018-08-26 22:00:01.500000+00:00,9903,00:54:36,Imported,,Europe/Prague,bike,80.0,hwt -404,https://rowsandall.com/rowers/workout/3076/emailcsv,https://rowsandall.com/rowers/workout/3076/emailtcx,94,1104,2018-08-26 22:00:01.500000+00:00,9903,00:54:36,Imported,,Europe/Prague,bike,80.0,hwt -405,https://rowsandall.com/rowers/workout/3072/emailcsv,https://rowsandall.com/rowers/workout/3072/emailtcx,0,0,2018-08-27 14:36:47+00:00,5855,00:14:58.700000,Bike Erg,,Europe/Prague,bikeerg,80.0,hwt -406,https://rowsandall.com/rowers/workout/3073/emailcsv,https://rowsandall.com/rowers/workout/3073/emailtcx,15,4,2018-08-27 14:36:47+00:00,5855,00:14:58.700000,Bike Erg,,Europe/Prague,bike,80.0,hwt -407,https://rowsandall.com/rowers/workout/3077/emailcsv,https://rowsandall.com/rowers/workout/3077/emailtcx,0,51,2018-09-11 05:31:02+00:00,7490,00:35:07.500000,7.5k,,Europe/Prague,water,80.0,hwt -408,https://rowsandall.com/rowers/workout/3080/emailcsv,https://rowsandall.com/rowers/workout/3080/emailtcx,0,0,2018-09-12 04:17:04+00:00,5921,00:34:50,Sofia part II, ,Europe/Sofia,other,80.0,hwt -409,https://rowsandall.com/rowers/workout/3079/emailcsv,https://rowsandall.com/rowers/workout/3079/emailtcx,87,60,2018-09-13 12:15:58+00:00,23476,00:59:59.700000,Mike 2,,Europe/Prague,rower,80.0,hwt -410,https://rowsandall.com/rowers/workout/3078/emailcsv,https://rowsandall.com/rowers/workout/3078/emailtcx,94,59,2018-09-14 13:02:04+00:00,24267,00:59:57.200000,Mike,,Europe/Prague,rower,80.0,hwt From 73bf96d8ba32abcdefd9e16b2c4ebabe00201095 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 21:48:33 +0100 Subject: [PATCH 13/57] removed secrets from docker image --- .dockerignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.dockerignore b/.dockerignore index 5ceb3864..9b34d71a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ venv +config.yaml From 65786061e8066b676395ce3e59d91217c3837348 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 22:04:33 +0100 Subject: [PATCH 14/57] dockerfile changes --- Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile b/Dockerfile index 09dc421d..acece889 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,9 @@ FROM debian +RUN apt-get update +RUN apt-get install -y default-libmysqlclient-dev RUN apt-get update && apt-get install \ -y --no-install-recommends python3 python3-virtualenv +RUN apt-get update && apt-get install libssl-dev RUN python3 -m virtualenv --python=/usr/bin/python3 /opt/venv COPY ./requirements.txt /usr/src/app/ WORKDIR /usr/src/app/ From 44a283cc5693f1e328df0cf8d0bc51c4bc9e9e2c Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 22:16:51 +0100 Subject: [PATCH 15/57] further dockerfile tuning --- Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index acece889..7f1e3605 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,8 @@ FROM debian RUN apt-get update RUN apt-get install -y default-libmysqlclient-dev +RUN apt-get install -y postgresql postgresql-contrib +RUN apt-get install gcc musl-dev postgresql-dev RUN apt-get update && apt-get install \ -y --no-install-recommends python3 python3-virtualenv RUN apt-get update && apt-get install libssl-dev From e49cfd837aafc5fdbf251611548ba930f63e6fc3 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 2 Jan 2020 22:19:03 +0100 Subject: [PATCH 16/57] docker --- Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 7f1e3605..d59b0760 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,6 @@ FROM debian RUN apt-get update RUN apt-get install -y default-libmysqlclient-dev RUN apt-get install -y postgresql postgresql-contrib -RUN apt-get install gcc musl-dev postgresql-dev RUN apt-get update && apt-get install \ -y --no-install-recommends python3 python3-virtualenv RUN apt-get update && apt-get install libssl-dev From 42d13a90b5bf371c01e6b96373ba3b149dde56ba Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 08:29:51 +0100 Subject: [PATCH 17/57] fixed bug in rower stats (gauges) --- rowers/templates/embedded_video.html | 50 ++++++++++++++-------------- rowers/templatetags/rowerfilters.py | 10 ++++-- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 7d66b3de..82d6346b 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -1,4 +1,4 @@ -{% extends "newbase.html" %} +workout.user{% extends "newbase.html" %} {% load staticfiles %} {% load rowerfilters %} {% load i18n %} @@ -453,36 +453,36 @@ function copyText() { set_basic(); {% endif %} {% if 'forcepower' in metricsgroups %} - poweroptions.max = {{ rower.pw_an|add:100|round100 }}; - poweroptions.greenFrom = {{ rower.pw_ut2 }}; - poweroptions.greenTo = {{ rower.pw_at }}; - poweroptions.yellowFrom = {{ rower.pw_at }}; - poweroptions.yellowTo = {{ rower.pw_an }}; - poweroptions.redFrom = {{ rower.pw_an }}; - poweroptions.redTo = {{ rower.pw_an|add:100|round100 }}; - poweroptions.majorTicks = {{ rower.pw_an|add:100|round100|majorticks }}; + poweroptions.max = {{ workout.user.pw_an|add:100|round100 }}; + poweroptions.greenFrom = {{ workout.user.pw_ut2 }}; + poweroptions.greenTo = {{ workout.user.pw_at }}; + poweroptions.yellowFrom = {{ workout.user.pw_at }}; + poweroptions.yellowTo = {{ workout.user.pw_an }}; + poweroptions.redFrom = {{ workout.user.pw_an }}; + poweroptions.redTo = {{ workout.user.pw_an|add:100|round100 }}; + poweroptions.majorTicks = {{ workout.user.pw_an|add:100|round100|majorticks }}; {% if workout.workouttype == 'water' %} - poweroptions.max = {{ rower.pw_an|waterpower:rower|add:100|round100 }} - poweroptions.greenFrom = {{ rower.pw_ut2|waterpower:rower }}; - poweroptions.greenTo = {{ rower.pw_at|waterpower:rower }}; - poweroptions.yellowFrom = {{ rower.pw_at|waterpower:rower }}; - poweroptions.yellowTo = {{ rower.pw_an|waterpower:rower }}; - poweroptions.redFrom = {{ rower.pw_an|waterpower:rower }}; - poweroptions.redTo = {{ rower.pw_an|waterpower:rower|add:100|round100 }}; - poweroptions.majorTicks = {{ rower.pw_an|waterpower:rower|add:100|round100|majorticks }}; + poweroptions.max = {{ workout.user.pw_an|waterpower:rower|add:100|round100 }} + poweroptions.greenFrom = {{ workout.user.pw_ut2|waterpower:rower }}; + poweroptions.greenTo = {{ workout.user.pw_at|waterpower:rower }}; + poweroptions.yellowFrom = {{ workout.user.pw_at|waterpower:rower }}; + poweroptions.yellowTo = {{ workout.user.pw_an|waterpower:rower }}; + poweroptions.redFrom = {{ workout.user.pw_an|waterpower:rower }}; + poweroptions.redTo = {{ workout.user.pw_an|waterpower:rower|add:100|round100 }}; + poweroptions.majorTicks = {{ workout.user.pw_an|waterpower:rower|add:100|round100|majorticks }}; {% endif %} power_now = power_values[0]; set_forcepower(); {% endif %} {% if 'athlete' in metricsgroups %} - hroptions.max = {{ rower.max|round20 }} - hroptions.greenFrom = {{ rower.ut2 }} - hroptions.greenTo = {{ rower.at }} - hroptions.yellowFrom = {{ rower.at }} - hroptions.yellowTo = {{ rower.an }} - hroptions.redFrom = {{ rower.an }} - hroptions.redTo = {{ rower.max }} - hroptions.majorTicks = {{ rower.max|round20|hrmajorticks:rower.rest }} + hroptions.max = {{ workout.user.max|round20 }} + hroptions.greenFrom = {{ workout.user.ut2 }} + hroptions.greenTo = {{ workout.user.at }} + hroptions.yellowFrom = {{ workout.user.at }} + hroptions.yellowTo = {{ workout.user.an }} + hroptions.redFrom = {{ workout.user.an }} + hroptions.redTo = {{ workout.user.max }} + hroptions.majorTicks = {{ workout.user.max|round20|hrmajorticks:workout.user.rest }} hr_now = hr_values[0]; set_athlete(); {% endif %} diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index b7f3be2f..48b5afde 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -127,11 +127,17 @@ def waterpower(x,rower): @register.filter def round20(x): - return int(20.*(1+int(int(x)/20))) + try: + return int(20.*(1+int(int(x)/20))) + except ValueError: + return 20 @register.filter def round100(x): - return int(100.*(1+int(int(x)/100))) + try: + return int(100.*(1+int(int(x)/100))) + except ValueError: + return 100 @register.filter def majorticks(maxval): From 327e02c49f310327a23f346902bf4b4e369abbcb Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 08:32:54 +0100 Subject: [PATCH 18/57] improced Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d59b0760..2ac9594e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM debian RUN apt-get update RUN apt-get install -y default-libmysqlclient-dev -RUN apt-get install -y postgresql postgresql-contrib +RUN apt-get install -y postgresql postgresql-contrib libpq-dev python-psycopg2 RUN apt-get update && apt-get install \ -y --no-install-recommends python3 python3-virtualenv RUN apt-get update && apt-get install libssl-dev From ec135d98d21e04b16fb17d7047210a78a2a4ae1a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 10:44:29 +0100 Subject: [PATCH 19/57] improved video bug --- Dockerfile | 4 ++-- rowers/templates/embedded_video.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2ac9594e..26847963 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ FROM debian RUN apt-get update -RUN apt-get install -y default-libmysqlclient-dev +RUN apt-get install -y default-libmysqlclient-dev gcc RUN apt-get install -y postgresql postgresql-contrib libpq-dev python-psycopg2 RUN apt-get update && apt-get install \ - -y --no-install-recommends python3 python3-virtualenv + -y --no-install-recommends python3 python3-virtualenv python3-dev RUN apt-get update && apt-get install libssl-dev RUN python3 -m virtualenv --python=/usr/bin/python3 /opt/venv COPY ./requirements.txt /usr/src/app/ diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 82d6346b..8bd24edf 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -1,4 +1,4 @@ -workout.user{% extends "newbase.html" %} +{% extends "newbase.html" %} {% load staticfiles %} {% load rowerfilters %} {% load i18n %} From fa3ebc2ac8d5cdf68455f86d7f8911b27009f3cc Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 12:12:29 +0100 Subject: [PATCH 20/57] fixing waterpower bug --- rowers/templates/embedded_video.html | 16 ++++++++-------- rowers/templatetags/rowerfilters.py | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 8bd24edf..6bd67499 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -462,14 +462,14 @@ function copyText() { poweroptions.redTo = {{ workout.user.pw_an|add:100|round100 }}; poweroptions.majorTicks = {{ workout.user.pw_an|add:100|round100|majorticks }}; {% if workout.workouttype == 'water' %} - poweroptions.max = {{ workout.user.pw_an|waterpower:rower|add:100|round100 }} - poweroptions.greenFrom = {{ workout.user.pw_ut2|waterpower:rower }}; - poweroptions.greenTo = {{ workout.user.pw_at|waterpower:rower }}; - poweroptions.yellowFrom = {{ workout.user.pw_at|waterpower:rower }}; - poweroptions.yellowTo = {{ workout.user.pw_an|waterpower:rower }}; - poweroptions.redFrom = {{ workout.user.pw_an|waterpower:rower }}; - poweroptions.redTo = {{ workout.user.pw_an|waterpower:rower|add:100|round100 }}; - poweroptions.majorTicks = {{ workout.user.pw_an|waterpower:rower|add:100|round100|majorticks }}; + poweroptions.max = {{ workout.user.pw_an|waterpower:workout.user|add:100|round100 }} + poweroptions.greenFrom = {{ workout.user.pw_ut2|waterpower:workout.user }}; + poweroptions.greenTo = {{ workout.user.pw_at|waterpower:workout.user }}; + poweroptions.yellowFrom = {{ workout.user.pw_at|waterpower:workout.user }}; + poweroptions.yellowTo = {{ workout.user.pw_an|waterpower:workout.user }}; + poweroptions.redFrom = {{ workout.user.pw_an|waterpower:workout.user }}; + poweroptions.redTo = {{ workout.user.pw_an|waterpower:workout.user|add:100|round100 }}; + poweroptions.majorTicks = {{ workout.user.pw_an|waterpower:workout.user|add:100|round100|majorticks }}; {% endif %} power_now = power_values[0]; set_forcepower(); diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index 48b5afde..b3b7b5d5 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -123,7 +123,9 @@ def is_coach(rower,rowers): @register.filter def waterpower(x,rower): - return int(x*(100-rower.otwslack)/100.) + if rower is not None: + return int(x*(100-rower.otwslack)/100.) + return int(x) @register.filter def round20(x): From a2ef4491bc297292fd3377480c1afaf7d9c3e072 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 13:42:42 +0100 Subject: [PATCH 21/57] broken Dockerfile again --- Dockerfile | 12 +++++++----- init.sh | 7 +++++++ 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 init.sh diff --git a/Dockerfile b/Dockerfile index 26847963..cdcd8290 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,16 @@ FROM debian +RUN mkdir /srv/app +RUN mkdir /srv/venv RUN apt-get update RUN apt-get install -y default-libmysqlclient-dev gcc RUN apt-get install -y postgresql postgresql-contrib libpq-dev python-psycopg2 RUN apt-get update && apt-get install \ -y --no-install-recommends python3 python3-virtualenv python3-dev RUN apt-get update && apt-get install libssl-dev -RUN python3 -m virtualenv --python=/usr/bin/python3 /opt/venv -COPY ./requirements.txt /usr/src/app/ -WORKDIR /usr/src/app/ -RUN . /opt/venv/bin/activate && pip install -r requirements.txt +RUN python3 -m virtualenv --python=/srv/venv/ +COPY ./requirements.txt /srv/app/ +WORKDIR /srv/app/ +RUN . /srv/venv/bin/activate && pip install -r requirements.txt COPY . . EXPOSE 8000 -CMD ["python", "./manage.py", "runserver"] +CMD ["init.sh"] diff --git a/init.sh b/init.sh new file mode 100644 index 00000000..c93635f0 --- /dev/null +++ b/init.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +source /srv/venv/bin/activate +cd /srv/app +python manage.py migrate +python manage.py collectstatic --noinput +python manage.py runserver From 95db75d4909314916a86988532f197ed66ab914b Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 14:57:20 +0100 Subject: [PATCH 22/57] almost there - dockerizing --- Dockerfile | 15 +++------------ app.py | 8 ++++++++ 2 files changed, 11 insertions(+), 12 deletions(-) create mode 100644 app.py diff --git a/Dockerfile b/Dockerfile index cdcd8290..7512e062 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,7 @@ -FROM debian -RUN mkdir /srv/app -RUN mkdir /srv/venv -RUN apt-get update -RUN apt-get install -y default-libmysqlclient-dev gcc -RUN apt-get install -y postgresql postgresql-contrib libpq-dev python-psycopg2 -RUN apt-get update && apt-get install \ - -y --no-install-recommends python3 python3-virtualenv python3-dev -RUN apt-get update && apt-get install libssl-dev -RUN python3 -m virtualenv --python=/srv/venv/ +FROM rosti/python:3.6 COPY ./requirements.txt /srv/app/ WORKDIR /srv/app/ -RUN . /srv/venv/bin/activate && pip install -r requirements.txt +ENV VIRTUAL_ENV = /srv/venv +RUN /opt/python/bin/pip install -r /srv/app/requirements.txt COPY . . -EXPOSE 8000 CMD ["init.sh"] diff --git a/app.py b/app.py new file mode 100644 index 00000000..e3fbe54f --- /dev/null +++ b/app.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +import os +import sys + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rowsandall_app.settings") +application = get_wsgi_application() + +#execute_from_command_line(sys.argv) From 348e0e209e4eee0876287a73e079f52bf5cdb024 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 15:25:14 +0100 Subject: [PATCH 23/57] container sort of working --- Dockerfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7512e062..d35cc5c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,3 @@ FROM rosti/python:3.6 -COPY ./requirements.txt /srv/app/ WORKDIR /srv/app/ -ENV VIRTUAL_ENV = /srv/venv -RUN /opt/python/bin/pip install -r /srv/app/requirements.txt COPY . . -CMD ["init.sh"] From 73ff474ea88c180f9a8678f9a010892149aa75ff Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 16:46:37 +0100 Subject: [PATCH 24/57] first version of mini player --- rowers/templates/embedded_video_mini.html | 681 ++++++++++++++++++++++ rowers/urls.py | 2 + rowers/views/workoutviews.py | 110 ++++ 3 files changed, 793 insertions(+) create mode 100644 rowers/templates/embedded_video_mini.html diff --git a/rowers/templates/embedded_video_mini.html b/rowers/templates/embedded_video_mini.html new file mode 100644 index 00000000..720e2794 --- /dev/null +++ b/rowers/templates/embedded_video_mini.html @@ -0,0 +1,681 @@ +{% extends "newbase.html" %} +{% load staticfiles %} +{% load rowerfilters %} +{% load i18n %} +{% load leaflet_tags %} + + + +{% block title %}Workout Video{% endblock %} +{% block og_title %}{{ analysis.name }}{% endblock %} +{% block description %}Rowing Video Analysis:{{ analysis.name }}{% endblock %} +{% block og_description %}Rowing Video Analysis:{{ analysis.name }}{% endblock %} +{% block og_image %} +{% if analysis %} + + +{% else %} + + +{% endif %} +{% endblock %} + +{% if analysis %} +{% block image_src %} + +{% endblock %} +{% endif %} + +{% block meta %} +{% leaflet_js %} +{% leaflet_css %} + + + + + + +{% endblock %} + +{% block main %} + + + +{% language 'en' %} +

    Video Analysis for {{ workout.name }}

    +
      +
    • +

      Playing the video will advance the data in synchronization. Use the regular + YouTube controls to move around in the video and play it.

      +
    • +
    • + + + Share + + + + + + + +
    • +
    +
      +
    • +
      + {{ mapdiv | safe}} + +
      +
      + +
      +
      + +
    • +
    • +
      + +
    • +
    • + +
    • +
    +

     

    +
    +
      +
    • + +
    • + +
    • +
        + {% if 'basic' in metricsgroups %} +
      • +
        +
      • +
      • +
        +
      • + {% endif %} + {% if 'forcepower' in metricsgroups %} +
      • +
        +
      • + {% endif %} + {% if 'athlete' in metricsgroups %} +
      • +
        +
      • + {% endif %} + {% if 'stroke' in metricsgroups %} + {% if workout.workouttype == 'water' %} +
      • +
        +
      • + {% endif %} + {% endif %} +
      +
    • +
    +
    +

     

    + + +{% endlanguage %} + +{% endblock %} + +{% block sidebar %} +{% include 'menu_workout.html' %} +{% endblock %} diff --git a/rowers/urls.py b/rowers/urls.py index 2a9c39d6..4940c251 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -348,6 +348,8 @@ urlpatterns = [ re_path(r'^video/(?P\d+)/delete/$',views.VideoDelete.as_view(),name='video_delete'), re_path(r'^video/(?P\w.+)/$',views.workout_video_view, name='workout_video_view'), + re_path(r'^video/(?P\w.+)/m$',views.workout_video_view_mini, + name='workout_video_view_mini'), re_path(r'^videos/',views.list_videos,name='list_videos'), re_path(r'^add-video/',views.video_selectworkout,name='video_selectworkout'), # re_path(r'^workout/(?P\d+)/$',views.workout_view,name='workout_view'), diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index eea37716..b72db049 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -48,6 +48,116 @@ def get_video_id(url): else: raise ValueError +# Show a video compared with data +def workout_video_view_mini(request,id=''): + try: + id = encoder.decode_hex(id) + analysis = VideoAnalysis.objects.get(id=id) + except VideoAnalysis.DoesNotExist: + raise Http404("Video Analysis does not exist") + + w = analysis.workout + delay = analysis.delay + + if w.workouttype in mytypes.otwtypes: + mode = 'water' + else: + mode = 'erg' + + if request.user.is_authenticated: + mayedit = checkworkoutuser(request.user,w) and isprorower(request.user.rower) + rower = request.user.rower + else: + mayedit = False + rower = None + + # get video ID and offset + if mayedit and request.method == 'POST': + form = VideoAnalysisCreateForm(request.POST) + metricsform = VideoAnalysisMetricsForm(request.POST,mode=mode) + if form.is_valid() and metricsform.is_valid(): + video_id = form.cleaned_data['url'] + try: + video_id = get_video_id(form.cleaned_data['url']) + except (TypeError,ValueError): + pass + delay = form.cleaned_data['delay'] + metricsgroups = metricsform.cleaned_data['groups'] + if 'save_button' in request.POST: + analysis.name = form.cleaned_data['name'] + analysis.video_id = video_id + analysis.delay = delay + analysis.metricsgroups = metricsgroups + analysis.save() + else: + video_id = id + delay = 0 + elif mayedit: + form = VideoAnalysisCreateForm( + initial = { + 'name':analysis.name, + 'delay': analysis.delay, + 'url': analysis.video_id, + } + ) + metricsform = VideoAnalysisMetricsForm(initial={'groups':analysis.metricsgroups}, + mode=mode) + metricsgroups = analysis.metricsgroups + video_id = analysis.video_id + else: + form = None + metricsform = None + metricsgroups = analysis.metricsgroups + + data, metrics, maxtime = dataprep.get_video_data(w,groups=metricsgroups,mode=mode) + hascoordinates = pd.Series(data['latitude']).std() > 0 + # create map + if hascoordinates: + mapscript, mapdiv = leaflet_chart_video(data['latitude'],data['longitude'], + w.name) + else: + mapscript, mapdiv = interactive_chart_video(data) + data['longitude'] = data['spm'] + data['latitude'] = list(range(len(data['spm']))) + + + breadcrumbs = [ + { + 'url':'/rowers/list-workouts/', + 'name':'Workouts' + }, + { + 'url':get_workout_default_page(request,encoder.encode_hex(w.id)), + 'name': w.name + }, + { + 'url':reverse('workout_video_view',kwargs={'id':encoder.encode_hex(analysis.id)}), + 'name': 'Video Analysis' + } + + ] + + + return render(request, + 'embedded_video_mini.html', + { + 'workout':w, + 'rower':rower, + 'data': json.dumps(data,default=default), + 'mapscript': mapscript, + 'mapdiv': mapdiv, + 'video_id': analysis.video_id, + 'form':form, + 'breadcrumbs':breadcrumbs, + 'analysis':analysis, + 'maxtime':maxtime, + 'metrics':metrics, + 'locked': True, + 'metricsform':metricsform, + 'metricsgroups': metricsgroups, + 'siteurl': settings.SITE_URL, + }) + # Show a video compared with data def workout_video_view(request,id=''): From 1e6a42d9678d3ba138e60fd51decb131bd5c4469 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 17:00:48 +0100 Subject: [PATCH 25/57] added mini viewer --- app.py | 2 ++ rowers/templates/embedded_video.html | 10 ++++++++++ rowers/templates/embedded_video_mini.html | 1 + 3 files changed, 13 insertions(+) diff --git a/app.py b/app.py index e3fbe54f..2672ad59 100644 --- a/app.py +++ b/app.py @@ -3,6 +3,8 @@ import os import sys os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rowsandall_app.settings") + +from django.core.wsgi import get_wsgi_application application = get_wsgi_application() #execute_from_command_line(sys.argv) diff --git a/rowers/templates/embedded_video.html b/rowers/templates/embedded_video.html index 6bd67499..5543733b 100644 --- a/rowers/templates/embedded_video.html +++ b/rowers/templates/embedded_video.html @@ -40,6 +40,10 @@ $(this).removeAttr('disabled'); }); }); + document.getElementById("smallscreen").style.display = "none"; + if ($(window).width() <= 950) { + $("#smallscreen").show() + } }); + + + + + +{% endblock %} + +{% block main %} + + + +{% language 'en' %} +

    Video Analysis for {{ workout.name }}

    +
      +
    • +

      Playing the video will advance the data in synchronization. Use the regular + YouTube controls to move around in the video and play it.

      +
    • +
    • + + + Share + + + + + + + +
    • +
    +
      +
    • +
      + {{ mapdiv | safe}} + +
      +
      + +
      +
      + +
    • +
    • +
      + +
    • +
    • + +
    • +
    +

     

    +
    +
      +
    • + +
    • + +
    • +
        + {% if 'basic' in metricsgroups %} +
      • +
        +
      • +
      • +
        +
      • + {% endif %} + {% if 'forcepower' in metricsgroups %} +
      • +
        +
      • + {% endif %} + {% if 'athlete' in metricsgroups %} +
      • +
        +
      • + {% endif %} + {% if 'stroke' in metricsgroups %} + {% if workout.workouttype == 'water' %} +
      • +
        +
      • + {% endif %} + {% endif %} +
      +
    • +
    +
    +

     

    + + +{% endlanguage %} + +{% endblock %} + +{% block sidebar %} +{% include 'menu_workout.html' %} +{% endblock %} From 661febd67d3b1cc31203f98fe91e793391b73190 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 17:16:37 +0100 Subject: [PATCH 28/57] releasing mini video --- rowers/urls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rowers/urls.py b/rowers/urls.py index 4940c251..5696c0d4 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -346,10 +346,10 @@ urlpatterns = [ re_path(r'^workout/(?P\b[0-9A-Fa-f]+\b)/video/$',views.workout_video_create_view, name='workout_video_create_view'), re_path(r'^video/(?P\d+)/delete/$',views.VideoDelete.as_view(),name='video_delete'), + re_path(r'^video/(?P\w.+)/m/$',views.workout_video_view_mini, + name='workout_video_view_mini'), re_path(r'^video/(?P\w.+)/$',views.workout_video_view, name='workout_video_view'), - re_path(r'^video/(?P\w.+)/m$',views.workout_video_view_mini, - name='workout_video_view_mini'), re_path(r'^videos/',views.list_videos,name='list_videos'), re_path(r'^add-video/',views.video_selectworkout,name='video_selectworkout'), # re_path(r'^workout/(?P\d+)/$',views.workout_view,name='workout_view'), From ba4ea364f38b602273524e8d559d97692cce0c6e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 18:39:58 +0100 Subject: [PATCH 29/57] inline --- rowers/templates/embedded_video_mini.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rowers/templates/embedded_video_mini.html b/rowers/templates/embedded_video_mini.html index 3ff231a7..ef286ecc 100644 --- a/rowers/templates/embedded_video_mini.html +++ b/rowers/templates/embedded_video_mini.html @@ -153,6 +153,8 @@ function copyText() { var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; + tag.removeAttribute('allowfullscreen'); + tag.setAttribute('donotallowfullscreen','') var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); @@ -179,6 +181,8 @@ function copyText() { height: '315', width: '560', modestbranding: '1', + playsinline: '0', + allowfullscreen: '0', videoId: '{{ video_id }}', events: { 'onReady': onPlayerReady, From 47e841692c22e5925f30fe9a24f7998e30cbab40 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 18:41:42 +0100 Subject: [PATCH 30/57] fix fix --- rowers/templates/embedded_video_mini.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowers/templates/embedded_video_mini.html b/rowers/templates/embedded_video_mini.html index ef286ecc..7eaae2ad 100644 --- a/rowers/templates/embedded_video_mini.html +++ b/rowers/templates/embedded_video_mini.html @@ -181,7 +181,7 @@ function copyText() { height: '315', width: '560', modestbranding: '1', - playsinline: '0', + playsinline: '1', allowfullscreen: '0', videoId: '{{ video_id }}', events: { From b054ac083f0a009aeb786aa0ddace7fc2588afa9 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 19:27:49 +0100 Subject: [PATCH 31/57] playsinline? --- rowers/templates/embedded_video_mini.html | 1 + 1 file changed, 1 insertion(+) diff --git a/rowers/templates/embedded_video_mini.html b/rowers/templates/embedded_video_mini.html index 7eaae2ad..f3a4f22c 100644 --- a/rowers/templates/embedded_video_mini.html +++ b/rowers/templates/embedded_video_mini.html @@ -155,6 +155,7 @@ function copyText() { tag.src = "https://www.youtube.com/iframe_api"; tag.removeAttribute('allowfullscreen'); tag.setAttribute('donotallowfullscreen','') + tag.setAttribute('playsinline','1') var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); From bd37696ed5214fcefd3e5c5349c91536fb96a1b9 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 3 Jan 2020 19:35:43 +0100 Subject: [PATCH 32/57] playsinline --- rowers/templates/embedded_video_mini.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rowers/templates/embedded_video_mini.html b/rowers/templates/embedded_video_mini.html index f3a4f22c..466cb5e9 100644 --- a/rowers/templates/embedded_video_mini.html +++ b/rowers/templates/embedded_video_mini.html @@ -182,8 +182,7 @@ function copyText() { height: '315', width: '560', modestbranding: '1', - playsinline: '1', - allowfullscreen: '0', + playerVars: {'playsinline':'1'}, videoId: '{{ video_id }}', events: { 'onReady': onPlayerReady, From 0a08d22366d70cf5ef86ead9fd177e3db70b7e32 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 4 Jan 2020 10:59:50 +0100 Subject: [PATCH 33/57] adding test and fixing get_dates_timeperiod --- rowers/plannedsessions.py | 5 +++-- rowers/tests/test_simplefunctions.py | 27 +++++++++++++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index ce71c7c8..1064db19 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -706,6 +706,7 @@ def get_team(request): def get_dates_timeperiod(request,startdatestring='',enddatestring='', defaulttimeperiod='thisweek'): # set start end date according timeperiod + # should always return datetime.date timeperiod = request.GET.get('when') @@ -720,8 +721,8 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring='', startdate = dt.datetime.strptime(startdatestring,'%Y-%m-%d').date() enddate = dt.datetime.strptime(enddatestring,'%Y-%m-%d').date() except ValueError: - startdate = parser.parse(startdatestring,fuzzy=True) - enddate = parser.parse(enddatestring, fuzzy=True) + startdate = parser.parse(startdatestring,fuzzy=True).date() + enddate = parser.parse(enddatestring, fuzzy=True).date() return startdate,enddate diff --git a/rowers/tests/test_simplefunctions.py b/rowers/tests/test_simplefunctions.py index 22cc3140..547f7a6e 100644 --- a/rowers/tests/test_simplefunctions.py +++ b/rowers/tests/test_simplefunctions.py @@ -11,11 +11,26 @@ from django.http import Http404 from rowers.views import get_workout +class TestDateTime(TestCase): + def setUp(self): + self.factory = RequestFactory() + + def tearDown(self): + pass + + def test_get_dates(self): + request = self.factory.get('/rowers/sessions/create/user/230/?startdate=13.01.2020&enddate=19.01.2020') + startdate,enddate = get_dates_timeperiod(request) + + teststart = datetime.date(2020,1,1) + self.assertTrue(teststart Date: Sat, 4 Jan 2020 11:02:34 +0100 Subject: [PATCH 34/57] fix date bug --- rowers/tests/test_simplefunctions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rowers/tests/test_simplefunctions.py b/rowers/tests/test_simplefunctions.py index 547f7a6e..fcc8743d 100644 --- a/rowers/tests/test_simplefunctions.py +++ b/rowers/tests/test_simplefunctions.py @@ -25,6 +25,9 @@ class TestDateTime(TestCase): teststart = datetime.date(2020,1,1) self.assertTrue(teststartenddate) + # tests simple functions from views.py class SimpleViewTest(TestCase): From c46d4d977c6e34ec5939e7b8e047c8cd64f46a74 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 4 Jan 2020 14:52:27 +0100 Subject: [PATCH 35/57] removed init.sh --- init.sh | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 init.sh diff --git a/init.sh b/init.sh deleted file mode 100644 index c93635f0..00000000 --- a/init.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -source /srv/venv/bin/activate -cd /srv/app -python manage.py migrate -python manage.py collectstatic --noinput -python manage.py runserver From c2bdc896091ebc6caa8a6d6e0ecdec6e2b9e280d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 4 Jan 2020 15:25:52 +0100 Subject: [PATCH 36/57] team clone gets dates right now --- rowers/views/planviews.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index c820b2ae..05910fbc 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -445,8 +445,9 @@ def plannedsession_create_view(request, sps = get_sessions(r,startdate=startdate,enddate=enddate).exclude( sessiontype='race') - - sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True) + sessiontemplates = PlannedSession.objects.filter( + manager=request.user, + is_template=True).order_by("name") try: trainingplan = TrainingPlan.objects.filter( @@ -1511,11 +1512,11 @@ def plannedsession_teamclone_view(request,id=0): ps.name += ' (copy)' ps.is_template = False - deltadays = ps.enddate-ps.startdate + deltadays = ps.preferreddate-ps.startdate - ps.startdate = timezone.now().date() - ps.enddate = (timezone.now()+deltadays).date() - ps.preferreddate = ps.preferreddate+deltadays + ps.startdate = startdate + ps.enddate = enddate + ps.preferreddate = startdate+deltadays ps.save() From 69148b426a7b1c95e0cd99e291fab2bda6f5bc5d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sun, 5 Jan 2020 19:22:22 +0100 Subject: [PATCH 37/57] Better navigation on mini video page --- rowers/templates/embedded_video_mini.html | 11 +++++++---- rowers/views/workoutviews.py | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/rowers/templates/embedded_video_mini.html b/rowers/templates/embedded_video_mini.html index 466cb5e9..20288285 100644 --- a/rowers/templates/embedded_video_mini.html +++ b/rowers/templates/embedded_video_mini.html @@ -47,7 +47,7 @@ function copyText() { var tempInput = document.createElement("input"); tempInput.style = "position: absolute; left: -1000px; top: -1000px"; - tempInput.value = "{{ siteurl }}/rowers/video/{{ analysis.id|encode }}/"; + tempInput.value = "{{ siteurl }}/rowers/video/{{ analysis.id|encode }}/m/"; document.body.appendChild(tempInput); tempInput.select(); document.execCommand("copy"); @@ -108,19 +108,22 @@ function copyText() {
  • Playing the video will advance the data in synchronization. Use the regular YouTube controls to move around in the video and play it.

    +

    In this reduced view, you cannot edit the video analysis. There is a separate + view for that here. +

  • + href="https://www.facebook.com/sharer/sharer.php?u=https://rowsandall.com/rowers/video/{{ analysis.id|encode }}/m/"> Share diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py index b72db049..592cbc14 100644 --- a/rowers/views/workoutviews.py +++ b/rowers/views/workoutviews.py @@ -131,7 +131,7 @@ def workout_video_view_mini(request,id=''): 'name': w.name }, { - 'url':reverse('workout_video_view',kwargs={'id':encoder.encode_hex(analysis.id)}), + 'url':reverse('workout_video_view_mini',kwargs={'id':encoder.encode_hex(analysis.id)}), 'name': 'Video Analysis' } From 7df562ab189053a1ac320ed555dd344d58226fd1 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 6 Jan 2020 10:02:41 +0100 Subject: [PATCH 38/57] fixing next_run date shift issue on Alert --- rowers/management/commands/processalerts.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rowers/management/commands/processalerts.py b/rowers/management/commands/processalerts.py index febfe20f..12937fcd 100644 --- a/rowers/management/commands/processalerts.py +++ b/rowers/management/commands/processalerts.py @@ -45,7 +45,7 @@ class Command(BaseCommand): # explanatorytexts othertexts = [alert.description()] - + # send email job = myqueue(queue,handle_send_email_alert, alert.manager.email, @@ -58,11 +58,11 @@ class Command(BaseCommand): # advance next_run if not testing: - alert.next_run = datetime.date.today() + datetime.timedelta(days=alert.period) + alert.next_run = datetime.date.today() + datetime.timedelta(days=alert.period-1) alert.save() if testing: print('{nr} alerts found'.format(nr = len(todaysalerts))) - + self.stdout.write(self.style.SUCCESS( 'Successfully processed alerts')) From 8ae0c796a7e44a4b526dca800381d2a9562e7b69 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 6 Jan 2020 20:32:57 +0100 Subject: [PATCH 39/57] fix and adding welcome emails to trial takers --- rowers/c2stuff.py | 1 + rowers/templates/plantrialwelcome.html | 26 ++++++++++++ rowers/templates/protrialewelcome.html | 26 ++++++++++++ rowers/views/userviews.py | 56 ++++++++++++++++---------- 4 files changed, 87 insertions(+), 22 deletions(-) create mode 100644 rowers/templates/plantrialwelcome.html create mode 100644 rowers/templates/protrialewelcome.html diff --git a/rowers/c2stuff.py b/rowers/c2stuff.py index 87895291..4a082f35 100644 --- a/rowers/c2stuff.py +++ b/rowers/c2stuff.py @@ -18,6 +18,7 @@ from iso8601 import ParseError import numpy import json +from json.decoder import JSONDecodeError from rowsandall_app.settings import ( C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET diff --git a/rowers/templates/plantrialwelcome.html b/rowers/templates/plantrialwelcome.html new file mode 100644 index 00000000..9da3e750 --- /dev/null +++ b/rowers/templates/plantrialwelcome.html @@ -0,0 +1,26 @@ +{% extends "emailbase.html" %} + +{% block body %} +

    Dear {{ first_name }},

    + +

    + Welcome on the trial for the Self-Coach plan. +

    +

    +As the developer of the Rowsandall.com site I am very interested to know what you think of Rowsandall.com. Especially, I'd like to understand how you started using the site, what you are looking for, and what you think could be improved. +

    +

    +The Self-Coach functionality allows you to create training plans and sessions for you and your training group. Feel free to contact me any time you need help. +

    +

    +I'd also love to hear a bit about your rowing background. +

    +

    +Thank you very much for your help and for supporting rowsandall.com. +

    + + +

    + Best Regards, the Rowsandall Team +

    +{% endblock %} diff --git a/rowers/templates/protrialewelcome.html b/rowers/templates/protrialewelcome.html new file mode 100644 index 00000000..b2e6d88a --- /dev/null +++ b/rowers/templates/protrialewelcome.html @@ -0,0 +1,26 @@ +{% extends "emailbase.html" %} + +{% block body %} +

    Dear {{ first_name }},

    + +

    + Welcome on the trial for the Pro plan. +

    +

    +As the developer of the Rowsandall.com site I am very interested to know what you think of Rowsandall.com. Especially, I'd like to understand how you started using the site, what you are looking for, and what you think could be improved. +

    +

    +The Self-Coach functionality allows you to create training plans and sessions for you and your training group. Feel free to contact me any time you need help. +

    +

    +I'd also love to hear a bit about your rowing background. +

    +

    +Thank you very much for your help and for supporting rowsandall.com. +

    + + +

    + Best Regards, the Rowsandall Team +

    +{% endblock %} diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py index a8aea814..710fd771 100644 --- a/rowers/views/userviews.py +++ b/rowers/views/userviews.py @@ -13,23 +13,30 @@ def start_trial_view(request): messages.error(request,'You do not qualify for a trial') url = '/rowers/paidplans' return HttpResponseRedirect(url) - + r.protrialexpires = datetime.date.today()+datetime.timedelta(13) r.save() url = reverse('workouts_view') messages.info(request,'We have started your 14 day trial period') - + subject2 = "User started Pro Trial" message2 = "User Started Pro Trial.\n" message2 += request.user.email + "\n" message2 += "User name: "+request.user.username - + send_mail(subject2, message2, 'Rowsandall Server ', ['roosendaalsander@gmail.com']) - + + send_template_email('Rowsandall ', + [r.user.email], + 'Welcome to the Rowsandall Pro Trial', + 'protrialewelcome.html', + {'first_name':r.user.first_name, + 'last_name':r.user.last_name}) + return HttpResponseRedirect(url) @login_required() @@ -40,7 +47,7 @@ def start_plantrial_view(request): messages.error(request,'You do not qualify for a trial') url = '/rowers/paidplans' return HttpResponseRedirect(url) - + r.plantrialexpires = datetime.date.today()+datetime.timedelta(13) r.protrialexpires = datetime.date.today()+datetime.timedelta(13) r.save() @@ -48,16 +55,23 @@ def start_plantrial_view(request): url = reverse('workouts_view') messages.info(request,'We have started your 14 day trial period') - + subject2 = "User started Plan Trial" message2 = "User Started Plan Trial.\n" message2 += request.user.email + "\n" message2 += "User name: "+request.user.username - + send_mail(subject2, message2, 'Rowsandall Server ', ['roosendaalsander@gmail.com']) - + + send_template_email('Rowsandall ', + [r.user.email], + 'Welcome to the Rowsandall Self-Coach Trial', + 'plantrialwelcome.html', + {'first_name':r.user.first_name, + 'last_name':r.user.last_name}) + return HttpResponseRedirect(url) # Page where user can manage his favorite charts @@ -79,7 +93,7 @@ def rower_favoritecharts_view(request,userid=0): FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=0) if aantal==0: FavoriteChartFormSet = formset_factory(FavoriteForm,formset=BaseFavoriteFormSet,extra=1) - + if request.method == 'POST': favorites_formset = FavoriteChartFormSet(request.POST) @@ -115,7 +129,7 @@ def rower_favoritecharts_view(request,userid=0): messages.error(request,message) else: favorites_formset = FavoriteChartFormSet(initial=favorites_data) - + context = { 'favorites_formset':favorites_formset, @@ -123,8 +137,8 @@ def rower_favoritecharts_view(request,userid=0): 'rower':r, } - - + + return render(request,'favoritecharts.html',context) # page where user sets his export settings @@ -154,7 +168,7 @@ def rower_exportsettings_view(request,userid=0): 'name': 'Export Settings' } ] - + return render(request, 'rower_exportsettings.html', {'form':form, 'rower':r, @@ -367,7 +381,7 @@ def rower_prefs_view(request,userid=0,message=""): 'rower':r, }) - + # Revoke an app that you granted access through the API. # this views is called when you press a button on the User edit page # the button is only there when you have granted access to an app @@ -401,7 +415,7 @@ def rower_update_empower_view( r = getrower(request.user) except Rower.DoesNotExist: raise Http404("Rower doesn't exist") - + if request.method == 'POST' and 'daterange' in request.POST: dateform = DateRangeForm(request.POST) if dateform.is_valid(): @@ -416,7 +430,7 @@ def rower_update_empower_view( 'startdate':startdate, 'enddate':enddate, }) - + if request.method == 'POST' and 'workouts' in request.POST: form = WorkoutMultipleCompareForm(request.POST) @@ -424,7 +438,7 @@ def rower_update_empower_view( cd = form.cleaned_data workouts = cd['workouts'] workoutdicts = [] - + for w in workouts: if w.user != r: message = "You can only alter your own workouts" @@ -440,7 +454,7 @@ def rower_update_empower_view( messages.error(request,message) else: - + workoutdict = { 'id':w.id, 'boattype':w.boattype, @@ -454,7 +468,7 @@ def rower_update_empower_view( w.workoutsource = 'speedcoach2corrected' w.save() - + job = myqueue(queuelow,handle_update_empower, request.user.email,workoutdicts, debug=False, @@ -479,7 +493,7 @@ def rower_update_empower_view( workoutsource='speedcoach2', user=r, ).order_by("-date","-starttime") - + form = WorkoutMultipleCompareForm() form.fields["workouts"].queryset = workouts # GET request = prepare form @@ -491,5 +505,3 @@ def rower_update_empower_view( 'form':form, 'rower':r }) - - From 251a52c15904c011be40a77c55b588621345d184 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 6 Jan 2020 21:03:35 +0100 Subject: [PATCH 40/57] better welcomes --- .../templates/paymentconfirmationemail.html | 12 +++++++++- rowers/templates/plantrialwelcome.html | 7 +++++- rowers/templates/protrialewelcome.html | 17 ++++++++++---- .../templates/subscription_update_email.html | 23 ++++++++++++++----- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/rowers/templates/paymentconfirmationemail.html b/rowers/templates/paymentconfirmationemail.html index 0bc62f45..1d97167c 100644 --- a/rowers/templates/paymentconfirmationemail.html +++ b/rowers/templates/paymentconfirmationemail.html @@ -7,6 +7,17 @@ Thank you. We have received the payment of € {{ amount }} for Rowsandall related services.

    +

    + With your contribution, you are helping to keep this service to the rowing community + running. As the founder and developer of the Rowsandall.com site I am very interested + to know what you think of Rowsandall.com, as well as suggestions for improvements. +

    + +

    + So don't hesitate to respond to this email and let me know. I will read and respond to each + email. +

    +

    Please contact our customer service by replying to this email if you have any further questions regarding the payment. @@ -16,4 +27,3 @@ Best Regards, the Rowsandall Team

    {% endblock %} - diff --git a/rowers/templates/plantrialwelcome.html b/rowers/templates/plantrialwelcome.html index 9da3e750..5f588c43 100644 --- a/rowers/templates/plantrialwelcome.html +++ b/rowers/templates/plantrialwelcome.html @@ -15,9 +15,14 @@ The Self-Coach functionality allows you to create training plans and sessions fo

    I'd also love to hear a bit about your rowing background.

    + +

    + So don't hesitate to respond to this email and let me know. I will read and respond to each + email. +

    Thank you very much for your help and for supporting rowsandall.com. -

    +

    diff --git a/rowers/templates/protrialewelcome.html b/rowers/templates/protrialewelcome.html index b2e6d88a..a7bf7892 100644 --- a/rowers/templates/protrialewelcome.html +++ b/rowers/templates/protrialewelcome.html @@ -7,17 +7,24 @@ Welcome on the trial for the Pro plan.

    -As the developer of the Rowsandall.com site I am very interested to know what you think of Rowsandall.com. Especially, I'd like to understand how you started using the site, what you are looking for, and what you think could be improved. -

    -

    -The Self-Coach functionality allows you to create training plans and sessions for you and your training group. Feel free to contact me any time you need help. +As the developer of the Rowsandall.com site I am very interested to know +what you think of Rowsandall.com. +Especially, I'd like to understand how you started using the site, +what you are looking for, and what you think could be improved.

    +

    I'd also love to hear a bit about your rowing background.

    + +

    + So don't hesitate to respond to this email and let me know. I will read and respond to each + email. +

    +

    Thank you very much for your help and for supporting rowsandall.com. -

    +

    diff --git a/rowers/templates/subscription_update_email.html b/rowers/templates/subscription_update_email.html index d805d0d5..6f0cee59 100644 --- a/rowers/templates/subscription_update_email.html +++ b/rowers/templates/subscription_update_email.html @@ -5,22 +5,34 @@

    Thank you. We have received the payment of € {{ amount }} for - your updated Rowsandall subscription. - You are now on the Rowsandall paid plan "{{ planname }}". + your updated Rowsandall subscription. + You are now on the Rowsandall paid plan "{{ planname }}".

    +

    + With your contribution, you are helping to keep this service to the rowing community + running. As the founder and developer of the Rowsandall.com site I am very interested + to know what you think of Rowsandall.com, as well as suggestions for improvements. +

    + +

    + So don't hesitate to respond to this email and let me know. I will read and respond to each + email. +

    + {% if recurring=='recurring' %}

    + Some more information about the subscription. The subscription cost is €{{ price }} per year. Your next charge is due on {{ end_of_billing_period }}. We will charge you automatically - on that date. + on that date.

    The subscription will keep running until you change or stop it. At any point in time you can change the automatically renewing subscription to a "one year only" subscription through the upgrade page. On this page, you can also - upgrade your subscription. + upgrade your subscription.

    {% else %} @@ -28,7 +40,7 @@ The price of the subscription is €{{ price }}. You have paid €{{ amount }} as a prorated cost of your upgrade. This one year subscription will automatically end on {{ end_of_billing_period }}. You can - renew your subscription after that. + renew your subscription after that.

    @@ -60,4 +72,3 @@ Best Regards, the Rowsandall Team

    {% endblock %} - From 8fa46ce8d8c8ea88b682662a42a4702153576038 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 6 Jan 2020 21:13:54 +0100 Subject: [PATCH 41/57] bug fixes and better user emails --- rowers/dataprep.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rowers/dataprep.py b/rowers/dataprep.py index bbfd6ffb..33f961be 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1782,6 +1782,11 @@ def delete_strokedata(id): dirname = 'media/strokedata_{id}.parquet.gz'.format(id=id) try: shutil.rmtree(dirname) + except OSError: + try: + os.remove(dirname) + except FileNotFoundError: + pass except FileNotFoundError: pass From 4c1f717be5d4f8963ad13c93c9fa741748bb8a79 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 6 Jan 2020 22:35:58 +0100 Subject: [PATCH 42/57] improved contact form --- rowers/forms.py | 1 - rowers/templates/email.html | 219 ++++++++++++++++++--------------- rowers/views/statements.py | 37 ++++-- rowsandall_app/settings_dev.py | 2 +- templates/newbase.html | 1 + 5 files changed, 145 insertions(+), 115 deletions(-) diff --git a/rowers/forms.py b/rowers/forms.py index 46de978c..bbd919b8 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -115,7 +115,6 @@ class EmailForm(forms.Form): lastname = forms.CharField(max_length=255) email = forms.EmailField() subject = forms.CharField(max_length=255) - botcheck = forms.CharField(max_length=5) message = forms.CharField() disqualificationreasons = ( diff --git a/rowers/templates/email.html b/rowers/templates/email.html index 474c3765..86fd7b2e 100644 --- a/rowers/templates/email.html +++ b/rowers/templates/email.html @@ -3,115 +3,134 @@ {% block main %}

    Contact us through email

    +
      -
    • - {% if form.errors %} -

      - Please correct the error{{ form.errors|pluralize }} below. -

      - {% endif %} - - -
      {% csrf_token %} - - - - - -
      - - - - - -
      - - - - - - -
      - - - -
      - - - -
      - - - - - -
      - Do you want to send me an email? - - -
      - - - -
      - -
      -
      +
    • + {% if form.errors %} +

      + Please correct the error{{ form.errors|pluralize }} below. +

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

      + + + + + +
      + + + + + +
      + + + + + + +
      + + + +
      + + + +
      + + + + + +
      + + + +
      + +
      +

      +
    • -

      Bug reporting, feature requests

      - -

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

      -

      +

      Bug reporting, feature requests

      + +

      + 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. +

      +

    • -

      Facebook Group

      - -

      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.

      - -
    • +

      Facebook Group

      -
    • -

      Twitter

      - -

      You can also check me on Twitter: -

      - When the site is down, this is the appropriate channel to look for apologies, updates, and offer help. -

      -
    • +

      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.

      + + -
    • -

      Rowsandall s.r.o.

      - -

      Rowsandall s.r.o.
      - Nové sady 988/2
      - 602 00 Brno
      - Czech Republic
      - IČ: 070 48 572
      - DIČ: CZ 070 48 572 (Nejsme plátce DPH)
      - Datová schránka: 7897syr
      - Email: info@rowsandall.com
      - 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)
      -

      +
    • +

      Twitter

      -
    • -
    -{% endblock %} +

    You can also check me on Twitter: +

    + When the site is down, this is the appropriate channel to look for apologies, updates, and offer help. +

    +
  • -{% block sidebar %} -{% include 'menu_help.html' %} -{% endblock %} +
  • +

    Rowsandall s.r.o.

    - +

    Rowsandall s.r.o.
    + Nové sady 988/2
    + 602 00 Brno
    + Czech Republic
    + IČ: 070 48 572
    + DIČ: CZ 070 48 572 (Nejsme plátce DPH)
    + Datová schránka: 7897syr
    + Email: info@rowsandall.com
    + 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)
    +

    + +
  • + + {% endblock %} + + {% block sidebar %} + {% include 'menu_help.html' %} + {% endblock %} + + {% block scripts %} + + + {% endblock %} diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 1f1e700d..f2b3a263 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -1073,28 +1073,39 @@ def add_defaultfavorites(r): f.save() return 1 + # Shows email form and sends it if submitted def sendmail(request): if request.method == 'POST': + # test recaptcha + response_string = request.POST.get('g-recaptcha-response') + # replace below with settings + recaptcha_secret = '6LdRtMwUAAAAABc3piLDlI5VNDkOtEMIOckNi9tm' + 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(): + if form.is_valid() and success: firstname = form.cleaned_data['firstname'] lastname = form.cleaned_data['lastname'] email = form.cleaned_data['email'] - subject = form.cleaned_data['subject'] - botcheck = form.cleaned_data['botcheck'].lower() + subject = 'Rowsandall Contact Form:'+form.cleaned_data['subject'] message = form.cleaned_data['message'] - if botcheck == 'yes': - try: - fullemail = firstname + " " + lastname + " " + "<" + email + ">" - send_mail(subject, message, fullemail, ['info@rowsandall.com']) - return HttpResponseRedirect('/rowers/email/thankyou/') - except: - return HttpResponseRedirect('/rowers/email/') - else: - messages.error(request,'You have to answer YES to the question') - return HttpResponseRedirect('/rowers/email/') + fullemail = firstname + " " + lastname + " " + "<" + email + ">" + send_mail(subject, message, fullemail, ['info@rowsandall.com']) + return HttpResponseRedirect('/rowers/email/thankyou/') else: + if not success: + messages.error(request,'Bots are not welcome') + else: + messages.error(request,'Something went wrong. Please try again') return HttpResponseRedirect('/rowers/email/') else: return HttpResponseRedirect('/rowers/email/') diff --git a/rowsandall_app/settings_dev.py b/rowsandall_app/settings_dev.py index ad4c57c1..d40f8ca2 100644 --- a/rowsandall_app/settings_dev.py +++ b/rowsandall_app/settings_dev.py @@ -60,7 +60,7 @@ DEBUG = True TEMPLATES[0]['OPTIONS']['debug'] = DEBUG -ALLOWED_HOSTS = ['localhost'] +ALLOWED_HOSTS = ['localhost','127.0.0.1'] # INSTALLED_APPS += ['debug_toolbar',] diff --git a/templates/newbase.html b/templates/newbase.html index 3b6f4e2a..885e3f90 100644 --- a/templates/newbase.html +++ b/templates/newbase.html @@ -48,6 +48,7 @@ {% block meta %} {% endblock %}
    + + + +{% endblock %} + +{% block main %} +
      +
    • +
      + {% csrf_token %} + + {{ form.as_table }} +
      + +
    • + +
    +{% endblock %} + +{% block sidebar %} +{% include 'menu_profile.html' %} +{% endblock %} diff --git a/rowers/templates/survey2.html b/rowers/templates/survey2.html new file mode 100644 index 00000000..a59c8179 --- /dev/null +++ b/rowers/templates/survey2.html @@ -0,0 +1,48 @@ +{% extends "newbase.html" %} +{% load staticfiles %} +{% load rowerfilters %} + +{% block title %}Rowsandall {% endblock %} + + +{% block meta %} + + +{% endblock %} + + +{% block main %} + +
      +
    • + + {% csrf_token %} + + {{ form.as_table }} +
      + +
    • + +
    + +{% endblock %} + + + + + +{% block sidebar %} +{% include 'menu_profile.html' %} +{% endblock %} diff --git a/rowers/urls.py b/rowers/urls.py index 97a45af6..7146d4da 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -449,6 +449,7 @@ urlpatterns = [ re_path(r'^user-multiflex-data/$',views.multiflex_data,name='multiflex_data'), re_path(r'^me/deactivate/$',views.deactivate_user,name='deactivate_user'), re_path(r'^me/delete/$',views.remove_user,name='remove_user'), + re_path(r'^survey/$',views.survey,name='survey'), re_path(r'^me/gdpr-optin-confirm/?/$',views.user_gdpr_confirm,name='user_gdpr_confirm'), re_path(r'^me/gdpr-optin-confirm/$',views.user_gdpr_confirm,name='user_gdpr_confirm'), re_path(r'^me/gdpr-optin/?/$',views.user_gdpr_optin,name='user_gdpr_optin'), diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 9f09bccc..aab50741 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -60,7 +60,7 @@ from rowers.forms import ( MetricsForm,DisqualificationForm,disqualificationreasons, disqualifiers,SearchForm,BillingForm,PlanSelectForm, VideoAnalysisCreateForm,WorkoutSingleSelectForm, - VideoAnalysisMetricsForm, + VideoAnalysisMetricsForm,SurveyForm, ) from django.urls import reverse, reverse_lazy diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py index 710fd771..205104fe 100644 --- a/rowers/views/userviews.py +++ b/rowers/views/userviews.py @@ -5,6 +5,31 @@ from __future__ import unicode_literals from rowers.views.statements import * +@login_required() +def survey(request): + + r = getrower(request.user) + + surveyform = SurveyForm() + + if request.method == 'POST': + form = SurveyForm(request.POST) + r.surveydone = True + r.surveydonedate = timezone.now() + r.save() + + nexturl = request.GET.get('next') + return HttpResponseRedirect(nexturl) + + context = { + 'teams':get_my_teams(request.user), + 'rower':r, + 'form':surveyform, + } + + + return render(request,'survey.html',context) + @login_required() def start_trial_view(request): r = getrower(request.user) diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index 283aa476..8814688e 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -98,6 +98,7 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'tz_detect.middleware.TimezoneMiddleware', 'rowers.middleware.GDPRMiddleWare', + 'rowers.middleware.SurveyMiddleWare', 'rowers.middleware.PowerTimeFitnessMetricMiddleWare', 'rowers.middleware.RowerPlanMiddleWare', ] diff --git a/templates/newbase.html b/templates/newbase.html index 41486614..5fab2852 100644 --- a/templates/newbase.html +++ b/templates/newbase.html @@ -327,6 +327,11 @@

    {% endif %} {% block ad %} +
    From 09a490c064a109d76832e325f91e19dc74191022 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 8 Jan 2020 22:43:41 +0100 Subject: [PATCH 54/57] committing survey --- rowers/tests/test_aavirtualevents.py | 107 ++++++------ rowers/tests/test_analysis.py | 115 +++++++------ rowers/tests/test_aworkouts.py | 51 +++--- rowers/tests/test_basicrower.py | 5 +- rowers/tests/test_courses.py | 5 +- rowers/tests/test_cpchart.py | 36 ++-- rowers/tests/test_emails.py | 71 ++++---- rowers/tests/test_empower.py | 10 +- rowers/tests/test_flexchart.py | 20 +-- rowers/tests/test_imports.py | 120 ++++++------- rowers/tests/test_interactivecharts.py | 32 ++-- rowers/tests/test_misc.py | 15 +- rowers/tests/test_newusers.py | 15 +- rowers/tests/test_payments.py | 67 ++++---- rowers/tests/test_permissions.py | 222 ++++++++++++------------- rowers/tests/test_plans.py | 14 +- rowers/tests/test_rowerplans.py | 11 +- rowers/tests/test_settings.py | 4 +- rowers/tests/test_simplefunctions.py | 2 +- rowers/tests/test_staticcharts.py | 62 +++---- rowers/tests/test_team.py | 48 +++--- rowers/tests/test_units.py | 4 +- rowers/tests/test_uploads.py | 83 +++++---- rowers/tests/test_user.py | 48 +++--- rowsandall_app/settings.py | 2 +- 25 files changed, 572 insertions(+), 597 deletions(-) diff --git a/rowers/tests/test_aavirtualevents.py b/rowers/tests/test_aavirtualevents.py index a5be7e82..13609595 100644 --- a/rowers/tests/test_aavirtualevents.py +++ b/rowers/tests/test_aavirtualevents.py @@ -20,7 +20,7 @@ class VirtualEventViewTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='coach') self.c = Client() @@ -36,7 +36,7 @@ class VirtualEventViewTest(TestCase): self.rpiet = Rower.objects.create(user=self.upiet, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.piet_workouts = WorkoutFactory.create_batch(5, user=self.rpiet) @@ -49,7 +49,7 @@ class VirtualEventViewTest(TestCase): self.rklaas = Rower.objects.create(user=self.uklaas, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.klaas_workouts = WorkoutFactory.create_batch(5, user=self.rklaas) @@ -62,7 +62,7 @@ class VirtualEventViewTest(TestCase): self.rhenk = Rower.objects.create(user=self.uhenk, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.henk_workouts = WorkoutFactory.create_batch(5, user=self.rhenk) @@ -83,7 +83,7 @@ class VirtualEventViewTest(TestCase): self.lastweek = lastweek self.intwoweeks = intwoweeks - + # erg races self.openergrace = VirtualRace.objects.create( name = faker.word(), @@ -104,7 +104,7 @@ class VirtualEventViewTest(TestCase): country = 'Indoor', manager = self.u ) - + self.submitergrace = VirtualRace.objects.create( name = faker.word(), startdate = yesterday.date(), @@ -143,7 +143,7 @@ class VirtualEventViewTest(TestCase): ) result = plannedsessions.add_rower_race(self.rpiet,self.submitergrace) - + # register Henk for submitergrace self.henkrecord = IndoorVirtualRaceResult.objects.create( userid = self.rhenk.id, @@ -161,7 +161,7 @@ class VirtualEventViewTest(TestCase): ) result = plannedsessions.add_rower_race(self.rhenk,self.submitergrace) - + # course coursefile = 'rowers/tests/testdata/course_22.kml' @@ -176,8 +176,8 @@ class VirtualEventViewTest(TestCase): course = courses.createcourse(self.r,cname,polygons,notes=cnotes) self.course = course - - + + # otw races self.openotwrace = VirtualRace.objects.create( name = faker.word(), @@ -247,11 +247,11 @@ class VirtualEventViewTest(TestCase): distance=result['totaldist'], workouttype = 'water', ) - + # OTW not matching course result = get_random_file(filename='rowers/tests/testdata/onwater2.csv') - + self.wwater = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -262,11 +262,11 @@ class VirtualEventViewTest(TestCase): ) - + # OTE 1k result = get_random_file(filename='rowers/tests/testdata/duzend_ote.csv') - + self.wduzend_r = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=nu.time(), @@ -279,7 +279,7 @@ class VirtualEventViewTest(TestCase): # Piet result = get_random_file(filename='rowers/tests/testdata/duzend_ote.csv') - + self.wduzend_rpiet = WorkoutFactory(user=self.rpiet, csvfilename=result['filename'], starttime=nu.time(), @@ -292,7 +292,7 @@ class VirtualEventViewTest(TestCase): # Klaas result = get_random_file(filename='rowers/tests/testdata/duzend_ote.csv') - + self.wduzend_rklaas = WorkoutFactory(user=self.rklaas, csvfilename=result['filename'], starttime=nu.time(), @@ -305,7 +305,7 @@ class VirtualEventViewTest(TestCase): # Henk result = get_random_file(filename='rowers/tests/testdata/duzend_ote.csv') - + self.wduzend_rhenk = WorkoutFactory(user=self.rhenk, csvfilename=result['filename'], starttime=nu.time(), @@ -317,7 +317,7 @@ class VirtualEventViewTest(TestCase): - + # OTE different result = get_random_file() self.wother_rpiet = WorkoutFactory(user=self.rpiet, @@ -334,8 +334,8 @@ class VirtualEventViewTest(TestCase): os.remove('rowers/tests/testdata/temp/course.kml') except (FileNotFoundError, OSError, IOError): pass - - + + #Scenarios @@ -344,7 +344,7 @@ class VirtualEventViewTest(TestCase): def test_races_view(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('virtualevents_view') response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -360,7 +360,7 @@ class VirtualEventViewTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - + form_data = { 'country':'All', 'regattatype':'ongoing' @@ -370,7 +370,7 @@ class VirtualEventViewTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - + form_data = { 'country':'All', 'regattatype':'previous' @@ -380,13 +380,13 @@ class VirtualEventViewTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - - + + # set up new OTE race def test_new_indoorrace(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('indoorvirtualevent_create_view') response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -421,15 +421,15 @@ class VirtualEventViewTest(TestCase): self.assertRedirects(response, expected_url = reverse('virtualevents_view'), status_code=302,target_status_code=200) - - - + + + # set up new OTE race def test_edit_indoorrace(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('indoorvirtualevent_edit_view', kwargs={'id':self.openergrace.id}) response = self.c.get(url) @@ -466,17 +466,17 @@ class VirtualEventViewTest(TestCase): expected_url = reverse('virtualevent_view', kwargs={'id':self.openergrace.id}), status_code=302,target_status_code=200) - - - + + + # set up new otw race # set up new OTE race def test_new_race(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('virtualevent_create_view') response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -513,7 +513,7 @@ class VirtualEventViewTest(TestCase): def test_edit_race(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('virtualevent_edit_view',kwargs={'id':self.openotwrace.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -547,12 +547,12 @@ class VirtualEventViewTest(TestCase): expected_url = reverse('virtualevent_view', kwargs={'id':self.openotwrace.id}), status_code=302,target_status_code=200) - + # view def test_race_view(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('virtualevent_view',kwargs={'id':self.openotwrace.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -565,21 +565,21 @@ class VirtualEventViewTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + url = reverse('virtualevent_view',kwargs={'id':self.submitergrace.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) - + # register # withdraw def test_register_race_view(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('indoorvirtualevent_register_view', kwargs={'id':self.openergrace.id}) - + response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -607,7 +607,7 @@ class VirtualEventViewTest(TestCase): login = self.c.login(username=self.upiet.username, password=self.passwordpiet) self.assertTrue(login) - + url = reverse('indoorvirtualevent_register_view',kwargs={'id':self.openergrace.id}) response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -653,10 +653,10 @@ class VirtualEventViewTest(TestCase): def test_register_otwrace_view(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = reverse('virtualevent_register_view', kwargs={'id':self.openotwrace.id}) - + response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -705,7 +705,7 @@ class VirtualEventViewTest(TestCase): response = self.c.post(url,form_data,follow=True) expected_url = reverse('virtualevent_view',kwargs={'id':self.openotwrace.id}) - + self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) @@ -716,13 +716,13 @@ class VirtualEventViewTest(TestCase): response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) - + # submit result (OTE) def test_ote_submit(self): login = self.c.login(username=self.upiet.username, password=self.passwordpiet) self.assertTrue(login) - + url = reverse('virtualevent_submit_result_view', kwargs={'id':self.submitergrace.id, 'workoutid':self.wduzend_rpiet.id}) @@ -741,7 +741,7 @@ class VirtualEventViewTest(TestCase): therecord = IndoorVirtualRaceResult.objects.get(userid=self.rpiet.id, race=self.submitergrace, id=self.pietrecord.id) - + self.assertTrue(therecord.coursecompleted) @@ -755,7 +755,7 @@ class VirtualEventViewTest(TestCase): def test_ote_submitfalse(self): login = self.c.login(username=self.upiet.username, password=self.passwordpiet) self.assertTrue(login) - + url = reverse('virtualevent_submit_result_view', kwargs={'id':self.submitergrace.id, 'workoutid':self.wother_rpiet.id}) @@ -774,7 +774,7 @@ class VirtualEventViewTest(TestCase): therecord = IndoorVirtualRaceResult.objects.get(userid=self.rpiet.id, race=self.submitergrace, id=self.pietrecord.id) - + self.assertTrue(not therecord.coursecompleted) @@ -782,7 +782,7 @@ class VirtualEventViewTest(TestCase): def test_otw_submit(self): login = self.c.login(username=self.upiet.username, password=self.passwordpiet) self.assertTrue(login) - + url = reverse('virtualevent_submit_result_view', kwargs={'id':self.submitotwrace.id, 'workoutid':self.wuh_otw.id}) @@ -819,7 +819,7 @@ class VirtualEventViewTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + def test_otw_courses_edit(self): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) @@ -850,5 +850,4 @@ class VirtualEventViewTest(TestCase): # standalone # calculate course adherence - # other background jobs - + # other background jobs diff --git a/rowers/tests/test_analysis.py b/rowers/tests/test_analysis.py index a4a0de04..50b0ab36 100644 --- a/rowers/tests/test_analysis.py +++ b/rowers/tests/test_analysis.py @@ -9,15 +9,15 @@ from .statements import * nu = datetime.datetime.now() from rowers.views import * - + class WorkoutCompareTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -42,7 +42,7 @@ class WorkoutCompareTest(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/team-compare-select/workout/'+encoded1+'/team/0/user/1/' response = self.c.get(url) @@ -74,14 +74,14 @@ class WorkoutCompareTest(TestCase): self.assertEqual(response.status_code,200) - + class BoxPlotTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -107,7 +107,7 @@ class BoxPlotTest(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/user-boxplot-select/' response = self.c.get(url) @@ -169,17 +169,17 @@ class BoxPlotTest(TestCase): response = self.c.get('/rowers/user-boxplot-data/') - + self.assertEqual(response.status_code,200) - + class ListWorkoutTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -223,14 +223,14 @@ class ListWorkoutTest(TestCase): response = self.c.post(url, form_data) self.assertEqual(response.status_code,200) - + class PlannedSessionTests(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -281,7 +281,7 @@ class ForcecurveTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -314,10 +314,10 @@ class ForcecurveTest(TestCase): class CumStatsTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -347,14 +347,14 @@ class CumStatsTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + class CumFlexTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -393,7 +393,7 @@ class CumFlexTest(TestCase): u'4+', u'8+', u'8x+'] - + form_data = { 'startdate':startdate, 'enddate':enddate, @@ -409,7 +409,7 @@ class CumFlexTest(TestCase): self.factory.user = self.u form = FlexAxesForm(self.factory,form_data) - + url = '/rowers/flexall/' @@ -447,19 +447,19 @@ class CumFlexTest(TestCase): session['options'] = options session.save() response = self.c.get('/') - + url = '/rowers/flexalldata/' response = self.c.get(url) self.assertEqual(response.status_code, 200) - + class MultiFlexTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -498,7 +498,7 @@ class MultiFlexTest(TestCase): u'4+', u'8+', u'8x+'] - + form_data = { 'startdate':startdate, 'enddate':enddate, @@ -550,18 +550,18 @@ class MultiFlexTest(TestCase): session['options'] = options session.save() response = self.c.get('/') - + url = '/rowers/user-multiflex-data/' response = self.c.get(url) self.assertEqual(response.status_code, 200) - + class HistoTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -603,7 +603,7 @@ class HistoTest(TestCase): u'4+', u'8+', u'8x+'] - + form_data = { 'startdate':startdate, 'enddate':enddate, @@ -614,11 +614,11 @@ class HistoTest(TestCase): url = '/rowers/histo/' response = self.c.get(url) self.assertEqual(response.status_code,200) - + response = self.c.post(url, form_data) self.assertEqual(response.status_code,200) - + options = { 'includereststrokes':False, 'rankingonly':False, @@ -647,10 +647,10 @@ class HistoTest(TestCase): class WorkoutCompareTestNew(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -675,7 +675,7 @@ class WorkoutCompareTestNew(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/user-analysis-select/compare/' response = self.c.get(url) @@ -724,7 +724,7 @@ class WorkoutCompareTestNew(TestCase): result = form.is_valid() if not result: print(form.errors) - + self.assertTrue(form.is_valid()) self.assertTrue(optionsform.is_valid()) self.assertTrue(dateform.is_valid()) @@ -736,10 +736,10 @@ class WorkoutCompareTestNew(TestCase): class WorkoutBoxPlotTestNew(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -764,7 +764,7 @@ class WorkoutBoxPlotTestNew(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/user-analysis-select/boxplot/' response = self.c.get(url) @@ -812,7 +812,7 @@ class WorkoutBoxPlotTestNew(TestCase): result = form.is_valid() if not result: print(form.errors) - + self.assertTrue(form.is_valid()) self.assertTrue(optionsform.is_valid()) self.assertTrue(dateform.is_valid()) @@ -824,10 +824,10 @@ class WorkoutBoxPlotTestNew(TestCase): class WorkoutHistoTestNew(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -852,7 +852,7 @@ class WorkoutHistoTestNew(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/user-analysis-select/histo/' response = self.c.get(url) @@ -900,7 +900,7 @@ class WorkoutHistoTestNew(TestCase): result = form.is_valid() if not result: print(form.errors) - + self.assertTrue(form.is_valid()) self.assertTrue(optionsform.is_valid()) self.assertTrue(dateform.is_valid()) @@ -912,10 +912,10 @@ class WorkoutHistoTestNew(TestCase): class WorkoutFlexallTestNew(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -940,7 +940,7 @@ class WorkoutFlexallTestNew(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/user-analysis-select/flexall/' response = self.c.get(url) @@ -988,7 +988,7 @@ class WorkoutFlexallTestNew(TestCase): result = form.is_valid() if not result: print(form.errors) - + self.assertTrue(form.is_valid()) self.assertTrue(optionsform.is_valid()) self.assertTrue(dateform.is_valid()) @@ -1000,10 +1000,10 @@ class WorkoutFlexallTestNew(TestCase): class WorkoutStatsTestNew(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -1028,7 +1028,7 @@ class WorkoutStatsTestNew(TestCase): login = self.c.login(username=self.u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/user-analysis-select/stats/' response = self.c.get(url) @@ -1082,8 +1082,8 @@ class WorkoutStatsTestNew(TestCase): script, div = statsdata(workouts,options) script, div = comparisondata(workouts,options) - - + + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db', side_effect=mocked_getsmallrowdata_db) def test_workouts_stats_submit(self, mocked_sqlalchemy, @@ -1126,7 +1126,7 @@ class WorkoutStatsTestNew(TestCase): result = form.is_valid() if not result: print(form.errors) - + self.assertTrue(form.is_valid()) self.assertTrue(optionsform.is_valid()) self.assertTrue(dateform.is_valid()) @@ -1134,4 +1134,3 @@ class WorkoutStatsTestNew(TestCase): response = self.c.post('/rowers/user-analysis-select/',form_data) self.assertEqual(response.status_code,200) - diff --git a/rowers/tests/test_aworkouts.py b/rowers/tests/test_aworkouts.py index 1b23d1b6..d82bc9ac 100644 --- a/rowers/tests/test_aworkouts.py +++ b/rowers/tests/test_aworkouts.py @@ -33,10 +33,10 @@ def create_image(storage, filename, size=(100, 100), image_mode='RGB', image_for class WorkoutViewTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -48,7 +48,7 @@ class WorkoutViewTest(TestCase): self.u.save() result = get_random_file(filename='rowers/tests/testdata/onwater2.csv') - + self.wwater = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -75,7 +75,7 @@ class WorkoutViewTest(TestCase): ) result = get_random_file(filename='rowers/tests/testdata/erg1.csv') - + self.werg1 = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -86,7 +86,7 @@ class WorkoutViewTest(TestCase): ) result = get_random_file(filename='rowers/tests/testdata/erg2.csv') - + self.werg2 = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -97,7 +97,7 @@ class WorkoutViewTest(TestCase): ) result = get_random_file(filename='rowers/tests/testdata/erg2.csv') - + self.werg2copy = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -107,9 +107,9 @@ class WorkoutViewTest(TestCase): workouttype = 'rower', ) - + result = get_random_file(filename='rowers/tests/testdata/erg3.csv') - + self.werg3 = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -141,7 +141,7 @@ class WorkoutViewTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_joins(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -154,7 +154,7 @@ class WorkoutViewTest(TestCase): d1 = self.werg1.date-datetime.timedelta(days=2) d2 = self.werg2.date+datetime.timedelta(days=2) - + date_form_data = { 'startdate': d1.strftime('%Y-%m%d'), 'enddate': d2.strftime('%Y-%m%d') @@ -162,7 +162,7 @@ class WorkoutViewTest(TestCase): response = self.c.post(url,date_form_data) self.assertEqual(response.status_code,200) - + url = reverse('workouts_join_view') response = self.c.get(url,follow=True) @@ -197,7 +197,7 @@ class WorkoutViewTest(TestCase): self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.middleware.myqueue') @@ -224,8 +224,8 @@ class WorkoutViewTest(TestCase): 'plottype':'line', 'teamid': '', } - - + + response = self.c.post(url,form_data,follow=True) self.assertEqual(response.status_code,200) @@ -269,7 +269,7 @@ class WorkoutViewTest(TestCase): response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_smoothen(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -287,7 +287,7 @@ class WorkoutViewTest(TestCase): 'id':encoder.encode_hex(self.wwater.id) } ) - + self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) @@ -302,12 +302,12 @@ class WorkoutViewTest(TestCase): 'id':encoder.encode_hex(self.wwater.id) } ) - + self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_windform(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -363,7 +363,7 @@ class WorkoutViewTest(TestCase): self.assertEqual(response.status_code,200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_setpowerform(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -409,7 +409,7 @@ class WorkoutViewTest(TestCase): self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_commentview(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -435,7 +435,7 @@ class WorkoutViewTest(TestCase): url = reverse('workout_unsubscribe_view',kwargs={'id':encoder.encode_hex(self.wwater.id)}) response = self.c.get(url) self.assertEqual(response.status_code,200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_mapview(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -471,7 +471,7 @@ class WorkoutViewTest(TestCase): #if not form.is_valid(): # print form.errors #self.assertTrue(form.is_valid()) - + response = self.c.post(url,form_data,format='multipart',follow=True) expected_url = reverse(self.r.defaultlandingpage, @@ -480,7 +480,7 @@ class WorkoutViewTest(TestCase): self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') @patch('rowers.dataprep.getrowdata_db',side_effect=mocked_getrowdata_db) @@ -536,7 +536,7 @@ class WorkoutViewTest(TestCase): response = self.c.post(url,form_data,follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_editsummaryview(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -590,7 +590,7 @@ class WorkoutViewTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db') def test_workout_delete(self, mocked_sqlalchemy, mocked_getsmallrowdata_db): @@ -611,4 +611,3 @@ class WorkoutViewTest(TestCase): self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) - diff --git a/rowers/tests/test_basicrower.py b/rowers/tests/test_basicrower.py index bd889be3..268ab876 100644 --- a/rowers/tests/test_basicrower.py +++ b/rowers/tests/test_basicrower.py @@ -15,10 +15,10 @@ from rowers.views import get_workout class SimpleViewTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='basic') @@ -59,4 +59,3 @@ class SimpleViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/list-workouts/', status_code=302,target_status_code=200) - diff --git a/rowers/tests/test_courses.py b/rowers/tests/test_courses.py index a6a976ad..723dbc74 100644 --- a/rowers/tests/test_courses.py +++ b/rowers/tests/test_courses.py @@ -11,7 +11,7 @@ class CoursesTest(TestCase): self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', ) @@ -73,9 +73,8 @@ class CoursesTest(TestCase): response = self.c.get('/rowers/courses/1/downloadkml/') self.assertEqual(response.status_code,200) - + self.assertEquals( response.get('Content-Disposition'), 'attachment; filename="course_1.kml"' ) - diff --git a/rowers/tests/test_cpchart.py b/rowers/tests/test_cpchart.py index 5429b1cb..4ab3a2bb 100644 --- a/rowers/tests/test_cpchart.py +++ b/rowers/tests/test_cpchart.py @@ -13,15 +13,15 @@ from rowers.utils import calculate_age import rowers.dataprep as dataprep - + @override_settings(TESTING=True) class OTWCPChartTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True,sex='male', + gdproptin=True,surveydone=True,sex='male', weightcategory='hwt', gdproptindate=timezone.now(), rowerplan='coach') @@ -45,8 +45,8 @@ class OTWCPChartTest(TestCase): totaldist = row.df['cum_dist'].max() totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - - + + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -54,7 +54,7 @@ class OTWCPChartTest(TestCase): duration = "%s:%s:%s.%s" % (hours,minutes,seconds,tenths) duration = datetime.time(hour=hours,minute=minutes,second=seconds) - + workoutdate = row.rowdatetime.strftime('%Y-%m-%d') workoutstarttime = row.rowdatetime.strftime('%H:%M:%S') @@ -104,16 +104,16 @@ class OTWCPChartTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code, 200) - - + + @override_settings(TESTING=True) class CPChartTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True,sex='male', + gdproptin=True,surveydone=True,sex='male', weightcategory='hwt', gdproptindate=timezone.now(), rowerplan='coach') @@ -146,7 +146,7 @@ class CPChartTest(TestCase): perfsdf = pd.read_csv('rowers/tests/testdata/calcageperformance.csv') r = self.u.rower - + for i in perfsdf.index: perf = CalcAgePerformance( age = age, @@ -156,14 +156,14 @@ class CPChartTest(TestCase): weightcategory = r.weightcategory ) perf.save() - + def tearDown(self): for workout in self.user_workouts: try: os.remove(workout.csvfilename) except (IOError, FileNotFoundError,OSError): pass - + def test_analytics_page(self): login = self.c.login(username=self.u.username,password=self.password) self.assertTrue(login) @@ -228,7 +228,7 @@ class CPChartTest(TestCase): r = self.u.rower age = calculate_age(r.birthdate) - + wcdurations = [] wcpower = [] durations = [1,4,30,60] @@ -244,7 +244,7 @@ class CPChartTest(TestCase): ) jsondf = df.to_json() - + result = handle_getagegrouprecords( jsondf,distances,durations,age,r.sex,r.weightcategory) @@ -258,8 +258,8 @@ class CPChartTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - - + + @patch('rowers.dataprep.fetchcperg', side_effect = mocked_fetchcperg) @patch('rowers.dataprep.create_engine') def test_rankingpieces(self, mocked_fetchcperg, mocked_sqlalchemy): @@ -322,5 +322,3 @@ class CPChartTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code, 200) - - diff --git a/rowers/tests/test_emails.py b/rowers/tests/test_emails.py index 27bf2795..b65bcd9c 100644 --- a/rowers/tests/test_emails.py +++ b/rowers/tests/test_emails.py @@ -12,23 +12,23 @@ class EmailUpload(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts1') workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + m = Message(mailbox=workoutsbox, from_header = u.email, subject = "run", @@ -73,23 +73,23 @@ class ZipEmailUpload(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts1') workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + m = Message(mailbox=workoutsbox, from_header = u.email, subject = "Sprint", @@ -127,7 +127,7 @@ workout water w = ws[4] self.assertEqual(w.name,'Sprint (5)') - + @override_settings(TESTING=True) class EmailUniCodeUpload(TestCase): def setUp(self): @@ -135,23 +135,23 @@ class EmailUniCodeUpload(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts2') workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + m = Message(mailbox=workoutsbox, from_header = u.email, subject = "Třeboň", @@ -196,23 +196,23 @@ class EmailBikeErgUpload(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts2') workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + m = Message(mailbox=workoutsbox, from_header = u.email, subject = "bikeerg", @@ -257,23 +257,23 @@ class EmailBikeUpload(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts3') workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + m = Message(mailbox=workoutsbox, from_header = u.email, subject = "bike", @@ -311,9 +311,9 @@ workout bike w = ws[0] self.assertEqual(w.workouttype,'Bike') - - -#@pytest.mark.django_db + + +#@pytest.mark.django_db @override_settings(TESTING=True) class EmailTests(TestCase): def setUp(self): @@ -321,24 +321,24 @@ class EmailTests(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + nu = datetime.datetime.now() workoutsbox = Mailbox.objects.create(name='workouts4') workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + for filename in os.listdir(u'rowers/tests/testdata/emails'): m = Message(mailbox=workoutsbox, from_header = u.email, @@ -384,7 +384,7 @@ race 1 os.remove(path) except (IOError,FileNotFoundError,OSError): pass - + @patch('rowers.dataprep.create_engine') @patch('rowers.polarstuff.get_polar_notifications') @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests) @@ -396,7 +396,7 @@ race 1 self.assertIn('Successfully processed email attachments',out.getvalue()) - + @override_settings(TESTING=True) class EmailAdminUpload(TestCase): def setUp(self): @@ -404,7 +404,7 @@ class EmailAdminUpload(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now(), birthdate = faker.profile()['birthdate'] ) @@ -412,10 +412,10 @@ class EmailAdminUpload(TestCase): self.theadmin = UserFactory(is_staff=True) self.rtheadmin = Rower.objects.create(user=self.theadmin, birthdate = faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') - + self.race = RaceFactory(manager = self.theadmin) nu = datetime.datetime.now() @@ -423,7 +423,7 @@ class EmailAdminUpload(TestCase): workoutsbox.save() failbox = Mailbox.objects.create(name='Failed') failbox.save() - + m = Message(mailbox=workoutsbox, from_header = self.theadmin.email, subject = "johnsworkout", @@ -460,7 +460,7 @@ race 1 if not len(ws): for w in Workout.objects.all(): print(w) - + self.assertEqual(len(ws),1) w = ws[0] @@ -473,4 +473,3 @@ race 1 result = results[0] self.assertTrue(result.coursecompleted) - diff --git a/rowers/tests/test_empower.py b/rowers/tests/test_empower.py index 4681113a..9073dd0c 100644 --- a/rowers/tests/test_empower.py +++ b/rowers/tests/test_empower.py @@ -14,10 +14,10 @@ class EmpowerTest(TestCase): 'sander@ds.ds', 'koeinsloot', ) - r = Rower.objects.create(user=u,rowerplan='coach',gdproptin=True, + r = Rower.objects.create(user=u,rowerplan='coach',gdproptin=True,surveydone=True, gdproptindate=timezone.now()) self.c = Client() - + self.nu = datetime.datetime.now() filename = 'rowers/tests/testdata/testdata.csv' otwfilename = 'rowers/tests/testdata/empower.csv' @@ -27,20 +27,20 @@ class EmpowerTest(TestCase): starttime=self.nu.strftime('%H:%M:%S'), duration="0:55:00",distance=8000, csvfilename=filename) - + self.wote = Workout.objects.create(name='testworkout', workouttype='Indoor Rower', user=r,date=self.nu.strftime('%Y-%m-%d'), starttime=self.nu.strftime('%H:%M:%S'), duration="0:55:00",distance=8000, csvfilename=otwfilename) - + powerperc = 100*np.array([r.pw_ut2, r.pw_ut1, r.pw_at, r.pw_tr,r.pw_an])/r.ftp - + self.hrdata = { 'hrmax':r.max, 'hrut2':r.ut2, diff --git a/rowers/tests/test_flexchart.py b/rowers/tests/test_flexchart.py index 96ed9e52..27869afa 100644 --- a/rowers/tests/test_flexchart.py +++ b/rowers/tests/test_flexchart.py @@ -9,10 +9,10 @@ from .statements import * class WorkoutViewTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', showfavoritechartnotes=True) @@ -25,7 +25,7 @@ class WorkoutViewTest(TestCase): self.u.save() result = get_random_file(filename='rowers/tests/testdata/onwater2.csv') - + self.wwater = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -47,7 +47,7 @@ class WorkoutViewTest(TestCase): ) result = get_random_file(filename='rowers/tests/testdata/erg1.csv') - + self.werg1 = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -58,7 +58,7 @@ class WorkoutViewTest(TestCase): ) result = get_random_file(filename='rowers/tests/testdata/erg2.csv') - + self.werg2 = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -69,7 +69,7 @@ class WorkoutViewTest(TestCase): ) result = get_random_file(filename='rowers/tests/testdata/erg3.csv') - + self.werg3 = WorkoutFactory(user=self.r, csvfilename=result['filename'], starttime=result['starttime'], @@ -98,7 +98,7 @@ class WorkoutViewTest(TestCase): notes=faker.word(), user=self.r ) - + def tearDown(self): pass @@ -113,7 +113,7 @@ class WorkoutViewTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + # change chart form_data = { 'xaxis':'time', @@ -161,7 +161,7 @@ class WorkoutViewTest(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + # change chart form_data = { 'xaxis':'time', @@ -190,4 +190,4 @@ class WorkoutViewTest(TestCase): } response = self.c.post(url,form_data) - self.assertEqual(response.status_code,200) + self.assertEqual(response.status_code,200) diff --git a/rowers/tests/test_imports.py b/rowers/tests/test_imports.py index 1612cef5..03710671 100644 --- a/rowers/tests/test_imports.py +++ b/rowers/tests/test_imports.py @@ -10,7 +10,7 @@ nu = datetime.datetime.now() import rowers -@pytest.mark.django_db +@pytest.mark.django_db @override_settings(TESTING=True) class C2Objects(DjangoTestCase): def setUp(self): @@ -22,7 +22,7 @@ class C2Objects(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -33,9 +33,9 @@ class C2Objects(DjangoTestCase): self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -44,7 +44,7 @@ class C2Objects(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -65,15 +65,15 @@ class C2Objects(DjangoTestCase): csvfilename=filename ) - + @patch('rowers.c2stuff.Session', side_effect=mocked_requests) def test_c2_callback(self, mock_Session): response = self.c.get('/call_back?code=dsdoij232s',follow=True) - + self.assertEqual(response.status_code, 200) - + @patch('rowers.c2stuff.Session', side_effect=mocked_requests) def test_c2_token_refresh(self, mock_Session): response = self.c.get('/rowers/me/c2refresh/',follow=True) @@ -99,7 +99,7 @@ class C2Objects(DjangoTestCase): response = self.c.get('/rowers/workout/c2list',follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests) @patch('rowers.dataprep.create_engine') def test_c2_import(self, mock_get, mocked_sqlalchemy): @@ -112,7 +112,7 @@ class C2Objects(DjangoTestCase): self.assertEqual(response.status_code, 200) - + @patch('rowers.dataprep.create_engine') def test_strokedata(self, mocked_sqlalchemy): with open('rowers/tests/testdata/c2stroketestdata.txt','r') as infile: @@ -157,7 +157,7 @@ class C2ObjectsTokenExpired(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -168,9 +168,9 @@ class C2ObjectsTokenExpired(DjangoTestCase): self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -179,7 +179,7 @@ class C2ObjectsTokenExpired(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -200,7 +200,7 @@ class C2ObjectsTokenExpired(DjangoTestCase): csvfilename=filename ) - + @patch('rowers.c2stuff.requests.post', side_effect=mocked_requests) @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests) @@ -209,7 +209,7 @@ class C2ObjectsTokenExpired(DjangoTestCase): response = self.c.get('/rowers/workout/c2list',follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.c2stuff.requests.get', side_effect=mocked_requests) @patch('rowers.dataprep.create_engine') def test_c2_import(self, mock_get, mocked_sqlalchemy): @@ -222,9 +222,9 @@ class C2ObjectsTokenExpired(DjangoTestCase): self.assertEqual(response.status_code, 200) - - -#@pytest.mark.django_db + + +#@pytest.mark.django_db @override_settings(TESTING=True) class StravaObjects(DjangoTestCase): def setUp(self): @@ -236,7 +236,7 @@ class StravaObjects(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -247,9 +247,9 @@ class StravaObjects(DjangoTestCase): self.r.save() self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -258,7 +258,7 @@ class StravaObjects(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -329,10 +329,10 @@ class StravaObjects(DjangoTestCase): self.assertEqual(result,"987654321234567898765432123456789") - -#@pytest.mark.django_db + +#@pytest.mark.django_db @override_settings(TESTING=True) -class STObjects(DjangoTestCase): +class STObjects(DjangoTestCase): def setUp(self): self.c = Client() self.u = User.objects.create_user('john', @@ -342,7 +342,7 @@ class STObjects(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -355,9 +355,9 @@ class STObjects(DjangoTestCase): self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -366,7 +366,7 @@ class STObjects(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -391,10 +391,10 @@ class STObjects(DjangoTestCase): def test_sporttracks_callback(self, mock_post): response = self.c.get('/sporttracks_callback?code=dsdoij232s',follow=True) - + self.assertEqual(response.status_code, 200) - + @patch('rowers.sporttracksstuff.requests.post', side_effect=mocked_requests) def test_sporttracks_token_refresh(self, mock_post): response = self.c.get('/rowers/me/sporttracksrefresh/',follow=True) @@ -419,7 +419,7 @@ class STObjects(DjangoTestCase): response = self.c.get('/rowers/workout/sporttracksimport',follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.imports.requests.get', side_effect=mocked_requests) def test_sporttracks_import(self, mock_get): @@ -478,9 +478,9 @@ class STObjects(DjangoTestCase): res = add_workout_from_data(self.u,1,data,data) -#@pytest.mark.django_db +#@pytest.mark.django_db @override_settings(TESTING=True) -class RunKeeperObjects(DjangoTestCase): +class RunKeeperObjects(DjangoTestCase): def setUp(self): self.c = Client() self.u = User.objects.create_user('john', @@ -490,7 +490,7 @@ class RunKeeperObjects(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -502,9 +502,9 @@ class RunKeeperObjects(DjangoTestCase): self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -513,7 +513,7 @@ class RunKeeperObjects(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -557,7 +557,7 @@ class RunKeeperObjects(DjangoTestCase): response = self.c.get('/rowers/workout/runkeeperimport',follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.imports.requests.get', side_effect=mocked_requests) def test_runkeeper_import(self, mock_get): @@ -570,10 +570,10 @@ class RunKeeperObjects(DjangoTestCase): self.assertEqual(response.status_code, 200) - -@pytest.mark.django_db + +@pytest.mark.django_db @override_settings(TESTING=True) -class UAObjects(DjangoTestCase): +class UAObjects(DjangoTestCase): def setUp(self): self.c = Client() self.u = User.objects.create_user('john', @@ -583,7 +583,7 @@ class UAObjects(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -596,9 +596,9 @@ class UAObjects(DjangoTestCase): self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -607,7 +607,7 @@ class UAObjects(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -632,10 +632,10 @@ class UAObjects(DjangoTestCase): def test_underarmour_callback(self, mock_post): response = self.c.get('/underarmour_callback?code=dsdoij232s',follow=True) - + self.assertEqual(response.status_code, 200) - + @patch('rowers.underarmourstuff.requests.post', side_effect=mocked_requests) def test_underarmour_token_refresh(self, mock_post): response = self.c.get('/rowers/me/underarmourrefresh/',follow=True) @@ -660,7 +660,7 @@ class UAObjects(DjangoTestCase): response = self.c.get('/rowers/workout/underarmourimport',follow=True) self.assertEqual(response.status_code,200) - + @patch('rowers.imports.requests.get', side_effect=mocked_requests) @patch('rowers.dataprep.create_engine') def test_underarmour_import(self, mock_get, mocked_sqlalchemy): @@ -674,9 +674,9 @@ class UAObjects(DjangoTestCase): self.assertEqual(response.status_code, 200) -#@pytest.mark.django_db +#@pytest.mark.django_db @override_settings(TESTING=True) -class TPObjects(DjangoTestCase): +class TPObjects(DjangoTestCase): def setUp(self): self.c = Client() self.u = User.objects.create_user('john', @@ -686,7 +686,7 @@ class TPObjects(DjangoTestCase): self.u.first_name = 'John' self.u.last_name = 'Sander' self.u.save() - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) @@ -699,9 +699,9 @@ class TPObjects(DjangoTestCase): self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() - + filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -710,7 +710,7 @@ class TPObjects(DjangoTestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -735,10 +735,10 @@ class TPObjects(DjangoTestCase): def test_tp_callback(self, mock_post): response = self.c.get('/tp_callback?code=dsdoij232s',follow=True) - + self.assertEqual(response.status_code, 200) - + @patch('rowers.tpstuff.requests.post', side_effect=mocked_requests) def test_tp_token_refresh(self, mock_post): response = self.c.get('/rowers/me/tprefresh/',follow=True) @@ -761,7 +761,7 @@ class TPObjects(DjangoTestCase): self.assertEqual(response.status_code, 302) -#@pytest.mark.django_db +#@pytest.mark.django_db @override_settings(TESTING=True) class AutoExportTests(TestCase): def setUp(self): @@ -769,7 +769,7 @@ class AutoExportTests(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) diff --git a/rowers/tests/test_interactivecharts.py b/rowers/tests/test_interactivecharts.py index 4d7fb2cd..7572d68e 100644 --- a/rowers/tests/test_interactivecharts.py +++ b/rowers/tests/test_interactivecharts.py @@ -14,7 +14,7 @@ class InteractiveChartTest(TestCase): u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.nu = datetime.datetime.now() @@ -26,7 +26,7 @@ class InteractiveChartTest(TestCase): starttime=self.nu.strftime('%H:%M:%S'), duration="0:55:00",distance=8000, csvfilename=self.filename) - + self.wote = Workout.objects.create(name='testworkout', workouttype='Indoor Rower', user=r,date=self.nu.strftime('%Y-%m-%d'), @@ -40,7 +40,7 @@ class InteractiveChartTest(TestCase): def test_painsled(self, mocked_sqlalchemy, mocked_read_df_sql): u = User.objects.get(username='john') r = Rower.objects.get(user=u) - + rr = rrower(hrmax=r.max,hrut2=r.ut2, hrut1=r.ut1,hrat=r.at, hrtr=r.tr,hran=r.an,ftp=r.ftp) @@ -59,7 +59,7 @@ class InteractiveChartTest(TestCase): @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_interactive_chart2(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + mocked_getsmallrowdata_db): res = iplots.interactive_chart(self.wote.id,promember=1) @patch('rowers.dataprep.create_engine') @@ -69,7 +69,7 @@ class InteractiveChartTest(TestCase): @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_df_sql') - def test_interactive_chart4(self, mocked_sqlalchemy,mocked_read_df_sql): + def test_interactive_chart4(self, mocked_sqlalchemy,mocked_read_df_sql): res = iplots.interactive_bar_chart(self.wote.id,promember=1) @patch('rowers.dataprep.create_engine') @@ -90,7 +90,7 @@ class InteractiveChartTest(TestCase): @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_interactive_chart7(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + mocked_getsmallrowdata_db): res = iplots.interactive_flex_chart2(self.wote.id,promember=0, xparam='time', yparam1='pace',yparam2='spm') @@ -98,8 +98,8 @@ class InteractiveChartTest(TestCase): @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) - def test_interactive_chart8(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + def test_interactive_chart8(self, mocked_sqlalchemy,mocked_read_df_sql, + mocked_getsmallrowdata_db): res = iplots.interactive_flex_chart2(self.wote.id, promember=0,xparam='distance', yparam1='pace',yparam2='spm') @@ -108,23 +108,23 @@ class InteractiveChartTest(TestCase): @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_interactive_chart9(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + mocked_getsmallrowdata_db): res = iplots.interactive_flex_chart2(self.wote.id, promember=1,xparam='time', yparam1='pace',yparam2='hr') @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) - def test_interactive_chart10(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + def test_interactive_chart10(self, mocked_sqlalchemy,mocked_read_df_sql, + mocked_getsmallrowdata_db): res = iplots.interactive_flex_chart2(self.wote.id, promember=1,xparam='distance', yparam1='pace',yparam2='hr') @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) - def test_interactive_chart11(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + def test_interactive_chart11(self, mocked_sqlalchemy,mocked_read_df_sql, + mocked_getsmallrowdata_db): res = iplots.interactive_flex_chart2(self.wote.id, promember=1,xparam='time', yparam1='pace',yparam2='spm') @@ -132,10 +132,8 @@ class InteractiveChartTest(TestCase): @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.read_df_sql') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) - def test_interactive_chart12(self, mocked_sqlalchemy,mocked_read_df_sql, - mocked_getsmallrowdata_db): + def test_interactive_chart12(self, mocked_sqlalchemy,mocked_read_df_sql, + mocked_getsmallrowdata_db): res = iplots.interactive_flex_chart2(self.wote.id,promember=1, xparam='distance', yparam1='pace',yparam2='spm') - - diff --git a/rowers/tests/test_misc.py b/rowers/tests/test_misc.py index f572f495..cf97672c 100644 --- a/rowers/tests/test_misc.py +++ b/rowers/tests/test_misc.py @@ -9,15 +9,15 @@ from .statements import * nu = datetime.datetime.now() - -#@pytest.mark.django_db + +#@pytest.mark.django_db class WorkoutTests(TestCase): def setUp(self): redis_connection.publish('tasks','KILL') self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) nu = datetime.datetime.now() @@ -30,14 +30,14 @@ class WorkoutTests(TestCase): def test_checkworkoutuser(self): self.assertEqual(checkworkoutuser(self.u,self.w),True) -#@pytest.mark.django_db +#@pytest.mark.django_db class C2Tests(TestCase): def setUp(self): redis_connection.publish('tasks','KILL') self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.nu = datetime.datetime.now() @@ -54,7 +54,7 @@ class C2Tests(TestCase): -#@pytest.mark.django_db +#@pytest.mark.django_db class subroutinetests(TestCase): def setUp(self): redis_connection.publish('tasks','KILL') @@ -77,6 +77,3 @@ class subroutinetests(TestCase): jsond = json.dumps(data) data = c2stuff.createc2workoutdata_as_splits(w) jsond = json.dumps(data) - - - diff --git a/rowers/tests/test_newusers.py b/rowers/tests/test_newusers.py index 2d5960e3..29f93712 100644 --- a/rowers/tests/test_newusers.py +++ b/rowers/tests/test_newusers.py @@ -8,7 +8,7 @@ from .statements import * nu = datetime.datetime.now() -#@pytest.mark.django_db +#@pytest.mark.django_db @override_settings(TESTING=True) class NewUserRegistrationTest(TestCase): def setUp(self): @@ -20,7 +20,7 @@ class NewUserRegistrationTest(TestCase): os.remove('rowsandall_workouts_2018-01-01_2019-01-01.csv') except: pass - + @patch('rowers.dataprep.workout_summary_to_df',side_effect=mock_workout_summaries) def test_newuser(self,mock_workout_summaries): form_data = { @@ -40,11 +40,11 @@ class NewUserRegistrationTest(TestCase): form = RegistrationFormUniqueEmail(form_data) self.assertTrue(form.is_valid()) - + response = self.c.post('/rowers/register/', form_data, follow=True) - + self.assertRedirects(response, - expected_url='/rowers/me/gdpr-optin/?next=/rowers/list-workouts/', + expected_url='/rowers/survey/?next=/rowers/list-workouts/', status_code=302,target_status_code=200) @@ -73,7 +73,7 @@ class NewUserRegistrationTest(TestCase): response = self.c.post(url,form_data) self.assertTrue(response.status_code,200) - + url = '/rowers/me/delete/' form_data = { @@ -84,6 +84,3 @@ class NewUserRegistrationTest(TestCase): self.assertRedirects(response, expected_url='/login/', status_code=302,target_status_code=200) - - - diff --git a/rowers/tests/test_payments.py b/rowers/tests/test_payments.py index cc23d5e0..b2795935 100644 --- a/rowers/tests/test_payments.py +++ b/rowers/tests/test_payments.py @@ -15,7 +15,7 @@ class PaymentTest(TestCase): def setUp(self): # settings.DEBUG = True - + p1 = PaidPlan( shortname='free', name='Basic', @@ -64,7 +64,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -79,7 +79,7 @@ class PaymentTest(TestCase): u.save() login = self.c.login(username=u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/billing/' response = self.c.get(url) @@ -93,7 +93,7 @@ class PaymentTest(TestCase): for code, name in list(countries): if name.lower() == country.lower(): countrycode = code - + form_data = { 'street_address':faker.street_address(), 'city':faker.city(), @@ -112,7 +112,7 @@ class PaymentTest(TestCase): self.assertEqual(response.status_code,200) expected_url = '/rowers/checkout/'+str(plan.id)+'/' - + self.assertRedirects(response, expected_url = expected_url, status_code=302,target_status_code=200) @@ -122,7 +122,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -139,10 +139,10 @@ class PaymentTest(TestCase): r.save() u.set_password(self.password) u.save() - + login = self.c.login(username=u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/upgrade/' response = self.c.get(url) @@ -156,7 +156,7 @@ class PaymentTest(TestCase): for code, name in list(countries): if name.lower() == country.lower(): countrycode = code - + form_data = { 'street_address':faker.street_address(), 'city':faker.city(), @@ -175,7 +175,7 @@ class PaymentTest(TestCase): self.assertEqual(response.status_code,200) expected_url = '/rowers/upgradecheckout/'+str(plan.id)+'/' - + self.assertRedirects(response, expected_url = expected_url, status_code=302,target_status_code=200) @@ -185,7 +185,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -208,10 +208,10 @@ class PaymentTest(TestCase): r.save() u.set_password(self.password) u.save() - + login = self.c.login(username=u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/downgrade/' response = self.c.get(url) @@ -222,7 +222,7 @@ class PaymentTest(TestCase): for code, name in list(countries): if name.lower() == country.lower(): countrycode = code - + form_data = { 'street_address':faker.street_address(), 'city':faker.city(), @@ -241,7 +241,7 @@ class PaymentTest(TestCase): self.assertEqual(response.status_code,200) expected_url = '/rowers/downgradecheckout/'+str(plans[0].id)+'/' - + self.assertRedirects(response, expected_url = expected_url, status_code=302,target_status_code=200) @@ -251,7 +251,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -274,22 +274,22 @@ class PaymentTest(TestCase): r.paidplan = plan r.save() - + login = self.c.login(username=u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/me/cancelsubscriptions/' response = self.c.get(url) self.assertEqual(response.status_code,200) - + @patch('rowers.views.braintreestuff.gateway',side_effect=MockBraintreeGateway) def test_planstobasic_view(self,mocked_gateway): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -312,10 +312,10 @@ class PaymentTest(TestCase): r.paidplan = plan r.save() - + login = self.c.login(username=u.username, password=self.password) self.assertTrue(login) - + url = '/rowers/me/cancelsubscription/34/' response = self.c.get(url,follow=True) @@ -329,7 +329,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -344,13 +344,13 @@ class PaymentTest(TestCase): r.save() result = mocktest(r) self.assertEqual(result,'121') - + @patch('rowers.views.braintreestuff.create_subscription', side_effect=mock_create_subscription) def test_checkouts_view(self,mock_subscription): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -396,7 +396,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -435,13 +435,13 @@ class PaymentTest(TestCase): self.assertRedirects(response, expected_url = '/rowers/paymentcompleted/?amount=20.00', status_code=302,target_status_code=200) - + @patch('rowers.views.braintreestuff.update_subscription', side_effect=mock_update_subscription) def test_downgrade_checkouts_view(self,mock_subscription): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -480,13 +480,13 @@ class PaymentTest(TestCase): self.assertRedirects(response, expected_url = '/rowers/downgradecompleted/', status_code=302,target_status_code=200) - + @patch('rowers.views.braintreestuff.create_subscription', side_effect=mock_create_subscription) def test_checkouts_view(self,mock_subscription): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -536,7 +536,7 @@ class PaymentTest(TestCase): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -575,13 +575,13 @@ class PaymentTest(TestCase): self.assertRedirects(response, expected_url = '/rowers/paymentcompleted/?amount=20.00', status_code=302,target_status_code=200) - + @patch('rowers.views.braintreestuff.update_subscription', side_effect=mock_update_subscription) def test_downgrade_checkouts_view(self,mock_subscription): u = UserFactory() r = Rower.objects.create(user=u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', paymentprocessor='braintree', @@ -620,4 +620,3 @@ class PaymentTest(TestCase): self.assertRedirects(response, expected_url = '/rowers/downgradecompleted/', status_code=302,target_status_code=200) - diff --git a/rowers/tests/test_permissions.py b/rowers/tests/test_permissions.py index a82002a7..2213a7b8 100644 --- a/rowers/tests/test_permissions.py +++ b/rowers/tests/test_permissions.py @@ -23,7 +23,7 @@ class PermissionsFreeCoach(TestCase): self.ufreecoach = UserFactory(username='coachuser') self.rfreecoach = Rower.objects.create(user=self.ufreecoach, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='freecoach',clubsize=100) self.coachinggroup = CoachingGroup.objects.create() @@ -33,11 +33,11 @@ class PermissionsFreeCoach(TestCase): self.password = faker.word() self.ufreecoach.set_password(self.password) self.ufreecoach.save() - + self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) @@ -45,11 +45,11 @@ class PermissionsFreeCoach(TestCase): self.password = faker.word() self.uplan.set_password(self.password) self.uplan.save() - + self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) @@ -61,7 +61,7 @@ class PermissionsFreeCoach(TestCase): self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) @@ -69,11 +69,11 @@ class PermissionsFreeCoach(TestCase): self.password = faker.word() self.uplan2.set_password(self.password) self.uplan2.save() - + self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) @@ -85,7 +85,7 @@ class PermissionsFreeCoach(TestCase): self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) @@ -93,9 +93,9 @@ class PermissionsFreeCoach(TestCase): self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() - - - + + + ## TeamFreeCoach self.teamfreecoach = Team.objects.create( @@ -120,8 +120,8 @@ class PermissionsFreeCoach(TestCase): ) self.assertEqual(team2.manager,self.ufreecoach) - - + + team3 = Team.objects.create( name = 'ThirdTeam', notes = faker.text(), @@ -129,9 +129,9 @@ class PermissionsFreeCoach(TestCase): ) self.assertEqual(team3.manager,self.ufreecoach) - - - + + + ## Free coach can create more than one group def test_plan_groupmanager(self): team1 = Team.objects.create( @@ -147,11 +147,11 @@ class PermissionsFreeCoach(TestCase): notes = faker.text(), manager = self.ufreecoach, ) - - self.assertEqual(team2.manager,self.ufreecoach) - - + self.assertEqual(team2.manager,self.ufreecoach) + + + ## Free Coach can create planned sessions and team planned sessions ## Self Coach and higher can create planned sessions and team planned sessions def test_plan_create_session(self): @@ -161,7 +161,7 @@ class PermissionsFreeCoach(TestCase): comment=faker.text() ) self.assertEqual(ps.manager,self.ufreecoach) - + def test_coach_create_session(self): ps = PlannedSession.objects.create( manager=self.ufreecoach, @@ -169,8 +169,8 @@ class PermissionsFreeCoach(TestCase): comment=faker.text() ) self.assertEqual(ps.manager,self.ufreecoach) - - + + ## Basic cannot join groups led by Free Coach def test_add_basic_pro_or_plan(self): with transaction.atomic(): @@ -191,7 +191,7 @@ class PermissionsFreeCoach(TestCase): distance=result['totaldist'], workouttype = 'rower', ) - + @override_settings(TESTING=True) class PermissionsBasicsTests(TestCase): def setUp(self): @@ -201,7 +201,7 @@ class PermissionsBasicsTests(TestCase): self.ucoach = UserFactory(username='coachuser') self.rcoach = Rower.objects.create(user=self.ucoach, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='coach',clubsize=10) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) @@ -212,11 +212,11 @@ class PermissionsBasicsTests(TestCase): self.password = faker.word() self.ucoach.set_password(self.password) self.ucoach.save() - + self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) @@ -224,11 +224,11 @@ class PermissionsBasicsTests(TestCase): self.password = faker.word() self.uplan.set_password(self.password) self.uplan.save() - + self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) @@ -240,7 +240,7 @@ class PermissionsBasicsTests(TestCase): self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) @@ -248,11 +248,11 @@ class PermissionsBasicsTests(TestCase): self.password = faker.word() self.uplan2.set_password(self.password) self.uplan2.save() - + self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) @@ -264,7 +264,7 @@ class PermissionsBasicsTests(TestCase): self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) @@ -272,9 +272,9 @@ class PermissionsBasicsTests(TestCase): self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() - - - + + + ## TeamPro, TeamCoach, TeamSelfCoach self.teampro = Team.objects.create( @@ -293,9 +293,9 @@ class PermissionsBasicsTests(TestCase): manager=self.ucoach) # Requirements - + ## Low level - + ## Coach can have any number of groups def test_coach_groupmanager(self): team1 = Team.objects.create( @@ -313,8 +313,8 @@ class PermissionsBasicsTests(TestCase): ) self.assertEqual(team2.manager,self.ucoach) - - + + team3 = Team.objects.create( name = 'ThirdTeam', notes = faker.text(), @@ -322,15 +322,15 @@ class PermissionsBasicsTests(TestCase): ) self.assertEqual(team3.manager,self.ucoach) - - - + + + ## Basic athletes can be member of Coach led group def test_add_coach(self): self.rbasic.team.add(self.teamcoach) self.assertIn(self.teamcoach,self.rbasic.team.all()) - - + + ## Self coach can create one group ## Self coach cannot create more than one group def test_plan_groupmanager(self): @@ -348,9 +348,9 @@ class PermissionsBasicsTests(TestCase): notes = faker.text(), manager = self.uplan, ) - - - + + + ## Pro users (and higher) can join group led by other Pro (or higher) user def test_add_proplan_pro_or_plan(self): self.rpro.team.add(self.teamplan) @@ -371,9 +371,9 @@ class PermissionsBasicsTests(TestCase): self.rcoach.team.add(self.teampro) self.assertIn(self.teampro,self.rcoach.team.all()) - - - + + + ## Coach can create planned sessions and team planned sessions ## Self Coach and higher can create planned sessions and team planned sessions def test_plan_create_session(self): @@ -383,7 +383,7 @@ class PermissionsBasicsTests(TestCase): comment=faker.text() ) self.assertEqual(ps.manager,self.uplan) - + def test_coach_create_session(self): ps = PlannedSession.objects.create( manager=self.ucoach, @@ -391,7 +391,7 @@ class PermissionsBasicsTests(TestCase): comment=faker.text() ) self.assertEqual(ps.manager,self.ucoach) - + ## Pro can have one group ## Pro cannot create more than one group def test_pro_groupmanager(self): @@ -409,8 +409,8 @@ class PermissionsBasicsTests(TestCase): notes = faker.text(), manager = self.upro, ) - - + + ## Pro or Basic cannot create planned sessions or team planned sessions def test_pro_create_plannedsession(self): with self.assertRaises(ValidationError): @@ -419,7 +419,7 @@ class PermissionsBasicsTests(TestCase): name = faker.word(), comment = faker.text() ) - + def test_basic_create_plannedsession(self): with self.assertRaises(ValidationError): ps = PlannedSession.objects.create( @@ -427,7 +427,7 @@ class PermissionsBasicsTests(TestCase): name = faker.word(), comment = faker.text() ) - + ## Basic cannot join groups led by Pro or Self Coach def test_add_basic_pro_or_plan(self): with transaction.atomic(): @@ -437,7 +437,7 @@ class PermissionsBasicsTests(TestCase): with transaction.atomic(): with self.assertRaises(ValidationError): self.rbasic.team.add(self.teampro) - + ## Basic cannot manage a group def test_basic_groupmanager(self): @@ -461,7 +461,7 @@ class PermissionsViewTests(TestCase): self.ucoach = UserFactory(username='coachuser') self.rcoach = Rower.objects.create(user=self.ucoach, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='coach',clubsize=10) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) @@ -472,11 +472,11 @@ class PermissionsViewTests(TestCase): self.ucoachpassword = faker.word() self.ucoach.set_password(self.ucoachpassword) self.ucoach.save() - + self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) @@ -484,11 +484,11 @@ class PermissionsViewTests(TestCase): self.uplanpassword = faker.word() self.uplan.set_password(self.uplanpassword) self.uplan.save() - + self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) @@ -500,7 +500,7 @@ class PermissionsViewTests(TestCase): self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) @@ -508,11 +508,11 @@ class PermissionsViewTests(TestCase): self.uplan2password = faker.word() self.uplan2.set_password(self.uplan2password) self.uplan2.save() - + self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) @@ -524,7 +524,7 @@ class PermissionsViewTests(TestCase): self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) @@ -532,9 +532,9 @@ class PermissionsViewTests(TestCase): self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() - - - + + + ## TeamPro, TeamCoach, TeamSelfCoach self.teampro = Team.objects.create( @@ -557,7 +557,7 @@ class PermissionsViewTests(TestCase): def test_coach_groups_create(self): login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword) self.assertTrue(login) - + url = reverse('team_create_view') response = self.c.get(url) @@ -574,7 +574,7 @@ class PermissionsViewTests(TestCase): form = TeamForm(form_data) if not form.is_valid(): print(form.errors) - + self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') @@ -596,7 +596,7 @@ class PermissionsViewTests(TestCase): form = TeamForm(form_data) if not form.is_valid(): print(form.errors) - + self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') @@ -605,7 +605,7 @@ class PermissionsViewTests(TestCase): self.assertRedirects(response, expected_url=expected_url, status_code=302,target_status_code=200) - + ## Basic athletes can be member of Coach led group ## Coach can create planned sessions and team planned sessions @@ -682,7 +682,7 @@ class PermissionsViewTests(TestCase): 'theuser':self.ubasic.id, } ) - + response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -700,7 +700,7 @@ class PermissionsViewTests(TestCase): 'theuser':self.ubasic.id, } ) - + response = self.c.get(url) self.assertEqual(response.status_code,403) @@ -747,11 +747,11 @@ class PermissionsViewTests(TestCase): self.assertRedirects(response, expected_url = url, status_code=302,target_status_code=200) - + aantal2 = len(Workout.objects.filter(user=self.rbasic)) self.assertEqual(aantal2,aantal+1) - + ## Coach can upload on behalf of athlete - if team allows @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) @@ -791,11 +791,11 @@ class PermissionsViewTests(TestCase): self.assertRedirects(response, expected_url = url, status_code=302,target_status_code=200) - + aantal2 = len(Workout.objects.filter(user=self.rbasic)) self.assertEqual(aantal2,aantal) - + ## Coach can edit athlete's workout def test_coach_edit_athlete_workout(self): self.rbasic.team.add(self.teamcoach) @@ -809,13 +809,13 @@ class PermissionsViewTests(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,403) - + ## Self coach can create one group ## Self coach cannot create more than one group def test_plan_groups_create(self): login = self.c.login(username=self.uplan.username, password=self.uplanpassword) self.assertTrue(login) - + url = reverse('team_create_view') response = self.c.get(url) @@ -832,7 +832,7 @@ class PermissionsViewTests(TestCase): form = TeamForm(form_data) if not form.is_valid(): print(form.errors) - + self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') @@ -854,7 +854,7 @@ class PermissionsViewTests(TestCase): form = TeamForm(form_data) if not form.is_valid(): print(form.errors) - + self.assertTrue(form.is_valid()) expected_url = reverse('paidplans') @@ -927,7 +927,7 @@ class PermissionsViewTests(TestCase): 'theuser':self.ubasic.id, } ) - + response = self.c.get(url) self.assertEqual(response.status_code,403) @@ -952,7 +952,7 @@ class PermissionsViewTests(TestCase): def test_pro_groups_create(self): login = self.c.login(username=self.upro.username, password=self.upropassword) self.assertTrue(login) - + url = reverse('team_create_view') response = self.c.get(url) @@ -969,7 +969,7 @@ class PermissionsViewTests(TestCase): form = TeamForm(form_data) if not form.is_valid(): print(form.errors) - + self.assertTrue(form.is_valid()) expected_url = reverse('rower_teams_view') @@ -991,7 +991,7 @@ class PermissionsViewTests(TestCase): form = TeamForm(form_data) if not form.is_valid(): print(form.errors) - + self.assertTrue(form.is_valid()) expected_url = reverse('paidplans') @@ -1049,7 +1049,7 @@ class PermissionsViewTests(TestCase): 'theuser':self.ubasic.id, } ) - + response = self.c.get(url) self.assertEqual(response.status_code,403) @@ -1095,7 +1095,7 @@ class PermissionsViewTests(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + ## Self Coach users can see team members' workout, but not edit def test_plan_edit_athlete_workout(self): @@ -1117,7 +1117,7 @@ class PermissionsViewTests(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + ## Basic users can see team members' workout, but not edit def test_basic_edit_athlete_workout(self): @@ -1148,7 +1148,7 @@ class PermissionsViewTests(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + # workflow url = reverse('workout_workflow_view', kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)} @@ -1165,7 +1165,7 @@ class PermissionsViewTests(TestCase): response = self.c.get(url) self.assertEqual(response.status_code,200) - + ## Pro users (and higher) can join group led by other Pro (or higher) user def test_team_member_request_pro_pro(self): login = self.c.login(username=self.upro.username,password=self.upropassword) @@ -1215,7 +1215,7 @@ class PermissionsCoachingTests(TestCase): self.ucoach = UserFactory(username='coachuser') self.rcoach = Rower.objects.create(user=self.ucoach, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='coach',clubsize=10) self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach) @@ -1226,11 +1226,11 @@ class PermissionsCoachingTests(TestCase): self.ucoachpassword = faker.word() self.ucoach.set_password(self.ucoachpassword) self.ucoach.save() - + self.uplan = UserFactory(username='planuser') self.rplan = Rower.objects.create(user=self.uplan, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan_workouts = WorkoutFactory.create_batch(5, user=self.rplan) @@ -1238,11 +1238,11 @@ class PermissionsCoachingTests(TestCase): self.password = faker.word() self.uplan.set_password(self.password) self.uplan.save() - + self.upro = UserFactory(username='prouser') self.rpro = Rower.objects.create(user=self.upro, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro_workouts = WorkoutFactory.create_batch(5, user=self.rpro) @@ -1254,7 +1254,7 @@ class PermissionsCoachingTests(TestCase): self.uplan2 = UserFactory(username='planuser2') self.rplan2 = Rower.objects.create(user=self.uplan2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='plan') self.uplan2_workouts = WorkoutFactory.create_batch(5, user=self.rplan2) @@ -1262,11 +1262,11 @@ class PermissionsCoachingTests(TestCase): self.password = faker.word() self.uplan2.set_password(self.password) self.uplan2.save() - + self.upro2 = UserFactory(username='prouser2') self.rpro2 = Rower.objects.create(user=self.upro2, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='pro') self.upro2_workouts = WorkoutFactory.create_batch(5, user=self.rpro2) @@ -1278,7 +1278,7 @@ class PermissionsCoachingTests(TestCase): self.ubasic = UserFactory(username='basicuser') self.rbasic = Rower.objects.create(user=self.ubasic, birthdate=faker.profile()['birthdate'], - gdproptin=True,gdproptindate=timezone.now(), + gdproptin=True,surveydone=True,gdproptindate=timezone.now(), rowerplan='basic') self.ubasic_workouts = WorkoutFactory.create_batch(5, user=self.rbasic) @@ -1286,9 +1286,9 @@ class PermissionsCoachingTests(TestCase): self.ubasicpassword = faker.word() self.ubasic.set_password(self.ubasicpassword) self.ubasic.save() - - - + + + ## TeamPro, TeamCoach, TeamSelfCoach self.teampro = Team.objects.create( @@ -1360,7 +1360,7 @@ class PermissionsCoachingTests(TestCase): coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) - + def test_athlete_request_coach_reject(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) @@ -1421,7 +1421,7 @@ class PermissionsCoachingTests(TestCase): coachingrequests = CoachOffer.objects.filter(user=self.ubasic) self.assertEqual(len(coachingrequests),0) - + def test_athlete_request_coach_accept_coach_drop(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) self.assertTrue(login) @@ -1512,7 +1512,7 @@ class PermissionsCoachingTests(TestCase): coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) - + def test_coach_offer_athlete_accept_coach_drop(self): login = self.c.login(username=self.ucoach.username,password=self.ucoachpassword) self.assertTrue(login) @@ -1558,7 +1558,7 @@ class PermissionsCoachingTests(TestCase): coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) - + def test_athlete_request_coach_accept_athlete_drop(self): login = self.c.login(username=self.ubasic.username,password=self.ubasicpassword) @@ -1611,7 +1611,7 @@ class PermissionsCoachingTests(TestCase): coaches = teams.rower_get_coaches(self.rbasic) self.assertEqual(len(coaches),0) - + # coach related ## coach disappears from list when downgrading diff --git a/rowers/tests/test_plans.py b/rowers/tests/test_plans.py index d69a3dc9..613478da 100644 --- a/rowers/tests/test_plans.py +++ b/rowers/tests/test_plans.py @@ -17,7 +17,7 @@ class TrainingPlanTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -175,7 +175,7 @@ class SessionLinkTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -348,7 +348,7 @@ class SessionCompleteTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -603,7 +603,7 @@ class ChallengeCompleteTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -827,7 +827,7 @@ class MandatoryTestCompleteTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -1040,7 +1040,7 @@ class PlannedSessionsView(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') self.r.save() @@ -1049,7 +1049,7 @@ class PlannedSessionsView(TestCase): self.u2 = UserFactory(username='testbasicuser') self.r2 = Rower.objects.create(user=self.u2, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='basic') diff --git a/rowers/tests/test_rowerplans.py b/rowers/tests/test_rowerplans.py index 6aeea434..d87f1a56 100644 --- a/rowers/tests/test_rowerplans.py +++ b/rowers/tests/test_rowerplans.py @@ -11,10 +11,10 @@ from rowers.views import hasplannedsessions,iscoachmember,ispromember class TrialsTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='basic') @@ -46,7 +46,7 @@ class TrialsTest(TestCase): self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date() self.r.save() - + self.assertEqual(hasplannedsessions(self.u),True) self.assertEqual(iscoachmember(self.u),False) self.assertEqual(ispromember(self.u),True) @@ -60,10 +60,7 @@ class TrialsTest(TestCase): self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date() self.r.save() - + self.assertEqual(hasplannedsessions(self.u),True) self.assertEqual(iscoachmember(self.u),False) self.assertEqual(ispromember(self.u),True) - - - diff --git a/rowers/tests/test_settings.py b/rowers/tests/test_settings.py index 3dbe555b..b9a44653 100644 --- a/rowers/tests/test_settings.py +++ b/rowers/tests/test_settings.py @@ -7,14 +7,14 @@ from __future__ import unicode_literals from .statements import * -#@pytest.mark.django_db +#@pytest.mark.django_db class DataTest(TestCase): def setUp(self): redis_connection.publish('tasks','KILL') u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - r = Rower.objects.create(user=u,gdproptin=True, + r = Rower.objects.create(user=u,gdproptin=True,surveydone=True, gdproptindate=timezone.now() ) self.nu = datetime.datetime.now() diff --git a/rowers/tests/test_simplefunctions.py b/rowers/tests/test_simplefunctions.py index fcc8743d..904fb01f 100644 --- a/rowers/tests/test_simplefunctions.py +++ b/rowers/tests/test_simplefunctions.py @@ -36,7 +36,7 @@ class SimpleViewTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') diff --git a/rowers/tests/test_staticcharts.py b/rowers/tests/test_staticcharts.py index db0b4235..cd7bc7ed 100644 --- a/rowers/tests/test_staticcharts.py +++ b/rowers/tests/test_staticcharts.py @@ -9,7 +9,7 @@ nu = datetime.datetime.now() -#@pytest.mark.django_db +#@pytest.mark.django_db @override_settings(TESTING=True) class PlotTests(TestCase): def setUp(self): @@ -18,7 +18,7 @@ class PlotTests(TestCase): 'sander@ds.ds', 'koeinsloot') r = Rower.objects.create(user=u, - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='basic') self.nu = datetime.datetime.now() @@ -29,14 +29,14 @@ class PlotTests(TestCase): starttime=self.nu.strftime('%H:%M:%S'), duration="0:55:00",distance=8000, csvfilename=filename) - + self.wote = Workout.objects.create(name='testworkout', workouttype='Indoor Rower', user=r,date=self.nu.strftime('%Y-%m-%d'), starttime=self.nu.strftime('%H:%M:%S'), duration="0:55:00",distance=8000, csvfilename=filename) - + # timestr = strftime("%Y%m%d-%H%M%S") # imagename = f1+timestr+'.png' # fullpathimagename = 'static/plots/'+imagename @@ -45,7 +45,7 @@ class PlotTests(TestCase): r.pw_at, r.pw_tr,r.pw_an])/r.ftp - + self.hrdata = { 'hrmax':r.max, 'hrut2':r.ut2, @@ -64,7 +64,7 @@ class PlotTests(TestCase): @patch('rowers.tasks.FigureCanvas') def test_ote_plots(self, mocked_rowingdata, mocked_canvas): w = self.wote - f1 = 'testdata.csv'[:-4] + f1 = 'testdata.csv'[:-4] timestr = strftime("%Y%m%d-%H%M%S") imagename = f1+timestr+'.png' fullpathimagename = 'static/plots/'+imagename @@ -72,7 +72,7 @@ class PlotTests(TestCase): plotnr = 1 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -85,7 +85,7 @@ class PlotTests(TestCase): plotnr = 1 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -98,7 +98,7 @@ class PlotTests(TestCase): plotnr = 2 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -111,7 +111,7 @@ class PlotTests(TestCase): plotnr = 3 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -124,7 +124,7 @@ class PlotTests(TestCase): plotnr = 4 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -137,7 +137,7 @@ class PlotTests(TestCase): plotnr = 5 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -150,7 +150,7 @@ class PlotTests(TestCase): plotnr = 6 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -163,7 +163,7 @@ class PlotTests(TestCase): plotnr = 7 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -176,7 +176,7 @@ class PlotTests(TestCase): plotnr = 8 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -189,7 +189,7 @@ class PlotTests(TestCase): plotnr = 13 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -203,7 +203,7 @@ class PlotTests(TestCase): @patch('rowers.tasks.FigureCanvas') def test_chartrequests(self, mocked_rowingdata, mocked_canvas): opid = encoder.encode_hex(self.wotw.id) - + url = reverse('workout_add_chart_view', kwargs={'id':opid, 'plotnr':13 @@ -212,7 +212,7 @@ class PlotTests(TestCase): workout_edit_url = reverse('workout_edit_view', kwargs={'id':opid}) - + login = self.c.login(username='john', password='koeinsloot') self.assertTrue(login) @@ -246,12 +246,12 @@ class PlotTests(TestCase): self.assertEqual(len(i),0) - + @patch('rowers.tasks.rdata') @patch('rowers.tasks.FigureCanvas') def test_otw_plots(self, mocked_rowingdata, mocked_canvas): w = self.wotw - f1 = 'testdata.csv'[:-4] + f1 = 'testdata.csv'[:-4] timestr = strftime("%Y%m%d-%H%M%S") imagename = f1+timestr+'.png' fullpathimagename = 'static/plots/'+imagename @@ -259,7 +259,7 @@ class PlotTests(TestCase): plotnr = 1 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -272,7 +272,7 @@ class PlotTests(TestCase): plotnr = 1 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -285,7 +285,7 @@ class PlotTests(TestCase): plotnr = 2 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -298,7 +298,7 @@ class PlotTests(TestCase): plotnr = 3 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -311,7 +311,7 @@ class PlotTests(TestCase): plotnr = 4 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -324,7 +324,7 @@ class PlotTests(TestCase): plotnr = 5 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -337,7 +337,7 @@ class PlotTests(TestCase): plotnr = 6 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -350,7 +350,7 @@ class PlotTests(TestCase): plotnr = 7 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -363,7 +363,7 @@ class PlotTests(TestCase): plotnr = 8 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -376,7 +376,7 @@ class PlotTests(TestCase): plotnr = 9 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, @@ -389,7 +389,7 @@ class PlotTests(TestCase): plotnr = 13 if (w.workouttype=='water'): plotnr = plotnr+3 - + res = handle_makeplot(f1,w.csvfilename, w.name,self.hrdata,plotnr,imagename) i = GraphImage(workout=w,creationdatetime=self.nu, diff --git a/rowers/tests/test_team.py b/rowers/tests/test_team.py index 99119a2c..05d16b5a 100644 --- a/rowers/tests/test_team.py +++ b/rowers/tests/test_team.py @@ -38,10 +38,10 @@ class TeamTest(TestCase): for i in range(6): u = UserFactory(username=usernames[i]) self.users.append(u) - + r = Rower.objects.create( birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', user=u, @@ -53,7 +53,7 @@ class TeamTest(TestCase): u.set_password(password) u.save() self.user_passwords.append(password) - + workouts = WorkoutFactory.create_batch(5, user=r) for w in workouts: @@ -64,7 +64,7 @@ class TeamTest(TestCase): self.u = self.users[0] self.password = self.user_passwords[0] - + self.t = TeamFactory(manager=self.u) # need to set up some requests for testing (they are not good below) @@ -105,7 +105,7 @@ class TeamTest(TestCase): self.assertRedirects(response, expected_url='/rowers/me/teams/'.format(t=self.t.id), status_code=302,target_status_code=200) - + def test_teamview(self): login = self.c.login(username=self.u.username, password = self.password) self.assertTrue(login) @@ -113,9 +113,9 @@ class TeamTest(TestCase): url = '/rowers/team/{t}/'.format(t=self.t.id) response = self.c.get(url) self.assertEqual(response.status_code, 200) - + def test_teamview_member(self): - + id,comment = add_member(self.t.id,self.users[1].rower) self.assertEqual(id,self.t.id) @@ -132,7 +132,7 @@ class TeamTest(TestCase): login = self.c.login(username=self.users[2].username, password = self.user_passwords[2]) self.assertTrue(login) - + response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) @@ -147,11 +147,11 @@ class TeamTest(TestCase): print(u) print(response.status_code) self.assertIn(response.status_code,[200,302]) - + login = self.c.login(username=self.users[1].username, password = self.user_passwords[1]) self.assertTrue(login) - + response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) @@ -166,14 +166,14 @@ class TeamTest(TestCase): print(u) print(response.status_code) self.assertIn(response.status_code,[200,302]) - + def test_teamsview_manager(self): url = '/rowers/me/teams/' login = self.c.login(username=self.u,password=self.password) self.assertTrue(login) - + response = self.c.get(url,follow=True) self.assertEqual(response.status_code,200) @@ -190,14 +190,14 @@ class TeamTest(TestCase): self.assertIn(response.status_code,[200,302]) def test_teamview_member_request(self): - + login = self.c.login(username=self.users[3].username, password = self.user_passwords[3]) self.assertTrue(login) url = '/rowers/team/{t}/requestmembership/{u}/'.format( t=self.t.id, u=self.users[3].id) - + response = self.c.get(url,follow=True) self.assertEqual(response.status_code, 200) @@ -226,8 +226,8 @@ class TeamTest(TestCase): self.assertRedirects(response, expected_url='/rowers/me/teams/', status_code=302,target_status_code=200) - - + + def test_team_invite_view(self): login = self.c.login(username=self.u.username, password = self.password) self.assertTrue(login) @@ -238,11 +238,11 @@ class TeamTest(TestCase): 'email': self.users[1].email, 'user': u'' } - + response = self.c.post(url, form_data) self.assertEqual(response.status_code, 200) - -@override_settings(TESTING=True) + +@override_settings(TESTING=True) class TeamTestLowLevel(TestCase): def setUp(self): redis_connection.publish('tasks','KILL') @@ -261,10 +261,10 @@ class TeamTestLowLevel(TestCase): for i in range(6): u = UserFactory(username=usernames[i]) self.users.append(u) - + r = Rower.objects.create( birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', user=u, @@ -276,7 +276,7 @@ class TeamTestLowLevel(TestCase): u.set_password(password) u.save() self.user_passwords.append(password) - + workouts = WorkoutFactory.create_batch(5, user=r) for w in workouts: @@ -287,7 +287,7 @@ class TeamTestLowLevel(TestCase): self.u = self.users[0] self.password = self.user_passwords[0] - + self.t = TeamFactory(manager=self.u) @@ -353,5 +353,3 @@ class TeamTestLowLevel(TestCase): # cannot create invite for team you don't manage id, comment = create_invite(self.t, self.users[3],self.users[4]) self.assertEqual(id,0) - - diff --git a/rowers/tests/test_units.py b/rowers/tests/test_units.py index 7546603a..95f76243 100644 --- a/rowers/tests/test_units.py +++ b/rowers/tests/test_units.py @@ -26,7 +26,7 @@ class ForceUnits(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') @@ -164,7 +164,7 @@ class TestForceUnit(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, + gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach') diff --git a/rowers/tests/test_uploads.py b/rowers/tests/test_uploads.py index aa2ea98c..22f9a4e5 100644 --- a/rowers/tests/test_uploads.py +++ b/rowers/tests/test_uploads.py @@ -9,7 +9,7 @@ nu = datetime.datetime.now() from rowers.views import add_defaultfavorites -#@pytest.mark.django_db +#@pytest.mark.django_db @override_settings(TESTING=True) class ViewTest(TestCase): def setUp(self): @@ -18,13 +18,13 @@ class ViewTest(TestCase): self.u = User.objects.create_user('john', 'sander@ds.ds', 'koeinsloot') - self.r = Rower.objects.create(user=self.u,gdproptin=True, + self.r = Rower.objects.create(user=self.u,gdproptin=True,surveydone=True, gdproptindate=timezone.now(), rowerplan='coach', ) add_defaultfavorites(self.r) - + self.nu = datetime.datetime.now() def test_upload_view_notloggedin(self): @@ -35,13 +35,13 @@ class ViewTest(TestCase): status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db) def test_upload_view_sled(self, mocked_sqlalchemy,mocked_getsmallrowdata_db): login = self.c.login(username='john',password='koeinsloot') self.assertTrue(login) - + filename = 'rowers/tests/testdata/testdata.csv' f = open(filename,'rb') file_data = {'file': f} @@ -70,7 +70,7 @@ class ViewTest(TestCase): response = self.c.get('/rowers/workout/'+encoded1+'/edit/', form_data, follow=True) self.assertEqual(response.status_code, 200) - + response = self.c.get('/rowers/workout/'+encoded1+'/histo/', form_data, follow=True) self.assertEqual(response.status_code, 200) @@ -108,7 +108,7 @@ class ViewTest(TestCase): self.assertTrue(form.is_valid()) response = self.c.post('/rowers/workout/'+encoded1+'/edit/', form_data, follow=True) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename @@ -128,11 +128,11 @@ class ViewTest(TestCase): status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + @patch('rowers.dataprep.create_engine') def test_upload_view_sled_negativetime(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/tim.csv' f = open(filename,'rb') file_data = {'file': f} @@ -157,7 +157,7 @@ class ViewTest(TestCase): response = self.c.post('/rowers/workout/upload/', form_data, follow=True) - + self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) @@ -165,9 +165,9 @@ class ViewTest(TestCase): response = self.c.get('/rowers/workout/'+encoded1+'/', form_data, follow=True) self.assertEqual(response.status_code, 200) - + f.close() - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -175,12 +175,12 @@ class ViewTest(TestCase): except (FileNotFoundError,OSError): pass - - + + @patch('rowers.dataprep.create_engine') def test_upload_view_sled_noname(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/testdata.csv' f = open(filename,'rb') file_data = {'file': f} @@ -216,7 +216,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_logcard(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/logcard.csv' f = open(filename,'rb') file_data = {'file': f} @@ -245,12 +245,12 @@ class ViewTest(TestCase): - + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.TCXParser') def test_upload_view_TCX_CN(self, mocked_sqlalchemy, mocked_tcx_parser): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/crewnerddata.tcx' f = open(filename,'rb') file_data = {'file': f} @@ -300,7 +300,7 @@ class ViewTest(TestCase): def test_upload_view_TCX_SpeedCoach2a(self, mocked_sqlalchemy, mocked_tcx_parser): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/Speedcoach2example.csv' f = open(filename,'rb') file_data = {'file': f} @@ -337,7 +337,7 @@ class ViewTest(TestCase): def test_upload_view_TCX_SpeedCoach2b(self, mocked_sqlalchemy, mocked_tcx_parser): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/Speedcoach2example.csv' f = open(filename,'rb') file_data = {'file': f} @@ -371,12 +371,12 @@ class ViewTest(TestCase): - @patch('rowers.dataprep.create_engine') + @patch('rowers.dataprep.create_engine') @patch('rowers.dataprep.TCXParser') def test_upload_view_TCX_SpeedCoach2c(self, mocked_sqlalchemy, mocked_tcx_parser): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/speedcoach3test3.csv' f = open(filename,'rb') file_data = {'file': f} @@ -412,7 +412,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_SpeedCoach2v127(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/SpeedCoach2Linkv1.27.csv' f = open(filename,'rb') file_data = {'file': f} @@ -449,7 +449,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_SpeedCoach2v127intervals(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/SpeedCoach2Link_interval.csv' f = open(filename,'rb') file_data = {'file': f} @@ -488,7 +488,7 @@ class ViewTest(TestCase): def test_upload_view_TCX_NoHR(self, mocked_sqlalchemy, mocked_tcx_parser): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/NoHR.tcx' f = open(filename,'rb') file_data = {'file': f} @@ -526,7 +526,7 @@ class ViewTest(TestCase): def test_upload_view_TCX_CN(self, mocked_sqlalchemy, mocked_tcx_parser): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/rowinginmotionexample.tcx' f = open(filename,'rb') file_data = {'file': f} @@ -559,7 +559,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_RP(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/RP_testdata.csv' f = open(filename,'rb') file_data = {'file': f} @@ -580,7 +580,7 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -592,7 +592,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_Mystery(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/mystery.csv' f = open(filename,'rb') file_data = {'file': f} @@ -613,7 +613,7 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -625,7 +625,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_RP_interval(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/RP_interval.csv' f = open(filename,'rb') file_data = {'file': f} @@ -646,7 +646,7 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -655,11 +655,11 @@ class ViewTest(TestCase): pass - + @patch('rowers.dataprep.create_engine') def test_upload_view_sled_desktop(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/painsled_desktop_example.csv' f = open(filename,'rb') file_data = {'file': f} @@ -680,7 +680,7 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -691,7 +691,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_sled_ergdata(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/ergdata_example.csv' f = open(filename,'rb') file_data = {'file': f} @@ -712,7 +712,7 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -723,7 +723,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_sled_boatcoach(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/boatcoach.csv' f = open(filename,'rb') file_data = {'file': f} @@ -744,7 +744,7 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: @@ -755,7 +755,7 @@ class ViewTest(TestCase): @patch('rowers.dataprep.create_engine') def test_upload_view_sled_ergstick(self, mocked_sqlalchemy): self.c.login(username='john',password='koeinsloot') - + filename = 'rowers/tests/testdata/ergstick.csv' f = open(filename,'rb') file_data = {'file': f} @@ -776,11 +776,10 @@ class ViewTest(TestCase): self.assertRedirects(response, expected_url='/rowers/workout/'+encoded1+'/edit/', status_code=302,target_status_code=200) self.assertEqual(response.status_code, 200) - + w = Workout.objects.get(id=1) f_to_be_deleted = w.csvfilename try: os.remove(f_to_be_deleted+'.gz') except (FileNotFoundError,OSError): pass - diff --git a/rowers/tests/test_user.py b/rowers/tests/test_user.py index 65dd006c..f5271bfb 100644 --- a/rowers/tests/test_user.py +++ b/rowers/tests/test_user.py @@ -18,13 +18,13 @@ class UserMiddleWareTest(TestCase): 'sander@ds.ds', 'koeinsloot') self.r = Rower.objects.create(user=u) - + self.c = Client() self.c.login(username='john',password='koeinsloot') self.nu = datetime.datetime.now() filename = 'rowers/tests/testdata/testdata.csv' - + rr = rrower(hrmax=self.r.max,hrut2=self.r.ut2, hrut1=self.r.ut1,hrat=self.r.at, hrtr=self.r.tr,hran=self.r.an,ftp=self.r.ftp) @@ -33,7 +33,7 @@ class UserMiddleWareTest(TestCase): totaltime = row.df['TimeStamp (sec)'].max()-row.df['TimeStamp (sec)'].min() totaltime = totaltime+row.df.loc[:,' ElapsedTime (sec)'].iloc[0] - + hours = int(totaltime/3600.) minutes = int((totaltime - 3600.*hours)/60.) seconds = int(totaltime - 3600.*hours - 60.*minutes) @@ -53,13 +53,13 @@ class UserMiddleWareTest(TestCase): duration=duration,distance=totaldist, csvfilename=filename ) - - + + def test_middleware(self): response = self.c.get('/rowers/list-workouts',follow=True) self.assertEqual(response.status_code,200) - - + + class UserTestsNoRower(TestCase): def setUp(self): u = User.objects.create_user('john', @@ -69,19 +69,19 @@ class UserTestsNoRower(TestCase): self.c = Client() self.c.login(username='john',password='koeinsloot') - + def test_user(self): response = self.c.get('/rowers/list-workouts',follow=True) self.assertEqual(response.status_code,200) - + class UserPreferencesTest(TestCase): def setUp(self): self.u = UserFactory() - + self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True, - gdproptindate=timezone.now(), + gdproptin=True,surveydone=Trueoptin=True, + gdproptin=True,surveydone=Trueoptindate=timezone.now(), rowerplan='coach') self.c = Client() @@ -123,14 +123,14 @@ class UserPreferencesTest(TestCase): userform = UserForm(form_data,instance=self.u) self.assertTrue(form.is_valid()) self.assertTrue(userform.is_valid()) - + response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) response = self.c.get(url) self.assertEqual(response.status_code,200) - - + + def test_exportsettings(self): login = self.c.login(username=self.u.username,password=self.password) self.assertTrue(login) @@ -149,15 +149,15 @@ class UserPreferencesTest(TestCase): 'sporttracks_auto_export':False, 'strava_auto_export':False, 'strava_auto_import':False, - 'trainingpeaks_auto_export':False, + 'trainingpeaks_auto_export':False, } form = RowerExportForm(form_data) self.assertTrue(form.is_valid()) - + response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - + def test_zones_workflowsettings(self): login = self.c.login(username=self.u.username,password=self.password) @@ -174,7 +174,7 @@ class UserPreferencesTest(TestCase): u'middlepanel-7-panel':u'None', u'middlepanel-8-panel':u'None', u'middlepanel-INITIAL_FORMS':'8', - u'middlepanel-MAX_NUM_FORMS':u'1000', + u'middlepanel-MAX_NUM_FORMS':u'1000', u'middlepanel-MIN_NUM_FORMS':u'0', u'middlepanel-TOTAL_FORMS':u'8', } @@ -182,7 +182,7 @@ class UserPreferencesTest(TestCase): MiddlePanelFormSet = formset_factory(WorkFlowMiddlePanelElement,extra=1) middlepanel_formset = MiddlePanelFormSet(post_data,prefix='middlepanel') self.assertTrue(middlepanel_formset.is_valid()) - + url = '/rowers/me/workflowconfig2/' response = self.c.get(url) @@ -190,7 +190,7 @@ class UserPreferencesTest(TestCase): response = self.c.post(url,post_data) self.assertEqual(response.status_code,200) - + def test_zones_preferences(self): login = self.c.login(username=self.u.username,password=self.password) self.assertTrue(login) @@ -209,7 +209,7 @@ class UserPreferencesTest(TestCase): self.assertTrue(form.is_valid()) url = '/rowers/me/preferences/' - + response = self.c.get(url) self.assertEqual(response.status_code,200) @@ -228,7 +228,7 @@ class UserPreferencesTest(TestCase): response = self.c.post(url,form_data,follow=True) self.assertEqual(response.status_code,200) - + form_data = { 'pw_ut2':150, 'pw_ut1':160, @@ -245,5 +245,3 @@ class UserPreferencesTest(TestCase): response = self.c.post(url,form_data) self.assertEqual(response.status_code,200) - - diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index 8814688e..c1120f33 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -97,8 +97,8 @@ MIDDLEWARE = [ 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'tz_detect.middleware.TimezoneMiddleware', - 'rowers.middleware.GDPRMiddleWare', 'rowers.middleware.SurveyMiddleWare', + 'rowers.middleware.GDPRMiddleWare', 'rowers.middleware.PowerTimeFitnessMetricMiddleWare', 'rowers.middleware.RowerPlanMiddleWare', ] From 6c827bef965e1adb4832a643553aa90a4fcc32a2 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 9 Jan 2020 10:53:06 +0100 Subject: [PATCH 55/57] 14 days no survey for new users --- rowers/middleware.py | 4 +-- rowers/tests/test_newusers.py | 2 +- rowers/tests/testdata/course.kml | 57 ++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 rowers/tests/testdata/course.kml diff --git a/rowers/middleware.py b/rowers/middleware.py index 03a7cb2c..42087eeb 100644 --- a/rowers/middleware.py +++ b/rowers/middleware.py @@ -1,4 +1,3 @@ - from django.utils import timezone from rowers.models import Workout, PowerTimeFitnessMetric, Rower, PaidPlan import datetime @@ -111,7 +110,8 @@ class SurveyMiddleWare(object): nexturl = request.path if 'survey' in nexturl: nexturl = '/rowers/list-workouts' - if not r.surveydone: + mustseesurvey = request.user.date_joined <= timezone.now()-datetime.timedelta(days=14) and not r.surveydone + if mustseesurvey: return redirect( '/rowers/survey/?next=%s' % nexturl ) diff --git a/rowers/tests/test_newusers.py b/rowers/tests/test_newusers.py index 29f93712..bdfae610 100644 --- a/rowers/tests/test_newusers.py +++ b/rowers/tests/test_newusers.py @@ -44,7 +44,7 @@ class NewUserRegistrationTest(TestCase): response = self.c.post('/rowers/register/', form_data, follow=True) self.assertRedirects(response, - expected_url='/rowers/survey/?next=/rowers/list-workouts/', + expected_url='/rowers/me/gdpr-optin/?next=/rowers/list-workouts/', status_code=302,target_status_code=200) diff --git a/rowers/tests/testdata/course.kml b/rowers/tests/testdata/course.kml new file mode 100644 index 00000000..56451bb7 --- /dev/null +++ b/rowers/tests/testdata/course.kml @@ -0,0 +1,57 @@ + + + + Courses.kml + + Courses + + CrewNerd Examples - Uherské Hradiště + 1 + + Start + + 1 + + + 17.4893745389,49.109471228,0 17.4911067423,49.1094811918,0 17.4909527884,49.1103411557,0 17.4888918133,49.1102899098,0 17.4893745389,49.109471228,0 17.4893745389,49.109471228,0 + + + + + + Turn + + 1 + + + 17.4836181002,49.0979347215,0 17.489332427,49.0981702202,0 17.4888058511,49.1024117428,0 17.4836162032,49.1030885423,0 17.4836181002,49.0979347215,0 17.4836181002,49.0979347215,0 + + + + + + Turn + + 1 + + + 17.4928830266,49.0866607478,0 17.4973472737,49.0861776065,0 17.4994059869,49.0903340046,0 17.4942740099,49.0899098202,0 17.4928830266,49.0866607478,0 17.4928830266,49.0866607478,0 + + + + + + Finish + + 1 + + + 17.4627698339,49.0723911762,0 17.4630054316,49.071305244,0 17.4643666779,49.0712945663,0 17.4641649495,49.0724875988,0 17.4627698339,49.0723911762,0 17.4627698339,49.0723911762,0 + + + + + + + + From 782c9b089dbcf7f680dcef8fc14c3bb79ce1d9f8 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 9 Jan 2020 13:10:01 +0100 Subject: [PATCH 56/57] passing all tests --- rowers/tests/test_user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rowers/tests/test_user.py b/rowers/tests/test_user.py index f5271bfb..92cff5e1 100644 --- a/rowers/tests/test_user.py +++ b/rowers/tests/test_user.py @@ -80,8 +80,8 @@ class UserPreferencesTest(TestCase): self.r = Rower.objects.create(user=self.u, birthdate=faker.profile()['birthdate'], - gdproptin=True,surveydone=Trueoptin=True, - gdproptin=True,surveydone=Trueoptindate=timezone.now(), + gdproptin=True,surveydone=True, + gdproptindate=timezone.now(), rowerplan='coach') self.c = Client() From 04f0ff578156289e3a9bba73c4452e886bbda5b2 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 10 Jan 2020 16:09:33 +0100 Subject: [PATCH 57/57] adding survey storage --- .gitignore | 1 + rowers/admin.py | 11 ++-- rowsandall_app/settings.py | 1 + rowsandall_app/urls.py | 2 + survey/__init__.py | 0 survey/admin.py | 21 +++++++ survey/apps.py | 4 ++ survey/models.py | 125 +++++++++++++++++++++++++++++++++++++ survey/urls.py | 10 +++ survey/views.py | 34 ++++++++++ 10 files changed, 204 insertions(+), 5 deletions(-) create mode 100644 survey/__init__.py create mode 100644 survey/admin.py create mode 100644 survey/apps.py create mode 100644 survey/models.py create mode 100644 survey/urls.py create mode 100644 survey/views.py diff --git a/.gitignore b/.gitignore index 0dc8c5c9..ad18f5a8 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ manage.py # migrations /rowers/migrations/ /cvkbrno/migrations/ +/survey/migrations/ # secrets config.yaml diff --git a/rowers/admin.py b/rowers/admin.py index cf091c81..26c6d660 100644 --- a/rowers/admin.py +++ b/rowers/admin.py @@ -17,7 +17,8 @@ from .models import ( # Register your models here so you can use them in the Admin module -# Rower details directly under the User + +# Rower details directly under the User class RowerInline(admin.StackedInline): model = Rower can_delete = False @@ -73,7 +74,7 @@ class UserAdmin(admin.ModelAdmin): ('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions',)}),) - + search_fields = ["username","first_name","last_name","email"] def rowerplan(self, obj): @@ -90,7 +91,7 @@ class FavoriteChartAdmin(admin.ModelAdmin): class C2WorldClassAgePerformanceAdmin(admin.ModelAdmin): list_display = ('sex','weightcategory','age','distance','power','name','season') - + class SiteAnnouncementAdmin(admin.ModelAdmin): list_display = ('announcement','created','modified','expires','dotweet') @@ -99,7 +100,7 @@ class TeamAdmin(admin.ModelAdmin): class TeamInviteAdmin(admin.ModelAdmin): list_display = ('issuedate','team','user','code') - + class TeamRequestAdmin(admin.ModelAdmin): list_display = ('issuedate','team','user','code') @@ -136,7 +137,7 @@ class IndoorVirtualRaceResultAdmin(admin.ModelAdmin): class PaidPlanAdmin(admin.ModelAdmin): list_display = ('name','shortname','price','paymenttype','paymentprocessor','external_id') - + admin.site.unregister(User) admin.site.register(User,UserAdmin) admin.site.register(Workout,WorkoutAdmin) diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index c1120f33..4ab15697 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -47,6 +47,7 @@ ALLOWED_HOSTS = CFG['allowed_hosts'] INSTALLED_APPS = [ 'rowers', + 'survey', # 'cvkbrno', 'django.contrib.admin', 'django.contrib.auth', diff --git a/rowsandall_app/urls.py b/rowsandall_app/urls.py index ec1b60df..b6bcca18 100644 --- a/rowsandall_app/urls.py +++ b/rowsandall_app/urls.py @@ -22,6 +22,7 @@ from django.views.generic import TemplateView from rowsandall_app.views import rootview, landingview from django.contrib.auth import views as auth_views from rowers import views as rowersviews +from survey import views as surveyviews import django @@ -65,6 +66,7 @@ urlpatterns += [ {'next_page': '/'}, name='logout',), re_path(r'^rowers/',include('rowers.urls')), + re_path(r'^survey/',include('survey.urls')), # re_path(r'^cvkbrno/',include('cvkbrno.urls')), # re_path(r'^admin/rq/',include('django_rq_dashboard.urls')), re_path(r'^call\_back',rowersviews.rower_process_callback), diff --git a/survey/__init__.py b/survey/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/survey/admin.py b/survey/admin.py new file mode 100644 index 00000000..29051dbc --- /dev/null +++ b/survey/admin.py @@ -0,0 +1,21 @@ +from .models import Response +from django.contrib import admin +from django.contrib.auth.admin import UserAdmin + +class ResponseInline(admin.StackedInline): + model = Response + fieldsets = ( + ('User Details',{'fields':('plan','username','email')}), + ('Used Features', + {'fields:': + ('logging','technical', + 'trend','planning','racing','coaching','export','video','interval')}), + ('Paid Plan Questions', + {'fields':('capabilities','fallshort','considered','features')}) + ) + +class ResponseAdmin(admin.ModelAdmin): + #inlines = (ResponseInline,) + list_display = ('plan','id','date','capabilities') + +admin.site.register(Response,ResponseAdmin) diff --git a/survey/apps.py b/survey/apps.py new file mode 100644 index 00000000..58263d6c --- /dev/null +++ b/survey/apps.py @@ -0,0 +1,4 @@ +from django.apps import AppConfig + +class SurveyConfig(AppConfig): + name = 'app' diff --git a/survey/models.py b/survey/models.py new file mode 100644 index 00000000..00284a9c --- /dev/null +++ b/survey/models.py @@ -0,0 +1,125 @@ +from django.contrib.auth.models import User +from django import forms +from django.forms import ModelForm + +from django.conf import settings +from django.db import models +from django.utils import timezone + +from rowers.database import * +import datetime + +def current_day(): + return (datetime.datetime.now(tz=timezone.utc)).date() + +class Response(models.Model): + planchoices = ( + ('basic','Free Athlete'), + ('freecoach','Free Coach'), + ('pro','Pro'), + ('plan','Self-Coach'), + ('coach','coach'), + ) + plan = models.CharField(max_length=150,choices=planchoices,default='basic') + username = models.CharField(max_length=150,unique=True,verbose_name='User Name',blank=True,null=True) + email = models.EmailField(max_length=150,verbose_name='User Email',blank=True,null=True) + date = models.DateField(default=current_day,verbose_name='survey date') + nrworkouts = models.IntegerField(default=0,verbose_name='nr of workouts per week') + nrworkoutsR = models.IntegerField(default=0,verbose_name='nr of workouts per week on Rowsandall') + + hearchoices = ( + ('wordofmouth','Word of mouth'), + ('socialmedia','Social Media (Facebook, Twitter)'), + ('otherinternet','Other internet'), + ('coach','From my Coach/Coachee'), + ('other','Other') + ) + + heard = models.CharField(max_length=150,blank=True,null=True, + default=None, + choices=hearchoices,verbose_name="How did you hear about Rowsandall") + + logging = models.BooleanField(default=False,verbose_name='Logging Workouts') + technial = models.BooleanField(default=False,verbose_name='Technical Analysis of workouts') + trend = models.BooleanField(default=False,verbose_name='Trend Analysis of workouts') + planning = models.BooleanField(default=False,verbose_name='Training planning') + racing = models.BooleanField(default=False,verbose_name='Online racing') + coaching = models.BooleanField(default=False,verbose_name='Coaching') + export = models.BooleanField(default=False,verbose_name='Exporting data to other sites') + video = models.BooleanField(default=False,verbose_name='Video Analysis') + interval = models.BooleanField(default=False,verbose_name='Interval editor') + + capabilities = models.NullBooleanField(default=None,null=True,blank=True, + verbose_name='Did you get the capabilities and features that you expected out of Rowsandall') + + fallshort = models.TextField(max_length=300,blank=True,verbose_name='Where did Rowsandall fall short of your expectations?') + + considerchoices = ( + ('no','No'), + ('pro','Yes: Pro'), + ('plan','Yes: Self-Coach'), + ('coach','Yes: Coach') + ) + + considered = models.CharField(max_length=150,choices=considerchoices,default=None,null=True,blank=True, + verbose_name='If you are on a Free plan, did you consider one of the paid plans?') + + features = models.TextField(max_length=300,blank=True, + verbose_name="What combination of features would entice you to upgrade to a paid plan") + + agreechoices = ( + ('completely_disagree','Completely Disagree'), + ('disagree','Disagree'), + ('neutral','Neither agree nor disagree'), + ('agree','Agree'), + ('completely_agree','Completely Agree'), + ) + + pricing = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="The pricing for plans is clear and understandable" + ) + + subscription = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like I get a good value for the price of the subscription" + ) + + advanced = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like the advanced features of Rowsandall are easy to use" + ) + + mobile = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="It is easy to use Rowsandall from a mobile device" + ) + + developer1 = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like the developer of Rowsandall is responsive to problems and resolves them quickly" + ) + + developer2 = models.CharField( + max_length=150,choices=agreechoices,default=None,null=True,blank=True, + verbose_name="I feel like the developer of Rowsandall is responsive to ideas for new features and capabilities" + ) + + sugchoices = ( + ('bug','Resolve a bug'), + ('newfeature','Add a new feature'), + ('improve','Improve the ease of use of the site'), + ('easy','Make the site easier to use on mobile devices'), + ('other','Other') + ) + + bug = models.BooleanField(default=False,verbose_name='Resolve a bug') + newfeature = models.BooleanField(default=False,verbose_name='Add a new feature') + improve = models.BooleanField(default=False,verbose_name='Improve the ease of use of the site') + easu = models.BooleanField(default=False,verbose_name='Make the site easier to use on mobile devices') + other = models.BooleanField(default=False,verbose_name='Other') + + suggestiontext = models.TextField( + max_length=300,default=None,null=True,blank=True, + verbose_name='My suggestion is (please write a short description of your suggestion)' + ) diff --git a/survey/urls.py b/survey/urls.py new file mode 100644 index 00000000..90cb2d20 --- /dev/null +++ b/survey/urls.py @@ -0,0 +1,10 @@ +from django.conf import settings +from django.conf.urls import url, include +from django.urls import path, re_path + +import survey.views as views + +urlpatterns = [ +#re_path(r'^responses/$',views.ResponseList.as_view(),name='responses_view'), +#re_path(r'^response/(?P\d+)/$',views.ResponseDetail.as_view(),name='response_view') +] diff --git a/survey/views.py b/survey/views.py new file mode 100644 index 00000000..7a3e6c99 --- /dev/null +++ b/survey/views.py @@ -0,0 +1,34 @@ +from django.shortcuts import render +from django.template.loader import render_to_string + +from django.views.generic.edit import UpdateView,DeleteView,CreateView +from django.views.generic import ListView,DetailView + +from django.http import ( + HttpResponse, HttpResponseRedirect, + JsonResponse, + HttpResponseForbidden, HttpResponseNotAllowed, + HttpResponseNotFound,Http404 + ) +from django.contrib.auth import authenticate, login, logout + +from survey.models import Response + +class ResponseList(ListView): + model = Response + template_name = 'response_list.view' + +class ResponseCreate(CreateView): + login_required = True + model = Response + template_name = 'response_create.html' + +class ResponseUpdate(UpdateView): + login_required = True + model = Response + template_name = 'response_update.html' + +class ResponseDetail(DetailView): + login_required = True + model = Response + template_name = 'response.html'