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 +5 -0
- data/lib/meme_captain/file_body.rb +15 -0
- data/lib/meme_captain/filesystem_cache.rb +41 -13
- data/lib/meme_captain/{content_type.rb → mime_type.rb} +7 -3
- data/lib/meme_captain/server.rb +7 -5
- data/lib/meme_captain.rb +2 -1
- data/meme_captain.gemspec +3 -1
- metadata +36 -7
data/config.ru
CHANGED
@@ -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
|
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
|
-
|
13
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
46
|
+
# Put data in the cache and return its path.
|
23
47
|
def put(id, data)
|
24
|
-
|
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
|
-
|
56
|
+
file_path
|
30
57
|
end
|
31
58
|
|
32
|
-
|
33
|
-
|
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
|
6
|
-
def
|
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
|
data/lib/meme_captain/server.rb
CHANGED
@@ -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
|
-
|
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.
|
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' =>
|
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,
|
49
|
+
[ 200, headers, MemeCaptain::FileBody.new(processed_cache_path) ]
|
48
50
|
end
|
49
51
|
|
50
52
|
helpers do
|
data/lib/meme_captain.rb
CHANGED
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.
|
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:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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-
|
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:
|
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:
|
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/
|
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
|