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.
@@ -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,8 @@
1
+ $: << File.dirname(__FILE__) + '/multi_encoder'
2
+
3
+ require 'version'
4
+ require 'qrencoder'
5
+ require 'gbarcode'
6
+ require 'storage'
7
+ require 'images'
8
+ 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,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,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,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,3 @@
1
+ module MultiEncoder
2
+ VERSION = "0.0.5"
3
+ 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