# Path: django_remote_submission/models.py
# class Job(TimeStampedModel):
#     """Encapsulates the information about a particular job.
# 
#     .. testsetup::
# 
#        from django_remote_submission.models import Server, Interpreter
#        from django.contrib.auth import get_user_model
#        python3 = Interpreter(name='Python 3', path='/bin/python3', arguments=['-u'])
#        server = Server(title='Remote', hostname='foo.invalid', port=22)
#        user = get_user_model()(username='john')
# 
#     >>> from django_remote_submission.models import Job
#     >>> job = Job(
#     ...     title='My Job',
#     ...     program='print("hello world")',
#     ...     remote_directory='/tmp/',
#     ...     remote_filename='foobar.py',
#     ...     owner=user,
#     ...     server=server,
#     ...     interpreter=python3,
#     ... )
#     >>> job
#     <Job: My Job>
# 
#     """
# 
#     title = models.CharField(
#         _('Job Name'),
#         help_text=_('The human-readable name of the job'),
#         max_length=250,
#     )
# 
#     uuid = models.UUIDField(
#         _('Job UUID'),
#         help_text=_('A unique identifier for use in grouping Result files'),
#         default=uuid.uuid4,
#         editable=False,
#     )
# 
#     program = models.TextField(
#         _('Job Program'),
#         help_text=_('The actual program to run (starting with a #!)'),
#     )
# 
#     STATUS = Choices(
#         ('initial', _('initial')),
#         ('submitted', _('submitted')),
#         ('success', _('success')),
#         ('failure', _('failure')),
#     )
#     status = StatusField(
#         _('Job Status'),
#         help_text=_('The current status of the program'),
#         default=STATUS.initial,
#     )
# 
#     remote_directory = models.CharField(
#         _('Job Remote Directory'),
#         help_text=_('The directory on the remote host to store the program'),
#         max_length=250,
#     )
# 
#     remote_filename = models.CharField(
#         _('Job Remote Filename'),
#         help_text=_('The filename to store the program to (e.g. reduce.py)'),
#         max_length=250,
#     )
# 
#     owner = models.ForeignKey(
#         settings.AUTH_USER_MODEL,
#         models.PROTECT,
#         related_name='jobs',
#         verbose_name=_('Job Owner'),
#         help_text=_('The user that owns this job'),
#     )
# 
#     server = models.ForeignKey(
#         'Server',
#         models.PROTECT,
#         related_name='jobs',
#         verbose_name=_('Job Server'),
#         help_text=_('The server that this job will run on'),
#     )
# 
#     interpreter = models.ForeignKey(
#         Interpreter,
#         models.PROTECT,
#         related_name='jobs',
#         verbose_name=_('Job Interpreter'),
#         help_text=_('The interpreter that this job will run on'),
#     )
# 
#     class Meta:  # noqa: D101
#         verbose_name = _('job')
#         verbose_name_plural = _('jobs')
# 
#     def __str__(self):
#         """Convert model to string, e.g. ``"My Job"``."""
#         return '{self.title}'.format(self=self)
# 
#     def clean(self):
#         """Ensure that the selected interpreter exists on the server.
# 
#         To use effectively, add this to the
#         :func:`django.db.models.signals.pre_save` signal for the :class:`Job`
#         model.
# 
#         """
#         available_interpreters = self.server.interpreters.all()
#         if self.interpreter not in available_interpreters:
#             raise ValidationError(_('The Interpreter picked is not valid for this server. '))
#             #'Please, choose one from: {0!s}.').format(available_interpreters))
#         else:
#             cleaned_data = super(Job, self).clean()
#             return cleaned_data
# 
#     # def save(self, *args, **kwargs):
#     #     '''
#     #     From Two scoops of django: "Use signals as a last resort."
#     #     '''
# 
#     #     super().save(*args, **kwargs)
#     #     # Post save
# 
#     #     import channels.layers
#     #     from asgiref.sync import async_to_sync
# 
#     #     def send_message(event):
#     #         message = event['text']
#     #         channel_layer = channels.layers.get_channel_layer()
#     #         # Send message to WebSocket
#     #         async_to_sync(channel_layer.send)(text_data=json.dumps(
#     #             message
#     #         ))
# 
#     #     user = self.owner
#     #     group_name = 'job-user-{}'.format(user.username)
# 
#     #     message = {
#     #         'job_id': self.id,
#     #         'title': self.title,
#     #         'status': self.status,
#     #         'modified': self.modified.isoformat(),
#     #     }
# 
#     #     channel_layer = channels.layers.get_channel_layer()
# 
#     #     async_to_sync(channel_layer.group_send)(
#     #         group_name,
#     #         {
#     #             'type': 'send_message',
#     #             'text': message
#     #         }
#     #     )


import json
from channels.generic.websocket import AsyncWebsocketConsumer
from .models import Job
        ))


class JobLogConsumer(AsyncWebsocketConsumer):

    async def connect(self):
        '''
        Creates group, add to the valid channels
        Connects and sends to the browser the log
        '''
        job_pk = self.scope['url_route']['kwargs']['job_pk']
        self.group_name = 'job-log-{}'.format(job_pk)

        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )

        await self.accept()
        await self.send_log(job_pk)

    async def disconnect(self, close_code):

        await self.channel_layer.group_discard(
            self.group_name,
            self.channel_name
        )

    async def send_log(self, job_pk):


# Path: django_remote_submission/models.py
# class Job(TimeStampedModel):
#     """Encapsulates the information about a particular job.
# 
#     .. testsetup::
# 
#        from django_remote_submission.models import Server, Interpreter
#        from django.contrib.auth import get_user_model
#        python3 = Interpreter(name='Python 3', path='/bin/python3', arguments=['-u'])
#        server = Server(title='Remote', hostname='foo.invalid', port=22)
#        user = get_user_model()(username='john')
# 
#     >>> from django_remote_submission.models import Job
#     >>> job = Job(
#     ...     title='My Job',
#     ...     program='print("hello world")',
#     ...     remote_directory='/tmp/',
#     ...     remote_filename='foobar.py',
#     ...     owner=user,
#     ...     server=server,
#     ...     interpreter=python3,
#     ... )
#     >>> job
#     <Job: My Job>
# 
#     """
# 
#     title = models.CharField(
#         _('Job Name'),
#         help_text=_('The human-readable name of the job'),
#         max_length=250,
#     )
# 
#     uuid = models.UUIDField(
#         _('Job UUID'),
#         help_text=_('A unique identifier for use in grouping Result files'),
#         default=uuid.uuid4,
#         editable=False,
#     )
# 
#     program = models.TextField(
#         _('Job Program'),
#         help_text=_('The actual program to run (starting with a #!)'),
#     )
# 
#     STATUS = Choices(
#         ('initial', _('initial')),
#         ('submitted', _('submitted')),
#         ('success', _('success')),
#         ('failure', _('failure')),
#     )
#     status = StatusField(
#         _('Job Status'),
#         help_text=_('The current status of the program'),
#         default=STATUS.initial,
#     )
# 
#     remote_directory = models.CharField(
#         _('Job Remote Directory'),
#         help_text=_('The directory on the remote host to store the program'),
#         max_length=250,
#     )
# 
#     remote_filename = models.CharField(
#         _('Job Remote Filename'),
#         help_text=_('The filename to store the program to (e.g. reduce.py)'),
#         max_length=250,
#     )
# 
#     owner = models.ForeignKey(
#         settings.AUTH_USER_MODEL,
#         models.PROTECT,
#         related_name='jobs',
#         verbose_name=_('Job Owner'),
#         help_text=_('The user that owns this job'),
#     )
# 
#     server = models.ForeignKey(
#         'Server',
#         models.PROTECT,
#         related_name='jobs',
#         verbose_name=_('Job Server'),
#         help_text=_('The server that this job will run on'),
#     )
# 
#     interpreter = models.ForeignKey(
#         Interpreter,
#         models.PROTECT,
#         related_name='jobs',
#         verbose_name=_('Job Interpreter'),
#         help_text=_('The interpreter that this job will run on'),
#     )
# 
#     class Meta:  # noqa: D101
#         verbose_name = _('job')
#         verbose_name_plural = _('jobs')
# 
#     def __str__(self):
#         """Convert model to string, e.g. ``"My Job"``."""
#         return '{self.title}'.format(self=self)
# 
#     def clean(self):
#         """Ensure that the selected interpreter exists on the server.
# 
#         To use effectively, add this to the
#         :func:`django.db.models.signals.pre_save` signal for the :class:`Job`
#         model.
# 
#         """
#         available_interpreters = self.server.interpreters.all()
#         if self.interpreter not in available_interpreters:
#             raise ValidationError(_('The Interpreter picked is not valid for this server. '))
#             #'Please, choose one from: {0!s}.').format(available_interpreters))
#         else:
#             cleaned_data = super(Job, self).clean()
#             return cleaned_data
# 
#     # def save(self, *args, **kwargs):
#     #     '''
#     #     From Two scoops of django: "Use signals as a last resort."
#     #     '''
# 
#     #     super().save(*args, **kwargs)
#     #     # Post save
# 
#     #     import channels.layers
#     #     from asgiref.sync import async_to_sync
# 
#     #     def send_message(event):
#     #         message = event['text']
#     #         channel_layer = channels.layers.get_channel_layer()
#     #         # Send message to WebSocket
#     #         async_to_sync(channel_layer.send)(text_data=json.dumps(
#     #             message
#     #         ))
# 
#     #     user = self.owner
#     #     group_name = 'job-user-{}'.format(user.username)
# 
#     #     message = {
#     #         'job_id': self.id,
#     #         'title': self.title,
#     #         'status': self.status,
#     #         'modified': self.modified.isoformat(),
#     #     }
# 
#     #     channel_layer = channels.layers.get_channel_layer()
# 
#     #     async_to_sync(channel_layer.group_send)(
#     #         group_name,
#     #         {
#     #             'type': 'send_message',
#     #             'text': message
#     #         }
#     #     )


# Path: django_remote_submission/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from .models import Job

        ))


class JobLogConsumer(AsyncWebsocketConsumer):

    async def connect(self):
        '''
        Creates group, add to the valid channels
        Connects and sends to the browser the log
        '''
        job_pk = self.scope['url_route']['kwargs']['job_pk']
        self.group_name = 'job-log-{}'.format(job_pk)

        await self.channel_layer.group_add(
            self.group_name,
            self.channel_name
        )

        await self.accept()
        await self.send_log(job_pk)

    async def disconnect(self, close_code):

        await self.channel_layer.group_discard(
            self.group_name,
            self.channel_name
        )

    async def send_log(self, job_pk):


        job = Job.objects.get(pk=job_pk)