Traffic Endpoints Support (#977)

Added support for the traffic endpoints found at https://developer.github.com/v3/repos/traffic/.

We added four functions to the Repository class (one for each of the endpoints) with corresponding unit tests. 

Fixes #926
This commit is contained in:
Justin Kufro
2018-12-05 09:54:31 +08:00
committed by Wan Liuyang
parent aca50a7581
commit a433a2fe3d
14 changed files with 646 additions and 5 deletions
+1
View File
@@ -89,6 +89,7 @@ from SourceImport import *
from Status import *
from Tag import *
from Team import *
from Traffic import *
from UserKey import *
from PaginatedList import *
@@ -19,4 +19,3 @@ None
200
[('status', '200 OK'), ('x-ratelimit-remaining', '4911'), ('content-length', '1129'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"1a93ec821b0bd7094340a9fc34017aa0"'), ('date', 'Sun, 27 May 2012 07:17:09 GMT'), ('content-type', 'application/json; charset=utf-8')]
{"clone_url":"https://github.com/jacquev6/PyGithub.git","has_downloads":true,"watchers":15,"git_url":"git://github.com/jacquev6/PyGithub.git","updated_at":"2012-05-27T06:55:28Z","permissions":{"pull":true,"admin":true,"push":true},"homepage":"http://vincent-jacques.net/PyGithub","url":"https://api.github.com/repos/jacquev6/PyGithub","mirror_url":null,"has_wiki":false,"has_issues":true,"fork":false,"forks":3,"size":308,"private":false,"open_issues":16,"svn_url":"https://github.com/jacquev6/PyGithub","owner":{"url":"https://api.github.com/users/jacquev6","avatar_url":"https://secure.gravatar.com/avatar/b68de5ae38616c296fa345d2b9df2225?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png","gravatar_id":"b68de5ae38616c296fa345d2b9df2225","login":"jacquev6","id":327146},"name":"PyGithub","language":"Python","description":"Python library implementing the full Github API v3","ssh_url":"git@github.com:jacquev6/PyGithub.git","pushed_at":"2012-05-27T06:00:28Z","created_at":"2012-02-25T12:53:47Z","id":3544490,"html_url":"https://github.com/jacquev6/PyGithub","full_name":"jacquev6/PyGithub"}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/repos/jkufro/PyGithub/traffic/clones
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Sun, 02 Dec 2018 17:25:20 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4988'), ('X-RateLimit-Reset', '1543775101'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"99f62fd904c91505ef4f1f8b89d22c08"'), ('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'), ('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'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'F408:56B2:D8A13F:1E6EC1B:5C041580')]
{"count":4,"uniques":4,"clones":[{"timestamp":"2018-11-27T00:00:00Z","count":4,"uniques":4}]}
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/repos/jkufro/PyGithub/traffic/popular/paths
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Sun, 02 Dec 2018 18:37:44 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', '1543779296'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"b886e79ff0cee5a1b67a5efa00b3ca0f"'), ('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'), ('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'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'F7B9:56B2:DB4511:1ECCC1B:5C042678')]
[{"path":"/jkufro/PyGithub","title":"jkufro/PyGithub: Typed interactions with the GitHub API v3","count":23,"uniques":4},{"path":"/jkufro/PyGithub/tree/traffic_endpoints","title":"jkufro/PyGithub at traffic_endpoints","count":13,"uniques":4},{"path":"/jkufro/PyGithub/blob/master/github/Repository.py","title":"PyGithub/Repository.py at master jkufro/PyGithub","count":6,"uniques":3},{"path":"/jkufro/PyGithub/branches","title":"Branches jkufro/PyGithub","count":6,"uniques":1},{"path":"/jkufro/PyGithub/commits/traffic_endpoints","title":"Commits jkufro/PyGithub","count":4,"uniques":2},{"path":"/jkufro/PyGithub/tree/traffic_endpoints/github","title":"PyGithub/github at traffic_endpoints jkufro/PyGithub","count":4,"uniques":2},{"path":"/jkufro/PyGithub/commit/f309070d99a58336a577bf7c88c49773fe3f16a2","title":"better pep8 compliance and delted unused Traffic.py file jkufro/PyGithub@f3...","count":3,"uniques":2},{"path":"/jkufro/PyGithub/commits","title":"Commits jkufro/PyGithub","count":3,"uniques":1},{"path":"/jkufro/PyGithub/commit/1fd7e391735715ad7f752e230a45eba891927e64","title":"made placeholder classes jkufro/PyGithub@1fd7e39","count":2,"uniques":1},{"path":"/jkufro/PyGithub/commit/5296fb83e0a8ab3fdcbc1b7a3a28beae4f8f38bb","title":"clone and view class jkufro/PyGithub@5296fb8","count":2,"uniques":1}]
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/repos/jkufro/PyGithub/traffic/popular/referrers
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Sun, 02 Dec 2018 17:25:02 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4997'), ('X-RateLimit-Reset', '1543775101'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"033913cf8de0341149e2639c12d7a240"'), ('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'), ('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'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'F3F4:56B2:D89E29:1E6E41C:5C04156D')]
[{"referrer":"github.com","count":5,"uniques":1}]
@@ -0,0 +1,11 @@
https
GET
api.github.com
None
/repos/jkufro/PyGithub/traffic/views
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
None
200
[('Server', 'GitHub.com'), ('Date', 'Sun, 02 Dec 2018 17:25:15 GMT'), ('Content-Type', 'application/json; charset=utf-8'), ('Transfer-Encoding', 'chunked'), ('Status', '200 OK'), ('X-RateLimit-Limit', '5000'), ('X-RateLimit-Remaining', '4991'), ('X-RateLimit-Reset', '1543775101'), ('Cache-Control', 'private, max-age=60, s-maxage=60'), ('Vary', 'Accept, Authorization, Cookie, X-GitHub-OTP'), ('ETag', 'W/"47961c20927a4d019bc73ee47bd8fe79"'), ('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'), ('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'"), ('Content-Encoding', 'gzip'), ('X-GitHub-Request-Id', 'F402:56B3:75FF23:12D1E43:5C04157B')]
{"count":93,"uniques":4,"views":[{"timestamp":"2018-11-27T00:00:00Z","count":56,"uniques":4},{"timestamp":"2018-11-28T00:00:00Z","count":6,"uniques":2},{"timestamp":"2018-11-30T00:00:00Z","count":18,"uniques":1},{"timestamp":"2018-12-01T00:00:00Z","count":4,"uniques":1},{"timestamp":"2018-12-02T00:00:00Z","count":9,"uniques":3}]}
+73
View File
@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
############################ Copyrights and license ############################
# #
# Copyright 2018 Justin Kufro <jkufro@andrew.cmu.edu> #
# Copyright 2018 Ivan Minno <iminno@andrew.cmu.edu> #
# Copyright 2018 Zilei Gu <zileig@andrew.cmu.edu> #
# Copyright 2018 Yves Zumbach <yzumbach@andrew.cmu.edu> #
# Copyright 2018 Leying Chen <leyingc@andrew.cmu.edu> #
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
# #
# PyGithub is free software: you can redistribute it and/or modify it under #
# the terms of the GNU Lesser General Public License as published by the Free #
# Software Foundation, either version 3 of the License, or (at your option) #
# any later version. #
# #
# PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY #
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more #
# details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
import Framework
import github
import datetime
class Traffic(Framework.TestCase):
def setUp(self):
Framework.TestCase.setUp(self)
self.user = self.g.get_user()
self.repo = self.user.get_repo("PyGithub")
def testGetReferrers(self):
referrerResponse = self.repo.get_top_referrers()
self.assertGreaterEqual(len(referrerResponse), 1)
self.assertEqual(referrerResponse[0].uniques, 1)
self.assertEqual(referrerResponse[0].referrer, "github.com")
self.assertEqual(referrerResponse[0].count, 5)
def testGetPaths(self):
pathsResponse = self.repo.get_top_paths()
self.assertEqual(len(pathsResponse), 10)
self.assertEqual(pathsResponse[0].uniques, 4)
self.assertEqual(pathsResponse[0].count, 23)
self.assertEqual(pathsResponse[0].path, "/jkufro/PyGithub")
self.assertEqual(pathsResponse[0].title, "jkufro/PyGithub: Typed interactions with the GitHub API v3")
def testGetViews(self):
viewsResponse = self.repo.get_views_traffic()
self.assertEqual(viewsResponse["count"], 93)
self.assertEqual(viewsResponse["uniques"], 4)
self.assertEqual(len(viewsResponse["views"]), 5)
view_obj = viewsResponse["views"][0]
self.assertEqual(view_obj.uniques, 4)
self.assertEqual(view_obj.timestamp, datetime.datetime(2018, 11, 27, 0, 0))
self.assertEqual(view_obj.count, 56)
def testGetClones(self):
clonesResponse = self.repo.get_clones_traffic()
self.assertEqual(clonesResponse["count"], 4)
self.assertEqual(clonesResponse["uniques"], 4)
self.assertEqual(len(clonesResponse["clones"]), 1)
clone_obj = clonesResponse["clones"][0]
self.assertEqual(clone_obj.uniques, 4)
self.assertEqual(clone_obj.timestamp, datetime.datetime(2018, 11, 27, 0, 0))
self.assertEqual(clone_obj.count, 4)