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, msg=None):
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,
107 'rendered_samples': ts.render(cs) })
108 tc = get_template('container_summary.html')
110 # Render container summary to app html
111 return render_to_response('app.html', {
112 'app_name': settings.HTSW_ST_APPNAME,
113 'page_name': 'Container Summary',
115 'bcmagic': BarcodeMagicForm(),
116 'select': 'container',
117 'body': tc.render(cc)
119 context_instance=RequestContext(request))
122 @revision.create_on_success
123 def container_add(request):
125 Form for adding a container.
129 revision.comment = "New container created by user."
131 # If user submitted the Container form.
132 if request.method == 'POST':
133 # Fill in ContainerForm with POSTed data.
134 form = ContainerForm(request.POST)
136 # If the form is valid, process it.
138 # Create new Container object from form data
139 c_obj = form.save(commit=False)
141 c_obj.uuid = get_uuid()
144 # Save the many to many link data.
146 return container_summary(request, c_obj.uuid)
148 # If users first visit, create empty form.
149 form = ContainerForm()
152 c = Context({'form': form,
153 'action_url': '/samples/container/add/'})
154 t = get_template('generic_form.html')
156 return render_to_response('app.html', {
157 'app_name': settings.HTSW_ST_APPNAME,
158 'page_name': 'Container Add',
160 'bcmagic': BarcodeMagicForm(),
161 'select': 'container',
164 context_instance=RequestContext(request))
167 @revision.create_on_success
168 def container_edit(request, container_id):
170 Allow editing of a container
173 revision.comment = "Manual container edit by user."
176 container = models.Container.objects.get(uuid=container_id)
177 except ObjectDoesNotExist, e:
178 msg = "Container (%s) cannot be edited as it does not exist." % (container_id)
179 return render_to_response('app.html', {
180 'app_name': settings.HTSW_ST_APPNAME,
181 'page_name': 'Container Edit',
183 'bcmagic': BarcodeMagicForm(),
184 'select': 'container',
187 context_instance=RequestContext(request))
189 # If user submitted the container form.
190 if request.method == 'POST':
191 # Fill in ContainerForm with POSTed data.
192 form = ContainerForm(request.POST, instance=container)
194 # If the form is valid, process it.
196 # Save Container object from form data
197 c_obj = form.save(commit=True)
198 # Save many2many changes as well
199 #form.save_m2m() #Not needed when form.save(commit=True)
201 return container_summary(request, c_obj.uuid)
203 # If users first visit, create form from Container instance.
204 form = ContainerForm(instance=container)
207 c = Context({'form': form,
208 'action_url': '%sedit/' % (container.get_absolute_url())})
209 t = get_template('generic_form.html')
211 return render_to_response('app.html', {
212 'app_name': settings.HTSW_ST_APPNAME,
213 'page_name': 'Container Edit',
215 'bcmagic': BarcodeMagicForm(),
216 'select': 'container',
219 context_instance=RequestContext(request))
222 def container_print(request, container_id):
224 prints a container label
228 container = models.Container.objects.get(uuid=container_id)
229 except ObjectDoesNotExist:
230 return HttpResponse('Container (%s) does not exist!' % (container_id))
233 params['container_name'] = __center_line(container.name[0:17], 17)
234 params['line1'] = __center_line('%s' % (container.name[17:34]), 17)
235 params['line2'] = __center_line('%s' % (container.name[34:51]), 17)
236 params['line3'] = __center_line('%s' % (container.name[51:68]), 17)
237 params['line4'] = __center_line('%s' % (container.name[68:85]), 17)
238 params['barcode'] = 'cntr|%s' % (container.uuid)
239 params['symbol'] = ''
241 c = RequestContext(request, params)
242 t = get_template('zpl_container_label.txt')
243 print_zpl(t.render(c))
245 return container_summary(request, container_id, msg='print command for container %s sent.' % (container.uuid))
248 ################################################
250 ################################################
252 def freezer_index(request):
254 Returns an index of available freezers
256 freezer_list = Freezer.objects.all()
257 c = Context({'freezer_list': freezer_list})
258 t = get_template('freezer_index.html')
260 return render_to_response('app.html', {
261 'app_name': "HTSW-SampleTracker",
262 'page_name': 'Freezer Index',
264 'bcmagic': BarcodeMagicForm(),
268 context_instance=RequestContext(request))
271 def freezer_summary(request, freezer_id, msg=None):
273 Returns summary of freezer_id
275 # Retrieve freezer by UUID
277 freezer = models.Freezer.objects.get(uuid=freezer_id)
278 except ObjectDoesNotExist, e:
279 msg = "Freezer (%s) does not exist." % (freezer_id)
280 return render_to_response('app.html', {
281 'app_name': settings.HTSW_ST_APPNAME,
282 'page_name': 'Freezer Summary',
284 'bcmagic': BarcodeMagicForm(),
288 context_instance=RequestContext(request))
290 # List of contained containers
291 container_list = freezer.container_set.all()
294 # Render prepared container index into freezer summary
295 cf = Context({'freezer': freezer,
297 tf = get_template('freezer_summary.html')
299 # Render Freezer summary to app html
300 return render_to_response('app.html', {
301 'app_name': settings.HTSW_ST_APPNAME,
302 'page_name': 'Freezer Summary',
304 'bcmagic': BarcodeMagicForm(),
306 'body': tf.render(cf)
308 context_instance=RequestContext(request))
311 @revision.create_on_success
312 def freezer_add(request):
314 Allows you to add a new freezer.
317 revision.comment = "New freezer created by user."
319 # If user submitted the freezer form.
320 if request.method == 'POST':
321 # Fill in FreezerForm with POSTed data.
322 form = FreezerForm(request.POST)
324 # If the form is valid, process it.
326 # Create new Freezer object from form data
327 f_obj = form.save(commit=False)
329 f_obj.uuid = get_uuid()
332 return freezer_summary(request, f_obj.uuid)
334 # If users first visit, create empty form.
338 c = Context({'form': form,
339 'action_url': '/samples/freezer/add/'})
340 t = get_template('generic_form.html')
342 return render_to_response('app.html', {
343 'app_name': settings.HTSW_ST_APPNAME,
344 'page_name': 'Freezer Add',
346 'bcmagic': BarcodeMagicForm(),
350 context_instance=RequestContext(request))
353 @revision.create_on_success
354 def freezer_edit(request, freezer_id):
356 Allow editing of a freezer
359 revision.comment = "Manual freezer edit by user."
362 freezer = models.Freezer.objects.get(uuid=freezer_id)
363 except ObjectDoesNotExist, e:
364 msg = "Freezer (%s) cannot be edited as it does not exist." % (freezer_id)
365 return render_to_response('app.html', {
366 'app_name': settings.HTSW_ST_APPNAME,
367 'page_name': 'Freezer Summary',
369 'bcmagic': BarcodeMagicForm(),
373 context_instance=RequestContext(request))
375 # If user submitted the freezer form.
376 if request.method == 'POST':
377 # Fill in FreezerForm with POSTed data.
378 form = FreezerForm(request.POST, instance=freezer)
380 # If the form is valid, process it.
382 # Save Freezer object from form data
383 f_obj = form.save(commit=True)
385 return freezer_summary(request, f_obj.uuid)
387 # If users first visit, create form from freezer instance.
388 form = FreezerForm(instance=freezer)
391 c = Context({'form': form,
392 'action_url': '%sedit/' % (freezer.get_absolute_url())})
393 t = get_template('generic_form.html')
395 return render_to_response('app.html', {
396 'app_name': settings.HTSW_ST_APPNAME,
397 'page_name': 'Freezer Edit',
399 'bcmagic': BarcodeMagicForm(),
403 context_instance=RequestContext(request))
406 def freezer_print(request, freezer_id):
408 prints a freezer label
412 freezer = models.Freezer.objects.get(uuid=freezer_id)
413 except ObjectDoesNotExist:
414 return HttpResponse('Freezer (%s) does not exist!' % (freezer_id))
417 params['freezer_name'] = __center_line(freezer.name, 17)
418 params['line1'] = __center_line('%s' % (freezer.name[17:34]), 17)
419 params['line2'] = __center_line('%s' % (freezer.name[34:51]), 17)
420 params['line3'] = __center_line('%s' % (freezer.name[51:68]), 17)
421 params['line4'] = __center_line('Temp: %s C' % (freezer.temperature), 17)
422 params['barcode'] = 'frzr|%s' % (freezer.uuid)
423 params['symbol'] = ''
425 c = RequestContext(request, params)
426 t = get_template('zpl_freezer_label.txt')
427 print_zpl(t.render(c))
429 return freezer_summary(request, freezer_id, msg='print command for freezer %s sent.' % (freezer.uuid))
432 ################################################
434 ################################################
436 def sample_index(request):
438 return a list of samples and what we can do with them.
440 sample_list = models.Sample.objects.all()
443 c = Context({'title': 'Sample Index',
444 'sample_list': sample_list})
445 t = get_template('sample_index.html')
446 #html.append('%s <a href="/samples/sample/%s/print">(print)</a>' \
447 # % (sample, sample.sampleid))
449 return render_to_response('app.html', {
450 'app_name': settings.HTSW_ST_APPNAME,
451 'page_name': 'Samples Index',
453 'bcmagic': BarcodeMagicForm(),
457 context_instance=RequestContext(request))
460 def sample_homeless(request):
462 Returns an index of homeless samples
464 sample_list = Sample.objects.filter(container=None)
465 c = Context({'title': 'Homeless Samples',
466 'sample_list': sample_list})
467 t = get_template('sample_homeless.html')
469 return render_to_response('app.html', {
470 'app_name': "HTSW-SampleTracker",
471 'page_name': 'Homeless Samples',
472 'bcmagic': BarcodeMagicForm(),
476 context_instance=RequestContext(request))
479 @revision.create_on_success
480 def sample_add(request):
482 Allow adding of a new sample
485 revision.comment = "New sample created by user."
487 ASSIGNED_CONTAINER = False
489 # If user submitted the sample form.
490 if request.method == 'POST':
491 # Fill in SampleForm with POSTed data.
492 form = SampleForm(request.POST)
494 # If the form is valid, process it.
496 # Create new Sample object from form data
497 s_obj = form.save(commit=False)
500 s_obj.sampleid = get_sampleid()
502 # If the user wants us to assign a container.
503 if form.cleaned_data['assign_container']:
506 assign_to_container(s_obj)
507 ASSIGNED_CONTAINER = True
508 except NoSpaceAvaliable, e:
509 #return HttpResponse("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
511 ASSIGNED_CONTAINER = False
516 if not ASSIGNED_CONTAINER:
517 msg = "NOTE: Sample is homeless"
518 return sample_summary(request, s_obj.sampleid, msg=msg)
521 msg = "Sample created."
522 return sample_summary(request, s_obj.sampleid, msg=msg)
524 # If users first visit, create empty form.
528 c = Context({'form': form,
529 'action_url': '/samples/sample/add/'})
530 t = get_template('generic_form.html')
532 return render_to_response('app.html', {
533 'app_name': settings.HTSW_ST_APPNAME,
534 'page_name': 'Sample Add',
536 'bcmagic': BarcodeMagicForm(),
540 context_instance=RequestContext(request))
543 @revision.create_on_success
544 def sample_edit(request, sampleid):
546 Allow editing of a sample
549 revision.comment = "Manual sample edit by user."
552 sample = models.Sample.objects.get(sampleid=sampleid)
553 except ObjectDoesNotExist, e:
554 msg = "Sample (%s) cannot be edited as it does not exist." % (sampleid)
555 return render_to_response('app.html', {
556 'app_name': settings.HTSW_ST_APPNAME,
557 'page_name': 'Sample Edit',
559 'bcmagic': BarcodeMagicForm(),
564 # If user submitted the sample form.
565 if request.method == 'POST':
566 # Fill in SampleForm with POSTed data.
567 form = SampleForm(request.POST, instance=sample)
569 # If the form is valid, process it.
571 # Save Sample object from form data
572 s_obj = form.save(commit=True)
574 msg = "Sample Update Saved"
575 return sample_summary(request, s_obj.sampleid, msg)
577 # If users first visit, create form from sample instance.
578 form = SampleForm(instance=sample)
581 c = Context({'form': form,
582 'action_url': '%sedit/' % (sample.get_absolute_url())})
583 t = get_template('generic_form.html')
585 return render_to_response('app.html', {
586 'app_name': settings.HTSW_ST_APPNAME,
587 'page_name': 'Sample Edit',
589 'bcmagic': BarcodeMagicForm(),
593 context_instance=RequestContext(request))
596 @revision.create_on_success
597 def sample_assign_container(request, sampleid):
599 Assigns sample to container using the assign to container algorithm
602 sample = Sample.objects.get(sampleid=sampleid)
605 assign_to_container(sample)
606 except NoSpaceAvaliable, e:
607 return render_to_response('app.html', {
608 'app_name': settings.HTSW_ST_APPNAME,
609 'page_name': 'Sample Assign',
611 'bcmagic': BarcodeMagicForm(),
613 'body': mark_safe("<b>Error:</b> %s<br /><i>You will need to prepare a new container before continuing.</i>" \
616 context_instance=RequestContext(request))
620 body = 'Sample (<a href="%s">%s</a>) assigned to container (<a href="%s">%s</a>)' \
621 % (sample.get_absolute_url(), str(sample), sample.container.get_absolute_url(), str(sample.container))
624 revision.comment = "Sample auto-assigned to container (%s: %s)" % (str(sample.container), sample.container.uuid)
626 return render_to_response('app.html', {
627 'app_name': settings.HTSW_ST_APPNAME,
628 'page_name': 'Sample Assign',
630 'bcmagic': BarcodeMagicForm(),
632 'body': mark_safe(body),
634 context_instance=RequestContext(request))
637 def sample_summary(request, sampleid, msg=None):
639 Display a summary of a given sample
642 sample = models.Sample.objects.get(sampleid=sampleid)
643 except ObjectDoesNotExist, e:
644 msg = "Sample (%s) does not exist." % (sampleid)
645 return render_to_response('app.html', {
646 'app_name': settings.HTSW_ST_APPNAME,
647 'page_name': 'Sample Summary',
649 'bcmagic': BarcodeMagicForm(),
653 context_instance=RequestContext(request))
655 c = Context({'sample': sample,
657 t = get_template('sample_summary.html')
659 return render_to_response('app.html', {
660 'app_name': settings.HTSW_ST_APPNAME,
661 'page_name': 'Sample Summary',
663 'bcmagic': BarcodeMagicForm(),
667 context_instance=RequestContext(request))
670 def sample_print(request, sampleid):
676 sample = models.Sample.objects.get(sampleid=sampleid)
677 except ObjectDoesNotExist:
678 return HttpResponse('Sample (%s) does not exist!' % (sampleid))
681 params['fullid'] = str(sample)
682 params['sampleid'] = __center_line("s|%s" % (sample.sampleid), 16)
683 params['line1'] = __center_line(sample.name[0:10], 10)
684 params['line2'] = __center_line(sample.name[10:25], 14)
685 params['line3'] = __center_line('ExpType %s' % (sample.sample_type.name[0:8]), 15)
686 params['slot_num'] = random.randint(1,81)
688 c = RequestContext(request, params)
689 t = get_template('half_inch_samples.txt')
690 print_zpl(t.render(c))
692 return sample_summary(request, sampleid, msg='print command for sample %s sent.' % (sample.sampleid))
695 def user_profile(request):
697 Information about the user
699 return render_to_response('registration/profile.html', {
700 'app_name': settings.HTSW_ST_APPNAME,
701 'page_name': 'User Profile',
703 'bcmagic': BarcodeMagicForm(),
704 'select': 'settings',
706 context_instance=RequestContext(request))
708 ################################################
709 # Barcode Magic Commands
710 ################################################
712 def __cmd_move_sample_return(form, request, msg=''):
714 A small helper function since this code is reused multiple times
717 c = Context({'form': form,
719 t = get_template('generic_form.html')
721 return render_to_response('app.html', {
722 'app_name': settings.HTSW_ST_APPNAME,
723 'page_name': 'CMD: Move Sample',
725 'bcmagic': BarcodeMagicForm({'bcm_mode': 'cmd_move_sample'}),
730 context_instance=RequestContext(request))
733 @revision.create_on_success
734 def cmd_move_sample(request):
736 Moves a sample to a target container
738 form = CmdMoveSampleForm()
740 if request.method == 'POST':
741 form = CmdMoveSampleForm(request.POST)
743 #If for some reason the form is not valid, return
744 if not form.is_valid():
745 msg = "Form is not valid."
746 return __cmd_move_sample_return(form, request, msg)
749 sample = models.Sample.objects.get(sampleid=form.cleaned_data['sampleid'])
750 except ObjectDoesNotExist, e:
751 msg = "Sample %s does not exist." % (form.cleaned_data['sampleid'])
752 return __cmd_move_sample_return(form, request, msg)
755 container = models.Container.objects.get(uuid=form.cleaned_data['container_id'])
756 except ObjectDoesNotExist, e:
757 msg = "Container %s does not exist." % (form.cleaned_data['container_id'])
758 return __cmd_move_sample_return(form, request, msg)
760 # Move the sample to the new container
761 old_container = sample.container
762 sample.container = container
763 if old_container is None:
764 revision.comment = "Sample (%s) moved from Homeless to Container(%s; uuid: %s)" \
765 % (str(sample), str(container), container.uuid)
767 revision.comment = "Sample (%s) moved from Container(%s; uuid: %s) to Container(%s; uuid: %s)" \
768 % (str(sample), str(old_container), old_container.uuid, str(container), container.uuid)
771 return __cmd_move_sample_return(CmdMoveSampleForm(), request, revision.comment)
773 return __cmd_move_sample_return(form, request)