pipe_dream 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0f47b91cab96e06142f2cd405feb214c927fcae0
4
+ data.tar.gz: e8e08de2ea36cd16f29381487068bf96242fdfab
5
+ SHA512:
6
+ metadata.gz: 6944745d527bff9e69d7aa46ffd00c104353489c09138b1ed1913cea4ec19f56c7119590d696670c74fc59436094bdd5ae2144ad9560f3c1b3ec7fc819bb1648
7
+ data.tar.gz: e6242e4ce14a76ffe315ba64c61d58d0d328dda381e172818c717763efb05d236099e5faa10455e977c0d8c2597d3d275ffb224f1704ce9818d85240631711be
@@ -0,0 +1,62 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.3.3-node-browsers
11
+
12
+ # Specify service dependencies here if necessary
13
+ # CircleCI maintains a library of pre-built images
14
+ # documented at https://circleci.com/docs/2.0/circleci-images/
15
+ # - image: circleci/postgres:9.4
16
+
17
+ working_directory: ~/pipe_dream
18
+
19
+ steps:
20
+ - checkout
21
+
22
+ # Download and cache dependencies
23
+ - restore_cache:
24
+ keys:
25
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
26
+ # fallback to using the latest cache if no exact match is found
27
+ - v1-dependencies-
28
+
29
+ - run:
30
+ name: install dependencies
31
+ command: |
32
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
33
+
34
+ - save_cache:
35
+ paths:
36
+ - ./vendor/bundle
37
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
38
+
39
+ # run rubocop
40
+ - run:
41
+ name: run rubocop
42
+ command: |
43
+ rubocop
44
+
45
+ # run tests!
46
+ - run:
47
+ name: run tests
48
+ command: |
49
+ mkdir /tmp/test-results
50
+ TEST_FILES="$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)"
51
+
52
+ bundle exec rspec --format progress \
53
+ --out /tmp/test-results/rspec.xml \
54
+ --format progress \
55
+ $TEST_FILES
56
+
57
+ # collect reports
58
+ - store_test_results:
59
+ path: /tmp/test-results
60
+ - store_artifacts:
61
+ path: /tmp/test-results
62
+ destination: test-results
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ .byebug_history
11
+ .rubocop-https---raw-githubusercontent-com-rubocop-hq-rubocop-master-config-enabled-yml
@@ -0,0 +1,13 @@
1
+ inherit_from:
2
+ - https://raw.githubusercontent.com/rubocop-hq/rubocop/master/config/enabled.yml
3
+
4
+ Metrics/BlockLength:
5
+ Enabled: true
6
+ Exclude:
7
+ - spec/**/*
8
+ Style/Documentation:
9
+ Enabled: false
10
+ Style/ExpandPathArguments:
11
+ Enabled: false
12
+ Style/FrozenStringLiteralComment:
13
+ Enabled: false
@@ -0,0 +1 @@
1
+ ruby-2.3.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in pipe_dream.gemspec
6
+ gemspec
@@ -0,0 +1,53 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pipe_dream (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.0)
10
+ diff-lcs (1.3)
11
+ jaro_winkler (1.5.1)
12
+ parallel (1.12.1)
13
+ parser (2.5.1.0)
14
+ ast (~> 2.4.0)
15
+ powerpack (0.1.2)
16
+ rainbow (3.0.0)
17
+ rake (10.5.0)
18
+ rspec (3.7.0)
19
+ rspec-core (~> 3.7.0)
20
+ rspec-expectations (~> 3.7.0)
21
+ rspec-mocks (~> 3.7.0)
22
+ rspec-core (3.7.1)
23
+ rspec-support (~> 3.7.0)
24
+ rspec-expectations (3.7.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.7.0)
27
+ rspec-mocks (3.7.0)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.7.0)
30
+ rspec-support (3.7.1)
31
+ rubocop (0.57.2)
32
+ jaro_winkler (~> 1.5.1)
33
+ parallel (~> 1.10)
34
+ parser (>= 2.5)
35
+ powerpack (~> 0.1)
36
+ rainbow (>= 2.2.2, < 4.0)
37
+ ruby-progressbar (~> 1.7)
38
+ unicode-display_width (~> 1.0, >= 1.0.1)
39
+ ruby-progressbar (1.9.0)
40
+ unicode-display_width (1.4.0)
41
+
42
+ PLATFORMS
43
+ ruby
44
+
45
+ DEPENDENCIES
46
+ bundler (~> 1.16)
47
+ pipe_dream!
48
+ rake (~> 10.0)
49
+ rspec (~> 3.7)
50
+ rubocop (~> 0.52)
51
+
52
+ BUNDLED WITH
53
+ 1.16.2
@@ -0,0 +1,52 @@
1
+ # PipeDream
2
+
3
+ PipeDream allows you to easily search YouTube by providing a simple wrapper
4
+ around YouTube's official APIs. What sets PipeDream apart from other options, is
5
+ that it has no dependencies outside the Ruby standard library. This makes it easy
6
+ to include in projects where you can't easily bundle dependencies, such as in an
7
+ Alfred workflow.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'pipe_dream'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install pipe_dream
24
+
25
+ ## Usage
26
+
27
+ Before you begin using PipeDream to perform searches, you will have to configure
28
+ it with your developer API key. You can create a new API key using the
29
+ [Google Cloud Console](https://console.cloud.google.com/). Once you have created your key, configure PipeDream with
30
+ it like this:
31
+
32
+ ```ruby
33
+ PipeDream.configure do |config|
34
+ config.api_key = '<your-api-key>'
35
+ end
36
+ ```
37
+
38
+ Now you can begin searching! Here is a basic example of how you can perform a search:
39
+
40
+ ```ruby
41
+ req = PipeDream::Request.new('redlettermedia')
42
+ res = PipeDream::Response.new(req.get)
43
+ # The items method will return an array of objects that wrap the search results.
44
+ items = res.items #=> [#<PipeDream::Result::Channel...]
45
+ channel = items.first
46
+ channel.title #=> 'RedLetterMedia'
47
+ channel.description #=> 'Red Letter Media is responsible for the 70 minute Phantom Menace review as well as Space Cop, Half in the Bag, and Best of the Worst. Full time frauds.'
48
+ ```
49
+
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[goronfreeman]/pipe_dream.
@@ -0,0 +1,10 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :console do
7
+ exec 'irb -r pipe_dream -I ./lib'
8
+ end
9
+
10
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'pipe_dream'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,21 @@
1
+ require 'pipe_dream/version'
2
+ require 'pipe_dream/configuration'
3
+ require 'pipe_dream/response'
4
+ require 'pipe_dream/result'
5
+ require 'pipe_dream/request'
6
+ require 'pipe_dream/utils'
7
+ require 'pipe_dream/results/base'
8
+ require 'pipe_dream/results/channel'
9
+ require 'pipe_dream/results/playlist'
10
+ require 'pipe_dream/results/video'
11
+
12
+ module PipeDream
13
+ class << self
14
+ attr_accessor :configuration
15
+ end
16
+
17
+ def self.configure
18
+ self.configuration ||= Configuration.new
19
+ yield(configuration)
20
+ end
21
+ end
@@ -0,0 +1,9 @@
1
+ module PipeDream
2
+ class Configuration
3
+ attr_accessor :api_key
4
+
5
+ def initialize
6
+ @api_key = nil
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,37 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ require 'pipe_dream/utils'
5
+
6
+ module PipeDream
7
+ class Request
8
+ include Utils
9
+
10
+ def initialize(search_term, options = {})
11
+ @search_term = search_term
12
+ @api_key = PipeDream.configuration.api_key
13
+ @options = camelize_keys(options)
14
+ end
15
+
16
+ def get
17
+ Net::HTTP.get(uri)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :search_term, :api_key, :options
23
+
24
+ def uri
25
+ URI('https://www.googleapis.com').tap do |uri|
26
+ uri.path = '/youtube/v3/search'
27
+ uri.query = URI.encode_www_form(params)
28
+ end
29
+ end
30
+
31
+ def params
32
+ { part: 'snippet',
33
+ key: api_key,
34
+ q: search_term }.merge(options)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,45 @@
1
+ require 'json'
2
+
3
+ module PipeDream
4
+ class Response
5
+ def initialize(data)
6
+ @data = JSON.parse(data)
7
+ end
8
+
9
+ def kind
10
+ @kind ||= data.fetch('kind')
11
+ end
12
+
13
+ def etag
14
+ @etag ||= JSON.parse(data.fetch('etag'))
15
+ end
16
+
17
+ def next_page_token
18
+ @next_page_token ||= data.fetch('nextPageToken')
19
+ end
20
+
21
+ def region_code
22
+ @region_code ||= data.fetch('regionCode')
23
+ end
24
+
25
+ def total_results
26
+ @total_results ||= page_info.fetch('totalResults')
27
+ end
28
+
29
+ def results_per_page
30
+ @results_per_page ||= page_info.fetch('resultsPerPage')
31
+ end
32
+
33
+ def items
34
+ @items ||= data.fetch('items').map { |item| Result.for(item) }
35
+ end
36
+
37
+ private
38
+
39
+ attr_reader :data
40
+
41
+ def page_info
42
+ @page_info ||= data.fetch('pageInfo')
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ module PipeDream
2
+ module Result
3
+ def self.for(item)
4
+ case item.dig('id', 'kind')
5
+ when 'youtube#channel'
6
+ Channel
7
+ when 'youtube#playlist'
8
+ Playlist
9
+ when 'youtube#video'
10
+ Video
11
+ end.new(item)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,66 @@
1
+ module PipeDream
2
+ module Result
3
+ class Base
4
+ def initialize(data)
5
+ @data = data
6
+ end
7
+
8
+ def published_at
9
+ @published_at ||= snippet.fetch('publishedAt')
10
+ end
11
+
12
+ def channel_id
13
+ @channel_id ||= snippet.fetch('channelId')
14
+ end
15
+
16
+ def title
17
+ @title ||= snippet.fetch('title')
18
+ end
19
+
20
+ def description
21
+ @description ||= snippet.fetch('description')
22
+ end
23
+
24
+ # TODO: Add thumbnail dimension info?
25
+ def thumbnail_url(size = :small)
26
+ @thumbnail_url ||=
27
+ snippet.dig('thumbnails', size_mappings.fetch(size, 'default'), 'url')
28
+ end
29
+
30
+ def channel_title
31
+ @channel_title ||= snippet.fetch('channelTitle')
32
+ end
33
+
34
+ def live_broadcast_content
35
+ @live_broadcast_content ||= snippet.fetch('liveBroadcastContent')
36
+ end
37
+
38
+ alias created_at published_at
39
+
40
+ private
41
+
42
+ attr_reader :data
43
+
44
+ def snippet
45
+ @snippet = data.fetch('snippet')
46
+ end
47
+
48
+ def size_mappings
49
+ { small: 'default',
50
+ medium: 'medium',
51
+ large: 'high' }
52
+ end
53
+
54
+ def id(key)
55
+ data.dig('id', key)
56
+ end
57
+
58
+ def url(path, params = {})
59
+ URI('https://www.youtube.com').tap do |uri|
60
+ uri.path = path
61
+ uri.query = URI.encode_www_form(params)
62
+ end.to_s
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,13 @@
1
+ module PipeDream
2
+ module Result
3
+ class Channel < Base
4
+ def id
5
+ @id ||= super('channelId')
6
+ end
7
+
8
+ def url
9
+ @url ||= super("/channel/#{id}")
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module PipeDream
2
+ module Result
3
+ class Playlist < Base
4
+ def id
5
+ @id ||= super('playlistId')
6
+ end
7
+
8
+ def url
9
+ @url ||= super('/playlist', list: id)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module PipeDream
2
+ module Result
3
+ class Video < Base
4
+ def id
5
+ @id ||= super('videoId')
6
+ end
7
+
8
+ def url
9
+ @url ||= super('/watch', v: id)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module PipeDream
2
+ module Utils
3
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
4
+ def camelize_keys(hash)
5
+ hash.tap do |h|
6
+ affected_keys = h.each_key.select { |key| key.to_s.include?('_') }
7
+ return h if affected_keys.empty?
8
+
9
+ camelized_keys = affected_keys.map do |key|
10
+ key.to_s.split('_').map.with_index do |k, index|
11
+ next k if index.zero?
12
+ k.capitalize
13
+ end.join.to_sym
14
+ end
15
+
16
+ Hash[affected_keys.zip(camelized_keys)].each do |old, new|
17
+ h[new] = h.delete(old)
18
+ end
19
+ end
20
+ end
21
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module PipeDream
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'pipe_dream/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'pipe_dream'
7
+ spec.version = PipeDream::VERSION
8
+ spec.authors = ['Hunter Braun']
9
+ spec.email = ['hunter.braun@gmail.com']
10
+
11
+ spec.summary = 'A dreamy, zero-dependency YouTube API wrapper.'
12
+ spec.homepage = 'https://github.com/goronfreeman/pipe_dream'
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
+ f.match(%r{^(test|spec|features)/})
16
+ end
17
+ spec.bindir = 'exe'
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.16'
22
+ spec.add_development_dependency 'rake', '~> 10.0'
23
+ spec.add_development_dependency 'rspec', '~> 3.7'
24
+ spec.add_development_dependency 'rubocop', '~> 0.52'
25
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pipe_dream
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Hunter Braun
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-07-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
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.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
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.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.52'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.52'
69
+ description:
70
+ email:
71
+ - hunter.braun@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".circleci/config.yml"
77
+ - ".gitignore"
78
+ - ".rubocop.yml"
79
+ - ".ruby-version"
80
+ - Gemfile
81
+ - Gemfile.lock
82
+ - README.md
83
+ - Rakefile
84
+ - bin/console
85
+ - bin/setup
86
+ - lib/pipe_dream.rb
87
+ - lib/pipe_dream/configuration.rb
88
+ - lib/pipe_dream/request.rb
89
+ - lib/pipe_dream/response.rb
90
+ - lib/pipe_dream/result.rb
91
+ - lib/pipe_dream/results/base.rb
92
+ - lib/pipe_dream/results/channel.rb
93
+ - lib/pipe_dream/results/playlist.rb
94
+ - lib/pipe_dream/results/video.rb
95
+ - lib/pipe_dream/utils.rb
96
+ - lib/pipe_dream/version.rb
97
+ - pipe_dream.gemspec
98
+ homepage: https://github.com/goronfreeman/pipe_dream
99
+ licenses: []
100
+ metadata: {}
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ requirements: []
116
+ rubyforge_project:
117
+ rubygems_version: 2.5.2
118
+ signing_key:
119
+ specification_version: 4
120
+ summary: A dreamy, zero-dependency YouTube API wrapper.
121
+ test_files: []