multi_encoder 0.0.5
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.
- data/.gitignore +22 -0
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +88 -0
- data/Rakefile +6 -0
- data/ext/gbarcode/LICENSE_GNU_BARCODE +339 -0
- data/ext/gbarcode/README_GNU_BARCODE +93 -0
- data/ext/gbarcode/barcode.h +119 -0
- data/ext/gbarcode/barcode.i +15 -0
- data/ext/gbarcode/barcode_wrap.c +3192 -0
- data/ext/gbarcode/codabar.c +182 -0
- data/ext/gbarcode/code128.c +607 -0
- data/ext/gbarcode/code39.c +173 -0
- data/ext/gbarcode/code93.c +213 -0
- data/ext/gbarcode/ean.c +774 -0
- data/ext/gbarcode/extconf.rb +6 -0
- data/ext/gbarcode/i25.c +164 -0
- data/ext/gbarcode/library.c +244 -0
- data/ext/gbarcode/msi.c +155 -0
- data/ext/gbarcode/pcl.c +200 -0
- data/ext/gbarcode/plessey.c +164 -0
- data/ext/gbarcode/ps.c +272 -0
- data/ext/gbarcode/svg.c +174 -0
- data/lib/multi_encoder.rb +8 -0
- data/lib/multi_encoder/helpers.rb +13 -0
- data/lib/multi_encoder/images.rb +3 -0
- data/lib/multi_encoder/images/abstract.rb +32 -0
- data/lib/multi_encoder/images/barcode.rb +39 -0
- data/lib/multi_encoder/images/qrcode.rb +16 -0
- data/lib/multi_encoder/railtie.rb +11 -0
- data/lib/multi_encoder/storage.rb +18 -0
- data/lib/multi_encoder/storage/aws.rb +73 -0
- data/lib/multi_encoder/storage/filesystem.rb +31 -0
- data/lib/multi_encoder/version.rb +3 -0
- data/multi_encoder.gemspec +35 -0
- data/spec/multi_encoder/barcode_image_spec.rb +57 -0
- data/spec/multi_encoder/qrcode_image_spec.rb +58 -0
- data/spec/spec_helper.rb +9 -0
- metadata +223 -0
data/ext/gbarcode/svg.c
ADDED
@@ -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,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,32 @@
|
|
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
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module MultiEncoder
|
4
|
+
class BarcodeImage < AbstractImage
|
5
|
+
|
6
|
+
DEFAULT_ENCODING = Gbarcode::BARCODE_39 | 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
|
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,18 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
|
3
|
+
module MultiEncoder
|
4
|
+
module Storage
|
5
|
+
mattr_reader :destination
|
6
|
+
|
7
|
+
def self.destination=(dest)
|
8
|
+
unless [:filesystem, :aws].include? dest
|
9
|
+
raise ArgumentError.new('Unsopported storage distination mate')
|
10
|
+
end
|
11
|
+
@@destination = dest
|
12
|
+
end
|
13
|
+
self.destination = :filesystem
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'storage/aws'
|
18
|
+
require 'storage/filesystem'
|
@@ -0,0 +1,73 @@
|
|
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: "multi-encoder-#{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 eps_path
|
57
|
+
"/tmp/#{@contents}.eps"
|
58
|
+
end
|
59
|
+
|
60
|
+
def filename
|
61
|
+
fingerprint.join
|
62
|
+
end
|
63
|
+
|
64
|
+
def connection
|
65
|
+
::Fog::Storage.new({
|
66
|
+
provider: 'AWS',
|
67
|
+
aws_access_key_id: ENV['AWS_ACCESS_KEY'],
|
68
|
+
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
|
69
|
+
})
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module MultiEncoder
|
2
|
+
module Storage
|
3
|
+
module FileSystem
|
4
|
+
|
5
|
+
def url
|
6
|
+
file_path.to_s.gsub Rails.root.join('public').to_s, ''
|
7
|
+
end
|
8
|
+
|
9
|
+
def root
|
10
|
+
defined?(Rails) ? Rails.root : Pathname.new('/tmp')
|
11
|
+
end
|
12
|
+
|
13
|
+
def directory
|
14
|
+
root.join 'public', 'system', type, *fingerprint
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_path
|
18
|
+
Pathname.new "#{directory.join(@contents)}.#{MultiEncoder::BarcodeImage::OUTPUT_FORMAT}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def exists?
|
22
|
+
file_path.exist?
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def eps_path
|
27
|
+
"/tmp/#{@contents}.eps"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'multi_encoder/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "multi_encoder"
|
8
|
+
spec.version = MultiEncoder::VERSION
|
9
|
+
spec.authors = ["Juan Alvarez"]
|
10
|
+
spec.email = ["alce@mac.com"]
|
11
|
+
spec.description = %q{QRCode and Barcode generator for rails}
|
12
|
+
spec.summary = %q{QRCode and Barcode generator for rails}
|
13
|
+
spec.homepage = "https://github.com/alce/multi_encoder"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib", "ext"]
|
20
|
+
spec.extensions = ["ext/gbarcode/extconf.rb"]
|
21
|
+
|
22
|
+
spec.required_ruby_version = ">= 1.9.2"
|
23
|
+
spec.requirements << "ImageMagick"
|
24
|
+
|
25
|
+
spec.add_dependency "qrencoder", "= 1.4.1"
|
26
|
+
spec.add_dependency "activesupport", ">= 3.0.0"
|
27
|
+
spec.add_dependency "actionpack", ">= 3.0.0"
|
28
|
+
spec.add_dependency "fog", "~> 1.10.0"
|
29
|
+
|
30
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
31
|
+
spec.add_development_dependency "rake"
|
32
|
+
spec.add_development_dependency "rspec"
|
33
|
+
spec.add_development_dependency "rake-compiler"
|
34
|
+
|
35
|
+
end
|