meme_captain 0.1.0 → 0.1.1

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/ChangeLog CHANGED
@@ -1,3 +1,64 @@
1
+ 0.1.1 2012-04-26
2
+
3
+ Update jQuery and fabric.js to latest versions.
4
+
5
+ Disable border on image links for IE.
6
+
7
+ Disable text positioning for browsers that don't support canvas.
8
+
9
+ Add new source images to the site: annoying Facebook girl and you're
10
+ gonna have a bad time.
11
+
12
+ Add new source images to the site: bad luck Brian, laundry room viking,
13
+ paranoid parrot, conspiracy Keanu, socially awesome awkward penguin
14
+ and you should feel bad.
15
+
16
+ Increase default stroke width to 8 pixels.
17
+
18
+ Add new source images to the site: condescending Wonka and first world
19
+ problems.
20
+
21
+ Add unsharp mask step to make text sharper.
22
+
23
+ Scale stroke width by supersample.
24
+
25
+ Make search result thumbnail size relative to image size.
26
+
27
+ Add share on Reddit link.
28
+
29
+ Add templateUrl to JSON response and template link to page.
30
+
31
+ Add favicon.ico to site.
32
+
33
+ Fix 404 error on empty u parameter.
34
+
35
+ Add new source images to the site: Ron Swanson and the more you know.
36
+
37
+ Add setup document.
38
+
39
+ Follow redirects when fetching source images.
40
+
41
+ Highlight form fields when they are populated or preloaded.
42
+
43
+ Add source image upload support to site.
44
+
45
+ Generalize and document thumb sprites script.
46
+
47
+ Add docs for setting up lightweight third-party sites.
48
+
49
+ Add JSONP support for lightweight third-party sites to use.
50
+
51
+ Use Magick::Image.destroy! to reduce memory leaking.
52
+
53
+ Handle odd image formats like BMP.
54
+
55
+ Add debug logging.
56
+
57
+ Write more rspecs.
58
+
59
+ Add new source images to the site: bad joke eel, Neil DeGrasse Tyson,
60
+ Obama not bad and impaired duck.
61
+
1
62
  0.1.0 2012-02-07
2
63
 
3
64
  Redesign web interface.
@@ -45,8 +106,7 @@
45
106
  Add new source images to the site: all the things 2, cool story bro,
46
107
  aw yeah, Boromir, Ned Stark.
47
108
 
48
- 0.0.8
49
- 2011-11-23
109
+ 0.0.8 2011-11-23
50
110
 
51
111
  Start change log.
52
112
 
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md CHANGED
@@ -76,9 +76,14 @@ http://memecaptain.com/g?u=http%3A%2F%2Fmemecaptain.com%2Fyao_ming.jpg&t1=sure+i
76
76
 
77
77
  ```json
78
78
  {
79
- imageUrl: "http://memecaptain.com/c7757f.jpg"
79
+ imageUrl: "http://memecaptain.com/c7757f.jpg",
80
+ templateUrl: "http://memecaptain.com/?u=c7757f.jpg"
80
81
  }
81
82
  ```
82
83
 
83
84
  Optional parameters t1x, t1y, t1w, t1h, t2x, t2y, t2w, t2h can be added to
84
85
  position and size text (see example above).
86
+
87
+ If you want to host a customized version of the memecaptain.com web interface
88
+ on your own web server but use the memecaptain.com backend see
89
+ [lightweight front end](https://github.com/mmb/meme_captain/blob/master/doc/lightweight_front_end.md).
data/config.ru CHANGED
@@ -3,12 +3,14 @@ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
3
3
  require 'mongo'
4
4
  require 'mongo_mapper'
5
5
  require 'rack'
6
+ require 'rack/contrib/jsonp'
6
7
  require 'rack/rewrite'
7
8
 
8
9
  require 'meme_captain'
9
10
 
10
11
  use Rack::ConditionalGet
11
12
  use Rack::Sendfile
13
+ use Rack::JSONP
12
14
 
13
15
  use Rack::Static, :urls => %w{/tmp}, :root => 'public'
14
16
 
@@ -22,6 +24,8 @@ MemeCaptain::MemeData.ensure_index [
22
24
  [:texts, 1],
23
25
  ]
24
26
 
27
+ MemeCaptain::Upload.ensure_index :upload_id
28
+
25
29
  MemeCaptain::SourceFetchFail.ensure_index :url
26
30
 
27
31
  use Rack::Rewrite do
@@ -0,0 +1,64 @@
1
+ If you want to host your own custom Meme Captain site but do not want to set
2
+ up the ruby backend you can use the memecaptain.com backend. In this scenario,
3
+ the HTML, Javscript and CSS are hosted on your web server and the meme images
4
+ are created on and hosted on memecaptain.com.
5
+
6
+ This is an option if you are on shared hosting and do not have access to
7
+ ruby or MongoDB or do not want to deal with setting them up.
8
+
9
+ Download the files at these locations and save them in your document root:
10
+
11
+ * http://memecaptain.com/
12
+ * http://memecaptain.com/css/screen.css
13
+ * http://memecaptain.com/js/fabric.min.js
14
+ * http://memecaptain.com/js/meme_captain.js
15
+ * http://memecaptain.com/source_images.json
16
+
17
+ The css in js should go in css and js directories in your document root so
18
+ that they match the url paths.
19
+
20
+ Find this line in js/meme_captain.js
21
+
22
+ ```
23
+ genUrl = '/g',
24
+ ```
25
+
26
+ and change it to
27
+
28
+ ```
29
+ genUrl = 'http://memecaptain.com/g',
30
+ ```
31
+
32
+ # Changing the Default Source Images
33
+
34
+ The source image thumbnails that show up on the page are driven by a JSON
35
+ description and a single image that contain CSS sprites. The JSON and image
36
+ must be regenerated to change them.
37
+
38
+ The rmagick ruby gem must be installed:
39
+
40
+ ```sh
41
+ gem install rmagick
42
+ ```
43
+
44
+ Get and run the script:
45
+
46
+ ```sh
47
+ wget https://raw.github.com/mmb/meme_captain/master/script/thumb_sprites.rb
48
+ RUBYOPT='r rubygems'
49
+ ruby thumb_sprites.rb -u URL_ROOT -s SOURCE_URL_PREFIX SOURCE_IMAGE_PATH/*
50
+ ```
51
+
52
+ SOURCE_IMAGE_PATH is the directory where the source images are stored.
53
+ URL_ROOT is the root url of the Meme Captain installation. SOURCE_URL_PREFIX
54
+ is the part between the root url and the image filenames in the image urls.
55
+
56
+ For example if the images are stored in /var/www/meme.com/source and the
57
+ url root is http://meme.com/, use:
58
+
59
+ ```sh
60
+ ruby thumb_sprites.rb -u http://meme.com/ -s source/ /var/www/meme.com/source/*
61
+ ```
62
+
63
+ Copy the generated source_images.json and thumbs_xxx.jpg files to the Meme
64
+ Captain document root.
data/doc/setup.md ADDED
@@ -0,0 +1,13 @@
1
+ # Requirements
2
+
3
+ * a Ruby/Rack web application environment (such as
4
+ [Passenger](http://www.modrails.com/))
5
+
6
+ * Ruby gem dependencies (see the gemspec)
7
+
8
+ * [MongoDB](http://www.mongodb.org/)
9
+
10
+ You will most likely need a dedicated or virtual private server to run
11
+ MongoDB as most shared hosting does not support it. See the lightweight front
12
+ end document for how host the static HTML/CSS/Javascript only and use
13
+ memecaptain.com for the backend.
@@ -11,6 +11,8 @@ module MemeCaptain
11
11
  def fetch!(url)
12
12
  curl = Curl::Easy.perform(url) do |c|
13
13
  c.useragent = 'Meme Captain http://memecaptain.com/'
14
+ c.follow_location = true
15
+ c.max_redirects = 3
14
16
  end
15
17
  unless curl.response_code == 200
16
18
  raise FetchError.new(curl.response_code)
@@ -24,7 +24,6 @@ module MemeCaptain
24
24
  text_layer = Magick::Image.new(
25
25
  img.page.width * super_sample, img.page.height * super_sample) {
26
26
  self.background_color = 'none'
27
- self.density = 72.0 * super_sample
28
27
  }
29
28
 
30
29
  text_poss.each do |text_pos|
@@ -50,7 +49,15 @@ module MemeCaptain
50
49
  min_pointsize = text_pos.min_pointsize * super_sample
51
50
 
52
51
  draw = Magick::Draw.new {
53
- text_pos.draw_options.each { |k,v| self.send("#{k}=", v) }
52
+ text_pos.draw_options.each do |k,v|
53
+ # options that need to be scaled by super sample
54
+ if [
55
+ :stroke_width
56
+ ].include?(k)
57
+ v *= super_sample
58
+ end
59
+ self.send("#{k}=", v)
60
+ end
54
61
  }
55
62
 
56
63
  draw.extend Draw
@@ -77,15 +84,20 @@ module MemeCaptain
77
84
  end
78
85
  end
79
86
 
80
- text_layer.resize!(1.0 / super_sample)
87
+ if super_sample != 1
88
+ text_layer.resize!(1.0 / super_sample)
89
+ text_layer = text_layer.unsharp_mask
90
+ end
81
91
 
82
92
  img.each do |frame|
83
93
  frame.composite!(text_layer, -frame.page.x, -frame.page.y,
84
94
  Magick::OverCompositeOp)
85
95
  frame.strip!
86
96
  end
87
- img
88
97
 
98
+ text_layer.destroy!
99
+
100
+ img
89
101
  end
90
102
 
91
103
  # Shortcut to generate a typical meme with text at the top and bottom.
@@ -0,0 +1,62 @@
1
+ require 'RMagick'
2
+
3
+ module MemeCaptain
4
+
5
+ module_function
6
+
7
+ # Public: Generate a pie slice meme background.
8
+ #
9
+ # size - The side length in pixels of the generated image.
10
+ # colors - An Array of color strings (any values that RMagick accepts).
11
+ # num_rays - The Fixnum of rays to create.
12
+ # block - An optiona block passed to Draw.new for specifying additional
13
+ # draw options
14
+ #
15
+ # Examples
16
+ #
17
+ # memebg(400, %w{red orange yellow green blue indigo violet}, 20) {
18
+ # # draw options
19
+ # # self.stroke = 'white'
20
+ # }.display
21
+ #
22
+ # Returns a Magick::Image of the meme background.
23
+ def memebg(size, colors, num_rays, &block)
24
+ # make circle 5% too big to avoid empty space at corners from rounding
25
+ # errors
26
+ circle_radius = Math.sqrt(2 * ((size / 2.0) ** 2)) * 1.05
27
+
28
+ side_len = 2 * circle_radius
29
+
30
+ start_x = side_len
31
+ start_y = circle_radius
32
+
33
+ center = "#{circle_radius},#{circle_radius}"
34
+
35
+ img = Magick::Image.new(side_len, side_len)
36
+
37
+ color_cycle = colors.cycle
38
+
39
+ (1..num_rays).each do |ray_index|
40
+ ray_radius = 2 * Math::PI / num_rays * ray_index
41
+
42
+ end_x = circle_radius + (Math.cos(ray_radius) * circle_radius)
43
+ end_y = circle_radius - (Math.sin(ray_radius) * circle_radius)
44
+
45
+ svg = "M#{center} L#{start_x},#{start_y} A#{center} 0 0,0 #{end_x},#{end_y} z"
46
+
47
+ draw = Magick::Draw.new {
48
+ instance_eval(&block) if block_given?
49
+ self.fill = color_cycle.next
50
+ }
51
+
52
+ draw.path svg
53
+ draw.draw img
54
+
55
+ start_x = end_x
56
+ start_y = end_y
57
+ end
58
+
59
+ img.crop! Magick::CenterGravity, size, size
60
+ end
61
+
62
+ end
@@ -0,0 +1,92 @@
1
+ module MemeCaptain
2
+
3
+ # Normalize query string parameters.
4
+ #
5
+ # Provide defaults, do some basic validation and convert some parameters
6
+ # to floats or integers.
7
+ class NormParams
8
+
9
+ def initialize(params={})
10
+ @u = ''
11
+
12
+ @t1 = ''
13
+ @t2 = ''
14
+
15
+ @t1x = 0.05
16
+ @t1y = 0
17
+ @t1w = 0.9
18
+ @t1h = 0.25
19
+
20
+ @t2x = 0.05
21
+ @t2y = 0.75
22
+ @t2w = 0.9
23
+ @t2h = 0.25
24
+
25
+ load params
26
+ end
27
+
28
+ # Load query string parameters.
29
+ #
30
+ # Do some basic validation and convert some parameters to floats or
31
+ # integers.
32
+ def load(params)
33
+ params.select { |k,v|
34
+ [
35
+ :u,
36
+ :t1,
37
+ :t2,
38
+ ].include? k.to_sym }.each do |k,v|
39
+ send "#{k}=", v.to_s
40
+ end
41
+
42
+ params.select { |k,v|
43
+ [
44
+ :t1x,
45
+ :t1y,
46
+ :t1w,
47
+ :t1h,
48
+
49
+ :t2x,
50
+ :t2y,
51
+ :t2w,
52
+ :t2h,
53
+ ].include?(k.to_sym) and !v.to_s.empty? }.each do |k,v|
54
+ send "#{k}=", convert_metric(v)
55
+ end
56
+ end
57
+
58
+ # Return a sorted string representation of the fields.
59
+ def signature
60
+ instance_variables.sort.map { |v|
61
+ name = v[1..-1] # remove @
62
+ "#{name}#{instance_variable_get(v)}"
63
+ }.join
64
+ end
65
+
66
+ attr_accessor :u
67
+
68
+ attr_accessor :t1
69
+ attr_accessor :t2
70
+
71
+ attr_accessor :t1x
72
+ attr_accessor :t1y
73
+ attr_accessor :t1w
74
+ attr_accessor :t1h
75
+
76
+ attr_accessor :t2x
77
+ attr_accessor :t2y
78
+ attr_accessor :t2w
79
+ attr_accessor :t2h
80
+
81
+ private
82
+
83
+ # Convert a metric string to a float or integer.
84
+ #
85
+ # Expects a string.
86
+ def convert_metric(metric)
87
+ metric.index('.') ? metric.to_f : metric.to_i
88
+ end
89
+
90
+ end
91
+
92
+ end
@@ -0,0 +1,12 @@
1
+ require 'pp'
2
+
3
+ module MemeCaptain
4
+
5
+ module_function
6
+
7
+ # Format an object like pp would would and return the formatted string.
8
+ def pretty_format(o)
9
+ PP.pp o, dump = ''
10
+ end
11
+
12
+ end