backframe 0.0.22 → 0.0.23

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.
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