multi_encoder 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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