backframe 0.0.22 → 0.0.23
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/backframe/image_cache.rb +129 -0
- data/lib/backframe/version.rb +1 -1
- data/lib/backframe.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 164aed2c6cdb4b3e52b7443072cad51c4942a12e
|
4
|
+
data.tar.gz: a984923f33796da1f5a2667107373286b7fa87ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61d46c442596d02acee9893393a76aed47979695d1b1ca44d44dbceed7b1d7dd26fd260736c76526a6ecbedb14310e0656a045a7f691efab9fad9bf20225c1c0
|
7
|
+
data.tar.gz: dec07e74c0db1b81f366652d075c419277d4805d80f216b972cb705ce2f6214d2bc8885f1ca827a47f33ff636e64adf3d61ca559cb50c636d1eee1a7aea94fb8
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Backframe
|
4
|
+
|
5
|
+
class ImageCache
|
6
|
+
|
7
|
+
def initialize(filepath, conversions)
|
8
|
+
@filepath = filepath
|
9
|
+
@conversions = conversions
|
10
|
+
end
|
11
|
+
|
12
|
+
def process!
|
13
|
+
normalized = normalize_conversions(conversions)
|
14
|
+
fullpath = fullpath(filepath)
|
15
|
+
content_type = content_type(filepath)
|
16
|
+
data = download(fullpath)
|
17
|
+
oriented = auto_orient(data)
|
18
|
+
dimensions = dimensions(oriented)
|
19
|
+
command = expand(normalized)
|
20
|
+
converted = execute(oriented, command)
|
21
|
+
OpenStruct.new({ :success => true, :data => converted, :content_type => content_type })
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :filepath, :conversions
|
27
|
+
|
28
|
+
#################### CONVERSION HANDLING ####################
|
29
|
+
|
30
|
+
def normalize_conversions(string)
|
31
|
+
output = []
|
32
|
+
string.upcase.split("-").each do |part|
|
33
|
+
if part == 'PREVIEW'
|
34
|
+
output << { :width => 250, :density => 2 }
|
35
|
+
elsif part == 'TINY'
|
36
|
+
output << { :fit => { :width => 20, :height => 20 }, :density => 2 }
|
37
|
+
elsif part == 'SMALL'
|
38
|
+
output << { :fit => { :width => 40, :height => 40 }, :density => 2 }
|
39
|
+
elsif part == 'MEDIUM'
|
40
|
+
output << { :fit => { :width => 250, :height => 250 }, :density => 2 }
|
41
|
+
elsif matches = part.match(/^F(\d*)X(\d*)(D(\d*))?$/)
|
42
|
+
density = (matches[3]) ? matches[4].to_i : 1
|
43
|
+
output << { :fit => { :width => matches[1].to_i, :height => matches[2].to_i }, :density => density }
|
44
|
+
elsif matches = part.match(/^W(\d*)(D(\d*))?$/)
|
45
|
+
density = (matches[2]) ? matches[3].to_i : 1
|
46
|
+
output << { :width => matches[1].to_i, :density => density }
|
47
|
+
elsif matches = part.match(/^H(\d*)(D(\d*))?$/)
|
48
|
+
density = (matches[2]) ? matches[3].to_i : 1
|
49
|
+
output << { :height => matches[1].to_i, :density => density }
|
50
|
+
elsif matches = part.match(/^C(\d*)X(\d*)X(\d*)X(\d*)(D(\d*))?$/)
|
51
|
+
density = (matches[4]) ? matches[5].to_i : 1
|
52
|
+
output << { :crop => { :width => matches[1].to_i, :height => matches[2].to_i, :x => matches[3].to_i, :y => matches[4].to_i, :density => density } }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
output
|
56
|
+
end
|
57
|
+
|
58
|
+
#################### ASSET HANDLING ####################
|
59
|
+
|
60
|
+
def fullpath(path)
|
61
|
+
File.exist?("#{Rails.root}/public/#{path}") ? "#{Rails.root}/public/#{path}" : "#{Rails.application.config.cdn_url}/#{path}"
|
62
|
+
end
|
63
|
+
|
64
|
+
def download(path)
|
65
|
+
open(path).read
|
66
|
+
end
|
67
|
+
|
68
|
+
def auto_orient(data)
|
69
|
+
execute(data, '-auto-orient')
|
70
|
+
end
|
71
|
+
|
72
|
+
def content_type(filepath)
|
73
|
+
ext = extension(filepath)
|
74
|
+
"image/#{ext}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def extension(filepath)
|
78
|
+
filepath.match(/.*\.([a-z]*)$/)[1]
|
79
|
+
end
|
80
|
+
|
81
|
+
def dimensions(data)
|
82
|
+
tmpfile = tmpfile(data)
|
83
|
+
command = "identify -format '%wx%h,%[exif:orientation]' '#{tmpfile.path}'"
|
84
|
+
output = `#{command}`
|
85
|
+
matches = output.match(/^(\d*)x(\d*)/)
|
86
|
+
{ :width => matches[1], :height => matches[2] }
|
87
|
+
end
|
88
|
+
|
89
|
+
def expand(conversions)
|
90
|
+
command = []
|
91
|
+
conversions.each do |conversion|
|
92
|
+
if conversion.key?(:fit)
|
93
|
+
width = conversion[:fit][:width] * conversion[:density]
|
94
|
+
height = conversion[:fit][:height] * conversion[:density].to_i
|
95
|
+
command << "-resize \"#{width}x#{height}^\" -gravity center -crop '#{width}x#{height}+0+0'"
|
96
|
+
elsif conversion.key?(:height)
|
97
|
+
height = conversion[:height] * conversion[:density].to_i
|
98
|
+
command << "-resize \"x#{height}\""
|
99
|
+
elsif conversion.key?(:width)
|
100
|
+
width = conversion[:width] * conversion[:density].to_i
|
101
|
+
command << "-resize \"#{width}\""
|
102
|
+
elsif conversion.key?(:crop)
|
103
|
+
command << "-crop '#{parts[1]}x#{parts[2]}+#{parts[3]}+#{parts[4]}'"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
command.join(' ')
|
107
|
+
end
|
108
|
+
|
109
|
+
#################### UTILITIES ####################
|
110
|
+
|
111
|
+
def tmpfile(data)
|
112
|
+
filename = SecureRandom.hex(32).to_s.upcase[0,8]
|
113
|
+
tmpfile = Tempfile.new(filename, :encoding => 'ascii-8bit')
|
114
|
+
tmpfile.write(data)
|
115
|
+
tmpfile.close if tmpfile && !tmpfile.closed?
|
116
|
+
tmpfile
|
117
|
+
end
|
118
|
+
|
119
|
+
def execute(data, command)
|
120
|
+
tmpfile = tmpfile(data)
|
121
|
+
command = "convert '#{tmpfile.path}' #{command} '#{tmpfile.path}'"
|
122
|
+
Rails.logger.debug(command)
|
123
|
+
output = `#{command}`
|
124
|
+
IO.read(tmpfile.path)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
data/lib/backframe/version.rb
CHANGED
data/lib/backframe.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backframe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.23
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Kops
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-05-
|
12
|
+
date: 2016-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: write_xlsx
|
@@ -113,6 +113,7 @@ files:
|
|
113
113
|
- lib/backframe/activerecord/default_values.rb
|
114
114
|
- lib/backframe/activerecord/filter_sort.rb
|
115
115
|
- lib/backframe/activerecord/migration.rb
|
116
|
+
- lib/backframe/image_cache.rb
|
116
117
|
- lib/backframe/mime.rb
|
117
118
|
- lib/backframe/models/activation.rb
|
118
119
|
- lib/backframe/models/activity.rb
|