initial attempt to use django restframework
[htsworkflow.git] / experiments / views.py
1 from __future__ import absolute_import, print_function, unicode_literals
2
3 # Create your views here.
4 from datetime import datetime
5 import os
6
7 #from django.template import Context, loader
8 #shortcut to the above modules
9 from django.contrib.auth.decorators import user_passes_test
10 from django.conf import settings
11 from django.core.exceptions import ObjectDoesNotExist
12 from django.core.mail import EmailMessage, mail_managers
13 from django.http import HttpResponse, Http404
14 from django.shortcuts import render_to_response, get_object_or_404
15 from django.template import RequestContext
16 from django.template.loader import get_template
17
18 from .models import DataRun, DataFile, FlowCell, Lane, Sequencer
19 from rest_framework import viewsets
20 from rest_framework.response import Response
21 from rest_framework.renderers import (TemplateHTMLRenderer,
22                                       JSONRenderer,
23                                       BrowsableAPIRenderer)
24
25 from .admin import LaneOptions
26 from .experiments import estimateFlowcellDuration, estimateFlowcellTimeRemaining, roundToDays, \
27      getUsersForFlowcell, \
28      makeEmailLaneMap
29 from .serializers import (
30     ClusterStationSerializer,
31     SequencerSerializer,
32     LaneSerializer,
33     FlowCellSerializer)
34 from samples.changelist import HTSChangeList
35 from samples.models import HTSUser
36
37
38 def index(request):
39     all_runs = DataRun.objects.order_by('-run_start_time')
40     return render_to_response('experiments/index.html',{'data_run_list': all_runs})
41
42 def detail(request, run_folder):
43     html_str = '<h2>Exp Track Details Page</h2>'
44     html_str += 'Run Folder: '+run_folder
45     r = get_object_or_404(DataRun,run_folder=run_folder)
46     return render_to_response('experiments/detail.html',{'run_f': r})
47
48 def makeFCSheet(request,fcid):
49   # get Flowcell by input fcid
50   # ...
51   rec = None
52   try:
53     rec = FlowCell.objects.get(flowcell_id=fcid)
54   except ObjectDoesNotExist:
55     pass
56   lanes = ['1','2','3','4','5','6','7','8']
57   return render_to_response('experiments/flowcellSheet.html',{'fc': rec})
58
59
60 @user_passes_test(lambda u: u.is_staff)
61 def startedEmail(request, pk):
62     """
63     Create the we have started processing your samples email
64     """
65     fc = get_object_or_404(FlowCell, id=pk)
66
67     send = request.REQUEST.get('send',False)
68     if send in ('1', 'on', 'True', 'true', True):
69         send = True
70     else:
71         send = False
72
73     bcc_managers = request.REQUEST.get('bcc', False)
74     if bcc_managers in ('on', '1', 'True', 'true'):
75         bcc_managers = True
76     else:
77         bcc_managers = False
78
79     email_lane = makeEmailLaneMap(fc)
80     flowcell_users = getUsersForFlowcell(fc)
81     estimate = estimateFlowcellTimeRemaining(fc)
82     estimate_low, estimate_high = roundToDays(estimate)
83     email_verify = get_template('experiments/email_preview.html')
84     email_template = get_template('experiments/started_email.txt')
85     sender = settings.NOTIFICATION_SENDER
86
87     warnings = []
88     emails = []
89
90     emailless_users = []
91     for user in flowcell_users:
92         # provide warning
93         if user.email is None or len(user.email) == 0:
94             warnings.append((user.admin_url(), user.username))
95     user=None
96
97     for user_email in email_lane.keys():
98         sending = ""
99         # build body
100         context = RequestContext(request,
101                                  {u'flowcell': fc,
102                                   u'lanes': email_lane[user_email],
103                                   u'runfolder': 'blank',
104                                   u'finish_low': estimate_low,
105                                   u'finish_high': estimate_high,
106                                   u'now': datetime.now(),
107                                   })
108
109         # build view
110         subject = "Flowcell %s" % ( fc.flowcell_id )
111         body = email_template.render(context)
112
113         if send:
114             email = EmailMessage(subject, body, sender, to=[user_email])
115             notified = set()
116             if bcc_managers:
117                 for manager in settings.MANAGERS:
118                     if len(manager) > 0:
119                         notified.add(manager)
120             for user in settings.NOTIFICATION_BCC:
121                 if len(user) > 0:
122                     notified.add(user)
123             email.bcc = list(notified)
124             email.send()
125
126         emails.append((user_email, subject, body, sending))
127
128     verify_context = RequestContext(
129         request,
130         { 'emails': emails,
131           'flowcell': fc,
132           'from': sender,
133           'send': send,
134           'site_managers': settings.MANAGERS,
135           'title': fc.flowcell_id,
136           'warnings': warnings,
137         })
138     return HttpResponse(email_verify.render(verify_context))
139
140 def finishedEmail(request, pk):
141     """
142     """
143     return HttpResponse("I've got nothing.")
144
145
146
147 class ClusterStationViewSet(viewsets.ReadOnlyModelViewSet):
148     renderer_classes = (TemplateHTMLRenderer,
149                         BrowsableAPIRenderer,
150                         JSONRenderer)
151     queryset = ClusterStation.objects.all()
152     serializer_class = ClusterStationSerializer
153     # template_name = 'experiments/cluster_station.html'
154
155 from pprint import pprint
156 class FlowCellViewSet(viewsets.ReadOnlyModelViewSet):
157     renderer_classes = (TemplateHTMLRenderer,
158                         BrowsableAPIRenderer,
159                         JSONRenderer)
160     queryset = FlowCell.objects.all()
161     lookup_field = 'flowcell_id'
162     serializer_class = FlowCellSerializer
163     template_name = 'experiments/flowcell_detail.html'
164
165     def retrieve(self, request, *args, **kwargs):
166         fc = get_object_or_404(self.queryset, flowcell_id = kwargs['flowcell_id'])
167         context = kwargs.copy()
168         context['request'] = request
169         serializer = FlowCellSerializer(
170             fc,
171             context=context,
172             )
173         pprint(serializer.data)
174         return Response(serializer.data)
175
176     #def retrieve(self, request, flowcell_id=None, format=None):
177     #    queryset = FlowCell.objects.all()
178     #    fc = get_object_or_404(queryset, flowcell_id=flowcell_id)
179     #    serializer = FlowCellSerializer(
180     #        fc,
181     #        context={
182     #            'request': request,
183     #            'format': format,
184     #        }
185     #    )
186     #    return Response(
187     #        serializer.data,
188     #    )
189
190     #def list(self, *args, **kwargs):
191     #    template_name = 'experiments/flowcell_index.html'
192     #    return super(FlowCellViewSet, self).list(*args, **kwargs)
193
194 class LaneViewSet(viewsets.ReadOnlyModelViewSet):
195     renderer_classes = (TemplateHTMLRenderer,
196                         BrowsableAPIRenderer,
197                         JSONRenderer)
198     queryset = Lane.objects.all()
199     serializer_class = LaneSerializer
200     template_name = 'experiments/flowcell_lane_detail.html'
201
202
203
204 class SequencerViewSet(viewsets.ReadOnlyModelViewSet):
205     renderer_classes = (TemplateHTMLRenderer,
206                         BrowsableAPIRenderer,
207                         JSONRenderer)
208     queryset = Sequencer.objects.all()
209     serializer_class = SequencerSerializer
210     template_name = 'experiments/sequencer.html'
211
212 def flowcell_detail(request, flowcell_id, lane_number=None):
213     fc = get_object_or_404(FlowCell, flowcell_id__startswith=flowcell_id)
214     fc.update_data_runs()
215
216
217     if lane_number is not None:
218         lanes = fc.lane_set.filter(lane_number=lane_number)
219     else:
220         lanes = fc.lane_set.all()
221
222     context = RequestContext(request,
223                              {'flowcell': fc,
224                               'lanes': lanes})
225
226     return render_to_response('experiments/flowcell_detail.html',
227                               context)
228
229 def flowcell_lane_detail(request, lane_pk):
230     lane = get_object_or_404(Lane, id=lane_pk)
231     lane.flowcell.update_data_runs()
232
233     dataruns = []
234     lane.flowcell.update_data_runs()
235     for run in lane.flowcell.datarun_set.all():
236         files = run.lane_files().get(lane.lane_number, None)
237         dataruns.append((run,
238                          lane.lane_number,
239                          files))
240
241     context = RequestContext(request,
242                              {'lib': lane.library,
243                               'lane': lane,
244                               'flowcell': lane.flowcell,
245                               'filtered_dataruns': dataruns})
246
247     return render_to_response('experiments/flowcell_lane_detail.html',
248                               context)
249
250 def read_result_file(self, key):
251     """Return the contents of filename if everything is approved
252     """
253     data_file = get_object_or_404(DataFile, random_key = key)
254
255     content_type = 'application/octet-stream'
256     if data_file.file_type.mimetype is not None:
257         content_type = data_file.file_type.mimetype
258
259     if os.path.exists(data_file.pathname):
260         return HttpResponse(open(data_file.pathname,'rb'),
261                             content_type=content_type)
262
263     raise Http404
264
265
266 def lanes_for(request, username=None):
267     """
268     Generate a report of recent activity for a user
269     """
270     query = {}
271     if username is not None:
272         try:
273             user = HTSUser.objects.get(username=username)
274             query.update({'library__affiliations__users__id': user.id})
275         except HTSUser.DoesNotExist as e:
276             raise Http404('User not found')
277
278     fcl = HTSChangeList(request, Lane,
279                         list_filter=['library__affiliations',
280                                      'library__library_species'],
281                         search_fields=['flowcell__flowcell_id', 'library__id', 'library__library_name'],
282                         list_per_page=200,
283                         model_admin=LaneOptions(Lane, None),
284                         extra_filters=query
285                         )
286
287     context = {'lanes': fcl, 'title': 'Lane Index'}
288
289     return render_to_response(
290         'samples/lanes_for.html',
291         context,
292         context_instance=RequestContext(request)
293     )