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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0ba1e52c321642997db0b9688fe95319d6cda0c8
4
- data.tar.gz: 1aad76b7e76e089e362f6da0c523a4b0109713e0
3
+ metadata.gz: 164aed2c6cdb4b3e52b7443072cad51c4942a12e
4
+ data.tar.gz: a984923f33796da1f5a2667107373286b7fa87ac
5
5
  SHA512:
6
- metadata.gz: c5996128d3b7f7660dffd109a555ec315ddfadbd84b934ecf770a0e551551430239fa70ccf47a75003e7ad8c4e3086cf09a1e954480aa62ad0b19648f21533a9
7
- data.tar.gz: c1fbeb7c121da645bd4535aa1f2d8c1874bd7142c9c5288df2f85f1eec8c3a36d74e9b5f7348595e863faee1b265b54d53fb73fb565fd391b6d15775339ba5c3
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
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Backframe
4
- VERSION = '0.0.22'
4
+ VERSION = '0.0.23'
5
5
  end
data/lib/backframe.rb CHANGED
@@ -22,6 +22,7 @@ require 'backframe/models/activity'
22
22
  require 'backframe/models/activation'
23
23
  require 'backframe/models/reset'
24
24
  require 'backframe/serializers/activity_serializer'
25
+ require 'backframe/image_cache'
25
26
 
26
27
  module Backframe
27
28
 
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.22
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-15 00:00:00.000000000 Z
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