film_snob 0.6.5 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +17 -4
- data/CHANGELOG.md +19 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +15 -0
- data/Guardfile +13 -0
- data/README.md +50 -11
- data/Rakefile +2 -5
- data/film_snob.gemspec +14 -22
- data/lib/film_snob.rb +8 -12
- data/lib/film_snob/exceptions.rb +5 -2
- data/lib/film_snob/{video_site.rb → oembed_provider.rb} +25 -9
- data/lib/film_snob/{video_sites → oembed_providers}/coub.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/dailymotion.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/funny_or_die.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/hulu.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/instagram.rb +2 -2
- data/lib/film_snob/oembed_providers/rdio.rb +20 -0
- data/lib/film_snob/{video_sites → oembed_providers}/rutube.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/soundcloud.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/vimeo.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/vine.rb +2 -2
- data/lib/film_snob/{video_sites → oembed_providers}/youtube.rb +11 -2
- data/lib/film_snob/{url_to_video.rb → url_to_oembed_provider.rb} +6 -5
- data/lib/film_snob/version.rb +1 -1
- data/spec/film_snob/oembed_provider_spec.rb +27 -0
- data/spec/film_snob/{video_sites → oembed_providers}/coub_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/dailymotion_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/funny_or_die_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/hulu_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/instagram_spec.rb +0 -0
- data/spec/film_snob/oembed_providers/rdio_spec.rb +38 -0
- data/spec/film_snob/{video_sites → oembed_providers}/rutube_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/soundcloud_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/vimeo_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/vine_spec.rb +0 -0
- data/spec/film_snob/{video_sites → oembed_providers}/youtube_spec.rb +18 -0
- data/spec/spec_helper.rb +4 -2
- metadata +47 -154
- data/lib/film_snob/deprecated.rb +0 -12
- data/spec/deprecated_spec.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f456c757ffe9c535c907220ae5774ddbd4506bba
|
4
|
+
data.tar.gz: 6f91fc2d8849c61775aea6259aafa36e2c01d28b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f034c43b8fd9e49fd3d923e60085d8b502f17ad30178999bfdf66fb4ed63da9570a29209c5b252d17964d0bcf938a87516b98cada9055a8132fd3a75fe0841a3
|
7
|
+
data.tar.gz: aaec57f2af26a92fb192969cee667b4eb4a42c0666b9b860dc4847a7832174f160296dfc01450fdc7078725a1e60adab2997d2889453a4caaf3bf2ca9de70b5c
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
+
sudo: false
|
2
|
+
cache: bundler
|
1
3
|
language: ruby
|
2
4
|
rvm:
|
3
|
-
- 1.9.3
|
4
5
|
- 2.0.0
|
5
6
|
- 2.1.0
|
6
7
|
- 2.1.1
|
@@ -8,11 +9,23 @@ rvm:
|
|
8
9
|
- 2.1.3
|
9
10
|
- 2.1.4
|
10
11
|
- 2.1.5
|
12
|
+
- 2.1.6
|
13
|
+
- 2.1.7
|
11
14
|
- 2.2.0
|
12
15
|
- 2.2.1
|
13
16
|
- 2.2.2
|
14
|
-
|
17
|
+
- 2.2.3
|
18
|
+
- ruby-head
|
19
|
+
- jruby-19mode
|
20
|
+
- jruby-9.0.1.0
|
21
|
+
- rbx-2
|
22
|
+
matrix:
|
23
|
+
fast_finish: true
|
24
|
+
allow_failures:
|
25
|
+
- rvm: ruby-head
|
26
|
+
- rvm: jruby-19mode
|
27
|
+
- rvm: jruby-9.0.1.0
|
28
|
+
- rvm: rbx-2
|
29
|
+
before_install: 'gem install bundler -v 1.10.6'
|
15
30
|
script:
|
16
31
|
- bundle exec rake ci
|
17
|
-
sudo: false
|
18
|
-
cache: bundler
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Change log
|
2
|
+
|
3
|
+
## 1.0.0 (2015-11-14)
|
4
|
+
|
5
|
+
### New features
|
6
|
+
|
7
|
+
* support for Rdio Urls
|
8
|
+
|
9
|
+
### changes
|
10
|
+
|
11
|
+
* dropped support for Ruby 1.9.3
|
12
|
+
* removed the `FilmSnob#watchable?` method in favor of `embeddable?`
|
13
|
+
* renamed a bunch of internal things that were all about videos, to reflect that
|
14
|
+
some of the sites like soundcloud and isntagram aren't really about videos
|
15
|
+
* no longer rescuing all errors when making the request
|
16
|
+
|
17
|
+
## Earlier
|
18
|
+
|
19
|
+
Added a bunch of stuff!
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
CHANGED
@@ -1,4 +1,19 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
+
gem "rake", "~> 10.4"
|
4
|
+
|
5
|
+
gem "pry", "~> 0.10"
|
6
|
+
gem "rubocop", "~> 0.35"
|
7
|
+
gem "todo_lint", "~> 0.2"
|
8
|
+
gem "rspec", "~> 3.4"
|
9
|
+
gem "webmock", "~> 1.22"
|
10
|
+
gem "vcr", "~> 2.9"
|
11
|
+
gem "codeclimate-test-reporter", "~> 0.4"
|
12
|
+
|
13
|
+
# TDD workflow
|
14
|
+
gem "guard"
|
15
|
+
gem "guard-rspec"
|
16
|
+
gem "guard-rubocop"
|
17
|
+
|
3
18
|
# Specify your gem's dependencies in film_snob.gemspec
|
4
19
|
gemspec
|
data/Guardfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# This group allows to skip running RuboCop when RSpec failed.
|
2
|
+
group :red_green_refactor, :halt_on_fail => true do
|
3
|
+
guard :rspec, :cmd => "bundle exec rspec --fail-fast" do
|
4
|
+
# run a spec when editing it
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
8
|
+
end
|
9
|
+
guard :rubocop, :all_on_start => false do
|
10
|
+
watch(/.+\.rb$/)
|
11
|
+
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
12
|
+
end
|
13
|
+
end
|
data/README.md
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
[![Code Climate](https://codeclimate.com/github/maxjacobson/film_snob.png)](https://codeclimate.com/github/maxjacobson/film_snob)
|
6
6
|
[![Test Coverage](https://codeclimate.com/github/maxjacobson/film_snob/badges/coverage.svg)](https://codeclimate.com/github/maxjacobson/film_snob)
|
7
7
|
|
8
|
-
|
8
|
+
Lookup things like titles and HTML embed codes for web media like videos,
|
9
|
+
pictures, and songs.
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
@@ -40,7 +41,28 @@ film.title #=> "Garann Means - Bacon is bad for you"
|
|
40
41
|
film.html #=> "<iframe src=\"//player.vimeo.com/video/64683454\" width=\"720\" height=\"405\" frameborder=\"0\" title=\"Garann Means - Bacon is bad for you\" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>"
|
41
42
|
```
|
42
43
|
|
43
|
-
film_snob uses the oembed protocol to get html for embed codes. These options
|
44
|
+
film_snob uses the oembed protocol to get html for embed codes. These options
|
45
|
+
assume some knowledge of the endpoint's API. The above vimeo example works
|
46
|
+
because they [have an extensively documented API][vimeo] which allows tons of
|
47
|
+
configuration. The other two don't seem to have any documentation or
|
48
|
+
configuration at all.
|
49
|
+
|
50
|
+
[vimeo]: http://developer.vimeo.com/apis/oembed
|
51
|
+
|
52
|
+
### Performance
|
53
|
+
|
54
|
+
The interface described above is nice for unknown URLs because you can use
|
55
|
+
film_snob to check if a URL should be embeddable, and then if it should be, you
|
56
|
+
can ask it for the HTML.
|
57
|
+
|
58
|
+
If you know for sure that a URL ought to be a YouTube video, it will be faster
|
59
|
+
to use an interface like this one:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
film = FilmSnob::YouTube.new("https://www.youtube.com/watch?v=st21dIMaGMs")
|
63
|
+
film.title #=> "Key & Peele - Continental Breakfast"
|
64
|
+
film.html #=> "<iframe width=\"480\" height=\"270\" src=\"https://www.youtube.com/embed/st21dIMaGMs?feature=oembed\" frameborder=\"0\" allowfullscreen></iframe>"
|
65
|
+
```
|
44
66
|
|
45
67
|
## Supported Sites
|
46
68
|
|
@@ -54,32 +76,49 @@ film_snob uses the oembed protocol to get html for embed codes. These options as
|
|
54
76
|
* Vine
|
55
77
|
* Rutube
|
56
78
|
* Soundcloud
|
79
|
+
* Rdio
|
57
80
|
|
58
81
|
The same methods work with all of these providers.
|
59
82
|
|
60
83
|
## Testing
|
61
84
|
|
62
|
-
Run `rake spec` to run all of the tests.
|
85
|
+
Run `bundle exec rake spec` to run all of the tests.
|
86
|
+
|
87
|
+
If you like TDD, you might want to run `bundle exec guard` instead, which will
|
88
|
+
listen for your changes and auto-run your tests when you save them or the
|
89
|
+
related files.
|
63
90
|
|
64
91
|
## Code Style
|
65
92
|
|
66
|
-
Run `rake style` to confirm the codebase is looking stylish.
|
93
|
+
Run `bundle exec rake style` to confirm the codebase is looking stylish.
|
67
94
|
|
68
95
|
## Continous Integration
|
69
96
|
|
70
|
-
Run `rake ci` to run both the tests and the style checks, which
|
97
|
+
Run `bundle exec rake ci` to run both the tests and the style checks, which
|
98
|
+
will be run on Travis; both should pass to have a green build.
|
71
99
|
|
72
100
|
## Questions?
|
73
101
|
|
74
102
|
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/maxjacobson/film_snob?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
75
103
|
|
76
|
-
Ping me in [the Gitter chat room](https://gitter.im/maxjacobson/film_snob) or
|
104
|
+
Ping me in [the Gitter chat room](https://gitter.im/maxjacobson/film_snob) or
|
105
|
+
[create a GitHub issue](https://github.com/maxjacobson/film_snob/issues/new)
|
77
106
|
|
78
107
|
## Contributing
|
79
108
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
109
|
+
Bug reports and pull requests are welcome on GitHub at
|
110
|
+
<https://github.com/maxjacobson/smashcut>. This project is intended to be a
|
111
|
+
safe, welcoming space for collaboration, and contributors are expected to
|
112
|
+
adhere to the [Contributor Covenant](http://contributor-covenant.org) code of
|
113
|
+
conduct.
|
114
|
+
|
115
|
+
## Releasing a new version
|
116
|
+
|
117
|
+
* change the version in `version.rb`.
|
118
|
+
* describe what changed in `CHANGELOG.md`
|
119
|
+
* commit the change
|
120
|
+
* run `bundle exec rake release` to create a git tag, push the code to github,
|
121
|
+
and push the release to rubygems
|
122
|
+
* describe the release on [the releases page][]
|
85
123
|
|
124
|
+
[the releases page]: https://github.com/maxjacobson/film_snob/releases
|
data/Rakefile
CHANGED
@@ -1,16 +1,13 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
3
|
require "rubocop/rake_task"
|
4
|
+
require "todo_lint"
|
4
5
|
|
5
6
|
RSpec::Core::RakeTask.new(:spec)
|
6
7
|
RuboCop::RakeTask.new(:style)
|
7
8
|
|
8
9
|
task :todos do
|
9
|
-
|
10
|
-
if RUBY_VERSION >= "2.0.0"
|
11
|
-
require "todo_lint"
|
12
|
-
TodoLint::Cli.new([]).run!
|
13
|
-
end
|
10
|
+
TodoLint::Cli.new([]).run!
|
14
11
|
end
|
15
12
|
|
16
13
|
task :ci => [:spec, :style, :todos]
|
data/film_snob.gemspec
CHANGED
@@ -4,29 +4,21 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require "film_snob/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
7
|
+
spec.name = "film_snob"
|
8
|
+
spec.version = FilmSnob::VERSION
|
9
|
+
spec.authors = ["Max Jacobson"]
|
10
|
+
spec.email = ["max@hardscrabble.net"]
|
11
|
+
spec.summary = "Fetch data from oEmbed APIs"
|
12
|
+
spec.description = "Lookup things like titles and HTML embed codes for web " \
|
13
|
+
"media like videos, pictures, and songs."
|
14
|
+
spec.homepage = "https://github.com/maxjacobson/film_snob"
|
15
|
+
spec.license = "MIT"
|
16
16
|
|
17
|
-
spec.files
|
18
|
-
spec.executables
|
19
|
-
spec.test_files
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_development_dependency "bundler",
|
23
|
-
spec.
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.3"
|
25
|
-
spec.add_development_dependency "webmock", "~> 1.21"
|
26
|
-
spec.add_development_dependency "vcr", "~> 2.9"
|
27
|
-
spec.add_development_dependency "pry", "~> 0.10"
|
28
|
-
spec.add_development_dependency "rubocop", "~> 0.32.1"
|
29
|
-
spec.add_development_dependency "todo_lint", "~> 0.2"
|
30
|
-
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
|
31
|
-
spec.required_ruby_version = ">= 1.9.3"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
23
|
+
spec.required_ruby_version = ">= 2.0.0"
|
32
24
|
end
|
data/lib/film_snob.rb
CHANGED
@@ -1,35 +1,31 @@
|
|
1
1
|
require "forwardable"
|
2
2
|
require "film_snob/version"
|
3
|
-
require "film_snob/
|
3
|
+
require "film_snob/url_to_oembed_provider"
|
4
4
|
require "film_snob/exceptions"
|
5
|
-
require "film_snob/deprecated"
|
6
5
|
|
7
6
|
class FilmSnob
|
8
|
-
extend
|
7
|
+
extend Forwardable
|
9
8
|
|
10
|
-
|
9
|
+
MEDIA_METHODS = [:site, :id, :clean_url, :title, :html]
|
11
10
|
|
12
|
-
def_delegators :
|
13
|
-
|
14
|
-
# TODO(2015-11-15): actually remove this method
|
15
|
-
deprecated_alias :watchable?, :embeddable?, :removed_in => "v1.0.0"
|
11
|
+
def_delegators :media, *MEDIA_METHODS
|
16
12
|
|
17
13
|
attr_reader :url
|
18
14
|
|
19
15
|
def initialize(url, options = {})
|
20
16
|
@url = url
|
21
|
-
@
|
17
|
+
@media = UrlToOembedProvider.new(url, options).media
|
22
18
|
end
|
23
19
|
|
24
20
|
def embeddable?
|
25
|
-
!@
|
21
|
+
!@media.nil?
|
26
22
|
end
|
27
23
|
|
28
24
|
private
|
29
25
|
|
30
|
-
def
|
26
|
+
def media
|
31
27
|
if embeddable?
|
32
|
-
@
|
28
|
+
@media
|
33
29
|
else
|
34
30
|
raise NotSupportedURLError, "#{url} is not a supported URL"
|
35
31
|
end
|
data/lib/film_snob/exceptions.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
class FilmSnob
|
2
|
-
|
3
|
-
class
|
2
|
+
# all FilmSnob errors can be rescued in one go by rescuing this one
|
3
|
+
class FilmSnobError < StandardError; end
|
4
|
+
|
5
|
+
class NotSupportedURLError < FilmSnobError; end
|
6
|
+
class NotEmbeddableError < FilmSnobError; end
|
4
7
|
end
|
@@ -2,13 +2,13 @@ require "net/http"
|
|
2
2
|
require "json"
|
3
3
|
|
4
4
|
class FilmSnob
|
5
|
-
|
6
|
-
# we're using this for things like Instagram
|
7
|
-
class VideoSite
|
5
|
+
class OembedProvider
|
8
6
|
attr_reader :url, :options
|
7
|
+
|
9
8
|
def initialize(url, options = {})
|
10
9
|
@url = url
|
11
|
-
@options = options
|
10
|
+
@options = friendly_options(options)
|
11
|
+
ensure_match unless options.delete(:matched)
|
12
12
|
end
|
13
13
|
|
14
14
|
def id
|
@@ -69,19 +69,23 @@ class FilmSnob
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def matching_pattern
|
72
|
-
self.class.valid_url_patterns.find do |pattern|
|
72
|
+
@matching_pattern ||= self.class.valid_url_patterns.find do |pattern|
|
73
73
|
pattern.match(url)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def oembed
|
78
|
-
@oembed ||=
|
79
|
-
|
80
|
-
|
78
|
+
@oembed ||= begin
|
79
|
+
if response.code.start_with?("2")
|
80
|
+
JSON.parse(response.body)
|
81
|
+
else
|
82
|
+
{}
|
83
|
+
end
|
84
|
+
end
|
81
85
|
end
|
82
86
|
|
83
87
|
def response
|
84
|
-
self.class.http.request get
|
88
|
+
@response ||= self.class.http.request get
|
85
89
|
end
|
86
90
|
|
87
91
|
def get
|
@@ -93,5 +97,17 @@ class FilmSnob
|
|
93
97
|
uri.query = URI.encode_www_form({ :url => clean_url }.merge(options))
|
94
98
|
end
|
95
99
|
end
|
100
|
+
|
101
|
+
def ensure_match
|
102
|
+
return unless matching_pattern.nil?
|
103
|
+
raise NotSupportedURLError, "#{self.class} can not handle #{url.inspect}"
|
104
|
+
end
|
105
|
+
|
106
|
+
# a subclass can override this one to define some aliases to paper over some
|
107
|
+
# quirks in a specific oembed provider's API, e.g. mapping "width" to
|
108
|
+
# "maxwidth"
|
109
|
+
def friendly_options(options)
|
110
|
+
options
|
111
|
+
end
|
96
112
|
end
|
97
113
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "film_snob/oembed_provider"
|
2
|
+
|
3
|
+
class FilmSnob
|
4
|
+
class Rdio < OembedProvider
|
5
|
+
def self.valid_url_patterns
|
6
|
+
[
|
7
|
+
%r{http?://www.rdio.com/artist/(?:[\w\d\-_]+/album/)}
|
8
|
+
]
|
9
|
+
end
|
10
|
+
|
11
|
+
# in this case, we're trusting Rdio to clean up the URL
|
12
|
+
def clean_url
|
13
|
+
@clean_url = url
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.oembed_endpoint
|
17
|
+
"http://www.rdio.com/api/oembed/"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require "film_snob/
|
1
|
+
require "film_snob/oembed_provider"
|
2
2
|
|
3
3
|
class FilmSnob
|
4
|
-
class YouTube <
|
4
|
+
class YouTube < OembedProvider
|
5
5
|
def self.valid_url_patterns
|
6
6
|
[
|
7
7
|
%r{
|
@@ -20,5 +20,14 @@ class FilmSnob
|
|
20
20
|
def clean_url
|
21
21
|
@clean_url ||= "https://www.youtube.com/watch?v=#{id}"
|
22
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def friendly_options(options)
|
27
|
+
if (width = options.delete(:width) || options.delete("width"))
|
28
|
+
options[:maxwidth] = width
|
29
|
+
end
|
30
|
+
options
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
path_to_providers = File.join(File.dirname(__FILE__), "oembed_providers")
|
2
|
+
Dir.entries(path_to_providers).each do |file|
|
3
|
+
require "film_snob/oembed_providers/#{file}" unless [".", ".."].include?(file)
|
3
4
|
end
|
4
5
|
|
5
6
|
class FilmSnob
|
6
|
-
class
|
7
|
+
class UrlToOembedProvider
|
7
8
|
attr_reader :url, :options
|
8
9
|
|
9
10
|
def initialize(url, options)
|
@@ -11,14 +12,14 @@ class FilmSnob
|
|
11
12
|
@options = options
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
+
def media
|
15
16
|
site.nil? ? nil : site.new(url, options)
|
16
17
|
end
|
17
18
|
|
18
19
|
private
|
19
20
|
|
20
21
|
def site
|
21
|
-
@site ||=
|
22
|
+
@site ||= OembedProvider.subclasses.find do |site|
|
22
23
|
site.valid_url_patterns.any? do |pattern|
|
23
24
|
pattern.match(url)
|
24
25
|
end
|
data/lib/film_snob/version.rb
CHANGED
@@ -0,0 +1,27 @@
|
|
1
|
+
# this is a generic parent class for sharing code
|
2
|
+
describe FilmSnob::OembedProvider do
|
3
|
+
describe "initialization" do
|
4
|
+
let(:film) { FilmSnob::YouTube.new(url, options) }
|
5
|
+
|
6
|
+
context "when you assure it the URL is a good match" do
|
7
|
+
let(:url) { "https://www.youtube.com/watch?v=st21dIMaGMs" }
|
8
|
+
let(:options) { { :matched => true } }
|
9
|
+
|
10
|
+
it "can look up the title, but the URL better be related to this site" do
|
11
|
+
VCR.use_cassette "youtube/continental breakfast" do
|
12
|
+
expect(film.title).to include "Continental Breakfast"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when you do not assure it the URL is a good match" do
|
18
|
+
let(:url) { "this just is not a YouTube URL" }
|
19
|
+
let(:options) { {} }
|
20
|
+
|
21
|
+
it "will yell at you" do
|
22
|
+
expect { film.title }.to raise_error(FilmSnob::NotSupportedURLError,
|
23
|
+
/can not handle/)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
describe FilmSnob::Rdio do
|
2
|
+
describe "rdio URLs" do
|
3
|
+
let(:url) { "http://www.rdio.com/#{path}" }
|
4
|
+
|
5
|
+
context "when the URL is an album" do
|
6
|
+
let(:path) { "artist/Sam_Smith/album/In_The_Lonely_Hour/" }
|
7
|
+
|
8
|
+
it "should parse" do
|
9
|
+
snob = FilmSnob.new(url)
|
10
|
+
expect(snob).to be_embeddable
|
11
|
+
expect(snob.site).to eq :rdio
|
12
|
+
VCR.use_cassette("rdio/in the lonely hour") do
|
13
|
+
expect(snob.title).to eq "In The Lonely Hour"
|
14
|
+
expect(snob.html).to include "iframe"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "a song" do
|
20
|
+
let(:path) do
|
21
|
+
"artist/Sam_Smith/album/In_The_Lonely_Hour/track/Stay_With_Me"
|
22
|
+
end
|
23
|
+
it "should parse normal track rdio URLs" do
|
24
|
+
snob = FilmSnob.new(url)
|
25
|
+
expect(snob).to be_embeddable
|
26
|
+
expect(snob.site).to eq :rdio
|
27
|
+
VCR.use_cassette("rdio/stay with me") do
|
28
|
+
expect(snob.title).to eq "Stay With Me"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not allow weak matches for rdio urls" do
|
34
|
+
snob = FilmSnob.new("google.com/q=rdio")
|
35
|
+
expect(snob).to_not be_embeddable
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -85,4 +85,22 @@ describe FilmSnob::YouTube do
|
|
85
85
|
expect(snob.site).to eq :youtube
|
86
86
|
expect(snob.clean_url).to eq "https://www.youtube.com/watch?v=sLSFOCyNC8Q"
|
87
87
|
end
|
88
|
+
|
89
|
+
it "should allow specifying the width of the video" do
|
90
|
+
film = FilmSnob.new("https://www.youtube.com/watch?v=ky9Ro9pP2gc",
|
91
|
+
:maxwidth => 350)
|
92
|
+
VCR.use_cassette "youtube/joanna1" do
|
93
|
+
expect(film.title).to include "Joanna"
|
94
|
+
expect(film.html).to include "350"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should allow specifying the width of the video via width option" do
|
99
|
+
film = FilmSnob.new("https://www.youtube.com/watch?v=ky9Ro9pP2gc",
|
100
|
+
:width => 350)
|
101
|
+
VCR.use_cassette "youtube/joanna2" do
|
102
|
+
expect(film.title).to include "Joanna"
|
103
|
+
expect(film.html).to include "350"
|
104
|
+
end
|
105
|
+
end
|
88
106
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -13,8 +13,6 @@ VCR.configure do |c|
|
|
13
13
|
end
|
14
14
|
|
15
15
|
RSpec.configure do |config|
|
16
|
-
config.default_formatter = "doc" if config.files_to_run.one?
|
17
|
-
|
18
16
|
config.order = :random
|
19
17
|
|
20
18
|
config.expect_with :rspec do |expectations|
|
@@ -26,4 +24,8 @@ RSpec.configure do |config|
|
|
26
24
|
config.mock_with :rspec do |mocks|
|
27
25
|
mocks.verify_partial_doubles = true
|
28
26
|
end
|
27
|
+
|
28
|
+
# allow to focus on one thing at a time if you like, by adding the focus tag
|
29
|
+
config.filter_run_including :focus => true
|
30
|
+
config.run_all_when_everything_filtered = true
|
29
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: film_snob
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Jacobson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,120 +24,8 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.10'
|
27
|
-
|
28
|
-
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '10.4'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '10.4'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '3.3'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '3.3'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: webmock
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '1.21'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '1.21'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: vcr
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - "~>"
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '2.9'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - "~>"
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '2.9'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: pry
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - "~>"
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0.10'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - "~>"
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0.10'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.32.1
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.32.1
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: todo_lint
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0.2'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0.2'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: codeclimate-test-reporter
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0.4'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0.4'
|
139
|
-
description: Find information about URLs from video sites, such as the title and embed
|
140
|
-
code of the video
|
27
|
+
description: Lookup things like titles and HTML embed codes for web media like videos,
|
28
|
+
pictures, and songs.
|
141
29
|
email:
|
142
30
|
- max@hardscrabble.net
|
143
31
|
executables: []
|
@@ -149,39 +37,43 @@ files:
|
|
149
37
|
- ".rubocop.yml"
|
150
38
|
- ".todo_lint.yml"
|
151
39
|
- ".travis.yml"
|
40
|
+
- CHANGELOG.md
|
41
|
+
- CODE_OF_CONDUCT.md
|
152
42
|
- Gemfile
|
43
|
+
- Guardfile
|
153
44
|
- LICENSE.txt
|
154
45
|
- README.md
|
155
46
|
- Rakefile
|
156
47
|
- film_snob.gemspec
|
157
48
|
- lib/film_snob.rb
|
158
|
-
- lib/film_snob/deprecated.rb
|
159
49
|
- lib/film_snob/exceptions.rb
|
160
|
-
- lib/film_snob/
|
50
|
+
- lib/film_snob/oembed_provider.rb
|
51
|
+
- lib/film_snob/oembed_providers/coub.rb
|
52
|
+
- lib/film_snob/oembed_providers/dailymotion.rb
|
53
|
+
- lib/film_snob/oembed_providers/funny_or_die.rb
|
54
|
+
- lib/film_snob/oembed_providers/hulu.rb
|
55
|
+
- lib/film_snob/oembed_providers/instagram.rb
|
56
|
+
- lib/film_snob/oembed_providers/rdio.rb
|
57
|
+
- lib/film_snob/oembed_providers/rutube.rb
|
58
|
+
- lib/film_snob/oembed_providers/soundcloud.rb
|
59
|
+
- lib/film_snob/oembed_providers/vimeo.rb
|
60
|
+
- lib/film_snob/oembed_providers/vine.rb
|
61
|
+
- lib/film_snob/oembed_providers/youtube.rb
|
62
|
+
- lib/film_snob/url_to_oembed_provider.rb
|
161
63
|
- lib/film_snob/version.rb
|
162
|
-
- lib/film_snob/video_site.rb
|
163
|
-
- lib/film_snob/video_sites/coub.rb
|
164
|
-
- lib/film_snob/video_sites/dailymotion.rb
|
165
|
-
- lib/film_snob/video_sites/funny_or_die.rb
|
166
|
-
- lib/film_snob/video_sites/hulu.rb
|
167
|
-
- lib/film_snob/video_sites/instagram.rb
|
168
|
-
- lib/film_snob/video_sites/rutube.rb
|
169
|
-
- lib/film_snob/video_sites/soundcloud.rb
|
170
|
-
- lib/film_snob/video_sites/vimeo.rb
|
171
|
-
- lib/film_snob/video_sites/vine.rb
|
172
|
-
- lib/film_snob/video_sites/youtube.rb
|
173
64
|
- spec/cassettes/README.md
|
174
|
-
- spec/
|
175
|
-
- spec/film_snob/
|
176
|
-
- spec/film_snob/
|
177
|
-
- spec/film_snob/
|
178
|
-
- spec/film_snob/
|
179
|
-
- spec/film_snob/
|
180
|
-
- spec/film_snob/
|
181
|
-
- spec/film_snob/
|
182
|
-
- spec/film_snob/
|
183
|
-
- spec/film_snob/
|
184
|
-
- spec/film_snob/
|
65
|
+
- spec/film_snob/oembed_provider_spec.rb
|
66
|
+
- spec/film_snob/oembed_providers/coub_spec.rb
|
67
|
+
- spec/film_snob/oembed_providers/dailymotion_spec.rb
|
68
|
+
- spec/film_snob/oembed_providers/funny_or_die_spec.rb
|
69
|
+
- spec/film_snob/oembed_providers/hulu_spec.rb
|
70
|
+
- spec/film_snob/oembed_providers/instagram_spec.rb
|
71
|
+
- spec/film_snob/oembed_providers/rdio_spec.rb
|
72
|
+
- spec/film_snob/oembed_providers/rutube_spec.rb
|
73
|
+
- spec/film_snob/oembed_providers/soundcloud_spec.rb
|
74
|
+
- spec/film_snob/oembed_providers/vimeo_spec.rb
|
75
|
+
- spec/film_snob/oembed_providers/vine_spec.rb
|
76
|
+
- spec/film_snob/oembed_providers/youtube_spec.rb
|
185
77
|
- spec/film_snob_spec.rb
|
186
78
|
- spec/spec_helper.rb
|
187
79
|
homepage: https://github.com/maxjacobson/film_snob
|
@@ -196,7 +88,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
196
88
|
requirements:
|
197
89
|
- - ">="
|
198
90
|
- !ruby/object:Gem::Version
|
199
|
-
version:
|
91
|
+
version: 2.0.0
|
200
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
93
|
requirements:
|
202
94
|
- - ">="
|
@@ -204,22 +96,23 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
96
|
version: '0'
|
205
97
|
requirements: []
|
206
98
|
rubyforge_project:
|
207
|
-
rubygems_version: 2.
|
99
|
+
rubygems_version: 2.5.0
|
208
100
|
signing_key:
|
209
101
|
specification_version: 4
|
210
|
-
summary: Fetch
|
102
|
+
summary: Fetch data from oEmbed APIs
|
211
103
|
test_files:
|
212
104
|
- spec/cassettes/README.md
|
213
|
-
- spec/
|
214
|
-
- spec/film_snob/
|
215
|
-
- spec/film_snob/
|
216
|
-
- spec/film_snob/
|
217
|
-
- spec/film_snob/
|
218
|
-
- spec/film_snob/
|
219
|
-
- spec/film_snob/
|
220
|
-
- spec/film_snob/
|
221
|
-
- spec/film_snob/
|
222
|
-
- spec/film_snob/
|
223
|
-
- spec/film_snob/
|
105
|
+
- spec/film_snob/oembed_provider_spec.rb
|
106
|
+
- spec/film_snob/oembed_providers/coub_spec.rb
|
107
|
+
- spec/film_snob/oembed_providers/dailymotion_spec.rb
|
108
|
+
- spec/film_snob/oembed_providers/funny_or_die_spec.rb
|
109
|
+
- spec/film_snob/oembed_providers/hulu_spec.rb
|
110
|
+
- spec/film_snob/oembed_providers/instagram_spec.rb
|
111
|
+
- spec/film_snob/oembed_providers/rdio_spec.rb
|
112
|
+
- spec/film_snob/oembed_providers/rutube_spec.rb
|
113
|
+
- spec/film_snob/oembed_providers/soundcloud_spec.rb
|
114
|
+
- spec/film_snob/oembed_providers/vimeo_spec.rb
|
115
|
+
- spec/film_snob/oembed_providers/vine_spec.rb
|
116
|
+
- spec/film_snob/oembed_providers/youtube_spec.rb
|
224
117
|
- spec/film_snob_spec.rb
|
225
118
|
- spec/spec_helper.rb
|
data/lib/film_snob/deprecated.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
class FilmSnob
|
2
|
-
module Deprecated
|
3
|
-
def deprecated_alias(previous, replacement, options)
|
4
|
-
define_method(previous) do |*args, &block|
|
5
|
-
Kernel.warn "WARNING: ##{previous} is deprecated and " \
|
6
|
-
"will be removed in #{options[:removed_in]}. " \
|
7
|
-
"Please use ##{replacement} instead."
|
8
|
-
send(replacement, *args, &block)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
data/spec/deprecated_spec.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
class FilmSnob
|
2
|
-
describe Deprecated do
|
3
|
-
class Dog
|
4
|
-
extend Deprecated
|
5
|
-
|
6
|
-
deprecated_alias :woof, :bark, :removed_in => "v4.0.0"
|
7
|
-
|
8
|
-
def bark
|
9
|
-
"bark"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:milo) { Dog.new }
|
14
|
-
|
15
|
-
describe "deprecated_alias" do
|
16
|
-
it "does not interfere with the current method" do
|
17
|
-
expect(Kernel).to_not receive(:warn)
|
18
|
-
milo.bark
|
19
|
-
end
|
20
|
-
|
21
|
-
it "creates an alias" do
|
22
|
-
expect(milo).to respond_to :woof
|
23
|
-
expect(Kernel).to receive(:warn)
|
24
|
-
expect(milo.woof).to eq "bark"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|