import time import colorsys import zipfile import bleach import arrow import pytz from pytz import UnknownTimeZoneError import operator import warnings import urllib import yaml from PIL import Image from numbers import Number from django.views.generic.base import TemplateView from django.contrib.auth import views as auth_views from django.db.models import Q from django import template from django.db import IntegrityError, transaction from django.views.decorators.csrf import csrf_exempt from matplotlib.backends.backend_agg import FigureCanvas import gc from pyparsing import ParseException from uuid import uuid4 import codecs import isodate import re import cgi from icalendar import Calendar, Event from functools import reduce import rowers.braintreestuff as braintreestuff import rowers.payments as payments from rowers.opaque import encoder from django.shortcuts import render from django.template.loader import render_to_string from django.views.generic.edit import UpdateView,DeleteView from django.http import ( HttpResponse, HttpResponseRedirect, JsonResponse, HttpResponseForbidden, HttpResponseNotAllowed, HttpResponseNotFound,Http404 ) from django.contrib.auth import authenticate, login, logout from rowers.forms import ( ForceCurveOptionsForm,HistoForm,TeamMessageForm, LoginForm,DocumentsForm,UploadOptionsForm,ImageForm,CourseForm, TeamUploadOptionsForm,WorkFlowLeftPanelForm,WorkFlowMiddlePanelForm, WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement, LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm, PlannedSessionTeamForm,PlannedSessionTeamMemberForm, VirtualRaceSelectForm,WorkoutRaceSelectForm,CourseSelectForm, RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm, FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm, MetricsForm,DisqualificationForm,disqualificationreasons, disqualifiers,SearchForm,BillingForm,PlanSelectForm, VideoAnalysisCreateForm,WorkoutSingleSelectForm, VideoAnalysisMetricsForm, ) from django.urls import reverse, reverse_lazy from django.core.exceptions import PermissionDenied from django.template import RequestContext from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.conf import settings from django.utils.datastructures import MultiValueDictKeyError from django.utils import timezone,translation from django.core.mail import send_mail, BadHeaderError from rowers.forms import ( SummaryStringForm,IntervalUpdateForm,StrokeDataForm, StatsOptionsForm,PredictedPieceForm,DateRangeForm,DeltaDaysForm, FitnessMetricForm,PredictedPieceFormNoDistance, EmailForm, RegistrationForm, RegistrationFormTermsOfService, RegistrationFormUniqueEmail,RegistrationFormSex, CNsummaryForm,UpdateWindForm, UpdateStreamForm,WorkoutMultipleCompareForm,ChartParamChoiceForm, FusionMetricChoiceForm,BoxPlotChoiceForm,MultiFlexChoiceForm, TrendFlexModalForm,WorkoutSplitForm,WorkoutJoinParamForm, AnalysisOptionsForm, AnalysisChoiceForm, PlannedSessionMultipleCloneForm,SessionDateShiftForm,RowerTeamForm, ) from rowers.models import ( Workout, User, Rower, WorkoutForm,FavoriteChart, PlannedSession, DeactivateUserForm,DeleteUserForm, TrainingPlan,TrainingPlanForm,TrainingTarget,TrainingTargetForm, TrainingMacroCycle,TrainingMesoCycle,TrainingMicroCycle, TrainingTarget,TrainingTargetForm, TrainingMacroCycleForm,createmacrofillers, createmicrofillers, createmesofillers, microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates, TrainingMesoCycleForm, TrainingMicroCycleForm, RaceLogo,RowerBillingAddressForm,PaidPlan, AlertEditForm, ConditionEditForm, PlannedSessionComment,CoachRequest,CoachOffer,checkaccessplanuser, VideoAnalysis ) from rowers.models import ( RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm, RowerPowerZonesForm,AccountRowerForm,UserForm, Team,TeamForm,TeamInviteForm,TeamInvite,TeamRequest, WorkoutComment,WorkoutCommentForm,RowerExportForm, CalcAgePerformance, PowerTimeFitnessMetric,BlogPost, PlannedSessionForm, PlannedSessionFormSmall,GeoCourseEditForm,VirtualRace, VirtualRaceForm,VirtualRaceResultForm,RowerImportExportForm, IndoorVirtualRaceResultForm,IndoorVirtualRaceResult, IndoorVirtualRaceForm,PlannedSessionCommentForm, Alert, Condition ) from rowers.models import ( FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement,BasePlannedSessionFormSet, get_course_timezone,BaseConditionFormSet, ) from rowers.metrics import rowingmetrics,defaultfavoritecharts,nometrics,metricsgroups from rowers import metrics as metrics from rowers import courses as courses import rowers.uploads as uploads from django.forms.formsets import formset_factory from django.forms import modelformset_factory from django.contrib.auth.decorators import login_required #,user_passes_test from rowers.decorators import user_passes_test from time import strftime,strptime,mktime,time,daylight import os,sys import datetime import iso8601 import rowers.c2stuff as c2stuff from rowers.c2stuff import c2_open from rowers.runkeeperstuff import runkeeper_open from rowers.sporttracksstuff import sporttracks_open from rowers.tpstuff import tp_open from iso8601 import ParseError import rowers.stravastuff as stravastuff from rowers.stravastuff import strava_open import rowers.polarstuff as polarstuff import rowers.sporttracksstuff as sporttracksstuff import rowers.underarmourstuff as underarmourstuff from rowers.underarmourstuff import underarmour_open import rowers.tpstuff as tpstuff import rowers.runkeeperstuff as runkeeperstuff import rowers.ownapistuff as ownapistuff from rowers.ownapistuff import TEST_CLIENT_ID, TEST_CLIENT_SECRET, TEST_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, POLAR_CLIENT_ID, POLAR_REDIRECT_URI, POLAR_CLIENT_SECRET, SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI, SPORTTRACKS_CLIENT_SECRET, UNDERARMOUR_CLIENT_ID, UNDERARMOUR_REDIRECT_URI, UNDERARMOUR_CLIENT_SECRET,UNDERARMOUR_CLIENT_KEY, RUNKEEPER_CLIENT_ID,RUNKEEPER_REDIRECT_URI,RUNKEEPER_CLIENT_SECRET, TP_CLIENT_ID,TP_REDIRECT_URI,TP_CLIENT_KEY,TP_CLIENT_SECRET, BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY, PAYMENT_PROCESSING_ON, RECAPTCHA_SITE_KEY, RECAPTCHA_SITE_SECRET ) #from rowers.tasks_standalone import addcomment2 from django.contrib import messages from async_messages import messages as a_messages from django.contrib.admin.widgets import AdminDateWidget,AdminTimeWidget,AdminSplitDateTime import requests import json from rest_framework.renderers import JSONRenderer from rest_framework.parsers import JSONParser from rowers.rows import handle_uploaded_file,handle_uploaded_image from rowers.plannedsessions import * from rowers.tasks import handle_makeplot,handle_otwsetpower,handle_sendemailtcx,handle_sendemailcsv from rowers.tasks import ( handle_sendemail_unrecognized,handle_sendemailnewcomment, handle_sendemailsummary, handle_send_disqualification_email, handle_sendemailfile, handle_sendemailkml, handle_sendemailnewresponse, handle_updatedps, handle_updatecp,long_test_task,long_test_task2, handle_zip_file,handle_getagegrouprecords, handle_updatefitnessmetric, handle_update_empower, handle_sendemailics, handle_sendemail_userdeleted, handle_sendemail_raceregistration, handle_sendemail_racesubmission, handle_sendemail_ical, ) from scipy.signal import savgol_filter #from django.shortcuts import render_to_response try: from Cookie import SimpleCookie except ModuleNotFoundError: from http.cookies import SimpleCookie from shutil import copyfile,move import rowers.mytypes as mytypes from rowingdata import rower as rrower from rowingdata import main as rmain from rowingdata import rowingdata as rrdata from rowingdata import make_cumvalues from rowingdata import summarydata import pandas as pd import numpy as np import matplotlib.pyplot as plt from rowers.emails import send_template_email,htmlstrip from rowers.alerts import * from pytz import timezone as tz,utc from timezonefinder import TimezoneFinder import dateutil import mpld3 from mpld3 import plugins import stravalib from stravalib.exc import ActivityUploadFailed,TimeoutExceeded from rowers.weather import get_wind_data,get_airport_code,get_metar_data from oauth2_provider.models import Application,Grant,AccessToken import django_rq queue = django_rq.get_queue('default') queuelow = django_rq.get_queue('low') queuehigh = django_rq.get_queue('low') import redis import threading from redis import StrictRedis,Redis from rq.exceptions import NoSuchJobError from rq.registry import StartedJobRegistry from rq import Queue,cancel_job from django.core.cache import cache from django_mailbox.models import Message,Mailbox,MessageAttachment # Utility to get stroke data in a JSON response class JSONResponse(HttpResponse): def __init__(self, data, **kwargs): content = JSONRenderer().render(data) kwargs['content_type'] = 'application/json' super(JSONResponse, self).__init__(content, **kwargs) def getfavorites(r,row): workouttype = 'ote' if row.workouttype in mytypes.otwtypes: workouttype = 'otw' matchworkouttypes = [workouttype,'all'] workoutsource = row.workoutsource if 'speedcoach2' in row.workoutsource: workoutsource = 'speedcoach2' favorites = FavoriteChart.objects.filter(user=r, workouttype__in=matchworkouttypes).order_by("id") favorites2 = FavoriteChart.objects.filter(user=r, workouttype__in=[workoutsource]).order_by("id") favorites = favorites | favorites2 maxfav = len(favorites)-1 return favorites,maxfav def get_workout_default_page(request,id): if request.user.is_anonymous: return reverse('workout_view',kwargs={'id':id}) else: r = Rower.objects.get(user=request.user) if r.defaultlandingpage == 'workout_edit_view': return reverse('workout_edit_view',kwargs={'id':id}) else: return reverse('workout_workflow_view',kwargs={'id':id}) def getrequestrower(request,rowerid=0,userid=0,notpermanent=False): userid = int(userid) rowerid = int(rowerid) if notpermanent == False: if rowerid == 0 and 'rowerid' in request.session: rowerid = request.session['rowerid'] if userid != 0: rowerid = 0 try: if rowerid != 0: r = Rower.objects.get(id=rowerid) elif userid != 0: u = User.objects.get(id=userid) r = getrower(u) else: r = getrower(request.user) except Rower.DoesNotExist: raise Http404("Rower doesn't exist") if not checkaccessuser(request.user,r): raise PermissionDenied("You have no access to this user") if notpermanent == False: request.session['rowerid'] = r.id return r def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False): userid = int(userid) rowerid = int(rowerid) if notpermanent == False: if rowerid == 0 and 'rowerid' in request.session: rowerid = request.session['rowerid'] if userid != 0: rowerid = 0 try: if rowerid != 0: r = Rower.objects.get(id=rowerid) elif userid != 0: u = User.objects.get(id=userid) r = getrower(u) else: r = getrower(request.user) except Rower.DoesNotExist: raise Http404("Rower doesn't exist") if not checkaccessplanuser(request.user,r): raise PermissionDenied("You have no access to this user") if notpermanent == False: request.session['rowerid'] = r.id return r def getrower(user): try: if user.is_anonymous: return None except AttributeError: if User.objects.get(id=user).is_anonymous: return None try: r = Rower.objects.get(user=user) except Rower.DoesNotExist: r = Rower(user=user) r.save() return r def get_workout(id): try: id = encoder.decode_hex(id) w = Workout.objects.get(id=id) except Workout.DoesNotExist: raise Http404("Workout doesn't exist") return w def get_workout_permitted(user,id): w = get_workout(id) if (checkworkoutuser(user,w)==False): raise PermissionDenied("Access denied") return w def get_workout_permittedview(user,id): w = get_workout(id) if (checkworkoutuserview(user,w)==False): raise PermissionDenied("Access denied") return w def getvalue(data): perc = 0 total = 1 done = 0 id = 0 session_key = 'noot' for i in data.iteritems(): if i[0] == 'total': total = float(i[1]) if i[0] == 'done': done = float(i[1]) if i[0] == 'id': id = i[1] if i[0] == 'session_key': session_key = i[1] return total,done,id,session_key class SessionTaskListener(threading.Thread): def __init__(self, r, channels): threading.Thread.__init__(self) self.redis = r self.pubsub = self.redis.pubsub() self.pubsub.subscribe(channels) def work(self, item): try: data = json.loads(item['data']) total,done,id,session_key = getvalue(data) perc = int(100.*done/total) cache.set(id,perc,3600) except TypeError: pass def run(self): for item in self.pubsub.listen(): if item['data'] == "KILL": self.pubsub.unsubscribe() print(self, "unsubscribed and finished") break else: self.work(item) queuefailed = Queue("failed",connection=Redis()) redis_connection = StrictRedis() r = Redis() # this doesn't yet work on production #if settings.DEBUG: # client = SessionTaskListener(r,['tasks']) # client.start() rq_registry = StartedJobRegistry(queue.name,connection=redis_connection) rq_registryhigh = StartedJobRegistry(queuehigh.name,connection=redis_connection) rq_registrylow = StartedJobRegistry(queuelow.name,connection=redis_connection) from rq.job import Job try: from rest_framework_swagger.views import get_swagger_view except ImportError: pass from rest_framework.renderers import JSONRenderer from rest_framework.parsers import JSONParser from rest_framework.response import Response from rowers.serializers import RowerSerializer,WorkoutSerializer try: from rest_framework import status,permissions,generics except ImportError: pass from rest_framework.decorators import api_view, renderer_classes from rowers.permissions import IsOwnerOrNot import rowers.plots as plots import rowers.mailprocessing as mailprocessing from io import BytesIO from scipy.special import lambertw from rowers.dataprep import timedeltaconv from rowers.dataprep import getsmallrowdata_db from scipy.interpolate import griddata #LOCALTIMEZONE = tz('Etc/UTC') USER_LANGUAGE = 'en-US' from rowers.interactiveplots import * from rowers.celery import result as celery_result # Define the API documentation try: schema_view = get_swagger_view(title='Rowsandall API') except NameError: pass def remove_asynctask(request,id): try: oldtasks = request.session['async_tasks'] except KeyError: oldtasks = [] newtasks = [] for task in oldtasks: if id not in task[0]: newtasks += [(task[0],task[1])] request.session['async_tasks'] = newtasks def get_job_result(jobid): if settings.TESTING: return None elif settings.CELERY: result = celery_result.AsyncResult(jobid).result else: running_job_ids = rq_registry.get_job_ids() if len(running_job_ids) and jobid in running_job_ids: # job is running return None else: # job is ready try: job = Job.fetch(jobid,connection=redis_connection) result = job.result except NoSuchJobError: return None return result verbose_job_status = { 'updatecp': 'Critical Power Calculation for Ergometer Workouts', 'updatecpwater': 'Critical Power Calculation for OTW Workouts', 'otwsetpower': 'Rowing Physics OTW Power Calculation', 'agegrouprecords': 'Calculate age group records', 'make_plot': 'Create static chart', 'long_test_task': 'Long Test Task', 'long_test_task2': 'Long Test Task 2', 'update_empower': 'Correct Empower Inflated Power Bug', 'submit_race': 'Checking Race Course Result', } def get_job_status(jobid): if settings.TESTING: summary = { 'status': 'failed', 'result': 0, 'finished': True, 'failed': True, 'started_at':None, } return summary elif settings.CELERY: job = celery_result.AsyncResult(jobid) jobresult = job.result if 'fail' in job.status.lower(): jobresult = '0' summary = { 'status': job.status, 'result': jobresult, 'started_at': None } else: try: job = Job.fetch(jobid,connection=redis_connection) try: status = job.status except AttributeError: status = job.get_status() summary = { 'status':status, 'result':job.result, 'started_at':job.started_at } except NoSuchJobError: summary = { 'status': 'success', 'result': 1, 'started_at':None, } try: if 'fail' in summary['status'].lower(): summary['failed'] = True else: summary['failed'] = False if 'success' in summary['status'].lower(): summary['finished'] = True elif 'finished' in summary['status'].lower(): summary['finished'] = True else: summary['finished'] = False except AttributeError: summary = { 'status': 'failed', 'result': 0, 'finished': True, 'failed': True, 'started_at':None, } return summary def kill_async_job(request,id='aap'): if settings.CELERY: job = celery_result.AsyncResult(id) job.revoke() else: try: cancel_job(id,connection=redis_connection) except NoSuchJobError: pass remove_asynctask(request,id) cache.delete(id) url = reverse(session_jobs_status) return HttpResponseRedirect(url) @login_required() def raise_500(request): if request.user.is_superuser: raise ValueError else: return HttpResponse("invalid") #@login_required() #def test_job_view(request,aantal=100): # # session_key = request.session._session_key # # job = myqueue(queuehigh,long_test_task,int(aantal), # session_key=session_key) # # # try: # request.session['async_tasks'] += [(job.id,'long_test_task')] # except KeyError: # request.session['async_tasks'] = [(job.id,'long_test_task')] # # url = reverse(session_jobs_status) # # return HttpResponseRedirect(url) #@login_required() #def test_job_view2(request,aantal=100): # # # job = myqueue(queuehigh,long_test_task2,int(aantal), # secret=settings.PROGRESS_CACHE_SECRET)# # # # try: # request.session['async_tasks'] += [(job.id,'long_test_task2')] # except KeyError: # request.session['async_tasks'] = [(job.id,'long_test_task2')] # # url = reverse(session_jobs_status) # # return HttpResponseRedirect(url) @csrf_exempt def post_progress(request,id=None,value=0): if request.method == 'POST': try: secret = request.POST['secret'] except KeyError: return HttpResponse('Access Denied',status=401) if secret == settings.PROGRESS_CACHE_SECRET: if not id: try: id = request.POST['id'] except KeyError: return HttpResponse('Invalid request',400) try: value = request.POST['value'] except KeyError: pass cache.set(id,value,3600) # test result = cache.get(id) return HttpResponse('progress cached '+str(result), status=201) else: # secret not given return HttpResponse('access denied',status=401) else: # request method is not POST return HttpResponse('GET method not allowed',status=405) def get_all_queued_jobs(userid=0): r = StrictRedis() jobs = [] celerykeys = r.keys('celery*') for key in celerykeys: id= key[17:] job = celery_result.AsyncResult(id) jobresult = job.result if 'fail' in job.status.lower(): jobresult = '0' jobs.append( (id,{ 'status':job.status, 'result':jobresult, 'function':'', 'meta':job.info, })) ids = [j.id for j in queue.jobs] ids += [j.id for j in queuehigh.jobs] ids += [j.id for j in queuelow.jobs] ids += [j.id for j in queuefailed.jobs] for id in ids: job = Job.fetch(id,connection=redis_connection) jobs.append( (id,{ 'status':job.get_status(), 'result':job.result, 'function':job.func_name, 'meta':job.meta, })) return jobs def get_stored_tasks_status(request): try: taskids = request.session['async_tasks'] except KeyError: taskids = [] taskstatus = [] for id,func_name in reversed(taskids): progress = 0 try: cached_progress = cache.get(id) if cached_progress is not None: cached_progress = int(cached_progress) else: cached_progress = 0 except ValueError: cached_progress = 0 finished = get_job_status(id)['finished'] if finished: cache.set(id,100) progress = 100 elif cached_progress is not None and cached_progress>0: progress = cached_progress else: progress = 0 this_task_status = { 'id':id, 'status':get_job_status(id)['status'], 'failed':get_job_status(id)['failed'], 'finished':get_job_status(id)['finished'], 'func_name':func_name, 'verbose': verbose_job_status[func_name], 'progress': progress, } taskstatus.append(this_task_status) return taskstatus @login_required() def get_thumbnails(request,id): row = get_workout_permitted(request.user,id) r = getrower(request.user) result = request.user.is_authenticated and ispromember(request.user) if result: promember=1 if request.user == row.user.user: mayedit=1 comments = WorkoutComment.objects.filter(workout=row) aantalcomments = len(comments) favorites,maxfav = getfavorites(r,row) charts = [] charts = thumbnails_set(r,encoder.decode_hex(id),favorites) try: if charts[0]['script'] == '': charts = [] except IndexError: charts = [] return JSONResponse(charts) def get_blog_posts(request): blogposts = BlogPost.objects.all().order_by("-date") jsondata = [] if blogposts: for blogpost in blogposts[0:3]: thedict = { 'title':blogpost.title, 'link':blogpost.link, } jsondata.append(thedict) return JSONResponse(jsondata) def get_blog_posts_old(request): try: response = requests.get( 'https://analytics.rowsandall.com/wp-json/wp/v2/posts?per_page=3') if response.status_code == 200: blogs_json = response.json() # with open('blogs.txt','w') as o: # o.write(json.dumps(blogs_json,indent=2,sort_keys=True)) else: blogs_json = [] except ConnectionError: pass blogposts = [] for postdata in blogs_json[0:3]: try: title = postdata['title']['rendered'].encode( 'ascii','xmlcharrefreplace') except TypeError: title = postdata['title']['rendered'].encode( 'ascii','xmlcharrefreplace').decode('utf-8') thedict = { 'title': title, # 'author': '', # 'image': image_url, # 'excerpt': excerpt_first, 'link': postdata['link'], } blogposts.append(thedict) return JSONResponse(blogposts) @login_required() def get_testscript(request,id): row = get_workout_permitted(request.user,id) r = getrower(request.user) object = { "script":"""
""", "div":"""
Hoi
""" } return JSONResponse([object,object]) @login_required() def session_jobs_view(request): taskstatus = get_stored_tasks_status(request) return HttpResponse(json.dumps(taskstatus)) @login_required() def session_jobs_status(request): taskstatus = get_stored_tasks_status(request) return render(request, 'async_tasks.html', {'taskstatus':taskstatus}) # Test if row data include candidates def rowhascoordinates(row): # create interactive plot f1 = row.csvfilename u = row.user.user r = getrower(u) rowdata = rdata(f1) hascoordinates = 1 if rowdata != 0: try: latitude = rowdata.df[' latitude'] if not latitude.std(): hascoordinates = 0 except (KeyError,AttributeError): hascoordinates = 0 else: hascoordinates = 0 return hascoordinates # Wrapper around the rowingdata call to catch some exceptions # Checks for CSV file, then for gzipped CSV file, and if all fails, returns 0 def rdata(file,rower=rrower()): try: res = rrdata(csvfile=file,rower=rower) except (IOError, IndexError, EOFError): try: res = rrdata(csvfile=file+'.gz',rower=rower) except (IOError, IndexError, EOFError): res = 0 return res # Query to get teams managed and member of def get_my_teams(user): try: therower = Rower.objects.get(user=user) try: teams1 = therower.team.all() except AttributeError: teams1 = [] teams2 = Team.objects.filter(manager=user) teams = list(set(teams1).union(set(teams2))) except TypeError: teams = [] return teams # Used for the interval editor - translates seconds to a time object def get_time(second): if (second<=0) or (second>1e9): hours = 0 minutes=0 sec=0 microsecond = 0 elif math.isnan(second): hours = 0 minutes=0 sec=0 microsecond = 0 else: days = int(second/(24.*3600.)) % (24*3600) hours = int((second-24.*3600.*days)/3600.) % 24 minutes = int((second-3600.*(hours+24.*days))/60.) % 60 sec = int(second-3600.*(hours+24.*days)-60.*minutes) % 60 microsecond = int(1.0e6*(second-3600.*(hours+24.*days)-60.*minutes-sec)) return datetime.time(hours,minutes,sec,microsecond) # get the workout ID from the SportTracks URI def getidfromsturi(uri,length=8): return uri[len(uri)-length:] import re def getidfromuri(uri): m = re.search('/(\w.*)\/(\d+)',uri) return m.group(2) from rowers.utils import ( geo_distance,serialize_list,deserialize_list,uniqify, str2bool,range_to_color_hex,absolute,myqueue,get_call, calculate_age,rankingdistances,rankingdurations, is_ranking_piece,my_dict_from_instance,wavg,NoTokenError ) import rowers.datautils as datautils from rowers.models import ( checkworkoutuser,checkaccessuser,checkviewworkouts,checkworkoutuserview ) # Check if a user is a Coach member def iscoachmember(user): if not user.is_anonymous: try: r = Rower.objects.get(user=user) except Rower.DoesNotExist: r = Rower(user=user) r.save() result = user.is_authenticated and ('coach' in r.rowerplan) else: result = False return result def cancreateteam(user): if user.is_anonymous: return False try: r = Rower.objects.get(user=user) except Rower.DoesNotExist: r = Rower(user=user) r.save() if user.is_authenticated and ('coach' in r.rowerplan): return True elif user.is_athenticated() and r.rowerplan in ['plan','pro']: ts = Team.objects.filter(manager=user) if len(otherteams) >= 1: return False # Check if a user can create planned sessions def hasplannedsessions(user): if not user.is_anonymous: try: r = Rower.objects.get(user=user) except Rower.DoesNotExist: r = Rower(user=user) r.save() result = user.is_authenticated and (r.rowerplan=='coach' or r.rowerplan=='freecoach' or r.rowerplan=='plan') if not result and r.plantrialexpires: result = user.is_authenticated and r.plantrialexpires >= datetime.date.today() else: result = False return result from rowers.utils import ProcessorCustomerError from rowers.utils import isprorower # Check if a user is a Pro member def ispromember(user): if user and not user.is_anonymous: try: r = Rower.objects.get(user=user) except Rower.DoesNotExist: r = Rower(user=user) r.save() result = user.is_authenticated and isprorower(r) else: result = False return result # More User/Rower utils def add_defaultfavorites(r): for c in defaultfavoritecharts: f = FavoriteChart(user=r, yparam1=c['yparam1'], yparam2=c['yparam2'], xparam=c['xparam'], plottype=c['plottype'], workouttype=c['workouttype'], reststrokes=c['reststrokes'], notes=c['notes']) f.save() return 1 # Shows email form and sends it if submitted def sendmail(request): if request.method == 'POST': # test recaptcha response_string = request.POST.get('g-recaptcha-response') # replace below with settings recaptcha_secret = RECAPTCHA_SITE_SECRET url = 'https://www.google.com/recaptcha/api/siteverify' data = { 'secret':recaptcha_secret, 'response': response_string, } response = requests.post(url,data=data,verify=True) success = False if response.status_code == 200: success = response.json().get('success') form = EmailForm(request.POST) if form.is_valid() and success: firstname = form.cleaned_data['firstname'] lastname = form.cleaned_data['lastname'] email = form.cleaned_data['email'] subject = 'Rowsandall Contact Form:'+form.cleaned_data['subject'] message = form.cleaned_data['message'] fullemail = firstname + " " + lastname + " " + "<" + email + ">" send_mail(subject, message, fullemail, ['info@rowsandall.com']) return HttpResponseRedirect('/rowers/email/thankyou/') else: if not success: messages.error(request,'Bots are not welcome') else: messages.error(request,'Something went wrong. Please try again') return HttpResponseRedirect('/rowers/email/') else: return HttpResponseRedirect('/rowers/email/') # Create workout data from Strava or Concept2 # data and create the associated Workout object and save it def add_workout_from_strokedata(user,importid,data,strokedata, source='c2',splitdata=None, workoutsource='concept2'): try: workouttype = data['type'] except KeyError: workouttype = 'rower' if workouttype not in [x[0] for x in Workout.workouttypes]: workouttype = 'other' try: comments = data['comments'] except: comments = ' ' # comments = "Imported data \n %s" % comments # comments = "Imported data \n"+comments # str(comments) try: thetimezone = tz(data['timezone']) except: thetimezone = 'UTC' r = getrower(user) try: rowdatetime = iso8601.parse_date(data['date_utc']) except KeyError: rowdatetime = iso8601.parse_date(data['start_date']) except ParseError: rowdatetime = iso8601.parse_date(data['date']) try: c2intervaltype = data['workout_type'] except KeyError: c2intervaltype = '' try: title = data['name'] except KeyError: title = "" try: t = data['comments'].split('\n', 1)[0] title += t[:20] except: title = 'Imported' starttimeunix = arrow.get(rowdatetime).timestamp res = make_cumvalues(0.1*strokedata['t']) cum_time = res[0] lapidx = res[1] unixtime = cum_time+starttimeunix # unixtime[0] = starttimeunix seconds = 0.1*strokedata.loc[:,'t'] nr_rows = len(unixtime) try: latcoord = strokedata.loc[:,'lat'] loncoord = strokedata.loc[:,'lon'] except: latcoord = np.zeros(nr_rows) loncoord = np.zeros(nr_rows) try: strokelength = strokedata.loc[:,'strokelength'] except: strokelength = np.zeros(nr_rows) dist2 = 0.1*strokedata.loc[:,'d'] try: spm = strokedata.loc[:,'spm'] except KeyError: spm = 0*dist2 try: hr = strokedata.loc[:,'hr'] except KeyError: hr = 0*spm pace = strokedata.loc[:,'p']/10. pace = np.clip(pace,0,1e4) pace = pace.replace(0,300) velo = 500./pace power = 2.8*velo**3 # save csv # Create data frame with all necessary data to write to csv df = pd.DataFrame({'TimeStamp (sec)':unixtime, ' Horizontal (meters)': dist2, ' Cadence (stokes/min)':spm, ' HRCur (bpm)':hr, ' longitude':loncoord, ' latitude':latcoord, ' Stroke500mPace (sec/500m)':pace, ' Power (watts)':power, ' DragFactor':np.zeros(nr_rows), ' DriveLength (meters)':np.zeros(nr_rows), ' StrokeDistance (meters)':strokelength, ' DriveTime (ms)':np.zeros(nr_rows), ' StrokeRecoveryTime (ms)':np.zeros(nr_rows), ' AverageDriveForce (lbs)':np.zeros(nr_rows), ' PeakDriveForce (lbs)':np.zeros(nr_rows), ' lapIdx':lapidx, ' ElapsedTime (sec)':seconds }) 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 csvfilename ='media/{code}_{importid}.csv'.format( importid=importid, code = uuid4().hex[:16] ) res = df.to_csv(csvfilename+'.gz',index_label='index', compression='gzip') # with Concept2 if source=='c2': try: totaldist = data['distance'] totaltime = data['time']/10. except KeyError: totaldist = 0 totaltime = 0 else: totaldist = 0 totaltime = 0 id,message = dataprep.save_workout_database( csvfilename,r, workouttype=workouttype, title=title,notes=comments, # totaldist=totaldist, # totaltime=totaltime, workoutsource=workoutsource, dosummary=True ) return id,message def keyvalue_get_default(key,options,def_options): try: return options[key] except KeyError: return def_options[key] # Creates unix time stamp from a datetime object def totimestamp(dt, epoch=datetime.datetime(1970,1,1,tzinfo=tz('UTC'))): td = dt - epoch # return td.total_seconds() return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6 # Check if a column of a dataframe has the required (aantal) # number of elements. Also checks if the column is a numerical type # Replaces any faulty columns with zeros def trydf(df,aantal,column): try: s = df[column] if len(s) != aantal: return np.zeros(aantal) if not np.issubdtype(s,np.number): return np.zeros(aantal) except KeyError: s = np.zeros(aantal) return s import rowers.teams as teams from rowers.models import C2WorldClassAgePerformance