meme_captain 0.0.2 → 0.0.3

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/config.ru CHANGED
@@ -1,5 +1,10 @@
1
1
  $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
2
 
3
+ require 'rack'
4
+
3
5
  require 'meme_captain'
4
6
 
7
+ use Rack::ConditionalGet
8
+ use Rack::Sendfile
9
+
5
10
  run MemeCaptain::Server
@@ -0,0 +1,15 @@
1
+ module MemeCaptain
2
+
3
+ # A Rack body for an object on the filesystem.
4
+ class FileBody
5
+
6
+ def initialize(path); @to_path = path; end
7
+
8
+ def each
9
+ open(to_path, 'rb') { |f| yield f.read(8192) until f.eof? }
10
+ end
11
+
12
+ attr_reader :to_path
13
+ end
14
+
15
+ end
@@ -5,32 +5,60 @@ module MemeCaptain
5
5
 
6
6
  def initialize(root_dir); @root_dir = root_dir; end
7
7
 
8
- # Get data from cache.
8
+ # Get the data of a file in the cache.
9
9
  #
10
- # On cache miss, if block given call block to get data from source and
10
+ # On cache miss, if block given, call block to get data from source and
11
11
  # cache it. If no block given return nil on cache miss.
12
- def get(id)
13
- file_path = id_path(id)
12
+ #
13
+ # If suffixes are passed in, loop through them and search for base id +
14
+ # suffix on filesystem. Return the data of the first found.
15
+ def get_data(id, suffixes=[''])
16
+ suffixes.each do |suffix|
17
+ file_path = id_path(id, suffix)
18
+ return open(file_path, 'rb') { |f| f.read } if File.exist?(file_path)
19
+ end
20
+
21
+ # not found in cache
22
+ if block_given?
23
+ data = yield
24
+ put(id, data)
25
+ data
26
+ end
27
+ end
14
28
 
15
- if File.exist?(file_path)
16
- open(file_path, 'rb') { |f| f.read }
17
- else
18
- put(id, yield) if block_given?
29
+ # Get the path of a file in the cache.
30
+ #
31
+ # On cache miss, if block given, call block to get data from source and
32
+ # cache it. If no block given return nil on cache miss.
33
+ #
34
+ # If suffixes are passed in, loop through them and search for base id +
35
+ # suffix on filesystem. Return the first found.
36
+ def get_path(id, suffixes=[''])
37
+ suffixes.each do |suffix|
38
+ file_path = id_path(id, suffix)
39
+ return file_path if File.exist?(file_path)
19
40
  end
41
+
42
+ # not found in cache
43
+ put(id, yield) if block_given?
20
44
  end
21
45
 
22
- # Put data in the cache and return it.
46
+ # Put data in the cache and return its path.
23
47
  def put(id, data)
24
- open(id_path(id), 'w') do |f|
48
+ mime_type = MemeCaptain.mime_type(data)
49
+ file_path = id_path(id, ".#{mime_type.extensions[0]}")
50
+
51
+ open(file_path, 'w') do |f|
25
52
  f.flock(File::LOCK_EX)
26
53
  f.write(data)
27
54
  f.flock(File::LOCK_UN)
28
55
  end
29
- data
56
+ file_path
30
57
  end
31
58
 
32
- def id_path(id)
33
- File.join(root_dir, File.expand_path(id, '/'))
59
+ # Get the cache file path for an id with optional suffix added.
60
+ def id_path(id, suffix=nil)
61
+ File.join(root_dir, File.expand_path(id, '/')) + suffix.to_s
34
62
  end
35
63
 
36
64
  attr_reader :root_dir
@@ -1,16 +1,20 @@
1
+ require 'mime/types'
2
+
1
3
  module MemeCaptain
2
4
 
3
5
  module_function
4
6
 
5
- # Determine content type from blob of image data.
6
- def content_type(img_data)
7
- if img_data[0,2].unpack('H4')[0] == 'ffd8'
7
+ # Determine mime type from blob of image data.
8
+ def mime_type(img_data)
9
+ mime_type_s = if img_data[0,2].unpack('H4')[0] == 'ffd8'
8
10
  'image/jpeg'
9
11
  elsif img_data[0,8].unpack('H16')[0] == '89504e470d0a1a0a'
10
12
  'image/png'
11
13
  elsif %w{474946383961 474946383761}.include?(img_data[0,6].unpack('H12')[0])
12
14
  'image/gif'
13
15
  end
16
+
17
+ MIME::Types[mime_type_s][0]
14
18
  end
15
19
 
16
20
  end
@@ -9,6 +9,8 @@ module MemeCaptain
9
9
 
10
10
  class Server < Sinatra::Base
11
11
 
12
+ ImageExts = %w{.jpeg .gif .png}
13
+
12
14
  get '/' do
13
15
  @img_tag = if params[:u]
14
16
  "<img src=\"#{h request.fullpath.sub(%r{^/}, '/i')}\" />"
@@ -29,22 +31,22 @@ module MemeCaptain
29
31
  @source_cache ||= MemeCaptain::FilesystemCache.new('img_cache/source')
30
32
 
31
33
  processed_id = Digest::SHA1.hexdigest(params.sort.map(&:join).join)
32
- processed_img_data = @processed_cache.get(processed_id) {
34
+ processed_cache_path = @processed_cache.get_path(processed_id, ImageExts) {
33
35
  source_id = Digest::SHA1.hexdigest(params[:u])
34
- source_img_data = @source_cache.get(source_id) {
36
+ source_img_data = @source_cache.get_data(source_id, ImageExts) {
35
37
  Curl::Easy.perform(params[:u]).body_str
36
38
  }
39
+
37
40
  MemeCaptain.meme(source_img_data, params[:tt], params[:tb]).to_blob {
38
41
  self.quality = 100
39
42
  }
40
43
  }
41
44
 
42
45
  headers = {
43
- 'Content-Type' => MemeCaptain.content_type(processed_img_data),
44
- 'ETag' => "\"#{Digest::SHA1.hexdigest(processed_img_data)}\"",
46
+ 'Content-Type' => MIME::Types.type_for(processed_cache_path)[0].to_s,
45
47
  }
46
48
 
47
- [ 200, headers, processed_img_data ]
49
+ [ 200, headers, MemeCaptain::FileBody.new(processed_cache_path) ]
48
50
  end
49
51
 
50
52
  helpers do
data/lib/meme_captain.rb CHANGED
@@ -1,4 +1,5 @@
1
- require 'meme_captain/content_type'
1
+ require 'meme_captain/file_body'
2
2
  require 'meme_captain/meme'
3
+ require 'meme_captain/mime_type'
3
4
  require 'meme_captain/server'
4
5
  require 'meme_captain/filesystem_cache'
data/meme_captain.gemspec CHANGED
@@ -4,7 +4,7 @@ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'meme_captain'
7
- s.version = '0.0.2'
7
+ s.version = '0.0.3'
8
8
  s.summary = 'create meme images'
9
9
  s.description = s.summary
10
10
  s.homepage = 'https://github.com/mmb/meme_captain'
@@ -15,6 +15,8 @@ Gem::Specification.new do |s|
15
15
 
16
16
  %w{
17
17
  curb
18
+ mime-types
19
+ rack
18
20
  rmagick
19
21
  sinatra
20
22
  }.each { |g| s.add_dependency g }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meme_captain
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 3
10
+ version: 0.0.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matthew M. Boedicker
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-20 00:00:00 -04:00
18
+ date: 2011-04-22 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -33,7 +33,7 @@ dependencies:
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
35
  - !ruby/object:Gem::Dependency
36
- name: rmagick
36
+ name: mime-types
37
37
  prerelease: false
38
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
@@ -47,7 +47,7 @@ dependencies:
47
47
  type: :runtime
48
48
  version_requirements: *id002
49
49
  - !ruby/object:Gem::Dependency
50
- name: sinatra
50
+ name: rack
51
51
  prerelease: false
52
52
  requirement: &id003 !ruby/object:Gem::Requirement
53
53
  none: false
@@ -60,6 +60,34 @@ dependencies:
60
60
  version: "0"
61
61
  type: :runtime
62
62
  version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: rmagick
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: sinatra
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :runtime
90
+ version_requirements: *id005
63
91
  description: create meme images
64
92
  email:
65
93
  - matthewm@boedicker.org
@@ -77,9 +105,10 @@ files:
77
105
  - img_cache/processed/.gitignore
78
106
  - img_cache/source/.gitignore
79
107
  - lib/meme_captain.rb
80
- - lib/meme_captain/content_type.rb
108
+ - lib/meme_captain/file_body.rb
81
109
  - lib/meme_captain/filesystem_cache.rb
82
110
  - lib/meme_captain/meme.rb
111
+ - lib/meme_captain/mime_type.rb
83
112
  - lib/meme_captain/server.rb
84
113
  - meme_captain.gemspec
85
114
  - views/index.erb