1 from django.http import HttpResponse, HttpResponseRedirect
2 from samplebc.samples import models
3 from django.core.exceptions import ObjectDoesNotExist
4 from django.template import Context, Template, RequestContext
5 from django.template.loader import get_template
6 from django.shortcuts import render_to_response
7 from django.contrib.auth.decorators import login_required
9 from django.utils.safestring import mark_safe
11 from samplebc.samples.forms import FreezerForm, ContainerForm, SampleForm, CmdMoveSampleForm
12 from samplebc.samples.models import Freezer, Container, Sample
13 from samplebc.samples.util import get_uuid, get_sampleid, assign_to_container
14 from samplebc.samples.errors import NoSpaceAvaliable
15 from samplebc import settings
18 from samplebc.bcmagic.forms import BarcodeMagicForm
21 from reversion import revision
28 ################################################
30 ################################################
32 def print_zpl(zpl_text):
34 Sends zpl_text to printer
36 ftp = ftplib.FTP(host='131.215.54.194', user='blank', passwd='')
38 ftp.storlines("STOR printme.txt", StringIO.StringIO(zpl_text))
42 def __center_line(line, width):
43 spaces_to_add = width - len(line)
45 front_half = spaces_to_add / 2
46 back_half = spaces_to_add - front_half
48 return (' ' * front_half) + line + (' ' * back_half)
53 ################################################
55 ################################################
57 def container_index(request):
59 Returns an index of available to containers
61 container_list = Container.objects.all()
62 c = Context({'title': 'Container Index',
63 'container_list': container_list})
64 t = get_template('container_index.html')
66 return render_to_response('app.html', {
67 'app_name': "HTSW-SampleTracker",
68 'page_name': 'Container Index',
69 'bcmagic': BarcodeMagicForm(),
70 'select': 'container',
73 context_instance=RequestContext(request))
78 def container_summary(request, container_id, msg=None):
80 Returns details of a container
82 # Retrieve container by UUID
84 container = models.Container.objects.get(uuid=container_id)
85 except ObjectDoesNotExist, e:
86 msg = "Container (%s) does not exist." % (container_id)
87 return render_to_response('app.html', {
88 'app_name': settings.HTSW_ST_APPNAME,
89 'page_name': 'Container Summary',
91 'bcmagic': BarcodeMagicForm(),
92 'select': 'container',
95 context_instance=RequestContext(request))
97 # Retrieve samples from container
98 sample_list = container.sample_set.all()
100 # Prepare a Sample Index of Contained Samples
101 cs = Context({'title': 'Contained Samples',
102 'sample_list': sample_list})
103 ts = get_template('sample_index.html')
105 # Render prepared samples into container summary
106 cc = Context({'container': container,
108 'rendered_samples': ts.render(cs) })
109 tc = get_template('container_summary.html')
111 # Render container summary to app html
112 return render_to_response('app.html', {
113 'app_name': settings.HTSW_ST_APPNAME,
114 'page_name': 'Container Summary',
116 'bcmagic': BarcodeMagicForm(),
117 'select': 'container',
118 'body': tc.render(cc)
120 context_instance=RequestContext(request))
123 @revision.create_on_success
124 def container_add(request):
126 Form for adding a container.
130 revision.comment = "New container created by user."
132 # If user submitted the Container form.
133 if request.method == 'POST':
134 # Fill in ContainerForm with POSTed data.
135 form = ContainerForm(request.POST)
137 # If the form is valid, process it.
139 # Create new Container object from form data
140 c_obj = form.save(commit=False)
142 c_obj.uuid = get_uuid()
145 # Save the many to many link data.
147 return container_summary(request, c_obj.uuid)
149 # If users first visit, create empty form.
150 form = ContainerForm()
153 c = Context({'form': form,
154 'action_url': '/samples/container/add/'})
155 t = get_template('generic_form.html')
157 return render_to_response('app.html', {
158 'app_name': settings.HTSW_ST_APPNAME,
159 'page_name': 'Container Add',
161 'bcmagic': BarcodeMagicForm(),
162 'select': 'container',
165 context_instance=RequestContext(request))
168 @revision.create_on_success
169 def container_edit(request, container_id):
171 Allow editing of a container
174 revision.comment = "Manual container edit by user."
177 container = models.Container.objects.get(uuid=container_id)
178 except ObjectDoesNotExist, e:
179 msg = "Container (%s) cannot be edited as it does not exist." % (container_id)
180 return render_to_response('app.html', {
181 'app_name': settings.HTSW_ST_APPNAME,
182 'page_name': 'Container Edit',
184 'bcmagic': BarcodeMagicForm(),
185 'select': 'container',
188 context_instance=RequestContext(request))
190 # If user submitted the container form.
191 if request.method == 'POST':
192 # Fill in ContainerForm with POSTed data.
193 form = ContainerForm(request.POST, instance=container)
195 # If the form is valid, process it.
197 # Save Container object from form data
198 c_obj = form.save(commit=True)
199 # Save many2many changes as well
200 #form.save_m2m() #Not needed when form.save(commit=True)
202 return container_summary(request, c_obj.uuid)
204 # If users first visit, create form from Container instance.
205 form = ContainerForm(instance=container)
208 c = Context({'form': form,
209 'action_url': '%sedit/' % (container.get_absolute_url())})
210 t = get_template('generic_form.html')
212 return render_to_response('app.html', {
213 'app_name': settings.HTSW_ST_APPNAME,
214 'page_name': 'Container Edit',
216 'bcmagic': BarcodeMagicForm(),
217 'select': 'container',
220 context_instance=RequestContext(request))
223 def container_print(request, container_id):
225 prints a container label
229 container = models.Container.objects.get(uuid=container_id)
230 except ObjectDoesNotExist:
231 return HttpResponse('Container (%s) does not exist!' % (container_id))
234 params['container_name'] = __center_line(container.name[0:17], 17)
235 params['line1'] = __center_line('%s' % (container.name[17:34]), 17)
236 params['line2'] = __center_line('%s' % (container.name[34:51]), 17)
237 params['line3'] = __center_line('%s' % (container.name[51:68]), 17)
238 params['line4'] = __center_line('%s' % (container.name[68:85]), 17)
239 params['barcode'] = 'cntr|%s' % (container.uuid)
240 params['symbol'] = ''
242 c = RequestContext(request, params)
243 t = get_template('zpl_container_label.txt')
244 print_zpl(t.render(c))
246 return container_summary(request, container_id, msg='print command for container %s sent.' % (container.uuid))
249 ################################################
251 ################################################
253 def freezer_index(request):
255 Returns an index of available freezers
257 freezer_list = Freezer.objects.all()
258 c = Context({'freezer_list': freezer_list})
259 t = get_template('freezer_index.html')
261 return render_to_response('app.html', {
262 'app_name': "HTSW-SampleTracker",
263 'page_name': 'Freezer Index',
265 'bcmagic': BarcodeMagicForm(),
269 context_instance=RequestContext(request))
272 def freezer_summary(request, freezer_id, msg=None):
274 Returns summary of freezer_id
276 # Retrieve freezer by UUID
278 freezer = models.Freezer.objects.get(uuid=freezer_id)
279 except ObjectDoesNotExist, e:
280 msg = "Freezer (%s) does not exist." % (freezer_id)
281 return render_to_response('app.html', {
282 'app_name': settings.HTSW_ST_APPNAME,
283 'page_name': 'Freezer Summary',
285 'bcmagic': BarcodeMagicForm(),
289 context_instance=RequestContext(request))
291 # List of contained containers
292 container_list = freezer.container_set.all()
295 # Render prepared container index into freezer summary
296 cf = Context({'freezer': freezer,
298 tf = get_template('freezer_summary.html')
300 # Render Freezer summary to app html
301 return render_to_response('app.html', {
302 'app_name': settings.HTSW_ST_APPNAME,
303 'page_name': 'Freezer Summary',
305 'bcmagic': BarcodeMagicForm(),
307 'body': tf.render(cf)
309 context_instance=RequestContext(request))
312 @revision.create_on_success
313 def freezer_add(request):
315 Allows you to add a new freezer.
318 revision.comment = "New freezer created by user."
320 # If user submitted the freezer form.
321 if request.method == 'POST':
322 # Fill in FreezerForm with POSTed data.
323 form = FreezerForm(request.POST)
325 # If the form is valid, process it.
327 # Create new Freezer object from form data
328 f_obj = form.save(commit=False)
330 f_obj.uuid = get_uuid()
333 return freezer_summary(request, f_obj.uuid)
335 # If users first visit, create empty form.
339 c = Context({'form': form,
340 'action_url': '/samples/freezer/add/'})
341 t = get_template('generic_form.html')
343 return render_to_response('app.html', {
344 'app_name': settings.HTSW_ST_APPNAME,
345 'page_name': 'Freezer Add',
347 'bcmagic': BarcodeMagicForm(),
351 context_instance=RequestContext(request))
354 @revision.create_on_success
355 def freezer_edit(request, freezer_id):
357 Allow editing of a freezer
360 revision.comment = "Manual freezer edit by user."
363 freezer = models.Freezer.objects.get(uuid=freezer_id)
364 except ObjectDoesNotExist, e:
365 msg = "Freezer (%s) cannot be edited as it does not exist." % (freezer_id)
366 return render_to_response('app.html', {
367 'app_name': settings.HTSW_ST_APPNAME,
368 'page_name': 'Freezer Summary',
370 'bcmagic': BarcodeMagicForm(),
374 context_instance=RequestContext(request))
376 # If user submitted the freezer form.
377 if request.method == 'POST':
378 # Fill in FreezerForm with POSTed data.
379 form = FreezerForm(request.POST, instance=freezer)
381 # If the form is valid, process it.
383 # Save Freezer object from form data
384 f_obj = form.save(commit=True)
386 return freezer_summary(request, f_obj.uuid)
388 # If users first visit, create form from freezer instance.
389 form = FreezerForm(instance=freezer)
392 c = Context({'form': form,
393 'action_url': '%sedit/' % (freezer.get_absolute_url())})
394 t = get_template('generic_form.html')
396 return render_to_response('app.html', {
397 'app_name': settings.HTSW_ST_APPNAME,
398 'page_name': 'Freezer Edit',
400 'bcmagic': BarcodeMagicForm(),
404 context_instance=RequestContext(request))
407 def freezer_print(request, freezer_id):
409 prints a freezer label
413 freezer = models.Freezer.objects.get(uuid=freezer_id)
414 except ObjectDoesNotExist:
415 return HttpResponse('Freezer (%s) does not exist!' % (freezer_id))
418 params['freezer_name'] = __center_line(freezer.name, 17)
419 params['line1'] = __center_line('%s' % (freezer.name[17:34]), 17)
420 params['line2'] = __center_line('%s' % (freezer.name[34:51]), 17)
421 params['line3'] = __center_line('%s' % (freezer.name[51:68]), 17)
422 params['line4'] = __center_line('Temp: %s C' % (freezer.temperature), 17)
423 params['barcode'] = 'frzr|%s' % (freezer.uuid)
424 params['symbol'] = ''
426 c = RequestContext(request, params)
427 t = get_template('zpl_freezer_label.txt')
428 print_zpl(t.render(c))
430 return freezer_summary(request, freezer_id, msg='print command for freezer %s sent.' % (freezer.uuid))
433 ################################################
435 ################################################
437 def sample_index(request):
439 return a list of samples and what we can do with them.
441 sample_list = models.Sample.objects.all()
444 c = Context({'title': 'Sample Index',
445 'sample_list': sample_list})
446 t = get_template('sample_index.html')
447 #html.append('%s <a href="/samples/sample/%s/print">(print)</a>' \
448 # % (sample, sample.sampleid))
450 return render_to_response('app.html', {
451 'app_name': settings.HTSW_ST_APPNAME,
452 'page_name': 'Samples Index',
454 'bcmagic': BarcodeMagicForm(),
458 context_instance=RequestContext(request))
461 def sample_homeless(request):
463 Returns an index of homeless samples
465 sample_list = Sample.objects.filter(container=None)
466 c = Context({'title': 'Homeless Samples',
467 'sample_list': sample_list})
468 t = get_template('sample_homeless.html')
470 return render_to_response('app.html', {
471 'app_name': "HTSW-SampleTracker",
472 'page_name': 'Homeless Samples',
473 'bcmagic': BarcodeMagicForm(),
477 context_instance=RequestContext(request))
480 @revision.create_on_success
481 def sample_add(request):
483 Allow adding of a new sample
486 revision.comment = "New sample created by user."
488 ASSIGNED_CONTAINER = False
490 # If user submitted the sample form.
491 if request.method == 'POST':
492 # Fill in SampleForm with POSTed data.
493 form = SampleForm(request.POST)
495 # If the form is valid, process it.
497 # Create new Sample object from form data
498 s_obj = form.save(commit=False)
501 s_obj.sampleid = get_sampleid()
503 # If the user wants us to assign a container.
504 if form.cleaned_data['assign_container']:
507 assign_to_container(s_obj)
508 ASSIGNED_CONTAINER = True
509 except NoSpaceAvaliable, e:
510 #return HttpResponse("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
512 ASSIGNED_CONTAINER = False
517 if not ASSIGNED_CONTAINER:
518 msg = "NOTE: Sample is homeless"
519 return sample_summary(request, s_obj.sampleid, msg=msg)
522 msg = "Sample created."
523 return sample_summary(request, s_obj.sampleid, msg=msg)
525 # If users first visit, create empty form.
529 c = Context({'form': form,
530 'action_url': '/samples/sample/add/'})
531 t = get_template('generic_form.html')
533 return render_to_response('app.html', {
534 'app_name': settings.HTSW_ST_APPNAME,
535 'page_name': 'Sample Add',
537 'bcmagic': BarcodeMagicForm(),
541 context_instance=RequestContext(request))
544 @revision.create_on_success
545 def sample_edit(request, sampleid):
547 Allow editing of a sample
550 revision.comment = "Manual sample edit by user."
553 sample = models.Sample.objects.get(sampleid=sampleid)
554 except ObjectDoesNotExist, e:
555 msg = "Sample (%s) cannot be edited as it does not exist." % (sampleid)
556 return render_to_response('app.html', {
557 'app_name': settings.HTSW_ST_APPNAME,
558 'page_name': 'Sample Edit',
560 'bcmagic': BarcodeMagicForm(),
565 # If user submitted the sample form.
566 if request.method == 'POST':
567 # Fill in SampleForm with POSTed data.
568 form = SampleForm(request.POST, instance=sample)
570 # If the form is valid, process it.
572 # Save Sample object from form data
573 s_obj = form.save(commit=True)
575 msg = "Sample Update Saved"
576 return sample_summary(request, s_obj.sampleid, msg)
578 # If users first visit, create form from sample instance.
579 form = SampleForm(instance=sample)
582 c = Context({'form': form,
583 'action_url': '%sedit/' % (sample.get_absolute_url())})
584 t = get_template('generic_form.html')
586 return render_to_response('app.html', {
587 'app_name': settings.HTSW_ST_APPNAME,
588 'page_name': 'Sample Edit',
590 'bcmagic': BarcodeMagicForm(),
594 context_instance=RequestContext(request))
597 @revision.create_on_success
598 def sample_assign_container(request, sampleid):
600 Assigns sample to container using the assign to container algorithm
603 sample = Sample.objects.get(sampleid=sampleid)
606 assign_to_container(sample)
607 except NoSpaceAvaliable, e:
608 return render_to_response('app.html', {
609 'app_name': settings.HTSW_ST_APPNAME,
610 'page_name': 'Sample Assign',
612 'bcmagic': BarcodeMagicForm(),
614 'body': mark_safe("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
617 context_instance=RequestContext(request))
621 body = 'Sample (<a href="%s">%s</a>) assigned to container (<a href="%s">%s</a>)' \
622 % (sample.get_absolute_url(), str(sample), sample.container.get_absolute_url(), str(sample.container))
625 revision.comment = "Sample auto-assigned to container (%s: %s)" % (str(sample.container), sample.container.uuid)
627 return render_to_response('app.html', {
628 'app_name': settings.HTSW_ST_APPNAME,
629 'page_name': 'Sample Assign',
631 'bcmagic': BarcodeMagicForm(),
633 'body': mark_safe(body),
635 context_instance=RequestContext(request))
638 def sample_summary(request, sampleid, msg=None):
640 Display a summary of a given sample
643 sample = models.Sample.objects.get(sampleid=sampleid)
644 except ObjectDoesNotExist, e:
645 msg = "Sample (%s) does not exist." % (sampleid)
646 return render_to_response('app.html', {
647 'app_name': settings.HTSW_ST_APPNAME,
648 'page_name': 'Sample Summary',
650 'bcmagic': BarcodeMagicForm(),
654 context_instance=RequestContext(request))
656 c = Context({'sample': sample,
658 t = get_template('sample_summary.html')
660 return render_to_response('app.html', {
661 'app_name': settings.HTSW_ST_APPNAME,
662 'page_name': 'Sample Summary',
664 'bcmagic': BarcodeMagicForm(),
668 context_instance=RequestContext(request))
671 def sample_print(request, sampleid):
677 sample = models.Sample.objects.get(sampleid=sampleid)
678 except ObjectDoesNotExist:
679 return HttpResponse('Sample (%s) does not exist!' % (sampleid))
682 params['fullid'] = str(sample)
683 params['sampleid'] = __center_line("s|%s" % (sample.sampleid), 16)
684 params['line1'] = __center_line(sample.name[0:10], 10)
685 params['line2'] = __center_line(sample.name[10:25], 14)
686 params['line3'] = __center_line('ExpType %s' % (sample.sample_type.name[0:8]), 15)
687 params['slot_num'] = random.randint(1,81)
689 c = RequestContext(request, params)
690 t = get_template('half_inch_samples.txt')
691 print_zpl(t.render(c))
693 return sample_summary(request, sampleid, msg='print command for sample %s sent.' % (sample.sampleid))
696 def user_profile(request):
698 Information about the user
700 return render_to_response('registration/profile.html', {
701 'app_name': settings.HTSW_ST_APPNAME,
702 'page_name': 'User Profile',
704 'bcmagic': BarcodeMagicForm(),
705 'select': 'settings',
707 context_instance=RequestContext(request))
709 ################################################
710 # Barcode Magic Commands
711 ################################################
713 def __cmd_move_sample_return(form, request, msg=''):
715 A small helper function since this code is reused multiple times
718 c = Context({'form': form,
720 t = get_template('generic_form.html')
722 return render_to_response('app.html', {
723 'app_name': settings.HTSW_ST_APPNAME,
724 'page_name': 'CMD: Move Sample',
726 'bcmagic': BarcodeMagicForm({'bcm_mode': 'cmd_move_sample'}),
731 context_instance=RequestContext(request))
734 @revision.create_on_success
735 def cmd_move_sample(request):
737 Moves a sample to a target container
739 form = CmdMoveSampleForm()
741 if request.method == 'POST':
742 form = CmdMoveSampleForm(request.POST)
744 #If for some reason the form is not valid, return
745 if not form.is_valid():
746 msg = "Form is not valid."
747 return __cmd_move_sample_return(form, request, msg)
750 sample = models.Sample.objects.get(sampleid=form.cleaned_data['sampleid'])
751 except ObjectDoesNotExist, e:
752 msg = "Sample %s does not exist." % (form.cleaned_data['sampleid'])
753 return __cmd_move_sample_return(form, request, msg)
756 container = models.Container.objects.get(uuid=form.cleaned_data['container_id'])
757 except ObjectDoesNotExist, e:
758 msg = "Container %s does not exist." % (form.cleaned_data['container_id'])
759 return __cmd_move_sample_return(form, request, msg)
761 # Move the sample to the new container
762 old_container = sample.container
763 sample.container = container
764 if old_container is None:
765 revision.comment = "Sample (%s) moved from Homeless to Container(%s; uuid: %s)" \
766 % (str(sample), str(container), container.uuid)
768 revision.comment = "Sample (%s) moved from Container(%s; uuid: %s) to Container(%s; uuid: %s)" \
769 % (str(sample), str(old_container), old_container.uuid, str(container), container.uuid)
772 return __cmd_move_sample_return(CmdMoveSampleForm(), request, revision.comment)
774 return __cmd_move_sample_return(form, request)