yt 0.14.1 → 0.14.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db4db84624546717fdc851f9686077c0926798ac
4
- data.tar.gz: 69322165d6a6a13484613c7d1f3e3fda0c3c79d4
3
+ metadata.gz: 3ab7c0d75dc3c575f9c55dd9e222505f70db290f
4
+ data.tar.gz: 1594d3e696c068d0a439396591e6a41efb292dd0
5
5
  SHA512:
6
- metadata.gz: fe0e64e30469c9539c4e5441e6d691bf91f6bf3f66e5d1cfbf6aa4a790a79e21aeeea6a4c2e02eb4d147817467e052409789054bd369268cba906759563fd655
7
- data.tar.gz: c4e6b9bbab1327dcc20acbdd65260d83b6ec06723a21a098efcb0bbb6fc5ef9555a6897d1a86dd48b120e86ee58857b051c383089f1503a49c48bce8659098be
6
+ metadata.gz: 5205274ae1d25ce04a75f6d5cd92742e1cfa77930695795a13879f463dcbaf0c5d5d25e56ef799bf90506c0494a29e732133faab705da4c9c32d2cf54bbb7d38
7
+ data.tar.gz: 42810660757c546f295d1f8b038ce2b7cefb74b30c20327cc7d1548e19562c07c06cfc3e53b867d604ef0156edc4be96bfcdc656acaeda030c87d1ef89441f2a
@@ -6,6 +6,12 @@ For more information about changelogs, check
6
6
  [Keep a Changelog](http://keepachangelog.com) and
7
7
  [Vandamme](http://tech-angels.github.io/vandamme).
8
8
 
9
+ ## 0.14.2 - 2015-04-08
10
+
11
+ * [FEATURE] Make `Annotation#text` a public method.
12
+ * [FEATURE] Make `data` a public method for Snippet, Status, ContentDetail and StatisticsSet.
13
+ * [FEATURE] Add .includes to .videos, so you can eager load snippet, status, statistics and content details for a collection of videos
14
+
9
15
  ## 0.14.1 - 2015-03-30
10
16
 
11
17
  * [FEATURE] New `monetized playbacks` report for channels.
data/README.md CHANGED
@@ -41,7 +41,7 @@ To install on your system, run
41
41
 
42
42
  To use inside a bundled Ruby project, add this line to the Gemfile:
43
43
 
44
- gem 'yt', '~> 0.14.1'
44
+ gem 'yt', '~> 0.14.2'
45
45
 
46
46
  Since the gem follows [Semantic Versioning](http://semver.org),
47
47
  indicating the full version in your Gemfile (~> *major*.*minor*.*patch*)
data/bin/yt CHANGED
@@ -7,100 +7,24 @@ rescue LoadError
7
7
  require 'yt'
8
8
  end
9
9
 
10
- ############################
11
-
12
- # account = Yt::Account.new refresh_token: ENV['YT_TEST_DEVICE_REFRESH_TOKEN']
13
-
14
- # youtube.readonly and yt-analytics.readonly are not available with device :(
15
- account = Yt::Account.new scopes: %w(userinfo.email userinfo.profile youtube)
16
- 0.upto(60) do |i|
17
- begin
18
- break if account.authentication
19
- rescue Yt::Errors::MissingAuth => e
20
- puts e.more_details if i.zero?
21
- 5.times {print '.'; sleep 1}
10
+ Yt.configuration.log_level = :debug
11
+ id = ARGV[1] || 'BPNYv0vd78A'
12
+
13
+ case ARGV[0]
14
+ when 'info'
15
+ puts "Yt version #{Yt::VERSION}"
16
+ video = Yt::Video.new id: id
17
+ puts video.annotations.first.text
18
+ when 'annotations'
19
+ video = Yt::Video.new id: id
20
+ count = video.annotations.size
21
+ puts "Video #{id} has #{count} #{'annotation'.pluralize count}"
22
+ video.annotations.each.with_index do |annotation, i|
23
+ puts "#{i+1}) #{annotation.text}"
22
24
  end
25
+ when 'video'
26
+ video = Yt::Video.new id: id
27
+ views = "#{video.view_count} #{'view'.pluralize video.view_count}"
28
+ likes = "#{video.like_count} #{'like'.pluralize video.like_count}"
29
+ puts "'#{video.title}' by #{video.channel_title} has #{views} and #{likes}"
23
30
  end
24
-
25
- puts "\nACCOUNT:\n"
26
- puts " ID: #{account.id}"
27
- puts " Email: #{account.email}"
28
- puts " Email verified? #{account.has_verified_email?}"
29
- puts " Gender: #{account.gender}"
30
- puts " Name: #{account.name}"
31
- puts " Given Name: #{account.given_name}"
32
- puts " Family Name: #{account.family_name}"
33
- puts " Profile URL: #{account.profile_url}"
34
- puts " Avatar URL: #{account.avatar_url}"
35
- puts " Locale: #{account.locale}"
36
- puts " Hd? #{account.hd}"
37
-
38
- puts "\nCHANNEL:\n"
39
- channel = account.channel
40
- puts " Title: #{channel.title}"
41
- puts " Description: #{channel.description.truncate(30)}"
42
- puts " Thumbnail URL: #{channel.thumbnail_url}"
43
- puts " Published at: #{channel.published_at}"
44
- puts " Public? #{channel.public?}"
45
- puts " Views: #{channel.view_count}"
46
- puts " Comments: #{channel.comment_count}"
47
- puts " Videos: #{channel.video_count}"
48
- puts " Subscribers: #{channel.subscriber_count}"
49
- puts " Subscribers are visible? #{channel.subscriber_count_visible?}"
50
- # These are not available with a device auth :(
51
- # puts " Views: #{channel.views}"
52
- # puts " Comments: #{channel.comments}"
53
- # puts " Likes: #{channel.likes}"
54
- # puts " Dislikes: #{channel.dislikes}"
55
- # puts " Shares: #{channel.shares}"
56
- # puts " Viewers: #{channel.viewer_percentages}"
57
-
58
- account.videos.first(5).each.with_index do |video, i|
59
- puts "\nVIDEO #{i+1}:\n"
60
- puts " Title: #{video.title}"
61
- puts " Description: #{video.description.truncate(30)}"
62
- puts " Thumbnail URL: #{video.thumbnail_url}"
63
- puts " Published at: #{video.published_at}"
64
- puts " Tags: #{video.tags}"
65
- puts " Channel ID: #{video.channel_id}"
66
- puts " Channel Title: #{video.channel_title}"
67
- puts " Category ID: #{video.category_id}"
68
- puts " Live content? #{video.live_broadcast_content}"
69
- puts " Public? #{video.public?}"
70
- puts " Views: #{video.view_count}"
71
- puts " Comments: #{video.comment_count}"
72
- puts " Likes: #{video.like_count}"
73
- puts " Dislikes: #{video.dislike_count}"
74
- puts " Favorites: #{video.favorite_count}"
75
- puts " Duration: #{video.duration}s"
76
- puts " HD: #{video.hd?}"
77
- puts " stereoscopic? #{video.stereoscopic?}"
78
- puts " captioned? #{video.captioned?}"
79
- puts " licensed? #{video.licensed?}"
80
- # These are not available with a device auth :(
81
- # puts " Views: #{video.views}"
82
- # puts " Comments: #{video.comments}"
83
- # puts " Likes: #{video.likes}"
84
- # puts " Dislikes: #{video.dislikes}"
85
- # puts " Shares: #{video.shares}"
86
- # puts " Viewers: #{video.viewer_percentages}"
87
- puts " Annotations: #{video.annotations.count}"
88
- end
89
-
90
- account.playlists.first(5).each.with_index do |playlist, i|
91
- puts "\nPLAYLIST #{i+1}:\n"
92
- puts " Title: #{playlist.title}"
93
- puts " Description: #{playlist.description.truncate(30)}"
94
- puts " Thumbnail URL: #{playlist.thumbnail_url}"
95
- puts " Published at: #{playlist.published_at}"
96
- puts " Tags: #{playlist.tags}"
97
- puts " Channel ID: #{playlist.channel_id}"
98
- puts " Channel Title: #{playlist.channel_title}"
99
- puts " Public? #{playlist.public?}"
100
- puts " Playlist items: #{playlist.playlist_items.count}"
101
- playlist.playlist_items.first(5).each.with_index do |playlist_item, j|
102
- puts " \nPLAYLIST ITEM #{j+1}:\n"
103
- puts " Position: #{playlist_item.position + 1}"
104
- puts " Video ID: #{playlist_item.video_id}"
105
- end
106
- end
@@ -41,11 +41,22 @@ module Yt
41
41
  end
42
42
  end
43
43
 
44
+ def includes(*relationships)
45
+ self.tap do
46
+ @items = []
47
+ @included_relationships = relationships
48
+ end
49
+ end
50
+
44
51
  private
45
52
 
46
53
  def apply_where_params!(params = {})
47
54
  params.merge!(@where_params ||= {})
48
55
  end
56
+
57
+ def included_relationships
58
+ @included_relationships || []
59
+ end
49
60
  end
50
61
  end
51
62
  end
@@ -4,13 +4,6 @@ module Yt
4
4
  module Collections
5
5
  class PartneredChannels < Channels
6
6
 
7
- def includes(relationship)
8
- self.tap do
9
- @items = []
10
- @includes_relationship = relationship
11
- end
12
- end
13
-
14
7
  private
15
8
 
16
9
  def attributes_for_new_item(data)
@@ -20,7 +13,7 @@ module Yt
20
13
  end
21
14
 
22
15
  def eager_load_items_from(items)
23
- if @includes_relationship == :viewer_percentages
16
+ if included_relationships.include? :viewer_percentages
24
17
  filters = "channel==#{items.map{|item| item['id']}.join(',')}"
25
18
  ids = "contentOwner==#{@auth.owner_name}"
26
19
  conditions = {ids: ids, filters: filters}
@@ -30,7 +23,7 @@ module Yt
30
23
  item['viewerPercentages'] = viewer_percentages[item['id']]
31
24
  end
32
25
  end
33
- items
26
+ super
34
27
  end
35
28
 
36
29
  # @private
@@ -3,10 +3,10 @@ require 'yt/collections/base'
3
3
  module Yt
4
4
  module Collections
5
5
  class Reports < Base
6
- DIMENSIONS = Hash.new({name: 'day', parse: -> (day) {Date.iso8601 day} }).tap do |hash|
7
- hash[:traffic_source] = {name: 'insightTrafficSourceType', parse: -> (type) {TRAFFIC_SOURCES.key type} }
8
- hash[:video] = {name: 'video', parse: -> (video_id) { Yt::Video.new id: video_id, auth: @auth } }
9
- hash[:playlist] = {name: 'playlist', parse: -> (playlist_id) { Yt::Playlist.new id: playlist_id, auth: @auth } }
6
+ DIMENSIONS = Hash.new({name: 'day', parse: ->(day) {Date.iso8601 day} }).tap do |hash|
7
+ hash[:traffic_source] = {name: 'insightTrafficSourceType', parse: ->(type) {TRAFFIC_SOURCES.key type} }
8
+ hash[:video] = {name: 'video', parse: ->(video_id) { Yt::Video.new id: video_id, auth: @auth } }
9
+ hash[:playlist] = {name: 'playlist', parse: ->(playlist_id) { Yt::Playlist.new id: playlist_id, auth: @auth } }
10
10
  end
11
11
 
12
12
  # @see https://developers.google.com/youtube/analytics/v1/dimsmets/dims#Traffic_Source_Dimensions
@@ -80,4 +80,4 @@ module Yt
80
80
  end
81
81
  end
82
82
  end
83
- end
83
+ end
@@ -8,12 +8,16 @@ module Yt
8
8
  # Resources with videos are: {Yt::Models::Channel channels} and
9
9
  # {Yt::Models::Account accounts}.
10
10
  class Videos < Base
11
+ def where(requirements = {})
12
+ @published_before = nil
13
+ super
14
+ end
11
15
 
12
16
  private
13
17
 
14
18
  def attributes_for_new_item(data)
15
19
  id = use_list_endpoint? ? data['id'] : data['id']['videoId']
16
- snippet = data['snippet'].merge includes_tags: false if data['snippet']
20
+ snippet = data['snippet'].reverse_merge includes_tags: false if data['snippet']
17
21
  {}.tap do |attributes|
18
22
  attributes[:id] = id
19
23
  attributes[:snippet] = snippet
@@ -24,6 +28,28 @@ module Yt
24
28
  end
25
29
  end
26
30
 
31
+ def eager_load_items_from(items)
32
+ if included_relationships.any?
33
+ ids = items.map{|item| item['id']['videoId']}
34
+ parts = included_relationships.map{|r| r.to_s.camelize(:lower)}
35
+ conditions = {id: ids.join(','), part: parts.join(',')}
36
+ videos = Collections::Videos.new(auth: @auth).where conditions
37
+
38
+ items.each do |item|
39
+ video = videos.find{|v| v.id == item['id']['videoId']}
40
+ parts.each do |part|
41
+ item[part] = case part
42
+ when 'snippet' then video.snippet.data.merge includes_tags: true
43
+ when 'status' then video.status.data
44
+ when 'statistics' then video.statistics_set.data
45
+ when 'contentDetails' then video.content_detail.data
46
+ end
47
+ end
48
+ end
49
+ end
50
+ super
51
+ end
52
+
27
53
  # @return [Hash] the parameters to submit to YouTube to list videos.
28
54
  # @see https://developers.google.com/youtube/v3/docs/search/list
29
55
  def list_params
@@ -71,12 +71,12 @@ module Yt
71
71
  timestamps.first < seconds if timestamps.any?
72
72
  end
73
73
 
74
- private
75
-
76
74
  def text
77
75
  @text ||= @data['TEXT'] || ''
78
76
  end
79
77
 
78
+ private
79
+
80
80
  has_attribute :type, default: ''
81
81
 
82
82
  def link_class
@@ -6,6 +6,7 @@ module Yt
6
6
  # of the video and an indication of whether captions are available.
7
7
  # @see https://developers.google.com/youtube/v3/docs/videos#resource
8
8
  class ContentDetail < Base
9
+ attr_reader :data
9
10
 
10
11
  def initialize(options = {})
11
12
  @data = options[:data]
@@ -12,6 +12,8 @@ module Yt
12
12
  # @see https://developers.google.com/youtube/v3/docs/playlists#resource
13
13
  # @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
14
14
  class Snippet < Base
15
+ attr_reader :data
16
+
15
17
  def initialize(options = {})
16
18
  @data = options[:data]
17
19
  @auth = options[:auth]
@@ -153,7 +155,7 @@ module Yt
153
155
  # @see https://developers.google.com/youtube/v3/docs/videos
154
156
  # @return [Boolean] whether YouTube API includes tags in this snippet.
155
157
  def includes_tags
156
- @includes_tags ||= @data.fetch :includes_tags, true
158
+ @includes_tags ||= data.fetch :includes_tags, true
157
159
  end
158
160
 
159
161
  private
@@ -6,6 +6,8 @@ module Yt
6
6
  # the resource has been viewed or liked.
7
7
  # @see https://developers.google.com/youtube/v3/docs/videos#resource
8
8
  class StatisticsSet < Base
9
+ attr_reader :data
10
+
9
11
  def initialize(options = {})
10
12
  @data = options[:data]
11
13
  end
@@ -12,6 +12,8 @@ module Yt
12
12
  # @see https://developers.google.com/youtube/v3/docs/playlists#resource
13
13
  # @see https://developers.google.com/youtube/v3/docs/playlistItems#resource
14
14
  class Status < Base
15
+ attr_reader :data
16
+
15
17
  def initialize(options = {})
16
18
  @data = options[:data]
17
19
  end
@@ -1,3 +1,3 @@
1
1
  module Yt
2
- VERSION = '0.14.1'
2
+ VERSION = '0.14.2'
3
3
  end
@@ -43,6 +43,13 @@ describe Yt::Annotation do
43
43
  end
44
44
  end
45
45
 
46
+ describe '#text' do
47
+ context 'given an annotation with text' do
48
+ let(:xml) { '<TEXT>Hello, world!</TEXT>' }
49
+ it { expect(annotation.text).to eq 'Hello, world!' }
50
+ end
51
+ end
52
+
46
53
  describe '#has_link_to_subscribe?' do
47
54
  context 'given an annotation with a link of class 5' do
48
55
  let(:xml) { '<action type="openUrl"><url link_class="5"/></action>' }
@@ -4,6 +4,13 @@ require 'yt/models/content_detail'
4
4
  describe Yt::ContentDetail do
5
5
  subject(:content_detail) { Yt::ContentDetail.new data: data }
6
6
 
7
+ describe '#data' do
8
+ let(:data) { {"key"=>"value"} }
9
+ specify 'returns the data the content detail was initialized with' do
10
+ expect(content_detail.data).to eq data
11
+ end
12
+ end
13
+
7
14
  describe '#duration' do
8
15
  context 'given a content_detail with duration in weeks, days, hours, minutes' do
9
16
  let(:data) { {"duration"=>"P1W2DT6H21M32S"}}
@@ -5,6 +5,13 @@ describe Yt::Snippet do
5
5
  subject(:snippet) { Yt::Snippet.new data: data }
6
6
  let(:data) { {} }
7
7
 
8
+ describe '#data' do
9
+ let(:data) { {"key"=>"value"} }
10
+ specify 'returns the data the snippet was initialized with' do
11
+ expect(snippet.data).to eq data
12
+ end
13
+ end
14
+
8
15
  describe '#title' do
9
16
  context 'given a snippet with a title' do
10
17
  let(:data) { {"title"=>"Fullscreen"} }
@@ -5,6 +5,13 @@ describe Yt::StatisticsSet do
5
5
  subject(:statistics_set) { Yt::StatisticsSet.new data: data }
6
6
  let(:value) { 42 }
7
7
 
8
+ describe '#data' do
9
+ let(:data) { {"key"=>"value"} }
10
+ specify 'returns the data the statistics set was initialized with' do
11
+ expect(statistics_set.data).to eq data
12
+ end
13
+ end
14
+
8
15
  describe '#view_count' do
9
16
  context 'given a video with views' do
10
17
  let(:data) { {"viewCount"=>value} }
@@ -4,6 +4,13 @@ require 'yt/models/status'
4
4
  describe Yt::Status do
5
5
  subject(:status) { Yt::Status.new data: data }
6
6
 
7
+ describe '#data' do
8
+ let(:data) { {"key"=>"value"} }
9
+ specify 'returns the data the status was initialized with' do
10
+ expect(status.data).to eq data
11
+ end
12
+ end
13
+
7
14
  describe '#public?' do
8
15
  context 'given fetching a status returns privacyStatus "public"' do
9
16
  let(:data) { {"privacyStatus"=>"public"} }
@@ -49,6 +49,33 @@ describe Yt::Account, :device_app do
49
49
  let(:other_video) { $account.videos.where(order: 'viewCount', chart: 'invalid').first }
50
50
  it { expect(other_video.id).to eq video.id }
51
51
  end
52
+
53
+ describe '.includes(:snippet)' do
54
+ let(:video) { $account.videos.includes(:snippet).first }
55
+
56
+ specify 'eager-loads the *full* snippet of each video' do
57
+ expect(video.instance_variable_defined? :@snippet).to be true
58
+ expect(video.channel_title).to be
59
+ expect(video.snippet.includes_tags).to be true
60
+ end
61
+ end
62
+
63
+ describe '.includes(:statistics, :status)' do
64
+ let(:video) { $account.videos.includes(:statistics, :status).first }
65
+
66
+ specify 'eager-loads the statistics and status of each video' do
67
+ expect(video.instance_variable_defined? :@statistics_set).to be true
68
+ expect(video.instance_variable_defined? :@status).to be true
69
+ end
70
+ end
71
+
72
+ describe '.includes(:content_details)' do
73
+ let(:video) { $account.videos.includes(:content_details).first }
74
+
75
+ specify 'eager-loads the statistics of each video' do
76
+ expect(video.instance_variable_defined? :@content_detail).to be true
77
+ end
78
+ end
52
79
  end
53
80
 
54
81
  describe '.upload_video' do
@@ -21,7 +21,68 @@ describe Yt::Channel, :device_app do
21
21
  expect(channel.subscriber_count_visible?).to be_in [true, false]
22
22
  end
23
23
 
24
- it { expect(channel.videos.first).to be_a Yt::Video }
24
+ describe '.videos' do
25
+ let(:video) { channel.videos.first }
26
+
27
+ specify 'returns the videos in the channel without their tags' do
28
+ expect(video).to be_a Yt::Video
29
+ expect(video.snippet.includes_tags).to be false
30
+ end
31
+
32
+ describe '.where(id: *anything*)' do
33
+ let(:video) { channel.videos.where(id: 'invalid').first }
34
+
35
+ specify 'is ignored (all the channel’s videos are returned)' do
36
+ expect(video).to be_a Yt::Video
37
+ end
38
+ end
39
+
40
+ describe '.where(chart: *anything*)' do
41
+ let(:video) { channel.videos.where(chart: 'invalid').first }
42
+
43
+ specify 'is ignored (all the channel’s videos are returned)' do
44
+ expect(video).to be_a Yt::Video
45
+ end
46
+ end
47
+
48
+ describe '.includes(:statistics, :status)' do
49
+ let(:video) { channel.videos.includes(:statistics, :status).first }
50
+
51
+ specify 'eager-loads the statistics and status of each video' do
52
+ expect(video.instance_variable_defined? :@statistics_set).to be true
53
+ expect(video.instance_variable_defined? :@status).to be true
54
+ end
55
+ end
56
+
57
+ describe '.includes(:content_details)' do
58
+ let(:video) { channel.videos.includes(:content_details).first }
59
+
60
+ specify 'eager-loads the statistics of each video' do
61
+ expect(video.instance_variable_defined? :@content_detail).to be true
62
+ end
63
+ end
64
+
65
+
66
+ describe 'when the channel has more than 500 videos' do
67
+ let(:id) { 'UCsmvakQZlvGsyjyOhmhvOsw' }
68
+
69
+ specify 'the estimated and actual number of videos can be retrieved' do
70
+ # @note: in principle, the following three counters should match, but
71
+ # in reality +video_count+ and +size+ are only approximations.
72
+ expect(channel.video_count).to be > 500
73
+ expect(channel.videos.size).to be > 500
74
+ end
75
+
76
+ specify 'over 500 videos can only be retrieved when sorting by date' do
77
+ # @note: these tests are slow because they go through multiple pages
78
+ # of results to test that we can overcome YouTube’s limitation of only
79
+ # returning the first 500 results when ordered by date.
80
+ expect(channel.videos.count).to be > 500
81
+ expect(channel.videos.where(order: 'viewCount').count).to be 500
82
+ end
83
+ end
84
+ end
85
+
25
86
  it { expect(channel.playlists.first).to be_a Yt::Playlist }
26
87
  it { expect{channel.delete_playlists}.to raise_error Yt::Errors::RequestError }
27
88
 
@@ -70,29 +131,6 @@ describe Yt::Channel, :device_app do
70
131
  it { expect(channel.subscribe!).to be_truthy }
71
132
  end
72
133
  end
73
-
74
- describe 'filtering by ID is ignored when listing videos' do
75
- it { expect(channel.videos.where(id: 'invalid').first).to be_a Yt::Video }
76
- end
77
-
78
- describe 'filtering by chart is ignored when listing videos' do
79
- it { expect(channel.videos.where(chart: 'invalid').first).to be_a Yt::Video }
80
- end
81
-
82
- context 'with more than 500 videos' do
83
- let(:id) { 'UCsmvakQZlvGsyjyOhmhvOsw' }
84
- # @note: in principle, the following three counters should match, but in
85
- # reality +video_count+ and +size+ are only approximations.
86
- it { expect(channel.video_count).to be > 500 }
87
- it { expect(channel.videos.size).to be > 500 }
88
- context 'with default order (by date)' do
89
- # @note: these tests are slow because they go through multiple pages of
90
- # results and do so to test that we can overcome YouTube’s limitation of
91
- # only returning the first 500 results when ordered by date.
92
- it { expect(channel.videos.count).to be > 500 }
93
- it { expect(channel.videos.where(order: 'viewCount').count).to be 500 }
94
- end
95
- end
96
134
  end
97
135
 
98
136
  context 'given my own channel' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 0.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claudio Baccigalupo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-31 00:00:00.000000000 Z
11
+ date: 2015-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport