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))
41 def __center_line(line, width):
42 spaces_to_add = width - len(line)
44 front_half = spaces_to_add / 2
45 back_half = spaces_to_add - front_half
47 return (' ' * front_half) + line + (' ' * back_half)
52 ################################################
54 ################################################
56 def container_index(request):
58 Returns an index of available to containers
60 container_list = Container.objects.all()
61 c = Context({'title': 'Container Index',
62 'container_list': container_list})
63 t = get_template('container_index.html')
65 return render_to_response('app.html', {
66 'app_name': "HTSW-SampleTracker",
67 'page_name': 'Container Index',
68 'bcmagic': BarcodeMagicForm(),
69 'select': 'container',
72 context_instance=RequestContext(request))
77 def container_summary(request, container_id):
79 Returns details of a container
81 # Retrieve container by UUID
83 container = models.Container.objects.get(uuid=container_id)
84 except ObjectDoesNotExist, e:
85 msg = "Container (%s) does not exist." % (container_id)
86 return render_to_response('app.html', {
87 'app_name': settings.HTSW_ST_APPNAME,
88 'page_name': 'Container Summary',
90 'bcmagic': BarcodeMagicForm(),
91 'select': 'container',
94 context_instance=RequestContext(request))
96 # Retrieve samples from container
97 sample_list = container.sample_set.all()
99 # Prepare a Sample Index of Contained Samples
100 cs = Context({'title': 'Contained Samples',
101 'sample_list': sample_list})
102 ts = get_template('sample_index.html')
104 # Render prepared samples into container summary
105 cc = Context({'container': container,
106 'rendered_samples': ts.render(cs) })
107 tc = get_template('container_summary.html')
109 # Render container summary to app html
110 return render_to_response('app.html', {
111 'app_name': settings.HTSW_ST_APPNAME,
112 'page_name': 'Container Summary',
114 'bcmagic': BarcodeMagicForm(),
115 'select': 'container',
116 'body': tc.render(cc)
118 context_instance=RequestContext(request))
121 @revision.create_on_success
122 def container_add(request):
124 Form for adding a container.
128 revision.comment = "New container created by user."
130 # If user submitted the Container form.
131 if request.method == 'POST':
132 # Fill in ContainerForm with POSTed data.
133 form = ContainerForm(request.POST)
135 # If the form is valid, process it.
137 # Create new Container object from form data
138 c_obj = form.save(commit=False)
140 c_obj.uuid = get_uuid()
143 # Save the many to many link data.
145 return container_summary(request, c_obj.uuid)
147 # If users first visit, create empty form.
148 form = ContainerForm()
151 c = Context({'form': form,
152 'action_url': '/samples/container/add/'})
153 t = get_template('generic_form.html')
155 return render_to_response('app.html', {
156 'app_name': settings.HTSW_ST_APPNAME,
157 'page_name': 'Container Add',
159 'bcmagic': BarcodeMagicForm(),
160 'select': 'container',
163 context_instance=RequestContext(request))
166 @revision.create_on_success
167 def container_edit(request, container_id):
169 Allow editing of a container
172 revision.comment = "Manual container edit by user."
175 container = models.Container.objects.get(uuid=container_id)
176 except ObjectDoesNotExist, e:
177 msg = "Container (%s) cannot be edited as it does not exist." % (container_id)
178 return render_to_response('app.html', {
179 'app_name': settings.HTSW_ST_APPNAME,
180 'page_name': 'Container Edit',
182 'bcmagic': BarcodeMagicForm(),
183 'select': 'container',
186 context_instance=RequestContext(request))
188 # If user submitted the container form.
189 if request.method == 'POST':
190 # Fill in ContainerForm with POSTed data.
191 form = ContainerForm(request.POST, instance=container)
193 # If the form is valid, process it.
195 # Save Container object from form data
196 c_obj = form.save(commit=True)
197 # Save many2many changes as well
198 #form.save_m2m() #Not needed when form.save(commit=True)
200 return container_summary(request, c_obj.uuid)
202 # If users first visit, create form from Container instance.
203 form = ContainerForm(instance=container)
206 c = Context({'form': form,
207 'action_url': '%sedit/' % (container.get_absolute_url())})
208 t = get_template('generic_form.html')
210 return render_to_response('app.html', {
211 'app_name': settings.HTSW_ST_APPNAME,
212 'page_name': 'Container Edit',
214 'bcmagic': BarcodeMagicForm(),
215 'select': 'container',
218 context_instance=RequestContext(request))
221 def container_print(request, container_id):
223 prints a container label
227 container = models.Container.objects.get(uuid=container_id)
228 except ObjectDoesNotExist:
229 return HttpResponse('Container (%s) does not exist!' % (container_id))
232 params['container_name'] = __center_line(container.name[0:17], 17)
233 params['line1'] = __center_line('%s' % (container.name[17:34]), 17)
234 params['line2'] = __center_line('%s' % (container.name[34:51]), 17)
235 params['line3'] = __center_line('%s' % (container.name[51:68]), 17)
236 params['line4'] = __center_line('%s' % (container.name[68:85]), 17)
237 params['barcode'] = 'cntr|%s' % (container.uuid)
238 params['symbol'] = ''
240 c = RequestContext(request, params)
241 t = get_template('zpl_container_label.txt')
242 print_zpl(t.render(c))
244 return HttpResponse('print command for container %s sent.' % (container.uuid))
247 ################################################
249 ################################################
251 def freezer_index(request):
253 Returns an index of available freezers
255 freezer_list = Freezer.objects.all()
256 c = Context({'freezer_list': freezer_list})
257 t = get_template('freezer_index.html')
259 return render_to_response('app.html', {
260 'app_name': "HTSW-SampleTracker",
261 'page_name': 'Freezer Index',
263 'bcmagic': BarcodeMagicForm(),
267 context_instance=RequestContext(request))
270 def freezer_summary(request, freezer_id):
272 Returns summary of freezer_id
274 # Retrieve freezer by UUID
276 freezer = models.Freezer.objects.get(uuid=freezer_id)
277 except ObjectDoesNotExist, e:
278 msg = "Freezer (%s) does not exist." % (freezer_id)
279 return render_to_response('app.html', {
280 'app_name': settings.HTSW_ST_APPNAME,
281 'page_name': 'Freezer Summary',
283 'bcmagic': BarcodeMagicForm(),
287 context_instance=RequestContext(request))
289 # List of contained containers
290 container_list = freezer.container_set.all()
293 # Render prepared container index into freezer summary
294 cf = Context({'freezer': freezer })
295 tf = get_template('freezer_summary.html')
297 # Render Freezer summary to app html
298 return render_to_response('app.html', {
299 'app_name': settings.HTSW_ST_APPNAME,
300 'page_name': 'Freezer Summary',
302 'bcmagic': BarcodeMagicForm(),
304 'body': tf.render(cf)
306 context_instance=RequestContext(request))
309 @revision.create_on_success
310 def freezer_add(request):
312 Allows you to add a new freezer.
315 revision.comment = "New freezer created by user."
317 # If user submitted the freezer form.
318 if request.method == 'POST':
319 # Fill in FreezerForm with POSTed data.
320 form = FreezerForm(request.POST)
322 # If the form is valid, process it.
324 # Create new Freezer object from form data
325 f_obj = form.save(commit=False)
327 f_obj.uuid = get_uuid()
330 return freezer_summary(request, f_obj.uuid)
332 # If users first visit, create empty form.
336 c = Context({'form': form,
337 'action_url': '/samples/freezer/add/'})
338 t = get_template('generic_form.html')
340 return render_to_response('app.html', {
341 'app_name': settings.HTSW_ST_APPNAME,
342 'page_name': 'Freezer Add',
344 'bcmagic': BarcodeMagicForm(),
348 context_instance=RequestContext(request))
351 @revision.create_on_success
352 def freezer_edit(request, freezer_id):
354 Allow editing of a freezer
357 revision.comment = "Manual freezer edit by user."
360 freezer = models.Freezer.objects.get(uuid=freezer_id)
361 except ObjectDoesNotExist, e:
362 msg = "Freezer (%s) cannot be edited as it does not exist." % (freezer_id)
363 return render_to_response('app.html', {
364 'app_name': settings.HTSW_ST_APPNAME,
365 'page_name': 'Freezer Summary',
367 'bcmagic': BarcodeMagicForm(),
371 context_instance=RequestContext(request))
373 # If user submitted the freezer form.
374 if request.method == 'POST':
375 # Fill in FreezerForm with POSTed data.
376 form = FreezerForm(request.POST, instance=freezer)
378 # If the form is valid, process it.
380 # Save Freezer object from form data
381 f_obj = form.save(commit=True)
383 return freezer_summary(request, f_obj.uuid)
385 # If users first visit, create form from freezer instance.
386 form = FreezerForm(instance=freezer)
389 c = Context({'form': form,
390 'action_url': '%sedit/' % (freezer.get_absolute_url())})
391 t = get_template('generic_form.html')
393 return render_to_response('app.html', {
394 'app_name': settings.HTSW_ST_APPNAME,
395 'page_name': 'Freezer Edit',
397 'bcmagic': BarcodeMagicForm(),
401 context_instance=RequestContext(request))
404 def freezer_print(request, freezer_id):
406 prints a freezer label
410 freezer = models.Freezer.objects.get(uuid=freezer_id)
411 except ObjectDoesNotExist:
412 return HttpResponse('Freezer (%s) does not exist!' % (freezer_id))
415 params['freezer_name'] = __center_line(freezer.name, 17)
416 params['line1'] = __center_line('%s' % (freezer.name[17:34]), 17)
417 params['line2'] = __center_line('%s' % (freezer.name[34:51]), 17)
418 params['line3'] = __center_line('%s' % (freezer.name[51:68]), 17)
419 params['line4'] = __center_line('Temp: %s C' % (freezer.temperature), 17)
420 params['barcode'] = 'frzr|%s' % (freezer.uuid)
421 params['symbol'] = ''
423 c = RequestContext(request, params)
424 t = get_template('zpl_freezer_label.txt')
425 print_zpl(t.render(c))
427 return HttpResponse('print command for freezer %s sent.' % (freezer.uuid))
430 ################################################
432 ################################################
434 def sample_index(request):
436 return a list of samples and what we can do with them.
438 sample_list = models.Sample.objects.all()
441 c = Context({'title': 'Sample Index',
442 'sample_list': sample_list})
443 t = get_template('sample_index.html')
444 #html.append('%s <a href="/samples/sample/%s/print">(print)</a>' \
445 # % (sample, sample.sampleid))
447 return render_to_response('app.html', {
448 'app_name': settings.HTSW_ST_APPNAME,
449 'page_name': 'Samples Index',
451 'bcmagic': BarcodeMagicForm(),
455 context_instance=RequestContext(request))
458 def sample_homeless(request):
460 Returns an index of homeless samples
462 sample_list = Sample.objects.filter(container=None)
463 c = Context({'title': 'Homeless Samples',
464 'sample_list': sample_list})
465 t = get_template('sample_homeless.html')
467 return render_to_response('app.html', {
468 'app_name': "HTSW-SampleTracker",
469 'page_name': 'Homeless Samples',
470 'bcmagic': BarcodeMagicForm(),
474 context_instance=RequestContext(request))
477 @revision.create_on_success
478 def sample_add(request):
480 Allow adding of a new sample
483 revision.comment = "New sample created by user."
485 ASSIGNED_CONTAINER = False
487 # If user submitted the sample form.
488 if request.method == 'POST':
489 # Fill in SampleForm with POSTed data.
490 form = SampleForm(request.POST)
492 # If the form is valid, process it.
494 # Create new Sample object from form data
495 s_obj = form.save(commit=False)
498 s_obj.sampleid = get_sampleid()
500 # If the user wants us to assign a container.
501 if form.cleaned_data['assign_container']:
504 assign_to_container(s_obj)
505 ASSIGNED_CONTAINER = True
506 except NoSpaceAvaliable, e:
507 #return HttpResponse("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
509 ASSIGNED_CONTAINER = False
514 if not ASSIGNED_CONTAINER:
515 msg = "NOTE: Sample is homeless"
516 return sample_summary(request, s_obj.sampleid, msg=msg)
519 msg = "Sample created."
520 return sample_summary(request, s_obj.sampleid, msg=msg)
522 # If users first visit, create empty form.
526 c = Context({'form': form,
527 'action_url': '/samples/sample/add/'})
528 t = get_template('generic_form.html')
530 return render_to_response('app.html', {
531 'app_name': settings.HTSW_ST_APPNAME,
532 'page_name': 'Sample Add',
534 'bcmagic': BarcodeMagicForm(),
538 context_instance=RequestContext(request))
541 @revision.create_on_success
542 def sample_edit(request, sampleid):
544 Allow editing of a sample
547 revision.comment = "Manual sample edit by user."
550 sample = models.Sample.objects.get(sampleid=sampleid)
551 except ObjectDoesNotExist, e:
552 msg = "Sample (%s) cannot be edited as it does not exist." % (sampleid)
553 return render_to_response('app.html', {
554 'app_name': settings.HTSW_ST_APPNAME,
555 'page_name': 'Sample Edit',
557 'bcmagic': BarcodeMagicForm(),
562 # If user submitted the sample form.
563 if request.method == 'POST':
564 # Fill in SampleForm with POSTed data.
565 form = SampleForm(request.POST, instance=sample)
567 # If the form is valid, process it.
569 # Save Sample object from form data
570 s_obj = form.save(commit=True)
572 msg = "Sample Update Saved"
573 return sample_summary(request, s_obj.sampleid, msg)
575 # If users first visit, create form from sample instance.
576 form = SampleForm(instance=sample)
579 c = Context({'form': form,
580 'action_url': '%sedit/' % (sample.get_absolute_url())})
581 t = get_template('generic_form.html')
583 return render_to_response('app.html', {
584 'app_name': settings.HTSW_ST_APPNAME,
585 'page_name': 'Sample Edit',
587 'bcmagic': BarcodeMagicForm(),
591 context_instance=RequestContext(request))
594 @revision.create_on_success
595 def sample_assign_container(request, sampleid):
597 Assigns sample to container using the assign to container algorithm
600 sample = Sample.objects.get(sampleid=sampleid)
603 assign_to_container(sample)
604 except NoSpaceAvaliable, e:
605 return render_to_response('app.html', {
606 'app_name': settings.HTSW_ST_APPNAME,
607 'page_name': 'Sample Assign',
609 'bcmagic': BarcodeMagicForm(),
611 'body': mark_safe("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
614 context_instance=RequestContext(request))
618 body = 'Sample (<a href="%s">%s</a>) assigned to container (<a href="%s">%s</a>)' \
619 % (sample.get_absolute_url(), str(sample), sample.container.get_absolute_url(), str(sample.container))
622 revision.comment = "Sample auto-assigned to container (%s: %s)" % (str(sample.container), sample.container.uuid)
624 return render_to_response('app.html', {
625 'app_name': settings.HTSW_ST_APPNAME,
626 'page_name': 'Sample Assign',
628 'bcmagic': BarcodeMagicForm(),
630 'body': mark_safe(body),
632 context_instance=RequestContext(request))
635 def sample_summary(request, sampleid, msg=None):
637 Display a summary of a given sample
640 sample = models.Sample.objects.get(sampleid=sampleid)
641 except ObjectDoesNotExist, e:
642 msg = "Sample (%s) does not exist." % (sampleid)
643 return render_to_response('app.html', {
644 'app_name': settings.HTSW_ST_APPNAME,
645 'page_name': 'Sample Summary',
647 'bcmagic': BarcodeMagicForm(),
651 context_instance=RequestContext(request))
653 c = Context({'sample': sample,
655 t = get_template('sample_summary.html')
657 return render_to_response('app.html', {
658 'app_name': settings.HTSW_ST_APPNAME,
659 'page_name': 'Sample Summary',
661 'bcmagic': BarcodeMagicForm(),
665 context_instance=RequestContext(request))
668 def sample_print(request, sampleid):
674 sample = models.Sample.objects.get(sampleid=sampleid)
675 except ObjectDoesNotExist:
676 return HttpResponse('Sample (%s) does not exist!' % (sampleid))
679 params['fullid'] = str(sample)
680 params['sampleid'] = __center_line("s|%s" % (sample.sampleid), 16)
681 params['line1'] = __center_line(sample.name[0:10], 10)
682 params['line2'] = __center_line(sample.name[10:25], 14)
683 params['line3'] = __center_line('ExpType %s' % (sample.sample_type.name[0:8]), 15)
684 params['slot_num'] = random.randint(1,81)
686 c = RequestContext(request, params)
687 t = get_template('half_inch_samples.txt')
688 print_zpl(t.render(c))
690 return HttpResponse('print command for sample %s sent.' % (sample.sampleid))
693 def user_profile(request):
695 Information about the user
697 return render_to_response('registration/profile.html', {
698 'app_name': settings.HTSW_ST_APPNAME,
699 'page_name': 'User Profile',
701 'bcmagic': BarcodeMagicForm(),
702 'select': 'settings',
704 context_instance=RequestContext(request))
706 ################################################
707 # Barcode Magic Commands
708 ################################################
710 def __cmd_move_sample_return(form, request, msg=''):
712 A small helper function since this code is reused multiple times
715 c = Context({'form': form,
717 t = get_template('generic_form.html')
719 return render_to_response('app.html', {
720 'app_name': settings.HTSW_ST_APPNAME,
721 'page_name': 'CMD: Move Sample',
723 'bcmagic': BarcodeMagicForm({'bcm_mode': 'cmd_move_sample'}),
728 context_instance=RequestContext(request))
731 @revision.create_on_success
732 def cmd_move_sample(request):
734 Moves a sample to a target container
736 form = CmdMoveSampleForm()
738 if request.method == 'POST':
739 form = CmdMoveSampleForm(request.POST)
741 #If for some reason the form is not valid, return
742 if not form.is_valid():
743 msg = "Form is not valid."
744 return __cmd_move_sample_return(form, request, msg)
747 sample = models.Sample.objects.get(sampleid=form.cleaned_data['sampleid'])
748 except ObjectDoesNotExist, e:
749 msg = "Sample %s does not exist." % (form.cleaned_data['sampleid'])
750 return __cmd_move_sample_return(form, request, msg)
753 container = models.Container.objects.get(uuid=form.cleaned_data['container_id'])
754 except ObjectDoesNotExist, e:
755 msg = "Container %s does not exist." % (form.cleaned_data['container_id'])
756 return __cmd_move_sample_return(form, request, msg)
758 # Move the sample to the new container
759 old_container = sample.container
760 sample.container = container
761 if old_container is None:
762 revision.comment = "Sample (%s) moved from Homeless to Container(%s; uuid: %s)" \
763 % (str(sample), str(container), container.uuid)
765 revision.comment = "Sample (%s) moved from Container(%s; uuid: %s) to Container(%s; uuid: %s)" \
766 % (str(sample), str(old_container), old_container.uuid, str(container), container.uuid)
769 return __cmd_move_sample_return(CmdMoveSampleForm(), request, revision.comment)
771 return __cmd_move_sample_return(form, request)