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,
|
||||
doclean=False):
|
||||
# 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():
|
||||
if np.isnan([m[key]]):
|
||||
m[key] = -1
|
||||
if m[key] == np.inf:
|
||||
m[key] = -1
|
||||
if -m[key] == np.inf:
|
||||
m[key] = -1
|
||||
|
||||
if debug:
|
||||
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,
|
||||
verbose_name='Receive email notifications')
|
||||
emailbounced = models.BooleanField(default=False,
|
||||
verbose_name='Email Address Bounced')
|
||||
|
||||
rowerplan = models.CharField(default='basic',max_length=30,
|
||||
choices=plans)
|
||||
|
||||
@@ -213,6 +213,7 @@ def is_session_complete_ws(ws,ps):
|
||||
if ratio>cratiomin and ratio<cratiomax:
|
||||
return ratio,'completed',completiondate
|
||||
else:
|
||||
completiondate = ws.reverse()[0].date
|
||||
return ratio,'partial',completiondate
|
||||
elif ps.sessiontype == 'test':
|
||||
if ratio==1.0:
|
||||
|
||||
@@ -52,6 +52,7 @@ import arrow
|
||||
# testing task
|
||||
|
||||
|
||||
|
||||
@app.task
|
||||
def add(x, y):
|
||||
return x + y
|
||||
@@ -548,10 +549,12 @@ def handle_sendemailsummary(first_name, last_name, email, csvfile, **kwargs):
|
||||
|
||||
return 1
|
||||
|
||||
#from rowers.emails import sendemail
|
||||
|
||||
@app.task
|
||||
def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
||||
|
||||
|
||||
# send email with attachment
|
||||
fullemail = first_name + " " + last_name + " " + "<" + email + ">"
|
||||
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 += "Best Regards, the Rowsandall Team"
|
||||
|
||||
|
||||
|
||||
email = EmailMessage(subject, message,
|
||||
'Rowsandall <info@rowsandall.com>',
|
||||
[fullemail])
|
||||
@@ -573,6 +578,7 @@ def handle_sendemailcsv(first_name, last_name, email, csvfile,**kwargs):
|
||||
email.attach_file(csvfile2)
|
||||
os.remove(csvfile2)
|
||||
|
||||
|
||||
res = email.send()
|
||||
|
||||
return 1
|
||||
|
||||
@@ -120,7 +120,11 @@
|
||||
<td> {{ ps.sessionvalue }} </td>
|
||||
<td> {{ actualvalue|lookup:ps.id }}</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>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@@ -92,7 +92,28 @@
|
||||
<p>
|
||||
The data protection officer for rowsandall.com is Sander Roosendaal and he may be contacted
|
||||
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>
|
||||
|
||||
|
||||
+16
-1
@@ -8722,7 +8722,14 @@ def workout_edit_view(request,id=0,message="",successmessage=""):
|
||||
startdatetime = (str(date) + ' ' + str(starttime))
|
||||
startdatetime = datetime.datetime.strptime(startdatetime,
|
||||
"%Y-%m-%d %H:%M:%S")
|
||||
startdatetime = timezone.make_aware(startdatetime)
|
||||
|
||||
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 = startdatetime.astimezone(pytz.timezone(thetimezone))
|
||||
|
||||
|
||||
@@ -11224,11 +11231,16 @@ def rower_edit_view(request,rowerid=0,message=""):
|
||||
getemailnotifications = cd['getemailnotifications']
|
||||
defaulttimezone=cd['defaulttimezone']
|
||||
u = r.user
|
||||
if u.email != email and len(email):
|
||||
resetbounce = True
|
||||
else:
|
||||
resetbounce = False
|
||||
if len(first_name):
|
||||
u.first_name = first_name
|
||||
u.last_name = last_name
|
||||
if len(email): ## and check_email_freeforuse(u,email):
|
||||
u.email = email
|
||||
resetbounce = True
|
||||
|
||||
|
||||
u.save()
|
||||
@@ -11239,6 +11251,9 @@ def rower_edit_view(request,rowerid=0,message=""):
|
||||
r.showfavoritechartnotes = showfavoritechartnotes
|
||||
r.sex = sex
|
||||
r.birthdate = birthdate
|
||||
if resetbounce and r.emailbounced:
|
||||
print "aap"
|
||||
r.emailbounced = False
|
||||
r.save()
|
||||
form = RowerForm(instance=r)
|
||||
powerform = RowerPowerForm(instance=r)
|
||||
|
||||
+18
-10
@@ -315,17 +315,25 @@ CACHE_MIDDLEWARE_SECONDS = 900
|
||||
|
||||
# email stuff
|
||||
|
||||
EMAIL_BACKEND = CFG['email_backend']
|
||||
EMAIL_HOST = CFG['email_host']
|
||||
#EMAIL_HOST = 'smtp.rosti.cz'
|
||||
#EMAIL_PORT = '25'
|
||||
EMAIL_PORT = CFG['email_port']
|
||||
EMAIL_HOST_USER = CFG['email_host_user']
|
||||
#EMAIL_HOST_PASSWORD = 'lnD3mbZ1NoI8RK1StOdO'
|
||||
EMAIL_HOST_PASSWORD = CFG['email_host_password']
|
||||
#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'
|
||||
|
||||
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 = False
|
||||
DEFAULT_FROM_EMAIL = 'admin@rowsandall.com'
|
||||
DEFAULT_FROM_EMAIL = 'info@rowsandall.com'
|
||||
|
||||
|
||||
# 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.smtp.EmailBackend'
|
||||
|
||||
#EMAIL_HOST = 'localhost'
|
||||
#EMAIL_PORT = '1025'
|
||||
#EMAIL_HOST_USER = ''
|
||||
#EMAIL_HOST_PASSWORD = ''
|
||||
#EMAIL_USE_TLS = True
|
||||
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'
|
||||
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
celery -A rowers purge
|
||||
celery -A rowers.tasks worker --loglevel=info --pool=solo
|
||||
@@ -247,6 +247,11 @@
|
||||
{{ user.rower.protrialexpires|date_dif|ddays }} days left in Pro trial
|
||||
</p>
|
||||
{% 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 %}
|
||||
{% for message in messages %}
|
||||
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
||||
|
||||
Reference in New Issue
Block a user