Skip to content

Commit

Permalink
Merge 25ec546 into 040ee90
Browse files Browse the repository at this point in the history
  • Loading branch information
misocho committed Jun 13, 2019
2 parents 040ee90 + 25ec546 commit b5fca59
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 1 deletion.
53 changes: 53 additions & 0 deletions wger/core/static/js/wger-core.js
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,28 @@ $(document).ready(function () {
window.location.href = targetUrl;
});

// Handle the workout JSON export
$('#export-json-button').click(function (e) {
var targetUrl;
var token;
var uid;
var workoutId;
var downloadInfo;
e.preventDefault();

downloadInfo = $('#pdf-download-info');
workoutId = downloadInfo.data('workoutId');
token = downloadInfo.data('token');
uid = downloadInfo.data('uid');

// Put together and redirect
targetUrl = '/' + getCurrentLanguage() +
'/workout/' + workoutId + '/json' +
'/' + uid +
'/' + token;
window.location.href = targetUrl;
});

// Handle the workout PDF download options for schedules
$('#download-pdf-button-schedule').click(function (e) {
var targetUrl;
Expand Down Expand Up @@ -697,4 +719,35 @@ $(document).ready(function () {
'/' + token;
window.location.href = targetUrl;
});

// Get JSON path
$('#get_the_file').change(function () {
var fileToRead = $('#get_the_file').files[0];
var fileread = new FileReader();
var url = '/en/workout/json/import';
var downloadInfo = $('#pdf-download-info');
var scheduleId = downloadInfo.attr('data-workout-id');

fileread.onload = function (e) {
var content = {};
content.data = e.target.result;
content.workout_id = scheduleId;
console.log(content);
fetch(url, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken')
},
method: 'POST',
body: JSON.stringify(content)
}).then(function (res) {
console.log(res.json());
location.reload();
}).catch(function (error) {
console.log(error);
});
};
fileread.readAsText(fileToRead);
});
});
16 changes: 16 additions & 0 deletions wger/manager/templates/mobile/workout/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,22 @@ <h4 class="modal-title">{% trans "Download as PDF" %}</h4>
</a>
</li>
{% if is_owner %}
<li>
<a id="export-json-button">
<span class="{% fa_class 'download' %}"></span>
{% trans "Export as JSON" %}
</a>
</li>
{% endif %}
{% if is_owner %}
<li>
<a href="">
<span class="{% fa_class 'upload' %}"></span>
{% trans "Import JSON" %}
</a>
</li>
{% endif %}
{% if is_owner %}
<li role="separator" class="divider"></li>
<li>
<a href="{% url 'manager:workout:delete' workout.id %}" class="wger-modal-dialog">
Expand Down
24 changes: 24 additions & 0 deletions wger/manager/templates/workout/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ <h4 class="modal-title">{% trans "Download as PDF" %}</h4>
{# Options #}
{# #}
{% block options %}

<div class="btn-group">
<button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="{% fa_class 'cog' %}"></span>
Expand Down Expand Up @@ -252,6 +253,29 @@ <h4 class="modal-title">{% trans "Download as PDF" %}</h4>
</a>
</li>
{% if is_owner %}
<li>
<a id="export-json-button">
<span class="{% fa_class 'download' %}"></span>
{% trans "Export as JSON" %}
</a>
</li>
{% endif %}
{% if is_owner %}
<li>
<a>
<input id="get_the_file" style="display: none" type="file" class="{% fa_class 'upload' %}">

<span class="{% fa_class 'upload' %}"></span>

<label for="get_the_file">
{% trans "Import JSON" %}
</label>
</a>


</li>
{% endif %}
{% if is_owner %}
<li role="separator" class="divider"></li>
<li>
<a href="{% url 'manager:workout:delete' workout.id %}" class="wger-modal-dialog">
Expand Down
59 changes: 59 additions & 0 deletions wger/manager/tests/test_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# This file is part of wger Workout Manager.
#
# wger Workout Manager is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wger Workout Manager is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
import json

from django.contrib.auth.models import User

from wger.core.tests.base_testcase import WorkoutManagerTestCase
from wger.utils.helpers import make_token


class WorkoutExportImportTestCase(WorkoutManagerTestCase):
'''
Tests exporting importing json
'''

def export_json(self):
'''
Function for exporting a workout as JSON
'''
self.user_login('test')
user = User.objects.get(username='test')
uid, token = make_token(user)
url = '/en/workout/{id}/json/{uuid}/{token}'.format(id=3, uuid=uid, token=token)
response = self.client.get(url)

return response

def test_import_json(self):
'''
Function for importing a workout as JSON
'''
self.user_login('test')
user = User.objects.get(username='test')
uid, token = make_token(user)

import_data = self.export_json().json()
url = '/en/workout/json/import'
content = {}
content['data'] = json.dumps(import_data, separators=(',', ':'))
content['workout_id'] = 3
response = self.client.post(url, data=content)
self.assertEqual(response.status_code, 200)

def test_export_json(self):
response = self.export_json()
self.assertEqual(response.status_code, 200)
self.assertEqual(response['Content-Type'], 'application/json')
self.assertEqual(response['Content-Disposition'], 'attachment; filename=Workout-3.json')
8 changes: 7 additions & 1 deletion wger/manager/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
log,
set,
day,
workout_session
workout_session,
json
)

app_name = "manager"
Expand Down Expand Up @@ -113,6 +114,11 @@
path('<day_pk>/timer',
workout.timer,
name='timer'),
path('<id>/json/<uidb64>/<token>',
json.export_workout,
name='export-workout'),
path('json/import',
json.Importworkout.as_view(), name='import-workout')
]


Expand Down
127 changes: 127 additions & 0 deletions wger/manager/views/json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# -*- coding: utf-8 -*-

# This file is part of wger Workout Manager.
#
# wger Workout Manager is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# wger Workout Manager is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License

import json

from rest_framework.views import APIView
from rest_framework.permissions import AllowAny

from django.http import HttpResponse
from django.http import HttpResponseForbidden
from django.shortcuts import get_object_or_404

from wger.manager.models import Workout, Day, Set, Exercise, Setting
from wger.core.models import DaysOfWeek
from wger.utils.helpers import check_token


def export_workout(request, id, uidb64=None, token=None):

# Get the workout
if uidb64 is not None and token is not None:
if check_token(uidb64, token):
workout = get_object_or_404(Workout, pk=id)
else:
return HttpResponseForbidden()
else:
if request.user.is_anonymous():
return HttpResponseForbidden()
workout = get_object_or_404(Workout, pk=id, user=request.user)

if len(workout.canonical_representation['day_list']) > 0:

exercise_set = workout.canonical_representation['day_list'][0]['set_list']
workout_details = {
'description': workout.canonical_representation['day_list'][0]['obj'].description,
'workout_days': workout.canonical_representation['day_list'][0]['days_of_week']['text']
}

set_list = []
for set in exercise_set:
set_dict = {}
exercise_list = []
holder = {}
set_dict['set_id'] = set['obj'].id
set_dict['set_order'] = set['obj'].order
set_dict['sets'] = set['obj'].sets
set_dict['excerciseday_id'] = set['obj'].exerciseday_id
for item in set['exercise_list']:
holder['name_of_exercise'] = item['obj'].name
holder['description'] = item['obj'].description
holder['category_id'] = item['obj'].category_id
holder['license_id'] = item['obj'].license_id
holder['author'] = item['obj'].Author_id
holder['settings_list'] = item['setting_list']
repetition_list = [repetition.name for repetition in item['repetition_units']]
weight_units = [unit.name for unit in item['weight_units']]
holder['weight_units'] = weight_units
holder['repetition_list'] = repetition_list
holder['comments'] = item['comment_list']
holder['reps'] = item['setting_obj_list'][0].reps
holder['order'] = item['setting_obj_list'][0].order
exercise_list.append(holder)

set_dict['muscles'] = set['muscles']
set_dict['exercise_list'] = exercise_list

set_list.append(set_dict)

workout_details['set_list'] = set_list
else:
workout_details = []

json_data = json.dumps(workout_details)

# Create the HttpResponse object with appropriate JSON headers
response = HttpResponse(json_data, content_type='application/json')

response['Content-Disposition'] = 'attachment; filename=Workout-{0}.json'.format(id)
response['Content-Length'] = len(response.content)
return response


class Importworkout(APIView):
permission_classes = (AllowAny, )

def post(self, request, *args, **kwargs):
content = request.data
data = json.loads(content['data'])
workout = get_object_or_404(Workout, pk=content['workout_id'])
workout.user = request.user
workout.comment = data['description']
workout.save()
days = data['workout_days'].split(', ')
days_of_week = DaysOfWeek.objects.filter(day_of_week__in=days)
day_save = Day.objects.create(training=workout, description=data['description'])
day_save.day.set(days_of_week)
set_list = data['set_list']
for set in set_list:
no_of_sets = set['sets']
exercise_names = [exercise['name_of_exercise'] for exercise in set['exercise_list']]
exercises = Exercise.objects.filter(name__in=exercise_names)
for exercise in exercises:
exercise_in_list = next((item for item in set['exercise_list']
if item['name_of_exercise'] == exercise.name), {})
reps = exercise_in_list.get('reps', 0)
order = exercise_in_list.get('order', 1)
day_set = Set(exerciseday=day_save, sets=no_of_sets, order=set['set_order'])
day_set.save()
day_set.exercises.add(exercise)
settings = Setting(set=day_set, exercise=exercise,
reps=reps, order=order)
settings.save()

return HttpResponse(data)

0 comments on commit b5fca59

Please sign in to comment.