Private
Public Access
1
0
This commit is contained in:
2024-12-30 15:01:07 +01:00
parent f7dcb08d4d
commit 8a2485d3b2
7 changed files with 45 additions and 231 deletions

View File

@@ -59,10 +59,15 @@ def idoklad_token():
response = requests.post('https://identity.idoklad.cz/server/connect/token', headers=headers, data=data)
if response.status_code == 200:
token = response.json()
token['updated_at'] = timezone.now()
token = iDokladToken.objects.filter(id=1).update(**token)
return iDokladToken.objects.get(id=1)
token_json = response.json()
token = iDokladToken.objects.all().order_by('-updated_at')[0]
token.access_token = token_json['access_token']
token.id_token = token_json['id_token']
token.refresh_token = token_json['refresh_token']
token.expires_in = token_json['expires_in']
token.updated_at = timezone.now()
token.save()
return token
else:
return None

View File

@@ -9,7 +9,7 @@
<li class="grid_4">
<p>Rowsandall.com offers free data and analysis for rowers, by rowers.
Of course, offering this service is not free. To help cover the
hosting costs, we have created paid plans offering extended
hosting costs, we have created a paid plan offering extended
functionality.
</p>
<p>
@@ -25,9 +25,6 @@
<th>&nbsp;</th>
<th>BASIC</th>
<th>PRO</th>
<th>SELF-COACH</th>
<th>COACH</th>
<th>Free COACH</th>
</tr>
</thead>
<tbody>
@@ -35,146 +32,92 @@
<td>Basic rowing metrics (spm, time, distance, heart rate, power)</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Manual Import, Export, Synchronization and download of all your data</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Heart rate and power zones</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Ranking Pieces, Stroke Analysis</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Compare Workouts</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Automatic Synchronization with other fitness sites</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>All other rowing metrics (Work per Stroke, Average and Peak Force, Drive Length, Catch and Finish Angle, Slip and Wash, Peak Force Angle, and more)</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Automatic Synchronization with other fitness sites</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Advanced Analysis (Critical Power, Stats, Box Chart, Trend Flex)</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;<a href="#freecoach">*</a></td>
</tr>
<tr>
<td>Compare Workouts</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;<a href="#freecoach">*</a></td>
</tr>
<tr>
<td>Empower Stroke Profile</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;<a href="#freecoach">*</a></td>
</tr>
<tr>
<td>Sensor Fusion, Split Workout, In-stroke metrics</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&#10004;<a href="#freecoach">*</a></td>
</tr>
<tr>
<td>Create and manage groups.</td>
<td>&nbsp;</td>
<td>&#10004; (max 1)</td>
<td>&#10004; (max 1)</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Create Training plans, tests and challenges for yourself and your training group. Track your performance
against plan.</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Create Training plans, tests and challenges for your athletes. Track their performance
against plan. </td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Manage your athlete's workouts</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Run analytics for your athletes</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;<a href="#freecoach">*</a></td>
</tr>
<tr>
<td>Change zone intensities and other workout related settings for your athletes</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&#10004;</td>
<td>&#10004;</td>
</tr>
<tr>
<td>Pricing</td>
<td>FREE</td>
<td nowrap="nowrap">From 25&euro;/year</td>
<td nowrap="nowrap">From 75&euro;/year</td>
<td nowrap="nowrap">From 90&euro;/year</td>
<td nowrap="nowrap">Free</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
{% if rower %}
<tr>
@@ -193,27 +136,11 @@
&nbsp;
{% endif %}
</td>
<td>
{% if rower.rowerplan == 'plan' %}
<h3>SELF-COACH ({{ rower.paymenttype }})</h3>
{% else %}
&nbsp;
{% endif %}
</td>
<td>
{% if rower.rowerplan == 'coach' %}
<h3>COACH ({{ rower.paymenttype }})</h3>
{% elif rower.rowerplan == 'freecoach' %}
<h3>Free COACH</h3>
{% else %}
&nbsp;
{% endif %}
</td>
</tr>
{% endif %}
<tr>
<td>
Available trials (no strings attached)
Available trial (no strings attached)
</td>
<td>
&nbsp;
@@ -231,40 +158,6 @@
&nbsp;
{% endif %}
</td>
<td>
{% if user.is_anonymous %}
<button style="width:100%">
<a href="/rowers/startplantrial/">Free SELF-COACH trial</a>
</button>
{% elif rower and rower.rowerplan == 'basic' and rower.plantrialexpires|date_dif == 1 %}
<button style="width:100%">
<a href="/rowers/startplantrial/">Free SELF-COACH trial</a>
</button>
{% elif rower and rower.rowerplan == 'pro' and rower.plantrialexpires|date_dif == 1 %}
<button style="width:100%">
<a href="/rowers/startplantrial/">Free SELF-COACH trial</a>
</button>
{% else %}
&nbsp;
{% endif %}
</td>
<td>
{% if user.is_anonymous %}
<button style="width:100%">
<a href="/rowers/startcoachtrial/">Free COACH trial</a>
</button>
{% elif rower and rower.rowerplan == 'basic' and rower.coachtrialexpires|date_dif == 1 %}
<button style="width:100%">
<a href="/rowers/startcoachtrial/">Free COACH trial</a>
</button>
{% elif rower and rower.rowerplan == 'pro' and rower.coachtrialexpires|date_dif == 1 %}
<button style="width:100%">
<a href="/rowers/startcoachtrial/">Free COACH trial</a>
</button>
{% else %}
&nbsp;
{% endif %}
</td>
</tr>
<tr>
<td>
@@ -289,79 +182,16 @@
{% endif %}
</button>
</td>
{% elif rower and rower.rowerplan == 'freecoach' %}
<td colspan="3">
<button style="width:100%">
{% if user|existing_customer %}
<a href="/rowers/upgrade/">UPGRADE NOW</a>
{% else %}
<a href="/rowers/billing/">BUY NOW</a>
{% endif %}
</button>
</td>
{% elif rower and rower.rowerplan == 'pro' %}
<td>&nbsp;</td>
<td colspan="2">
<button style="width:100%">
{% if user|existing_customer %}
<a href="/rowers/upgrade/">UPGRADE NOW</a>
{% else %}
<a href="/rowers/billing/">BUY NOW</a>
{% endif %}
</button>
</td>
{% elif rower and rower.rowerplan == 'plan' %}
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>
<button style="width:100%">
{% if user|existing_customer %}
<a href="/rowers/upgrade/">UPGRADE NOW</a>
{% else %}
<a href="/rowers/billing/">BUY NOW</a>
{% endif %}
</button>
</td>
<td colspan=3>
&nbsp;
</td>
{% endif %}
</tr>
</tbody>
</table>
</p>
<h2>Coach and Self-Coach Membership</h2>
<p>Rowsandall.com's Training Planning functionality
is part of the paid "Self-Coach" and "Coach" plans.</p>
<p>On the "Self-Coach" plan, you can plan your own sessions.</p>
<p>On the "Coach" plan, you can establish teams, see workouts done by
athletes on your team, and plan individual and group sessions for your
athletes.
<p>
<strong>Payment methods</strong>: We accept credit card payments and PayPal through Braintree.
</p>
<p>The Coach plan functionality listed is available to the coach only.
Individual athletes
can purchase upgrades to "Pro" and "Self-Coach" plans.
</p>
<p id="freecoach">
The Coach plans come in two versions: free and paid. On the free coach plan,
you can only have athletes who are on the PRO paid plans or higher, and you
cannot upload any workouts to your own account. Some of the advanced Analysis functionality
becomes available when the athlete group is larger than 4.
On the paid
plans, your athletes can be on the free plan, and you have full access to the
site functionality for your own workouts and those of your athletes.
</p>
<p>If you would like to find a coach who helps you plan your training
through rowsandall.com, contact me throught the contact form.</p>
<h2>Terms and Conditions, Contact Information</h2>
<p>

View File

@@ -21,7 +21,7 @@ class ListWorkoutTest(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -80,7 +80,7 @@ class PlannedSessionTests(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -135,7 +135,7 @@ class ForcecurveTest(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -275,7 +275,7 @@ class WorkoutCompareTestNew(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -377,7 +377,7 @@ class WorkoutBoxPlotTestNew(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -478,7 +478,7 @@ class WorkoutHistoTestNew(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -579,7 +579,7 @@ class History(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(20, user=self.r)
@@ -670,7 +670,7 @@ class GoldMedalScores(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(20, user=self.r)
@@ -774,7 +774,7 @@ class WorkoutFlexallTestNew(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -875,7 +875,7 @@ class WorkoutStatsTestNew(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -1188,7 +1188,7 @@ class MarkerPerformanceTest(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)
@@ -1366,7 +1366,7 @@ class AlertTest(TestCase):
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True,surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach')
rowerplan='pro')
self.c = Client()
self.user_workouts = WorkoutFactory.create_batch(5, user=self.r)

View File

@@ -183,7 +183,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -242,7 +242,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -306,7 +306,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -373,7 +373,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -507,7 +507,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -548,7 +548,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -570,7 +570,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -617,7 +617,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -663,7 +663,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -708,7 +708,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),
@@ -759,7 +759,7 @@ description: ""
birthdate=faker.profile()['birthdate'],
gdproptin=True, ftpset=True, surveydone=True,
gdproptindate=timezone.now(),
rowerplan='coach',
rowerplan='pro',
paymentprocessor='braintree',
street_address=faker.street_address(),
city=faker.city(),

View File

@@ -41,28 +41,7 @@ class TrialsTest(TestCase):
self.r.protrialexpires = (nu+datetime.timedelta(days=10)).date()
self.r.save()
self.assertEqual(isplanmember(self.u),False)
self.assertEqual(iscoachmember(self.u),False)
self.assertEqual(ispromember(self.u),True)
self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date()
self.r.save()
self.assertEqual(isplanmember(self.u),True)
self.assertEqual(iscoachmember(self.u),False)
self.assertEqual(iscoachmember(self.u),True)
self.assertEqual(ispromember(self.u),True)
def test_protrial(self):
self.r.rowerplan = 'pro'
self.r.save()
self.assertEqual(isplanmember(self.u),False)
self.assertEqual(iscoachmember(self.u),False)
self.assertEqual(ispromember(self.u),True)
self.r.plantrialexpires = (nu+datetime.timedelta(days=10)).date()
self.r.save()
self.assertEqual(is_plantrial(self.u),True)
self.assertEqual(isplanmember(self.u),True)
self.assertEqual(iscoachmember(self.u),False)
self.assertEqual(ispromember(self.u),True)

View File

@@ -25,7 +25,7 @@ class URLTests(TestCase):
'sander@ds.ds',
'koeinsloot',
)
r = Rower.objects.create(user=u,rowerplan='coach',gdproptin=True, ftpset=True,
r = Rower.objects.create(user=u,rowerplan='pro',gdproptin=True, ftpset=True,
gdproptindate=timezone.now())
self.c = Client()
cs = courses.kmltocourse('rowers/tests/testdata/thyro.kml')

Binary file not shown.