2 package SGN
::Controller
::Barcode
;
10 #use GD::Barcode::QRcode;
13 use Math
::Base36
':all';
17 BEGIN { extends
'Catalyst::Controller'; }
19 sub index : Path
('/barcode') Args
(0) {
23 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
25 my @rows = $schema->resultset('Project::Project')->all();
27 foreach my $row (@rows) {
28 push @projects, [ $row->project_id, $row->name, $row->description ];
30 $c->stash->{projects
} = \
@projects;
31 @rows = $schema->resultset('NaturalDiversity::NdGeolocation')->all();
33 foreach my $row (@rows) {
34 push @locations, [ $row->nd_geolocation_id,$row->description ];
37 # get tool description info
39 my @tools_def = read_file
($c->path_to("../cassava/documents/barcode/tools.def"));
41 print STDERR
join "\n", @tools_def;
43 $c->stash->{tools_def
} = \
@tools_def;
44 $c->stash->{locations
} = \
@locations;
45 $c->stash->{template
} = '/barcode/index.mas';
51 URL: mapped to URL /barcode/image
52 Params: code : the code to represent in the barcode
53 text : human readable text
54 size : either small, large
55 top : pixels from the top
56 Desc: creates the barcode image, sets the content type to
57 image/png and returns the barcode image to the browser
64 sub barcode_image
: Path
('/barcode/image') Args
(0) {
68 my $code = $c->req->param("code");
69 my $text = $c->req->param("text");
70 my $size = $c->req->param("size");
71 my $top = $c->req->param("top");
73 my $barcode = $self->barcode($code, $text, $size, $top);
75 $c->res->headers->content_type('image/png');
77 $c->res->body($barcode->png());
81 sub barcode_tempfile_jpg
: Path
('/barcode/tempfile') Args
(4) {
90 my $barcode = $self->barcode($code,
96 $c->tempfiles_subdir('barcode');
97 my ($file, $uri) = $c->tempfile( TEMPLATE
=> [ 'barcode', 'bc-XXXXX'], SUFFIX
=>'.jpg');
99 open(my $F, ">", $file) || die "Can't open file $file $@";
100 print $F $barcode->jpeg();
109 Usage: $self->barcode($code, $text, $size, 30);
110 Desc: generates a barcode (GD image)
111 Ret: a GD::Image object
112 Args: $code, $text, $size, upper margin
126 if ($size eq "small") { $scale = 1; }
127 if ($size eq "huge") { $scale = 5; }
128 my $barcode_object = Barcode
::Code128
->new();
129 $barcode_object->barcode($code);
130 $barcode_object->font('large');
131 $barcode_object->border(2);
132 $barcode_object->scale($scale);
133 $barcode_object->top_margin($top);
134 $barcode_object->font_align("center");
135 my $barcode = $barcode_object ->gd_image();
136 my $text_width = gdLargeFont
->width()*length($text);
137 $barcode->string(gdLargeFont
,int(($barcode->width()-$text_width)/2),10,$text, $barcode->colorAllocate(0, 0, 0));
142 sub code128_png
:Path
('/barcode/code128png') :Args
(2) {
145 my $identifier = shift;
149 $identifier =~ s/\+/ /g;
151 my $barcode_object = Barcode
::Code128
->new();
152 $barcode_object->barcode($identifier);
153 $barcode_object->font('large');
154 $barcode_object->border(2);
155 $barcode_object->top_margin(30);
156 $barcode_object->font_align("center");
157 my $barcode = $barcode_object ->gd_image();
158 my $text_width = gdLargeFont
->width()*length($text);
159 $barcode->string(gdLargeFont
,int(($barcode->width()-$text_width)/2),10,$text, $barcode->colorAllocate(0, 0, 0));
160 $c->res->headers->content_type('image/png');
162 $c->res->body($barcode->png());
165 # a barcode element for a continuous barcode
167 sub barcode_element
: Path
('/barcode/element/') :Args
(2) {
173 my $size = $c->req->param("size");
176 if ($size eq "large") {
180 my $barcode_object = Barcode
::Code128
->new();
181 $barcode_object->barcode($text);
182 $barcode_object->height(100);
183 $barcode_object->scale($scale);
184 #$barcode_object->width(200);
185 $barcode_object->font('large');
186 $barcode_object->border(0);
187 $barcode_object->top_margin(0);
188 my $barcode = $barcode_object ->gd_image();
190 my $barcode_slice = GD
::Image
->new($barcode->width, $height);
191 my $white = $barcode_slice->colorAllocate(255,255,255);
192 $barcode_slice->filledRectangle(0, 0, $barcode->width, $height, $white);
194 print STDERR
"Creating barcode with width ".($barcode->width)." and height $height\n";
195 $barcode_slice->copy($barcode, 0, 0, 0, 0, $barcode->width, $height);
197 $c->res->headers->content_type('image/png');
199 $c->res->body($barcode_slice->png());
202 sub qrcode_png
:Path
('/barcode/qrcodepng') :Args
(2) {
211 my $bc = GD
::Barcode
::QRcode
->new($link, { Ecc
=> 'L', Version
=>2, ModuleSize
=> 2 });
212 my $image = $bc->plot();
214 $c->res->headers->content_type('image/png');
215 $c->res->body($image->png());
218 sub barcode_tool
:Path
('/barcode/tool') Args
(3) {
222 my $tool_version = shift;
225 my ($db, $accession) = split ":", $cvterm;
227 print STDERR
"Searching $cvterm, DB $db...\n";
228 my ($db_row) = $c->dbic_schema('Bio::Chado::Schema')->resultset('General::Db')->search( { name
=> $db } );
230 print STDERR
$db_row->db_id;
231 print STDERR
"DB_ID for $db: $\n";
234 my $dbxref_rs = $c->dbic_schema('Bio::Chado::Schema')->resultset('General::Dbxref')->search_rs( { accession
=>$accession, db_id
=>$db_row->db_id } );
236 my $cvterm_rs = $c->dbic_schema('Bio::Chado::Schema')->resultset('Cv::Cvterm')->search( { dbxref_id
=> $dbxref_rs->first->dbxref_id });
238 my $cvterm_id = $cvterm_rs->first()->cvterm_id();
239 my $cvterm_synonym_rs = ""; #$c->dbic_schema('Bio::Chado::Schema')->resultset('Cv::Cvtermsynonym')->search->( { cvterm_id=>$cvterm_id });
241 $c->stash->{cvterm
} = $cvterm;
242 $c->stash->{cvterm_name
} = $cvterm_rs->first()->name();
243 $c->stash->{cvterm_definition
} = $cvterm_rs->first()->definition();
244 $c->stash->{cvterm_values
} = $values;
245 $c->stash->{tool_version
} = $tool_version;
246 $c->stash->{template
} = '/barcode/tool/tool.mas';
247 # $c->stash->{cvterm_synonym} = $cvterm_synonym_rs->synonym();
248 $c->forward('View::Mason');
252 sub barcode_multitool
:Path
('/barcode/multitool') Args
(0) {
257 $c->stash->{operator
} = $c->req->param('operator');
258 $c->stash->{date
} = $c->req->param('date');
259 $c->stash->{project
} = $c->req->param('project');
260 $c->stash->{location
} = $c->req->param('location');
262 my @cvterms = $c->req->param('cvterms');
264 my $cvterm_data = [];
266 foreach my $cvterm (@cvterms) {
268 my ($db, $accession) = split ":", $cvterm;
270 print STDERR
"Searching $cvterm, DB $db...\n";
271 my ($db_row) = $c->dbic_schema('Bio::Chado::Schema')->resultset('General::Db')->search( { name
=> $db } );
273 print STDERR
$db_row->db_id;
274 print STDERR
"DB_ID for $db: $\n";
277 my $dbxref_rs = $c->dbic_schema('Bio::Chado::Schema')->resultset('General::Dbxref')->search_rs( { accession
=>$accession, db_id
=>$db_row->db_id } );
279 my $cvterm_rs = $c->dbic_schema('Bio::Chado::Schema')->resultset('Cv::Cvterm')->search( { dbxref_id
=> $dbxref_rs->first->dbxref_id });
281 my $cvterm_id = $cvterm_rs->first()->cvterm_id();
282 my $cvterm_synonym_rs = ""; #$c->dbic_schema('Bio::Chado::Schema')->resultset('Cv::Cvtermsynonym')->search->( { cvterm_id=>$cvterm_id });
284 push @
$cvterm_data, { cvterm
=> $cvterm,
285 cvterm_name
=> $cvterm_rs->first()->name(),
286 cvterm_definition
=> $cvterm_rs->first->definition,
291 $c->stash->{cvterms
} = $cvterm_data;
293 $c->stash->{template
} = '/barcode/tool/multi_tool.mas';
298 sub continuous_scale
: Path
('/barcode/continuous_scale') Args
(0) {
301 my $start = $c->req->param("start");
302 my $end = $c->req->param("end");
303 my $step = $c->req->param("step");
304 my $height = $c->req->param("height");
308 # barcodes all have to have the same with - use with of end value
309 my $text_width = length($end);
311 for(my $i = $start; $i <= $end; $i += $step) {
312 my $text = $urlencode{sprintf "%".$text_width."d", $i};
313 print STDERR
"TEXT: $text\n";
314 push @barcodes, qq { <img src
="/barcode/element/$i/$height" align
="right" /> };
318 $c->res->body("<table cellpadding=\"0\" cellspacing=\"0\">". (join "\n", (map { "<tr><td>$_</td></tr>"} @barcodes)). "</table>");
323 sub continuous_scale_form
: Path
('/barcode/continuous_scale/input') :Args
(0) {
328 <h1>Create continuous barcode</h1>
330 <form action="/barcode/continuous_scale">
331 Start value <input name="start" /><br />
332 End value <input name="end" /><br />
333 Step size <input name="step" /><br />
334 Increment (pixels) <input name="height" />
336 <input type="submit" />
341 $c->res->body($form);
345 sub generate_barcode
: Path
('/barcode/generate') Args
(0) {
349 my $text = $c->req->param("text");
350 my $size = $c->req->param("size");
352 $c->stash->{code
} = $text;
353 $c->stash->{size
} = $size;
355 $c->stash->{template
} = "/barcode/tool/generate.mas";
359 sub metadata_barcodes
: Path
('/barcode/metadata') Args
(0) {
365 $c->stash->{operator
} = $c->req->param("operator");
366 $c->stash->{date
} = $c->req->param("date");
367 $c->stash->{size
} = $c->req->param("size");
368 $c->stash->{project
} = $c->req->param("project");
369 $c->stash->{location
} = $c->req->param("location");
371 $c->stash->{template
} = '/barcode/tool/metadata.mas';
374 sub new_barcode_tool
: Path
('/barcode/tool/') Args
(1) {
380 $c->stash->{template
} = '/barcode/tool/'.$term.'.mas';
383 sub cross_tool
: Path
('/barcode/tool/cross') {
387 $c->stash->{template
} = '/barcode/tool/cross.mas';
390 sub dna_tool
: Path
('/barcode/tool/dna/') {
393 $c->stash->{template
} = '/barcode/tool/dna.mas';
396 sub generate_unique_barcode_labels
: Path
('/barcode/unique') Args
(0) {
401 $c->stash->{template
} = 'generic_message.mas';
402 $c->stash->{message
} = 'You must be logged in to use the unique barcode tool.';
406 my $label_pages = $c->req->param("label_pages");
407 my $label_rows = $c->req->param("label_rows") || 10;
408 my $label_cols = $c->req->param("label_cols") || 1;
409 my $page_format = $c->req->param("page_format") || "letter";
410 my $top_margin_mm = $c->req->param("top_margin");
411 my $left_margin_mm = $c->req->param("left_margin");
412 my $bottom_margin_mm = $c->req->param("bottom_margin");
413 my $right_margin_mm = $c->req->param("right_margin");
415 # convert mm into pixels
417 my ($top_margin, $left_margin, $bottom_margin, $right_margin) = map { int($_ * 2.846) } ($top_margin_mm,
421 my $total_labels = $label_pages * $label_cols * $label_rows;
424 my $dir = $c->tempfiles_subdir('pdfs');
425 my ($FH, $filename) = $c->tempfile(TEMPLATE
=>"pdfs/pdf-XXXXX", SUFFIX
=>".pdf", UNLINK
=>0);
426 print STDERR
"FILENAME: $filename \n\n\n";
427 my $pdf = PDF
::Create
->new(filename
=>$c->path_to($filename),
428 Author
=>$c->config->{project_name
},
430 CreationDate
=> [ localtime ],
434 if (!$page_format) { $page_format = "Letter"; }
436 print STDERR
"PAGE FORMAT IS: $page_format. LABEL ROWS: $label_rows, COLS: $label_cols. TOTAL LABELS: $total_labels\n";
439 push @pages, PDF
::LabelPage
->new( { top_margin
=>$top_margin, bottom_margin
=>$bottom_margin, left_margin
=>$left_margin, right_margin
=>$right_margin, pdf
=>$pdf, cols
=> $label_cols, rows
=> $label_rows });
441 foreach my $label_count (1..$total_labels) {
442 my $label_code = $self->generate_label_code($c);
444 print STDERR
"LABEL CODE: $label_code\n";
448 my $tempfile = $c->forward('/barcode/barcode_tempfile_jpg', [ $label_code, $label_code , 'large', 20 ]);
449 my $image = $pdf->image($tempfile);
450 print STDERR
"IMAGE: ".Data
::Dumper
::Dumper
($image);
452 # note: pdf coord system zero is lower left corner
455 if ($pages[-1]->need_more_labels()) {
456 print STDERR
"ADDING LABEL...\n";
457 $pages[-1]->add_label($image);
461 print STDERR
"CREATING NEW PAGE...\n";
463 push @pages, PDF
::LabelPage
->new({ top_margin
=>$top_margin, bottom_margin
=>$bottom_margin, left_margin
=>$left_margin, right_margin
=>$right_margin, pdf
=>$pdf, cols
=> $label_cols, rows
=> $label_rows });
465 $pages[-1]->add_label($image);
470 foreach my $p (@pages) {
476 #$c->stash->{not_found} = \@not_found;
477 #$c->stash->{found} = \@found;
478 $c->stash->{file
} = $filename;
479 $c->stash->{filetype
} = 'PDF';
480 $c->stash->{template
} = '/barcode/unique_barcode_download.mas';
485 sub generate_label_code
{
489 my $dbh = $c->dbc->dbh();
491 my $h = $dbh->prepare("SELECT nextval('phenome.unique_barcode_label_id_seq')");
493 my ($next_val) = $h->fetchrow_array();
495 print STDERR
"nextval is $next_val\n";
497 my $encoded = Math
::Base36
::encode_base36
($next_val, 7);