diff --git a/endpoints/api/repository.py b/endpoints/api/repository.py index f1da2838d..8878c9f84 100644 --- a/endpoints/api/repository.py +++ b/endpoints/api/repository.py @@ -13,7 +13,8 @@ from data.database import Repository as RepositoryTable from endpoints.api import (truthy_bool, format_date, nickname, log_action, validate_json_request, require_repo_read, require_repo_write, require_repo_admin, RepositoryParamResource, resource, query_param, parse_args, ApiResource, - request_error, require_scope, path_param, page_support) + request_error, require_scope, path_param, page_support, parse_args, + query_param, truthy_bool) from endpoints.exception import Unauthorized, NotFound, InvalidRequest, ExceedsLicenseException from endpoints.api.billing import lookup_allowed_private_repos, get_namespace_plan from endpoints.api.subscribe import check_repository_usage @@ -234,9 +235,12 @@ class Repository(RepositoryParamResource): } } + @parse_args() + @query_param('includeStats', 'Whether to include pull and push statistics', type=truthy_bool, + default=False) @require_repo_read @nickname('getRepo') - def get(self, namespace, repository): + def get(self, namespace, repository, parsed_args): """Fetch the specified repository.""" logger.debug('Get repo: %s/%s' % (namespace, repository)) @@ -254,6 +258,7 @@ class Repository(RepositoryParamResource): return tag_info repo = model.repository.get_repository(namespace, repository) + stats = None if repo: tags = model.tag.list_repository_tags(namespace, repository, include_storage=True) tag_dict = {tag.name: tag_view(tag) for tag in tags} @@ -264,13 +269,25 @@ class Repository(RepositoryParamResource): if get_authenticated_user() else False) is_public = model.repository.is_repository_public(repo) - (pull_today, pull_thirty_day) = model.log.get_repository_pulls(repo, timedelta(days=1), - timedelta(days=30)) + if parsed_args['includeStats']: + (pull_today, pull_thirty_day) = model.log.get_repository_pulls(repo, timedelta(days=1), + timedelta(days=30)) - (push_today, push_thirty_day) = model.log.get_repository_pushes(repo, timedelta(days=1), - timedelta(days=30)) + (push_today, push_thirty_day) = model.log.get_repository_pushes(repo, timedelta(days=1), + timedelta(days=30)) - return { + stats = { + 'pulls': { + 'today': pull_today, + 'thirty_day': pull_thirty_day + }, + 'pushes': { + 'today': push_today, + 'thirty_day': push_thirty_day + } + } + + repo_data = { 'namespace': namespace, 'name': repository, 'description': repo.description, @@ -281,18 +298,13 @@ class Repository(RepositoryParamResource): 'is_organization': repo.namespace_user.organization, 'is_starred': is_starred, 'status_token': repo.badge_token if not is_public else '', - 'stats': { - 'pulls': { - 'today': pull_today, - 'thirty_day': pull_thirty_day - }, - 'pushes': { - 'today': push_today, - 'thirty_day': push_thirty_day - } - } } + if stats is not None: + repo_data['stats'] = stats + + return repo_data + raise NotFound() @require_repo_write diff --git a/static/js/pages/repo-view.js b/static/js/pages/repo-view.js index e7088d399..f6056a019 100644 --- a/static/js/pages/repo-view.js +++ b/static/js/pages/repo-view.js @@ -53,7 +53,8 @@ $scope.viewScope.images = null; var params = { - 'repository': $scope.namespace + '/' + $scope.name + 'repository': $scope.namespace + '/' + $scope.name, + 'includeStats': true }; $scope.repositoryResource = ApiService.getRepoAsResource(params).get(function(repo) { diff --git a/test/test_api_usage.py b/test/test_api_usage.py index c7eaf9d6d..6d75bfaa4 100644 --- a/test/test_api_usage.py +++ b/test/test_api_usage.py @@ -1513,7 +1513,12 @@ class TestListRepos(ApiTestCase): class TestViewPublicRepository(ApiTestCase): def test_normalview(self): - self.getJsonResponse(Repository, params=dict(repository='public/publicrepo')) + resp = self.getJsonResponse(Repository, params=dict(repository='public/publicrepo')) + self.assertFalse('stats' in resp) + + def test_normalview_withstats(self): + resp = self.getJsonResponse(Repository, params=dict(repository='public/publicrepo', includeStats=True)) + self.assertTrue('stats' in resp) def test_anon_access_disabled(self): import features