Merge branch 'feature/autopep' into develop
This commit is contained in:
+1
-4
@@ -2,9 +2,7 @@ from rowers.models import Alert, Condition, User, Rower, Workout
|
||||
from rowers.teams import coach_getcoachees
|
||||
from rowers.dataprep import getsmallrowdata_db, getrowdata_db
|
||||
import datetime
|
||||
# BASIC operations
|
||||
|
||||
# create alert
|
||||
import numpy as np
|
||||
|
||||
|
||||
def create_alert(manager, rower, measured, period=7, emailalert=True,
|
||||
@@ -65,7 +63,6 @@ def alert_add_filters(alert, filters):
|
||||
for f in filters:
|
||||
metric = f['metric']
|
||||
value1 = f['value1']
|
||||
value2 = f['value2']
|
||||
condition = f['condition']
|
||||
|
||||
if condition and metric and value1:
|
||||
|
||||
+27
-52
@@ -72,8 +72,7 @@ def process_webhook(notification):
|
||||
transactions = subscription.transactions
|
||||
if transactions:
|
||||
amount = int(transactions[0].amount)
|
||||
eurocredits = credits.upgrade(amount, r)
|
||||
eurocredits = credits.upgrade(amount, r)
|
||||
_ = credits.upgrade(amount, r)
|
||||
return send_invoice(notification.subscription)
|
||||
if notification.kind == 'subscription_canceled':
|
||||
subscription = notification.subscription
|
||||
@@ -97,10 +96,7 @@ def process_webhook(notification):
|
||||
|
||||
|
||||
def send_invoice(subscription):
|
||||
with open('braintreewebhooks.log', 'a') as f:
|
||||
t = time.localtime()
|
||||
timestamp = time.strftime('%b-%d-%Y_%H%M', t)
|
||||
f.write('Subscription ID '+str(subscription.id)+'\n')
|
||||
dologging('braintreewebhooks.log', 'Subscription ID '+str(subscription.id))
|
||||
subscription_id = subscription.id
|
||||
rs = Rower.objects.filter(subscription_id=subscription_id)
|
||||
if rs.count() == 0: # pragma: no cover
|
||||
@@ -176,20 +172,6 @@ def get_client_token(rower):
|
||||
return client_token
|
||||
|
||||
|
||||
def get_plans_costs(): # pragma: no cover
|
||||
plans = gateway.plan.all()
|
||||
|
||||
localplans = PaidPlan.object.filter(paymentprocessor='braintree')
|
||||
|
||||
for plan in localplans:
|
||||
for btplan in btplans:
|
||||
if int(btplan.id) == plan.external_id:
|
||||
plan.price = float(x)
|
||||
plan.save()
|
||||
|
||||
return plans
|
||||
|
||||
|
||||
def make_payment(rower, data):
|
||||
nonce_from_the_client = data['payment_method_nonce']
|
||||
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
|
||||
@@ -226,17 +208,11 @@ def make_payment(rower, data):
|
||||
fakturoid_contact_id = fakturoid.get_contacts(rower)
|
||||
if not fakturoid_contact_id:
|
||||
fakturoid_contact_id = fakturoid.create_contact(rower)
|
||||
id = fakturoid.create_invoice(rower, amount, transaction.id, dosend=True, contact_id=fakturoid_contact_id,
|
||||
name=additional_text)
|
||||
|
||||
try:
|
||||
job = myqueue(queuehigh, handle_send_email_transaction,
|
||||
name, rower.user.email, amount)
|
||||
job = myqueue(queuehigh, handle_send_email_transation_notification,
|
||||
name.rower.user.email, amount, additional_text)
|
||||
except: # pragma: no cover
|
||||
pass
|
||||
_ = fakturoid.create_invoice(rower, amount, transaction.id, dosend=True, contact_id=fakturoid_contact_id,
|
||||
name=additional_text)
|
||||
|
||||
_ = myqueue(queuehigh, handle_send_email_transaction,
|
||||
name, rower.user.email, amount)
|
||||
return amount, True
|
||||
else: # pragma: no cover
|
||||
return 0, False
|
||||
@@ -280,7 +256,7 @@ def update_subscription(rower, data, method='up'):
|
||||
yesterday = (timezone.now()-datetime.timedelta(days=1)).date()
|
||||
rower.paidplan = plan
|
||||
amount_int = int(float(amount))
|
||||
eurocredits = credits.upgrade(amount_int, rower)
|
||||
_ = credits.upgrade(amount_int, rower)
|
||||
rower.planexpires = result.subscription.billing_period_end_date
|
||||
rower.teamplanexpires = result.subscription.billing_period_end_date
|
||||
rower.clubsize = plan.clubsize
|
||||
@@ -319,16 +295,16 @@ def update_subscription(rower, data, method='up'):
|
||||
else: # pragma: no cover
|
||||
amount = 0
|
||||
|
||||
job = myqueue(queuehigh,
|
||||
handle_send_email_subscription_update,
|
||||
name, rower.user.email,
|
||||
plan.name,
|
||||
plan.paymenttype,
|
||||
plan.price,
|
||||
amount,
|
||||
result.subscription.billing_period_end_date.strftime(
|
||||
'%Y-%m-%d'),
|
||||
method)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_send_email_subscription_update,
|
||||
name, rower.user.email,
|
||||
plan.name,
|
||||
plan.paymenttype,
|
||||
plan.price,
|
||||
amount,
|
||||
result.subscription.billing_period_end_date.strftime(
|
||||
'%Y-%m-%d'),
|
||||
method)
|
||||
|
||||
return True, amount
|
||||
else: # pragma: no cover
|
||||
@@ -352,12 +328,12 @@ def create_subscription(rower, data):
|
||||
nonce_from_the_client = data['payment_method_nonce']
|
||||
nonce = gateway.payment_method_nonce.find(nonce_from_the_client)
|
||||
info = nonce.three_d_secure_info
|
||||
paymenttype = nonce.type
|
||||
# paymenttype = nonce.type
|
||||
|
||||
if nonce.type != 'PayPalAccount': # pragma: no cover
|
||||
if info is None or not info.liability_shifted:
|
||||
return False, 0
|
||||
amount = data['amount']
|
||||
# amount = data['amount']
|
||||
|
||||
planid = data['plan']
|
||||
plan = PaidPlan.objects.get(id=planid)
|
||||
@@ -399,7 +375,7 @@ def create_subscription(rower, data):
|
||||
|
||||
recurring = plan.paymenttype
|
||||
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_send_email_subscription_create,
|
||||
name, rower.user.email,
|
||||
@@ -420,18 +396,19 @@ def cancel_subscription(rower, id):
|
||||
themessages = []
|
||||
errormessages = []
|
||||
try:
|
||||
result = gateway.subscription.cancel(id)
|
||||
_ = gateway.subscription.cancel(id)
|
||||
themessages.append("Subscription canceled")
|
||||
except: # pragma: no cover
|
||||
errormessages.append(
|
||||
"We could not find the subscription record in our customer database. We have notified the site owner, who will contact you.")
|
||||
"We could not find the subscription record in our customer database."
|
||||
" We have notified the site owner, who will contact you.")
|
||||
|
||||
name = '{f} {l}'.format(f=rower.user.first_name,
|
||||
l=rower.user.last_name)
|
||||
|
||||
job = myqueue(queuehigh,
|
||||
handle_send_email_failed_cancel,
|
||||
name, rower.user.email, rower.user.username, id)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_send_email_failed_cancel,
|
||||
name, rower.user.email, rower.user.username, id)
|
||||
|
||||
return False, themessages, errormessages
|
||||
|
||||
@@ -510,15 +487,13 @@ def get_transactions(start_date, end_date): # pragma: no cover
|
||||
dates = []
|
||||
currencies = []
|
||||
statuses = []
|
||||
ids = []
|
||||
# ids = []
|
||||
usernames = []
|
||||
customerids = []
|
||||
transactionids = []
|
||||
subscriptionids = []
|
||||
ownids = []
|
||||
|
||||
countlines = [1 for transaction in results]
|
||||
|
||||
for transaction in results:
|
||||
r = None
|
||||
rs = Rower.objects.filter(
|
||||
|
||||
+41
-75
@@ -74,11 +74,12 @@ def getagegrouprecord(age, sex='male', weightcategory='hwt',
|
||||
ages = df['age']
|
||||
powers = df['power']
|
||||
|
||||
#poly_coefficients = np.polyfit(ages,powers,6)
|
||||
def fitfunc(pars, x): return np.abs(pars[0])*(1-x/max(120, pars[1]))-np.abs(
|
||||
pars[2])*np.exp(-x/np.abs(pars[3]))+np.abs(pars[4])*(np.sin(np.pi*x/max(50, pars[5])))
|
||||
def fitfunc(pars, x):
|
||||
return np.abs(pars[0])*(1-x/max(120, pars[1]))-np.abs(
|
||||
pars[2])*np.exp(-x/np.abs(pars[3]))+np.abs(pars[4])*(np.sin(np.pi*x/max(50, pars[5])))
|
||||
|
||||
def errfunc(pars, x, y): return fitfunc(pars, x)-y
|
||||
def errfunc(pars, x, y):
|
||||
return fitfunc(pars, x)-y
|
||||
|
||||
p0 = [700, 120, 700, 10, 100, 100]
|
||||
|
||||
@@ -92,8 +93,6 @@ def getagegrouprecord(age, sex='male', weightcategory='hwt',
|
||||
if success:
|
||||
power = fitfunc(p1, float(age))
|
||||
|
||||
#power = np.polyval(poly_coefficients,age)
|
||||
|
||||
power = 0.5*(np.abs(power)+power)
|
||||
else: # pragma: no cover
|
||||
power = 0
|
||||
@@ -123,14 +122,13 @@ oauth_data = {
|
||||
def c2_open(user):
|
||||
r = Rower.objects.get(user=user)
|
||||
if (r.c2token == '') or (r.c2token is None):
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
raise NoTokenError("User has no token")
|
||||
else:
|
||||
if (timezone.now() > r.tokenexpirydate):
|
||||
res = rower_c2_token_refresh(user)
|
||||
if res == None: # pragma: no cover
|
||||
if res is None: # pragma: no cover
|
||||
raise NoTokenError("User has no token")
|
||||
if res[0] != None:
|
||||
if res[0] is not None:
|
||||
thetoken = res[0]
|
||||
else: # pragma: no cover
|
||||
raise NoTokenError("User has no token")
|
||||
@@ -142,7 +140,7 @@ def c2_open(user):
|
||||
|
||||
def get_c2_workouts(rower, page=1, do_async=True):
|
||||
try:
|
||||
thetoken = c2_open(rower.user)
|
||||
_ = c2_open(rower.user)
|
||||
except NoTokenError: # pragma: no cover
|
||||
return 0
|
||||
|
||||
@@ -175,7 +173,7 @@ def get_c2_workouts(rower, page=1, do_async=True):
|
||||
|
||||
knownc2ids = uniqify(knownc2ids+tombstones+parkedids)
|
||||
|
||||
newids = [c2id for c2id in c2ids if not c2id in knownc2ids]
|
||||
newids = [c2id for c2id in c2ids if c2id not in knownc2ids]
|
||||
if settings.TESTING:
|
||||
newids = c2ids
|
||||
|
||||
@@ -188,20 +186,18 @@ def get_c2_workouts(rower, page=1, do_async=True):
|
||||
counter = 0
|
||||
for c2id in newids:
|
||||
if do_async: # pragma: no cover
|
||||
res = myqueue(queuehigh,
|
||||
handle_c2_async_workout,
|
||||
alldata,
|
||||
rower.user.id,
|
||||
rower.c2token,
|
||||
c2id,
|
||||
counter,
|
||||
rower.defaulttimezone
|
||||
)
|
||||
#res = handle_c2_async_workout(alldata,rower.user.id,rower.c2token,c2id,counter)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_c2_async_workout,
|
||||
alldata,
|
||||
rower.user.id,
|
||||
rower.c2token,
|
||||
c2id,
|
||||
counter,
|
||||
rower.defaulttimezone)
|
||||
|
||||
counter = counter+1
|
||||
else:
|
||||
workoutid = create_async_workout(alldata,
|
||||
rower.user, c2id)
|
||||
_ = create_async_workout(alldata, rower.user, c2id)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -212,12 +208,9 @@ def create_async_workout(alldata, user, c2id):
|
||||
data = alldata[c2id]
|
||||
splitdata = None
|
||||
|
||||
distance = data['distance']
|
||||
c2id = data['id']
|
||||
workouttype = data['type']
|
||||
verified = data['verified']
|
||||
startdatetime = iso8601.parse_date(data['date'])
|
||||
weightclass = data['weight_class']
|
||||
|
||||
try:
|
||||
title = data['name']
|
||||
@@ -229,43 +222,16 @@ def create_async_workout(alldata, user, c2id):
|
||||
except:
|
||||
title = ''
|
||||
|
||||
weightcategory = 'hwt'
|
||||
if weightclass == "L":
|
||||
weightcategory = 'lwt'
|
||||
|
||||
# Create CSV file name and save data to CSV file
|
||||
csvfilename = 'media/Import_'+str(c2id)+'.csv.gz'
|
||||
|
||||
totaltime = data['time']/10.
|
||||
duration = dataprep.totaltime_sec_to_string(totaltime)
|
||||
|
||||
try:
|
||||
timezone_str = data['timezone']
|
||||
except: # pragma: no cover
|
||||
timezone_str = 'UTC'
|
||||
|
||||
workoutdate = startdatetime.astimezone(
|
||||
pytz.timezone(timezone_str)
|
||||
).strftime('%Y-%m-%d')
|
||||
starttime = startdatetime.astimezone(
|
||||
pytz.timezone(timezone_str)
|
||||
).strftime('%H:%M:%S')
|
||||
|
||||
try:
|
||||
notes = data['comments']
|
||||
name = notes[:40]
|
||||
except (KeyError, TypeError):
|
||||
notes = 'C2 Import Workout from {startdatetime}'.format(
|
||||
startdatetime=startdatetime)
|
||||
name = notes
|
||||
|
||||
r = Rower.objects.get(user=user)
|
||||
|
||||
authorizationstring = str('Bearer ' + r.c2token)
|
||||
headers = {'Authorization': authorizationstring,
|
||||
'user-agent': 'sanderroosendaal',
|
||||
'Content-Type': 'application/json'}
|
||||
url2 = "https://log.concept2.com/api/users/me/results"+str(c2id)
|
||||
# url2 = "https://log.concept2.com/api/users/me/results"+str(c2id)
|
||||
url = "https://log.concept2.com/api/users/me/results/"+str(c2id)+"/strokes"
|
||||
try:
|
||||
s = requests.get(url, headers=headers)
|
||||
@@ -638,7 +604,7 @@ def createc2workoutdata(w):
|
||||
spmav = int(row.df[' Cadence (stokes/min)'][mask].mean())
|
||||
hrav = int(row.df[' HRCur (bpm)'][mask].mean())
|
||||
except ValueError:
|
||||
smpav = 0
|
||||
spmav = 0
|
||||
try:
|
||||
hrav = int(row.df[' HRCur (bpm)'][mask].mean())
|
||||
except ValuError:
|
||||
@@ -729,7 +695,6 @@ def createc2workoutdata(w):
|
||||
"time": int(10*makeseconds(durationstr)),
|
||||
"weight_class": c2wc(w.weightcategory),
|
||||
"comments": w.notes,
|
||||
"stroke_count": int(row.stroke_count),
|
||||
'stroke_rate': int(row.df[' Cadence (stokes/min)'].mean()),
|
||||
'drag_factor': int(row.dragfactor),
|
||||
"heart_rate": {
|
||||
@@ -749,7 +714,7 @@ def createc2workoutdata(w):
|
||||
|
||||
def do_refresh_token(refreshtoken):
|
||||
scope = "results:write,user:read"
|
||||
client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
|
||||
post_data = {"grant_type": "refresh_token",
|
||||
"client_secret": C2_CLIENT_SECRET,
|
||||
"client_id": C2_CLIENT_ID,
|
||||
@@ -793,7 +758,7 @@ def do_refresh_token(refreshtoken):
|
||||
def get_token(code):
|
||||
messg = ''
|
||||
scope = "user:read,results:write"
|
||||
client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(C2_CLIENT_ID, C2_CLIENT_SECRET)
|
||||
post_data = {"grant_type": "authorization_code",
|
||||
"code": code,
|
||||
"redirect_uri": C2_REDIRECT_URI,
|
||||
@@ -840,7 +805,7 @@ def make_authorization_url(request): # pragma: no cover
|
||||
# Generate a random string for the state parameter
|
||||
# Save it for use later to prevent xsrf attacks
|
||||
from uuid import uuid4
|
||||
state = str(uuid4())
|
||||
# state = str(uuid4())
|
||||
scope = "user:read,results:write"
|
||||
|
||||
params = {"client_id": C2_CLIENT_ID,
|
||||
@@ -857,14 +822,14 @@ def make_authorization_url(request): # pragma: no cover
|
||||
|
||||
def get_workout(user, c2id, do_async=True):
|
||||
r = Rower.objects.get(user=user)
|
||||
thetoken = c2_open(user)
|
||||
_ = c2_open(user)
|
||||
|
||||
job = myqueue(queuehigh,
|
||||
handle_c2_getworkout,
|
||||
user.id,
|
||||
r.c2token,
|
||||
c2id,
|
||||
r.defaulttimezone)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_c2_getworkout,
|
||||
user.id,
|
||||
r.c2token,
|
||||
c2id,
|
||||
r.defaulttimezone)
|
||||
|
||||
return 1
|
||||
|
||||
@@ -909,7 +874,7 @@ def get_username(access_token): # pragma: no cover
|
||||
|
||||
try:
|
||||
res = me_json['data']['username']
|
||||
id = me_json['data']['id']
|
||||
_ = me_json['data']['id']
|
||||
except KeyError:
|
||||
res = None
|
||||
|
||||
@@ -974,7 +939,7 @@ def workout_c2_upload(user, w, asynchron=False):
|
||||
except KeyError: # pragma: no cover
|
||||
return "This workout type cannot be uploaded to Concept2", 0
|
||||
|
||||
thetoken = c2_open(user)
|
||||
_ = c2_open(user)
|
||||
|
||||
r = Rower.objects.get(user=user)
|
||||
|
||||
@@ -1017,16 +982,17 @@ def workout_c2_upload(user, w, asynchron=False):
|
||||
w.save()
|
||||
message = "Upload to Concept2 was successful"
|
||||
else: # pragma: no cover
|
||||
message = "Something went wrong in workout_c2_upload_view. Response code 200/201 but C2 sync failed: "+response.text
|
||||
message = "Something went wrong in workout_c2_upload_view." \
|
||||
" Response code 200/201 but C2 sync failed: "+response.text
|
||||
c2id = 0
|
||||
else: # pragma: no cover
|
||||
|
||||
job = myqueue(queue,
|
||||
handle_c2_sync,
|
||||
w.id,
|
||||
url,
|
||||
headers,
|
||||
json.dumps(data, default=default))
|
||||
_ = myqueue(queue,
|
||||
handle_c2_sync,
|
||||
w.id,
|
||||
url,
|
||||
headers,
|
||||
json.dumps(data, default=default))
|
||||
c2id = 0
|
||||
|
||||
return message, c2id
|
||||
|
||||
+1
-9
@@ -25,7 +25,7 @@ from django.conf import settings
|
||||
|
||||
import geocoder
|
||||
|
||||
from matplotlib import path
|
||||
# from matplotlib import path
|
||||
import xml.etree.ElementTree as et
|
||||
|
||||
from xml.etree.ElementTree import Element, SubElement, Comment, tostring
|
||||
@@ -42,10 +42,6 @@ def howfaris(lat_lon, course):
|
||||
|
||||
return distance
|
||||
|
||||
#whatisnear = 150
|
||||
|
||||
# get nearest races
|
||||
|
||||
|
||||
def getnearestraces(lat_lon, races, whatisnear=150):
|
||||
newlist = []
|
||||
@@ -55,7 +51,6 @@ def getnearestraces(lat_lon, races, whatisnear=150):
|
||||
newlist.append(race)
|
||||
else:
|
||||
c = race.course
|
||||
coords = c.coord
|
||||
distance = howfaris(lat_lon, c)
|
||||
if distance < whatisnear:
|
||||
newlist.append(race)
|
||||
@@ -84,7 +79,6 @@ def getnearestcourses(lat_lon, courses, whatisnear=150, strict=False):
|
||||
newlist = []
|
||||
counter = 0
|
||||
for c in courses:
|
||||
coords = c.coord
|
||||
distance = howfaris(lat_lon, c)
|
||||
|
||||
if distance < whatisnear:
|
||||
@@ -199,8 +193,6 @@ def coursetokml(course):
|
||||
polygons = GeoPolygon.objects.filter(
|
||||
course=course).order_by("order_in_course")
|
||||
|
||||
polygonsxml = []
|
||||
|
||||
for polygon in polygons:
|
||||
placemark = SubElement(folder2, 'Placemark')
|
||||
polygonname = SubElement(placemark, 'name')
|
||||
|
||||
@@ -20,10 +20,8 @@ def time_in_path(df, p, maxmin='max', getall=False, name='unknown', logfile=None
|
||||
if df.empty: # pragma: no cover
|
||||
return 0
|
||||
|
||||
latitude = df.latitude
|
||||
longitude = df.longitude
|
||||
|
||||
def f(x): return coordinate_in_path(x['latitude'], x['longitude'], p)
|
||||
def f(x):
|
||||
return coordinate_in_path(x['latitude'], x['longitude'], p)
|
||||
|
||||
df['inpolygon'] = df.apply(f, axis=1)
|
||||
|
||||
|
||||
+106
-123
@@ -31,7 +31,6 @@ from zipfile import BadZipFile
|
||||
import zipfile
|
||||
import os
|
||||
from rowers.models import strokedatafields
|
||||
from rowingdata.csvparsers import HumonParser
|
||||
|
||||
from rowingdata import (
|
||||
KinoMapParser,
|
||||
@@ -56,8 +55,7 @@ from rowingdata import (
|
||||
ETHParser,
|
||||
NKLiNKLogbookParser,
|
||||
HeroParser,
|
||||
SmartRowParser,
|
||||
)
|
||||
SmartRowParser,)
|
||||
|
||||
# All the data preparation, data cleaning and data mangling should
|
||||
# be defined here
|
||||
@@ -111,13 +109,8 @@ import arrow
|
||||
|
||||
thetimezone = get_current_timezone()
|
||||
|
||||
|
||||
#allowedcolumns = [item[0] for item in rowingmetrics]
|
||||
allowedcolumns = [key for key, value in strokedatafields.items()]
|
||||
|
||||
#from async_messages import messages as a_messages
|
||||
|
||||
|
||||
queue = django_rq.get_queue('default')
|
||||
queuelow = django_rq.get_queue('low')
|
||||
queuehigh = django_rq.get_queue('default')
|
||||
@@ -169,8 +162,6 @@ def get_video_data(w, groups=['basic'], mode='water'):
|
||||
p = nicepaceformat(p)
|
||||
df2['pace'] = p
|
||||
|
||||
#mask = df2['time'] < delay
|
||||
#df2 = df2.mask(mask).dropna()
|
||||
df2['time'] = (df2['time']-df2['time'].min())
|
||||
|
||||
df2 = df2.round(decimals=2)
|
||||
@@ -190,8 +181,6 @@ def get_video_data(w, groups=['basic'], mode='water'):
|
||||
coordinates.set_index(pd.to_timedelta(
|
||||
coordinates['time'], unit='s'), inplace=True)
|
||||
coordinates = coordinates.resample('1s').mean().interpolate()
|
||||
#mask = coordinates['time'] < delay
|
||||
#coordinates = coordinates.mask(mask).dropna()
|
||||
coordinates['time'] = coordinates['time']-coordinates['time'].min()
|
||||
latitude = coordinates['latitude']
|
||||
longitude = coordinates['longitude']
|
||||
@@ -295,11 +284,11 @@ def get_latlon_time(id):
|
||||
|
||||
try:
|
||||
try:
|
||||
latitude = rowdata.df.loc[:, ' latitude']
|
||||
longitude = rowdata.df.loc[:, ' longitude']
|
||||
_ = rowdata.df.loc[:, ' latitude']
|
||||
_ = rowdata.df.loc[:, ' longitude']
|
||||
except KeyError: # pragma: no cover
|
||||
latitude = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
|
||||
longitude = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
|
||||
rowdata.df['latitude'] = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
|
||||
rowdata.df['longitude'] = 0 * rowdata.df.loc[:, 'TimeStamp (sec)']
|
||||
except AttributeError: # pragma: no cover
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -438,7 +427,7 @@ def get_workouts(ids, userid): # pragma: no cover
|
||||
def filter_df(datadf, fieldname, value, largerthan=True):
|
||||
|
||||
try:
|
||||
x = datadf[fieldname]
|
||||
_ = datadf[fieldname]
|
||||
except KeyError:
|
||||
return datadf
|
||||
|
||||
@@ -486,9 +475,9 @@ def join_workouts(r, ids, title='Joined Workout',
|
||||
makeprivate = False
|
||||
startdatetime = timezone.now()
|
||||
|
||||
if setprivate == True and makeprivate == False: # pragma: no cover
|
||||
if setprivate is True and makeprivate is False: # pragma: no cover
|
||||
makeprivate = True
|
||||
elif setprivate == False and makeprivate == True: # pragma: no cover
|
||||
elif setprivate is False and makeprivate is True: # pragma: no cover
|
||||
makeprivate = False
|
||||
|
||||
# reorder in chronological order
|
||||
@@ -501,6 +490,11 @@ def join_workouts(r, ids, title='Joined Workout',
|
||||
workouttype = parent.workouttype
|
||||
notes = parent.notes
|
||||
summary = parent.summary
|
||||
if parent.privacy == 'hidden':
|
||||
makeprivate = True
|
||||
else:
|
||||
makeprivate = False
|
||||
startdatetime = parent.startdatetime
|
||||
|
||||
files = [w.csvfilename for w in ws]
|
||||
|
||||
@@ -524,7 +518,9 @@ def join_workouts(r, ids, title='Joined Workout',
|
||||
notes=notes,
|
||||
oarlength=oarlength,
|
||||
inboard=inboard,
|
||||
startdatetime=startdatetime,
|
||||
makeprivate=makeprivate,
|
||||
summary=summary,
|
||||
dosmooth=False,
|
||||
consistencychecks=False)
|
||||
|
||||
@@ -585,12 +581,12 @@ def resample(id, r, parent, overwrite='copy'):
|
||||
|
||||
row.write_csv(parent.csvfilename, gzip=True)
|
||||
|
||||
res = dataprep(row.df, id=parent.id, bands=True, barchart=True,
|
||||
otwpower=True, empower=True, inboard=parent.inboard)
|
||||
_ = dataprep(row.df, id=parent.id, bands=True, barchart=True,
|
||||
otwpower=True, empower=True, inboard=parent.inboard)
|
||||
isbreakthrough, ishard = checkbreakthrough(parent, r)
|
||||
marker = check_marker(parent)
|
||||
result = update_wps(r, mytypes.otwtypes)
|
||||
result = update_wps(r, mytypes.otetypes)
|
||||
_ = check_marker(parent)
|
||||
_ = update_wps(r, mytypes.otwtypes)
|
||||
_ = update_wps(r, mytypes.otetypes)
|
||||
|
||||
tss, normp = workout_rscore(parent)
|
||||
goldmedalstandard, goldmedalseconds = workout_goldmedalstandard(parent)
|
||||
@@ -607,7 +603,7 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
|
||||
# clean data remove zeros and negative values
|
||||
|
||||
try:
|
||||
workoutids = datadf['workoutid'].unique()
|
||||
_ = datadf['workoutid'].unique()
|
||||
except KeyError:
|
||||
datadf['workoutid'] = 0
|
||||
|
||||
@@ -638,13 +634,13 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
|
||||
# protect 0 spm values from being nulled
|
||||
try:
|
||||
datadf['spm'] = datadf['spm'] + 1.0
|
||||
except (KeyError, TypeError) as e:
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
|
||||
# protect 0 workoutstate values from being nulled
|
||||
try:
|
||||
datadf['workoutstate'] = datadf['workoutstate'] + 1
|
||||
except (KeyError, TypeError) as e:
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
|
||||
try:
|
||||
@@ -676,13 +672,13 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
|
||||
# bring spm back to real values
|
||||
try:
|
||||
datadf['spm'] = datadf['spm'] - 1
|
||||
except (TypeError, KeyError) as e:
|
||||
except (TypeError, KeyError):
|
||||
pass
|
||||
|
||||
# bring workoutstate back to real values
|
||||
try:
|
||||
datadf['workoutstate'] = datadf['workoutstate'] - 1
|
||||
except (TypeError, KeyError) as e:
|
||||
except (TypeError, KeyError):
|
||||
pass
|
||||
|
||||
# return from positive domain to negative
|
||||
@@ -840,11 +836,11 @@ def clean_df_stats(datadf, workstrokesonly=True, ignorehr=True,
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
|
||||
workoutstateswork = [1, 4, 5, 8, 9, 6, 7]
|
||||
# workoutstateswork = [1, 4, 5, 8, 9, 6, 7]
|
||||
workoutstatesrest = [3]
|
||||
workoutstatetransition = [0, 2, 10, 11, 12, 13]
|
||||
# workoutstatetransition = [0, 2, 10, 11, 12, 13]
|
||||
|
||||
if workstrokesonly == 'True' or workstrokesonly == True:
|
||||
if workstrokesonly == 'True' or workstrokesonly is True:
|
||||
try:
|
||||
datadf = datadf[~datadf['workoutstate'].isin(workoutstatesrest)]
|
||||
except:
|
||||
@@ -872,10 +868,10 @@ def getpartofday(row, r):
|
||||
timezone_str = tf.timezone_at(lng=lonavg, lat=latavg)
|
||||
except (ValueError, OverflowError): # pragma: no cover
|
||||
timezone_str = 'UTC'
|
||||
if timezone_str == None: # pragma: no cover
|
||||
if timezone_str is None: # pragma: no cover
|
||||
timezone_str = tf.closest_timezone_at(lng=lonavg,
|
||||
lat=latavg)
|
||||
if timezone_str == None:
|
||||
if timezone_str is None:
|
||||
timezone_str = r.defaulttimezone
|
||||
try:
|
||||
workoutstartdatetime = pytz.timezone(timezone_str).localize(
|
||||
@@ -1008,7 +1004,7 @@ def update_c2id_sql(id, c2id):
|
||||
table, c2id, id)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
_ = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
@@ -1022,7 +1018,8 @@ def getcpdata_sql(rower_id, table='cpdata'):
|
||||
rower_id=rower_id,
|
||||
table=table,
|
||||
))
|
||||
connection = engine.raw_connection()
|
||||
|
||||
_ = engine.raw_connection()
|
||||
df = pd.read_sql_query(query, engine)
|
||||
|
||||
return df
|
||||
@@ -1036,7 +1033,7 @@ def deletecpdata_sql(rower_id, table='cpdata'): # pragma: no cover
|
||||
))
|
||||
with engine.connect() as conn, conn.begin():
|
||||
try:
|
||||
result = conn.execute(query)
|
||||
_ = conn.execute(query)
|
||||
except:
|
||||
print("Database locked")
|
||||
conn.close()
|
||||
@@ -1064,11 +1061,10 @@ def updatecpdata_sql(rower_id, delta, cp, table='cpdata', distance=[]): # pragm
|
||||
|
||||
|
||||
def fetchcperg(rower, theworkouts):
|
||||
theids = [int(w.id) for w in theworkouts]
|
||||
thefilenames = [w.csvfilename for w in theworkouts]
|
||||
cpdf = getcpdata_sql(rower.id, table='ergcpdata')
|
||||
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queuelow,
|
||||
handle_updateergcp,
|
||||
rower.id,
|
||||
@@ -1138,7 +1134,7 @@ def check_marker(workout):
|
||||
theid = df.loc[indexmax, 'id']
|
||||
|
||||
wmax = Workout.objects.get(id=theid)
|
||||
gms_max = wmax.goldmedalstandard
|
||||
# gms_max = wmax.goldmedalstandard
|
||||
|
||||
# check if equal, bigger, or smaller than previous
|
||||
if not wmax.rankingpiece:
|
||||
@@ -1210,16 +1206,17 @@ def calculate_goldmedalstandard(rower, workout, recurrance=True):
|
||||
)
|
||||
)
|
||||
jsondf = df2.to_json()
|
||||
job = myqueue(queuelow, handle_getagegrouprecords,
|
||||
jsondf, distances, durations, age, rower.sex, rower.weightcategory)
|
||||
_ = myqueue(queuelow, handle_getagegrouprecords,
|
||||
jsondf, distances, durations, age, rower.sex, rower.weightcategory)
|
||||
|
||||
wcpower = pd.Series(wcpower, dtype='float')
|
||||
wcdurations = pd.Series(wcdurations, dtype='float')
|
||||
|
||||
def fitfunc(pars, x): return pars[0] / \
|
||||
(1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
|
||||
def fitfunc(pars, x):
|
||||
return pars[0] / (1+(x/pars[2])) + pars[1]/(1+(x/pars[3]))
|
||||
|
||||
def errfunc(pars, x, y): return fitfunc(pars, x)-y
|
||||
def errfunc(pars, x, y):
|
||||
return fitfunc(pars, x)-y
|
||||
|
||||
if len(wcdurations) >= 4: # pragma: no cover
|
||||
p1wc, success = optimize.leastsq(
|
||||
@@ -1227,7 +1224,7 @@ def calculate_goldmedalstandard(rower, workout, recurrance=True):
|
||||
else:
|
||||
factor = fitfunc(p0, wcdurations.mean()/wcpower.mean())
|
||||
p1wc = [p0[0]/factor, p0[1]/factor, p0[2], p0[3]]
|
||||
success = 0
|
||||
|
||||
return 0, 0
|
||||
|
||||
times = df['delta']
|
||||
@@ -1292,7 +1289,7 @@ def setcp(workout, background=False, recurrance=True):
|
||||
return pd.DataFrame(), pd.Series(dtype='float'), pd.Series(dtype='float')
|
||||
|
||||
if background: # pragma: no cover
|
||||
job = myqueue(queuelow, handle_setcp, strokesdf, filename, workout.id)
|
||||
_ = myqueue(queuelow, handle_setcp, strokesdf, filename, workout.id)
|
||||
return pd.DataFrame({'delta': [], 'cp': []}), pd.Series(dtype='float'), pd.Series(dtype='float')
|
||||
|
||||
if not strokesdf.empty:
|
||||
@@ -1339,7 +1336,7 @@ def update_wps(r, types, mode='water', asynchron=True):
|
||||
|
||||
ids = [w.id for w in workouts]
|
||||
if asynchron:
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queue,
|
||||
handle_update_wps,
|
||||
r.id,
|
||||
@@ -1441,11 +1438,11 @@ def fetchcp(rower, theworkouts, table='cpdata'): # pragma: no cover
|
||||
if not cpdf.empty:
|
||||
return cpdf['delta'], cpdf['cp'], avgpower2
|
||||
else:
|
||||
job = myqueue(queuelow,
|
||||
handle_updatecp,
|
||||
rower.id,
|
||||
theids,
|
||||
table=table)
|
||||
_ = myqueue(queuelow,
|
||||
handle_updatecp,
|
||||
rower.id,
|
||||
theids,
|
||||
table=table)
|
||||
|
||||
return pd.Series([], dtype='float'), pd.Series([], dtype='float'), avgpower2
|
||||
|
||||
@@ -1489,11 +1486,11 @@ def create_row_df(r, distance, duration, startdatetime, workouttype='rower',
|
||||
else:
|
||||
spm = avgspm
|
||||
|
||||
step = totalseconds/float(nr_strokes)
|
||||
# step = totalseconds/float(nr_strokes)
|
||||
|
||||
elapsed = np.arange(nr_strokes)*totalseconds/(float(nr_strokes-1))
|
||||
|
||||
dstep = distance/float(nr_strokes)
|
||||
# dstep = distance/float(nr_strokes)
|
||||
|
||||
d = np.arange(nr_strokes)*distance/(float(nr_strokes-1))
|
||||
|
||||
@@ -1564,12 +1561,12 @@ def checkbreakthrough(w, r):
|
||||
if workouttype in otwtypes:
|
||||
res, btvalues, res2 = utils.isbreakthrough(
|
||||
delta, cpvalues, r.p0, r.p1, r.p2, r.p3, r.cpratio)
|
||||
success = update_rolling_cp(r, otwtypes, 'water')
|
||||
_ = update_rolling_cp(r, otwtypes, 'water')
|
||||
|
||||
elif workouttype in otetypes:
|
||||
res, btvalues, res2 = utils.isbreakthrough(
|
||||
delta, cpvalues, r.ep0, r.ep1, r.ep2, r.ep3, r.ecpratio)
|
||||
success = update_rolling_cp(r, otetypes, 'erg')
|
||||
_ = update_rolling_cp(r, otetypes, 'erg')
|
||||
else: # pragma: no cover
|
||||
res = 0
|
||||
res2 = 0
|
||||
@@ -1584,12 +1581,12 @@ def checkbreakthrough(w, r):
|
||||
w.rankingpiece = True
|
||||
w.save()
|
||||
if r.getemailnotifications and not r.emailbounced: # pragma: no cover
|
||||
job = myqueue(queuehigh, handle_sendemail_breakthrough,
|
||||
w.id,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
btvalues=btvalues.to_json())
|
||||
_ = myqueue(queuehigh, handle_sendemail_breakthrough,
|
||||
w.id,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
btvalues=btvalues.to_json())
|
||||
|
||||
# submit email task to send email about breakthrough workout
|
||||
if ishard: # pragma: no cover
|
||||
@@ -1597,12 +1594,12 @@ def checkbreakthrough(w, r):
|
||||
w.rankingpiece = True
|
||||
w.save()
|
||||
if r.getemailnotifications and not r.emailbounced:
|
||||
job = myqueue(queuehigh, handle_sendemail_hard,
|
||||
w.id,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
btvalues=btvalues.to_json())
|
||||
_ = myqueue(queuehigh, handle_sendemail_hard,
|
||||
w.id,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
btvalues=btvalues.to_json())
|
||||
|
||||
return isbreakthrough, ishard
|
||||
|
||||
@@ -1624,7 +1621,6 @@ def checkduplicates(r, workoutdate, workoutstartdatetime, workoutenddatetime):
|
||||
ws2.append(ww)
|
||||
|
||||
if (len(ws2) != 0):
|
||||
message = "Warning: This workout overlaps with an existing one and was marked as a duplicate"
|
||||
duplicate = True
|
||||
return duplicate
|
||||
|
||||
@@ -1724,7 +1720,7 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
windowsize = 2 * (int(10. / (f))) + 1
|
||||
else: # pragma: no cover
|
||||
windowsize = 1
|
||||
if not 'originalvelo' in row.df:
|
||||
if 'originalvelo' not in row.df:
|
||||
row.df['originalvelo'] = velo
|
||||
|
||||
if windowsize > 3 and windowsize < len(velo):
|
||||
@@ -1861,16 +1857,16 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower',
|
||||
w.team.add(t)
|
||||
|
||||
# put stroke data in database
|
||||
res = dataprep(row.df, id=w.id, bands=True,
|
||||
barchart=True, otwpower=True, empower=True, inboard=inboard)
|
||||
_ = dataprep(row.df, id=w.id, bands=True,
|
||||
barchart=True, otwpower=True, empower=True, inboard=inboard)
|
||||
|
||||
isbreakthrough, ishard = checkbreakthrough(w, r)
|
||||
marker = check_marker(w)
|
||||
result = update_wps(r, mytypes.otwtypes)
|
||||
result = update_wps(r, mytypes.otetypes)
|
||||
_ = check_marker(w)
|
||||
_ = update_wps(r, mytypes.otwtypes)
|
||||
_ = update_wps(r, mytypes.otetypes)
|
||||
|
||||
job = myqueue(queuehigh, handle_calctrimp, w.id, f2,
|
||||
r.ftp, r.sex, r.hrftp, r.max, r.rest)
|
||||
_ = myqueue(queuehigh, handle_calctrimp, w.id, f2,
|
||||
r.ftp, r.sex, r.hrftp, r.max, r.rest)
|
||||
|
||||
return (w.id, message)
|
||||
|
||||
@@ -1914,7 +1910,7 @@ def get_startdate_time_zone(r, row, startdatetime=None):
|
||||
startdatetime = row.rowdatetime
|
||||
|
||||
try:
|
||||
tz = startdatetime.tzinfo
|
||||
_ = startdatetime.tzinfo
|
||||
except AttributeError: # pragma: no cover
|
||||
startdatetime = row.rowdatetime
|
||||
|
||||
@@ -1987,7 +1983,6 @@ def parsenonpainsled(fileformat, f2, summary, startdatetime='', empowerfirmware=
|
||||
|
||||
s = 'Parsenonpainsled, start date time = {startdatetime}'.format(
|
||||
startdatetime=startdatetime,
|
||||
#rowdatetime = row.rowdatetime
|
||||
)
|
||||
dologging('debuglog.log', s)
|
||||
|
||||
@@ -2158,11 +2153,10 @@ def new_workout_from_file(r, f2,
|
||||
uploadoptions['file'] = datafile
|
||||
url = settings.UPLOAD_SERVICE_URL
|
||||
|
||||
job = myqueue(queuehigh,
|
||||
handle_request_post,
|
||||
url,
|
||||
uploadoptions
|
||||
)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_request_post,
|
||||
url,
|
||||
uploadoptions)
|
||||
|
||||
except BadZipFile: # pragma: no cover
|
||||
pass
|
||||
@@ -2227,10 +2221,10 @@ def new_workout_from_file(r, f2,
|
||||
extension = extension2
|
||||
f4 = filename+'a'+extension
|
||||
copyfile(f2, f4)
|
||||
job = myqueue(queuehigh,
|
||||
handle_sendemail_unrecognized,
|
||||
f4,
|
||||
r.user.email)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_unrecognized,
|
||||
f4,
|
||||
r.user.email)
|
||||
|
||||
return (0, message, f2)
|
||||
|
||||
@@ -2377,7 +2371,7 @@ def split_workout(r, parent, splitsecond, splitmode):
|
||||
messages.append(message)
|
||||
ids.append(encoder.encode_hex(id))
|
||||
|
||||
if not 'keep original' in splitmode: # pragma: no cover
|
||||
if 'keep original' not in splitmode: # pragma: no cover
|
||||
if 'keep second' in splitmode or 'keep first' in splitmode:
|
||||
parent.delete()
|
||||
messages.append('Deleted Workout: ' + parent.name)
|
||||
@@ -2448,7 +2442,6 @@ def new_workout_from_df(r, df,
|
||||
|
||||
df.rename(columns=columndict, inplace=True)
|
||||
|
||||
#starttimeunix = mktime(startdatetime.utctimetuple())
|
||||
starttimeunix = arrow.get(startdatetime).timestamp()
|
||||
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
|
||||
|
||||
@@ -2458,15 +2451,13 @@ def new_workout_from_df(r, df,
|
||||
|
||||
row.write_csv(csvfilename, gzip=True)
|
||||
|
||||
# res = df.to_csv(csvfilename+'.gz',index_label='index',
|
||||
# compression='gzip')
|
||||
|
||||
id, message = save_workout_database(csvfilename, r,
|
||||
workouttype=workouttype,
|
||||
boattype=boattype,
|
||||
title=title,
|
||||
workoutsource=workoutsource,
|
||||
notes=notes,
|
||||
summary=summary,
|
||||
oarlength=oarlength,
|
||||
inboard=inboard,
|
||||
makeprivate=makeprivate,
|
||||
@@ -2474,8 +2465,8 @@ def new_workout_from_df(r, df,
|
||||
rpe=rpe,
|
||||
consistencychecks=False)
|
||||
|
||||
job = myqueue(queuehigh, handle_calctrimp, id, csvfilename,
|
||||
r.ftp, r.sex, r.hrftp, r.max, r.rest)
|
||||
_ = myqueue(queuehigh, handle_calctrimp, id, csvfilename,
|
||||
r.ftp, r.sex, r.hrftp, r.max, r.rest)
|
||||
|
||||
return (id, message)
|
||||
|
||||
@@ -2520,7 +2511,7 @@ def delete_strokedata(id):
|
||||
|
||||
def update_strokedata(id, df):
|
||||
delete_strokedata(id)
|
||||
rowdata = dataprep(df, id=id, bands=True, barchart=True, otwpower=True)
|
||||
_ = dataprep(df, id=id, bands=True, barchart=True, otwpower=True)
|
||||
|
||||
# Test that all data are of a numerical time
|
||||
|
||||
@@ -2555,7 +2546,7 @@ def getrowdata_db(id=0, doclean=False, convertnewtons=True,
|
||||
else:
|
||||
row = Workout.objects.get(id=id)
|
||||
|
||||
if checkefficiency == True and not data.empty:
|
||||
if checkefficiency is True and not data.empty:
|
||||
try:
|
||||
if data['efficiency'].mean() == 0 and data['power'].mean() != 0: # pragma: no cover
|
||||
data = add_efficiency(id=id)
|
||||
@@ -2586,15 +2577,13 @@ def getsmallrowdata_db(columns, ids=[], doclean=True, workstrokesonly=True, comp
|
||||
if len(ids) > 1:
|
||||
for id, f in zip(ids, csvfilenames):
|
||||
try:
|
||||
#df = dd.read_parquet(f,columns=columns,engine='pyarrow')
|
||||
df = pd.read_parquet(f, columns=columns)
|
||||
data.append(df)
|
||||
except (OSError, ArrowInvalid, IndexError): # pragma: no cover
|
||||
rowdata, row = getrowdata(id=id)
|
||||
if rowdata and len(rowdata.df):
|
||||
datadf = dataprep(rowdata.df, id=id,
|
||||
bands=True, otwpower=True, barchart=True)
|
||||
# df = dd.read_parquet(f,columns=columns,engine='pyarrow')
|
||||
_ = dataprep(rowdata.df, id=id,
|
||||
bands=True, otwpower=True, barchart=True)
|
||||
df = pd.read_parquet(f, columns=columns)
|
||||
data.append(df)
|
||||
|
||||
@@ -2649,7 +2638,6 @@ def getrowdata(id=0):
|
||||
# get user
|
||||
|
||||
r = row.user
|
||||
u = r.user
|
||||
|
||||
rr = rrower(hrmax=r.max, hrut2=r.ut2,
|
||||
hrut1=r.ut1, hrat=r.at,
|
||||
@@ -2677,8 +2665,8 @@ def prepmultipledata(ids, verbose=False): # pragma: no cover
|
||||
if verbose:
|
||||
print(id)
|
||||
if rowdata and len(rowdata.df):
|
||||
data = dataprep(rowdata.df, id=id, bands=True,
|
||||
barchart=True, otwpower=True)
|
||||
_ = dataprep(rowdata.df, id=id, bands=True,
|
||||
barchart=True, otwpower=True)
|
||||
return ids
|
||||
|
||||
# Read a set of columns for a set of workout ids, returns data as a
|
||||
@@ -2707,8 +2695,8 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
|
||||
except OSError:
|
||||
rowdata, row = getrowdata(id=ids[0])
|
||||
if rowdata and len(rowdata.df):
|
||||
datadf = dataprep(
|
||||
rowdata.df, id=ids[0], bands=True, otwpower=True, barchart=True)
|
||||
_ = dataprep(rowdata.df,
|
||||
id=ids[0], bands=True, otwpower=True, barchart=True)
|
||||
df = pd.read_parquet(filename, columns=columns)
|
||||
else:
|
||||
data = []
|
||||
@@ -2721,8 +2709,8 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
|
||||
except (OSError, IndexError, ArrowInvalid):
|
||||
rowdata, row = getrowdata(id=id)
|
||||
if rowdata and len(rowdata.df): # pragma: no cover
|
||||
datadf = dataprep(rowdata.df, id=id,
|
||||
bands=True, otwpower=True, barchart=True)
|
||||
_ = dataprep(rowdata.df, id=id,
|
||||
bands=True, otwpower=True, barchart=True)
|
||||
df = pd.read_parquet(f, columns=columns)
|
||||
data.append(df)
|
||||
|
||||
@@ -2753,8 +2741,8 @@ def read_cols_df_sql(ids, columns, convertnewtons=True):
|
||||
|
||||
|
||||
def initiate_cp(r):
|
||||
success = update_rolling_cp(r, otwtypes, 'water')
|
||||
success = update_rolling_cp(r, otetypes, 'erg')
|
||||
_ = update_rolling_cp(r, otwtypes, 'water')
|
||||
_ = update_rolling_cp(r, otetypes, 'erg')
|
||||
|
||||
# Read stroke data from the DB for a Workout ID. Returns a pandas dataframe
|
||||
|
||||
@@ -2784,9 +2772,6 @@ def read_df_sql(id):
|
||||
|
||||
|
||||
def datafusion(id1, id2, columns, offset):
|
||||
workout1 = Workout.objects.get(id=id1)
|
||||
workout2 = Workout.objects.get(id=id2)
|
||||
|
||||
df1, w1 = getrowdata_db(id=id1)
|
||||
df1 = df1.drop([ # 'cumdist',
|
||||
'hr_ut2',
|
||||
@@ -2821,7 +2806,7 @@ def datafusion(id1, id2, columns, offset):
|
||||
keep1.pop(c)
|
||||
|
||||
for c in df1.columns:
|
||||
if not c in keep1:
|
||||
if c not in keep1:
|
||||
df1 = df1.drop(c, 1, errors='ignore')
|
||||
|
||||
df = pd.concat([df1, df2], ignore_index=True)
|
||||
@@ -2846,7 +2831,6 @@ def fix_newtons(id=0, limit=3000): # pragma: no cover
|
||||
# rowdata,row = getrowdata_db(id=id,doclean=False,convertnewtons=False)
|
||||
rowdata = getsmallrowdata_db(['peakforce'], ids=[id], doclean=False)
|
||||
try:
|
||||
#avgforce = rowdata['averageforce']
|
||||
peakforce = rowdata['peakforce']
|
||||
if peakforce.mean() > limit:
|
||||
w = Workout.objects.get(id=id)
|
||||
@@ -2860,7 +2844,7 @@ def fix_newtons(id=0, limit=3000): # pragma: no cover
|
||||
|
||||
def remove_invalid_columns(df): # pragma: no cover
|
||||
for c in df.columns:
|
||||
if not c in allowedcolumns:
|
||||
if c not in allowedcolumns:
|
||||
df.drop(labels=c, axis=1, inplace=True)
|
||||
|
||||
return df
|
||||
@@ -2907,7 +2891,6 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
if rowdatadf.empty:
|
||||
return 0
|
||||
|
||||
#rowdatadf.set_index([range(len(rowdatadf))], inplace=True)
|
||||
t = rowdatadf.loc[:, 'TimeStamp (sec)']
|
||||
t = pd.Series(t - rowdatadf.loc[:, 'TimeStamp (sec)'].iloc[0])
|
||||
|
||||
@@ -2981,7 +2964,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
if forceunit == 'lbs':
|
||||
driveenergy = drivelength * averageforce * lbstoN
|
||||
else:
|
||||
drivenergy = drivelength * averageforce
|
||||
driveenergy = drivelength * averageforce
|
||||
|
||||
if forceunit == 'lbs':
|
||||
averageforce *= lbstoN
|
||||
@@ -3034,7 +3017,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
data['hr_bottom'] = 0.0 * data['hr']
|
||||
|
||||
try:
|
||||
tel = rowdatadf.loc[:, ' ElapsedTime (sec)']
|
||||
_ = rowdatadf.loc[:, ' ElapsedTime (sec)']
|
||||
except KeyError: # pragma: no cover
|
||||
rowdatadf[' ElapsedTime (sec)'] = rowdatadf['TimeStamp (sec)']
|
||||
|
||||
@@ -3218,7 +3201,7 @@ def workout_trimp(w, reset=False):
|
||||
w.maxhr = maxhr
|
||||
w.save()
|
||||
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_calctrimp,
|
||||
w.id,
|
||||
@@ -3246,7 +3229,7 @@ def workout_rscore(w, reset=False):
|
||||
r.hrftp = int(hrftp)
|
||||
r.save()
|
||||
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_calctrimp,
|
||||
w.id,
|
||||
@@ -3274,7 +3257,7 @@ def workout_normv(w, pp=4.0):
|
||||
r.hrftp = int(hrftp)
|
||||
r.save()
|
||||
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_calctrimp,
|
||||
w.id,
|
||||
|
||||
+18
-19
@@ -2,6 +2,7 @@ from rowers.utils import totaltime_sec_to_string
|
||||
from rowers.metrics import dtypes
|
||||
import datetime
|
||||
from scipy.signal import savgol_filter
|
||||
import os
|
||||
|
||||
# This is Data prep used for testing purposes (no Django environment)
|
||||
# Uses the debug SQLite database for stroke data
|
||||
@@ -35,6 +36,12 @@ from rowers.utils import lbstoN
|
||||
import pytz
|
||||
from timezonefinder import TimezoneFinder
|
||||
|
||||
from rowingdata import (
|
||||
RowProParser, TCXParser, MysteryParser, RowPerfectParser,
|
||||
ErgDataParser, CoxMateParser, BoatCoachAdvancedParser, BoatCoachOTWParser,
|
||||
BoatCoachParser, painsledDesktopParser, SpeedCoach2Parser, speedcoachParser,
|
||||
ErgStickParser, FITParser, fitsummarydata
|
||||
)
|
||||
|
||||
try:
|
||||
user = DATABASES['default']['USER']
|
||||
@@ -171,14 +178,12 @@ def create_c2_stroke_data_db(
|
||||
spm = 20*np.zeros(nr_strokes)
|
||||
|
||||
try:
|
||||
step = totalseconds/float(nr_strokes)
|
||||
_ = totalseconds/float(nr_strokes)
|
||||
except ZeroDivisionError:
|
||||
return 0
|
||||
|
||||
elapsed = np.arange(nr_strokes)*totalseconds/(float(nr_strokes-1))
|
||||
|
||||
dstep = distance/float(nr_strokes)
|
||||
|
||||
d = np.arange(nr_strokes)*distance/(float(nr_strokes-1))
|
||||
|
||||
unixtime = starttimeunix + elapsed
|
||||
@@ -215,12 +220,9 @@ def create_c2_stroke_data_db(
|
||||
'cum_dist': d
|
||||
})
|
||||
|
||||
timestr = strftime("%Y%m%d-%H%M%S")
|
||||
|
||||
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
|
||||
|
||||
res = df.to_csv(csvfilename, index_label='index',
|
||||
compression='gzip')
|
||||
_ = df.to_csv(csvfilename, index_label='index', compression='gzip')
|
||||
|
||||
data = dataprep(df, id=workoutid, bands=False, debug=debug)
|
||||
|
||||
@@ -300,8 +302,6 @@ def add_c2_stroke_data_db(strokedata, workoutid, starttimeunix, csvfilename,
|
||||
|
||||
df.sort_values(by='TimeStamp (sec)', ascending=True)
|
||||
|
||||
timestr = strftime("%Y%m%d-%H%M%S")
|
||||
|
||||
# Create CSV file name and save data to CSV file
|
||||
|
||||
res = df.to_csv(csvfilename, index_label='index',
|
||||
@@ -447,8 +447,7 @@ def update_empower(id, inboard, oarlength, boattype, df, f1, debug=False): # pr
|
||||
if debug: # pragma: no cover
|
||||
print("not updated ", id)
|
||||
|
||||
rowdata = dataprep(df, id=id, bands=True, barchart=True, otwpower=True,
|
||||
debug=debug)
|
||||
_ = dataprep(df, id=id, bands=True, barchart=True, otwpower=True, debug=debug)
|
||||
|
||||
row = rrdata(df=df)
|
||||
row.write_csv(f1, gzip=True)
|
||||
@@ -511,7 +510,7 @@ def update_workout_field_sql(workoutid, fieldname, value, debug=False):
|
||||
table, fieldname, value, workoutid)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
_ = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
@@ -527,7 +526,7 @@ def update_c2id_sql(id, c2id): # pragma: no cover
|
||||
table, c2id, id)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
result = conn.execute(query)
|
||||
_ = conn.execute(query)
|
||||
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
@@ -588,7 +587,7 @@ def getcpdata_sql(rower_id, table='cpdata', debug=False): # pragma: no cover
|
||||
rower_id=rower_id,
|
||||
table=table,
|
||||
))
|
||||
connection = engine.raw_connection()
|
||||
_ = engine.raw_connection()
|
||||
df = pd.read_sql_query(query, engine)
|
||||
|
||||
return df
|
||||
@@ -606,7 +605,7 @@ def deletecpdata_sql(rower_id, table='cpdata', debug=False): # pragma: no cover
|
||||
))
|
||||
with engine.connect() as conn, conn.begin():
|
||||
try:
|
||||
result = conn.execute(query)
|
||||
_ = conn.execute(query)
|
||||
except: # pragma: no cover
|
||||
print("Database locked")
|
||||
conn.close()
|
||||
@@ -627,7 +626,7 @@ def delete_agegroup_db(age, sex, weightcategory, debug=False):
|
||||
))
|
||||
with engine.connect() as conn, conn.begin():
|
||||
try:
|
||||
result = conn.execute(query)
|
||||
_ = conn.execute(query)
|
||||
except: # pragma: no cover
|
||||
print("Database locked")
|
||||
conn.close()
|
||||
@@ -687,7 +686,7 @@ def updatecpdata_sql(rower_id, delta, cp, table='cpdata', distance=pd.Series([],
|
||||
else:
|
||||
engine = create_engine(database_url, echo=False)
|
||||
|
||||
with engine.connect() as conn, conn.begin():
|
||||
with engine.connect() as conn, conn.begin():
|
||||
df.to_sql(table, engine, if_exists='append', index=False)
|
||||
conn.close()
|
||||
engine.dispose()
|
||||
@@ -818,7 +817,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
if forceunit == 'lbs':
|
||||
driveenergy = drivelength*averageforce*lbstoN
|
||||
else: # pragma: no cover
|
||||
drivenergy = drivelength*averageforce
|
||||
driveenergy = drivelength*averageforce
|
||||
|
||||
distance = rowdatadf.loc[:, 'cum_dist']
|
||||
|
||||
@@ -865,7 +864,7 @@ def dataprep(rowdatadf, id=0, bands=True, barchart=True, otwpower=True,
|
||||
data['hr_bottom'] = 0.0*data['hr']
|
||||
|
||||
try:
|
||||
tel = rowdatadf.loc[:, ' ElapsedTime (sec)']
|
||||
_ = rowdatadf.loc[:, ' ElapsedTime (sec)']
|
||||
except KeyError: # pragma: no cover
|
||||
rowdatadf[' ElapsedTime (sec)'] = rowdatadf['TimeStamp (sec)']
|
||||
|
||||
|
||||
+12
-16
@@ -6,7 +6,6 @@ from scipy import optimize
|
||||
|
||||
from rowers.mytypes import otwtypes, otetypes, rowtypes
|
||||
|
||||
#p0 = [500,350,10,8000]
|
||||
p0 = [190, 200, 33, 16000]
|
||||
|
||||
# RPE to TSS
|
||||
@@ -73,10 +72,12 @@ def updatecp(delta, cpvalues, r, workouttype='water'): # pragma: no cover
|
||||
|
||||
def cpfit(powerdf, fraclimit=0.0001, nmax=1000):
|
||||
# Fit the data to thee parameter CP model
|
||||
def fitfunc(pars, x): return abs(
|
||||
pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
|
||||
def fitfunc(pars, x):
|
||||
return abs(
|
||||
pars[0])/(1+(x/abs(pars[2]))) + abs(pars[1])/(1+(x/abs(pars[3])))
|
||||
|
||||
def errfunc(pars, x, y): return fitfunc(pars, x)-y
|
||||
def errfunc(pars, x, y):
|
||||
return fitfunc(pars, x)-y
|
||||
|
||||
p1 = p0
|
||||
|
||||
@@ -235,8 +236,6 @@ def getcp_new(dfgrouped, logarr): # pragma: no cover
|
||||
restime = np.array(restime)
|
||||
power = np.array(power)
|
||||
|
||||
#power[0] = power[1]
|
||||
|
||||
cpvalues = griddata(restime, power,
|
||||
logarr, method='linear', fill_value=0)
|
||||
|
||||
@@ -264,7 +263,6 @@ def getcp(dfgrouped, logarr):
|
||||
delta = []
|
||||
cpvalue = []
|
||||
avgpower = {}
|
||||
#avgpower[0] = 0
|
||||
|
||||
for id, group in dfgrouped:
|
||||
tt = group['time'].copy()
|
||||
@@ -273,7 +271,7 @@ def getcp(dfgrouped, logarr):
|
||||
# Remove data where PM is repeating final power value
|
||||
# of an interval during the rest
|
||||
rolling_std = ww.rolling(window=4).std()
|
||||
deltas = tt.diff()
|
||||
# deltas = tt.diff()
|
||||
|
||||
mask = rolling_std == 0
|
||||
ww.loc[mask] = 0
|
||||
@@ -281,7 +279,7 @@ def getcp(dfgrouped, logarr):
|
||||
mask = ww > 2000
|
||||
ww.loc[mask] = 0
|
||||
|
||||
tmax = tt.max()
|
||||
# tmax = tt.max()
|
||||
|
||||
try:
|
||||
avgpower[id] = int(ww.mean())
|
||||
@@ -389,13 +387,13 @@ def getfastest(df, thevalue, mode='distance'):
|
||||
dd = pd.Series(dd, dtype='float')
|
||||
|
||||
G = pd.concat([pd.Series([0]), dd])
|
||||
T = pd.concat([pd.Series([0]), dd])
|
||||
h = np.mgrid[0:len(tt)+1:1, 0:len(tt)+1:1]
|
||||
distances = pd.DataFrame(h[1]-h[0])
|
||||
# T = pd.concat([pd.Series([0]), dd])
|
||||
# h = np.mgrid[0:len(tt)+1:1, 0:len(tt)+1:1]
|
||||
# distances = pd.DataFrame(h[1]-h[0])
|
||||
ones = 1+np.zeros(len(G))
|
||||
Ghor = np.outer(ones, G)
|
||||
Thor = np.outer(ones, T)
|
||||
Tver = np.outer(T, ones)
|
||||
# Thor = np.outer(ones, T)
|
||||
# Tver = np.outer(T, ones)
|
||||
Gver = np.outer(G, ones)
|
||||
Gdif = Ghor-Gver
|
||||
Gdif = np.tril(Gdif.T).T
|
||||
@@ -428,8 +426,6 @@ def getfastest(df, thevalue, mode='distance'):
|
||||
# if restime[i]<thevalue*60*1000:
|
||||
# print(i,restime[i],distance[i],60*1000*thevalue)
|
||||
|
||||
d2 = 0
|
||||
|
||||
if mode == 'distance':
|
||||
duration = griddata(distance, restime, [
|
||||
thevalue], method='linear', rescale=True)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
from django.contrib.auth.decorators import login_required, user_passes_test
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.urls import reverse
|
||||
|
||||
from django.http import HttpResponseRedirect
|
||||
|
||||
+6
-6
@@ -20,7 +20,7 @@ import pytz
|
||||
import iso8601
|
||||
|
||||
from matplotlib.backends.backend_agg import FigureCanvas
|
||||
#from matplotlib.backends.backend_cairo import FigureCanvasCairo as FigureCanvas
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
from rowsandall_app.settings import SITE_URL
|
||||
@@ -130,10 +130,10 @@ def send_confirm(user, name, link, options): # pragma: no cover
|
||||
fullemail = user.email
|
||||
subject = 'New Workout Added: '+name
|
||||
|
||||
res = send_template_email('Rowsandall <info@rowsandall.com>',
|
||||
[fullemail],
|
||||
subject, 'confirmemail.html',
|
||||
d
|
||||
)
|
||||
_ = send_template_email('Rowsandall <info@rowsandall.com>',
|
||||
[fullemail],
|
||||
subject, 'confirmemail.html',
|
||||
d
|
||||
)
|
||||
|
||||
return 1
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ def create_invoice(rower, amount, braintreeid, dosend=True,
|
||||
if res.status_code not in [200, 201]: # pragma: no cover
|
||||
return 0
|
||||
|
||||
url = res.json()['url']
|
||||
# url = res.json()['url']
|
||||
id = res.json()['id']
|
||||
|
||||
urlpay = 'https://app.fakturoid.cz/api/v2/accounts/{slug}/invoices/{id}/fire.json?event=pay'.format(
|
||||
|
||||
+15
-26
@@ -1,4 +1,3 @@
|
||||
from rowers.models import VirtualRace, GeoCourse
|
||||
from rowers.utils import rankingdistances, rankingdurations
|
||||
from rowers.utils import (
|
||||
workflowleftpanel, workflowmiddlepanel,
|
||||
@@ -18,7 +17,7 @@ from django.contrib.auth.forms import UserCreationForm
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.admin.widgets import AdminDateWidget
|
||||
from django.forms.widgets import SelectDateWidget, HiddenInput
|
||||
#from django.forms.extras.widgets import SelectDateWidget
|
||||
|
||||
from django.utils import timezone, translation
|
||||
from django.forms import ModelForm, Select
|
||||
import rowers.dataprep as dataprep
|
||||
@@ -573,11 +572,17 @@ class UploadOptionsForm(forms.Form):
|
||||
choices3 = [(0, '---')]
|
||||
|
||||
noregistrations = []
|
||||
for ra in VirtualRace.objects.filter(registration_closure__gt=timezone.now(), sessiontype='race'): # pragma: no cover
|
||||
for ra in VirtualRace.objects.filter(
|
||||
registration_closure__gt=timezone.now(),
|
||||
sessiontype='race'
|
||||
): # pragma: no cover
|
||||
rs = VirtualRaceResult.objects.filter(race=ra, userid=r.id)
|
||||
if rs.count() == 0:
|
||||
noregistrations.append((-ra.id, ra.name))
|
||||
for ra in VirtualRace.objects.filter(registration_closure__gt=timezone.now(), sessiontype='indoorrace'): # pragma: no cover
|
||||
for ra in VirtualRace.objects.filter(
|
||||
registration_closure__gt=timezone.now(),
|
||||
sessiontype='indoorrace'
|
||||
): # pragma: no cover
|
||||
rs = IndoorVirtualRaceResult.objects.filter(race=ra, userid=r.id)
|
||||
if rs.count() == 0:
|
||||
noregistrations.append((-ra.id, ra.name))
|
||||
@@ -1055,20 +1060,6 @@ class RegistrationFormSex(RegistrationFormUniqueEmail):
|
||||
adaptiveclass = forms.ChoiceField(label='Adaptive Classification',
|
||||
choices=adaptivecategories, initial='None', required=False)
|
||||
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# self.fields['sex'].initial = 'not specified'
|
||||
|
||||
# Time field supporting microseconds. Not used, I believe.
|
||||
|
||||
|
||||
class MyTimeField(forms.TimeField):
|
||||
|
||||
def __init__(self, *args, **kwargs): # pragma: no cover
|
||||
super(MyTimeField, self).__init__(*args, **kwargs)
|
||||
supports_microseconds = True
|
||||
|
||||
# Form used to automatically define intervals by pace or power
|
||||
|
||||
|
||||
class PowerIntervalUpdateForm(forms.Form):
|
||||
selectorchoices = (
|
||||
@@ -1847,14 +1838,13 @@ class StravaChartForm(forms.Form):
|
||||
choices=yaxchoices2, label='Fourth Chart', required=True)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
extrametrics = kwargs.pop('extrametrics', [])
|
||||
super(StravaChartForm, self).__init__(*args, **kwargs)
|
||||
|
||||
rower = Rower.objects.get(user=request.user)
|
||||
|
||||
axchoicespro = (
|
||||
('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
|
||||
)
|
||||
# axchoicespro = (
|
||||
# ('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
|
||||
# )
|
||||
|
||||
axchoicesbasicx = []
|
||||
axchoicesbasicy = []
|
||||
@@ -1889,14 +1879,13 @@ class FlexAxesForm(forms.Form):
|
||||
choices=yaxchoices2, label='Right Axis', required=True)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
extrametrics = kwargs.pop('extrametrics', [])
|
||||
super(FlexAxesForm, self).__init__(*args, **kwargs)
|
||||
|
||||
rower = Rower.objects.get(user=request.user)
|
||||
|
||||
axchoicespro = (
|
||||
('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
|
||||
)
|
||||
# axchoicespro = (
|
||||
# ('', ax[1]) if ax[4] == 'pro' and ax[0] else (ax[0], ax[1]) for ax in axes
|
||||
# )
|
||||
|
||||
axchoicesbasicx = []
|
||||
axchoicesbasicy = []
|
||||
|
||||
+24
-40
@@ -11,7 +11,7 @@ import requests
|
||||
from requests import Session, Request
|
||||
from requests_oauthlib import OAuth1, OAuth1Session
|
||||
from requests_oauthlib.oauth1_session import TokenRequestDenied
|
||||
from requests import Request, Session
|
||||
|
||||
import rowers.mytypes as mytypes
|
||||
from rowers.mytypes import otwtypes
|
||||
from rowers.rower_rules import is_workout_user, ispromember
|
||||
@@ -35,13 +35,6 @@ from rowsandall_app.settings import (
|
||||
|
||||
from pytz import timezone as tz, utc
|
||||
|
||||
# You must initialize logging, otherwise you'll not see debug output.
|
||||
# logging.basicConfig()
|
||||
# logging.getLogger().setLevel(logging.DEBUG)
|
||||
#requests_log = logging.getLogger("requests.packages.urllib3")
|
||||
# requests_log.setLevel(logging.DEBUG)
|
||||
#requests_log.propagate = True
|
||||
|
||||
|
||||
from rowers.tasks import handle_get_garmin_file
|
||||
import django_rq
|
||||
@@ -100,18 +93,15 @@ repeattypes = {
|
||||
"RepeatUntilDistance": "REPEAT_UNTIL_TIME",
|
||||
"RepeatUntilCalories": "REPEAT_UNTIL_CALORIES",
|
||||
"RepeatUntilHrLessThan": "REPEAT_UNTIL_HR_LESS_THAN",
|
||||
"RepeatUntilHrGreaterThan": "REPEAT_UNTIL_HR_GREATER_THAN",
|
||||
"RepeatUntilPowerLessThan": "REPEAT_UNTIL_POWER_LESS_THAN",
|
||||
"RepeatUntilHrGreaterThan": "REPEAT_UNTIL_HR_GREATER_THAN",
|
||||
"RepeatUntilPowerLessThan": "REPEAT_UNTIL_POWER_LESS_THAN",
|
||||
"RepeatUntilPowerGreaterThan": "REPEAT_UNTIL_POWER_GREATER_THAN",
|
||||
"RepeatUntilPowerLapLessThan": "REPEAT_UNTIL_POWER_LAP_LESS_THAN",
|
||||
"RepeatUntilPowerLapLessThan": "REPEAT_UNTIL_POWER_LAP_LESS_THAN",
|
||||
"RepeatUntilPowerLapGreaterThan": "REPEAT_UNTIL_POWER_LAP_GREATER_THAN",
|
||||
}
|
||||
|
||||
|
||||
def garmin_authorize(): # pragma: no cover
|
||||
redirect_uri = oauth_data['redirect_uri']
|
||||
client_secret = oauth_data['client_secret']
|
||||
client_id = oauth_data['client_id']
|
||||
base_uri = oauth_data['base_url']
|
||||
|
||||
garmin = OAuth1Session(oauth_data['client_id'],
|
||||
@@ -133,7 +123,7 @@ def garmin_processcallback(redirect_response, resource_owner_key, resource_owner
|
||||
oauth_response = garmin.parse_authorization_response(redirect_response)
|
||||
|
||||
verifier = oauth_response.get('oauth_verifier')
|
||||
token = oauth_response.get('oauth_token')
|
||||
# token = oauth_response.get('oauth_token')
|
||||
access_token_url = 'https://connectapi.garmin.com/oauth-service/oauth/access_token'
|
||||
|
||||
# Using OAuth1Session
|
||||
@@ -155,7 +145,7 @@ def garmin_processcallback(redirect_response, resource_owner_key, resource_owner
|
||||
|
||||
def garmin_open(user): # pragma: no cover
|
||||
r = Rower.objects.get(user=user)
|
||||
token = Rower.garmintoken
|
||||
token = r.garmintoken
|
||||
|
||||
if (token == '') or (token is None):
|
||||
raise NoTokenError("User has no garmin token")
|
||||
@@ -191,7 +181,8 @@ def get_garmin_workout_list(user): # pragma: no cover
|
||||
resource_owner_secret=r.garminrefreshtoken,
|
||||
)
|
||||
|
||||
url = 'https://healthapi.garmin.com/wellness-api/rest/activities?uploadStartTimeInSeconds=1593113760&uploadEndTimeInSeconds=1593279360'
|
||||
url = 'https://healthapi.garmin.com/wellness-api/rest/' \
|
||||
'activities?uploadStartTimeInSeconds=1593113760&uploadEndTimeInSeconds=1593279360'
|
||||
|
||||
result = garmin.get(url)
|
||||
|
||||
@@ -218,7 +209,7 @@ def step_to_garmin(step, order=0):
|
||||
intensity = 'INTERVAL'
|
||||
except KeyError:
|
||||
intensity = None
|
||||
#durationvaluetype = ''
|
||||
# durationvaluetype = ''
|
||||
if durationtype == 'Time':
|
||||
durationtype = 'TIME'
|
||||
durationvalue = int(durationvalue/1000.)
|
||||
@@ -272,11 +263,11 @@ def step_to_garmin(step, order=0):
|
||||
|
||||
if targetType is not None and targetType.lower() == "power":
|
||||
targetType = 'POWER'
|
||||
if targetValue is not None and targetValue <= 1000:
|
||||
targetValueType = 'PERCENT' # pragma: no cover
|
||||
else:
|
||||
targetValueType = None
|
||||
targetValue -= 1000
|
||||
# if targetValue is not None and targetValue <= 1000:
|
||||
# targetValueType = 'PERCENT' # pragma: no cover
|
||||
# else:
|
||||
# # targetValueType = None
|
||||
# targetValue -= 1000
|
||||
|
||||
try:
|
||||
targetValueLow = step['dict']['targetValueLow']
|
||||
@@ -285,8 +276,8 @@ def step_to_garmin(step, order=0):
|
||||
targetValue = None
|
||||
elif targetValueLow == 0: # pragma: no cover
|
||||
targetValueLow = None
|
||||
elif targetValueLow <= 1000 and targetType == 'POWER': # pragma: no cover
|
||||
targetValueType = 'PERCENT'
|
||||
# elif targetValueLow <= 1000 and targetType == 'POWER': # pragma: no cover
|
||||
# targetValueType = 'PERCENT'
|
||||
elif targetValueLow > 1000 and targetType == 'POWER': # pragma: no cover
|
||||
targetValueLow -= 1000
|
||||
except KeyError:
|
||||
@@ -296,8 +287,8 @@ def step_to_garmin(step, order=0):
|
||||
if targetValue is not None and targetValue > 0 and targetValueHigh == 0: # pragma: no cover
|
||||
targetValueHigh = targetValue
|
||||
targetValue = 0
|
||||
elif targetValueHigh <= 1000 and targetType == 'POWER': # pragma: no cover
|
||||
targetValueType = 'PERCENT'
|
||||
# elif targetValueHigh <= 1000 and targetType == 'POWER': # pragma: no cover
|
||||
# targetValueType = 'PERCENT'
|
||||
elif targetValueHigh > 1000 and targetType == 'POWER': # pragma: no cover
|
||||
targetValueHigh -= 1000
|
||||
elif targetValueHigh == 0: # pragma: no cover
|
||||
@@ -477,12 +468,6 @@ def garmin_getworkout(garminid, r, activity):
|
||||
distance = activity['distanceInMeters']
|
||||
except KeyError:
|
||||
distance = 0
|
||||
try:
|
||||
averagehr = activity['averageHeartRateInBeatsPerMinute']
|
||||
maxhr = activity['maxHeartRateInBeatsPerMinute']
|
||||
except KeyError: # pragma: no cover
|
||||
averagehr = 0
|
||||
maxhr = 0
|
||||
try:
|
||||
w = Workout.objects.get(uploadedtogarmin=garminid)
|
||||
except Workout.DoesNotExist:
|
||||
@@ -494,8 +479,8 @@ def garmin_getworkout(garminid, r, activity):
|
||||
|
||||
utc_offset = datetime.timedelta(seconds=offset)
|
||||
now = datetime.datetime.now(pytz.utc)
|
||||
zones = [tz.zone for tz in map(pytz.timezone, pytz.all_timezones_set)
|
||||
if now.astimezone(tz).utcoffset() == utc_offset]
|
||||
zones = [ttz.zone for ttz in map(
|
||||
pytz.timezone, pytz.all_timezones_set) if now.astimezone(ttz).utcoffset() == utc_offset]
|
||||
if r.defaulttimezone in zones: # pragma: no cover
|
||||
thetimezone = r.defaulttimezone
|
||||
elif len(zones):
|
||||
@@ -509,8 +494,7 @@ def garmin_getworkout(garminid, r, activity):
|
||||
day=startdatetime.day,
|
||||
hour=startdatetime.hour,
|
||||
minute=startdatetime.minute,
|
||||
second=startdatetime.second,
|
||||
).astimezone(pytz.timezone(thetimezone))
|
||||
second=startdatetime.second,).astimezone(pytz.timezone(thetimezone))
|
||||
|
||||
w.startdatetime = startdatetime
|
||||
w.starttime = w.startdatetime.time()
|
||||
@@ -557,12 +541,12 @@ def garmin_workouts_from_details(data):
|
||||
df[' AverageBoatSpeed (m/s)'] = 0
|
||||
df[' Stroke500mPace (sec/500m)'] = pace
|
||||
try:
|
||||
spm = df[' Cadence (stokes/min)']
|
||||
_ = df[' Cadence (stokes/min)']
|
||||
except KeyError:
|
||||
df[' Cadence (stokes/min)'] = 0
|
||||
df['cum_dist'] = df[' Horizontal (meters)']
|
||||
try:
|
||||
power = df[' Power (watts)']
|
||||
_ = df[' Power (watts)']
|
||||
except KeyError:
|
||||
df[' Power (watts)'] = 0
|
||||
df[' AverageDriveForce (lbs)'] = 0
|
||||
@@ -591,7 +575,7 @@ def garmin_workouts_from_summaries(activities):
|
||||
try:
|
||||
r = Rower.objects.get(garmintoken=garmintoken)
|
||||
id = activity['summaryId']
|
||||
w = garmin_getworkout(id, r, activity)
|
||||
_ = garmin_getworkout(id, r, activity)
|
||||
except Rower.DoesNotExist: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
+7
-17
@@ -70,10 +70,6 @@ def splitstdata(lijst):
|
||||
def imports_open(user, oauth_data):
|
||||
r = Rower.objects.get(user=user)
|
||||
token = getattr(r, oauth_data['tokenname'])
|
||||
try:
|
||||
refreshtoken = getattr(r, oauth_data['refreshtokenname'])
|
||||
except (TypeError, AttributeError, KeyError): # pragma: no cover
|
||||
refreshtoken = None
|
||||
|
||||
try:
|
||||
tokenexpirydate = getattr(r, oauth_data['expirydatename'])
|
||||
@@ -81,7 +77,6 @@ def imports_open(user, oauth_data):
|
||||
tokenexpirydate = None
|
||||
|
||||
if (token == '') or (token is None):
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
raise NoTokenError("User has no token")
|
||||
else:
|
||||
tokenname = oauth_data['tokenname']
|
||||
@@ -109,10 +104,10 @@ def imports_open(user, oauth_data):
|
||||
|
||||
# Refresh token using refresh token
|
||||
def imports_do_refresh_token(refreshtoken, oauth_data, access_token=''):
|
||||
client_auth = requests.auth.HTTPBasicAuth(
|
||||
oauth_data['client_id'],
|
||||
oauth_data['client_secret']
|
||||
)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(
|
||||
# oauth_data['client_id'],
|
||||
# oauth_data['client_secret']
|
||||
# )
|
||||
|
||||
post_data = {"grant_type": "refresh_token",
|
||||
"client_secret": oauth_data['client_secret'],
|
||||
@@ -127,8 +122,6 @@ def imports_do_refresh_token(refreshtoken, oauth_data, access_token=''):
|
||||
if 'grant_type' in oauth_data:
|
||||
if oauth_data['grant_type']:
|
||||
post_data['grant_type'] = oauth_data['grant_type']
|
||||
else: # pragma: no cover
|
||||
grant_type = post_data.pop('grant_type', None)
|
||||
|
||||
if oauth_data['bearer_auth']:
|
||||
headers['authorization'] = 'Bearer %s' % access_token
|
||||
@@ -192,9 +185,9 @@ def imports_get_token(
|
||||
client_id = oauth_data['client_id']
|
||||
base_uri = oauth_data['base_url']
|
||||
|
||||
client_auth = requests.auth.HTTPBasicAuth(
|
||||
client_id, client_secret
|
||||
)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(
|
||||
# client_id, client_secret
|
||||
# )
|
||||
|
||||
post_data = {"grant_type": "authorization_code",
|
||||
"code": code,
|
||||
@@ -216,8 +209,6 @@ def imports_get_token(
|
||||
post_data['grant_type'] = oauth_data['grant_type']
|
||||
if 'strava' in oauth_data['autorization_uri']:
|
||||
post_data['grant_type'] = "authorization_code"
|
||||
else: # pragma: no cover
|
||||
grant_type = post_data.pop('grant_type', None)
|
||||
|
||||
if 'json' in oauth_data['content_type']:
|
||||
response = requests.post(
|
||||
@@ -268,7 +259,6 @@ def imports_make_authorization_url(oauth_data): # pragma: no cover
|
||||
"scope": oauth_data['scope'],
|
||||
"state": state}
|
||||
|
||||
import urllib
|
||||
url = oauth_data['authorizaton_uri']+urllib.parse.urlencode(params)
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
+57
-304
File diff suppressed because it is too large
Load Diff
+2
-5
@@ -14,7 +14,6 @@ redis_connection = StrictRedis()
|
||||
|
||||
|
||||
def getvalue(data): # pragma: no cover
|
||||
perc = 0
|
||||
total = 1
|
||||
done = 0
|
||||
id = 0
|
||||
@@ -43,8 +42,7 @@ def longtask(aantal, jobid=None, debug=False,
|
||||
if counter > 10:
|
||||
counter = 0
|
||||
if debug:
|
||||
progress = 100.*i/aantal
|
||||
if jobid != None:
|
||||
if jobid is not None:
|
||||
redis_connection.publish(channel, json.dumps(
|
||||
{
|
||||
'done': i,
|
||||
@@ -60,7 +58,6 @@ def longtask(aantal, jobid=None, debug=False,
|
||||
def longtask2(aantal, jobid=None, debug=False, secret=''): # pragma: no cover
|
||||
counter = 0
|
||||
|
||||
channel = 'tasks'
|
||||
for i in range(aantal):
|
||||
time.sleep(1)
|
||||
counter += 1
|
||||
@@ -69,7 +66,7 @@ def longtask2(aantal, jobid=None, debug=False, secret=''): # pragma: no cover
|
||||
progress = int(100.*i/aantal)
|
||||
if debug:
|
||||
print(progress)
|
||||
if jobid != None:
|
||||
if jobid is not None:
|
||||
if debug:
|
||||
url = SITE_URL_DEV
|
||||
else:
|
||||
|
||||
@@ -7,20 +7,22 @@ import arrow
|
||||
from django.utils import timezone
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from rowers.models import Rower,Workout
|
||||
from rowers.models import Rower, Workout
|
||||
import re
|
||||
from django.db.models import Q
|
||||
from rowers.dataprep import join_workouts
|
||||
|
||||
|
||||
def name_short(name):
|
||||
expr = '(.*)\s.*\(\d+\)'
|
||||
match = re.findall(expr,name)
|
||||
match = re.findall(expr, name)
|
||||
|
||||
if match:
|
||||
return match[0]
|
||||
|
||||
return name
|
||||
|
||||
|
||||
def get_duplicates(a):
|
||||
seen = {}
|
||||
dupes = []
|
||||
@@ -38,28 +40,25 @@ def get_duplicates(a):
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
rs = (r for r in Rower.objects.all() if r.ispaid and r.autojoin)
|
||||
now = timezone.now()
|
||||
rs = (r for r in Rower.objects.all() if r.ispaid and r.autojoin)
|
||||
|
||||
for r in rs:
|
||||
workouts = Workout.objects.filter(user=r,
|
||||
duplicate=False,
|
||||
startdatetime__gte=timezone.now()-datetime.timedelta(days=2))
|
||||
|
||||
|
||||
duplicates = get_duplicates(name_short(w.name) for w in workouts)
|
||||
|
||||
for name, count in duplicates.items():
|
||||
if count > 1:
|
||||
workouts2 = workouts.filter(
|
||||
Q(name__contains=name)
|
||||
)
|
||||
Q(name__contains=name))
|
||||
|
||||
duplicates2 = get_duplicates(w.date for w in workouts)
|
||||
for dd, count in duplicates2.items():
|
||||
if count > 1:
|
||||
workouts3 = workouts2.filter(date=dd)
|
||||
ids = [w.id for w in workouts3]
|
||||
id, message = join_workouts(r,ids,title=name,
|
||||
id, message = join_workouts(r, ids, title=name,
|
||||
parent=workouts3[0],
|
||||
killparents=True)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#!/srv/venv/bin/python
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
@@ -10,11 +8,12 @@ import json
|
||||
|
||||
from simplejson.errors import JSONDecodeError
|
||||
|
||||
PY3K = sys.version_info >= (3,0)
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from rowers.models import BlogPost
|
||||
|
||||
PY3K = sys.version_info >= (3, 0)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
blogs_json = []
|
||||
@@ -24,7 +23,7 @@ class Command(BaseCommand):
|
||||
if response.status_code == 200:
|
||||
try:
|
||||
blogs_json = response.json()
|
||||
except JSONDecodeError:
|
||||
except JSONDecodeError:
|
||||
try:
|
||||
blogs_json = json.loads(response.text)
|
||||
except JSONDecodeError:
|
||||
@@ -35,16 +34,13 @@ class Command(BaseCommand):
|
||||
pass
|
||||
|
||||
if blogs_json:
|
||||
result = BlogPost.objects.all().delete()
|
||||
_ = BlogPost.objects.all().delete()
|
||||
|
||||
for postdata in blogs_json[0:3]:
|
||||
title = postdata['title']['rendered']
|
||||
link = postdata['link']
|
||||
datetime = postdata['date']
|
||||
datetime = arrow.get(datetime).datetime
|
||||
date = datetime.date()
|
||||
|
||||
|
||||
blogpost = BlogPost(
|
||||
link=link,
|
||||
date=date,
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
#!/srv/venv/bin/python
|
||||
import sys
|
||||
import os
|
||||
# If you find a solution that does not need the two paths, please comment!
|
||||
sys.path.append('$path_to_root_of_project$')
|
||||
sys.path.append('$path_to_root_of_project$/$project_name$')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail, BadHeaderError,EmailMessage
|
||||
from django.core.mail import send_mail, BadHeaderError, EmailMessage
|
||||
|
||||
import datetime
|
||||
from rowers.models import *
|
||||
@@ -17,6 +11,12 @@ from rowsandall_app.settings import BASE_DIR
|
||||
|
||||
import pandas as pd
|
||||
|
||||
sys.path.append('$path_to_root_of_project$')
|
||||
sys.path.append('$path_to_root_of_project$/$project_name$')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
|
||||
|
||||
|
||||
def getemails():
|
||||
rs = Rower.objects.all()
|
||||
firstnames = [r.user.first_name for r in rs]
|
||||
@@ -24,20 +24,18 @@ def getemails():
|
||||
emails = [r.user.email for r in rs]
|
||||
is_actives = [r.user.is_active for r in rs]
|
||||
df = pd.DataFrame({
|
||||
'first_name':firstnames,
|
||||
'last_name':lastnames,
|
||||
'email':emails,
|
||||
'is_active':is_actives
|
||||
})
|
||||
'first_name': firstnames,
|
||||
'last_name': lastnames,
|
||||
'email': emails,
|
||||
'is_active': is_actives})
|
||||
|
||||
return df
|
||||
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
email_list = getemails()
|
||||
email_list.to_csv('email_list.csv',encoding='utf-8')
|
||||
email_list.to_csv('email_list.csv', encoding='utf-8')
|
||||
|
||||
fullemail = 'roosendaalsander@gmail.com'
|
||||
subject = "Rowsandall users list"
|
||||
@@ -45,12 +43,13 @@ class Command(BaseCommand):
|
||||
message += "Best Regards, the Rowsandall Team"
|
||||
message += "Users list attached \n\n"
|
||||
|
||||
email = EmailMessage(subject, message,
|
||||
'Rowsandall <info@rowsandall.com>',
|
||||
[fullemail])
|
||||
email = EmailMessage(
|
||||
subject, message,
|
||||
'Rowsandall <info@rowsandall.com>',
|
||||
[fullemail])
|
||||
|
||||
email.attach_file('email_list.csv')
|
||||
|
||||
os.remove('email_list.csv')
|
||||
|
||||
res = email.send()
|
||||
_ = email.send()
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
#!/srv/venv/bin/python
|
||||
import sys
|
||||
import os
|
||||
# If you find a solution that does not need the two paths, please comment!
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail, BadHeaderError, EmailMessage
|
||||
|
||||
import datetime
|
||||
from rowers.models import Rower
|
||||
from rowsandall_app.settings import BASE_DIR
|
||||
|
||||
sys.path.append('$path_to_root_of_project$')
|
||||
sys.path.append('$path_to_root_of_project$/$project_name$')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.conf import settings
|
||||
from django.core.mail import send_mail, BadHeaderError,EmailMessage
|
||||
|
||||
import datetime
|
||||
from rowers.models import Rower
|
||||
from rowsandall_app.settings import BASE_DIR
|
||||
|
||||
def getexpired():
|
||||
rs = Rower.objects.all()
|
||||
@@ -43,10 +43,9 @@ class Command(BaseCommand):
|
||||
message += r.user.first_name+" "+r.user.last_name+" "+r.user.username
|
||||
message += "\n"
|
||||
|
||||
email = EmailMessage(subject, message,
|
||||
'Rowsandall <info@rowsandall.com>',
|
||||
[fullemail])
|
||||
email = EmailMessage(
|
||||
subject, message,
|
||||
'Rowsandall <info@rowsandall.com>',
|
||||
[fullemail])
|
||||
|
||||
|
||||
|
||||
res = email.send()
|
||||
_ = email.send()
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
import sys
|
||||
import os
|
||||
|
||||
PY3K = sys.version_info >= (3,0)
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from rowers.models import Alert, Condition, User
|
||||
from rowers.tasks import handle_send_email_alert
|
||||
@@ -13,15 +11,17 @@ from rowers import alerts
|
||||
|
||||
from rowers.utils import myqueue
|
||||
|
||||
import datetime
|
||||
|
||||
import django_rq
|
||||
|
||||
PY3K = sys.version_info >= (3, 0)
|
||||
|
||||
queue = django_rq.get_queue('default')
|
||||
queuelow = django_rq.get_queue('low')
|
||||
queuehigh = django_rq.get_queue('low')
|
||||
|
||||
|
||||
import datetime
|
||||
|
||||
class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
@@ -29,8 +29,7 @@ class Command(BaseCommand):
|
||||
action='store_true',
|
||||
dest='testing',
|
||||
default=False,
|
||||
help="Run in testing mode, don't send emails",
|
||||
)
|
||||
help="Run in testing mode, don't send emails", )
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if 'testing' in options:
|
||||
@@ -38,7 +37,8 @@ class Command(BaseCommand):
|
||||
else:
|
||||
testing = False
|
||||
|
||||
todaysalerts = Alert.objects.filter(next_run__lt = datetime.date.today(),emailalert=True)
|
||||
todaysalerts = Alert.objects.filter(
|
||||
next_run__lt=datetime.date.today(), emailalert=True)
|
||||
|
||||
for alert in todaysalerts:
|
||||
stats = alerts.alert_get_stats(alert)
|
||||
@@ -47,14 +47,14 @@ class Command(BaseCommand):
|
||||
othertexts = [alert.description()]
|
||||
|
||||
# send email
|
||||
job = myqueue(queue,handle_send_email_alert,
|
||||
alert.manager.email,
|
||||
alert.manager.first_name,
|
||||
alert.manager.last_name,
|
||||
alert.rower.user.first_name,
|
||||
alert.name,
|
||||
stats,debug=True,
|
||||
othertexts=othertexts)
|
||||
_ = myqueue(queue, handle_send_email_alert,
|
||||
alert.manager.email,
|
||||
alert.manager.first_name,
|
||||
alert.manager.last_name,
|
||||
alert.rower.user.first_name,
|
||||
alert.name,
|
||||
stats, debug=True,
|
||||
othertexts=othertexts)
|
||||
|
||||
# advance next_run
|
||||
if not testing:
|
||||
@@ -62,7 +62,7 @@ class Command(BaseCommand):
|
||||
alert.save()
|
||||
|
||||
if testing:
|
||||
print('{nr} alerts found'.format(nr = len(todaysalerts)))
|
||||
print('{nr} alerts found'.format(nr=len(todaysalerts)))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
'Successfully processed alerts'))
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#!/srv/venv/bin/python
|
||||
|
||||
""" Process emails """
|
||||
import sys
|
||||
import os
|
||||
PY3K = sys.version_info >= (3, 0)
|
||||
|
||||
import zipfile
|
||||
from zipfile import BadZipFile
|
||||
@@ -18,12 +15,12 @@ import json
|
||||
import io
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
#from django_mailbox.models import Message, MessageAttachment,Mailbox
|
||||
|
||||
from django.urls import reverse
|
||||
from django.conf import settings
|
||||
|
||||
from django.utils import timezone
|
||||
from rowers.models import Workout, Rower
|
||||
from rowers.models import User, Workout, Rower
|
||||
|
||||
from rowingdata import rower as rrower
|
||||
from rowingdata import rowingdata as rrdata
|
||||
@@ -37,7 +34,6 @@ import rowers.stravastuff as stravastuff
|
||||
import rowers.nkstuff as nkstuff
|
||||
from rowers.opaque import encoder
|
||||
|
||||
from rowers.models import User,Workout
|
||||
from rowers.rower_rules import user_is_not_basic
|
||||
from rowers.utils import dologging
|
||||
|
||||
@@ -47,10 +43,14 @@ sys.path.append('$path_to_root_of_project$/$project_name$')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
|
||||
|
||||
if not getattr(__builtins__, "WindowsError", None):
|
||||
class WindowsError(OSError): pass
|
||||
PY3K = sys.version_info >= (3, 0)
|
||||
|
||||
def rdata(file_obj, rower=rrower()): # pragma: no cover
|
||||
if not getattr(__builtins__, "WindowsError", None):
|
||||
class WindowsError(OSError):
|
||||
pass
|
||||
|
||||
|
||||
def rdata(file_obj, rower=rrower()): # pragma: no cover
|
||||
""" Read rowing data file and return 0 if file doesn't exist"""
|
||||
try:
|
||||
result = rrdata(file_obj, rower=rower)
|
||||
@@ -60,7 +60,6 @@ def rdata(file_obj, rower=rrower()): # pragma: no cover
|
||||
return result
|
||||
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
@@ -68,71 +67,57 @@ class Command(BaseCommand):
|
||||
action='store_true',
|
||||
dest='testing',
|
||||
default=False,
|
||||
help="Run in testing mode, don't send emails",
|
||||
)
|
||||
help="Run in testing mode, don't send emails", )
|
||||
parser.add_argument(
|
||||
'--mailbox',
|
||||
action='store_true',
|
||||
dest='mailbox',
|
||||
default='workouts',
|
||||
help="Changing mailbox name",
|
||||
)
|
||||
help="Changing mailbox name", )
|
||||
|
||||
"""Run the Email processing command """
|
||||
def handle(self, *args, **options):
|
||||
if 'testing' in options:
|
||||
testing = options['testing']
|
||||
else: # pragma: no cover
|
||||
testing = False
|
||||
|
||||
# Polar
|
||||
try:
|
||||
polar_available = polarstuff.get_polar_notifications()
|
||||
res = polarstuff.get_all_new_workouts(polar_available)
|
||||
except: # pragma: no cover
|
||||
_ = polarstuff.get_all_new_workouts(polar_available)
|
||||
except: # pragma: no cover
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
||||
dologging('processemail.log',''.join('!! ' + line for line in lines))
|
||||
dologging('processemail.log', ''.join('!! ' + line for line in lines))
|
||||
|
||||
# Concept2
|
||||
try:
|
||||
rowers = Rower.objects.filter(c2_auto_import=True)
|
||||
for r in rowers: # pragma: no cover
|
||||
for r in rowers: # pragma: no cover
|
||||
if user_is_not_basic(r.user):
|
||||
c2stuff.get_c2_workouts(r)
|
||||
except: # pragma: no cover
|
||||
except: # pragma: no cover
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
||||
dologging('processemail.log',''.join('!! ' + line for line in lines))
|
||||
|
||||
dologging('processemail.log', ''.join('!! ' + line for line in lines))
|
||||
|
||||
try:
|
||||
rowers = Rower.objects.filter(rp3_auto_import=True)
|
||||
for r in rowers: # pragma: no cover
|
||||
for r in rowers: # pragma: no cover
|
||||
if user_is_not_basic(r.user):
|
||||
res = rp3stuff.get_rp3_workouts(r)
|
||||
except: # pragma: no cover
|
||||
_ = rp3stuff.get_rp3_workouts(r)
|
||||
except: # pragma: no cover
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
||||
dologging('processemail.log',''.join('!! ' + line for line in lines))
|
||||
dologging('processemail.log', ''.join('!! ' + line for line in lines))
|
||||
|
||||
try:
|
||||
rowers = Rower.objects.filter(nk_auto_import=True)
|
||||
for r in rowers: # pragma: no cover
|
||||
for r in rowers: # pragma: no cover
|
||||
if user_is_not_basic(r.user):
|
||||
s = 'Starting NK Auto Import for user {id}'.format(id=r.user.id)
|
||||
dologging('nklog.log',s)
|
||||
res = nkstuff.get_nk_workouts(r)
|
||||
except: # pragma: no cover
|
||||
dologging('nklog.log', s)
|
||||
_ = nkstuff.get_nk_workouts(r)
|
||||
except: # pragma: no cover
|
||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
|
||||
dologging('processemail.log',''.join('!! ' + line for line in lines))
|
||||
|
||||
# Strava
|
||||
#rowers = Rower.objects.filter(strava_auto_import=True)
|
||||
#for r in rowers:
|
||||
# if user_is_not_basic(r.user): # pragma: no cover
|
||||
# stravastuff.get_strava_workouts(r)
|
||||
dologging('processemail.log', ''.join('!! ' + line for line in lines))
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
'Successfully processed email attachments'))
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
#!/srv/venv/bin/python
|
||||
import sys
|
||||
import os
|
||||
# If you find a solution that does not need the two paths, please comment!
|
||||
sys.path.append('$path_to_root_of_project$')
|
||||
sys.path.append('$path_to_root_of_project$/$project_name$')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.conf import settings
|
||||
#from rowers.mailprocessing import processattachments
|
||||
|
||||
import time
|
||||
from django.conf import settings
|
||||
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage,AdvancedWorkoutForm
|
||||
|
||||
from rowers.models import (
|
||||
Workout, User, Rower, WorkoutForm,
|
||||
RowerForm, GraphImage, AdvancedWorkoutForm)
|
||||
from django.core.files.base import ContentFile
|
||||
|
||||
from rowsandall_app.settings import BASE_DIR
|
||||
|
||||
from rowers.dataprep import *
|
||||
|
||||
# If you find a solution that does not need the two paths, please comment!
|
||||
sys.path.append('$path_to_root_of_project$')
|
||||
sys.path.append('$path_to_root_of_project$/$project_name$')
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = '$project_name$.settings'
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
repair_data(verbose=True)
|
||||
|
||||
@@ -99,12 +99,12 @@ class RowerPlanMiddleWare(object):
|
||||
# remove from Free Coach groups
|
||||
|
||||
# send email
|
||||
job = myqueue(queue,
|
||||
handle_sendemail_expired,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
str(r.planexpires))
|
||||
_ = myqueue(queue,
|
||||
handle_sendemail_expired,
|
||||
r.user.email,
|
||||
r.user.first_name,
|
||||
r.user.last_name,
|
||||
str(r.planexpires))
|
||||
|
||||
response = self.get_response(request)
|
||||
|
||||
|
||||
+25
-46
@@ -3,7 +3,7 @@ from rowers.metrics import rowingmetrics
|
||||
from django.db.models.signals import m2m_changed
|
||||
from rowers.courseutils import coordinate_in_path
|
||||
from rowers.utils import (
|
||||
workflowleftpanel, workflowmiddlepanel,
|
||||
# workflowleftpanel, workflowmiddlepanel,
|
||||
defaultleft, defaultmiddle, landingpages, landingpages2,
|
||||
steps_read_fit, steps_write_fit, ps_dict_order
|
||||
)
|
||||
@@ -15,18 +15,15 @@ import uuid
|
||||
|
||||
from django.db import models, IntegrityError
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.validators import validate_email
|
||||
from django.core.exceptions import ValidationError
|
||||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
from django.dispatch import receiver
|
||||
from django.forms.widgets import SplitDateTimeWidget, SelectDateWidget
|
||||
#from django.forms.extras.widgets import SelectDateWidget
|
||||
from django.forms.formsets import BaseFormSet
|
||||
|
||||
#from datetimewidget.widgets import DateTimeWidget
|
||||
from django.contrib.admin.widgets import AdminDateWidget, AdminTimeWidget, AdminSplitDateTime
|
||||
from django.core.validators import validate_email
|
||||
|
||||
import os
|
||||
import json
|
||||
import twitter
|
||||
@@ -55,8 +52,6 @@ import datetime
|
||||
|
||||
from taggit.managers import TaggableManager
|
||||
|
||||
#from rules.contrib.models import RulesModel
|
||||
|
||||
from rowers.rower_rules import *
|
||||
from rowers.opaque import encoder
|
||||
|
||||
@@ -322,7 +317,6 @@ def update_records(url=c2url, verbose=True):
|
||||
dfs = pd.read_html(url, attrs={'class': 'views-table'})
|
||||
df = dfs[0]
|
||||
df.columns = df.columns.str.strip()
|
||||
success = 1
|
||||
except: # pragma: no cover
|
||||
df = pd.DataFrame()
|
||||
|
||||
@@ -574,29 +568,16 @@ def course_spline(coordinates):
|
||||
latitudes = coordinates['latitude'].values
|
||||
longitudes = coordinates['longitude'].values
|
||||
|
||||
# spline parameters
|
||||
s = 1.0
|
||||
k = min([5, len(latitudes)-1])
|
||||
nest = -1
|
||||
|
||||
t = np.linspace(0, 1, len(latitudes))
|
||||
tnew = np.linspace(0, 1, 100)
|
||||
|
||||
try:
|
||||
#latnew = CubicSpline(t,latitudes,bc_type='not-a-knot')(tnew)
|
||||
#lonnew = CubicSpline(t,longitudes,bc_type='not-a-knot')(tnew)
|
||||
latnew = interp1d(t, latitudes)(tnew)
|
||||
lonnew = interp1d(t, longitudes)(tnew)
|
||||
except ValueError: # pragma: no cover
|
||||
latnew = latitudes
|
||||
lonnew = longitudes
|
||||
|
||||
# latnew = CubicSpline(t,latitudes,bc_type='natural')(tnew)
|
||||
# lonnew = CubicSpline(t,longitudes,bc_type='natural')(tnew)
|
||||
|
||||
# tckp,u = splprep([t,latitudes,longitudes],s=s,k=k,nest=nest)
|
||||
# tnew,latnew,lonnew = splev(np.linspace(0,1,100),tckp)
|
||||
|
||||
newcoordinates = pd.DataFrame({
|
||||
'latitude': latnew,
|
||||
'longitude': lonnew,
|
||||
@@ -673,7 +654,8 @@ def get_delta(vector, polygon):
|
||||
|
||||
p = polygon_to_path(polygon)
|
||||
|
||||
def f(x): return coordinate_in_path(x['lat'], x['lon'], p)
|
||||
def f(x):
|
||||
return coordinate_in_path(x['lat'], x['lon'], p)
|
||||
|
||||
df = pd.DataFrame({'x': x,
|
||||
'lat': lat,
|
||||
@@ -795,7 +777,7 @@ class PaidPlan(models.Model):
|
||||
shortname=self.shortname,
|
||||
price=self.price,
|
||||
paymenttype=self.paymenttype,
|
||||
paymentprocessor=self.paymentprocessor,
|
||||
# paymentprocessor=self.paymentprocessor,
|
||||
)
|
||||
|
||||
|
||||
@@ -1346,8 +1328,9 @@ class BaseFavoriteFormSet(BaseFormSet):
|
||||
xparam = form.cleaned_data['xparam']
|
||||
yparam1 = form.cleaned_data['yparam1']
|
||||
yparam2 = form.cleaned_data['yparam2']
|
||||
plottype = form.cleaned_data['plottype']
|
||||
reststrokes = form.cleaned_data['reststrokes']
|
||||
# plottype = form.cleaned_data['plottype']
|
||||
# reststrokes = form.cleaned_data['reststrokes']
|
||||
pass
|
||||
|
||||
if not xparam:
|
||||
raise forms.ValidationError(
|
||||
@@ -1402,10 +1385,11 @@ class BaseConditionFormSet(BaseFormSet):
|
||||
|
||||
for form in self.forms:
|
||||
if form.cleaned_data:
|
||||
metric = form.cleaned_data['metric']
|
||||
condition = form.cleaned_data['condition']
|
||||
value1 = form.cleaned_data['value1']
|
||||
value2 = form.cleaned_data['value2']
|
||||
# metric = form.cleaned_data['metric']
|
||||
# condition = form.cleaned_data['condition']
|
||||
# value1 = form.cleaned_data['value1']
|
||||
# value2 = form.cleaned_data['value2']
|
||||
pass
|
||||
|
||||
|
||||
rowchoices = []
|
||||
@@ -1475,7 +1459,7 @@ class Alert(models.Model):
|
||||
return description
|
||||
|
||||
def shortdescription(self): # pragma: no cover
|
||||
metricdict = {key: value for (key, value) in parchoicesy1}
|
||||
# metricdict = {key: value for (key, value) in parchoicesy1}
|
||||
|
||||
if self.measured.condition == 'between':
|
||||
description = '{value1} < {metric} < {value2}'.format(
|
||||
@@ -1526,7 +1510,7 @@ class GeoCourse(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
name = self.name
|
||||
country = self.country
|
||||
# country = self.country
|
||||
d = self.distance
|
||||
if d == 0: # pragma: no cover
|
||||
self.distance = course_length(self)
|
||||
@@ -1535,7 +1519,7 @@ class GeoCourse(models.Model):
|
||||
|
||||
return u'{name} - {d}m'.format(
|
||||
name=name,
|
||||
country=country,
|
||||
# country=country,
|
||||
d=d,
|
||||
)
|
||||
|
||||
@@ -2530,7 +2514,6 @@ class PlannedSession(models.Model):
|
||||
can_be_shared = models.BooleanField(default=True)
|
||||
|
||||
fitfile = models.FileField(upload_to=get_file_path, blank=True, null=True)
|
||||
#steps_json = models.TextField(max_length=10000,default=None,blank=True,null=True)
|
||||
steps = PlannedSessionStepField(default={}, null=True, max_length=1000)
|
||||
interval_string = models.TextField(max_length=1000, default=None, blank=True, null=True,
|
||||
verbose_name='Interval String (optional)')
|
||||
@@ -2565,7 +2548,7 @@ class PlannedSession(models.Model):
|
||||
if self.sessionvalue <= 0: # pragma: no cover
|
||||
self.sessionvalue = 1
|
||||
|
||||
manager = self.manager
|
||||
# manager = self.manager
|
||||
if self.sessiontype not in ['race', 'indoorrace']:
|
||||
if not can_add_session(self.manager):
|
||||
raise ValidationError(
|
||||
@@ -2612,7 +2595,7 @@ class PlannedSession(models.Model):
|
||||
self.sessionmode = 'distance'
|
||||
self.sessionunit = 'm'
|
||||
self.criterium = 'none'
|
||||
if self.course == None: # pragma: no cover
|
||||
if self.course is None: # pragma: no cover
|
||||
self.course = GeoCourse.objects.all()[0]
|
||||
self.sessionvalue = self.course.distance
|
||||
elif self.sessiontype != 'coursetest' and self.sessiontype != 'race':
|
||||
@@ -2626,7 +2609,6 @@ class PlannedSession(models.Model):
|
||||
if self.preferreddate < self.startdate: # pragma: no cover
|
||||
self.preferreddate = self.startdate
|
||||
|
||||
#super(PlannedSession,self).save(*args, **kwargs)
|
||||
if self.steps:
|
||||
steps = self.steps
|
||||
elif self.fitfile: # pragma: no cover
|
||||
@@ -2640,7 +2622,7 @@ class PlannedSession(models.Model):
|
||||
|
||||
steps = self.steps
|
||||
steps['filename'] = os.path.join(settings.MEDIA_ROOT, filename)
|
||||
fitfile = steps_write_fit(steps)
|
||||
_ = steps_write_fit(steps)
|
||||
self.fitfile.name = filename
|
||||
self.steps = steps
|
||||
|
||||
@@ -2752,8 +2734,8 @@ class VirtualRace(PlannedSession):
|
||||
def __str__(self):
|
||||
|
||||
name = self.name
|
||||
startdate = self.startdate
|
||||
enddate = self.enddate
|
||||
# startdate = self.startdate
|
||||
# enddate = self.enddate
|
||||
|
||||
stri = u'Virtual challenge {n}'.format(
|
||||
n=name,
|
||||
@@ -4031,9 +4013,6 @@ class WorkoutForm(ModelForm):
|
||||
|
||||
|
||||
class AdvancedWorkoutForm(ModelForm):
|
||||
#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', 'boatbrand']
|
||||
@@ -4332,8 +4311,8 @@ class RowerPowerZonesForm(ModelForm):
|
||||
try:
|
||||
ut3name = cleaned_data['ut3name']
|
||||
except:
|
||||
ut2name = 'UT3'
|
||||
cleaned_data['ut3name'] = 'UT3'
|
||||
ut3name = 'UT3'
|
||||
cleaned_data['ut3name'] = ut3name
|
||||
try:
|
||||
ut2name = cleaned_data['ut2name']
|
||||
except:
|
||||
@@ -4717,10 +4696,10 @@ class SiteAnnouncement(models.Model):
|
||||
self.modified = timezone.now()
|
||||
if self.dotweet: # pragma: no cover
|
||||
try:
|
||||
status = tweetapi.PostUpdate(self.announcement)
|
||||
_ = tweetapi.PostUpdate(self.announcement)
|
||||
except:
|
||||
try:
|
||||
status = tweetapi.PostUpdate(self.announcement[:270])
|
||||
_ = tweetapi.PostUpdate(self.announcement[:270])
|
||||
except:
|
||||
pass
|
||||
return super(SiteAnnouncement, self).save(*args, **kwargs)
|
||||
|
||||
+3
-4
@@ -358,7 +358,6 @@ rowtypes = (
|
||||
checktypes = [i[0] for i in workouttypes_ordered.items()]
|
||||
|
||||
|
||||
#colors = Category10[9]
|
||||
colors = list(set(Category10[9]))+list(set(Category20[19]+Category20c[19]))
|
||||
color_map = {checktypes[i]: colors[i] for i in range(len(checktypes))}
|
||||
|
||||
@@ -557,7 +556,7 @@ polaraccesslink_sports = {
|
||||
'DUATHLON_CYCLING': 'bike',
|
||||
'DUATHLON_RUNNING': 'Run',
|
||||
'FIELD_HOCKEY': 'other',
|
||||
'FINNISH_BASEBALL': 'other',
|
||||
'FINNISH_BASEBALL': 'other',
|
||||
'FITNESS_DANCING': 'other',
|
||||
'FITNESS_MARTIAL_ARTS': 'other',
|
||||
'FITNESS_STEP': 'Workout',
|
||||
@@ -625,7 +624,7 @@ polaraccesslink_sports = {
|
||||
'ROLLER_BLADING': 'InlineSkate',
|
||||
'ROLLER_SKIING_CLASSIC': 'NordicSki',
|
||||
'ROLLER_SKIING_FREESTYLE': 'NordicSki',
|
||||
'ROWING': 'water',
|
||||
'ROWING': 'water',
|
||||
'RUGBY': 'other',
|
||||
'RUNNING': 'Run',
|
||||
'SHOW_DANCING': 'other',
|
||||
@@ -664,5 +663,5 @@ polaraccesslink_sports = {
|
||||
'WATERSPORTS_WINDSURFING': 'other',
|
||||
'XC_SKIING_CLASSIC': 'NordicSki',
|
||||
'XC_SKIING_FREESTYLE': 'NordicSki',
|
||||
'YOGA': 'Yoga'
|
||||
'YOGA': 'Yoga'
|
||||
}
|
||||
|
||||
+10
-9
@@ -1,4 +1,5 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import datetime
|
||||
from datetime import timedelta
|
||||
from uuid import uuid4
|
||||
@@ -52,14 +53,14 @@ def add_workout_from_data(userid, nkid, data, strokedata, source='nk', splitdata
|
||||
elapsedTime = data["elapsedTime"]
|
||||
totalDistanceGps = data["totalDistanceGps"]
|
||||
totalDistanceImp = data["totalDistanceImp"]
|
||||
intervals = data["intervals"] # add intervals
|
||||
# intervals = data["intervals"] # add intervals
|
||||
oarlockSessions = data["oarlockSessions"]
|
||||
deviceId = data["deviceId"] # you could get the firmware version
|
||||
# deviceId = data["deviceId"] # you could get the firmware version
|
||||
|
||||
totalDistance = totalDistanceGps
|
||||
useImpeller = False
|
||||
if speedInput: # pragma: no cover
|
||||
totdalDistance = totalDistanceImp
|
||||
totalDistance = totalDistanceImp
|
||||
useImpeller = True
|
||||
|
||||
summary = get_nk_allstats(data, strokedata)
|
||||
@@ -69,19 +70,19 @@ def add_workout_from_data(userid, nkid, data, strokedata, source='nk', splitdata
|
||||
# oarlock inboard, length, boat name
|
||||
if oarlockSessions:
|
||||
oarlocksession = oarlockSessions[0] # should take seatIndex
|
||||
boatName = oarlocksession["boatName"]
|
||||
# boatName = oarlocksession["boatName"]
|
||||
oarLength = oarlocksession["oarLength"] # cm
|
||||
oarInboardLength = oarlocksession["oarInboardLength"] # cm
|
||||
seatNumber = oarlocksession["seatNumber"]
|
||||
# seatNumber = oarlocksession["seatNumber"]
|
||||
try:
|
||||
oarlockfirmware = oarlocksession["firmwareVersion"]
|
||||
except KeyError:
|
||||
oarlockfirmware = ''
|
||||
else: # pragma: no cover
|
||||
boatName = ''
|
||||
# boatName = ''
|
||||
oarLength = 289
|
||||
oarInboardLength = 88
|
||||
seatNumber = 1
|
||||
# seatNumber = 1
|
||||
oarlockfirmware = ''
|
||||
|
||||
workouttype = "water"
|
||||
@@ -139,7 +140,7 @@ def get_nk_intervalstats(workoutdata, strokedata):
|
||||
i = 0
|
||||
|
||||
for interval in intervals:
|
||||
id = interval['id']
|
||||
# id = interval['id']
|
||||
sdist = interval['totalDistanceGps']
|
||||
avgpace = interval['avgPaceGps']/1000.
|
||||
avgpacetd = timedelta(seconds=avgpace)
|
||||
@@ -325,6 +326,6 @@ def readlogs_summaries(logfile, dosave=0): # pragma: no cover
|
||||
json.dump(strokeData, f2)
|
||||
with open(filename2, 'w') as f2:
|
||||
json.dump(summaryData, f2)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
print(traceback.format_exc())
|
||||
print("error")
|
||||
|
||||
+5
-22
@@ -31,13 +31,6 @@ queue = django_rq.get_queue('default')
|
||||
queuelow = django_rq.get_queue('low')
|
||||
queuehigh = django_rq.get_queue('low')
|
||||
|
||||
|
||||
try:
|
||||
from json.decoder import JSONDecodeError
|
||||
except ImportError: # pragma: no cover
|
||||
JSONDecodeError = ValueError
|
||||
|
||||
|
||||
oauth_data = {
|
||||
'client_id': NK_CLIENT_ID,
|
||||
'client_secret': NK_CLIENT_SECRET,
|
||||
@@ -56,12 +49,6 @@ oauth_data = {
|
||||
def get_token(code): # pragma: no cover
|
||||
url = oauth_data['base_url']
|
||||
|
||||
headers = {'Accept': 'application/json',
|
||||
# 'Authorization': auth_header,
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
# 'user-agent': 'sanderroosendaal'
|
||||
}
|
||||
|
||||
post_data = {"client_id": oauth_data['client_id'],
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": oauth_data['redirect_uri'],
|
||||
@@ -88,13 +75,12 @@ def nk_open(user):
|
||||
r = Rower.objects.get(user=user)
|
||||
|
||||
if (r.nktoken == '') or (r.nktoken is None): # pragma: no cover
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
raise NoTokenError("User has no token")
|
||||
else:
|
||||
if (timezone.now() > r.nktokenexpirydate):
|
||||
|
||||
thetoken = rower_nk_token_refresh(user)
|
||||
if thetoken == None: # pragma: no cover
|
||||
if thetoken is None: # pragma: no cover
|
||||
raise NoTokenError("User has no token")
|
||||
return thetoken
|
||||
else:
|
||||
@@ -105,7 +91,7 @@ def nk_open(user):
|
||||
|
||||
def get_nk_workouts(rower, do_async=True, before=0, after=0):
|
||||
try:
|
||||
thetoken = nk_open(rower.user)
|
||||
_ = nk_open(rower.user)
|
||||
except NoTokenError: # pragma: no cover
|
||||
return 0
|
||||
|
||||
@@ -136,7 +122,7 @@ def get_nk_workouts(rower, do_async=True, before=0, after=0):
|
||||
pass
|
||||
|
||||
knownnkids = uniqify(knownnkids+tombstones+parkedids)
|
||||
newids = [nkid for nkid in nkids if not nkid in knownnkids]
|
||||
newids = [nkid for nkid in nkids if nkid not in knownnkids]
|
||||
s = 'New NK IDs {newids}'.format(newids=newids)
|
||||
dologging('nklog.log', s)
|
||||
|
||||
@@ -211,7 +197,8 @@ def get_nk_workout_list(user, fake=False, after=0, before=0):
|
||||
if (r.nktoken == '') or (r.nktoken is None): # pragma: no cover
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401, s)
|
||||
elif (r.nktokenexpirydate is None or timezone.now()+timedelta(seconds=10) > r.nktokenexpirydate): # pragma: no cover
|
||||
elif (r.nktokenexpirydate is None or
|
||||
timezone.now()+timedelta(seconds=10) > r.nktokenexpirydate): # pragma: no cover
|
||||
s = "Token expired. Needs to refresh."
|
||||
return custom_exception_handler(401, s)
|
||||
else:
|
||||
@@ -251,10 +238,6 @@ def get_workout(user, nkid, do_async=True, startdate='', enddate=''):
|
||||
s = "Token expired. Needs to refresh."
|
||||
return custom_exception_handler(401, s), 0
|
||||
|
||||
params = {
|
||||
'sessionIds': nkid,
|
||||
}
|
||||
|
||||
before = 0
|
||||
after = 0
|
||||
if startdate: # pragma: no cover
|
||||
|
||||
+2
-2
@@ -38,8 +38,8 @@ class OpaqueEncoder:
|
||||
def transcode(self, i):
|
||||
"""Reversibly transcode a 32-bit integer to a scrambled form, returning a new 32-bit integer."""
|
||||
r = i & 0xffff
|
||||
l = i >> 16 & 0xffff ^ self.transform(r)
|
||||
return ((r ^ self.transform(l)) << 16) + l
|
||||
lla = i >> 16 & 0xffff ^ self.transform(r)
|
||||
return ((r ^ self.transform(lla)) << 16) + lla
|
||||
|
||||
def encode_hex(self, i):
|
||||
"""Transcode an integer and return it as an 8-character hex string."""
|
||||
|
||||
+10
-8
@@ -7,7 +7,7 @@ import requests
|
||||
import requests.auth
|
||||
import json
|
||||
from django.utils import timezone
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
import numpy as np
|
||||
from dateutil import parser
|
||||
import time
|
||||
@@ -30,7 +30,10 @@ from rowingdata import rowingdata
|
||||
import pandas as pd
|
||||
from rowers.models import Rower, Workout
|
||||
|
||||
from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET, SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI
|
||||
from rowsandall_app.settings import (
|
||||
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
||||
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
|
||||
SPORTTRACKS_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI)
|
||||
|
||||
TEST_CLIENT_ID = "1"
|
||||
TEST_CLIENT_SECRET = "aapnootmies"
|
||||
@@ -57,8 +60,8 @@ def custom_exception_handler(exc, message): # pragma: no cover
|
||||
|
||||
|
||||
def do_refresh_token(refreshtoken): # pragma: no cover
|
||||
client_auth = requests.auth.HTTPBasicAuth(
|
||||
TEST_CLIENT_ID, TEST_CLIENT_SECRET)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(
|
||||
# TEST_CLIENT_ID, TEST_CLIENT_SECRET)
|
||||
post_data = {"grant_type": "refresh_token",
|
||||
"client_secret": TEST_CLIENT_SECRET,
|
||||
"client_id": TEST_CLIENT_ID,
|
||||
@@ -86,8 +89,8 @@ def do_refresh_token(refreshtoken): # pragma: no cover
|
||||
|
||||
|
||||
def get_token(code): # pragma: no cover
|
||||
client_auth = requests.auth.HTTPBasicAuth(
|
||||
TEST_CLIENT_ID, TEST_CLIENT_SECRET)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(
|
||||
# TEST_CLIENT_ID, TEST_CLIENT_SECRET)
|
||||
post_data = {"grant_type": "authorization_code",
|
||||
"code": code,
|
||||
"redirect_uri": "http://localhost:8000/rowers/test_callback",
|
||||
@@ -123,7 +126,6 @@ def make_authorization_url(request): # pragma: no cover
|
||||
"scope": "write",
|
||||
"state": state}
|
||||
|
||||
import urllib
|
||||
url = "http://localhost:8000/rowers/o/authorize" + \
|
||||
urllib.parse.urlencode(params)
|
||||
|
||||
@@ -170,8 +172,8 @@ def get_ownapi_workout_list(user): # pragma: no cover
|
||||
def get_ownapi_workout(user, ownapiid): # pragma: no cover
|
||||
r = Rower.objects.get(user=user)
|
||||
if (r.ownapitoken == '') or (r.ownapitoken is None):
|
||||
return custom_exception_handler(401, s)
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401, s)
|
||||
elif (timezone.now() > r.ownapitokenexpirydate):
|
||||
s = "Token expired. Needs to refresh."
|
||||
return custom_exception_handler(401, s)
|
||||
|
||||
+13
-30
@@ -6,7 +6,6 @@ from rowers.models import (
|
||||
get_course_timezone, IndoorVirtualRaceResult, VirtualRace, createmacrofillers,
|
||||
createmesofillers, createmicrofillers, CourseStandard,
|
||||
)
|
||||
from rowers.utils import totaltime_sec_to_string
|
||||
from rowers.tasks import (
|
||||
handle_sendemail_raceregistration, handle_sendemail_racesubmission
|
||||
)
|
||||
@@ -372,8 +371,6 @@ def get_todays_micro(plan, thedate=timezone.now()):
|
||||
if thismicro:
|
||||
thismicro = thismicro[0]
|
||||
else: # pragma: no cover
|
||||
mms = TrainingMicroCycle.objects.all()
|
||||
|
||||
return None
|
||||
|
||||
return thismicro
|
||||
@@ -421,17 +418,14 @@ def add_workouts_plannedsession(ws, ps, r):
|
||||
coursecompleted=False,
|
||||
)
|
||||
record.save()
|
||||
job = myqueue(queue, handle_check_race_course, w.csvfilename,
|
||||
w.id, ps.course.id, record.id,
|
||||
w.user.user.email, w.user.user.first_name,
|
||||
mode='coursetest')
|
||||
_ = myqueue(queue, handle_check_race_course, w.csvfilename,
|
||||
w.id, ps.course.id, record.id,
|
||||
w.user.user.email, w.user.user.first_name,
|
||||
mode='coursetest')
|
||||
if ps.sessiontype == 'fastest_distance': # pragma: no cover
|
||||
records = CourseTestResult.objects.filter(
|
||||
userid=w.user.id, plannedsession=ps)
|
||||
for record in records:
|
||||
#w1 = Workout.objects.get(id=record.workoutid)
|
||||
#w1.plannedsession = None
|
||||
# w1.save()
|
||||
record.delete()
|
||||
|
||||
df = dataprep.getsmallrowdata_db(
|
||||
@@ -463,9 +457,6 @@ def add_workouts_plannedsession(ws, ps, r):
|
||||
records = CourseTestResult.objects.filter(
|
||||
userid=w.user.id, plannedsession=ps)
|
||||
for record in records:
|
||||
#w1 = Workout.objects.get(id=record.workoutid)
|
||||
#w1.plannedsession = None
|
||||
# w1.save()
|
||||
record.delete()
|
||||
|
||||
df = dataprep.getsmallrowdata_db(
|
||||
@@ -638,7 +629,7 @@ def is_session_complete_ws(ws, ps):
|
||||
value *= 1000.
|
||||
|
||||
cratiomin = 1
|
||||
cratiomax = 1
|
||||
# cratiomax = 1
|
||||
|
||||
cratios = {
|
||||
'better than nothing': 0,
|
||||
@@ -651,12 +642,12 @@ def is_session_complete_ws(ws, ps):
|
||||
if ps.criterium == 'none':
|
||||
if ps.sessiontype == 'session':
|
||||
cratiomin = 0.8
|
||||
cratiomax = 1.2
|
||||
# cratiomax = 1.2
|
||||
else:
|
||||
cratios['on target'] = 0.9167
|
||||
cratios['over target'] = 1.0833
|
||||
cratiomin = 0.9167
|
||||
cratiomax = 1.0833
|
||||
# cratiomax = 1.0833
|
||||
|
||||
score = 0
|
||||
completiondate = None
|
||||
@@ -790,10 +781,10 @@ def is_session_complete_ws(ws, ps):
|
||||
coursecompleted=False,
|
||||
)
|
||||
record.save()
|
||||
job = myqueue(queue, handle_check_race_course, ws[0].csvfilename,
|
||||
ws[0].id, ps.course.id, record.id,
|
||||
ws[0].user.user.email, ws[0].user.user.first_name,
|
||||
mode='coursetest')
|
||||
_ = myqueue(queue, handle_check_race_course, ws[0].csvfilename,
|
||||
ws[0].id, ps.course.id, record.id,
|
||||
ws[0].user.user.email, ws[0].user.user.first_name,
|
||||
mode='coursetest')
|
||||
|
||||
return (0, 'not done', None)
|
||||
|
||||
@@ -804,8 +795,6 @@ def is_session_complete_ws(ws, ps):
|
||||
|
||||
|
||||
def is_session_complete(r, ps):
|
||||
verdict = 'not done'
|
||||
|
||||
if r not in ps.rower.all(): # pragma: no cover
|
||||
return 0, 'not assigned', None
|
||||
|
||||
@@ -1290,7 +1279,7 @@ def race_can_submit(r, race):
|
||||
|
||||
if timezone.now() > startdatetime and timezone.now() < evaluation_closure:
|
||||
is_complete, has_registered = race_rower_status(r, race)
|
||||
if is_complete == False:
|
||||
if is_complete is False:
|
||||
return True
|
||||
else:
|
||||
return True
|
||||
@@ -1311,7 +1300,7 @@ def race_can_editentry(r, race):
|
||||
|
||||
if timezone.now() < evaluation_closure:
|
||||
is_complete, has_registered = race_rower_status(r, race)
|
||||
if is_complete == False:
|
||||
if is_complete is False:
|
||||
return True
|
||||
else: # pragma: no cover
|
||||
return False
|
||||
@@ -1594,7 +1583,6 @@ def add_workout_fastestrace(ws, race, r, recordid=0, doregister=False):
|
||||
errors.append('For tests, you can only attach one workout')
|
||||
return result, comments, errors, 0
|
||||
|
||||
username = r.user.first_name+' '+r.user.last_name
|
||||
if r.birthdate:
|
||||
age = calculate_age(r.birthdate)
|
||||
else: # pragma: no cover
|
||||
@@ -1634,7 +1622,6 @@ def add_workout_fastestrace(ws, race, r, recordid=0, doregister=False):
|
||||
records = IndoorVirtualRaceResult.objects.filter(
|
||||
userid=r.id,
|
||||
race=race,
|
||||
#workoutid = ws[0].id
|
||||
)
|
||||
|
||||
if ws[0].workouttype != record.boatclass: # pragma: no cover
|
||||
@@ -1767,7 +1754,6 @@ def add_workout_indoorrace(ws, race, r, recordid=0, doregister=False):
|
||||
errors.append('For tests, you can only attach one workout')
|
||||
return result, comments, errors, 0
|
||||
|
||||
username = r.user.first_name+' '+r.user.last_name
|
||||
if r.birthdate:
|
||||
age = calculate_age(r.birthdate)
|
||||
else: # pragma: no cover
|
||||
@@ -1915,7 +1901,6 @@ def add_workout_race(ws, race, r, splitsecond=0, recordid=0, doregister=False):
|
||||
errors.append('For tests, you can only attach one workout')
|
||||
return result, comments, errors, 0
|
||||
|
||||
username = r.user.first_name+' '+r.user.last_name
|
||||
if r.birthdate:
|
||||
age = calculate_age(r.birthdate)
|
||||
else: # pragma: no cover
|
||||
@@ -1971,8 +1956,6 @@ def add_workout_race(ws, race, r, splitsecond=0, recordid=0, doregister=False):
|
||||
if ws[0].workouttype != record.boatclass: # pragma: no cover
|
||||
ws[0].workouttype = record.boatclass
|
||||
ws[0].save()
|
||||
#errors.append('Your workout boat class is different than on your race registration')
|
||||
# return 0,comments,errors,0
|
||||
|
||||
if ws[0].boattype != record.boattype: # pragma: no cover
|
||||
errors.append(
|
||||
|
||||
+3
-3
@@ -76,8 +76,8 @@ def mkplot(row, title):
|
||||
ax1.set_title(title)
|
||||
plt.grid(True)
|
||||
majorFormatter = FuncFormatter(format_pace_tick)
|
||||
majorLocator = (5)
|
||||
timeTickFormatter = NullFormatter()
|
||||
# majorLocator = (5)
|
||||
# timeTickFormatter = NullFormatter()
|
||||
|
||||
ax1.yaxis.set_major_formatter(majorFormatter)
|
||||
|
||||
@@ -88,7 +88,7 @@ def mkplot(row, title):
|
||||
ax2.plot(t, hr, 'r-')
|
||||
ax2.set_ylabel('Heart Rate', color='r')
|
||||
majorTimeFormatter = FuncFormatter(format_time_tick)
|
||||
majorLocator = (15*60)
|
||||
# majorLocator = (15*60)
|
||||
ax2.xaxis.set_major_formatter(majorTimeFormatter)
|
||||
ax2.patch.set_alpha(0.0)
|
||||
for tl in ax2.get_yticklabels():
|
||||
|
||||
+9
-22
@@ -57,8 +57,6 @@ queuehigh = django_rq.get_queue('high')
|
||||
# Project
|
||||
# from .models import Profile
|
||||
|
||||
|
||||
#baseurl = 'https://polaraccesslink.com/v3-example'
|
||||
baseurl = 'https://polaraccesslink.com/v3'
|
||||
|
||||
|
||||
@@ -125,7 +123,7 @@ def get_token(code):
|
||||
def make_authorization_url(): # pragma: no cover
|
||||
# Generate a random string for the state parameter
|
||||
# Save it for use later to prevent xsrf attacks
|
||||
state = str(uuid4())
|
||||
# state = str(uuid4())
|
||||
|
||||
params = {"client_id": POLAR_CLIENT_ID,
|
||||
"response_type": "code",
|
||||
@@ -155,7 +153,7 @@ def revoke_access(user): # pragma: no cover
|
||||
|
||||
def get_polar_notifications():
|
||||
url = baseurl+'/notifications'
|
||||
state = str(uuid4())
|
||||
# state = str(uuid4())
|
||||
auth_string = '{id}:{secret}'.format(
|
||||
id=POLAR_CLIENT_ID,
|
||||
secret=POLAR_CLIENT_SECRET
|
||||
@@ -302,16 +300,12 @@ def get_polar_workouts(user):
|
||||
'title': '',
|
||||
}
|
||||
|
||||
#session = requests.session()
|
||||
#newHeaders = {'Content-type': 'application/json', 'Accept': 'text/plain'}
|
||||
# session.headers.update(newHeaders)
|
||||
|
||||
url = settings.UPLOAD_SERVICE_URL
|
||||
|
||||
dologging('polar.log', uploadoptions)
|
||||
dologging('polar.log', url)
|
||||
#response = session.post(url,json=uploadoptions)
|
||||
job = myqueue(
|
||||
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_request_post,
|
||||
url,
|
||||
@@ -381,9 +375,6 @@ def register_user(user, token):
|
||||
json=payload,
|
||||
headers=headers
|
||||
)
|
||||
#url = baseurl+'/users'
|
||||
|
||||
#response = requests.post(url,params=params,headers=headers)
|
||||
|
||||
if response.status_code not in [200, 201]: # pragma: no cover
|
||||
# dologging('polar.log',url)
|
||||
@@ -419,10 +410,6 @@ def get_polar_user_info(user, physical=False): # pragma: no cover
|
||||
'Accept': 'application/json'
|
||||
}
|
||||
|
||||
params = {
|
||||
'user-id': r.polaruserid
|
||||
}
|
||||
|
||||
if not physical:
|
||||
url = baseurl+'/users/{userid}'.format(
|
||||
userid=r.polaruserid
|
||||
@@ -478,11 +465,11 @@ def get_polar_workout(user, id, transactionid):
|
||||
exercise_dict = response.json()
|
||||
thisid = exercise_dict['id']
|
||||
if thisid == id:
|
||||
url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}/exercises/{exerciseid}/tcx'.format(
|
||||
userid=r.polaruserid,
|
||||
transactionid=transactionid,
|
||||
exerciseid=id
|
||||
)
|
||||
url = baseurl+'/users/{userid}/exercise-transactions/{transactionid}' \
|
||||
'/exercises/{exerciseid}/tcx'.format(
|
||||
userid=r.polaruserid,
|
||||
transactionid=transactionid,
|
||||
exerciseid=id)
|
||||
authorizationstring = str('Bearer ' + r.polartoken)
|
||||
headers2 = {
|
||||
'Authorization': authorizationstring,
|
||||
|
||||
@@ -19,7 +19,18 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
package='rowing_workout_metrics',
|
||||
syntax='proto3',
|
||||
serialized_options=None,
|
||||
serialized_pb=_b('\n\x1crowing-workout-metrics.proto\x12\x16rowing_workout_metrics\"p\n\x15WorkoutMetricsRequest\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03sex\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\"p\n\x16WorkoutMetricsResponse\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x32w\n\x07Metrics\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest\x1a..rowing_workout_metrics.WorkoutMetricsResponseb\x06proto3')
|
||||
serialized_pb=_b('\n\x1crowing-workout-metrics.proto\x12\x16'
|
||||
'rowing_workout_metrics\"p\n\x15WorkoutMetricsRequest'
|
||||
'\x12\x10\n\x08\x66ilename'
|
||||
'\x18\x01 \x01(\t\x12\x0b\n\x03sex'
|
||||
'\x18\x02 \x01(\t\x12\x0b\n\x03\x66tp\x18\x03 \x01'
|
||||
'(\x01\x12\r\n\x05hrftp\x18\x04 \x01(\x01\x12\r\n\x05hrmax'
|
||||
'\x18\x05 \x01(\x01\x12\r\n\x05hrmin\x18\x06 \x01(\x01\"p\n\x16WorkoutMetricsResponse'
|
||||
'\x12\x0b\n\x03tss\x18\x01 \x01(\x01\x12\r\n\x05normp\x18\x02 \x01(\x01\x12\r\n\x05trimp'
|
||||
'\x18\x03 \x01(\x01\x12\r\n\x05hrtss\x18\x04 \x01(\x01\x12\r\n\x05normv'
|
||||
'\x18\x05 \x01(\x01\x12\r\n\x05normw\x18\x06 \x01(\x01\x32w\n\x07Metrics'
|
||||
'\x12l\n\x0b\x43\x61lcMetrics\x12-.rowing_workout_metrics.WorkoutMetricsRequest'
|
||||
'\x1a..rowing_workout_metrics.WorkoutMetricsResponseb\x06proto3')
|
||||
)
|
||||
|
||||
|
||||
|
||||
+5
-7
@@ -4,7 +4,7 @@ import gzip
|
||||
import shutil
|
||||
import hashlib
|
||||
|
||||
|
||||
from math import isinf, isnan
|
||||
import uuid
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ def validate_image_extension(value):
|
||||
ext = os.path.splitext(value.name)[1].lower()
|
||||
valid_extension = ['.jpg', '.jpeg', '.png', '.gif']
|
||||
|
||||
if not ext in valid_extension: # pragma: no cover
|
||||
if ext not in valid_extension: # pragma: no cover
|
||||
raise ValidationError(u'File not supported')
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ def validate_file_extension(value):
|
||||
'.CSV', '.fit', '.FIT', '.zip', '.ZIP',
|
||||
'.gz', '.GZ', '.xls',
|
||||
'.jpg', '.jpeg', '.tiff', '.png', '.gif', '.bmp']
|
||||
if not ext in valid_extensions: # pragma: no cover
|
||||
if ext not in valid_extensions: # pragma: no cover
|
||||
raise ValidationError(u'File not supported!')
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ def must_be_csv(value):
|
||||
import os
|
||||
ext = os.path.splitext(value.name)[1]
|
||||
valid_extensions = ['.csv', '.CSV']
|
||||
if not ext in valid_extensions: # pragma: no cover
|
||||
if ext not in valid_extensions: # pragma: no cover
|
||||
raise ValidationError(u'File not supported!')
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ def validate_kml(value):
|
||||
import os
|
||||
ext = os.path.splitext(value.name)[1]
|
||||
valid_extensions = ['.kml', '.KML']
|
||||
if not ext in valid_extensions: # pragma: no cover
|
||||
if ext not in valid_extensions: # pragma: no cover
|
||||
raise ValidationError(u'File not supported!')
|
||||
|
||||
|
||||
@@ -144,8 +144,6 @@ def handle_uploaded_file(f):
|
||||
fname = f.name
|
||||
ext = fname.split('.')[-1]
|
||||
fname = '%s.%s' % (uuid.uuid4(), ext)
|
||||
#timestr = uuid.uuid4().hex[:10]+'-'+time.strftime("%Y%m%d-%H%M%S")
|
||||
#fname = timestr+'-'+fname
|
||||
fname2 = 'media/'+fname
|
||||
with open(fname2, 'wb+') as destination:
|
||||
for chunk in f.chunks():
|
||||
|
||||
+2
-15
@@ -6,8 +6,6 @@ from rowers.tasks import handle_rp3_async_workout
|
||||
from rowsandall_app.settings import (
|
||||
C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET,
|
||||
STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET,
|
||||
RP3_CLIENT_ID, RP3_CLIENT_SECRET,
|
||||
RP3_REDIRECT_URI, RP3_CLIENT_KEY,
|
||||
RP3_CLIENT_ID, RP3_CLIENT_KEY, RP3_REDIRECT_URI, RP3_CLIENT_SECRET,
|
||||
UPLOAD_SERVICE_URL, UPLOAD_SERVICE_SECRET
|
||||
)
|
||||
@@ -29,8 +27,6 @@ queuelow = django_rq.get_queue('low')
|
||||
queuehigh = django_rq.get_queue('high')
|
||||
|
||||
|
||||
#from async_messages import message_user,messages
|
||||
|
||||
oauth_data = {
|
||||
'client_id': RP3_CLIENT_ID,
|
||||
'client_secret': RP3_CLIENT_SECRET,
|
||||
@@ -64,8 +60,6 @@ def do_refresh_token(refreshtoken): # pragma: no cover
|
||||
|
||||
|
||||
def get_token(code): # pragma: no cover
|
||||
client_auth = requests.auth.HTTPBasicAuth(
|
||||
RP3_CLIENT_KEY, RP3_CLIENT_SECRET)
|
||||
post_data = {
|
||||
"client_id": RP3_CLIENT_KEY,
|
||||
"grant_type": "authorization_code",
|
||||
@@ -73,9 +67,6 @@ def get_token(code): # pragma: no cover
|
||||
"redirect_uri": RP3_REDIRECT_URI,
|
||||
"client_secret": RP3_CLIENT_SECRET,
|
||||
}
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
"https://rp3rowing-app.com/oauth/token",
|
||||
@@ -102,8 +93,6 @@ def make_authorization_url(request): # pragma: no cover
|
||||
|
||||
|
||||
def get_rp3_workout_list(user):
|
||||
r = Rower.objects.get(user=user)
|
||||
|
||||
auth_token = rp3_open(user)
|
||||
|
||||
headers = {'Authorization': 'Bearer ' + auth_token}
|
||||
@@ -148,13 +137,13 @@ def get_rp3_workouts(rower, do_async=True): # pragma: no cover
|
||||
w.uploadedtorp3 for w in Workout.objects.filter(user=rower)
|
||||
])
|
||||
|
||||
newids = [rp3id for rp3id in rp3ids if not rp3id in knownrp3ids]
|
||||
newids = [rp3id for rp3id in rp3ids if rp3id not in knownrp3ids]
|
||||
|
||||
for id in newids:
|
||||
startdatetime = workouts_list.loc[id, 'executed_at']
|
||||
dologging('rp3_import.log', startdatetime)
|
||||
|
||||
job = myqueue(
|
||||
_ = myqueue(
|
||||
queuehigh,
|
||||
handle_rp3_async_workout,
|
||||
rower.user.id,
|
||||
@@ -221,7 +210,6 @@ def get_rp3_workout_token(workout_id, auth_token, waittime=3, max_attempts=20):
|
||||
|
||||
|
||||
def get_rp3_workout_link(user, workout_id, waittime=3, max_attempts=20): # pragma: no cover
|
||||
r = Rower.objects.get(user=user)
|
||||
auth_token = rp3_open(user)
|
||||
|
||||
return get_rp3_workout_token(workout_id, auth_token, waittime=waittime, max_attempts=max_attempts)
|
||||
@@ -231,7 +219,6 @@ def get_rp3_workout(user, workout_id, startdatetime=None): # pragma: no cover
|
||||
url = get_rp3_workout_link(user, workout_id)
|
||||
filename = 'media/RP3Import_'+str(workout_id)+'.csv'
|
||||
|
||||
r = Rower.objects.get(user=user)
|
||||
auth_token = rp3_open(user)
|
||||
|
||||
if not startdatetime:
|
||||
|
||||
@@ -6,7 +6,7 @@ from rest_framework import serializers
|
||||
from rowers.models import (
|
||||
Workout, Rower, FavoriteChart, VirtualRaceResult,
|
||||
VirtualRace, GeoCourse, StandardCollection, CourseStandard,
|
||||
GeoCourse, GeoPolygon, GeoPoint, PlannedSession,
|
||||
GeoPolygon, GeoPoint, PlannedSession,
|
||||
)
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
@@ -164,7 +164,7 @@ def createsporttracksworkoutdata(w):
|
||||
return 0
|
||||
|
||||
# adding diff, trying to see if this is valid
|
||||
#t = row.df.loc[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)']
|
||||
# t = row.df.loc[:,'TimeStamp (sec)'].values-10*row.df.ix[0,'TimeStamp (sec)']
|
||||
t = row.df.loc[:, 'TimeStamp (sec)'].values - \
|
||||
row.df.loc[:, 'TimeStamp (sec)'].iloc[0]
|
||||
try:
|
||||
@@ -293,7 +293,6 @@ def workout_sporttracks_upload(user, w, asynchron=False): # pragma: no cover
|
||||
message = "Uploading to SportTracks"
|
||||
stid = 0
|
||||
# ready to upload. Hurray
|
||||
r = w.user
|
||||
|
||||
thetoken = sporttracks_open(user)
|
||||
|
||||
@@ -311,8 +310,8 @@ def workout_sporttracks_upload(user, w, asynchron=False): # pragma: no cover
|
||||
|
||||
url = "https://api.sporttracks.mobi/api/v2/fitnessActivities.json"
|
||||
if asynchron:
|
||||
job = myqueue(queue, handle_sporttracks_sync,
|
||||
w.id, url, headers, json.dumps(data, default=default))
|
||||
_ = myqueue(queue, handle_sporttracks_sync,
|
||||
w.id, url, headers, json.dumps(data, default=default))
|
||||
return "Asynchronous sync", 0
|
||||
|
||||
response = requests.post(url, headers=headers,
|
||||
@@ -398,9 +397,9 @@ def add_workout_from_data(user, importid, data, strokedata, source='sporttracks'
|
||||
return (0, "No distance or heart rate data in the workout")
|
||||
|
||||
try:
|
||||
l = data['location']
|
||||
locs = data['location']
|
||||
|
||||
res = splitstdata(l)
|
||||
res = splitstdata(locs)
|
||||
times_location = res[0]
|
||||
latlong = res[1]
|
||||
latcoord = []
|
||||
@@ -492,8 +491,6 @@ def add_workout_from_data(user, importid, data, strokedata, source='sporttracks'
|
||||
|
||||
df.sort_values(by='TimeStamp (sec)', ascending=True)
|
||||
|
||||
timestr = strftime("%Y%m%d-%H%M%S")
|
||||
|
||||
# csvfilename ='media/Import_'+str(importid)+'.csv'
|
||||
csvfilename = 'media/{code}_{importid}.csv'.format(
|
||||
importid=importid,
|
||||
|
||||
+16
-19
@@ -82,7 +82,7 @@ def strava_open(user):
|
||||
f.write('\n')
|
||||
token = imports_open(user, oauth_data)
|
||||
if user.rower.strava_owner_id == 0: # pragma: no cover
|
||||
strava_owner_id = set_strava_athlete_id(user)
|
||||
_ = set_strava_athlete_id(user)
|
||||
return token
|
||||
|
||||
|
||||
@@ -120,9 +120,6 @@ def strava_establish_push(): # pragma: no cover
|
||||
'callback_url': webhooklink,
|
||||
'verify_token': webhookverification,
|
||||
}
|
||||
headers = {'user-agent': 'sanderroosendaal',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': oauth_data['content_type']}
|
||||
|
||||
response = requests.post(url, data=post_data)
|
||||
|
||||
@@ -160,7 +157,7 @@ def set_strava_athlete_id(user):
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401, s)
|
||||
elif (r.stravatokenexpirydate is None or timezone.now()+timedelta(seconds=3599) > r.stravatokenexpirydate):
|
||||
token = imports_open(user, oauth_data)
|
||||
_ = imports_open(user, oauth_data)
|
||||
|
||||
authorizationstring = str('Bearer ' + r.stravatoken)
|
||||
headers = {'Authorization': authorizationstring,
|
||||
@@ -185,7 +182,9 @@ def get_strava_workout_list(user, limit_n=0):
|
||||
if (r.stravatoken == '') or (r.stravatoken is None): # pragma: no cover
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
return custom_exception_handler(401, s)
|
||||
elif (r.stravatokenexpirydate is None or timezone.now()+timedelta(seconds=3599) > r.stravatokenexpirydate): # pragma: no cover
|
||||
elif (
|
||||
r.stravatokenexpirydate is None or timezone.now()+timedelta(seconds=3599) > r.stravatokenexpirydate
|
||||
): # pragma: no cover
|
||||
s = "Token expired. Needs to refresh."
|
||||
return custom_exception_handler(401, s)
|
||||
else:
|
||||
@@ -209,7 +208,7 @@ def get_strava_workout_list(user, limit_n=0):
|
||||
|
||||
def async_get_workout(user, stravaid):
|
||||
try:
|
||||
token = strava_open(user)
|
||||
_ = strava_open(user)
|
||||
except NoTokenError: # pragma: no cover
|
||||
return 0
|
||||
|
||||
@@ -246,9 +245,9 @@ def createstravaworkoutdata(w, dozip=True):
|
||||
|
||||
if datalength != 0:
|
||||
data.rename(columns=columndict, inplace=True)
|
||||
res = data.to_csv(w.csvfilename+'.gz',
|
||||
index_label='index',
|
||||
compression='gzip')
|
||||
_ = data.to_csv(w.csvfilename+'.gz',
|
||||
index_label='index',
|
||||
compression='gzip')
|
||||
try:
|
||||
row = rowingdata(csvfile=filename)
|
||||
except IOError:
|
||||
@@ -317,7 +316,7 @@ def handle_stravaexport(f2, workoutname, stravatoken, description='',
|
||||
|
||||
def workout_strava_upload(user, w, quick=False, asynchron=True):
|
||||
try:
|
||||
thetoken = strava_open(user)
|
||||
_ = strava_open(user)
|
||||
except NoTokenError: # pragma: no cover
|
||||
return "Please connect to Strava first", 0
|
||||
|
||||
@@ -326,7 +325,6 @@ def workout_strava_upload(user, w, quick=False, asynchron=True):
|
||||
r = Rower.objects.get(user=user)
|
||||
res = -1
|
||||
if (r.stravatoken == '') or (r.stravatoken is None): # pragma: no cover
|
||||
s = "Token doesn't exist. Need to authorize"
|
||||
raise NoTokenError("Your hovercraft is full of eels")
|
||||
|
||||
if (is_workout_user(user, w)):
|
||||
@@ -340,13 +338,12 @@ def workout_strava_upload(user, w, quick=False, asynchron=True):
|
||||
activity_type = mytypes.stravamapping[w.workouttype]
|
||||
except KeyError: # pragma: no cover
|
||||
activity_type = 'Rowing'
|
||||
job = myqueue(queue,
|
||||
handle_strava_sync,
|
||||
r.stravatoken,
|
||||
w.id,
|
||||
tcxfile, w.name, activity_type,
|
||||
w.notes
|
||||
)
|
||||
_ = myqueue(queue,
|
||||
handle_strava_sync,
|
||||
r.stravatoken,
|
||||
w.id,
|
||||
tcxfile, w.name, activity_type,
|
||||
w.notes)
|
||||
dologging('strava_export_log.log', 'Exporting as {t} from {w}'.format(
|
||||
t=activity_type, w=w.workouttype))
|
||||
return "Asynchronous sync", -1
|
||||
|
||||
+272
-427
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,8 @@ import time
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
from django.contrib import messages
|
||||
|
||||
proj_path = "../"
|
||||
sys.path.append(proj_path)
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "rowsandall_app.settings")
|
||||
@@ -15,11 +17,7 @@ django.setup()
|
||||
|
||||
@app.task
|
||||
def addcomment2(userid, id, debug=False):
|
||||
|
||||
time.sleep(5)
|
||||
# w = Workout.objects.get(id=id)
|
||||
# w.notes += '\n the task has run'
|
||||
# w.save()
|
||||
u = User.objects.get(id=userid)
|
||||
messages.info(u, ' The task has run')
|
||||
messages.error(u, ' Het is veel te laat')
|
||||
|
||||
+51
-61
@@ -88,7 +88,7 @@ def create_team(name, manager, private='open', notes='', viewing='allmembers'):
|
||||
private=private, viewing=viewing)
|
||||
t.save()
|
||||
r = Rower.objects.get(user=manager)
|
||||
res = add_member(t.id, r)
|
||||
_ = add_member(t.id, r)
|
||||
except IntegrityError:
|
||||
return (0, 'Team name duplication')
|
||||
return (t.id, 'Team created')
|
||||
@@ -131,13 +131,13 @@ def add_member(id, rower):
|
||||
# code to add all workouts
|
||||
ws = Workout.objects.filter(user=rower)
|
||||
|
||||
res = handle_add_workouts_team(ws, t)
|
||||
_ = handle_add_workouts_team(ws, t)
|
||||
|
||||
# code to add plannedsessions
|
||||
plannedsessions = PlannedSession.objects.filter(
|
||||
team=t, enddate__gte=timezone.now().date())
|
||||
for ps in plannedsessions: # pragma: no cover
|
||||
res = ps.rower.add(rower)
|
||||
_ = ps.rower.add(rower)
|
||||
|
||||
# set_teamplanexpires(rower)
|
||||
# code for Stuck At Home Team (temporary)
|
||||
@@ -154,7 +154,7 @@ def remove_member(id, rower):
|
||||
# remove the team from rower's workouts:
|
||||
ws = Workout.objects.filter(user=rower, team=t)
|
||||
|
||||
res = handle_remove_workouts_team(ws, t)
|
||||
_ = handle_remove_workouts_team(ws, t)
|
||||
|
||||
# set_teamplanexpires(rower)
|
||||
return (id, 'Member removed')
|
||||
@@ -270,9 +270,9 @@ def send_coachrequest_email(rekwest):
|
||||
|
||||
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_coachrequest,
|
||||
email, name, code, coachname)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_coachrequest,
|
||||
email, name, code, coachname)
|
||||
|
||||
|
||||
def send_coacheerequest_email(rekwest):
|
||||
@@ -283,14 +283,13 @@ def send_coacheerequest_email(rekwest):
|
||||
|
||||
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_coacheerequest,
|
||||
email, name, code, coachname)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_coacheerequest,
|
||||
email, name, code, coachname)
|
||||
|
||||
|
||||
def create_request(team, user):
|
||||
r2 = Rower.objects.get(user=user)
|
||||
r = Rower.objects.get(user=team.manager)
|
||||
if r2 in Rower.objects.filter(team=team): # pragma: no cover
|
||||
return (0, 'Already a member of that team')
|
||||
|
||||
@@ -323,8 +322,6 @@ def get_coach_club_size(coach):
|
||||
|
||||
# request by coach to coach user
|
||||
def create_coaching_offer(coach, user):
|
||||
r = user.rower
|
||||
|
||||
if coach in rower_get_coaches(user.rower): # pragma: no cover
|
||||
return (0, 'You are already coaching this person.')
|
||||
|
||||
@@ -348,7 +345,6 @@ def create_coaching_offer(coach, user):
|
||||
|
||||
|
||||
def create_invite(team, manager, user=None, email=''):
|
||||
r = Rower.objects.get(user=manager)
|
||||
if not is_team_manager(manager, team):
|
||||
return (0, 'Not the team manager')
|
||||
if user:
|
||||
@@ -359,7 +355,7 @@ def create_invite(team, manager, user=None, email=''):
|
||||
return (0, 'Rower does not exist')
|
||||
if r2 in Rower.objects.filter(team=team):
|
||||
return (0, 'Already member of that team')
|
||||
elif email == None or email == '': # pragma: no cover
|
||||
elif email is None or email == '': # pragma: no cover
|
||||
return (0, 'Invalid request - missing email or user')
|
||||
else:
|
||||
try:
|
||||
@@ -390,13 +386,11 @@ def revoke_request(user, id):
|
||||
except TeamRequest.DoesNotExist: # pragma: no cover
|
||||
return (0, 'The request is invalid')
|
||||
|
||||
t = rekwest.team
|
||||
|
||||
if rekwest.user == user:
|
||||
rekwest.delete()
|
||||
return (1, 'Request revoked')
|
||||
else: # pragma: no cover
|
||||
return (0, 'You are not the requestor')
|
||||
|
||||
return (0, 'You are not the requestor') # pragma: no cover
|
||||
|
||||
|
||||
def reject_revoke_coach_offer(user, id):
|
||||
@@ -493,9 +487,9 @@ def send_invite_email(id):
|
||||
manager = invitation.team.manager.first_name + \
|
||||
' '+invitation.team.manager.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_invite,
|
||||
email, name, code, teamname, manager)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_invite,
|
||||
email, name, code, teamname, manager)
|
||||
|
||||
return (1, 'Invitation email sent')
|
||||
|
||||
@@ -506,9 +500,9 @@ def send_team_delete_mail(t, rower):
|
||||
email = u.email
|
||||
name = u.first_name+' '+u.last_name
|
||||
manager = t.manager.first_name+' '+t.manager.last_name
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_team_removed,
|
||||
email, name, teamname, manager)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_team_removed,
|
||||
email, name, teamname, manager)
|
||||
|
||||
return (1, 'Team delete email sent')
|
||||
|
||||
@@ -521,41 +515,38 @@ def send_email_member_dropped(teamid, rower):
|
||||
name = u.first_name+' '+u.last_name
|
||||
manager = t.manager.first_name+' '+t.manager.last_name
|
||||
|
||||
res = myqueue(queuehigh, handle_sendemail_member_dropped,
|
||||
email, name, teamname, manager)
|
||||
_ = myqueue(queuehigh, handle_sendemail_member_dropped,
|
||||
email, name, teamname, manager)
|
||||
|
||||
return (1, 'Member dropped email sent')
|
||||
|
||||
|
||||
def send_request_accept_email(rekwest): # pragma: no cover
|
||||
id = rekwest.id
|
||||
email = rekwest.user.email
|
||||
teamname = rekwest.team.name
|
||||
name = rekwest.user.first_name+' '+rekwest.user.last_name
|
||||
manager = rekwest.team.manager.first_name+' '+rekwest.team.manager.last_name
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_request_accept,
|
||||
email, name, teamname, manager)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_request_accept,
|
||||
email, name, teamname, manager)
|
||||
|
||||
return (1, 'Invitation email sent')
|
||||
|
||||
|
||||
def send_request_reject_email(rekwest):
|
||||
id = rekwest.id
|
||||
teamname = rekwest.team.name
|
||||
email = rekwest.user.email
|
||||
name = rekwest.user.first_name+' '+rekwest.user.last_name
|
||||
manager = rekwest.team.manager.first_name+' '+rekwest.team.manager.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_request_reject,
|
||||
email, name, teamname, manager)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_request_reject,
|
||||
email, name, teamname, manager)
|
||||
|
||||
return (1, 'Invitation email sent')
|
||||
|
||||
|
||||
def send_invite_reject_email(invitation):
|
||||
id = invitation.id
|
||||
email = invitation.team.manager.email
|
||||
if invitation.user:
|
||||
name = invitation.user.first_name+' '+invitation.user.last_name
|
||||
@@ -566,15 +557,14 @@ def send_invite_reject_email(invitation):
|
||||
manager = invitation.team.manager.first_name + \
|
||||
' '+invitation.team.manager.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_invite_reject,
|
||||
email, name, teamname, manager)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_invite_reject,
|
||||
email, name, teamname, manager)
|
||||
|
||||
return (1, 'Invitation email sent')
|
||||
|
||||
|
||||
def send_invite_accept_email(invitation): # pragma: no cover
|
||||
id = invitation.id
|
||||
email = invitation.team.manager.email
|
||||
if invitation.user:
|
||||
name = invitation.user.first_name+' '+invitation.user.last_name
|
||||
@@ -585,9 +575,9 @@ def send_invite_accept_email(invitation): # pragma: no cover
|
||||
manager = invitation.team.manager.first_name + \
|
||||
' '+invitation.team.manager.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_invite_accept,
|
||||
email, name, teamname, manager)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_invite_accept,
|
||||
email, name, teamname, manager)
|
||||
|
||||
return (1, 'Invitation email sent')
|
||||
|
||||
@@ -598,9 +588,9 @@ def send_team_message(team, message): # pragma: no cover
|
||||
|
||||
for rower in rowers:
|
||||
rowername = rower.user.first_name + " " + rower.user.last_name
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_message,
|
||||
rower.user.email, team.manager.email, rowername, message, team.name, managername)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_message,
|
||||
rower.user.email, team.manager.email, rowername, message, team.name, managername)
|
||||
|
||||
return (1, 'message sent')
|
||||
|
||||
@@ -613,9 +603,9 @@ def send_request_email(rekwest):
|
||||
teamname = rekwest.team.name
|
||||
requestor = rekwest.user.first_name+' '+rekwest.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_request,
|
||||
email, name, code, teamname, requestor, id)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_request,
|
||||
email, name, code, teamname, requestor, id)
|
||||
|
||||
return (1, 'Invitation email sent')
|
||||
|
||||
@@ -729,9 +719,9 @@ def send_coachoffer_rejected_email(rekwest):
|
||||
|
||||
name = rekwest.user.first_name + " " + rekwest.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_coachoffer_rejected,
|
||||
coachemail, coachname, name)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_coachoffer_rejected,
|
||||
coachemail, coachname, name)
|
||||
|
||||
|
||||
def send_coachrequest_rejected_email(rekwest):
|
||||
@@ -740,9 +730,9 @@ def send_coachrequest_rejected_email(rekwest):
|
||||
|
||||
name = rekwest.user.first_name + " " + rekwest.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_coachrequest_rejected,
|
||||
email, coachname, name)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_coachrequest_rejected,
|
||||
email, coachname, name)
|
||||
|
||||
|
||||
def send_coachrequest_accepted_email(rekwest):
|
||||
@@ -751,9 +741,9 @@ def send_coachrequest_accepted_email(rekwest):
|
||||
|
||||
name = rekwest.user.first_name + " " + rekwest.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_coachrequest_accepted,
|
||||
email, coachname, name)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_coachrequest_accepted,
|
||||
email, coachname, name)
|
||||
|
||||
|
||||
def send_coachoffer_accepted_email(rekwest):
|
||||
@@ -762,6 +752,6 @@ def send_coachoffer_accepted_email(rekwest):
|
||||
|
||||
name = rekwest.user.first_name + " " + rekwest.user.last_name
|
||||
|
||||
res = myqueue(queuehigh,
|
||||
handle_sendemail_coachoffer_accepted,
|
||||
coachemail, coachname, name)
|
||||
_ = myqueue(queuehigh,
|
||||
handle_sendemail_coachoffer_accepted,
|
||||
coachemail, coachname, name)
|
||||
|
||||
+1
-6
@@ -21,8 +21,6 @@ from rowsandall_app.settings import (
|
||||
|
||||
tpapilocation = "https://api.trainingpeaks.com"
|
||||
|
||||
#from async_messages import message_user,messages
|
||||
|
||||
oauth_data = {
|
||||
'client_id': TP_CLIENT_ID,
|
||||
'client_secret': TP_CLIENT_SECRET,
|
||||
@@ -53,7 +51,7 @@ def do_refresh_token(refreshtoken):
|
||||
|
||||
|
||||
def get_token(code):
|
||||
client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
|
||||
# client_auth = requests.auth.HTTPBasicAuth(TP_CLIENT_KEY, TP_CLIENT_SECRET)
|
||||
post_data = {
|
||||
"client_id": TP_CLIENT_KEY,
|
||||
"grant_type": "authorization_code",
|
||||
@@ -61,9 +59,6 @@ def get_token(code):
|
||||
"redirect_uri": TP_REDIRECT_URI,
|
||||
"client_secret": TP_CLIENT_SECRET,
|
||||
}
|
||||
headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}
|
||||
|
||||
response = requests.post(
|
||||
"https://oauth.trainingpeaks.com/oauth/token",
|
||||
|
||||
@@ -151,8 +151,6 @@ class TraverseLinksTest(TestCase):
|
||||
if response.status_code == 200:
|
||||
soup = BeautifulSoup(response.content, 'html.parser')
|
||||
|
||||
text = soup.get_text()
|
||||
|
||||
for link in soup.find_all('a'):
|
||||
new_link = link.get('href')
|
||||
if VERBOSE:
|
||||
|
||||
+11
-12
@@ -87,7 +87,7 @@ def make_plot(r, w, f1, f2, plottype, title, imagename='', plotnr=0):
|
||||
}
|
||||
|
||||
axis = r.staticgrids
|
||||
if axis == None: # pragma: no cover
|
||||
if axis is None: # pragma: no cover
|
||||
gridtrue = False
|
||||
axis = 'both'
|
||||
else:
|
||||
@@ -133,14 +133,14 @@ def do_sync(w, options, quick=False):
|
||||
|
||||
do_strava_export = w.user.strava_auto_export
|
||||
try:
|
||||
upload_to_strava = options['upload_to_Strava'] or do_strava_export
|
||||
do_strava_export = options['upload_to_Strava'] or do_strava_export
|
||||
except KeyError:
|
||||
upload_to_strava = False
|
||||
pass
|
||||
|
||||
try:
|
||||
if options['stravaid'] != 0 and options['stravaid'] != '': # pragma: no cover
|
||||
w.uploadedtostrava = options['stravaid']
|
||||
upload_to_strava = False
|
||||
# upload_to_strava = False
|
||||
do_strava_export = False
|
||||
w.save()
|
||||
except KeyError:
|
||||
@@ -174,14 +174,14 @@ def do_sync(w, options, quick=False):
|
||||
|
||||
do_c2_export = w.user.c2_auto_export
|
||||
try:
|
||||
upload_to_c2 = options['upload_to_C2'] or do_c2_export
|
||||
do_c2_export = options['upload_to_C2'] or do_c2_export
|
||||
except KeyError:
|
||||
upload_to_c2 = False
|
||||
pass
|
||||
|
||||
try:
|
||||
if options['c2id'] != 0 and options['c2id'] != '': # pragma: no cover
|
||||
w.uploadedtoc2 = options['c2id']
|
||||
upload_to_c2 = False
|
||||
# upload_to_c2 = False
|
||||
do_c2_export = False
|
||||
w.save()
|
||||
except KeyError:
|
||||
@@ -250,16 +250,15 @@ def do_sync(w, options, quick=False):
|
||||
with open('st_export.log', 'a') as logfile:
|
||||
logfile.write(str(timezone.now())+': ')
|
||||
logfile.write(str(w.user)+' NoTokenError\n')
|
||||
message = "Please connect to SportTracks first"
|
||||
id = 0
|
||||
|
||||
return 0
|
||||
|
||||
if ('upload_to_TrainingPeaks' in options and options['upload_to_TrainingPeaks']) or (w.user.trainingpeaks_auto_export): # pragma: no cover
|
||||
try:
|
||||
message, id = tpstuff.workout_tp_upload(
|
||||
_, id = tpstuff.workout_tp_upload(
|
||||
w.user.user, w
|
||||
)
|
||||
except NoTokenError:
|
||||
message = "Please connect to TrainingPeaks first"
|
||||
id = 0
|
||||
return 0
|
||||
|
||||
return 1
|
||||
|
||||
+23
-17
@@ -17,7 +17,6 @@ from rest_framework.permissions import *
|
||||
from rowers import views
|
||||
from django.contrib.auth import views as auth_views
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.utils.decorators import method_decorator
|
||||
|
||||
from rowers.permissions import (
|
||||
IsOwnerOrNot, IsOwnerOrReadOnly,
|
||||
@@ -71,7 +70,7 @@ class PlannedSessionViewSet(viewsets.ModelViewSet):
|
||||
|
||||
class WorkoutViewSet(viewsets.ModelViewSet):
|
||||
model = Workout
|
||||
#queryset = Workout.objects.all().order_by("-date", "-starttime")
|
||||
|
||||
serializer_class = WorkoutSerializer
|
||||
|
||||
def get_queryset(self): # pragma: no cover
|
||||
@@ -90,7 +89,6 @@ class WorkoutViewSet(viewsets.ModelViewSet):
|
||||
class RowerViewSet(viewsets.ModelViewSet):
|
||||
model = Rower
|
||||
serializer_class = RowerSerializer
|
||||
#queryset = Rower.objects.all()
|
||||
|
||||
def get_queryset(self): # pragma: no cover
|
||||
try:
|
||||
@@ -109,7 +107,6 @@ class RowerViewSet(viewsets.ModelViewSet):
|
||||
class FavoriteChartViewSet(viewsets.ModelViewSet):
|
||||
model = FavoriteChart
|
||||
serializer_class = FavoriteChartSerializer
|
||||
#queryset = FavoriteChart.objects.all()
|
||||
|
||||
def get_queryset(self): # pragma: no cover
|
||||
try:
|
||||
@@ -235,8 +232,6 @@ handler400 = views.error400_view
|
||||
handler500 = views.error500_view
|
||||
|
||||
|
||||
#app_name = "rowers"
|
||||
|
||||
urlpatterns = [
|
||||
re_path(r'^o/authorize/$', base.AuthorizationView.as_view(), name="authorize"),
|
||||
re_path(r'^o/token/$', base.TokenView.as_view(), name="token"),
|
||||
@@ -352,17 +347,21 @@ urlpatterns = [
|
||||
re_path(r'^workouts-join-select/user/(?P<userid>\d+)/$',
|
||||
views.workouts_join_select, name='workouts_join_select'),
|
||||
re_path(
|
||||
r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
|
||||
r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(
|
||||
r'^user-analysis-select/(?P<function>\w.*)/session/(?P<session>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
|
||||
r'^user-analysis-select/(?P<function>\w.*)/session/(?P<session>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(
|
||||
r'^user-analysis-select/(?P<function>\w.*)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
|
||||
r'^user-analysis-select/(?P<function>\w.*)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/user/(?P<userid>\d+)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/(?P<function>\w.*)/team/(?P<teamid>\d+)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(
|
||||
r'^user-analysis-select/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.analysis_new, name='analysis_new'),
|
||||
r'^user-analysis-select/team/(?P<teamid>\d+)/workout/(?P<id>\b[0-9A-Fa-f]+\b)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/user/(?P<userid>\d+)/$',
|
||||
views.analysis_new, name='analysis_new'),
|
||||
re_path(r'^user-analysis-select/team/(?P<teamid>\d+)/$',
|
||||
@@ -613,7 +612,8 @@ urlpatterns = [
|
||||
views.workout_nkimport_view, name='workout_nkimport_view'),
|
||||
re_path(r'^workout/nkimport/all/$', views.workout_getnkworkout_all,
|
||||
name='workout_getnkworkout_all'),
|
||||
re_path(r'^workout/nkimport/all/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$', views.workout_getnkworkout_all,
|
||||
re_path(r'^workout/nkimport/all/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',
|
||||
views.workout_getnkworkout_all,
|
||||
name='workout_getnkworkout_all'),
|
||||
re_path(r'^workout/rp3import/(?P<externalid>\d+)/$', views.workout_getrp3importview,
|
||||
name='workout_getrp3importview'),
|
||||
@@ -853,12 +853,16 @@ urlpatterns = [
|
||||
name='workout_workflow_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/courses/$', views.workout_course_view,
|
||||
name='workout_course_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/(?P<xparam>[\w\ ]+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/'\
|
||||
'(?P<xparam>[\w\ ]+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+)/$',
|
||||
views.workout_flexchart3_view, name='workout_flexchart3_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)/$',
|
||||
views.workout_flexchart3_view, name='workout_flexchart3_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/$',
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/'\
|
||||
'(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/(?P<plottype>\w+.*)/$',
|
||||
views.workout_flexchart3_view, name='workout_flexchart3_view'),
|
||||
re_path(
|
||||
r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/'\
|
||||
'(?P<xparam>\w+.*)/(?P<yparam1>[\w\ ]+.*)/(?P<yparam2>[\w\ ]+.*)/$',
|
||||
views.workout_flexchart3_view, name='workout_flexchart3_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchart/$',
|
||||
views.workout_flexchart3_view, name='workout_flexchart3_view'),
|
||||
re_path(r'^workout/(?P<id>\b[0-9A-Fa-f]+\b)/flexchartstacked/$',
|
||||
@@ -1002,7 +1006,8 @@ urlpatterns = [
|
||||
name='plannedsession_teamclone_view'),
|
||||
re_path(r'^sessions/(?P<id>\d+)/clone/$', views.plannedsession_clone_view),
|
||||
re_path(
|
||||
r'^sessions/(?P<psid>\d+)/detach/(?P<id>\b[0-9A-Fa-f]+\b)/user/(?P<userid>\d+)/$', views.plannedsession_detach_view),
|
||||
r'^sessions/(?P<psid>\d+)/detach/(?P<id>\b[0-9A-Fa-f]+\b)/user/(?P<userid>\d+)/$',
|
||||
views.plannedsession_detach_view),
|
||||
re_path(
|
||||
r'^sessions/(?P<psid>\d+)/detach/(?P<id>\b[0-9A-Fa-f]+\b)/$', views.plannedsession_detach_view),
|
||||
re_path(r'^sessions/(?P<id>\d+)/$', views.plannedsession_view,
|
||||
@@ -1043,7 +1048,8 @@ urlpatterns = [
|
||||
name='plannedsessions_print_view'),
|
||||
re_path(r'^sessions/(?P<id>\d+)/message/$', views.plannedsession_message_view,
|
||||
name='plannedsession_message_view'),
|
||||
re_path(r'^sessions/print/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$', views.plannedsessions_print_view,
|
||||
re_path(r'^sessions/print/user/(?P<userid>\d+)/(?P<startdatestring>\d+-\d+-\d+)/(?P<enddatestring>\d+-\d+-\d+)/$',
|
||||
views.plannedsessions_print_view,
|
||||
name='plannedsessions_print_view'),
|
||||
re_path(r'^sessions/sendcalendar/$', views.plannedsessions_icsemail_view,
|
||||
name='plannedsessions_coach_icsemail_view'),
|
||||
|
||||
+27
-28
@@ -16,14 +16,11 @@ import datetime
|
||||
import json
|
||||
import time
|
||||
from fitparse import FitFile
|
||||
from django.conf import settings
|
||||
|
||||
from django.http import HttpResponse
|
||||
|
||||
import requests
|
||||
|
||||
from django.http import HttpResponse
|
||||
|
||||
import humanize
|
||||
from pytz.exceptions import UnknownTimeZoneError
|
||||
import pytz
|
||||
@@ -189,7 +186,6 @@ palettes = {
|
||||
'gold_sunset': (47, -31, .26, -0.12, 0.94, -0.5),
|
||||
'blue_red': (207, -200, .85, 0, .74, -.24),
|
||||
'blue_green': (207, -120, .85, 0, .75, .25),
|
||||
'cyan_green': (192, -50, .08, .65, .98, -.34),
|
||||
'cyan_purple': trcolors(237, 248, 251, 136, 65, 157),
|
||||
'green_blue': trcolors(240, 249, 232, 8, 104, 172),
|
||||
'orange_red': trcolors(254, 240, 217, 179, 0, 0),
|
||||
@@ -237,7 +233,8 @@ def str2bool(v): # pragma: no cover
|
||||
def uniqify(seq, idfun=None):
|
||||
# order preserving
|
||||
if idfun is None:
|
||||
def idfun(x): return x
|
||||
def idfun(x):
|
||||
return x
|
||||
seen = {}
|
||||
result = []
|
||||
for item in seq:
|
||||
@@ -465,14 +462,14 @@ def totaltime_sec_to_string(totaltime, shorten=False):
|
||||
hours=hours,
|
||||
minutes=minutes,
|
||||
seconds=seconds,
|
||||
tenths=tenths
|
||||
# tenths=tenths
|
||||
)
|
||||
else:
|
||||
duration = "{minutes}:{seconds:02d}".format(
|
||||
hours=hours,
|
||||
# hours=hours,
|
||||
minutes=minutes,
|
||||
seconds=seconds,
|
||||
tenths=tenths
|
||||
# tenths=tenths
|
||||
)
|
||||
|
||||
return duration
|
||||
@@ -559,12 +556,12 @@ def get_strava_stream(r, metric, stravaid, series_type='time', fetchresolution='
|
||||
if metric == 'power': # pragma: no cover
|
||||
metric = 'watts'
|
||||
|
||||
url = "https://www.strava.com/api/v3/activities/{stravaid}/streams/{metric}?resolution={fetchresolution}&series_type={series_type}".format(
|
||||
stravaid=stravaid,
|
||||
fetchresolution=fetchresolution,
|
||||
series_type=series_type,
|
||||
metric=metric
|
||||
)
|
||||
url = "https://www.strava.com/api/v3/activities/{stravaid}" \
|
||||
"/streams/{metric}?resolution={fetchresolution}&series_type={series_type}".format(
|
||||
stravaid=stravaid,
|
||||
fetchresolution=fetchresolution,
|
||||
series_type=series_type,
|
||||
metric=metric)
|
||||
|
||||
s = requests.get(url, headers=headers)
|
||||
|
||||
@@ -574,7 +571,6 @@ def get_strava_stream(r, metric, stravaid, series_type='time', fetchresolution='
|
||||
|
||||
try:
|
||||
for data in s.json():
|
||||
y = None
|
||||
try:
|
||||
if data['type'] == metric:
|
||||
return np.array(data['data'])
|
||||
@@ -790,14 +786,14 @@ def get_step_type(step): # pragma: no cover
|
||||
return t
|
||||
|
||||
|
||||
def peel(l):
|
||||
if len(l) == 0: # pragma: no cover
|
||||
def peel(listToPeel):
|
||||
if len(listToPeel) == 0: # pragma: no cover
|
||||
return None, None
|
||||
if len(l) == 1:
|
||||
return l[0], None
|
||||
if len(listToPeel) == 1:
|
||||
return listToPeel[0], None
|
||||
|
||||
first = l[0]
|
||||
rest = l[1:]
|
||||
first = listToPeel[0]
|
||||
rest = listToPeel[1:]
|
||||
|
||||
if first['type'] == 'Step': # pragma: no cover
|
||||
return first, rest
|
||||
@@ -944,7 +940,7 @@ def step_to_string(step, short=False):
|
||||
repeatValue = 1
|
||||
|
||||
nr = 0
|
||||
name = ''
|
||||
|
||||
intensity = ''
|
||||
duration = ''
|
||||
unit = ''
|
||||
@@ -954,7 +950,11 @@ def step_to_string(step, short=False):
|
||||
|
||||
durationtype = step['durationType']
|
||||
if step['durationValue'] == 0:
|
||||
if durationtype not in ['RepeatUntilStepsCmplt', 'RepeatUntilHrLessThan', 'RepeatUntilHrGreaterThan']: # pragma: no cover
|
||||
if durationtype not in [
|
||||
'RepeatUntilStepsCmplt',
|
||||
'RepeatUntilHrLessThan',
|
||||
'RepeatUntilHrGreaterThan'
|
||||
]: # pragma: no cover
|
||||
return '', type, -1, -1, 1
|
||||
|
||||
if durationtype == 'Time':
|
||||
@@ -963,7 +963,6 @@ def step_to_string(step, short=False):
|
||||
if value/1000. >= 3600: # pragma: no cover
|
||||
unit = 'h'
|
||||
dd = timedelta(seconds=value/1000.)
|
||||
#duration = humanize.naturaldelta(dd, minimum_unit="seconds")
|
||||
duration = '{v}'.format(v=str(dd))
|
||||
elif durationtype == 'Distance':
|
||||
unit = 'm'
|
||||
@@ -1163,7 +1162,7 @@ def step_to_string(step, short=False):
|
||||
|
||||
nr = step['stepId']
|
||||
|
||||
name = step['wkt_step_name']
|
||||
# name = step['wkt_step_name']
|
||||
|
||||
notes = ''
|
||||
try:
|
||||
@@ -1178,10 +1177,10 @@ def step_to_string(step, short=False):
|
||||
intensity = 0
|
||||
|
||||
s = '{duration} {unit} {target} {repeat} {notes}'.format(
|
||||
nr=nr,
|
||||
name=name,
|
||||
# nr=nr,
|
||||
# name=name,
|
||||
unit=unit,
|
||||
intensity=intensity,
|
||||
# intensity=intensity,
|
||||
duration=duration,
|
||||
target=target,
|
||||
repeat=repeat,
|
||||
|
||||
@@ -3736,8 +3736,7 @@ def workout_flexchart3_view(request, *args, **kwargs):
|
||||
'yaxis1': yparam1,
|
||||
'yaxis2': yparam2,
|
||||
}
|
||||
flexaxesform = FlexAxesForm(request, initial=initial,
|
||||
extrametrics=extrametrics)
|
||||
flexaxesform = FlexAxesForm(request, initial=initial)
|
||||
|
||||
initial = {
|
||||
'includereststrokes': not workstrokesonly,
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ def get_metar_data(airportcode, unixtime):
|
||||
lengte = len(doc.xpath('data/METAR/station_id'))
|
||||
idnr = int(lengte/2)
|
||||
try:
|
||||
id = doc.xpath('data/METAR/station_id')[idnr].text
|
||||
_ = doc.xpath('data/METAR/station_id')[idnr].text
|
||||
temp_c = doc.xpath('data/METAR/temp_c')[idnr].text
|
||||
wind_dir = doc.xpath('data/METAR/wind_dir_degrees')[idnr].text
|
||||
wind_speed = doc.xpath('data/METAR/wind_speed_kt')[idnr].text
|
||||
@@ -138,7 +138,7 @@ def get_wind_data(lat, long, unixtime):
|
||||
windbearing = 0
|
||||
summary = 'unknown'
|
||||
airports = ['unknown']
|
||||
temparature = 'unknown'
|
||||
temperature = 'unknown'
|
||||
temperaturec = 'unknown'
|
||||
message = 'Not able to get weather data'
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
|
||||
@@ -1,5 +1 @@
|
||||
|
||||
from django import forms
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.db import models
|
||||
|
||||
|
||||
+88
-94
@@ -12,7 +12,7 @@ https://docs.djangoproject.com/en/1.9/ref/settings/
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from YamJam import yamjam
|
||||
#from django.utils.translation import ugettext_lazy as _
|
||||
# from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
# Read configuration (passwords, keys, secrets) from YamJam configuration
|
||||
# You have to create your own config.yaml in the project directory
|
||||
@@ -20,8 +20,6 @@ CFG = yamjam()['rowsandallapp']
|
||||
|
||||
DEFAULT_CHARSET = 'UTF-8'
|
||||
|
||||
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
@@ -39,10 +37,10 @@ TESTING = False
|
||||
|
||||
ALLOWED_HOSTS = CFG['allowed_hosts']
|
||||
|
||||
#OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'oauth2_provider.AccessToken'
|
||||
#OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
|
||||
#OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = 'oauth2_provider.RefreshToken'
|
||||
#OAUTH2_PROVIDER_ACCESS_TOKEN_EXPIRE_SECONDS = 3600
|
||||
# OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'oauth2_provider.AccessToken'
|
||||
# OAUTH2_PROVIDER_APPLICATION_MODEL = 'oauth2_provider.Application'
|
||||
# OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = 'oauth2_provider.RefreshToken'
|
||||
# OAUTH2_PROVIDER_ACCESS_TOKEN_EXPIRE_SECONDS = 3600
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
@@ -51,20 +49,20 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
INSTALLED_APPS = [
|
||||
'rowers',
|
||||
'survey',
|
||||
# 'cvkbrno',
|
||||
# 'cvkbrno',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
# 'suit',
|
||||
# 'suit_rq',
|
||||
# 'suit',
|
||||
# 'suit_rq',
|
||||
'leaflet',
|
||||
'django_rq',
|
||||
# 'django_rq_dashboard',
|
||||
# 'translation_manager',
|
||||
# 'django_mailbox',
|
||||
# 'django_rq_dashboard',
|
||||
# 'translation_manager',
|
||||
# 'django_mailbox',
|
||||
'rest_framework',
|
||||
'datetimewidget',
|
||||
'rest_framework_swagger',
|
||||
@@ -91,12 +89,12 @@ MIDDLEWARE = [
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.common.BrokenLinkEmailsMiddleware',
|
||||
'django.middleware.gzip.GZipMiddleware',
|
||||
# 'htmlmin.middleware.HtmlMinifyMiddleware',
|
||||
# 'htmlmin.middleware.MarkRequestMiddleware',
|
||||
# 'htmlmin.middleware.HtmlMinifyMiddleware',
|
||||
# 'htmlmin.middleware.MarkRequestMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
# 'django.middleware.locale.LocaleMiddleware',
|
||||
# 'django.middleware.locale.LocaleMiddleware',
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
@@ -106,14 +104,14 @@ MIDDLEWARE = [
|
||||
'tz_detect.middleware.TimezoneMiddleware',
|
||||
'rowers.middleware.SurveyMiddleWare',
|
||||
'rowers.middleware.GDPRMiddleWare',
|
||||
# 'rowers.middleware.PowerTimeFitnessMetricMiddleWare',
|
||||
# 'rowers.middleware.PowerTimeFitnessMetricMiddleWare',
|
||||
'rowers.middleware.RowerPlanMiddleWare',
|
||||
]
|
||||
|
||||
ROOT_URLCONF = 'rowsandall_app.urls'
|
||||
HTML_MINIFY = True
|
||||
|
||||
#EXCLUDE_FROM_MINIFYING = ('^rowers/flexall',
|
||||
# EXCLUDE_FROM_MINIFYING = ('^rowers/flexall',
|
||||
# '^rowers/list-workouts',
|
||||
# '^rowers/list-graphs',
|
||||
# '^admin/',
|
||||
@@ -124,7 +122,7 @@ APPEND_SLASH = True
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'DIRS': [os.path.join(BASE_DIR,'templates')],
|
||||
'DIRS': [os.path.join(BASE_DIR, 'templates')],
|
||||
'APP_DIRS': True,
|
||||
'OPTIONS': {
|
||||
'context_processors': [
|
||||
@@ -132,19 +130,18 @@ TEMPLATES = [
|
||||
'django.template.context_processors.request',
|
||||
'django.contrib.auth.context_processors.auth',
|
||||
'django.contrib.messages.context_processors.messages',
|
||||
'django.template.context_processors.i18n',
|
||||
# 'context_processors.google_analytics',
|
||||
'django.template.context_processors.i18n',
|
||||
# 'context_processors.google_analytics',
|
||||
'context_processors.warning_message',
|
||||
'rowers.context_processors.braintree_merchant',
|
||||
],
|
||||
'libraries' : {
|
||||
'libraries': {
|
||||
'staticfiles': 'django.templatetags.static',
|
||||
}
|
||||
# 'loaders': [
|
||||
# 'django.template.loaders.app_directories.Loader',
|
||||
# ],
|
||||
# 'loaders': [
|
||||
# 'django.template.loaders.app_directories.Loader',
|
||||
# ],
|
||||
},
|
||||
|
||||
},
|
||||
]
|
||||
|
||||
@@ -177,8 +174,8 @@ DATABASES = {
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
},
|
||||
'TEST': {
|
||||
'CHARSET': 'utf8',
|
||||
'COLLATION': 'utf8_general_ci',
|
||||
'CHARSET': 'utf8',
|
||||
'COLLATION': 'utf8_general_ci',
|
||||
},
|
||||
}
|
||||
|
||||
@@ -192,9 +189,9 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||||
'OPTIONS': {
|
||||
'min_length': 9,
|
||||
}
|
||||
'OPTIONS': {
|
||||
'min_length': 9,
|
||||
}
|
||||
},
|
||||
{
|
||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||||
@@ -203,7 +200,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||||
},
|
||||
{
|
||||
'NAME': 'rowers.validator.LettersAndDigitsValidator',
|
||||
'NAME': 'rowers.validator.LettersAndDigitsValidator',
|
||||
}
|
||||
]
|
||||
|
||||
@@ -217,11 +214,11 @@ USE_I18N = True
|
||||
USE_L10N = False
|
||||
|
||||
DATE_INPUT_FORMATS = [
|
||||
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
|
||||
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
|
||||
'%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
|
||||
'%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
|
||||
'%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
|
||||
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
|
||||
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
|
||||
'%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
|
||||
'%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
|
||||
'%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
|
||||
]
|
||||
|
||||
DATE_FORMAT = 'Y-m-d'
|
||||
@@ -229,12 +226,12 @@ DATE_FORMAT = 'Y-m-d'
|
||||
USE_TZ = True
|
||||
TIME_ZONE = 'UTC'
|
||||
|
||||
TZ_DETECT_COUNTRIES = ('US','DE','GB','CZ','FR','IT')
|
||||
TZ_DETECT_COUNTRIES = ('US', 'DE', 'GB', 'CZ', 'FR', 'IT')
|
||||
|
||||
LOCALE_PATHS = (
|
||||
os.path.join(BASE_DIR, 'locale'),
|
||||
# os.path.join(BASE_DIR, 'cvkbrno/locale'),
|
||||
)
|
||||
# os.path.join(BASE_DIR, 'cvkbrno/locale'),
|
||||
)
|
||||
|
||||
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
@@ -244,19 +241,16 @@ LANGUAGE_COOKIE_NAME = 'wm_lang'
|
||||
# https://docs.djangoproject.com/en/1.9/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
#STATIC_ROOT = BASE_DIR
|
||||
# STATIC_ROOT = BASE_DIR
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
||||
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/plots'),]
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/plots'), ]
|
||||
# os.path.join(BASE_DIR, 'static'),
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
|
||||
|
||||
|
||||
# user authentication
|
||||
|
||||
# user authentication
|
||||
LOGIN_REDIRECT_URL = '/rowers/list-workouts/'
|
||||
LOGIN_URL = '/login/'
|
||||
@@ -268,18 +262,18 @@ LOGOUT_REDIRECT_URL = '/'
|
||||
PROGRESS_CACHE_SECRET = CFG['progress_cache_secret']
|
||||
try:
|
||||
UPLOAD_SERVICE_URL = CFG['upload_service_url']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
UPLOAD_SERVICE_URL = "http://localhost:8000/rowers/workout/api/upload/"
|
||||
try:
|
||||
UPLOAD_SERVICE_SECRET = CFG['upload_service_secret']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
UPLOAD_SERVICE_SECRET = "FoYezZWLSyfAVimumpHEeYsJjsNCerxV"
|
||||
|
||||
# Concept 2
|
||||
C2_CLIENT_ID = CFG['c2_client_id']
|
||||
C2_CLIENT_SECRET = CFG['c2_client_secret']
|
||||
C2_REDIRECT_URI = CFG['c2_callback']
|
||||
#C2_REDIRECT_URI = "http://localhost:8000/call_back"
|
||||
# C2_REDIRECT_URI = "http://localhost:8000/call_back"
|
||||
|
||||
# Strava
|
||||
|
||||
@@ -316,8 +310,8 @@ UNDERARMOUR_CLIENT_ID = CFG['underarmour_client_name']
|
||||
UNDERARMOUR_CLIENT_SECRET = CFG['underarmour_client_secret']
|
||||
UNDERARMOUR_CLIENT_KEY = CFG['underarmour_client_key']
|
||||
UNDERARMOUR_REDIRECT_URI = CFG['underarmour_callback']
|
||||
#UNDERARMOUR_REDIRECT_URI = "http://rowsandall.com/underarmour_callback"
|
||||
#UNDERARMOUR_REDIRECT_URI = "http://localhost:8000/underarmour_callback"
|
||||
# UNDERARMOUR_REDIRECT_URI = "http://rowsandall.com/underarmour_callback"
|
||||
# UNDERARMOUR_REDIRECT_URI = "http://localhost:8000/underarmour_callback"
|
||||
|
||||
# TrainingPeaks
|
||||
TP_CLIENT_ID = CFG["tp_client_id"]
|
||||
@@ -349,56 +343,56 @@ RQ_QUEUES = {
|
||||
'HOST': 'localhost',
|
||||
'PORT': 6379,
|
||||
'DB': 0,
|
||||
# 'PASSWORD': 'some-password',
|
||||
# 'PASSWORD': 'some-password',
|
||||
'DEFAULT_TIMEOUT': 360,
|
||||
},
|
||||
'low': {
|
||||
'HOST': 'localhost',
|
||||
'PORT': 6379,
|
||||
'DB': 0,
|
||||
# 'PASSWORD': 'some-password',
|
||||
# 'PASSWORD': 'some-password',
|
||||
'DEFAULT_TIMEOUT': 360,
|
||||
},
|
||||
'high': {
|
||||
'HOST': 'localhost',
|
||||
'PORT': 6379,
|
||||
'DB': 0,
|
||||
# 'PASSWORD': 'some-password',
|
||||
# 'PASSWORD': 'some-password',
|
||||
'DEFAULT_TIMEOUT': 360,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
#SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
|
||||
#SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||
# SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
|
||||
# SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||
SESSION_SAVE_EVERY_REQUEST = True
|
||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
||||
|
||||
# admin stuff for error reporting
|
||||
SERVER_EMAIL='admin@rowsandall.com'
|
||||
ADMINS = [('Sander','roosendaalsander@gmail.com')]
|
||||
SERVER_EMAIL = 'admin@rowsandall.com'
|
||||
ADMINS = [('Sander', 'roosendaalsander@gmail.com')]
|
||||
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
|
||||
'LOCATION': 'localhost:11211',
|
||||
'TIMEOUT': 900,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CACHE_MIDDLEWARE_ALIAS = 'default'
|
||||
CACHE_MIDDLEWARE_SECONDS = 900
|
||||
|
||||
# email stuff
|
||||
|
||||
#EMAIL_BACKEND = CFG['email_backend']
|
||||
#EMAIL_HOST = CFG['email_host']
|
||||
#EMAIL_PORT = CFG['email_port']
|
||||
#EMAIL_HOST_USER = CFG['email_host_user']
|
||||
#EMAIL_HOST_PASSWORD = CFG['email_host_password']
|
||||
#EMAIL_USE_TLS = CFG['email_use_tls']
|
||||
#DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
|
||||
# EMAIL_BACKEND = CFG['email_backend']
|
||||
# EMAIL_HOST = CFG['email_host']
|
||||
# EMAIL_PORT = CFG['email_port']
|
||||
# EMAIL_HOST_USER = CFG['email_host_user']
|
||||
# EMAIL_HOST_PASSWORD = CFG['email_host_password']
|
||||
# EMAIL_USE_TLS = CFG['email_use_tls']
|
||||
# DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
|
||||
|
||||
EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||
|
||||
@@ -407,7 +401,7 @@ AWS_SES_REGION_ENDPOINT = CFG['aws_smtp']
|
||||
|
||||
AWS_SES_ACCESS_KEY_ID = CFG['aws_access_key_id']
|
||||
AWS_SES_SECRET_ACCESS_KEY = CFG['aws_secret_access_key']
|
||||
AWS_ACCESS_KEY_ID = CFG['aws_access_key_id']
|
||||
AWS_ACCESS_KEY_ID = CFG['aws_access_key_id']
|
||||
AWS_SECRET_ACCESS_KEY = CFG['aws_secret_access_key']
|
||||
|
||||
EMAIL_HOST = CFG['aws_smtp']
|
||||
@@ -435,7 +429,7 @@ OAUTH2_PROVIDER = {
|
||||
'APPLICATION_MODEL': 'oauth2_provider.Application',
|
||||
'REFRESH_TOKEN_MODEL': 'oauth2_provider.RefreshToken',
|
||||
'ACCESS_TOKEN_EXPIRE_SECONDS': 36000,
|
||||
#'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore'
|
||||
# 'OAUTH2_BACKEND_CLASS': 'oauth2_provider.oauth2_backends.JSONOAuthLibCore'
|
||||
}
|
||||
|
||||
|
||||
@@ -446,38 +440,38 @@ REST_FRAMEWORK = {
|
||||
# or allow read-only access for unauthenticated users.
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'rest_framework.permissions.IsAuthenticated'
|
||||
# 'rest_framework.permissions.DjangoModelPermissions'
|
||||
# 'rest_framework.permissions.DjangoModelPermissions'
|
||||
],
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.BasicAuthentication',
|
||||
# 'rest_framework.authentication.SessionAuthentication',
|
||||
# 'rest_framework.authentication.TokenAuthentication',
|
||||
# 'rest_framework.authentication.SessionAuthentication',
|
||||
# 'rest_framework.authentication.TokenAuthentication',
|
||||
'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
|
||||
),
|
||||
'PAGE_SIZE': 20,
|
||||
'DEFAULT_PAGINATION_CLASS':'rest_framework.pagination.LimitOffsetPagination',
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||
}
|
||||
|
||||
SWAGGER_SETTINGS = {
|
||||
'SECURITY_DEFINITIONS': {
|
||||
'basic': {
|
||||
'type':'basic'
|
||||
},
|
||||
'type': 'basic'
|
||||
},
|
||||
'oauth2': {
|
||||
'type':'oauth2',
|
||||
'authorizationUrl':'/rowers/o/authorize',
|
||||
'type': 'oauth2',
|
||||
'authorizationUrl': '/rowers/o/authorize',
|
||||
'flow': 'implicit',
|
||||
},
|
||||
'api_key': {
|
||||
},
|
||||
'api_key': {
|
||||
'type': 'apiKey',
|
||||
'in': 'header',
|
||||
'name': 'Authorization'
|
||||
},
|
||||
},
|
||||
},
|
||||
'SHOW_REQUEST_HEADERS': True,
|
||||
'USE_SESSION_AUTH': True,
|
||||
'JSON_EDITOR': True,
|
||||
}
|
||||
}
|
||||
|
||||
# Analytics
|
||||
|
||||
@@ -511,75 +505,75 @@ except KeyError:
|
||||
|
||||
try:
|
||||
BRAINTREE_MERCHANT_ID = CFG['braintree_merchant_id']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_MERCHANT_ID = ''
|
||||
|
||||
try:
|
||||
BRAINTREE_MERCHANT_ACCOUNT_ID = CFG['braintree_merchant_account_id']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_MERCHANT_ACCOUNT_ID = 'rowsandallEUR'
|
||||
|
||||
try:
|
||||
BRAINTREE_PUBLIC_KEY = CFG['braintree_public_key']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_PUBLIC_KEY = ''
|
||||
|
||||
try:
|
||||
BRAINTREE_PRIVATE_KEY = CFG['braintree_private_key']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_PRIVATE_KEY = ''
|
||||
|
||||
try:
|
||||
BRAINTREE_SANDBOX_MERCHANT_ID = CFG['braintree_sandbox_merchant_id']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_SANDBOX_MERCHANT_ID = ''
|
||||
|
||||
try:
|
||||
BRAINTREE_SANDBOX_PUBLIC_KEY = CFG['braintree_sandbox_public_key']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_SANDBOX_PUBLIC_KEY = ''
|
||||
|
||||
try:
|
||||
BRAINTREE_SANDBOX_PRIVATE_KEY = CFG['braintree_sandbox_private_key']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
BRAINTREE_SANDBOX_PRIVATE_KEY = ''
|
||||
|
||||
try:
|
||||
PAYMENT_PROCESSING_ON = CFG['payment_processing_on']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
PAYMENT_PROCESSING_ON = False
|
||||
|
||||
try:
|
||||
FAKTUROID_API_KEY = CFG['fakturoid_api_key']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
FAKTUROID_API_KEY = ''
|
||||
|
||||
try:
|
||||
FAKTUROID_EMAIL = CFG['fakturoid_email']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
FAKTUROID_EMAIL = ''
|
||||
|
||||
try:
|
||||
FAKTUROID_SLUG = CFG['fakturoid_slug']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
FAKTUROID_SLUG = ''
|
||||
|
||||
# ID obfuscation
|
||||
try:
|
||||
OPAQUE_SECRET_KEY = CFG['opaque_secret_key']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
OPAQUE_SECRET_KEY = 0xa193443a
|
||||
|
||||
# Celery or RQ
|
||||
try:
|
||||
CELERY = CFG['use_celery']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
CELERY = False
|
||||
|
||||
try:
|
||||
WORKOUTS_FIT_TOKEN = CFG['workouts_fit_token']
|
||||
WORKOUTS_FIT_URL = CFG['workouts_fit_url']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
WORKOUTS_FIT_TOKEN = 'aapnootmies'
|
||||
WORKOUTS_FIT_URL = 'http://localhost:50053/tojson'
|
||||
|
||||
@@ -588,7 +582,7 @@ except KeyError: # pragma: no cover
|
||||
try:
|
||||
RECAPTCHA_SITE_KEY = CFG['recaptcha_site_key']
|
||||
RECAPTCHA_SITE_SECRET = CFG['recaptcha_site_secret']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
RECAPTCHA_SITE_KEY = ''
|
||||
RECAPTCHA_SITE_SECRET = ''
|
||||
|
||||
|
||||
@@ -14,15 +14,13 @@ import sys
|
||||
|
||||
try:
|
||||
use_sqlite = CFG['use_sqlite']
|
||||
except KeyError: # pragma: no cover
|
||||
except KeyError: # pragma: no cover
|
||||
use_sqlite = False
|
||||
|
||||
for element in sys.argv:
|
||||
if 'test' in element:
|
||||
TESTING = True
|
||||
|
||||
|
||||
|
||||
if TESTING or use_sqlite:
|
||||
DATABASES = {
|
||||
'default': {
|
||||
@@ -31,7 +29,8 @@ if TESTING or use_sqlite:
|
||||
'HOST': 'localhost',
|
||||
'USER': '',
|
||||
'PASSWORD': 'roeidata',
|
||||
'PORT': '3306', },
|
||||
'PORT': '3306',
|
||||
},
|
||||
# 'TEST': {
|
||||
# 'CHARSET': 'utf8',
|
||||
# 'COLLATION': 'utf8_general_ci',
|
||||
@@ -42,7 +41,7 @@ if TESTING or use_sqlite:
|
||||
# 'NAME': 'rowsanda_107501',
|
||||
# 'USER': 'rowsanda_107501',
|
||||
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
|
||||
@@ -63,10 +62,10 @@ DEBUG = True
|
||||
|
||||
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
|
||||
|
||||
ALLOWED_HOSTS = ['localhost','127.0.0.1','dunav.ngrok.io']
|
||||
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'dunav.ngrok.io']
|
||||
|
||||
# INSTALLED_APPS += ['debug_toolbar',]
|
||||
#INSTALLED_APPS += ["sslserver"]
|
||||
# INSTALLED_APPS += ["sslserver"]
|
||||
|
||||
# MIDDLEWARE_CLASSES += ['debug_toolbar.middleware.DebugToolbarMiddleware',]
|
||||
|
||||
@@ -74,18 +73,20 @@ CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
|
||||
'LOCATION': os.path.join(BASE_DIR, 'django_cache'),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Application definition
|
||||
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = BASE_DIR
|
||||
#STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
||||
# STATIC_ROOT = os.path.join(BASE_DIR, 'static')
|
||||
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),
|
||||
os.path.join(BASE_DIR, 'static/plots'),]
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(BASE_DIR, 'static'),
|
||||
os.path.join(BASE_DIR, 'static/plots'),
|
||||
]
|
||||
|
||||
|
||||
INTERNAL_IPS = ['127.0.0.1']
|
||||
@@ -99,10 +100,10 @@ SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
|
||||
|
||||
SITE_URL = "http://localhost:8000"
|
||||
|
||||
#EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
|
||||
#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
# EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
|
||||
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
|
||||
EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
"""
|
||||
Django settings for rowsandall_app project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 1.9.5.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/1.9/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/1.9/ref/settings/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from .settings import *
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
# 'HOST': 'localhost',
|
||||
},
|
||||
# 'TEST': {
|
||||
# 'CHARSET': 'utf8',
|
||||
# 'COLLATION': 'utf8_general_ci',
|
||||
# },
|
||||
|
||||
# 'slave': {
|
||||
# 'ENGINE': 'django.db.backends.mysql',
|
||||
# 'NAME': 'rowsanda_107501',
|
||||
# 'USER': 'rowsanda_107501',
|
||||
# 'PASSWORD': 'roeidata',
|
||||
# 'HOST': 'store3.rosti.cz',
|
||||
# 'PORT': '3306',
|
||||
# }
|
||||
}
|
||||
|
||||
#BROKER_URL = 'redis://localhost:6379/0'
|
||||
#CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
|
||||
#CELERY_IGNORE_RESULT = False
|
||||
|
||||
#CELERY_ACCEPT_CONTENT = ['json']
|
||||
#CELERY_TASK_SERIALIZER = 'json'
|
||||
#CELERY_RESULT_SERIALIZER = 'json'
|
||||
#CELERY_TRACK_STARTED = True
|
||||
#CELERY_SEND_TASK_SENT_EVENT = True
|
||||
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
TEMPLATES[0]['OPTIONS']['debug'] = DEBUG
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
INSTALLED_APPS += ['debug_toolbar',]
|
||||
|
||||
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware',]
|
||||
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
|
||||
'LOCATION': os.path.join(BASE_DIR, 'django_cache'),
|
||||
}
|
||||
}
|
||||
|
||||
# Application definition
|
||||
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = BASE_DIR
|
||||
STATICFILES_DIRS = [os.path.join(BASE_DIR,'static/plots'),os.path.join(BASE_DIR,'static'),]
|
||||
|
||||
# INTERNAL_IPS = ['127.0.0.1']
|
||||
|
||||
MEDIA_URL = '/media/'
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
|
||||
LOGIN_REDIRECT_URL = '/rowers/list-workouts/'
|
||||
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
|
||||
|
||||
SITE_URL = "http://localhost:8000"
|
||||
|
||||
#EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
|
||||
|
||||
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
|
||||
#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
|
||||
#EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||
|
||||
AWS_SES_REGION_NAME = 'eu-west-1'
|
||||
AWS_SES_REGION_ENDPOINT = 'email.eu-west-1.amazonaws.com'
|
||||
|
||||
EMAIL_HOST = CFG['aws_smtp']
|
||||
EMAIL_PORT = CFG['aws_port']
|
||||
EMAIL_HOST_USER = CFG['aws_smtp_username']
|
||||
EMAIL_HOST_PASSWORD = CFG['aws_smtp_password']
|
||||
EMAIL_USE_TLS = CFG['email_use_tls']
|
||||
DEFAULT_FROM_EMAIL = 'info@rowsandall.com'
|
||||
|
||||
SETTINGS_NAME = 'rowsandall_app.settings_thinkpad'
|
||||
|
||||
|
||||
+55
-41
@@ -25,69 +25,80 @@ from rowers import views as rowersviews
|
||||
from survey import views as surveyviews
|
||||
|
||||
import django
|
||||
import django.views.i18n
|
||||
|
||||
|
||||
# admin look
|
||||
admin.site.enable_nav_sidebar = False
|
||||
|
||||
import django.views.i18n
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
re_path('^', include('django.contrib.auth.urls')),
|
||||
re_path(r'^password_change_done/$',auth_views.PasswordChangeDoneView.as_view(),name='password_change_done'),
|
||||
re_path(r'^password_change/$',auth_views.PasswordChangeView.as_view(),name='password_change'),
|
||||
re_path(r'^password_reset/$',
|
||||
re_path(
|
||||
r'^password_change_done/$',
|
||||
auth_views.PasswordChangeDoneView.as_view(),
|
||||
name='password_change_done'),
|
||||
re_path(
|
||||
r'^password_change/$',
|
||||
auth_views.PasswordChangeView.as_view(),
|
||||
name='password_change'),
|
||||
re_path(
|
||||
r'^password_reset/$',
|
||||
auth_views.PasswordResetView.as_view(),
|
||||
{'template_name': 'rowers/templates/registration/password_reset.html'},
|
||||
name='password_reset'),
|
||||
re_path(r'^password_reset/done/$',
|
||||
re_path(
|
||||
r'^password_reset/done/$',
|
||||
auth_views.PasswordResetDoneView.as_view(),
|
||||
name='password_reset_done'),
|
||||
re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
|
||||
re_path(
|
||||
r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
|
||||
auth_views.PasswordResetConfirmView.as_view(),
|
||||
name='password_reset_confirm'),
|
||||
re_path(r'^reset/done/$',
|
||||
re_path(
|
||||
r'^reset/done/$',
|
||||
auth_views.PasswordResetCompleteView.as_view(),
|
||||
name='password_reset_complete'),
|
||||
]
|
||||
]
|
||||
|
||||
urlpatterns += [
|
||||
re_path(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt',
|
||||
content_type='text/plain')),
|
||||
re_path(r'^robots\.txt$', TemplateView.as_view(
|
||||
template_name='robots.txt',
|
||||
content_type='text/plain')),
|
||||
re_path(r'^admin/', admin.site.urls),
|
||||
re_path(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework2')),
|
||||
re_path(r'^$',landingview),
|
||||
re_path(r'^landing/$',landingview),
|
||||
re_path(r'^getblogs/$',rowersviews.get_blog_posts),
|
||||
re_path(r'^$', landingview),
|
||||
re_path(r'^landing/$', landingview),
|
||||
re_path(r'^getblogs/$', rowersviews.get_blog_posts),
|
||||
re_path(r'^login/',
|
||||
# auth_views.LoginView,
|
||||
# auth_views.LoginView,
|
||||
auth_views.LoginView.as_view(),
|
||||
name='login'),
|
||||
re_path(r'^logout/$',
|
||||
auth_views.LogoutView.as_view(),
|
||||
{'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),
|
||||
re_path(r'^nk\_callback',rowersviews.rower_process_nkcallback),
|
||||
re_path(r'^stravacall\_back',rowersviews.rower_process_stravacallback),
|
||||
re_path(r'^garmin\_callback',rowersviews.rower_process_garmincallback),
|
||||
re_path(r'^sporttracks\_callback',rowersviews.rower_process_sporttrackscallback),
|
||||
re_path(r'^polarflowcallback',rowersviews.rower_process_polarcallback),
|
||||
re_path(r'^tp\_callback',rowersviews.rower_process_tpcallback),
|
||||
re_path(r'^rp3\_callback',rowersviews.rower_process_rp3callback),
|
||||
re_path(r'^twitter\_callback',rowersviews.rower_process_twittercallback),
|
||||
auth_views.LogoutView.as_view(),
|
||||
{'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),
|
||||
re_path(r'^nk\_callback', rowersviews.rower_process_nkcallback),
|
||||
re_path(r'^stravacall\_back', rowersviews.rower_process_stravacallback),
|
||||
re_path(r'^garmin\_callback', rowersviews.rower_process_garmincallback),
|
||||
re_path(r'^sporttracks\_callback', rowersviews.rower_process_sporttrackscallback),
|
||||
re_path(r'^polarflowcallback', rowersviews.rower_process_polarcallback),
|
||||
re_path(r'^tp\_callback', rowersviews.rower_process_tpcallback),
|
||||
re_path(r'^rp3\_callback', rowersviews.rower_process_rp3callback),
|
||||
re_path(r'^twitter\_callback', rowersviews.rower_process_twittercallback),
|
||||
re_path(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
re_path(r'^tz_detect/', include('tz_detect.urls')),
|
||||
re_path(r'^logo/',logoview),
|
||||
re_path(r'^media/(?P<filename>.*\.fit)$',rowersviews.download_fit),
|
||||
re_path(r'^logo/', logoview),
|
||||
re_path(r'^media/(?P<filename>.*\.fit)$', rowersviews.download_fit),
|
||||
path('django-rq/', include('django_rq.urls')),
|
||||
# path('500/', rowersviews.error500_view),
|
||||
# re_path(r'^jsi18n/', django.views.i18n.javascript_catalog,name='jsi18n'),
|
||||
]
|
||||
# path('500/', rowersviews.error500_view),
|
||||
# re_path(r'^jsi18n/', django.views.i18n.javascript_catalog,name='jsi18n'),
|
||||
]
|
||||
|
||||
js_info_dict = {
|
||||
'packages': ('recurrence', ),
|
||||
@@ -100,7 +111,7 @@ urlpatterns += [
|
||||
# monkey patch workaround for bug in recurrence library
|
||||
django.views.i18n.javascript_catalog = None
|
||||
|
||||
if settings.DEBUG: # pragma: no cover
|
||||
if settings.DEBUG: # pragma: no cover
|
||||
import debug_toolbar
|
||||
import django
|
||||
urlpatterns += [
|
||||
@@ -109,10 +120,13 @@ if settings.DEBUG: # pragma: no cover
|
||||
kwargs={'document_root': settings.STATIC_ROOT+'plots/'})
|
||||
]
|
||||
urlpatterns += [
|
||||
# re_path(r'^__debug__/','debug_toolbar.urls'),
|
||||
re_path(r'^static/(?P<path>.*)$',
|
||||
# re_path(r'^__debug__/','debug_toolbar.urls'),
|
||||
re_path(
|
||||
r'^static/(?P<path>.*)$',
|
||||
django.views.static.serve,
|
||||
kwargs={'document_root': settings.STATIC_ROOT,
|
||||
'show_indexes': True}
|
||||
kwargs={
|
||||
'document_root': settings.STATIC_ROOT,
|
||||
'show_indexes': True
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
+31
-32
@@ -9,65 +9,64 @@ from rowingdata import main as rmain
|
||||
|
||||
import random
|
||||
|
||||
def landingview(request):
|
||||
loginform = LoginForm()
|
||||
|
||||
return render(request,
|
||||
'landingpage.html',
|
||||
def landingview(request):
|
||||
return render(
|
||||
request,
|
||||
'landingpage.html',
|
||||
)
|
||||
|
||||
def logoview(request): # pragma: no cover
|
||||
|
||||
def logoview(request): # pragma: no cover
|
||||
image_data = open(settings.STATIC_ROOT+"/img/apple-icon-144x144.png", "rb").read()
|
||||
return HttpResponse(image_data, content_type="image/png")
|
||||
|
||||
|
||||
def rootview(request): # pragma: no cover
|
||||
def rootview(request): # pragma: no cover
|
||||
magicsentence = rmain()
|
||||
loginform = LoginForm()
|
||||
|
||||
planoffering = {
|
||||
'name': 'PLAN',
|
||||
'image':'/static/img/Plan.png',
|
||||
'text':'We offer a fully integrated way for you or your coach to set up a training plan. Compare plan vs execution based on time, distance, heart rate or power.'
|
||||
}
|
||||
'image': '/static/img/Plan.png',
|
||||
'text': 'We offer a fully integrated way for you or your coach to set up a training plan. Compare plan vs execution based on time, distance, heart rate or power.'
|
||||
}
|
||||
|
||||
uploadoffering = {
|
||||
'name': 'SYNC',
|
||||
'image':'/static/img/upload.png',
|
||||
'text':'Easily upload data from the most popular devices and apps'
|
||||
}
|
||||
'image': '/static/img/upload.png',
|
||||
'text': 'Easily upload data from the most popular devices and apps'
|
||||
}
|
||||
|
||||
logoffering = {
|
||||
'name': 'LOG',
|
||||
'image':'/static/img/log.png',
|
||||
'text':'Maintain a consistent log for all your rowing (indoor and on the water)'
|
||||
}
|
||||
'image': '/static/img/log.png',
|
||||
'text': 'Maintain a consistent log for all your rowing (indoor and on the water)'
|
||||
}
|
||||
|
||||
analyzeoffering = {
|
||||
'name': 'ANALYZE',
|
||||
'image':'/static/img/analyze.png',
|
||||
'text':'Analyze your workouts with a consistent set of tools'
|
||||
}
|
||||
'image': '/static/img/analyze.png',
|
||||
'text': 'Analyze your workouts with a consistent set of tools'
|
||||
}
|
||||
|
||||
compareoffering = {
|
||||
'name': 'COMPARE',
|
||||
'image':'/static/img/compare.png',
|
||||
'text':'Compare your results between workouts and with other rowers in your team'
|
||||
}
|
||||
'image': '/static/img/compare.png',
|
||||
'text': 'Compare your results between workouts and with other rowers in your team'
|
||||
}
|
||||
|
||||
raceoffering = {
|
||||
'name': 'RACE',
|
||||
'image':'/static/img/Race 01.png',
|
||||
'text':'Virtual regattas are an informal way to add a competitive element to your training and can be used as a quick way to set up small regattas'
|
||||
}
|
||||
'image': '/static/img/Race 01.png',
|
||||
'text': 'Virtual regattas are an informal way to add a competitive element to your training and can be used as a quick way to set up small regattas'
|
||||
}
|
||||
|
||||
coachoffering = {
|
||||
'name': 'COACHING',
|
||||
'image':'/static/img/Remote coaching.png',
|
||||
'text':'Rowsandall.com is the ideal platform for remote rowing coaching. As a coach, you can easily manage your athletes, set up plans and monitor execution and technique'
|
||||
}
|
||||
|
||||
|
||||
'image': '/static/img/Remote coaching.png',
|
||||
'text': 'Rowsandall.com is the ideal platform for remote rowing coaching. As a coach, you can easily manage your athletes, set up plans and monitor execution and technique'
|
||||
}
|
||||
|
||||
allofferings = [
|
||||
planoffering,
|
||||
@@ -77,7 +76,7 @@ def rootview(request): # pragma: no cover
|
||||
raceoffering,
|
||||
compareoffering,
|
||||
coachoffering,
|
||||
]
|
||||
]
|
||||
|
||||
aux = list(allofferings)
|
||||
random.shuffle(aux)
|
||||
@@ -88,6 +87,6 @@ def rootview(request): # pragma: no cover
|
||||
'frontpage.html',
|
||||
{
|
||||
'versionstring': magicsentence,
|
||||
'form':loginform,
|
||||
'offerings':offerings,
|
||||
'form': loginform,
|
||||
'offerings': offerings,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user