Merge branch 'release/v6.25'
This commit is contained in:
@@ -677,10 +677,14 @@ def getsmallrowdata_db(columns,ids=[],debug=False):
|
|||||||
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False,
|
def fitnessmetric_to_sql(m,table='powertimefitnessmetric',debug=False,
|
||||||
doclean=False):
|
doclean=False):
|
||||||
# test if nan among values
|
# test if nan among values
|
||||||
if np.nan in m.values():
|
if np.nan in m.values() or np.inf in m.values():
|
||||||
for key in m.keys():
|
for key in m.keys():
|
||||||
if np.isnan([m[key]]):
|
if np.isnan([m[key]]):
|
||||||
m[key] = -1
|
m[key] = -1
|
||||||
|
if m[key] == np.inf:
|
||||||
|
m[key] = -1
|
||||||
|
if -m[key] == np.inf:
|
||||||
|
m[key] = -1
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
engine = create_engine(database_url_debug, echo=False)
|
engine = create_engine(database_url_debug, echo=False)
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
import time
|
|
||||||
from django.views.generic.base import TemplateView
|
|
||||||
from django.shortcuts import render
|
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
|
||||||
from django.contrib.auth import authenticate, login, logout
|
|
||||||
from rowers.forms import LoginForm,DocumentsForm,UploadOptionsForm
|
|
||||||
from django.core.urlresolvers import reverse
|
|
||||||
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 EmailForm, RegistrationForm, RegistrationFormTermsOfService,RegistrationFormUniqueEmail,CNsummaryForm,UpdateWindForm,UpdateStreamForm
|
|
||||||
from rowers.forms import PredictedPieceForm
|
|
||||||
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage,AdvancedWorkoutForm
|
|
||||||
import StringIO
|
|
||||||
from django.contrib.auth.decorators import login_required,user_passes_test
|
|
||||||
from time import strftime,strptime,mktime,time,daylight
|
|
||||||
import os,sys
|
|
||||||
import datetime
|
|
||||||
import iso8601
|
|
||||||
import c2stuff
|
|
||||||
from c2stuff import C2NoTokenError
|
|
||||||
from iso8601 import ParseError
|
|
||||||
import stravastuff
|
|
||||||
import sporttracksstuff
|
|
||||||
from rowsandall_app.settings import C2_CLIENT_ID, C2_REDIRECT_URI, C2_CLIENT_SECRET, STRAVA_CLIENT_ID, STRAVA_REDIRECT_URI, STRAVA_CLIENT_SECRET
|
|
||||||
from rowsandall_app.settings import SPORTTRACKS_CLIENT_ID, SPORTTRACKS_REDIRECT_URI, SPORTTRACKS_CLIENT_SECRET
|
|
||||||
import requests
|
|
||||||
import json
|
|
||||||
from rowers.rows import handle_uploaded_file
|
|
||||||
from rowers.tasks import handle_makeplot,handle_otwsetpower,handle_sendemailtcx
|
|
||||||
from scipy.signal import savgol_filter
|
|
||||||
|
|
||||||
from rowingdata import rower as rrower
|
|
||||||
from rowingdata import main as rmain
|
|
||||||
from rowingdata import rowingdata as rdata
|
|
||||||
from rowingdata import TCXParser,RowProParser,ErgDataParser,TCXParserNoHR
|
|
||||||
from rowingdata import painsledDesktopParser,speedcoachParser,ErgStickParser
|
|
||||||
from rowingdata import SpeedCoach2Parser,FITParser,fitsummarydata
|
|
||||||
from rowingdata import make_cumvalues
|
|
||||||
from rowingdata import summarydata,get_file_type
|
|
||||||
import pandas as pd
|
|
||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from pytz import timezone as tz,utc
|
|
||||||
import dateutil
|
|
||||||
import mpld3
|
|
||||||
from mpld3 import plugins
|
|
||||||
import stravalib
|
|
||||||
from stravalib.exc import ActivityUploadFailed,TimeoutExceeded
|
|
||||||
from weather import get_wind_data
|
|
||||||
|
|
||||||
import django_rq
|
|
||||||
queue = django_rq.get_queue('default')
|
|
||||||
queuelow = django_rq.get_queue('low')
|
|
||||||
queuehigh = django_rq.get_queue('low')
|
|
||||||
|
|
||||||
import plots
|
|
||||||
|
|
||||||
from io import BytesIO
|
|
||||||
from scipy.special import lambertw
|
|
||||||
|
|
||||||
# used in shell to send a newsletter to all Rowers
|
|
||||||
def emailall(emailfile,subject):
|
|
||||||
rowers = Rower.objects.all()
|
|
||||||
for rower in rowers:
|
|
||||||
email = rower.user.email
|
|
||||||
firstname = rower.user.first_name
|
|
||||||
|
|
||||||
print email
|
|
||||||
|
|
||||||
with open(emailfile) as f:
|
|
||||||
message = f.read()
|
|
||||||
|
|
||||||
message = '\nDear '+firstname+',\n\n'+str(message)
|
|
||||||
|
|
||||||
send_mail(
|
|
||||||
subject,
|
|
||||||
message,
|
|
||||||
'info@rowsandall.com',
|
|
||||||
[email],
|
|
||||||
)
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
from django.core.mail.message import MIMEText
|
||||||
|
#from email.mime.application import MIMEApplication
|
||||||
|
from django.core.mail.message import MIMEMultipart
|
||||||
|
|
||||||
|
# boto3 email functionality
|
||||||
|
import boto3
|
||||||
|
AWS_REGION = "us-west-2"
|
||||||
|
CHARSET = "UTF-8"
|
||||||
|
client = boto3.client('ses',region_name=AWS_REGION)
|
||||||
|
|
||||||
|
def sendemail(fromaddress,recipients,subjecttext,bodytext,attachment=None):
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg['Subject'] = subjecttext
|
||||||
|
msg['From'] = fromaddress
|
||||||
|
msg['To'] = recipients
|
||||||
|
part = MIMEText(bodytext)
|
||||||
|
msg.attach(part)
|
||||||
|
|
||||||
|
# if attachment:
|
||||||
|
# part = MIMEApplication(open(attachment,'rb').read())
|
||||||
|
# part.add_header('Content-Disposition', 'attachment',
|
||||||
|
# filename=attachment)
|
||||||
|
# msg.attach(part)
|
||||||
|
|
||||||
|
result = client.send_raw_email(
|
||||||
|
Source=msg['From'],
|
||||||
|
Destination=msg['To'],
|
||||||
|
RawMessage=msg
|
||||||
|
)
|
||||||
|
|
||||||
|
return result
|
||||||
@@ -571,6 +571,8 @@ class Rower(models.Model):
|
|||||||
|
|
||||||
getemailnotifications = models.BooleanField(default=False,
|
getemailnotifications = models.BooleanField(default=False,
|
||||||
verbose_name='Receive email notifications')
|
verbose_name='Receive email notifications')
|
||||||
|
emailbounced = models.BooleanField(default=False,
|
||||||
|
verbose_name='Email Address Bounced')
|
||||||
|
|
||||||
rowerplan = models.CharField(default='basic',max_length=30,
|
rowerplan = models.CharField(default='basic',max_length=30,
|
||||||
choices=plans)
|
choices=plans)
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ def is_session_complete_ws(ws,ps):
|
|||||||
if ratio>cratiomin and ratio<cratiomax:
|
if ratio>cratiomin and ratio<cratiomax:
|
||||||
return ratio,'completed',completiondate
|
return ratio,'completed',completiondate
|
||||||
else:
|
else:
|
||||||
|
completiondate = ws.reverse()[0].date
|
||||||
return ratio,'partial',completiondate
|
return ratio,'partial',completiondate
|
||||||
elif ps.sessiontype == 'test':
|
elif ps.sessiontype == 'test':
|
||||||
if ratio==1.0:
|
if ratio==1.0:
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import arrow
|
|||||||
# testing task
|
# testing task
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def add(x, y):
|
def add(x, y):
|
||||||
return x + y
|
return x + y
|
||||||
@@ -548,10 +549,12 @@ def handle_sendemailsummary(first_name, last_name, email, csvfile, **kwargs):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
#from rowers.emails import sendemail
|
||||||
|
|
||||||
@app.task
|
@app.task
|
||||||
def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
||||||
|
|
||||||
|
|
||||||
# send email with attachment
|
# send email with attachment
|
||||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||||
subject = "File from Rowsandall.com"
|
subject = "File from Rowsandall.com"
|
||||||
@@ -559,6 +562,8 @@ def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
|||||||
message += "Please find attached the requested file for your workout.\n\n"
|
message += "Please find attached the requested file for your workout.\n\n"
|
||||||
message += "Best Regards, the Rowsandall Team"
|
message += "Best Regards, the Rowsandall Team"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
email = EmailMessage(subject, message,
|
email = EmailMessage(subject, message,
|
||||||
'Rowsandall <info@rowsandall.com>',
|
'Rowsandall <info@rowsandall.com>',
|
||||||
[fullemail])
|
[fullemail])
|
||||||
@@ -573,6 +578,7 @@ def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
|||||||
email.attach_file(csvfile2)
|
email.attach_file(csvfile2)
|
||||||
os.remove(csvfile2)
|
os.remove(csvfile2)
|
||||||
|
|
||||||
|
|
||||||
res = email.send()
|
res = email.send()
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
@@ -120,7 +120,11 @@
|
|||||||
<td> {{ ps.sessionvalue }} </td>
|
<td> {{ ps.sessionvalue }} </td>
|
||||||
<td> {{ actualvalue|lookup:ps.id }}</td>
|
<td> {{ actualvalue|lookup:ps.id }}</td>
|
||||||
<td> {{ ps.sessionunit }} </td>
|
<td> {{ ps.sessionunit }} </td>
|
||||||
|
{% if completeness|lookup:ps.id == 'partial' %}
|
||||||
|
<td style="color:darkgray"><i> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</i></td>
|
||||||
|
{% else %}
|
||||||
<td> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</td>
|
<td> {{ completiondate|lookup:ps.id|date:"Y-m-d" }}</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -94,6 +94,27 @@
|
|||||||
at support@rowsandall.com.
|
at support@rowsandall.com.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<h2>Notifications and Email Policy</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Some actions on the site result in an individual email sent to you.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
We will rarely use mass email to communicate to all our users. These cases
|
||||||
|
are limited to substantial changes in terms and conditions and other
|
||||||
|
announcements impacting the terms on which you use the site. We will
|
||||||
|
it is important to get these messages to you. If you do not with
|
||||||
|
to receive such emails, you can indicate so in the user settings.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Other site related communication (new features, outages, bugs,
|
||||||
|
price changes) are communicated through announcements on the
|
||||||
|
website, throught Twitter, Facebook and our blog
|
||||||
|
posts.
|
||||||
|
</p>
|
||||||
|
|
||||||
<h2>Data Deletion</h2>
|
<h2>Data Deletion</h2>
|
||||||
|
|
||||||
<p>If you have previously consented to allow rowsandall.com to store and process your personal
|
<p>If you have previously consented to allow rowsandall.com to store and process your personal
|
||||||
|
|||||||
@@ -8722,7 +8722,14 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
|||||||
startdatetime = (str(date) + ' ' + str(starttime))
|
startdatetime = (str(date) + ' ' + str(starttime))
|
||||||
startdatetime = datetime.datetime.strptime(startdatetime,
|
startdatetime = datetime.datetime.strptime(startdatetime,
|
||||||
"%Y-%m-%d %H:%M:%S")
|
"%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
|
startdatetime = startdatetime.replace(tzinfo=pytz.timezone(thetimezone))
|
||||||
|
try:
|
||||||
|
# aware object can be in any timezone
|
||||||
|
out = startdatetime.astimezone(pytz.utc)
|
||||||
|
except (ValueError, TypeError):
|
||||||
startdatetime = timezone.make_aware(startdatetime)
|
startdatetime = timezone.make_aware(startdatetime)
|
||||||
|
|
||||||
startdatetime = startdatetime.astimezone(pytz.timezone(thetimezone))
|
startdatetime = startdatetime.astimezone(pytz.timezone(thetimezone))
|
||||||
|
|
||||||
|
|
||||||
@@ -11224,11 +11231,16 @@ def rower_edit_view(request,rowerid=0,message=""):
|
|||||||
getemailnotifications = cd['getemailnotifications']
|
getemailnotifications = cd['getemailnotifications']
|
||||||
defaulttimezone=cd['defaulttimezone']
|
defaulttimezone=cd['defaulttimezone']
|
||||||
u = r.user
|
u = r.user
|
||||||
|
if u.email != email and len(email):
|
||||||
|
resetbounce = True
|
||||||
|
else:
|
||||||
|
resetbounce = False
|
||||||
if len(first_name):
|
if len(first_name):
|
||||||
u.first_name = first_name
|
u.first_name = first_name
|
||||||
u.last_name = last_name
|
u.last_name = last_name
|
||||||
if len(email): ## and check_email_freeforuse(u,email):
|
if len(email): ## and check_email_freeforuse(u,email):
|
||||||
u.email = email
|
u.email = email
|
||||||
|
resetbounce = True
|
||||||
|
|
||||||
|
|
||||||
u.save()
|
u.save()
|
||||||
@@ -11239,6 +11251,9 @@ def rower_edit_view(request,rowerid=0,message=""):
|
|||||||
r.showfavoritechartnotes = showfavoritechartnotes
|
r.showfavoritechartnotes = showfavoritechartnotes
|
||||||
r.sex = sex
|
r.sex = sex
|
||||||
r.birthdate = birthdate
|
r.birthdate = birthdate
|
||||||
|
if resetbounce and r.emailbounced:
|
||||||
|
print "aap"
|
||||||
|
r.emailbounced = False
|
||||||
r.save()
|
r.save()
|
||||||
form = RowerForm(instance=r)
|
form = RowerForm(instance=r)
|
||||||
powerform = RowerPowerForm(instance=r)
|
powerform = RowerPowerForm(instance=r)
|
||||||
|
|||||||
+18
-10
@@ -315,17 +315,25 @@ CACHE_MIDDLEWARE_SECONDS = 900
|
|||||||
|
|
||||||
# email stuff
|
# email stuff
|
||||||
|
|
||||||
EMAIL_BACKEND = CFG['email_backend']
|
#EMAIL_BACKEND = CFG['email_backend']
|
||||||
EMAIL_HOST = CFG['email_host']
|
#EMAIL_HOST = CFG['email_host']
|
||||||
#EMAIL_HOST = 'smtp.rosti.cz'
|
#EMAIL_PORT = CFG['email_port']
|
||||||
#EMAIL_PORT = '25'
|
#EMAIL_HOST_USER = CFG['email_host_user']
|
||||||
EMAIL_PORT = CFG['email_port']
|
#EMAIL_HOST_PASSWORD = CFG['email_host_password']
|
||||||
EMAIL_HOST_USER = CFG['email_host_user']
|
#EMAIL_USE_TLS = CFG['email_use_tls']
|
||||||
#EMAIL_HOST_PASSWORD = 'lnD3mbZ1NoI8RK1StOdO'
|
#DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
|
||||||
EMAIL_HOST_PASSWORD = CFG['email_host_password']
|
|
||||||
|
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']
|
EMAIL_USE_TLS = CFG['email_use_tls']
|
||||||
#EMAIL_USE_TLS = False
|
DEFAULT_FROM_EMAIL = 'info@rowsandall.com'
|
||||||
DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
|
|
||||||
|
|
||||||
|
|
||||||
# weather stuff
|
# weather stuff
|
||||||
|
|||||||
@@ -83,8 +83,16 @@ SITE_URL = "http://localhost:8000"
|
|||||||
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
|
#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
|
||||||
#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||||
|
|
||||||
#EMAIL_HOST = 'localhost'
|
EMAIL_BACKEND = 'django_ses.SESBackend'
|
||||||
#EMAIL_PORT = '1025'
|
|
||||||
#EMAIL_HOST_USER = ''
|
AWS_SES_REGION_NAME = 'eu-west-1'
|
||||||
#EMAIL_HOST_PASSWORD = ''
|
AWS_SES_REGION_ENDPOINT = 'email.eu-west-1.amazonaws.com'
|
||||||
#EMAIL_USE_TLS = True
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
celery -A rowers purge
|
||||||
celery -A rowers.tasks worker --loglevel=info --pool=solo
|
celery -A rowers.tasks worker --loglevel=info --pool=solo
|
||||||
@@ -247,6 +247,11 @@
|
|||||||
{{ user.rower.protrialexpires|date_dif|ddays }} days left in Pro trial
|
{{ user.rower.protrialexpires|date_dif|ddays }} days left in Pro trial
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if user.rower.emailbounced %}
|
||||||
|
<p class="message">
|
||||||
|
Your email bounced. Please update your email address in the <a href="/rowers/me/edit/">user settings</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
||||||
|
|||||||
Reference in New Issue
Block a user