def export_schedule(request, pk, uidb64=None, token=None): ''' Export the current schedule as an iCal file ''' # Load the schedule if uidb64 is not None and token is not None: if check_token(uidb64, token): schedule = get_object_or_404(Schedule, pk=pk) else: return HttpResponseForbidden() else: if request.user.is_anonymous(): return HttpResponseForbidden() schedule = get_object_or_404(Schedule, pk=pk, user=request.user) # Create the calendar calendar = get_calendar() # Create the events and add them to the calendar start_date = datetime.date.today() for step in schedule.schedulestep_set.all(): get_events_workout(calendar, step.workout, step.duration, start_date) start_date = start_date + datetime.timedelta(weeks=step.duration) # Send the file to the user response = HttpResponse(content_type='text/calendar') response['Content-Disposition'] = \ 'attachment; filename=Calendar-schedule-{0}.ics'.format(schedule.pk) response.write(calendar.to_ical()) response['Content-Length'] = len(response.content) return response
def workout_json(request, id, comments=False, uidb64=None, token=None): ''' Generates a JSON with the contents of the given workout and allows user to download in browser ''' # Load 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) # package response and download file in browser response = HttpResponse(str(workout.canonical_representation), content_type='application/json') response[ 'Content-Disposition'] = 'attachment; filename=Workout-{0}.json'.format( id) response['Content-Length'] = len(response.content) return response
def export(request, pk, uidb64=None, token=None): ''' Export the current workout as an iCal file ''' # Load the workout if uidb64 is not None and token is not None: if check_token(uidb64, token): workout = get_object_or_404(Workout, pk=pk) else: return HttpResponseForbidden() else: if request.user.is_anonymous(): return HttpResponseForbidden() workout = get_object_or_404(Workout, pk=pk, user=request.user) # Create the calendar calendar = get_calendar() # Create the events and add them to the calendar get_events_workout(calendar, workout, workout.user.userprofile.workout_duration) # Send the file to the user response = HttpResponse(content_type='text/calendar') response['Content-Disposition'] = \ 'attachment; filename=Calendar-workout-{0}.ics'.format(workout.pk) response.write(calendar.to_ical()) response['Content-Length'] = len(response.content) return response
def export_pdf(request, pk, uidb64=None, token=None): ''' Show the workout schedule ''' user = request.user # Load the workout if uidb64 is not None and token is not None: if check_token(uidb64, token): schedule = get_object_or_404(Schedule, pk=pk) else: return HttpResponseForbidden() else: if request.user.is_anonymous(): return HttpResponseForbidden() schedule = get_object_or_404(Schedule, pk=pk, user=user) # Create the HttpResponse object with the appropriate PDF headers. # and use it to the create the PDF using it as a file like object response = HttpResponse(content_type='application/pdf') doc = SimpleDocTemplate(response, pagesize=A4, leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject='Schedule for {0}'.format(request.user.username)) # container for the 'Flowable' objects elements = [] # Set the title p = Paragraph(u'<para align="center">{0}</para>'.format(schedule), styleSheet["HeaderBold"]) elements.append(p) elements.append(Spacer(10 * cm, 0.5 * cm)) # Iterate through the Workout and render the training days for step in schedule.schedulestep_set.all(): p = Paragraph(u'<para>{0} {1}</para>'.format(step.duration, _('Weeks')), styleSheet["HeaderBold"]) elements.append(p) elements.append(Spacer(10 * cm, 0.5 * cm)) for day in step.workout.canonical_representation['day_list']: elements.append(render_workout_day(day, nr_of_weeks=7)) elements.append(Spacer(10 * cm, 0.5 * cm)) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) url = reverse('manager:schedule:view', kwargs={'pk': schedule.id}) elements.append(render_footer(request.build_absolute_uri(url))) # write the document and send the response to the browser doc.build(elements) response['Content-Disposition'] = 'attachment; filename=Schedule-{0}-log.pdf'.format(pk) response['Content-Length'] = len(response.content) return response
def export_pdf(request, pk, uidb64=None, token=None): ''' Show the workout schedule ''' user = request.user # Load the workout if uidb64 is not None and token is not None: if check_token(uidb64, token): schedule = get_object_or_404(Schedule, pk=pk) else: return HttpResponseForbidden() else: if request.user.is_anonymous(): return HttpResponseForbidden() schedule = get_object_or_404(Schedule, pk=pk, user=user) # Create the HttpResponse object with the appropriate PDF headers. # and use it to the create the PDF using it as a file like object response = HttpResponse(content_type='application/pdf') doc = SimpleDocTemplate(response, pagesize=A4, leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject='Schedule for {0}'.format(request.user.username)) # container for the 'Flowable' objects elements = [] # Set the title p = Paragraph(u'<para align="center">{0}</para>'.format(schedule), styleSheet["HeaderBold"]) elements.append(p) elements.append(Spacer(10*cm, 0.5*cm)) # Iterate through the Workout and render the training days for step in schedule.schedulestep_set.all(): p = Paragraph(u'<para>{0} {1}</para>'.format(step.duration, _('Weeks')), styleSheet["HeaderBold"]) elements.append(p) elements.append(Spacer(10*cm, 0.5*cm)) for day in step.workout.canonical_representation['day_list']: elements.append(render_workout_day(day, nr_of_weeks=7)) elements.append(Spacer(10*cm, 0.5*cm)) # Footer, date and info elements.append(Spacer(10*cm, 0.5*cm)) url = reverse('manager:schedule:view', kwargs={'pk': schedule.id}) elements.append(render_footer(request.build_absolute_uri(url))) # write the document and send the response to the browser doc.build(elements) response['Content-Disposition'] = 'attachment; filename=Schedule-{0}-log.pdf'.format(pk) response['Content-Length'] = len(response.content) return response
def workout_log(request, id, images=False, comments=False, uidb64=None, token=None): """ Generates a PDF with the contents of the given workout See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html """ comments = bool(int(comments)) images = bool(int(images)) # Load 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) # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate( response, pagesize=A4, # pagesize = landscape(A4), leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject=_('Workout for %s') % request.user.username) # container for the 'Flowable' objects elements = [] # Set the title p = Paragraph( '<para align="center"><strong>%(description)s</strong></para>' % {'description': workout}, styleSheet["HeaderBold"]) elements.append(p) elements.append(Spacer(10 * cm, 0.5 * cm)) # Iterate through the Workout and render the training days for day in workout.canonical_representation['day_list']: elements.append( render_workout_day(day, images=images, comments=comments)) elements.append(Spacer(10 * cm, 0.5 * cm)) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) elements.append( render_footer(request.build_absolute_uri(workout.get_absolute_url()))) # write the document and send the response to the browser doc.build(elements) # Create the HttpResponse object with the appropriate PDF headers. response[ 'Content-Disposition'] = 'attachment; filename=Workout-{0}-log.pdf'.format( id) response['Content-Length'] = len(response.content) return response
def export_pdf(request, id, uidb64=None, token=None): """ Generates a PDF with the contents of a nutrition plan See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html """ # Load the plan if uidb64 is not None and token is not None: if check_token(uidb64, token): plan = get_object_or_404(NutritionPlan, pk=id) else: return HttpResponseForbidden() else: if request.user.is_anonymous: return HttpResponseForbidden() plan = get_object_or_404(NutritionPlan, pk=id, user=request.user) plan_data = plan.get_nutritional_values() # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate( response, pagesize=A4, title=_('Nutritional plan'), author='wger Workout Manager', subject=_('Nutritional plan for %s') % request.user.username, topMargin=1 * cm, ) # container for the 'Flowable' objects elements = [] data = [] # Iterate through the Plan meal_markers = [] ingredient_markers = [] # Meals i = 0 for meal in plan.meal_set.select_related(): i += 1 meal_markers.append(len(data)) if not meal.time: p = Paragraph( '<para align="center"><strong>{nr} {meal_nr}</strong></para>'. format(nr=_('Nr.'), meal_nr=i), styleSheet["SubHeader"]) else: p = Paragraph( '<para align="center"><strong>' '{nr} {meal_nr} - {meal_time}' '</strong></para>'.format( nr=_('Nr.'), meal_nr=i, meal_time=meal.time.strftime("%H:%M")), styleSheet["SubHeader"]) data.append([p]) # Ingredients for item in meal.mealitem_set.select_related(): ingredient_markers.append(len(data)) p = Paragraph('<para>{0}</para>'.format(item.ingredient.name), styleSheet["Normal"]) if item.get_unit_type() == MEALITEM_WEIGHT_GRAM: unit_name = 'g' else: unit_name = ' × ' + item.weight_unit.unit.name data.append([ Paragraph("{0:.0f}{1}".format(item.amount, unit_name), styleSheet["Normal"]), p ]) # Add filler data.append([Spacer(1 * cm, 0.6 * cm)]) # Set general table styles table_style = [] # Set specific styles, e.g. background for title cells for marker in meal_markers: # Set background colour for headings table_style.append( ('BACKGROUND', (0, marker), (-1, marker), header_colour)) table_style.append( ('BOX', (0, marker), (-1, marker), 1.25, colors.black)) # Make the headings span the whole width table_style.append(('SPAN', (0, marker), (-1, marker))) # has the plan any data? if data: t = Table(data, style=table_style) # Manually set the width of the columns t._argW[0] = 3.5 * cm # There is nothing to output else: t = Paragraph( _('<i>This is an empty plan, what did you expect on the PDF?</i>'), styleSheet["Normal"]) # Add site logo elements.append(get_logo()) elements.append(Spacer(10 * cm, 0.5 * cm)) # Set the title (if available) if plan.description: p = Paragraph( '<para align="center"><strong>%(description)s</strong></para>' % {'description': plan.description}, styleSheet["HeaderBold"]) elements.append(p) # Filler elements.append(Spacer(10 * cm, 1.5 * cm)) # append the table to the document elements.append(t) elements.append(Paragraph('<para> </para>', styleSheet["Normal"])) # Create table with nutritional calculations data = [] data.append([ Paragraph( '<para align="center">{0}</para>'.format(_('Nutritional data')), styleSheet["SubHeaderBlack"]) ]) data.append([ Paragraph(_('Macronutrients'), styleSheet["Normal"]), Paragraph(_('Total'), styleSheet["Normal"]), Paragraph(_('Percent of energy'), styleSheet["Normal"]), Paragraph(_('g per body kg'), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Energy'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['energy']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Protein'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['protein']), styleSheet["Normal"]), Paragraph(str(plan_data['percent']['protein']), styleSheet["Normal"]), Paragraph(str(plan_data['per_kg']['protein']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Carbohydrates'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['carbohydrates']), styleSheet["Normal"]), Paragraph(str(plan_data['percent']['carbohydrates']), styleSheet["Normal"]), Paragraph(str(plan_data['per_kg']['carbohydrates']), styleSheet["Normal"]) ]) data.append([ Paragraph(" " + _('Sugar content in carbohydrates'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['carbohydrates_sugar']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Fat'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['fat']), styleSheet["Normal"]), Paragraph(str(plan_data['percent']['fat']), styleSheet["Normal"]), Paragraph(str(plan_data['per_kg']['fat']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Saturated fat content in fats'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['fat_saturated']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Fibres'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['fibres']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Sodium'), styleSheet["Normal"]), Paragraph(str(plan_data['total']['sodium']), styleSheet["Normal"]) ]) table_style = [] table_style.append(('BOX', (0, 0), (-1, -1), 1.25, colors.black)) table_style.append(('GRID', (0, 0), (-1, -1), 0.40, colors.black)) table_style.append(('SPAN', (0, 0), (-1, 0))) # Title table_style.append(('SPAN', (1, 2), (-1, 2))) # Energy table_style.append(('BACKGROUND', (0, 3), (-1, 3), row_color)) # Protein table_style.append( ('BACKGROUND', (0, 4), (-1, 4), row_color)) # Carbohydrates table_style.append(('SPAN', (1, 5), (-1, 5))) # Sugar table_style.append(('LEFTPADDING', (0, 5), (0, 5), 15)) table_style.append(('BACKGROUND', (0, 6), (-1, 6), row_color)) # Fats table_style.append(('SPAN', (1, 7), (-1, 7))) # Saturated fats table_style.append(('LEFTPADDING', (0, 7), (0, 7), 15)) table_style.append(('SPAN', (1, 8), (-1, 8))) # Fibres table_style.append(('SPAN', (1, 9), (-1, 9))) # Sodium t = Table(data, style=table_style) t._argW[0] = 6 * cm elements.append(t) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) elements.append( render_footer(request.build_absolute_uri(plan.get_absolute_url()))) doc.build(elements) response[ 'Content-Disposition'] = 'attachment; filename=nutritional-plan.pdf' response['Content-Length'] = len(response.content) return response
def export_pdf(request, id, uidb64=None, token=None): ''' Generates a PDF with the contents of a nutrition plan See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html ''' # Load the plan if uidb64 is not None and token is not None: if check_token(uidb64, token): plan = get_object_or_404(NutritionPlan, pk=id) else: return HttpResponseForbidden() else: if request.user.is_anonymous(): return HttpResponseForbidden() plan = get_object_or_404(NutritionPlan, pk=id, user=request.user) plan_data = plan.get_nutritional_values() # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate(response, pagesize=A4, title=_('Workout'), author='wger Workout Manager', subject=_('Nutritional plan %s') % request.user.username) # Background colour for header # Reportlab doesn't use the HTML hexadecimal format, but has a range of # 0 till 1, so we have to convert here. header_colour = colors.Color( int('73', 16) / 255.0, int('8a', 16) / 255.0, int('5f', 16) / 255.0) # container for the 'Flowable' objects elements = [] data = [] # Iterate through the Plan meal_markers = [] ingredient_markers = [] # Meals i = 0 for meal in plan.meal_set.select_related(): i += 1 meal_markers.append(len(data)) if not meal.time: p = Paragraph( u'<para align="center"><strong>{nr} {meal_nr}</strong></para>'. format(nr=_('Nr.'), meal_nr=i), styleSheet["Normal"]) else: p = Paragraph( u'<para align="center"><strong>' u'{nr} {meal_nr} - {meal_time}' u'</strong></para>'.format( nr=_('Nr.'), meal_nr=i, meal_time=meal.time.strftime("%H:%M")), styleSheet["Normal"]) data.append([p]) # Ingredients for item in meal.mealitem_set.select_related(): ingredient_markers.append(len(data)) p = Paragraph(u'<para>{0}</para>'.format(item.ingredient.name), styleSheet["Normal"]) if item.get_unit_type() == MEALITEM_WEIGHT_GRAM: unit_name = 'g' else: unit_name = ' ' + item.weight_unit.unit.name data.append([ Paragraph(u"{0}{1}".format(item.amount, unit_name), styleSheet["Normal"]), p ]) # Set general table styles table_style = [] # Set specific styles, e.g. background for title cells for marker in meal_markers: # Set background colour for headings table_style.append( ('BACKGROUND', (0, marker), (-1, marker), header_colour)) table_style.append( ('BOX', (0, marker), (-1, marker), 1.25, colors.black)) # Make the headings span the whole width table_style.append(('SPAN', (0, marker), (-1, marker))) # has the plan any data? if data: t = Table(data, style=table_style) # Manually set the width of the columns t._argW[0] = 2.5 * cm # There is nothing to output else: t = Paragraph( _('<i>This is an empty plan, what did you expect on the PDF?</i>'), styleSheet["Normal"]) # Set the title (if available) if plan.description: p = Paragraph( '<para align="center"><strong>%(description)s</strong></para>' % {'description': plan.description}, styleSheet["Bold"]) elements.append(p) # Filler elements.append(Spacer(10 * cm, 0.5 * cm)) # append the table to the document elements.append(t) elements.append(Paragraph('<para> </para>', styleSheet["Normal"])) # Create table with nutritional calculations data = [] data.append([ Paragraph( u'<para align="center">{0}</para>'.format(_('Nutritional data')), styleSheet["Bold"]) ]) data.append([ Paragraph(_('Macronutrients'), styleSheet["Normal"]), Paragraph(_('Total'), styleSheet["Normal"]), Paragraph(_('Percent of energy'), styleSheet["Normal"]), Paragraph(_('g per body kg'), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Energy'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['energy']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Protein'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['protein']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['percent']['protein']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['per_kg']['protein']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Carbohydrates'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['carbohydrates']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['percent']['carbohydrates']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['per_kg']['carbohydrates']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Sugar content in carbohydrates'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['carbohydrates_sugar']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Fat'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['fat']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['percent']['fat']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['per_kg']['fat']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Saturated fat content in fats'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['fat_saturated']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Fibres'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['fibres']), styleSheet["Normal"]) ]) data.append([ Paragraph(_('Sodium'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['sodium']), styleSheet["Normal"]) ]) table_style = [] table_style.append(('BOX', (0, 0), (-1, -1), 1.25, colors.black)) table_style.append(('GRID', (0, 0), (-1, -1), 0.40, colors.black)) table_style.append(('SPAN', (0, 0), (-1, 0))) # Title table_style.append(('SPAN', (1, 2), (-1, 2))) # Energy table_style.append(('SPAN', (1, 5), (-1, 5))) # Sugar table_style.append(('SPAN', (1, 7), (-1, 7))) # Saturated fats table_style.append(('SPAN', (1, 8), (-1, 8))) # Fibres table_style.append(('SPAN', (1, 9), (-1, 9))) # Sodium t = Table(data, style=table_style) t._argW[0] = 5 * cm elements.append(t) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) created = datetime.date.today().strftime("%d.%m.%Y") url = reverse('nutrition-view', kwargs={'id': plan.id}) p = Paragraph( '''<para align="left"> %(date)s - <a href="%(url)s">%(url)s</a> - %(created)s %(version)s </para>''' % { 'date': _("Created on the <b>%s</b>") % created, 'created': "wger Workout Manager", 'version': get_version(), 'url': request.build_absolute_uri(url), }, styleSheet["Normal"]) elements.append(p) doc.build(elements) response[ 'Content-Disposition'] = 'attachment; filename=nutritional-plan.pdf' response['Content-Length'] = len(response.content) return response
def workout_log(request, id, images=False, comments=False, uidb64=None, token=None): ''' Generates a PDF with the contents of the given workout See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html ''' comments = bool(int(comments)) images = bool(int(images)) # Load 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) # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate(response, pagesize=A4, # pagesize = landscape(A4), leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject=_('Workout for %s') % request.user.username) # container for the 'Flowable' objects elements = [] # Set the title p = Paragraph('<para align="center"><strong>%(description)s</strong></para>' % {'description': workout}, styleSheet["HeaderBold"]) elements.append(p) elements.append(Spacer(10 * cm, 0.5 * cm)) # Iterate through the Workout and render the training days for day in workout.canonical_representation['day_list']: elements.append(render_workout_day(day, images=images, comments=comments)) elements.append(Spacer(10 * cm, 0.5 * cm)) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) elements.append(render_footer(request.build_absolute_uri(workout.get_absolute_url()))) # write the document and send the response to the browser doc.build(elements) # Create the HttpResponse object with the appropriate PDF headers. response['Content-Disposition'] = 'attachment; filename=Workout-{0}-log.pdf'.format(id) response['Content-Length'] = len(response.content) return response
def export_pdf(request, id, uidb64=None, token=None): ''' Generates a PDF with the contents of a nutrition plan See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html ''' # Load the plan if uidb64 is not None and token is not None: if check_token(uidb64, token): plan = get_object_or_404(NutritionPlan, pk=id) else: return HttpResponseForbidden() else: if request.user.is_anonymous(): return HttpResponseForbidden() plan = get_object_or_404(NutritionPlan, pk=id, user=request.user) plan_data = plan.get_nutritional_values() # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate(response, pagesize=A4, title=_('Nutrition plan'), author='wger Workout Manager', subject=_('Nutritional plan %s') % request.user.username) # Background colour for header # Reportlab doesn't use the HTML hexadecimal format, but has a range of # 0 till 1, so we have to convert here. header_colour = colors.Color(int('73', 16) / 255.0, int('8a', 16) / 255.0, int('5f', 16) / 255.0) # container for the 'Flowable' objects elements = [] data = [] # Iterate through the Plan meal_markers = [] ingredient_markers = [] # Meals i = 0 for meal in plan.meal_set.select_related(): i += 1 meal_markers.append(len(data)) if not meal.time: p = Paragraph(u'<para align="center"><strong>{nr} {meal_nr}</strong></para>' .format(nr=_('Nr.'), meal_nr=i), styleSheet["Normal"]) else: p = Paragraph(u'<para align="center"><strong>' u'{nr} {meal_nr} - {meal_time}' u'</strong></para>' .format(nr=_('Nr.'), meal_nr=i, meal_time=meal.time.strftime("%H:%M")), styleSheet["Normal"]) data.append([p]) # Ingredients for item in meal.mealitem_set.select_related(): ingredient_markers.append(len(data)) p = Paragraph(u'<para>{0}</para>'.format(item.ingredient.name), styleSheet["Normal"]) if item.get_unit_type() == MEALITEM_WEIGHT_GRAM: unit_name = 'g' else: unit_name = ' ' + item.weight_unit.unit.name data.append([Paragraph(u"{0}{1}".format(item.amount, unit_name), styleSheet["Normal"]), p]) # Set general table styles table_style = [] # Set specific styles, e.g. background for title cells for marker in meal_markers: # Set background colour for headings table_style.append(('BACKGROUND', (0, marker), (-1, marker), header_colour)) table_style.append(('BOX', (0, marker), (-1, marker), 1.25, colors.black)) # Make the headings span the whole width table_style.append(('SPAN', (0, marker), (-1, marker))) # has the plan any data? if data: t = Table(data, style=table_style) # Manually set the width of the columns t._argW[0] = 2.5 * cm # There is nothing to output else: t = Paragraph(_('<i>This is an empty plan, what did you expect on the PDF?</i>'), styleSheet["Normal"]) # Set the title (if available) if plan.description: p = Paragraph('<para align="center"><strong>%(description)s</strong></para>' % {'description': plan.description}, styleSheet["Bold"]) elements.append(p) # Filler elements.append(Spacer(10 * cm, 0.5 * cm)) # append the table to the document elements.append(t) elements.append(Paragraph('<para> </para>', styleSheet["Normal"])) # Create table with nutritional calculations data = [] data.append([Paragraph(u'<para align="center">{0}</para>'.format(_('Nutritional data')), styleSheet["Bold"])]) data.append([Paragraph(_('Macronutrients'), styleSheet["Normal"]), Paragraph(_('Total'), styleSheet["Normal"]), Paragraph(_('Percent of energy'), styleSheet["Normal"]), Paragraph(_('g per body kg'), styleSheet["Normal"])]) data.append([Paragraph(_('Energy'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['energy']), styleSheet["Normal"])]) data.append([Paragraph(_('Protein'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['protein']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['percent']['protein']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['per_kg']['protein']), styleSheet["Normal"])]) data.append([Paragraph(_('Carbohydrates'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['carbohydrates']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['percent']['carbohydrates']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['per_kg']['carbohydrates']), styleSheet["Normal"])]) data.append([Paragraph(_('Sugar content in carbohydrates'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['carbohydrates_sugar']), styleSheet["Normal"])]) data.append([Paragraph(_('Fat'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['fat']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['percent']['fat']), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['per_kg']['fat']), styleSheet["Normal"])]) data.append([Paragraph(_('Saturated fat content in fats'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['fat_saturated']), styleSheet["Normal"])]) data.append([Paragraph(_('Fibres'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['fibres']), styleSheet["Normal"])]) data.append([Paragraph(_('Sodium'), styleSheet["Normal"]), Paragraph(six.text_type(plan_data['total']['sodium']), styleSheet["Normal"])]) table_style = [] table_style.append(('BOX', (0, 0), (-1, -1), 1.25, colors.black)) table_style.append(('GRID', (0, 0), (-1, -1), 0.40, colors.black)) table_style.append(('SPAN', (0, 0), (-1, 0))) # Title table_style.append(('SPAN', (1, 2), (-1, 2))) # Energy table_style.append(('SPAN', (1, 5), (-1, 5))) # Sugar table_style.append(('SPAN', (1, 7), (-1, 7))) # Saturated fats table_style.append(('SPAN', (1, 8), (-1, 8))) # Fibres table_style.append(('SPAN', (1, 9), (-1, 9))) # Sodium t = Table(data, style=table_style) t._argW[0] = 5 * cm elements.append(t) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) created = datetime.date.today().strftime("%d.%m.%Y") url = reverse('nutrition:plan:view', kwargs={'id': plan.id}) p = Paragraph('''<para align="left"> %(date)s - <a href="%(url)s">%(url)s</a> - %(created)s %(version)s </para>''' % {'date': _("Created on the <b>%s</b>") % created, 'created': "wger Workout Manager", 'version': get_version(), 'url': request.build_absolute_uri(url), }, styleSheet["Normal"]) elements.append(p) doc.build(elements) response['Content-Disposition'] = 'attachment; filename=nutritional-plan.pdf' response['Content-Length'] = len(response.content) return response
def workout_view(request, id, uidb64=None, token=None): ''' Generates a PDF with the contents of the workout, without table for logs ''' # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Load 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) # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate( response, pagesize=A4, # pagesize = landscape(A4), leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject=_('Workout for %s') % request.user.username) # container for the 'Flowable' objects elements = [] # table data, here we will put the workout info data = [] # Init several counters and markers, this will be used after the iteration to # set different borders and colours day_markers = [] exercise_markers = {} group_exercise_marker = {} group_day_marker = {} # Background colour for days # Reportlab doesn't use the HTML hexadecimal format, but has a range of # 0 till 1, so we have to convert here. header_colour = colors.Color( int('73', 16) / 255.0, int('8a', 16) / 255.0, int('5f', 16) / 255.0) # # Iterate through the Workout # # Days for day in workout.canonical_representation['day_list']: set_count = 1 day_markers.append(len(data)) group_day_marker[day['obj'].id] = { 'start': len(data), 'end': len(data) } if not exercise_markers.get(day['obj'].id): exercise_markers[day['obj'].id] = [] p = Paragraph( '<para align="center">%(days)s: %(description)s</para>' % { 'days': day['days_of_week']['text'], 'description': day['obj'].description }, styleSheet["Bold"]) data.append([p]) # Sets for set in day['set_list']: group_exercise_marker[set['obj'].id] = { 'start': len(data), 'end': len(data) } # Exercises for exercise in set['exercise_list']: group_exercise_marker[set['obj'].id]['end'] = len(data) # Note: '+1' here because there's an emtpy cell between days exercise_markers[day['obj'].id].append(len(data) + 1) data.append([ set_count, Paragraph(exercise['obj'].name, styleSheet["Small"]), exercise['setting_text'] ]) set_count += 1 data.append(['']) group_day_marker[day['obj'].id]['end'] = len(data) # Set the widths and heights of rows and columns # Note: 'None' is treated as 'automatic'. Either there is only one value for the whole list # or exactly one for every row/column colwidths = None rowheights = [None] * len(data) table_style = [ ('FONT', (0, 0), (-1, -1), 'OpenSans'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # Note: a padding of 3 seems to be the default ('LEFTPADDING', (0, 0), (-1, -1), 2), ('RIGHTPADDING', (0, 0), (-1, -1), 0), ('TOPPADDING', (0, 0), (-1, -1), 3), ('BOTTOMPADDING', (0, 0), (-1, -1), 2), ] # Set specific styles, e.g. background for title cells for marker in day_markers: # Set background colour for headings table_style.append( ('BACKGROUND', (0, marker), (-1, marker), header_colour)) table_style.append( ('BOX', (0, marker), (-1, marker), 1.25, colors.black)) # Make the headings span the whole width table_style.append(('SPAN', (0, marker), (-1, marker))) # Manually set rowheights[marker - 1] = 5 # Combine the cells for exercises on the same set counter = 1 for marker in group_exercise_marker: counter += 1 start_marker = group_exercise_marker[marker]['start'] end_marker = group_exercise_marker[marker]['end'] table_style.append(('SPAN', (0, start_marker), (0, end_marker))) table_style.append( ('BOX', (0, start_marker), (-1, end_marker), 0.25, colors.black)) if counter % 2: table_style.append(('BACKGROUND', (0, start_marker), (-1, end_marker), colors.lavender)) for marker in group_day_marker: start_marker = group_day_marker[marker]['start'] end_marker = group_day_marker[marker]['end'] table_style.append(('BOX', (0, start_marker), (-1, end_marker - 2), 1.25, colors.black)) # Set the table data if data: t = Table(data, colwidths, rowheights, style=table_style) # Manually set the width of the columns if len(t._argW) > 1: t._argW[0] = 0.6 * cm # Numbering t._argW[1] = 9 * cm # Exercise t._argW[2] = 4 * cm # Repetitions # There is nothing to output else: t = Paragraph( _('<i>This is an empty workout, what did you expect on the PDF?</i>' ), styleSheet["Normal"]) # # Add all elements to the document # # Set the title (if available) if workout.comment: p = Paragraph( '<para align="center"><strong>%(description)s</strong></para>' % {'description': workout.comment}, styleSheet["Bold"]) elements.append(p) # Filler elements.append(Spacer(10 * cm, 0.5 * cm)) # Append the table elements.append(t) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) created = datetime.date.today().strftime("%d.%m.%Y") p = Paragraph( '''<para align="left"> %(date)s - <a href="%(url)s">%(url)s</a> - %(created)s %(version)s </para>''' % { 'date': _("Created on the <b>%s</b>") % created, 'created': "wger Workout Manager", 'version': get_version(), 'url': request.build_absolute_uri(workout.get_absolute_url()), }, styleSheet["Normal"]) elements.append(p) # write the document and send the response to the browser doc.build(elements) # Create the HttpResponse object with the appropriate PDF headers. response[ 'Content-Disposition'] = 'attachment; filename=Workout-{0}-table.pdf'.format( id) response['Content-Length'] = len(response.content) return response
def workout_log(request, id, uidb64=None, token=None): ''' Generates a PDF with the contents of the given workout See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html ''' # Load 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) # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate(response, pagesize=A4, # pagesize = landscape(A4), leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject=_('Workout for %s') % request.user.username) # container for the 'Flowable' objects elements = [] # table data, here we will put the workout info data = [] # Init several counters and markers, this will be used after the iteration to # set different borders and colours day_markers = [] exercise_markers = {} group_exercise_marker = {} group_day_marker = {} # Set the number of weeks for this workout # (sets number of columns for the weight/date log) nr_of_weeks = 7 # Set the first column of the weight log, depends on design first_weight_column = 3 # Background colour for days # Reportlab doesn't use the HTML hexadecimal format, but has a range of # 0 till 1, so we have to convert here. header_colour = colors.Color(int('73', 16) / 255.0, int('8a', 16) / 255.0, int('5f', 16) / 255.0) # # Iterate through the Workout # # Days for day in workout.canonical_representation['day_list']: set_count = 1 day_markers.append(len(data)) group_day_marker[day['obj'].id] = {'start': len(data), 'end': len(data)} if not exercise_markers.get(day['obj'].id): exercise_markers[day['obj'].id] = [] P = Paragraph('<para align="center">%(days)s: %(description)s</para>' % {'days': day['days_of_week']['text'], 'description': day['obj'].description}, styleSheet["Bold"]) data.append([P]) # Note: the _('Date') will be on the 3rd cell, but since we make a span # over 3 cells, the value has to be on the 1st one data.append([_('Date') + ' ', '', ''] + [''] * nr_of_weeks) data.append([_('Nr.'), _('Exercise'), _('Reps')] + [_('Weight')] * nr_of_weeks) # Sets for set in day['set_list']: group_exercise_marker[set['obj'].id] = {'start': len(data), 'end': len(data)} # Exercises for exercise in set['exercise_list']: group_exercise_marker[set['obj'].id]['end'] = len(data) # Note: '+1' here because there's an emtpy cell between days exercise_markers[day['obj'].id].append(len(data) + 1) data.append([set_count, Paragraph(exercise['obj'].name, styleSheet["Small"]), exercise['setting_text']] + [''] * nr_of_weeks) set_count += 1 data.append(['']) group_day_marker[day['obj'].id]['end'] = len(data) # Set the widths and heights of rows and columns # Note: 'None' is treated as 'automatic'. Either there is only one value for the whole list # or exactly one for every row/column colwidths = None rowheights = [None] * len(data) # Set general table styles table_style = [('FONT', (0, 0), (-1, -1), 'OpenSans'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # Note: a padding of 3 seems to be the default ('LEFTPADDING', (0, 0), (-1, -1), 2), ('RIGHTPADDING', (0, 0), (-1, -1), 0), ('TOPPADDING', (0, 0), (-1, -1), 3), ('BOTTOMPADDING', (0, 0), (-1, -1), 2), ] # Set specific styles, e.g. background for title cells for marker in day_markers: # Set background colour for headings table_style.append(('BACKGROUND', (0, marker), (-1, marker), header_colour)) table_style.append(('BOX', (0, marker), (-1, marker), 1.25, colors.black)) table_style.append(('BOX', (0, marker), (-1, marker + 2), 1.25, colors.black)) # Make the headings span the whole width table_style.append(('SPAN', (0, marker), (-1, marker))) # Make the space between days span the whole width table_style.append(('SPAN', (0, marker - 1), (-1, marker - 1))) # Manually set rowheights[marker - 1] = 5 # Make the date span 3 cells and align it to the right table_style.append(('ALIGN', (0, marker + 1), (2, marker + 1), 'RIGHT')) table_style.append(('SPAN', (0, marker + 1), (2, marker + 1))) # Combine the cells for exercises on the same set for marker in group_exercise_marker: start_marker = group_exercise_marker[marker]['start'] end_marker = group_exercise_marker[marker]['end'] table_style.append(('VALIGN', (0, start_marker), (0, end_marker), 'MIDDLE')) table_style.append(('SPAN', (0, start_marker), (0, end_marker))) # Set an alternating background colour for rows for i in exercise_markers: counter = 1 for j in exercise_markers[i]: if not j % 2: table_style.append(('BACKGROUND', (1, j - 1), (-1, j - 1), colors.lavender)) counter += 1 # Make the 'impression' span 3 cells and align it to the right for marker in group_day_marker: start_marker = group_day_marker[marker]['start'] end_marker = group_day_marker[marker]['end'] # There is an empty cell between the day blocks, set a border around them table_style.append(('INNERGRID', (0, start_marker), (- 1, end_marker - 2), 0.25, colors.black)) table_style.append(('BOX', (0, start_marker), (-1, end_marker - 2), 1.25, colors.black)) # Set the table data if data: t = Table(data, colwidths, rowheights, style=table_style) # Manually set the width of the columns for i in range(first_weight_column, nr_of_weeks + first_weight_column): t._argW[i] = 1.8 * cm # Columns for entering the log t._argW[0] = 0.6 * cm # Exercise numbering t._argW[1] = 3.5 * cm # Name of exercise t._argW[2] = 2 * cm # Repetitions # There is nothing to output else: t = Paragraph(_('<i>This is an empty workout, what did you expect on the PDF?</i>'), styleSheet["Normal"]) # # Add all elements to the document # # Set the title (if available) if workout.comment: P = Paragraph('<para align="center"><strong>%(description)s</strong></para>' % {'description': workout.comment}, styleSheet["Bold"]) elements.append(P) # Filler elements.append(Spacer(10*cm, 0.5*cm)) # Append the table elements.append(t) # Footer, date and info elements.append(Spacer(10*cm, 0.5*cm)) created = datetime.date.today().strftime("%d.%m.%Y") url = reverse('workout-view', kwargs={'id': workout.id}) P = Paragraph('''<para align="left"> %(date)s - <a href="%(url)s">%(url)s</a> - %(created)s %(version)s </para>''' % {'date': _("Created on the <b>%s</b>") % created, 'created': "wger Workout Manager", 'version': get_version(), 'url': request.build_absolute_uri(url), }, styleSheet["Normal"]) elements.append(P) # write the document and send the response to the browser doc.build(elements) # Create the HttpResponse object with the appropriate PDF headers. response['Content-Disposition'] = 'attachment; filename=Workout-{0}-log.pdf'.format(id) response['Content-Length'] = len(response.content) return response
def workout_view(request, id, uidb64=None, token=None): ''' Generates a PDF with the contents of the workout, without table for logs ''' # Create the HttpResponse object with the appropriate PDF headers. response = HttpResponse(content_type='application/pdf') # Load 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) # Create the PDF object, using the response object as its "file." doc = SimpleDocTemplate(response, pagesize=A4, # pagesize = landscape(A4), leftMargin=cm, rightMargin=cm, topMargin=0.5 * cm, bottomMargin=0.5 * cm, title=_('Workout'), author='wger Workout Manager', subject=_('Workout for %s') % request.user.username) # container for the 'Flowable' objects elements = [] # table data, here we will put the workout info data = [] # Init several counters and markers, this will be used after the iteration to # set different borders and colours day_markers = [] exercise_markers = {} group_exercise_marker = {} group_day_marker = {} # Background colour for days # Reportlab doesn't use the HTML hexadecimal format, but has a range of # 0 till 1, so we have to convert here. header_colour = colors.Color(int('73', 16) / 255.0, int('8a', 16) / 255.0, int('5f', 16) / 255.0) # # Iterate through the Workout # # Days for day in workout.canonical_representation['day_list']: set_count = 1 day_markers.append(len(data)) group_day_marker[day['obj'].id] = {'start': len(data), 'end': len(data)} if not exercise_markers.get(day['obj'].id): exercise_markers[day['obj'].id] = [] p = Paragraph('<para align="center">%(days)s: %(description)s</para>' % {'days': day['days_of_week']['text'], 'description': day['obj'].description}, styleSheet["Bold"]) data.append([p]) # Sets for set in day['set_list']: group_exercise_marker[set['obj'].id] = {'start': len(data), 'end': len(data)} # Exercises for exercise in set['exercise_list']: group_exercise_marker[set['obj'].id]['end'] = len(data) # Note: '+1' here because there's an emtpy cell between days exercise_markers[day['obj'].id].append(len(data) + 1) # Process the settings if exercise['has_weight']: setting_out = [] for i in exercise['setting_text'].split(u'–'): setting_out.append(Paragraph(i, styleSheet["Small"], bulletText='')) else: setting_out = Paragraph(exercise['setting_text'], styleSheet["Small"]) data.append([set_count, Paragraph(exercise['obj'].name, styleSheet["Small"]), setting_out]) set_count += 1 data.append(['']) group_day_marker[day['obj'].id]['end'] = len(data) # Set the widths and heights of rows and columns # Note: 'None' is treated as 'automatic'. Either there is only one value for the whole list # or exactly one for every row/column colwidths = None rowheights = [None] * len(data) table_style = [('FONT', (0, 0), (-1, -1), 'OpenSans'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), # Note: a padding of 3 seems to be the default ('LEFTPADDING', (0, 0), (-1, -1), 2), ('RIGHTPADDING', (0, 0), (-1, -1), 2), ('TOPPADDING', (0, 0), (-1, -1), 3), ('BOTTOMPADDING', (0, 0), (-1, -1), 2), ] # Set specific styles, e.g. background for title cells for marker in day_markers: # Set background colour for headings table_style.append(('BACKGROUND', (0, marker), (-1, marker), header_colour)) table_style.append(('BOX', (0, marker), (-1, marker), 1.25, colors.black)) # Make the headings span the whole width table_style.append(('SPAN', (0, marker), (-1, marker))) # Manually set rowheights[marker - 1] = 5 # Combine the cells for exercises on the same set counter = 1 for marker in group_exercise_marker: counter += 1 start_marker = group_exercise_marker[marker]['start'] end_marker = group_exercise_marker[marker]['end'] table_style.append(('SPAN', (0, start_marker), (0, end_marker))) table_style.append(('BOX', (0, start_marker), (-1, end_marker), 0.25, colors.black)) if counter % 2: table_style.append(('BACKGROUND', (0, start_marker), (-1, end_marker), colors.lavender)) for marker in group_day_marker: start_marker = group_day_marker[marker]['start'] end_marker = group_day_marker[marker]['end'] table_style.append(('BOX', (0, start_marker), (-1, end_marker - 2), 1.25, colors.black)) # Set the table data if data: t = Table(data, colwidths, rowheights, style=table_style) # Manually set the width of the columns if len(t._argW) > 1: t._argW[0] = 0.6 * cm # Numbering t._argW[1] = 10 * cm # Exercise t._argW[2] = 2.5 * cm # Repetitions # There is nothing to output else: t = Paragraph(_('<i>This is an empty workout, what did you expect on the PDF?</i>'), styleSheet["Normal"]) # # Add all elements to the document # # Set the title (if available) if workout.comment: p = Paragraph('<para align="center"><strong>%(description)s</strong></para>' % {'description': workout.comment}, styleSheet["Bold"]) elements.append(p) # Filler elements.append(Spacer(10 * cm, 0.5 * cm)) # Append the table elements.append(t) # Footer, date and info elements.append(Spacer(10 * cm, 0.5 * cm)) created = datetime.date.today().strftime("%d.%m.%Y") p = Paragraph('''<para align="left"> %(date)s - <a href="%(url)s">%(url)s</a> - %(created)s %(version)s </para>''' % {'date': _("Created on the <b>%s</b>") % created, 'created': "wger Workout Manager", 'version': get_version(), 'url': request.build_absolute_uri(workout.get_absolute_url()), }, styleSheet["Normal"]) elements.append(p) # write the document and send the response to the browser doc.build(elements) # Create the HttpResponse object with the appropriate PDF headers. response['Content-Disposition'] = 'attachment; filename=Workout-{0}-table.pdf'.format(id) response['Content-Length'] = len(response.content) return response
def workout_log(request, id, images=False, comments=False, uidb64=None, token=None): ''' Generates a PDF with the contents of the given workout See also * http://www.blog.pythonlibrary.org/2010/09/21/reportlab * http://www.reportlab.com/apis/reportlab/dev/platypus.html ''' comments = bool(int(comments)) images = bool(int(images)) # Load 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 for item in set['exercise_list']: holder['name_of_exercise'] = item['obj'].name holder['setting_list'] = item['setting_list'] holder['comments'] = item['comment_list'] exercise_list.append(holder) 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 the appropriate PDF headers. response = HttpResponse(json_data, content_type='application/json') # Create the HttpResponse object with the appropriate PDF headers. response[ 'Content-Disposition'] = 'attachment; filename=Workout-{0}.json'.format( id) response['Content-Length'] = len(response.content) return response