Skip to content

Commit

Permalink
@wip Implementing analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
claudiob committed May 30, 2014
1 parent 4e4fa50 commit 090e9fc
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 19 deletions.
3 changes: 2 additions & 1 deletion lib/yt.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
require 'yt/config'
require 'yt/models/account'
require 'yt/models/account'
require 'yt/models/content_owner'
8 changes: 6 additions & 2 deletions lib/yt/actions/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
module Yt
module Actions
module List
delegate :count, :first, :any?, :each, :map, :find, to: :list
delegate :count, :first, :any?, :each, :map, :flat_map, :find, to: :list
alias size count

def first!
Expand Down Expand Up @@ -51,7 +51,7 @@ def fetch_page(params = {})
request = Yt::Request.new params
response = request.run
token = response.body['nextPageToken']
items = response.body.fetch 'items', []
items = response.body.fetch items_key, []
{items: items, token: token}
end

Expand All @@ -65,6 +65,10 @@ def list_params
params[:exptected_response] = Net::HTTPOK
end
end

def items_key
'items'
end
end
end
end
1 change: 1 addition & 0 deletions lib/yt/associations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Associations
autoload :Authentications
autoload :Channels
autoload :DetailsSets
autoload :Earnings
autoload :Ids
autoload :PlaylistItems
autoload :Playlists
Expand Down
36 changes: 36 additions & 0 deletions lib/yt/associations/earnings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'yt/collections/earnings'

module Yt
module Associations
# Provides the `has_many :earnings` method to YouTube resources, which
# allows to invoke earning-related methods, such as .earnings_on.
# YouTube resources with earning are: channels.
module Earnings
def earnings_on(date)
earnings_within(date, date).values.first
end

def earnings_since(from)
# NOTE: Today's earnings are not available, and hardly yesterday's
earnings_within from, 1.day.ago
end

def earnings_within(from, to)
date_range = Range.new *[from, to].map(&:to_date)
Hash[*date_range.flat_map do |date|
[date, (@earnings ||= {})[date] ||= range_earnings(date_range)[date]]
end]
end

private

def range_earnings(date_range)
(@range_earnings ||= {})[date_range] ||= earnings.within date_range
end

def earnings
Collections::Earnings.of self
end
end
end
end
42 changes: 42 additions & 0 deletions lib/yt/collections/earnings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require 'yt/collections/base'

module Yt
module Collections
class Earnings < Base

def within(days_range)
@days_range = sorted days_range
Hash[*flat_map{|daily_earning| daily_earning}]
end

private

def new_item(data)
# NOTE: could use column headers to be more precise
[Date.iso8601(data.first), data.last]
end

def list_params
super.tap do |params|
params[:path] = '/youtube/analytics/v1/reports'
params[:params] = {}.tap do |params|
params['ids'] = "contentOwner==#{@auth.id}"
params['filters'] = "channel==#{@parent.id}"
params['start-date'] = @days_range.begin
params['end-date'] = @days_range.end
params['metrics'] = :earnings
params['dimensions'] = :day
end
end
end

def items_key
'rows'
end

def sorted(range)
range.min ? range : (range.end..range.begin)
end
end
end
end
18 changes: 2 additions & 16 deletions lib/yt/models/account.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,11 @@
require 'yt/models/base'
require 'yt/models/authenticable'

module Yt
module Models
# Provides methods to access a YouTube account.
class Account < Base
has_one :authentication, delegate: [:access_token, :refresh_token, :expires_at]
class Account < Authenticable
has_one :channel, delegate: [:videos, :playlists, :create_playlist, :delete_playlists, :update_playlists]
has_one :user_info, delegate: [:id, :email, :has_verified_email?, :gender, :name, :given_name, :family_name, :profile_url, :avatar_url, :locale, :hd]

def initialize(options = {})
@access_token = options[:access_token]
@refresh_token = options[:refresh_token]
@expires_at = options[:expires_at]
@authorization_code = options[:authorization_code]
@redirect_uri = options[:redirect_uri]
@scopes = options[:scopes]
end

def auth
self
end
end
end
end
22 changes: 22 additions & 0 deletions lib/yt/models/authenticable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
require 'yt/models/base'

module Yt
module Models
class Authenticable < Base
has_one :authentication, delegate: [:access_token, :refresh_token, :expires_at]

def initialize(options = {})
@access_token = options[:access_token]
@refresh_token = options[:refresh_token]
@expires_at = options[:expires_at]
@authorization_code = options[:authorization_code]
@redirect_uri = options[:redirect_uri]
@scopes = options[:scopes]
end

def auth
self
end
end
end
end
1 change: 1 addition & 0 deletions lib/yt/models/channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Channel < Resource
has_many :subscriptions
has_many :videos
has_many :playlists
has_many :earnings # requires auth with an account with 'yt-analytics-monetary.readonly'
end
end
end
15 changes: 15 additions & 0 deletions lib/yt/models/content_owner.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'yt/models/authenticable'

module Yt
module Models
# Provides methods to access a YouTube content_owner.
class ContentOwner < Authenticable
attr_reader :id

def initialize(options = {})
@id = options[:id]
super options
end
end
end
end

0 comments on commit 090e9fc

Please sign in to comment.