Skip to content
This repository
Browse code

Merge branch 'feature/metadata' into develop

* feature/metadata:
  Added link around image
  add alt-attribute support
  Textfields enabled, not disable. Elsewise selecting is not possible
  Absolute URL support
  Refactor to DRY and more consistent code.
  Title hackishly implemented.
  • Loading branch information...
commit 7881b409dfc7de2d7cfd0bdfbcb050da1d524473 2 parents 94849da + fd37069
authored March 25, 2013
1  Gemfile
@@ -3,6 +3,7 @@ source "https://rubygems.org"
3 3
 
4 4
 gem 'sinatra', '~> 1.4'
5 5
 gem 'rmagick', '~> 2.13'
  6
+gem 'video_info', '~> 1.1'
6 7
 
7 8
 group :test do
8 9
   gem 'rspec', '~> 2.13'
4  Gemfile.lock
@@ -2,6 +2,7 @@ GEM
2 2
   remote: https://rubygems.org/
3 3
   specs:
4 4
     diff-lcs (1.2.1)
  5
+    multi_json (1.7.2)
5 6
     rack (1.5.2)
6 7
     rack-protection (1.5.0)
7 8
       rack
@@ -23,6 +24,8 @@ GEM
23 24
       rack-protection (~> 1.4)
24 25
       tilt (~> 1.3, >= 1.3.4)
25 26
     tilt (1.3.6)
  27
+    video_info (1.1.1)
  28
+      multi_json
26 29
 
27 30
 PLATFORMS
28 31
   ruby
@@ -33,3 +36,4 @@ DEPENDENCIES
33 36
   rspec (~> 2.13)
34 37
   shotgun
35 38
   sinatra (~> 1.4)
  39
+  video_info (~> 1.1)
39  lib/youtube.rb
... ...
@@ -1,28 +1,41 @@
1 1
 require 'RMagick'
  2
+require 'video_info'
2 3
 require 'net/http'
3 4
 
4 5
 class YouTube
5  
-  def initialize id
  6
+  def initialize id, opts = {}
6 7
     @id = id
  8
+    @meta = nil
  9
+
  10
+    @base_url = opts[:base_url] || ''
7 11
   end
8 12
 
9  
-  def img_tag overlay = false
10  
-    %Q{<img src="#{thumb(overlay)}" alt=""/>}
  13
+  def title
  14
+    parse
  15
+    @meta.title
11 16
   end
12 17
 
13  
-  private
14  
-  def thumb overlay
  18
+  def href
  19
+    "http://www.youtube.com/watch?v=#{@id}"
  20
+  end
  21
+
  22
+  def tags
15 23
     parse
16  
-    thumbname({:overlay => overlay, :omit_public => true})
  24
+    get_thumbs.map {|t| %Q{<a href="#{href}"><img src="#{t}" alt="#{title}"/></a>} }
17 25
   end
18 26
 
  27
+  private
19 28
   def parse
20  
-    img = Net::HTTP.get("i.ytimg.com", "/vi/#{@id}/0.jpg")
  29
+    @meta ||= VideoInfo.get(href)
  30
+  end
  31
+
  32
+  def get_thumbs
  33
+    img = Net::HTTP.get(URI(@meta.thumbnail_large))
21 34
 
22 35
     tmpfile = Tempfile.new(["tubemp", ".jpg"])
23 36
     begin
24 37
       tmpfile.binmode
25  
-      tmpfile.write img
  38
+      tmpfile.write(img)
26 39
       tmpfile.close
27 40
 
28 41
       images = Magick::ImageList.new(tmpfile.path, File.join("assets", "overlay.png"))
@@ -35,6 +48,9 @@ def parse
35 48
       images = nil
36 49
       tmpfile.unlink
37 50
     end
  51
+
  52
+    [ thumbname({:overlay => false, :absolute => true}),
  53
+      thumbname({:overlay => true, :absolute  => true}) ]
38 54
   end
39 55
 
40 56
   # Creates a path to the thumbnail
@@ -47,7 +63,12 @@ def thumbname opts = {}
47 63
 
48 64
     filename = opts[:overlay] ? "#{@id}_overlay": @id
49 65
     parts = ["thumbs", "#{filename}.png"]
50  
-    parts.unshift("public") unless opts[:omit_public]
  66
+
  67
+    if opts[:absolute]
  68
+      parts.unshift(@base_url)
  69
+    else
  70
+      parts.unshift("public")
  71
+    end
51 72
     File.join(parts)
52 73
   end
53 74
 end
1  spec/spec_helper.rb
... ...
@@ -1,5 +1,4 @@
1 1
 require 'rack/test'
2  
-
3 2
 require File.expand_path File.join('../../tubemp.rb'), __FILE__
4 3
 
5 4
 module RSpecMixin
56  spec/youtube_spec.rb
... ...
@@ -1,46 +1,64 @@
1 1
 require File.join(File.dirname(__FILE__), "..", "lib", "youtube")
2 2
 
3 3
 IMAGE_RE = /\<img.*src="(.*)".*alt="(.*).*\/\>/
  4
+LINK_RE  = /\<a.*href="(.*)".*\>/
  5
+
4 6
 describe YouTube do
5 7
   before do
  8
+    info = mock("video");
  9
+    info.stub(:title).and_return("Tony Tribe , Red Red Wine")
  10
+    info.stub(:thumbnail_large).and_return("http://i.ytimg.com/vi/D80QdsFWdcQ/hqdefault.jpg")
  11
+    VideoInfo.stub(:get).and_return info
  12
+
6 13
     @id = "D80QdsFWdcQ"
7  
-    @yt = YouTube.new @id
  14
+    @yt = YouTube.new @id, {:base_url => "http://example.com"}
8 15
     @filename = File.join("public", "thumbs", "#{@id}.png")
9 16
   end
10 17
 
11  
-  describe '#img_tag' do
  18
+  describe '#tags' do
12 19
     context "valid ID" do
13  
-      it 'should render a valid image tag' do
14  
-        @yt.stub(:parse)
15  
-        @yt.img_tag.should =~ IMAGE_RE
  20
+      it 'should render a list of valid image tags' do
  21
+        @yt.tags.each {|t| t.should match IMAGE_RE }
16 22
       end
17 23
 
18 24
       it 'should link to a thumbnail in PNG format' do
19  
-        @yt.stub(:parse)
20  
-        img = @yt.img_tag.match IMAGE_RE
  25
+        img = @yt.tags[0].match IMAGE_RE
21 26
         src = img[1]
22 27
         src.should =~ /#{@id}\.png/
23 28
       end
24 29
 
25 30
       it 'should link to the overlayed thumbnail with overlay=true' do
26  
-        @yt.stub(:parse)
27  
-        img = @yt.img_tag(true).match IMAGE_RE
  31
+        img = @yt.tags[1].match IMAGE_RE
28 32
         src = img[1]
29 33
         src.should =~ /#{@id}_overlay\.png/
30 34
       end
31 35
 
  36
+      it 'should link to an absolute URL' do
  37
+        img = @yt.tags[0].match IMAGE_RE
  38
+        src = img[1]
  39
+        src.should match /^http:\/\/.*$/
  40
+      end
  41
+
  42
+      it 'should have the title as alt attribute' do
  43
+        @yt.tags[0].match(IMAGE_RE)[2].should match "Tony Tribe , Red Red Wine"
  44
+      end
  45
+
  46
+      it 'should have a link pointing to the youtube video' do
  47
+        @yt.tags[0].match(LINK_RE)[1].should match /http:\/\/www\.youtube\.com/
  48
+      end
  49
+
32 50
       context 'local image does not exist' do
33 51
         before do
34 52
           File.delete @filename if File.exists? @filename
35 53
         end
36 54
 
37 55
         it 'should create its thumb in "public/thumbs" dir' do
38  
-          @yt.img_tag
  56
+          @yt.tags
39 57
           File.exists?(@filename).should be_true
40 58
         end
41 59
 
42 60
         it 'should get the large thumbnail' do
43  
-          @yt.img_tag
  61
+          @yt.tags
44 62
           img = Magick::ImageList.new(@filename)
45 63
           img.rows.should >= 300
46 64
           img.columns.should >= 400
@@ -54,17 +72,29 @@
54 72
         end
55 73
 
56 74
         it 'should overwrite when a newer image is found online' do
57  
-          @yt.img_tag
  75
+          @yt.tags
58 76
           @existing.should_not eq File.stat(@filename)
59 77
         end
60 78
       end
61 79
 
62 80
       it 'should overlay a play-icon' do
63  
-        @yt.img_tag
  81
+        @yt.tags
64 82
         filename = File.join("public", "thumbs", "#{@id}_over.png")
65 83
         File.exists?(filename)
66 84
       end
67 85
     end # context "valid ID"
  86
+  end
68 87
 
  88
+  describe "#title" do
  89
+    it "should render a title" do
  90
+      @yt.title.should eq "Tony Tribe , Red Red Wine"
  91
+    end
69 92
   end
  93
+
  94
+  describe "#href" do
  95
+    it 'should render a link' do
  96
+      @yt.href.should eq "http://www.youtube.com/watch?v=#{@id}"
  97
+    end
  98
+  end
  99
+
70 100
 end
13  tubemp.rb
@@ -4,12 +4,9 @@
4 4
 include ERB::Util
5 5
 
6 6
 get '/:id' do
7  
-  yt = YouTube.new params[:id]
  7
+  yt = YouTube.new params[:id], {:base_url => request.base_url }
8 8
 
9  
-  image_tags = [yt.img_tag, yt.img_tag(true)]
10  
-  title      = "title here"
11  
-
12  
-  erb :index, :locals => {:image_tags => image_tags, :title => title}
  9
+  erb :index, :locals => {:tags => yt.tags, :title => yt.title}
13 10
 end
14 11
 
15 12
 __END__
@@ -74,9 +71,9 @@
74 71
 </html>
75 72
 
76 73
 @@ index
77  
-<% image_tags.each do |image_tag| %>
  74
+<% tags.each do |tag| %>
78 75
   <div class="large-6 columns">
79  
-    <%= image_tag %><br />
80  
-    <input type="text" disabled="disabled" value="<%= html_escape image_tag %>" />
  76
+    <%= tag %><br />
  77
+    <input type="text" value="<%= html_escape tag %>" />
81 78
   </div>
82 79
 <% end %>

0 notes on commit 7881b40

Please sign in to comment.
Something went wrong with that request. Please try again.