Skip to content

Commit

Permalink
Merge pull request #1233 from octokit/stats
Browse files Browse the repository at this point in the history
Generate stats client
  • Loading branch information
Heather Harvey authored Apr 7, 2020
2 parents 6d16db1 + dc269c3 commit 791aec6
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 189 deletions.
110 changes: 29 additions & 81 deletions lib/octokit/client/stats.rb
Original file line number Diff line number Diff line change
@@ -1,106 +1,54 @@
# frozen_string_literal: true

module Octokit
class Client

# Methods for the Repository Statistics API
# Methods for the Stats API
#
# @see https://developer.github.com/v3/repos/statistics/
module Stats
# Get the weekly commit count for the repository owner and everyone else
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @return [Sawyer::Resource] A single stats
# @see https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repository-owner-and-everyone-else
def participation_stats(repo, options = {})
get "#{Repository.path repo}/stats/participation", options
end

# Get contributors list with additions, deletions, and commit counts
# Get the number of additions and deletions per week
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
# @option retry_wait [Number] How long Octokit should wait between retries.
# @return [Array<Sawyer::Resource>] Array of contributor stats
# @see https://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts
# @example Get contributor stats for octokit
# @client.contributors_stats('octokit/octokit.rb')
def contributors_stats(repo, options = {})
get_stats(repo, "contributors", options)
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @return [Array<Sawyer::Resource>] A list of stats
# @see https://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week
def code_frequency_stats(repo, options = {})
get "#{Repository.path repo}/stats/code_frequency", options
end
alias :contributor_stats :contributors_stats

# Get the last year of commit activity data
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
# @option retry_wait [Number] How long Octokit should wait between retries.
# @return [Array<Sawyer::Resource>] The last year of commit activity grouped by
# week. The days array is a group of commits per day, starting on Sunday.
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @return [Array<Sawyer::Resource>] A list of stats
# @see https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data
# @example Get commit activity for octokit
# @client.commit_activity_stats('octokit/octokit.rb')
def commit_activity_stats(repo, options = {})
get_stats(repo, "commit_activity", options)
get "#{Repository.path repo}/stats/commit_activity", options
end

# Get the number of additions and deletions per week
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
# @option retry_wait [Number] How long Octokit should wait between retries.
# @return [Array<Sawyer::Resource>] Weekly aggregate of the number of additions
# and deletions pushed to a repository.
# @see https://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week
# @example Get code frequency stats for octokit
# @client.code_frequency_stats('octokit/octokit.rb')
def code_frequency_stats(repo, options = {})
get_stats(repo, "code_frequency", options)
end

# Get the weekly commit count for the repo owner and everyone else
# Get contributors list with additions, deletions, and commit counts
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
# @option retry_wait [Number] How long Octokit should wait between retries.
# @return [Sawyer::Resource] Total commit counts for the owner and total commit
# counts in all. all is everyone combined, including the owner in the last
# 52 weeks. If you’d like to get the commit counts for non-owners, you can
# subtract all from owner.
# @see https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repository-owner-and-everyone-else
# @example Get weekly commit counts for octokit
# @client.participation_stats("octokit/octokit.rb")
def participation_stats(repo, options = {})
get_stats(repo, "participation", options)
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @return [Array<Sawyer::Resource>] A list of stats
# @see https://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts
def contributors_stats(repo, options = {})
get "#{Repository.path repo}/stats/contributors", options
end

# Get the number of commits per hour in each day
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository
# @option retry_timeout [Number] How long Octokit should keep trying to get stats (in seconds)
# @option retry_wait [Number] How long Octokit should wait between retries.
# @return [Array<Array>] Arrays containing the day number, hour number, and
# number of commits
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @return [Array<Sawyer::Resource>] A list of stats
# @see https://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day
# @example Get octokit punch card
# @octokit.punch_card_stats
def punch_card_stats(repo, options = {})
get_stats(repo, "punch_card", options)
end
alias :punch_card :punch_card_stats

private

# @private Get stats for a repository
#
# @param repo [Integer, String, Hash, Repository] A GitHub repository
# @param metric [String] The metrics you are looking for
# @return [Array<Sawyer::Resource> or nil] Stats in metric-specific format, or nil if not yet calculated.
# @see https://developer.github.com/v3/repos/statistics/
def get_stats(repo, metric, options = {})
options = options.dup
if retry_timeout = options.delete(:retry_timeout)
retry_wait = options.delete(:retry_wait) || 0.5
timeout = Time.now + retry_timeout
end
loop do
data = get("#{Repository.path repo}/stats/#{metric}", options)
return data if last_response.status == 200
return [] if last_response.status == 204
return nil unless retry_timeout
return nil if Time.now >= timeout
sleep retry_wait if retry_wait
end
get "#{Repository.path repo}/stats/punch_card", options
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/openapi_client_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def self.at(definition, parameterizer: OpenAPIClientGenerator::Endpoint::Positio
def self.resource_for_path(path)
path_segments = path.split("/").reject{ |segment| segment == "" }

supported_resources = %w(deployments pages hooks releases labels milestones issues reactions projects gists events checks contents downloads readme notifications pulls)
supported_resources = %w(deployments pages hooks releases labels milestones issues reactions projects gists events checks contents downloads readme notifications pulls stats)
resource = case path_segments.first
when "orgs", "users"
path_segments[2]
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/repos/pengwynn/pingwynn/stats/code_frequency","body":{"encoding":"UTF-8","string":""},"headers":{"Accept":["application/vnd.github.v3+json"],"User-Agent":["Octokit Ruby Gem 3.0.0.pre"],"Authorization":["token <<ACCESS_TOKEN>>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Server":["GitHub.com"],"Date":["Tue, 14 Jan 2014 22:34:48 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Status":["200 OK"],"X-Ratelimit-Limit":["5000"],"X-Ratelimit-Remaining":["4994"],"X-Ratelimit-Reset":["1389742411"],"Cache-Control":["private, max-age=60, s-maxage=60"],"Etag":["\"ec128e3cf4182ffb3d7ed73db513086b\""],"X-Oauth-Scopes":["user, public_repo, repo, gist"],"X-Accepted-Oauth-Scopes":["repo, repo:status, repo:deployment, public_repo, delete_repo, user, user:email, user:follow, admin:org, write:org, read:org, gist, site_admin, user:assets, user:assets:read"],"Vary":["Accept, Authorization, Cookie, X-GitHub-OTP","Accept-Encoding"],"X-Github-Media-Type":["github.v3; format=json"],"X-Content-Type-Options":["nosniff"],"Access-Control-Allow-Credentials":["true"],"Access-Control-Expose-Headers":["ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval"],"Access-Control-Allow-Origin":["*"],"X-Github-Request-Id":["443FDC73:0368:3CAE69E:52D5BB87"]},"body":{"encoding":"UTF-8","string":"[[1376179200,25,-5],[1376784000,32,0],[1377388800,0,0],[1377993600,0,0],[1378598400,0,0],[1379203200,0,0],[1379808000,0,0],[1380412800,2,-1],[1381017600,0,0],[1381622400,0,0],[1382227200,0,0],[1382832000,0,0],[1383436800,5,-4],[1384041600,0,0],[1384646400,0,0],[1385251200,0,0],[1385856000,7,-6],[1386460800,0,0],[1387065600,0,0],[1387670400,4,-2],[1388275200,0,0],[1388880000,0,0],[1389484800,0,0]]"},"http_version":null},"recorded_at":"Tue, 14 Jan 2014 22:34:47 GMT"}],"recorded_with":"VCR 2.4.0"}
{"http_interactions":[{"request":{"method":"get","uri":"https://api.github.com/repos/<GITHUB_LOGIN>/<GITHUB_TEST_REPOSITORY>/stats/code_frequency","body":{"encoding":"US-ASCII","base64_string":""},"headers":{"Accept":["application/vnd.github.v3+json"],"User-Agent":["Octokit Ruby Gem 4.15.0"],"Content-Type":["application/json"],"Authorization":["token <<ACCESS_TOKEN>>"],"Accept-Encoding":["gzip;q=1.0,deflate;q=0.6,identity;q=0.3"]}},"response":{"status":{"code":200,"message":"OK"},"headers":{"Date":["Mon, 06 Apr 2020 17:53:50 GMT"],"Content-Type":["application/json; charset=utf-8"],"Transfer-Encoding":["chunked"],"Server":["GitHub.com"],"Status":["200 OK"],"X-Ratelimit-Limit":["5000"],"X-Ratelimit-Remaining":["4891"],"X-Ratelimit-Reset":["1586198128"],"Cache-Control":["private, max-age=60, s-maxage=60"],"Vary":["Accept, Authorization, Cookie, X-GitHub-OTP","Accept-Encoding, Accept, X-Requested-With"],"Etag":["W/\"f32328b366517e28ebc6cfdbf5d80513\""],"X-Oauth-Scopes":["admin:enterprise, admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, read:packages, repo, user, write:discussion, write:packages"],"X-Accepted-Oauth-Scopes":[""],"X-Github-Media-Type":["github.v3; format=json"],"Access-Control-Expose-Headers":["ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, Deprecation, Sunset"],"Access-Control-Allow-Origin":["*"],"Strict-Transport-Security":["max-age=31536000; includeSubdomains; preload"],"X-Frame-Options":["deny"],"X-Content-Type-Options":["nosniff"],"X-Xss-Protection":["1; mode=block"],"Referrer-Policy":["origin-when-cross-origin, strict-origin-when-cross-origin"],"Content-Security-Policy":["default-src 'none'"],"X-Github-Request-Id":["C911:1703:6DDD0:824E8:5E8B6CAE"]},"body":{"encoding":"ASCII-8BIT","base64_string":"W1sxNTc3NTc3NjAwLDEsMF0sWzE1NzgxODI0MDAsMCwwXSxbMTU3ODc4NzIw\nMCwwLDBdLFsxNTc5MzkyMDAwLDAsMF0sWzE1Nzk5OTY4MDAsMCwwXSxbMTU4\nMDYwMTYwMCwzLC0zXSxbMTU4MTIwNjQwMCwwLDBdLFsxNTgxODExMjAwLDAs\nMF0sWzE1ODI0MTYwMDAsMCwwXSxbMTU4MzAyMDgwMCw2NjgsLTY2OF0sWzE1\nODM2MjU2MDAsMCwwXSxbMTU4NDIzMDQwMCwzMzcsLTMzN10sWzE1ODQ4MzUy\nMDAsMTIsLTEyXSxbMTU4NTQ0MDAwMCwwLDBdLFsxNTg2MDQ0ODAwLDAsMF1d\n"},"http_version":null},"recorded_at":"Mon, 06 Apr 2020 17:53:38 GMT"}],"recorded_with":"VCR 5.1.0"}
Loading

0 comments on commit 791aec6

Please sign in to comment.