mustachio 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,28 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'sinatra', '~> 1.2.3', :require => 'sinatra/base'
4
+ gem 'dragonfly', '~> 0.9.0'
5
+ gem 'magickly', '~> 1.1'
6
+ gem 'addressable', '~> 2.2.4', :require => 'addressable/uri'
7
+ gem 'haml'
8
+
9
+ gem 'face', '0.0.4'
10
+ gem 'imagesize', '~> 0.1', :require => 'image_size'
11
+
12
+ group :development do
13
+ gem 'jeweler', '~> 1.6'
14
+ end
15
+
16
+ group :development, :test do
17
+ gem 'rack-test', :require => 'rack/test'
18
+ gem 'rspec', '~> 2.5'
19
+ gem 'webmock', '~> 1.6', :require => 'webmock/rspec'
20
+ gem 'vcr', '~> 1.9'
21
+
22
+ gem 'ruby-debug19', :require => 'ruby-debug', :platforms => :ruby_19
23
+ gem 'ruby-debug', :platforms => :ruby_18
24
+ end
25
+
26
+ group :production do
27
+ gem 'newrelic_rpm', :require => false
28
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,94 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (3.0.7)
5
+ addressable (2.2.5)
6
+ archive-tar-minitar (0.5.2)
7
+ columnize (0.3.2)
8
+ crack (0.1.8)
9
+ diff-lcs (1.1.2)
10
+ dragonfly (0.9.0)
11
+ rack
12
+ rack
13
+ face (0.0.4)
14
+ json (>= 1.4.6)
15
+ rest-client (>= 1.6.1)
16
+ git (1.2.5)
17
+ haml (3.0.25)
18
+ httparty (0.7.7)
19
+ crack (= 0.1.8)
20
+ imagesize (0.1.1)
21
+ jeweler (1.6.0)
22
+ bundler (~> 1.0.0)
23
+ git (>= 1.2.5)
24
+ rake
25
+ json (1.5.1)
26
+ linecache (0.43)
27
+ linecache19 (0.5.12)
28
+ ruby_core_source (>= 0.1.4)
29
+ magickly (1.1.1)
30
+ activesupport (>= 2.0.0)
31
+ addressable (~> 2.2)
32
+ dragonfly (~> 0.8)
33
+ haml (~> 3.0.25)
34
+ httparty (~> 0.7.3)
35
+ sinatra (~> 1.2.1)
36
+ mime-types (1.16)
37
+ newrelic_rpm (2.14.1)
38
+ rack (1.2.2)
39
+ rack-test (0.6.0)
40
+ rack (>= 1.0)
41
+ rake (0.8.7)
42
+ rest-client (1.6.1)
43
+ mime-types (>= 1.16)
44
+ rspec (2.5.0)
45
+ rspec-core (~> 2.5.0)
46
+ rspec-expectations (~> 2.5.0)
47
+ rspec-mocks (~> 2.5.0)
48
+ rspec-core (2.5.1)
49
+ rspec-expectations (2.5.0)
50
+ diff-lcs (~> 1.1.2)
51
+ rspec-mocks (2.5.0)
52
+ ruby-debug (0.10.4)
53
+ columnize (>= 0.1)
54
+ ruby-debug-base (~> 0.10.4.0)
55
+ ruby-debug-base (0.10.4)
56
+ linecache (>= 0.3)
57
+ ruby-debug-base19 (0.11.25)
58
+ columnize (>= 0.3.1)
59
+ linecache19 (>= 0.5.11)
60
+ ruby_core_source (>= 0.1.4)
61
+ ruby-debug19 (0.11.6)
62
+ columnize (>= 0.3.1)
63
+ linecache19 (>= 0.5.11)
64
+ ruby-debug-base19 (>= 0.11.19)
65
+ ruby_core_source (0.1.5)
66
+ archive-tar-minitar (>= 0.5.2)
67
+ sinatra (1.2.6)
68
+ rack (~> 1.1)
69
+ tilt (< 2.0, >= 1.2.2)
70
+ tilt (1.3)
71
+ vcr (1.9.0)
72
+ webmock (1.6.2)
73
+ addressable (>= 2.2.2)
74
+ crack (>= 0.1.7)
75
+
76
+ PLATFORMS
77
+ ruby
78
+
79
+ DEPENDENCIES
80
+ addressable (~> 2.2.4)
81
+ dragonfly (~> 0.9.0)
82
+ face (= 0.0.4)
83
+ haml
84
+ imagesize (~> 0.1)
85
+ jeweler (~> 1.6)
86
+ magickly (~> 1.1)
87
+ newrelic_rpm
88
+ rack-test
89
+ rspec (~> 2.5)
90
+ ruby-debug
91
+ ruby-debug19
92
+ sinatra (~> 1.2.3)
93
+ vcr (~> 1.9)
94
+ webmock (~> 1.6)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Aidan Feldman
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ ![the queen](http://mustachio.heroku.com/?src=http://www.librarising.com/astrology/celebs/images2/QR/queenelizabethii.jpg)
2
+
3
+ http://mustachio.heroku.com/?src=YOUR-IMAGE-URL
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "mustachio"
18
+ gem.homepage = "http://github.com/afeld/mustachio"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{automatic mustachifying of any image}
21
+ gem.description = %Q{Adds a 'mustachify' shortcut to magickly.}
22
+ gem.email = "aidan.feldman@gmail.com"
23
+ gem.authors = ["Aidan Feldman"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rake/rdoctask'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "mustachio #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
data/bookmarklet.js ADDED
@@ -0,0 +1,18 @@
1
+ // original
2
+ javascript:(function(){
3
+ var URL = 'http://mustachio.heroku.com/magickly?mustachify=true&src=';
4
+ var images = document.getElementsByTagName('img');
5
+ var i;
6
+ for (i = 0; i < images.length; i += 1){
7
+ var image = images[i];
8
+ var src = image.getAttribute('src');
9
+ if (image.src[0] === '/'){
10
+ image.setAttribute('src', URL + encodeURIComponent(window.location.origin + src));
11
+ } else if (src.match(/^https?:\/\//)) {
12
+ image.setAttribute('src', URL + encodeURIComponent(src));
13
+ }
14
+ }
15
+ })();
16
+
17
+ // JSMin'd
18
+ javascript:(function(){var URL='http://mustachio.heroku.com/magickly?mustachify=true&src=';var images=document.getElementsByTagName('img');var i;for(i=0;i<images.length;i+=1){var image=images[i];var src=image.getAttribute('src');if(image.src[0]==='/'){image.setAttribute('src',URL+encodeURIComponent(window.location.origin+src));}else if(src.match(/^https?:\/\//)){image.setAttribute('src',URL+encodeURIComponent(src));}}})();
data/config.ru ADDED
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require
4
+
5
+ require File.join(File.dirname(__FILE__), 'lib', 'mustachio')
6
+
7
+ map '/' do
8
+ run Mustachio
9
+ end
10
+
11
+ map '/magickly' do
12
+ run Magickly::App
13
+ end
data/lib/mustachio.rb ADDED
@@ -0,0 +1,102 @@
1
+ require 'sinatra/base'
2
+ require 'magickly'
3
+ require 'image_size'
4
+ require 'face'
5
+
6
+ # thanks to http://therantsandraves.com/?p=602 for the 'staches
7
+ MUSTACHE = {
8
+ :filename => File.expand_path(File.join(File.join(File.dirname(__FILE__), '..', 'public', 'images', 'mustache_03.png'))),
9
+ :width => nil,
10
+ :height => nil,
11
+ :top_offset => -5.0,
12
+ :bottom_offset => -15.0
13
+ }
14
+ MUSTACHE[:width], MUSTACHE[:height] = ImageSize.new(File.new(MUSTACHE[:filename])).get_size
15
+
16
+ FACE_POS_ATTRS = ['center', 'eye_left', 'eye_right', 'mouth_left', 'mouth_center', 'mouth_right', 'nose']
17
+
18
+ Magickly.dragonfly.configure do |c|
19
+ c.analyser.add :face_data do |temp_object|
20
+ Mustachio.face_client.faces_detect(:file => temp_object.file, :attributes => 'none')['photos'].first
21
+ end
22
+
23
+ c.analyser.add :face_data_as_px do |temp_object|
24
+ data = Mustachio.face_client.faces_detect(:file => temp_object.file, :attributes => 'none')['photos'].first # TODO use #face_data
25
+
26
+ data['tags'].map! do |face|
27
+ FACE_POS_ATTRS.each do |pos_attr|
28
+ if face[pos_attr].nil?
29
+ puts "WARN: missing position attribute '#{pos_attr}'"
30
+ else
31
+ face[pos_attr]['x'] *= (data['width'] / 100.0)
32
+ face[pos_attr]['y'] *= (data['height'] / 100.0)
33
+ end
34
+ end
35
+
36
+ face
37
+ end
38
+
39
+ data
40
+ end
41
+
42
+ c.job :mustachify do
43
+ photo_data = @job.face_data_as_px
44
+ width = photo_data['width']
45
+
46
+ commands = []
47
+ photo_data['tags'].each do |face|
48
+ # perform affine transform, such that the top-center
49
+ # of the mustache is mapped to the nose, and the bottom-center
50
+ # of the stache is mapped to the center of the mouth
51
+ affine_params = [
52
+ [ MUSTACHE[:width]/2, MUSTACHE[:top_offset] ], # top-center of stache
53
+ [ face['nose']['x'], face['nose']['y'] ], # nose
54
+
55
+ [ MUSTACHE[:width]/2, MUSTACHE[:height] + MUSTACHE[:bottom_offset] ], # bottom-center of stache
56
+ [ face['mouth_center']['x'], face['mouth_center']['y'] ] # center of mouth
57
+ ]
58
+ affine_params_str = affine_params.map{|p| p.join(',') }.join(' ')
59
+
60
+ commands << "\\( #{MUSTACHE[:filename]} +distort Affine '#{affine_params_str}' \\)"
61
+ end
62
+ commands << "-flatten"
63
+
64
+ command_str = commands.join(' ')
65
+ process :convert, command_str
66
+ end
67
+ end
68
+
69
+ class Mustachio < Sinatra::Base
70
+ @@face_client = Face.get_client(
71
+ :api_key => (ENV['MUSTACHIO_FACE_API_KEY'] || raise("Please set MUSTACHIO_FACE_API_KEY.")),
72
+ :api_secret => (ENV['MUSTACHIO_FACE_API_SECRET'] || raise("Please set MUSTACHIO_FACE_API_SECRET."))
73
+ )
74
+
75
+ set :static, true
76
+ set :public, 'public'
77
+
78
+ configure :production do
79
+ require 'newrelic_rpm' if ENV['NEW_RELIC_ID']
80
+ end
81
+
82
+ class << self
83
+ def face_client
84
+ @@face_client
85
+ end
86
+ end
87
+
88
+ get '/' do
89
+ src = params[:src]
90
+ if src
91
+ image = Magickly.process_src params[:src], :mustachify => true
92
+ image.to_response(env)
93
+ else
94
+ @site = Addressable::URI.parse(request.url).site
95
+ haml :index
96
+ end
97
+ end
98
+
99
+ get '/face_api_dev_challenge' do
100
+ haml :face_api_dev_challenge
101
+ end
102
+ end
data/mustachio.gemspec ADDED
@@ -0,0 +1,105 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{mustachio}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{Aidan Feldman}]
12
+ s.date = %q{2011-05-16}
13
+ s.description = %q{Adds a 'mustachify' shortcut to magickly.}
14
+ s.email = %q{aidan.feldman@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bookmarklet.js",
29
+ "config.ru",
30
+ "lib/mustachio.rb",
31
+ "mustachio.gemspec",
32
+ "public/favicon.ico",
33
+ "public/images/dubya.jpeg",
34
+ "public/images/guy_hecker.jpeg",
35
+ "public/images/mustache_03.png",
36
+ "spec/fixtures/vcr_cassettes/big_obama.yml",
37
+ "spec/fixtures/vcr_cassettes/dubya.yml",
38
+ "spec/fixtures/vcr_cassettes/small_obama.yml",
39
+ "spec/spec_helper.rb",
40
+ "spec/support/big_obama.jpeg",
41
+ "spec/support/dubya.jpeg",
42
+ "spec/support/small_obama.jpeg",
43
+ "spec/unit/analyser_spec.rb",
44
+ "views/face_api_dev_challenge.haml",
45
+ "views/ga.haml",
46
+ "views/index.haml"
47
+ ]
48
+ s.homepage = %q{http://github.com/afeld/mustachio}
49
+ s.licenses = [%q{MIT}]
50
+ s.require_paths = [%q{lib}]
51
+ s.rubygems_version = %q{1.8.2}
52
+ s.summary = %q{automatic mustachifying of any image}
53
+
54
+ if s.respond_to? :specification_version then
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
58
+ s.add_runtime_dependency(%q<sinatra>, ["~> 1.2.3"])
59
+ s.add_runtime_dependency(%q<dragonfly>, ["~> 0.9.0"])
60
+ s.add_runtime_dependency(%q<magickly>, ["~> 1.1"])
61
+ s.add_runtime_dependency(%q<addressable>, ["~> 2.2.4"])
62
+ s.add_runtime_dependency(%q<haml>, [">= 0"])
63
+ s.add_runtime_dependency(%q<face>, ["= 0.0.4"])
64
+ s.add_runtime_dependency(%q<imagesize>, ["~> 0.1"])
65
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6"])
66
+ s.add_development_dependency(%q<rack-test>, [">= 0"])
67
+ s.add_development_dependency(%q<rspec>, ["~> 2.5"])
68
+ s.add_development_dependency(%q<webmock>, ["~> 1.6"])
69
+ s.add_development_dependency(%q<vcr>, ["~> 1.9"])
70
+ s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
71
+ s.add_development_dependency(%q<ruby-debug>, [">= 0"])
72
+ else
73
+ s.add_dependency(%q<sinatra>, ["~> 1.2.3"])
74
+ s.add_dependency(%q<dragonfly>, ["~> 0.9.0"])
75
+ s.add_dependency(%q<magickly>, ["~> 1.1"])
76
+ s.add_dependency(%q<addressable>, ["~> 2.2.4"])
77
+ s.add_dependency(%q<haml>, [">= 0"])
78
+ s.add_dependency(%q<face>, ["= 0.0.4"])
79
+ s.add_dependency(%q<imagesize>, ["~> 0.1"])
80
+ s.add_dependency(%q<jeweler>, ["~> 1.6"])
81
+ s.add_dependency(%q<rack-test>, [">= 0"])
82
+ s.add_dependency(%q<rspec>, ["~> 2.5"])
83
+ s.add_dependency(%q<webmock>, ["~> 1.6"])
84
+ s.add_dependency(%q<vcr>, ["~> 1.9"])
85
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
86
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
87
+ end
88
+ else
89
+ s.add_dependency(%q<sinatra>, ["~> 1.2.3"])
90
+ s.add_dependency(%q<dragonfly>, ["~> 0.9.0"])
91
+ s.add_dependency(%q<magickly>, ["~> 1.1"])
92
+ s.add_dependency(%q<addressable>, ["~> 2.2.4"])
93
+ s.add_dependency(%q<haml>, [">= 0"])
94
+ s.add_dependency(%q<face>, ["= 0.0.4"])
95
+ s.add_dependency(%q<imagesize>, ["~> 0.1"])
96
+ s.add_dependency(%q<jeweler>, ["~> 1.6"])
97
+ s.add_dependency(%q<rack-test>, [">= 0"])
98
+ s.add_dependency(%q<rspec>, ["~> 2.5"])
99
+ s.add_dependency(%q<webmock>, ["~> 1.6"])
100
+ s.add_dependency(%q<vcr>, ["~> 1.9"])
101
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
102
+ s.add_dependency(%q<ruby-debug>, [">= 0"])
103
+ end
104
+ end
105
+
Binary file
Binary file
Binary file
Binary file