highcharts-rails 3.0.1 → 3.0.1.5.pre1
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/CHANGELOG.markdown +4 -0
- data/README.markdown +48 -0
- data/highcharts-rails.gemspec +1 -0
- data/lib/highcharts-rails.rb +1 -1
- data/lib/highcharts/export_endpoint.rb +122 -0
- data/lib/highcharts/version.rb +1 -1
- metadata +23 -5
- data.tar.gz.asc +0 -18
- metadata.gz.asc +0 -18
data/CHANGELOG.markdown
CHANGED
data/README.markdown
CHANGED
@@ -45,6 +45,54 @@ Or one of the themes
|
|
45
45
|
|
46
46
|
Other than that, refer to the [Highcharts documentation](http://highcharts.com/documentation/how-to-use)
|
47
47
|
|
48
|
+
## Export endpoint
|
49
|
+
|
50
|
+
This gem contains a Rack endpoint for converting the chart to a downloadable file.
|
51
|
+
It is not required by default, so to use it, `require
|
52
|
+
'highcharts/export_endpoint'`
|
53
|
+
|
54
|
+
The endpoint is basically a port of the [PHP version made available](https://github.com/highslide-software/highcharts.com/blob/master/exporting-server/php/php-batik/index.php).
|
55
|
+
It currently needs a lot of cleanup, but it is working fine for me. Your milage
|
56
|
+
may vary.
|
57
|
+
|
58
|
+
It uses [Apache Batik](http://xmlgraphics.apache.org/batik/) for the conversion, which must be
|
59
|
+
installed separately, as well as a Java Runtime Environment.
|
60
|
+
|
61
|
+
It expects to find a JRE in `/usr/bin/java`, and Batik in
|
62
|
+
`/usr/share/java/batik-rasterizer.jar`, but both paths are configurable.
|
63
|
+
|
64
|
+
Example usage in Rails:
|
65
|
+
|
66
|
+
# config/routes.rb
|
67
|
+
require 'highcharts/export_endpoint'
|
68
|
+
|
69
|
+
MyRailsApp::Application.routes.draw do
|
70
|
+
...
|
71
|
+
mount Highcharts::ExportEndpoint.new({
|
72
|
+
java_path: "/usr/bin/java",
|
73
|
+
batik: "/usr/share/java/batik-rasterizer.jar"
|
74
|
+
}), at: "highcharts-export"
|
75
|
+
...
|
76
|
+
end
|
77
|
+
|
78
|
+
# When rendering the chart
|
79
|
+
new Highcharts.Chart({
|
80
|
+
...
|
81
|
+
exporting: {
|
82
|
+
url: "/highcharts-export",
|
83
|
+
...
|
84
|
+
}
|
85
|
+
})
|
86
|
+
|
87
|
+
### Cocaine
|
88
|
+
|
89
|
+
The exporting endpoint uses [Cocaine](https://github.com/thoughtbot/cocaine) for
|
90
|
+
handling the command lines and arguments and so on.
|
91
|
+
|
92
|
+
I don't know a way to get optional dependencies in the gemspec, so for now
|
93
|
+
that gets added whether you want it or not. I'd like to get this fixed,
|
94
|
+
but would also like to avoid `begin; require 'cocaine'; rescue LoadError; ...; end` and similar hacks.
|
95
|
+
|
48
96
|
## Licensing
|
49
97
|
|
50
98
|
Highcharts, which makes up the majority of this gem, has [its own, separate licensing](http://highcharts.com/license).
|
data/highcharts-rails.gemspec
CHANGED
data/lib/highcharts-rails.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
require 'highcharts/version'
|
2
|
-
require 'highcharts/rails'
|
2
|
+
require 'highcharts/rails'
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'cocaine'
|
3
|
+
|
4
|
+
module Highcharts
|
5
|
+
class ExportEndpoint
|
6
|
+
class InsecureSVGError < ArgumentError; end
|
7
|
+
class MissingLibrary < RuntimeError; end
|
8
|
+
class FailedToGenerateChart < RuntimeError; end
|
9
|
+
class InvalidType < ArgumentError; end
|
10
|
+
|
11
|
+
attr_reader :output, :options
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@options = default_options.merge(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def default_options
|
18
|
+
{
|
19
|
+
java_path: "/usr/bin/java",
|
20
|
+
batik: "/usr/share/java/batik-rasterizer.jar",
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(env)
|
25
|
+
dup._call(env)
|
26
|
+
end
|
27
|
+
|
28
|
+
def _call(env)
|
29
|
+
with_rescues do
|
30
|
+
raise MissingLibrary.new("Could not find batik-rasterizer.jar in #{options[:batik].inspect}") unless File.exists?(options[:batik].to_s)
|
31
|
+
|
32
|
+
request = Rack::Request.new(env)
|
33
|
+
|
34
|
+
filename = request.params["filename"].to_s
|
35
|
+
filename = "chart" if filename.blank? || filename !~ /\A[A-Za-z0-9\-_ ]+\Z/
|
36
|
+
|
37
|
+
type = request.params["type"].to_s
|
38
|
+
width = request.params["width"].to_i
|
39
|
+
svg = request.params["svg"].to_s
|
40
|
+
|
41
|
+
raise InsecureSVGError.new if svg.index("<!ENTITY") || svg.index("<!DOCTYPE")
|
42
|
+
|
43
|
+
if type == "image/svg+xml"
|
44
|
+
# We were sent SVG from the client, so can just render that back
|
45
|
+
return [200, {
|
46
|
+
'Content-Disposition' => "attachment; filename=\"#{filename}.svg\"",
|
47
|
+
'Content-Type' => 'image/svg+xml'
|
48
|
+
}, [svg]]
|
49
|
+
end
|
50
|
+
|
51
|
+
width = width > 0 ? width.to_s : "600"
|
52
|
+
extension = case type
|
53
|
+
when "image/png" then "png"
|
54
|
+
when "image/jpeg" then "jpg"
|
55
|
+
when "application/pdf" then "pdf"
|
56
|
+
when "image/svg+xml" then "svg"
|
57
|
+
else raise InvalidType.new("#{type} is not a valid type.")
|
58
|
+
end
|
59
|
+
|
60
|
+
input = write_svg_to_file(svg)
|
61
|
+
@output = create_output_file(extension)
|
62
|
+
|
63
|
+
command.run(batik: options[:batik], outfile: output.path, type: type, width: width, infile: input.path)
|
64
|
+
input.close
|
65
|
+
content_length = output.size
|
66
|
+
output.rewind
|
67
|
+
|
68
|
+
raise FailedToGenerateChart.new("Nothing written to file") if !File.exists?(output.path) || content_length < 10
|
69
|
+
|
70
|
+
Rack::Response.new(self, 200, {
|
71
|
+
'Content-Disposition' => "attachment; filename=\"#{filename}.#{extension}\"",
|
72
|
+
'Content-Type' => type
|
73
|
+
}).finish
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Pass the block along to the output file, and
|
78
|
+
# make sure to close the file afterwards
|
79
|
+
def each(&block)
|
80
|
+
output.each(&block)
|
81
|
+
ensure
|
82
|
+
output.close
|
83
|
+
end
|
84
|
+
|
85
|
+
def command
|
86
|
+
Cocaine::CommandLine.new(options[:java_path], "-jar :batik -m :type -d :outfile -w :width :infile")
|
87
|
+
end
|
88
|
+
|
89
|
+
def write_svg_to_file(contents)
|
90
|
+
file = ::Tempfile.new(["highcharts-input", ".svg"], Dir.tmpdir, encoding: 'utf-8')
|
91
|
+
file.puts contents
|
92
|
+
file.flush
|
93
|
+
file
|
94
|
+
end
|
95
|
+
|
96
|
+
def create_output_file(extension)
|
97
|
+
file = ::Tempfile.new(["highcharts-chart", ".#{extension}"])
|
98
|
+
file.binmode
|
99
|
+
file
|
100
|
+
end
|
101
|
+
|
102
|
+
def with_rescues
|
103
|
+
yield
|
104
|
+
rescue Highcharts::ExportEndpoint::InsecureSVGError => e
|
105
|
+
[400, {'Content-Type' => 'text/plain'}, ["The posted SVG could contain code for a malicious attack"]]
|
106
|
+
rescue Highcharts::ExportEndpoint::InvalidType => e
|
107
|
+
[400, {'Content-Type' => 'text/plain'}, [e]]
|
108
|
+
rescue Cocaine::CommandNotFoundError => e
|
109
|
+
[503, {'Content-Type' => 'text/plain'}, ["Unable to find required binary. #{e}"]]
|
110
|
+
rescue Highcharts::ExportEndpoint::MissingLibrary => e
|
111
|
+
[503, {'Content-Type' => 'text/plain'}, ["Unable to find required library. #{e}"]]
|
112
|
+
rescue Highcharts::ExportEndpoint::FailedToGenerateChart => e
|
113
|
+
[500, {'Content-Type' => 'text/plain'}, ["Failed to generate chart. More details may be available in the server logs."]]
|
114
|
+
rescue => e
|
115
|
+
[500, {'Content-Type' => 'text/plain'}, ["Something went wrong. More details may be available in the server logs."]]
|
116
|
+
end
|
117
|
+
|
118
|
+
def error(code, message)
|
119
|
+
[code, {}, [message].flatten]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
data/lib/highcharts/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: highcharts-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
version: 3.0.1
|
4
|
+
prerelease: 8
|
5
|
+
version: 3.0.1.5.pre1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Per Christian B. Viken
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -27,6 +27,22 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '3.1'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: cocaine
|
32
|
+
type: :runtime
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.4.0
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.4.0
|
30
46
|
- !ruby/object:Gem::Dependency
|
31
47
|
name: bundler
|
32
48
|
type: :development
|
@@ -91,6 +107,7 @@ files:
|
|
91
107
|
- app/assets/javascripts/highcharts/themes/skies.js
|
92
108
|
- highcharts-rails.gemspec
|
93
109
|
- lib/highcharts-rails.rb
|
110
|
+
- lib/highcharts/export_endpoint.rb
|
94
111
|
- lib/highcharts/rails.rb
|
95
112
|
- lib/highcharts/version.rb
|
96
113
|
homepage: http://northblue.org/
|
@@ -108,9 +125,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
126
|
none: false
|
110
127
|
requirements:
|
111
|
-
- - ! '
|
128
|
+
- - ! '>'
|
112
129
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
130
|
+
version: 1.3.1
|
114
131
|
requirements: []
|
115
132
|
rubyforge_project:
|
116
133
|
rubygems_version: 1.8.24
|
@@ -118,3 +135,4 @@ signing_key:
|
|
118
135
|
specification_version: 3
|
119
136
|
summary: Gem for easily adding Highcharts to the Rails Asset Pipeline
|
120
137
|
test_files: []
|
138
|
+
has_rdoc:
|
data.tar.gz.asc
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
|
3
|
-
Comment: GPGTools - http://gpgtools.org
|
4
|
-
|
5
|
-
iQIcBAABAgAGBQJRZCX4AAoJEH1ncb0Txu7XWUgQAKSwMYAj6ECNovM5FQnW9Xrs
|
6
|
-
84xcCzwhur/YD5/jOVxl85tTVmboBRdVPp53CmsuquGYUMRrrXRobt6C6/hMp4DP
|
7
|
-
imZ72AL1ZjYjFPCjHXuJzVXsiwGKLE7SdhGo01l3+69rhGwurpA3fZ9d1DaO+YZ6
|
8
|
-
BlwHypnXlQGOPapB7Eh2V/U5UbZi3V1kLTlUaJyUu914p99Jo6MutHobM7aShMOx
|
9
|
-
hdqn+ZqN0ha2ourKFk+wJKWTMKe4jvlp9SDrOLe9JY+AJ9zfCns+QFwFJQaC6+VE
|
10
|
-
DlxQVt33q2nl+W7DdQr23kBM9/Vr9tQzNPE4E17NvGGZBwTZGxPSwPVzoO1ajRVH
|
11
|
-
MwzbcKrqo1AkRDY5th1Hf2WAyruQ62DlbHF/5luJo1ezsuakus74/JWIo36BXKdp
|
12
|
-
R20yR4hnQflxGj9BwOUZ5oroG4+PvIBHEfy9no7R600u5Q/RzCj+C3MCekYTMyKV
|
13
|
-
KurzDyFfanNU1RNVkV2rJAAB2373cCZRiORqi7HNfdjkzzJiuFCTIWNkEo2eLPx4
|
14
|
-
KlCZL5czNj1fgiEZclMGqv7Le5RXR3SuQXzxTw/cpEbvy5Zwm1zUGWankUQb+TEg
|
15
|
-
7hP/wQD5E8zJ/ZYbYjXCnS2K8e59+EOc5DcGpaPT9ELSmaCDlG3AvNnKuFS3g+nj
|
16
|
-
pm1NAKtYl8Y62Yf35hba
|
17
|
-
=qJvF
|
18
|
-
-----END PGP SIGNATURE-----
|
metadata.gz.asc
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
-----BEGIN PGP SIGNATURE-----
|
2
|
-
Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
|
3
|
-
Comment: GPGTools - http://gpgtools.org
|
4
|
-
|
5
|
-
iQIbBAABAgAGBQJRZCX4AAoJEH1ncb0Txu7X/t4P9R5ENkevewpnG4BmYF2THRJd
|
6
|
-
bws9bcN4bPeSYpceQBphAnFEVQfL+QAXzTweHHw5nk/mGg1iPl18ySyWWeWdSq+G
|
7
|
-
bbjIAqcG9IdeX/ItzzWXn47WvXhjsu7s6LZ3vP57Y7q0+AcHW45Tl90p1XYSFI3D
|
8
|
-
1Cx1lh6ljZ7JtsNe8j3lnxHq/gL29RA+f4u+k8u+jdas69I+dpcc5EiuI+9C2AnB
|
9
|
-
usTAafb8Q7lVwsiv9Mkgufai5c3J9LkSZOjLF8GhoXSVE/xybAFpFs4SzyoGKm6K
|
10
|
-
C/xXtZV+78/sv5WUm1UK//T/9LXO0jebYiE5/WZgJZDnt/zDVJDYU5Nmsr9IF1ty
|
11
|
-
QYRHUO3iMZODpDyeRxKDEL1DMYoKrZJbvZqbJx+0FmYSfvxqcyX0cKoIFYOLhZUo
|
12
|
-
rxWKoEw3otoWiJhKJPC6A+CkYS3NxOjHjixhRs6T59Dxo5Hb5dYO9cF823feCIGU
|
13
|
-
ge/FlB4wBTJeFrSSMTjl/ABU5Vrdfx2/Ng5e/nyAwFaki8p4n8CRNnfYvsJ8SvQC
|
14
|
-
8jAspjcyeiXzQx27ujgny45NTYNMkfrl01OLHsRjVaXnTw97z8+96QQaCV/5M0tA
|
15
|
-
ZZtWxDI2BTWXIkzBp0BzyAq1utDiS++CE/p3nEhlDGRMwj49iAg3JD3mfS0/OfmB
|
16
|
-
cHbhD6RW3WPUEGUKW4M=
|
17
|
-
=LkjG
|
18
|
-
-----END PGP SIGNATURE-----
|