barcode_encoder 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +83 -0
  9. data/Rakefile +6 -0
  10. data/barcode_encoder.gemspec +34 -0
  11. data/ext/gbarcode/LICENSE_GNU_BARCODE +339 -0
  12. data/ext/gbarcode/README_GNU_BARCODE +93 -0
  13. data/ext/gbarcode/barcode.h +119 -0
  14. data/ext/gbarcode/barcode.i +15 -0
  15. data/ext/gbarcode/barcode_wrap.c +3192 -0
  16. data/ext/gbarcode/codabar.c +182 -0
  17. data/ext/gbarcode/code128.c +607 -0
  18. data/ext/gbarcode/code39.c +173 -0
  19. data/ext/gbarcode/code93.c +213 -0
  20. data/ext/gbarcode/ean.c +774 -0
  21. data/ext/gbarcode/extconf.rb +6 -0
  22. data/ext/gbarcode/i25.c +164 -0
  23. data/ext/gbarcode/library.c +244 -0
  24. data/ext/gbarcode/msi.c +155 -0
  25. data/ext/gbarcode/pcl.c +200 -0
  26. data/ext/gbarcode/plessey.c +164 -0
  27. data/ext/gbarcode/ps.c +272 -0
  28. data/ext/gbarcode/svg.c +174 -0
  29. data/lib/multi_encoder.rb +7 -0
  30. data/lib/multi_encoder/helpers.rb +13 -0
  31. data/lib/multi_encoder/images.rb +3 -0
  32. data/lib/multi_encoder/images/abstract.rb +37 -0
  33. data/lib/multi_encoder/images/barcode.rb +39 -0
  34. data/lib/multi_encoder/images/qrcode.rb +16 -0
  35. data/lib/multi_encoder/railtie.rb +11 -0
  36. data/lib/multi_encoder/storage.rb +25 -0
  37. data/lib/multi_encoder/storage/aws.rb +69 -0
  38. data/lib/multi_encoder/storage/filesystem.rb +29 -0
  39. data/lib/multi_encoder/version.rb +3 -0
  40. data/spec/multi_encoder/barcode_image_spec.rb +62 -0
  41. data/spec/multi_encoder/qrcode_image_spec.rb +63 -0
  42. data/spec/spec_helper.rb +9 -0
  43. metadata +189 -0
@@ -0,0 +1,174 @@
1
+ /*
2
+ * svg.c -- print out the barcode SVG-style
3
+ *
4
+ * Copyright (c) 2001 David J. Humphreys (humphrd@tcd.ie)
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ *
20
+ *
21
+ * http://www.onefour.net/barcode/
22
+ *
23
+ * Made with a mac! (Tested under os X, 10.1)
24
+ *
25
+ * I wanted to output barcodes as SVG for some art work.
26
+ * This will output everything as an SVG file. This file can
27
+ * then be inserted into another SVG file.
28
+ *
29
+ * I don't want to get into the specifics of SVG files here. I
30
+ * suppose there will be a few specifics on my website (above) along
31
+ * with a few examples.
32
+ */
33
+
34
+ #include <stdio.h>
35
+ #include <stdlib.h>
36
+ #include <string.h>
37
+ #include <ctype.h>
38
+ #include <errno.h>
39
+
40
+ #include "barcode.h"
41
+
42
+ /* If there is any need to print out a comment,
43
+ * then this is the method */
44
+ int svg_comment(char *Message, FILE *f){
45
+ fprintf(f, "<!-- %s -->\n",Message);
46
+ return 0;
47
+ }
48
+
49
+ /* Prints the title (bc->ascii) and the
50
+ * desc(ription) */
51
+ int svg_desc(struct Barcode_Item *bc, FILE *f){
52
+ fprintf(f, "<title>%s</title>\n",bc->ascii);
53
+ fprintf(f, "<desc>\n");
54
+ fprintf(f, "\t%s:\t%s\n",bc->encoding,bc->ascii);
55
+ fprintf(f, "\tGNU-barcode:\t%s\n",BARCODE_VERSION);
56
+ fprintf(f, "\tbarcode:\thttp://www.gnu.org/\n");
57
+ fprintf(f, "\tsvg-code:\thttp://www.onefour.net/barcode\n");
58
+ fprintf(f, "</desc>\n");
59
+ return 0;
60
+ }
61
+
62
+ /* print out the start of the svg file,
63
+ * with some xml voodoo. There are a
64
+ * lot of \"s in this code.
65
+ * It bounds the svg file by
66
+ * bc->width or 104 and
67
+ * bc->height or 100
68
+ * The title of the file is bc->ascii
69
+ * NOTE: margins and scale are ignored
70
+ * the user can simply insert the
71
+ * svg file into another and then
72
+ * specify scale and margin.*/
73
+ int svg_start( struct Barcode_Item *bc, FILE *f){
74
+ if(bc->height == 0) bc->height = 100;
75
+ if(bc->width == 0) bc->width = 104;
76
+ fprintf(f, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
77
+ fprintf(f, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n");
78
+ fprintf(f, "<svg width=\"%i\" height=\"%i\">\n",bc->width ,bc->height);
79
+ svg_desc(bc,f);
80
+ return 0;
81
+ }
82
+
83
+ /* just close the svg file */
84
+ int svg_end(FILE *f){
85
+ fprintf(f, "</svg>\n");
86
+ return 0;
87
+ }
88
+
89
+ /* prints out the code for the bars.
90
+ * the bars are drawn with rect(angles)
91
+ * rather than lines. The mathematics
92
+ * for placing a line then setting the
93
+ * stroke width gets messy. */
94
+ int svg_bars(struct Barcode_Item *bc, FILE *f){
95
+ int
96
+ i = 0, /* Loop counter */
97
+ height = 70, /* Each box is 70 pixels in hieght */
98
+ xpos = 0; /* Where the current box is drawn */
99
+ int current; /* The current character in partial */
100
+ int is_bar = 0;
101
+
102
+ fprintf(f, "<g fill=\"black\">\n");
103
+
104
+ for(i = 0; i < strlen(bc->partial); i++){
105
+ current = (int)bc->partial[i] - 48;
106
+ if(current > 9){
107
+ height = 75; /* Guide bar */
108
+ current = (int)bc->partial[++i] - 48;
109
+ i++; /* Skip the following 'a' */
110
+ }
111
+ else
112
+ height = 70;
113
+ if(is_bar == 1){
114
+ fprintf(f, "\t<rect x=\"%i\" y=\"0\" ",xpos); /* all bars start at y=0 */
115
+ fprintf(f, "height=\"%i\" width=\"%i\" stroke-width=\"0\"/>\n",height,current);
116
+ is_bar = 0;
117
+ }
118
+ else
119
+ is_bar = 1;
120
+ xpos += current;
121
+ }
122
+ fprintf(f, "</g>\n");
123
+ return 0;
124
+ }
125
+
126
+ /* positions the characters that will
127
+ * be printed. This assumes they will
128
+ * be under the barcode.*/
129
+ int svg_text(struct Barcode_Item *bc, FILE *f){
130
+ unsigned
131
+ i = 0,
132
+ j = 0,
133
+ infosz = strlen(bc->textinfo),
134
+ xpos = 0,
135
+ prev_x = 0,
136
+ correction = 0; /* This correction seems to be needed to align text properly */
137
+ double dub1, dub2;
138
+ char printer;
139
+ char *temp_info = malloc(infosz);
140
+ if(!temp_info)
141
+ return -1;
142
+ fprintf(f, "<g font-family=\"Helvitica\" font-size=\"12\">\n");
143
+
144
+ while(i < infosz){
145
+ for(j = 0; bc->textinfo[i + j + 1] != ' ' &&
146
+ bc->textinfo[i + j + 1] != '\0';j++); /* Empty loop, just increment j */
147
+
148
+ j ++;
149
+ strncpy(temp_info, (bc->textinfo + i),j);
150
+ sscanf(temp_info, "%lf:%lf:%c", &dub1, &dub2, &printer);
151
+ i += j;
152
+
153
+ xpos = (int)dub1;
154
+ if((xpos - prev_x) >= 10)
155
+ correction += 2;
156
+
157
+ prev_x = xpos;
158
+ fprintf(f, "\t<text x=\"%i\" y=\"%i\">%c</text>\n",(xpos - correction),80,printer);
159
+ }
160
+ fprintf(f, "</g>\n");
161
+ free(temp_info);
162
+ return 0;
163
+ }
164
+
165
+ /* This is the function to call. It calls the
166
+ * functions above in order. Thers is no real
167
+ * error detection in this code. */
168
+ int Barcode_svg_print(struct Barcode_Item *bc, FILE *f){
169
+ svg_start(bc,f);
170
+ svg_bars(bc,f);
171
+ svg_text(bc,f); /* Should test for text output bit in flags */
172
+ svg_end(f);
173
+ return 0;
174
+ }
@@ -0,0 +1,7 @@
1
+ $: << File.dirname(__FILE__) + '/multi_encoder'
2
+
3
+ require 'version'
4
+ require 'gbarcode'
5
+ require 'storage'
6
+ require 'images'
7
+ require 'railtie' if defined? Rails
@@ -0,0 +1,13 @@
1
+ module MultiEncoder
2
+ module Helpers
3
+ def barcode(string, options = {})
4
+ image = BarcodeImage.new string, options
5
+ image_tag image.href
6
+ end
7
+
8
+ def qrcode(string, options = {})
9
+ image = QRcodeImage.new string, options
10
+ image_tag image.href
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ require 'images/abstract'
2
+ require 'images/barcode'
3
+ require 'images/qrcode'
@@ -0,0 +1,37 @@
1
+ module MultiEncoder
2
+ class AbstractImage
3
+
4
+ OUTPUT_FORMAT = 'png'
5
+
6
+ def initialize(string, options = {})
7
+ @contents = string
8
+ @options = options
9
+ choose_storage
10
+ end
11
+
12
+ def href
13
+ write unless exists?
14
+ url
15
+ end
16
+
17
+ private
18
+ def fingerprint
19
+ Digest::MD5.hexdigest(@contents)[0,9].scan(/.../)
20
+ end
21
+
22
+ def choose_storage
23
+ storage = case MultiEncoder::Storage.destination
24
+ when :filesystem
25
+ MultiEncoder::Storage::FileSystem
26
+ when :aws
27
+ MultiEncoder::Storage::AWS
28
+ end
29
+ self.class.send :include, storage
30
+ end
31
+
32
+ private
33
+ def eps_path
34
+ "/tmp/#{@contents}-#{Time.now.strftime('%Y%m%d-%H%M%S')}.eps"
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ require 'tempfile'
2
+
3
+ module MultiEncoder
4
+ class BarcodeImage < AbstractImage
5
+
6
+ DEFAULT_ENCODING = Gbarcode::BARCODE_128 | Gbarcode::BARCODE_NO_CHECKSUM
7
+
8
+ def type
9
+ 'barcodes'
10
+ end
11
+
12
+ def write
13
+ barcode = Gbarcode.barcode_create @contents.upcase
14
+ Gbarcode.barcode_encode extract_options(barcode), DEFAULT_ENCODING
15
+ FileUtils.mkdir_p directory
16
+ eps = File.open("#{eps_path}", 'wb')
17
+
18
+ begin
19
+ Gbarcode.barcode_print barcode, eps, Gbarcode::BARCODE_OUT_EPS
20
+ eps.close
21
+ system("convert #{eps_path} #{file_path}")
22
+ ensure
23
+ FileUtils.rm(eps) if File.exists? eps_path
24
+ end
25
+ save if respond_to? :save
26
+ end
27
+
28
+ private
29
+ def extract_options(bc)
30
+ bc.width = @options[:width] if @options[:width]
31
+ bc.height = @options[:height] if @options[:height]
32
+ bc.scalef = @options[:scaling_factor] if @options[:scaling_factor]
33
+ bc.xoff = @options[:xoff] if @options[:xoff]
34
+ bc.yoff = @options[:yoff] if @options[:yoff]
35
+ bc.margin = @options[:margin] if @options[:margin]
36
+ bc
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,16 @@
1
+ module MultiEncoder
2
+ class QRcodeImage < AbstractImage
3
+
4
+ def type
5
+ 'qrcodes'
6
+ end
7
+
8
+ def write
9
+ qrcode = QREncoder.encode @contents.downcase
10
+ png = qrcode.png @options
11
+ FileUtils.mkdir_p directory
12
+ png.save file_path
13
+ save if respond_to? :save
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ require 'helpers'
2
+
3
+ module MultiEncoder
4
+ class Railtie < ::Rails::Railtie
5
+ initializer 'multi-encoder.initialize' do
6
+ ActiveSupport.on_load :action_view do
7
+ include MultiEncoder::Helpers
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+
3
+ module MultiEncoder
4
+ module Storage
5
+ mattr_reader :destination
6
+ mattr_accessor :aws_bucket_prefix
7
+ mattr_accessor :aws_access_key
8
+ mattr_accessor :aws_secret_access_key
9
+
10
+ def self.configure
11
+ yield self
12
+ end
13
+
14
+ def self.destination=(dest)
15
+ unless [:filesystem, :aws].include? dest
16
+ raise ArgumentError.new('Unsopported storage distination mate')
17
+ end
18
+ @@destination = dest
19
+ end
20
+ self.destination = :filesystem
21
+ end
22
+ end
23
+
24
+ require 'storage/aws'
25
+ require 'storage/filesystem'
@@ -0,0 +1,69 @@
1
+ require 'active_support/concern'
2
+
3
+ module MultiEncoder
4
+ module Storage
5
+ module AWS
6
+ extend ActiveSupport::Concern
7
+
8
+ included { require 'fog' }
9
+
10
+ def url
11
+ file.public_url
12
+ end
13
+
14
+ def file
15
+ @file ||= aws_directory.files.get(filename)
16
+ end
17
+
18
+ def root
19
+ Pathname.new('/tmp')
20
+ end
21
+
22
+ def directory
23
+ root.join 'public', 'system', type, *fingerprint
24
+ end
25
+
26
+ def aws_directory
27
+ env = defined?(Rails) ? Rails.env : 'gem-dev'
28
+ @aws_directory ||= connection.directories.create({
29
+ key: "#{Storage.aws_bucket_prefix}-#{env}-#{type}",
30
+ public: true
31
+ })
32
+ end
33
+
34
+ def file_path
35
+ Pathname.new "/tmp/#{filename}.png"
36
+ end
37
+
38
+ def exists?
39
+ !!aws_directory.files.head(filename)
40
+ end
41
+
42
+ def save
43
+ aws_directory.files.create({
44
+ body: IO.read(file_path),
45
+ key: filename,
46
+ public: true,
47
+ content_type: 'image/png'
48
+ })
49
+ end
50
+
51
+ def delete
52
+ file.destroy
53
+ end
54
+
55
+ private
56
+ def filename
57
+ fingerprint.join
58
+ end
59
+
60
+ def connection
61
+ ::Fog::Storage.new({
62
+ provider: 'AWS',
63
+ aws_access_key_id: Storage.aws_access_key,
64
+ aws_secret_access_key: Storage.aws_secret_access_key
65
+ })
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,29 @@
1
+ module MultiEncoder
2
+ module Storage
3
+ module FileSystem
4
+
5
+ def url
6
+ if defined? Rails
7
+ file_path.to_s.gsub Rails.root.join('public').to_s, ''
8
+ end
9
+ end
10
+
11
+ def root
12
+ defined?(Rails) ? Rails.root : Pathname.new('/tmp')
13
+ end
14
+
15
+ def directory
16
+ root.join 'public', 'system', type, *fingerprint
17
+ end
18
+
19
+ def file_path
20
+ Pathname.new "#{directory.join(@contents)}.#{MultiEncoder::BarcodeImage::OUTPUT_FORMAT}"
21
+ end
22
+
23
+ def exists?
24
+ file_path.exist?
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,3 @@
1
+ module MultiEncoder
2
+ VERSION = "0.0.9"
3
+ end
@@ -0,0 +1,62 @@
1
+ require 'spec_helper'
2
+
3
+ module MultiEncoder
4
+
5
+ describe BarcodeImage do
6
+
7
+ let(:barcode) { BarcodeImage.new 'thesisist'}
8
+
9
+ context "Filesystem storage" do
10
+ after do
11
+ root_dir = barcode.root.join 'public'
12
+ FileUtils.rm_rf root_dir if root_dir.exist?
13
+ end
14
+
15
+ specify 'exsits? is false' do
16
+ barcode.exists?.should be_false
17
+ end
18
+
19
+ it 'should write the file if href is requested' do
20
+ barcode.should_receive(:write)
21
+ barcode.href
22
+ end
23
+
24
+ it 'writes the png to the filesystem' do
25
+ barcode.write
26
+ barcode.exists?.should be_true
27
+ end
28
+
29
+ it 'does not write the png twice' do
30
+ barcode.write
31
+ barcode.should_not_receive(:write)
32
+ barcode.href
33
+ end
34
+ end
35
+
36
+ context "AWS storage" do
37
+ before do
38
+ MultiEncoder::Storage.configure do |c|
39
+ c.destination = :aws
40
+ c.aws_bucket_prefix = ENV['AWS_BUCKET_PREFIX']
41
+ c.aws_access_key = ENV['AWS_ACCESS_KEY']
42
+ c.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
43
+ end
44
+ end
45
+
46
+ after do
47
+ barcode.delete if barcode.exists?
48
+ end
49
+
50
+ specify 'exsits? is false' do
51
+ barcode.exists?.should be_false
52
+ end
53
+
54
+ it 'saves to as3' do
55
+ barcode.write
56
+ barcode.exists?.should be_true
57
+ barcode.should_not_receive(:write)
58
+ barcode.href.should match(/^http/)
59
+ end
60
+ end
61
+ end
62
+ end