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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +17 -4
  4. data/CHANGELOG.md +19 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +15 -0
  7. data/Guardfile +13 -0
  8. data/README.md +50 -11
  9. data/Rakefile +2 -5
  10. data/film_snob.gemspec +14 -22
  11. data/lib/film_snob.rb +8 -12
  12. data/lib/film_snob/exceptions.rb +5 -2
  13. data/lib/film_snob/{video_site.rb → oembed_provider.rb} +25 -9
  14. data/lib/film_snob/{video_sites → oembed_providers}/coub.rb +2 -2
  15. data/lib/film_snob/{video_sites → oembed_providers}/dailymotion.rb +2 -2
  16. data/lib/film_snob/{video_sites → oembed_providers}/funny_or_die.rb +2 -2
  17. data/lib/film_snob/{video_sites → oembed_providers}/hulu.rb +2 -2
  18. data/lib/film_snob/{video_sites → oembed_providers}/instagram.rb +2 -2
  19. data/lib/film_snob/oembed_providers/rdio.rb +20 -0
  20. data/lib/film_snob/{video_sites → oembed_providers}/rutube.rb +2 -2
  21. data/lib/film_snob/{video_sites → oembed_providers}/soundcloud.rb +2 -2
  22. data/lib/film_snob/{video_sites → oembed_providers}/vimeo.rb +2 -2
  23. data/lib/film_snob/{video_sites → oembed_providers}/vine.rb +2 -2
  24. data/lib/film_snob/{video_sites → oembed_providers}/youtube.rb +11 -2
  25. data/lib/film_snob/{url_to_video.rb → url_to_oembed_provider.rb} +6 -5
  26. data/lib/film_snob/version.rb +1 -1
  27. data/spec/film_snob/oembed_provider_spec.rb +27 -0
  28. data/spec/film_snob/{video_sites → oembed_providers}/coub_spec.rb +0 -0
  29. data/spec/film_snob/{video_sites → oembed_providers}/dailymotion_spec.rb +0 -0
  30. data/spec/film_snob/{video_sites → oembed_providers}/funny_or_die_spec.rb +0 -0
  31. data/spec/film_snob/{video_sites → oembed_providers}/hulu_spec.rb +0 -0
  32. data/spec/film_snob/{video_sites → oembed_providers}/instagram_spec.rb +0 -0
  33. data/spec/film_snob/oembed_providers/rdio_spec.rb +38 -0
  34. data/spec/film_snob/{video_sites → oembed_providers}/rutube_spec.rb +0 -0
  35. data/spec/film_snob/{video_sites → oembed_providers}/soundcloud_spec.rb +0 -0
  36. data/spec/film_snob/{video_sites → oembed_providers}/vimeo_spec.rb +0 -0
  37. data/spec/film_snob/{video_sites → oembed_providers}/vine_spec.rb +0 -0
  38. data/spec/film_snob/{video_sites → oembed_providers}/youtube_spec.rb +18 -0
  39. data/spec/spec_helper.rb +4 -2
  40. metadata +47 -154
  41. data/lib/film_snob/deprecated.rb +0 -12
  42. data/spec/deprecated_spec.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cf290744ac7770ce7b8d8f0ebdde751b4428557
4
- data.tar.gz: 0df2231616cbd058bea30b5480708f1c795e1d83
3
+ metadata.gz: f456c757ffe9c535c907220ae5774ddbd4506bba
4
+ data.tar.gz: 6f91fc2d8849c61775aea6259aafa36e2c01d28b
5
5
  SHA512:
6
- metadata.gz: 56540292bb66647af0749970dd8a9e28b6a09de560e3b1f7d8365f68c3ae613e48aa95d8fcf6b0bda984a5c0de7c7464ae7aa2faec3451e81a155324480498fe
7
- data.tar.gz: 5d132d9626ea0fe6852938748ba813539fdbd5626e5513f13d24d0e2a7dac1d4cc7b6b30868d75be63da772468a180bc1eed76ba6b8b3770a7efe14fbfbf0ad8
6
+ metadata.gz: f034c43b8fd9e49fd3d923e60085d8b502f17ad30178999bfdf66fb4ed63da9570a29209c5b252d17964d0bcf938a87516b98cada9055a8132fd3a75fe0841a3
7
+ data.tar.gz: aaec57f2af26a92fb192969cee667b4eb4a42c0666b9b860dc4847a7832174f160296dfc01450fdc7078725a1e60adab2997d2889453a4caaf3bf2ca9de70b5c
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --require spec_helper
3
+ --format documentation
@@ -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
- before_install: "gem install bundler -v 1.10"
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
@@ -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!
@@ -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
@@ -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
- Helps parse URLs of web videos.
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 assume some knowledge of the endpoint's API. The above vimeo example works because they [have an extensively documented API](http://developer.vimeo.com/apis/oembed) which allows tons of configuration. The other two don't seem to have any documentation or configuration at all.
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 will be run on Travis; both should pass to have a green build.
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 [create a GitHub issue](https://github.com/maxjacobson/film_snob/issues/new)
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
- 1. Fork it ( https://github.com/maxjacobson/film_snob/fork )
81
- 2. Create your feature branch (`git checkout -b my-new-feature`)
82
- 3. Commit your changes (`git commit -am "Add some feature"`)
83
- 4. Push to the branch (`git push origin my-new-feature`)
84
- 5. Create a new Pull Request
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
- # This tool requires keyword arguments
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]
@@ -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 = "film_snob"
8
- spec.version = FilmSnob::VERSION
9
- spec.authors = ["Max Jacobson"]
10
- spec.email = ["max@hardscrabble.net"]
11
- spec.summary = "Fetch embed codes for videos"
12
- spec.description = "Find information about URLs from video sites, " \
13
- "such as the title and embed code of the video"
14
- spec.homepage = "https://github.com/maxjacobson/film_snob"
15
- spec.license = "MIT"
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 = `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)/})
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", "~> 1.10"
23
- spec.add_development_dependency "rake", "~> 10.4"
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
@@ -1,35 +1,31 @@
1
1
  require "forwardable"
2
2
  require "film_snob/version"
3
- require "film_snob/url_to_video"
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 Deprecated, Forwardable
7
+ extend Forwardable
9
8
 
10
- VIDEO_METHODS = [:site, :id, :clean_url, :title, :html]
9
+ MEDIA_METHODS = [:site, :id, :clean_url, :title, :html]
11
10
 
12
- def_delegators :video, *VIDEO_METHODS
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
- @video = UrlToVideo.new(url, options).video
17
+ @media = UrlToOembedProvider.new(url, options).media
22
18
  end
23
19
 
24
20
  def embeddable?
25
- !@video.nil?
21
+ !@media.nil?
26
22
  end
27
23
 
28
24
  private
29
25
 
30
- def video
26
+ def media
31
27
  if embeddable?
32
- @video
28
+ @media
33
29
  else
34
30
  raise NotSupportedURLError, "#{url} is not a supported URL"
35
31
  end
@@ -1,4 +1,7 @@
1
1
  class FilmSnob
2
- class NotSupportedURLError < StandardError; end
3
- class NotEmbeddableError < StandardError; end
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
- # TODO(2015-11-15): rename to something more general
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 ||= JSON.parse response.body
79
- rescue
80
- @oembed = {}
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
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Coub < VideoSite
4
+ class Coub < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{https?://coub.com/view/(\w*)}
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Dailymotion < VideoSite
4
+ class Dailymotion < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{https?://www.dailymotion.com/video/([\w\d\-_]+)},
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class FunnyOrDie < VideoSite
4
+ class FunnyOrDie < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{http://www.funnyordie.com/videos/([\w\d]+)}
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Hulu < VideoSite
4
+ class Hulu < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{https?://(?:(?:www).)?hulu.com/watch/(\d+)}
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Instagram < VideoSite
4
+ class Instagram < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{https?://(?:(?:www).)?instagram.com/p/(\w+)},
@@ -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/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Rutube < VideoSite
4
+ class Rutube < OembedProvider
5
5
  def initialize(url, options = {})
6
6
  super(url, options.merge(:format => :json))
7
7
  end
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Soundcloud < VideoSite
4
+ class Soundcloud < OembedProvider
5
5
  def initialize(url, options = {})
6
6
  super(url, options.merge(:format => :json))
7
7
  end
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Vimeo < VideoSite
4
+ class Vimeo < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{https?://vimeo.com/(\d{1,})},
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class Vine < VideoSite
4
+ class Vine < OembedProvider
5
5
  def self.valid_url_patterns
6
6
  [
7
7
  %r{https://vine.co/v/(\w+)}
@@ -1,7 +1,7 @@
1
- require "film_snob/video_site"
1
+ require "film_snob/oembed_provider"
2
2
 
3
3
  class FilmSnob
4
- class YouTube < VideoSite
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
- Dir[File.join(File.dirname(__FILE__), "video_sites", "*.rb")].each do |file|
2
- require file
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 UrlToVideo
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 video
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 ||= VideoSite.subclasses.find do |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
@@ -1,3 +1,3 @@
1
1
  class FilmSnob
2
- VERSION = "0.6.5"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -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
@@ -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
@@ -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
@@ -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.6.5
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-14 00:00:00.000000000 Z
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
- - !ruby/object:Gem::Dependency
28
- name: rake
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/url_to_video.rb
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/deprecated_spec.rb
175
- - spec/film_snob/video_sites/coub_spec.rb
176
- - spec/film_snob/video_sites/dailymotion_spec.rb
177
- - spec/film_snob/video_sites/funny_or_die_spec.rb
178
- - spec/film_snob/video_sites/hulu_spec.rb
179
- - spec/film_snob/video_sites/instagram_spec.rb
180
- - spec/film_snob/video_sites/rutube_spec.rb
181
- - spec/film_snob/video_sites/soundcloud_spec.rb
182
- - spec/film_snob/video_sites/vimeo_spec.rb
183
- - spec/film_snob/video_sites/vine_spec.rb
184
- - spec/film_snob/video_sites/youtube_spec.rb
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: 1.9.3
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.4.5.1
99
+ rubygems_version: 2.5.0
208
100
  signing_key:
209
101
  specification_version: 4
210
- summary: Fetch embed codes for videos
102
+ summary: Fetch data from oEmbed APIs
211
103
  test_files:
212
104
  - spec/cassettes/README.md
213
- - spec/deprecated_spec.rb
214
- - spec/film_snob/video_sites/coub_spec.rb
215
- - spec/film_snob/video_sites/dailymotion_spec.rb
216
- - spec/film_snob/video_sites/funny_or_die_spec.rb
217
- - spec/film_snob/video_sites/hulu_spec.rb
218
- - spec/film_snob/video_sites/instagram_spec.rb
219
- - spec/film_snob/video_sites/rutube_spec.rb
220
- - spec/film_snob/video_sites/soundcloud_spec.rb
221
- - spec/film_snob/video_sites/vimeo_spec.rb
222
- - spec/film_snob/video_sites/vine_spec.rb
223
- - spec/film_snob/video_sites/youtube_spec.rb
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
@@ -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
@@ -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