From 5d3e58c1fc95392ae302dc22c36e9c8d0422e99e Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 8 Mar 2018 12:52:38 +0100 Subject: [PATCH 1/4] revised privacy policy --- rowers/interactiveplots.py | 5 +- rowers/templates/gdpr_optin.html | 171 +-------------------- rowers/templates/legal.html | 175 +--------------------- rowers/templates/privacypolicy.html | 223 ++++++++++++++++++++++++++++ 4 files changed, 229 insertions(+), 345 deletions(-) create mode 100644 rowers/templates/privacypolicy.html diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index c80bb63c..1ecdbb61 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -3269,7 +3269,10 @@ def thumbnail_flex_chart(rowdata,id=0,promember=0, rowdata['xname'] = axlabels[xparam] - rowdata['yname1'] = axlabels[yparam1] + try: + rowdata['yname1'] = axlabels[yparam1] + except KeyError: + rowdata['yname1'] = axlabels[xparam] if yparam2 != 'None': rowdata['yname2'] = axlabels[yparam2] else: diff --git a/rowers/templates/gdpr_optin.html b/rowers/templates/gdpr_optin.html index 939a307f..f340bd93 100644 --- a/rowers/templates/gdpr_optin.html +++ b/rowers/templates/gdpr_optin.html @@ -20,176 +20,7 @@


-

Personal information collection

-

- rowsandall.com may collect and use the following kinds of information: -

- Explicitly, the following information is collected: - -

- -

- The site is only accessible to user of 16 years and older. -

- -

Data Deletion

- -

All the data mentioned in the previous section are stored in files - and in a database, hosted on our hosting provider's servers. Our - hosting provider is creating backups of those data. The database backups - are retained for 7 days. File backups are retained for 30 days. However, - the file names or content do not contain any links to the users. The - link to the file is stored under the user data in the database, so once - a database entry is removed, there is no way to link a file with data - to a particular user. -

-

- When a user requests deletion of the data, his account and all data linked to his account - are removed from the database and the files are deleted. This includes all data mentioned in the - previous section. In backups, database entries will be removed after 7 days and files after - 30 days. -

- -

Data deletion can be initiated by the user through the button on the user settings page.

- -

Data Security

- -

The site uses SSL to encrypt data transferred between the server and the client (web browers, - mobile apps, third party sites). Any forms are secured from Cross Site Request Forgery (CSRF) using Django's - CSRF middleware.

- -

- We have a double defense against reading or editing of personal data. First, we ensure that all "protected" views - are only visible to logged-in users. Only logged-in users have buttons leading to the private parts of the site. - As a second step, protecting against guessing of URL, before serving data from the database, we check explicitly that the data - is owned by the user in question, redirecting unauthorized requests to a "Permission Denied" page. Private data is collected - through POST requests to prevent them from being visible in URL data. -

- -

rowsandall.com will take reasonable technical and organisational precautions to prevent the loss, - misuse or alteration of your personal information.

- -

In case of loss, misuse or alteration of your personal information, we will inform you without undue delay and take measures - to prevent further misuse. In particular, we will deactivate your account, which will not delete the data but make them - inaccessible even for people who obtained the password (including yourself). We will await your instructions. If no - instructions are received within 7 days of contacting you, your account and all your data will be removed. -

- - -

Data Sharing and access to data

- -

- Only the data owner can the site administrator can edit and/or delete the data. Per our data policy, the site administrator will not alter - or delete any data owned by users, unless requested so. As data are not stored on servers that are physically owner by us, or by - our hosting provider, but we use rented server space, we are technically sharing the information to agents or sub-contractors. -

- -

- Where rowsandall.com discloses your personal information to its agents or sub-contractors for these purposes, - the agent or sub-contractor in question will be obligated to use that personal information in accordance with the terms of this privacy statement. - Our hosting provider is based in the European Union and is bound by the same GDPR regulation as we are. -

- -

In addition to the disclosures reasonably necessary for the purposes identified elsewhere above, rowsandall.com - may disclose your personal information to the extent that it is required to do so by law, in connection with - any legal proceedings or prospective legal proceedings, and in order to establish, exercise or defend its legal rights.

- - -

- Workout data and charts based on workout data can be shared to anyone by sharing the URL. Workouts have an option to be set to - "private", in which case the data are not visible to anyone except the owner. The site is not searchable for data other than - your own data, so there is no way for other people to track your workouts, unless you share them. -

- -

- Cross-border data transfers. Information that rowsandall.com collects may be stored and processed in and transferred - between any of the countries in which rowsandall.com operates to enable the use of the information in accordance with this privacy policy. - In addition, personal information that you submit for publication on the website will be published on the internet and - may be available around the world. - You agree to such cross-border transfers of personal information. -

- -

- By accepting an "invitation" to become a member of a team, or by requesting to become part of a team, you agree to automatically - share all your workout data (including workouts done prior to becoming a member of the team) to the team manager (coach) and, - depending to the team policy, to other members of the team. When you leave - a team, all your workout data will immediately become invisible to those who had access to it during your team membership, including - workouts that cover the period of time when you were member of the team. As a member of a team, you grant the team manager - permission to edit workout data - on your behalf, including the creation of charts and cross workout analysis. You also grant the team manager permission to - edit your heart rate and power settings, as well as functional threshold information and the account information accessible on your - settings page under the header "Account Information". The team manager is not able to access or change your passwords, team memberships, - favorite charts, export settings, workflow layout, or secret tokens. Also, the team manager is not able to download all your data, - not can he deactivate or delete your account. -

- -

- This site offers the possiblity to synchronize your data with other fitness sites. By clicking on the share or connect button (link, or - equivalent) you agree to share information between rowsandall.com and the other website. Rowsandall.com is not responsible for the privacy - policies or practices of any third party. -

- -

Data portability

- -

Through the "download your data" link on the user settings page, each user can download all workout data. Stroke data can be downloaded - through links in the downloaded workout data file.

+ {% include "privacypolicy.html" %}
diff --git a/rowers/templates/legal.html b/rowers/templates/legal.html index 6a4b3d35..995660c3 100644 --- a/rowers/templates/legal.html +++ b/rowers/templates/legal.html @@ -156,183 +156,10 @@

Privacy Policy

-

Credit

-

This document was created using a Contractology template available at -http://www.freenetlaw.com.. It was modified to reflect the GDPR requirements.

+{% include "privacypolicy.html" %} -

Personal information collection

-

- rowsandall.com may collect and use the following kinds of information: -

- Explicitly, the following information is collected: - -

- -

- The site is only accessible to user of 16 years and older. -

- -

Data Deletion

- -

All the data mentioned in the previous section are stored in files - and in a database, hosted on our hosting provider's servers. Our - hosting provider is creating backups of those data. The database backups - are retained for 7 days. File backups are retained for 30 days. However, - the file names or content do not contain any links to the users. The - link to the file is stored under the user data in the database, so once - a database entry is removed, there is no way to link a file with data - to a particular user. -

-

- When a user requests deletion of the data, his account and all data linked to his account - are removed from the database and the files are deleted. This includes all data mentioned in the - previous section. In backups, database entries will be removed after 7 days and files after - 30 days. -

- -

Data deletion can be initiated by the user through the button on the user settings page.

- -

Data Security

- -

The site uses SSL to encrypt data transferred between the server and the client (web browers, - mobile apps, third party sites). Any forms are secured from Cross Site Request Forgery (CSRF) using Django's - CSRF middleware.

- -

- We have a double defense against reading or editing of personal data. First, we ensure that all "protected" views - are only visible to logged-in users. Only logged-in users have buttons leading to the private parts of the site. - As a second step, protecting against guessing of URL, before serving data from the database, we check explicitly that the data - is owned by the user in question, redirecting unauthorized requests to a "Permission Denied" page. Private data is collected - through POST requests to prevent them from being visible in URL data. -

- -

rowsandall.com will take reasonable technical and organisational precautions to prevent the loss, - misuse or alteration of your personal information.

- -

In case of loss, misuse or alteration of your personal information, we will inform you without undue delay and take measures - to prevent further misuse. In particular, we will deactivate your account, which will not delete the data but make them - inaccessible even for people who obtained the password (including yourself). We will await your instructions. If no - instructions are received within 7 days of contacting you, your account and all your data will be removed. -

- - -

Data Sharing and access to data

- -

- Only the data owner can the site administrator can edit and/or delete the data. Per our data policy, the site administrator will not alter - or delete any data owned by users, unless requested so. As data are not stored on servers that are physically owner by us, or by - our hosting provider, but we use rented server space, we are technically sharing the information to agents or sub-contractors. -

- -

- Where rowsandall.com discloses your personal information to its agents or sub-contractors for these purposes, - the agent or sub-contractor in question will be obligated to use that personal information in accordance with the terms of this privacy statement. - Our hosting provider is based in the European Union and is bound by the same GDPR regulation as we are. -

- -

In addition to the disclosures reasonably necessary for the purposes identified elsewhere above, rowsandall.com - may disclose your personal information to the extent that it is required to do so by law, in connection with - any legal proceedings or prospective legal proceedings, and in order to establish, exercise or defend its legal rights.

- - -

- Workout data and charts based on workout data can be shared to anyone by sharing the URL. Workouts have an option to be set to - "private", in which case the data are not visible to anyone except the owner. The site is not searchable for data other than - your own data, so there is no way for other people to track your workouts, unless you share them. -

- -

- Cross-border data transfers. Information that rowsandall.com collects may be stored and processed in and transferred - between any of the countries in which rowsandall.com operates to enable the use of the information in accordance with this privacy policy. - In addition, personal information that you submit for publication on the website will be published on the internet and - may be available around the world. - You agree to such cross-border transfers of personal information. -

- -

- By accepting an "invitation" to become a member of a team, or by requesting to become part of a team, you agree to automatically - share all your workout data (including workouts done prior to becoming a member of the team) to the team manager (coach) and, - depending to the team policy, to other members of the team. When you leave - a team, all your workout data will immediately become invisible to those who had access to it during your team membership, including - workouts that cover the period of time when you were member of the team. As a member of a team, you grant the team manager - permission to edit workout data - on your behalf, including the creation of charts and cross workout analysis. You also grant the team manager permission to - edit your heart rate and power settings, as well as functional threshold information and the account information accessible on your - settings page under the header "Account Information". The team manager is not able to access or change your passwords, team memberships, - favorite charts, export settings, workflow layout, or secret tokens. Also, the team manager is not able to download all your data, - not can he deactivate or delete your account. -

- -

- This site offers the possiblity to synchronize your data with other fitness sites. By clicking on the share or connect button (link, or - equivalent) you agree to share information between rowsandall.com and the other website. Rowsandall.com is not responsible for the privacy - policies or practices of any third party. -

- -

Data portability

- -

Through the "download your data" link on the user settings page, each user can download all workout data. Stroke data can be downloaded - through links in the downloaded workout data file.

-
diff --git a/rowers/templates/privacypolicy.html b/rowers/templates/privacypolicy.html new file mode 100644 index 00000000..ee7ec1a2 --- /dev/null +++ b/rowers/templates/privacypolicy.html @@ -0,0 +1,223 @@ + +

Personal information collection

+

+ At rowsandall.com we take your privacy very seriously. IN order to provide access + to the service we must collect and store some personal information about you. +

+ +

+ Childen under 16 years of age are not permitted to access the services provided + by rowsandall.com. By agreeing to this privacy policy you are also agreeing + that you are 16 years of age or older. +

+ +

+ What is collected? Rowsandall.com may collect and use the following kinds of information: +

+

+ +

+ Basic profile information is collected from you when you create your account including your full + name and email address. As you use the site, information about the users, workouts, + charts and other resources you interact with will also be stored and linked to + your profile information. +

+ +

+ Explicitly, the following information is collected: +

+

+ + +

Who can I contact?

+ +

+ The data protection officer for rowsandall.com is Sander Roosendaal and he may be contacted + at support@rowsandall.com. +

+ +

Data Deletion

+ +

If you have previously consented to allow rowsandall.com to store and process your personal + data in accordance with this privacy policy, and you wish to withdraw your conent, + you can do one of the following: +

+

+ +

All the data mentioned in the previous section are stored in files + and in a database, hosted on our hosting provider's servers. Our + hosting provider is creating backups of those data. The database backups + are retained for 7 days. File backups are retained for 30 days. However, + the file names or content do not contain any links to the users. The + link to the file is stored under the user data in the database, so once + a database entry is removed, there is no way to link a file with data + to a particular user. +

+

+ When a user requests deletion of the data, his account and all data linked to his account + are removed from the database and the files are deleted. This includes all data mentioned in the + previous section. In backups, database entries will be removed after 7 days and files after + 30 days. +

+ +

Data deletion can be initiated by the user through the button on the user settings page.

+ +

Data Security

+ +

The site uses SSL to encrypt data transferred between the server and the client (web browers, + mobile apps, third party sites). Any forms are secured from Cross Site Request Forgery (CSRF) using Django's + CSRF middleware.

+ +

+ We have a double defense against reading or editing of personal data. First, we ensure that all "protected" views + are only visible to logged-in users. Only logged-in users have buttons leading to the private parts of the site. + As a second step, protecting against guessing of URL, before serving data from the database, we check explicitly that the data + is owned by the user in question, redirecting unauthorized requests to a "Permission Denied" page. Private data is collected + through POST requests to prevent them from being visible in URL data. +

+ +

rowsandall.com will take reasonable technical and organisational precautions to prevent the loss, + misuse or alteration of your personal information.

+ +

In case of loss, misuse or alteration of your personal information, we will inform you without undue delay and take measures + to prevent further misuse. In particular, we will deactivate your account, which will not delete the data but make them + inaccessible even for people who obtained the password (including yourself). We will await your instructions. If no + instructions are received within 7 days of contacting you, your account and all your data will be removed. +

+ + +

Who is my data shared with?

+ +

+ Only the data owner and the site administrator can edit and/or delete the data. Per our data policy, the site administrator will not alter + or delete any data owned by users, unless requested so. As data are not stored on servers that are physically owner by us, or by + our hosting provider, but we use rented server space, we are technically sharing the information to agents or sub-contractors. +

+ +

+ Where rowsandall.com discloses your personal information to its agents or sub-contractors for these purposes, + the agent or sub-contractor in question will be obligated to use that personal information in accordance with the terms of this privacy statement. + Our hosting provider is based in the European Union and is bound by the same GDPR regulation as we are. +

+ +

In addition to the disclosures reasonably necessary for the purposes identified elsewhere above, rowsandall.com + may disclose your personal information to the extent that it is required to do so by law, in connection with + any legal proceedings or prospective legal proceedings, and in order to establish, exercise or defend its legal rights.

+ + +

+ Workout data and charts based on workout data can be shared to anyone by sharing the URL. Workouts have an option to be set to + "private", in which case the data are not visible to anyone except the owner. The site is not searchable for data other than + your own data, so there is no way for other people to track your workouts, unless you share them. +

+ +

+ Cross-border data transfers. Information that rowsandall.com collects may be stored and processed in and transferred + between any of the countries in which rowsandall.com operates to enable the use of the information in accordance with this privacy policy. + In addition, personal information that you submit for publication on the website will be published on the internet and + may be available around the world. + You agree to such cross-border transfers of personal information. +

+ +

+ By accepting an "invitation" to become a member of a team, or by requesting to become part of a team, you agree to automatically + share all your workout data (including workouts done prior to becoming a member of the team) to the team manager (coach) and, + depending to the team policy, to other members of the team. When you leave + a team, all your workout data will immediately become invisible to those who had access to it during your team membership, including + workouts that cover the period of time when you were member of the team. As a member of a team, you grant the team manager + permission to edit workout data + on your behalf, including the creation of charts and cross workout analysis. You also grant the team manager permission to + edit your heart rate and power settings, as well as functional threshold information and the account information accessible on your + settings page under the header "Account Information". The team manager is not able to access or change your passwords, team memberships, + favorite charts, export settings, workflow layout, or secret tokens. Also, the team manager is not able to download all your data, + not can he deactivate or delete your account. +

+ +

+ This site offers the possiblity to synchronize your data with other fitness sites. By clicking on the share or connect button (link, or + equivalent) you agree to share information between rowsandall.com and the other website. Rowsandall.com is not responsible for the privacy + policies or practices of any third party. Sharing the data to third party sites is at your own risk and you should ensure that the third party + has suitable GDPR compliant measures in place. +

+ +

Inactive Users - accounts are deleted after 18 months

+ +

+ If a user is not active on the site for 12 months, we will make deactivate the account. After 18 months, the account is deleted. +

+ +

Duration of consent

+ +

+ The data will be retained for the duration of the owner's membership, or 18 months after the user's last activity on the site. +

+ +

Data portability

+ +

Through the "download your data" link on the user settings page, each user can download all workout data. Stroke data can be downloaded + through links in the downloaded workout data file.

+ +

Your personal data are shown on the user settings page. Send an email to support@rowsandall.com if you wish to obtain a full record of all the personal data + relating to you that has been collected in accordance with this privacy policy. +

+ From 150171200bb940dc1358edc4f1b6673946e49cc1 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 8 Mar 2018 13:16:46 +0100 Subject: [PATCH 2/4] bugfix split workout --- rowers/dataprep.py | 15 ++++++++++++--- rowers/tasks.py | 2 ++ rowers/templates/teams.html | 8 +++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 85bf4b22..2c5e2aab 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -1402,9 +1402,18 @@ def split_workout(r, parent, splitsecond, splitmode): messages.append(message) ids.append(id) if 'keep second' in splitmode: - data2['cumdist'] = data2['cumdist'] - data2.iloc[0, 'cumdist'] - data2['distance'] = data2['distance'] - data2.iloc[0, 'distance'] - data2['time'] = data2['time'] - data2.iloc[0, 'time'] + data2['cumdist'] = data2['cumdist'] - data2.iloc[ + 0, + data2.columns.get_loc('cumdist') + ] + data2['distance'] = data2['distance'] - data2.iloc[ + 0, + data2.columns.get_loc('distance') + ] + data2['time'] = data2['time'] - data2.iloc[ + 0, + data2.columns.get_loc('time') + ] if 'secondprivate' in splitmode: setprivate = True else: diff --git a/rowers/tasks.py b/rowers/tasks.py index 29619a05..10d72f3a 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -942,6 +942,8 @@ def handle_sendemail_invite(email, name, code, teamname, manager, message += " team's workouts on rowsandall.com and your workouts will " message += " be visible to " message += "the members of the team.\n\n" + message += "By accepting the invite, you are agreeing with the sharing " + message += "of personal data according to our privacy policy.\n\n" message += 'If you already have an account on rowsandall.com, you can login to the site and you will find the invitation here on the Teams page:\n' message += ' https://rowsandall.com/rowers/me/teams \n\n' message += 'You can also click the direct link: \n' diff --git a/rowers/templates/teams.html b/rowers/templates/teams.html index 959a4748..9971a001 100644 --- a/rowers/templates/teams.html +++ b/rowers/templates/teams.html @@ -106,7 +106,13 @@
{% if invites or requests or myrequests or myinvites %} -

Invitations and Requests

+

Invitations and Requests

+

This section lists open invites to join a team. By accepting + a team invite, you are agreeing with the sharing + of personal data between team members and coaches according to + our privacy policy. +

+ From 656104a921310e8f65967f0d2eedf210f21b1cf0 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 9 Mar 2018 09:01:00 +0100 Subject: [PATCH 3/4] more detailed privacy policy around teams and bug fix --- rowers/templates/privacypolicy.html | 43 ++++++++++++++++++++++++++++- rowers/templates/team.html | 7 +++++ rowers/templates/teams.html | 6 +++- rowers/views.py | 9 ++++-- 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/rowers/templates/privacypolicy.html b/rowers/templates/privacypolicy.html index ee7ec1a2..65906b84 100644 --- a/rowers/templates/privacypolicy.html +++ b/rowers/templates/privacypolicy.html @@ -178,6 +178,20 @@ may be available around the world. You agree to such cross-border transfers of personal information.

+ +

Team Functionality

+ +

+ On rowsandall.com, users with the paid "Coach" plan can establish teams and invite other users to become part of the team. The purpose + of a team is to share workout and training plan data between the coach and the team members. In terms of sharing behavior, there are two types of teams: +

    +
  • "All Members" - This is the default team type. All members can see workouts of all other members, except those workouts that the members have + marked as "private". +
  • "Coach Only" - With this setting, each individual team member is sharing his workout data only with the team manager. Other members cannot see + his workouts. +
+ The sharing behavior is chosen by the team member when he establishes the team and can be changed during the existence of the team. +

By accepting an "invitation" to become a member of a team, or by requesting to become part of a team, you agree to automatically @@ -192,7 +206,34 @@ favorite charts, export settings, workflow layout, or secret tokens. Also, the team manager is not able to download all your data, not can he deactivate or delete your account.

- + +

+ Each team member is bound by this privacy policy and the GDPR regulation of the European Union regarding the personal data of other team + members that he has access to. By accepting an invitation to a team, the new member agrees to limit the use of these data strictly to the + allowed use according to this privacy policy and the GDPR. +

+ +

+ Team managers can access requests of users to be added to one of their teams. By accepting the invitation, the manager accepts the responsibilities + and duties associated with access to personal data of the new team member. He is bound by this privacy policy and the GDPR regulation + of the European Union regarding the personal data that he has access to. +

+ +

+ In case that a team manager wants to change the sharing behavior of one of his teams from "Coach Only" to "All Members", he has to inform all + impacted team members in due time. He shall give team members a minimum of three days to decide whether they agree with the new sharing policy, and + collect the consent of the team members with the new sharing policy. The team manager must remove team members who did not give their active consent + to the new policy from his team. If a team member has not responded within 7 days of being notified, the team manager will understand this as "no consent" + and remove the team member. +

+ +

+ When notified of a change in team sharing behavior by the team manager, the team member has to decide whether he agrees. In case of disagreement, he shall + revoke his team membership within less than 7 days of being notified. +

+ +

Third Party Sharing

+

This site offers the possiblity to synchronize your data with other fitness sites. By clicking on the share or connect button (link, or equivalent) you agree to share information between rowsandall.com and the other website. Rowsandall.com is not responsible for the privacy diff --git a/rowers/templates/team.html b/rowers/templates/team.html index cc53418c..2d992033 100644 --- a/rowers/templates/team.html +++ b/rowers/templates/team.html @@ -32,6 +32,13 @@ {% elif hasrequested %}

You have requested access to this team

{% else %} +

You can request access to this team. By requesting access, you + agree to the Privacy Policy regarding + team functionality. You agree to share your workout data (except + workouts marked as "private") to all team members and the team manager. + You also grant the team manager access to your heart rate and power + zone settings, as well as your functional threshold information. You + are granting the team manager permission to edit your workouts.

Join A request will be sent to the team manager diff --git a/rowers/templates/teams.html b/rowers/templates/teams.html index 9971a001..af2bc40e 100644 --- a/rowers/templates/teams.html +++ b/rowers/templates/teams.html @@ -111,7 +111,11 @@ a team invite, you are agreeing with the sharing of personal data between team members and coaches according to our privacy policy. -

+

+ +

As a team manager, by accepting a team invite, you are agreeing + with privacy policy regarding teams and + personal data owned by team members.

diff --git a/rowers/views.py b/rowers/views.py index dfd3a102..0d94704c 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -12190,8 +12190,13 @@ def plannedsession_teamcreate_view(request,timeperiod='thisweek', teams = Team.objects.filter(manager=request.user) - teamchoices = [(team.id, team.name) for team in teams] - teaminitial = [str(teams[0].id)] + if len(teams)>0: + teamchoices = [(team.id, team.name) for team in teams] + teaminitial = [str(teams[0].id)] + else: + messages.info(request,"You have no teams established yet. We are redirecting you to the Team Management page.") + url = reverse(rower_teams_view) + return HttpResponseRedirect(url) startdate,enddate = get_dates_timeperiod(timeperiod) From ac82aa8dddc22aae298eefd3dae7a3d1536b8af4 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 9 Mar 2018 12:58:41 +0100 Subject: [PATCH 4/4] link to dummy workout xls template --- rowers/templates/document_form.html | 9 +++++++++ static/dummy_workout_template.xls | Bin 0 -> 35840 bytes 2 files changed, 9 insertions(+) create mode 100644 static/dummy_workout_template.xls diff --git a/rowers/templates/document_form.html b/rowers/templates/document_form.html index 41dee55e..bc3b8a98 100644 --- a/rowers/templates/document_form.html +++ b/rowers/templates/document_form.html @@ -40,6 +40,8 @@
+ + diff --git a/static/dummy_workout_template.xls b/static/dummy_workout_template.xls new file mode 100644 index 0000000000000000000000000000000000000000..c3d13b69efd0de7fa8140b2bb108ae405c2da814 GIT binary patch literal 35840 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 literal 0 HcmV?d00001