# Kod źródłowy modułu exercises.views

    from django.urls.base import reverse_lazy
    from django.views.generic.detail import DetailView
    from tasks.constants import NotificationsData, NotificationType
    from tasks.models import ExerciseTaskPosition
    from users.decorators import apprentice_login_required
    from utils.general import progress_percent

    class NotificationContent(object):
        def __init__(self, title='', description='', button_txt='', button_control_css_class='', button_href='',
                     button_extra_arg='', **kwargs):
            self.title = title
            self.description = description
            self.button_text = button_txt
            self.button_control_css_class = button_control_css_class
            self.button_href = button_href
            self.button_extra_arg = button_extra_arg

        @classmethod
        def from_type(cls, notification_type):
            notification_data_dict = NotificationsData.NOTIFICATION_DATA.get(notification_type)
            if notification_data_dict:
                return cls(**notification_data_dict)
            return cls()

    @apprentice_login_required
    class ExerciseDetailView(DetailView):
        """Widok reprezentujący wybrane ćwiczenie"""
        template_name = 'exercises/exercise.html'
        pk_url_kwarg = 'exercise_task_position_id'
        context_object_name = 'selected_exercise_task_position'

        def get_queryset(self):
            return ExerciseTaskPosition.objects.active()

        def get_context_data(self, **kwargs):
            context = super(ExerciseDetailView, self).get_context_data(**kwargs)
            task_all_exercises_count = self.object.task.all_exercises_count()
            task_done_exercises_count = self.object.task.done_exercises_count(self.request.user)
            context['exercises_progress'] = progress_percent(task_done_exercises_count, task_all_exercises_count)

            if task_all_exercises_count == task_done_exercises_count:
                context['all_done'] = True
            done = True if self.request.user in self.object.exercise.apprentices.all() else False
            context['done'] = done

            todo_notification_content = NotificationContent.from_type(NotificationType.EXERCISE_TODO)
            done_notification_content = NotificationContent.from_type(NotificationType.EXERCISE_DONE)
            done_all_notification_content = NotificationContent.from_type(NotificationType.EXERCISE_DONE_ALL)
            todo_notification_content.description = todo_notification_content.description.format(task_done_exercises_count,
                                                                                                 task_all_exercises_count)
            todo_notification_content.button_extra_arg = self.object.id
            done_notification_content.description = done_notification_content.description.format(
                task_done_exercises_count + (0 if done else 1), task_all_exercises_count)
            done_all_notification_content.button_href = reverse_lazy('tasks:task-detail',
                                                                     kwargs={'task_slug': self.object.task.slug,
                                                                             'task_id': self.object.task.id})
            context['todo_notification_context'] = todo_notification_content
            context['done_notification_context'] = done_notification_content
            context['done_all_notification_context'] = done_all_notification_content

            return context