barcode_encoder 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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