videostore 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +32 -0
- data/lib/videostore.rb +186 -0
- data/rakefile +5 -0
- data/spec/videostore_spec.rb +58 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 09b1398177f07a17cf92e64abc1e80d340ec18e3
|
4
|
+
data.tar.gz: 646de11ca15ee3cdd1f45296e13b42135029de2a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73f157b799290715c47b24a178f0b13dc0f2307f832e1ec6218e6140e8bea54e6dac9e613a2f5d6693828a5f672eda1179ab31909695091b0aa89a4afc6de9c8
|
7
|
+
data.tar.gz: 42afaca160aef9172b55bc39a3b7d100400f5017b3926fa76add8bffdbaf4d9c2959125c34ef5d52140bf4c735af42d367fa666eb9dec16cd43008a36f96e934
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
videostore
|
2
|
+
==========
|
3
|
+
|
4
|
+
A gem for storing information about videos on remote streaming sites
|
5
|
+
|
6
|
+
Features:
|
7
|
+
- Currenty supports Youtube and Vimeo
|
8
|
+
- Methods for checking if they're still online
|
9
|
+
- Methods for bringing down up-to-date data from API #
|
10
|
+
- Various sorting options made possible through duck typing
|
11
|
+
|
12
|
+
To start using the gem have a file to the lib directory called keys.rb that defines
|
13
|
+
YOUTUBE_DEVELOPER_KEY as your google developer key with access to the V3 Youtube API.
|
14
|
+
|
15
|
+
Instantiate a new Youtube video with
|
16
|
+
> VideoStore::Youtube.new(<insert youtube ID here>)
|
17
|
+
|
18
|
+
Do the same with Vimeo, but replace Youtube with Vimeo!!
|
19
|
+
|
20
|
+
Both classes respond to:
|
21
|
+
present? -- Returns true if the video
|
22
|
+
video_id -- ID
|
23
|
+
uri -- URI for the video
|
24
|
+
title -- The Title
|
25
|
+
thumbnail_uri -- URI for the thumbnail
|
26
|
+
channel_name -- Name of the poster of the video
|
27
|
+
views -- # of views
|
28
|
+
likes -- # of likes
|
29
|
+
comment_count -- # of comments
|
30
|
+
duration -- length of the video in seconds
|
31
|
+
|
32
|
+
This duck typing allows you to sort both kinds of videos in the same collection.
|
data/lib/videostore.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'google/api_client'
|
3
|
+
require 'vimeo'
|
4
|
+
begin
|
5
|
+
load 'keys.rb' ## store your youtube API key here as the constant YOUTUBE_DEVELOPER_KEY
|
6
|
+
rescue LoadError
|
7
|
+
raise "To start using the gem have a file to the lib directory called keys.rb " <<
|
8
|
+
"that defines YOUTUBE_DEVELOPER_KEY as your google developer key (must have access to the V3 Youtube API)."
|
9
|
+
end
|
10
|
+
|
11
|
+
module VideoStore
|
12
|
+
class Video
|
13
|
+
attr_accessor :video_id
|
14
|
+
attr_reader :title, :thumbnail_uri, :channel_name, :views,
|
15
|
+
:likes, :comment_count, :duration
|
16
|
+
ATTRIBUTES = :video_id, :title, :thumbnail_uri, :channel_name, :views,
|
17
|
+
:likes, :comment_count, :duration
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
raise NoMethodError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Youtube < Video
|
25
|
+
DEVELOPER_KEY = ::YOUTUBE_DEVELOPER_KEY
|
26
|
+
YOUTUBE_API_SERVICE_NAME = "youtube"
|
27
|
+
YOUTUBE_API_VERSION = "v3"
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def establish_connection
|
31
|
+
@client = Google::APIClient.new(key: DEVELOPER_KEY,
|
32
|
+
application_name: YOUTUBE_API_SERVICE_NAME,
|
33
|
+
application_version: YOUTUBE_API_VERSION,
|
34
|
+
authorization: nil)
|
35
|
+
@connection = @client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
|
36
|
+
end
|
37
|
+
def connection
|
38
|
+
@connection
|
39
|
+
end
|
40
|
+
def client
|
41
|
+
@client
|
42
|
+
end
|
43
|
+
end # end of class methods
|
44
|
+
establish_connection
|
45
|
+
|
46
|
+
def initialize(video_id)
|
47
|
+
@video_id = video_id
|
48
|
+
@response_hash = Hash.new
|
49
|
+
populate_attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
def connection
|
53
|
+
self.class.connection
|
54
|
+
end
|
55
|
+
def client
|
56
|
+
self.class.client
|
57
|
+
end
|
58
|
+
|
59
|
+
def present?(options = {})
|
60
|
+
JSON.parse(fetch_data('id').response.body)["pageInfo"]["totalResults"] == 1
|
61
|
+
end
|
62
|
+
|
63
|
+
def populate_attributes(options = {})
|
64
|
+
if present?
|
65
|
+
content_details = JSON.parse(fetch_data('contentDetails').response.body)['items'].first['contentDetails']
|
66
|
+
@duration = content_details["duration"].youtube_duration_to_seconds
|
67
|
+
|
68
|
+
statistics = JSON.parse(fetch_data('statistics').response.body)['items'].first['statistics']
|
69
|
+
@views = statistics["viewCount"].to_i
|
70
|
+
@likes = statistics["likeCount"].to_i
|
71
|
+
@comment_count = statistics["commentCount"].to_i
|
72
|
+
|
73
|
+
snippet = JSON.parse(fetch_data('snippet').response.body)['items'].first['snippet']
|
74
|
+
@title = snippet["title"]
|
75
|
+
@thumbnail_uri = snippet["thumbnails"]["default"]["url"]
|
76
|
+
@channel_name = snippet["channelTitle"]
|
77
|
+
end
|
78
|
+
info
|
79
|
+
end
|
80
|
+
|
81
|
+
def uri
|
82
|
+
"http://www.youtube.com/watch?v=#{@video_id}" if present?
|
83
|
+
end
|
84
|
+
|
85
|
+
def info
|
86
|
+
response = {}
|
87
|
+
if present?
|
88
|
+
ATTRIBUTES.each do |attribute|
|
89
|
+
response.merge!({attribute => send(attribute)})
|
90
|
+
end
|
91
|
+
else
|
92
|
+
response.merge!({:video_id => @video_id})
|
93
|
+
response.merge!({:video_not_found => 'video_not_found'})
|
94
|
+
end
|
95
|
+
response
|
96
|
+
end
|
97
|
+
|
98
|
+
def youtube? ; true ; end
|
99
|
+
def vimeo? ; false ; end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def fetch_data(part, options = {})
|
104
|
+
if options[:use_cache] && @response_hash[part]
|
105
|
+
@response_hash[part]
|
106
|
+
else
|
107
|
+
@response_hash[part] = client.execute!(
|
108
|
+
:api_method => connection.videos.list,
|
109
|
+
:parameters => {
|
110
|
+
:id => @video_id,
|
111
|
+
:part => part,
|
112
|
+
}
|
113
|
+
)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end # end of Youtube class
|
118
|
+
|
119
|
+
class Vimeo < Video
|
120
|
+
def initialize(video_id)
|
121
|
+
@video_id = video_id
|
122
|
+
populate_attributes
|
123
|
+
end
|
124
|
+
|
125
|
+
def present?
|
126
|
+
::Vimeo::Simple::Video.info(@video_id
|
127
|
+
).parsed_response.class == Array
|
128
|
+
end
|
129
|
+
|
130
|
+
def uri
|
131
|
+
"http:://vimeo.com/#{@video_id}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def populate_attributes
|
135
|
+
if present?
|
136
|
+
fetch_data
|
137
|
+
|
138
|
+
@title = @response['title']
|
139
|
+
@thumbnail_uri = @response['thumbnail_large']
|
140
|
+
@channel_name = @response['user_name']
|
141
|
+
@views = @response['stats_number_of_plays']
|
142
|
+
@likes = @response['stats_number_of_likes']
|
143
|
+
@comment_count = @response['stats_number_of_comments']
|
144
|
+
@duration = @response['duration']
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def info
|
149
|
+
response = {}
|
150
|
+
if present?
|
151
|
+
ATTRIBUTES.each do |attribute|
|
152
|
+
response.merge!({attribute => send(attribute)})
|
153
|
+
end
|
154
|
+
else
|
155
|
+
response.merge!({:video_id => @video_id})
|
156
|
+
response.merge!({:video_not_found => 'video_not_found'})
|
157
|
+
end
|
158
|
+
response
|
159
|
+
end
|
160
|
+
|
161
|
+
def youtube? ; false ; end
|
162
|
+
def vimeo? ; true ; end
|
163
|
+
|
164
|
+
private
|
165
|
+
|
166
|
+
def fetch_data
|
167
|
+
@response = JSON.parse(
|
168
|
+
::Vimeo::Simple::Video.info(@video_id).response.body
|
169
|
+
).first
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class String
|
175
|
+
def youtube_duration_to_seconds
|
176
|
+
hours = match(/(\d+)H/)
|
177
|
+
minutes = match(/(\d+)M/)
|
178
|
+
seconds = match(/(\d+)S/)
|
179
|
+
|
180
|
+
hours = hours ? hours[1].to_i : 0
|
181
|
+
minutes = minutes ? minutes[1].to_i : 0
|
182
|
+
seconds = seconds ? seconds[1].to_i : 0
|
183
|
+
|
184
|
+
(hours * 3600) + (minutes * 60) + seconds
|
185
|
+
end
|
186
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../lib/videostore"
|
2
|
+
|
3
|
+
describe VideoStore::Youtube do
|
4
|
+
before :each do
|
5
|
+
@youtube = VideoStore::Youtube.new('vWeaOG6KzqE')
|
6
|
+
@invalid_youtube = VideoStore::Youtube.new('imnotavalididlol')
|
7
|
+
@vimeo = VideoStore::Vimeo.new(39605750)
|
8
|
+
@invalid_vimeo = VideoStore::Vimeo.new(5)
|
9
|
+
end
|
10
|
+
context 'youtube' do
|
11
|
+
it "can tell when a video is and isn't there, and what it is" do
|
12
|
+
@youtube.present?.should == true
|
13
|
+
@invalid_youtube.present?.should == false
|
14
|
+
@youtube.youtube?.should == true
|
15
|
+
@youtube.vimeo?.should == false
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can pull down information" do
|
19
|
+
@youtube.video_id.should == "vWeaOG6KzqE"
|
20
|
+
@youtube.title.should == "Madeon | The incomplete mix | Not All tracks | Adio"
|
21
|
+
@youtube.thumbnail_uri.should == "https://i1.ytimg.com/vi/vWeaOG6KzqE/default.jpg"
|
22
|
+
@youtube.channel_name.should == "Adio Music"
|
23
|
+
@youtube.duration.should == 3306
|
24
|
+
@youtube.views.should > 350223
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'vimeo' do
|
29
|
+
it "can tell when a video is and isn't there" do
|
30
|
+
@vimeo.present?.should == true
|
31
|
+
@invalid_vimeo.present?.should == false
|
32
|
+
@vimeo.vimeo?.should == true
|
33
|
+
@vimeo.youtube?.should == false
|
34
|
+
end
|
35
|
+
|
36
|
+
it "can pull down information" do
|
37
|
+
@vimeo.video_id.should == 39605750
|
38
|
+
@vimeo.title.should == "woot woot"
|
39
|
+
@vimeo.thumbnail_uri.should == "http://b.vimeocdn.com/ts/273/226/273226915_640.jpg"
|
40
|
+
@vimeo.channel_name.should == "Cole Ruffing"
|
41
|
+
@vimeo.duration.should == 243
|
42
|
+
@vimeo.views.should > 1356
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'collection' do
|
47
|
+
it 'can sort collections' do
|
48
|
+
@sort_by_title = [@vimeo, @youtube].sort_by! {|x| x.title }
|
49
|
+
@sort_by_title[0].youtube?.should == true
|
50
|
+
|
51
|
+
@sort_by_channel_name = [@vimeo, @youtube].sort_by! {|x| x.channel_name }
|
52
|
+
@sort_by_channel_name[0].youtube?.should == true
|
53
|
+
|
54
|
+
@sort_by_duration = [@vimeo, @youtube].sort_by! {|x| x.views }
|
55
|
+
@sort_by_duration[0].vimeo?.should == true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: videostore
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Husa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-01 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: The videostore gem is a utility for storing and tracking remote videos
|
14
|
+
at streaming sites such as Vimeo and Youtube.
|
15
|
+
email: davidhusa@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/videostore.rb
|
21
|
+
- spec/videostore_spec.rb
|
22
|
+
- rakefile
|
23
|
+
- README.md
|
24
|
+
homepage: http://davidhusa.com
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.0.7
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Utility for storing/tracking remote videos
|
48
|
+
test_files: []
|