diff options
-rw-r--r-- | Pipfile | 4 | ||||
-rw-r--r-- | docker-compose.yml | 4 | ||||
-rw-r--r-- | docker/pysite.dockerapp | 2 | ||||
-rw-r--r-- | pydis_site/apps/main/models/__init__.py | 3 | ||||
-rw-r--r-- | pydis_site/apps/main/models/repo_data.py | 33 | ||||
-rw-r--r-- | pydis_site/apps/main/views/home.py | 94 |
6 files changed, 103 insertions, 37 deletions
@@ -30,3 +30,7 @@ requests = "*" [requires] python_version = "3.7" + +[scripts] +makemigrations = "python manage.py makemigrations" +django_shell = "python manage.py shell" diff --git a/docker-compose.yml b/docker-compose.yml index 04ec51de..0c504c40 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,6 +12,8 @@ version: "3.6" services: postgres: image: postgres:11-alpine + ports: + - "127.0.0.1:7777:5432" environment: POSTGRES_DB: pysite POSTGRES_PASSWORD: supersecretpassword @@ -30,7 +32,7 @@ services: - .:/app:ro - staticfiles:/var/www/static environment: - DATABASE_URL: postgres://pysite:supersecretpassword@postgres/pysite + DATABASE_URL: postgres://pysite:supersecretpassword@postgres:5432/pysite DEBUG: "true" SECRET_KEY: suitable-for-development-only STATIC_ROOT: /var/www/static diff --git a/docker/pysite.dockerapp b/docker/pysite.dockerapp index dc472b2e..2426008e 100644 --- a/docker/pysite.dockerapp +++ b/docker/pysite.dockerapp @@ -25,6 +25,8 @@ services: postgres: image: postgres:11-alpine + ports: + - "127.0.0.1:5432:5432" environment: POSTGRES_DB: "${pg_db}" POSTGRES_USER: "${pg_user}" diff --git a/pydis_site/apps/main/models/__init__.py b/pydis_site/apps/main/models/__init__.py new file mode 100644 index 00000000..7a2cbb0b --- /dev/null +++ b/pydis_site/apps/main/models/__init__.py @@ -0,0 +1,3 @@ +from .repo_data import RepoData + +__all__ = ["RepoData"] diff --git a/pydis_site/apps/main/models/repo_data.py b/pydis_site/apps/main/models/repo_data.py new file mode 100644 index 00000000..40540410 --- /dev/null +++ b/pydis_site/apps/main/models/repo_data.py @@ -0,0 +1,33 @@ +from django.db import models +from django.utils import timezone + + +class RepoData(models.Model): + """Information about one of our repos fetched from the GitHub API.""" + + last_updated = models.DateTimeField( + default=timezone.now, + help_text="The date and time this data was last fetched." + ) + repo_name = models.CharField( + primary_key=True, + max_length=40, + help_text="The full name of the repo, e.g. python-discord/site" + ) + description = models.CharField( + max_length=400, + help_text="The description of the repo." + ) + forks = models.IntegerField( + help_text="The number of forks of this repo" + ) + stargazers = models.IntegerField( + help_text="The number of stargazers for this repo" + ) + language = models.CharField( + max_length=20, + help_text="The primary programming language used for this repo." + ) + + def __str__(self): + return self.repo_name diff --git a/pydis_site/apps/main/views/home.py b/pydis_site/apps/main/views/home.py index 8f45b912..883177bb 100644 --- a/pydis_site/apps/main/views/home.py +++ b/pydis_site/apps/main/views/home.py @@ -1,47 +1,69 @@ import requests + from django.shortcuts import render +from django.utils import timezone from django.views import View +from pydis_site.apps.main.models import RepoData +GITHUB_API = "https://api.github.com/repos" +REPOS = [ + "python-discord/site", + "python-discord/bot", + "python-discord/snekbox", + "python-discord/seasonalbot", + "python-discord/django-simple-bulma", + "python-discord/django-crispy-bulma", +] - -class Home(View): - - projects = [ - "site", - "bot", - "snekbox", - "seasonalbot", - "django-simple-bulma", - "django-crispy-bulma", - ] - - def _get_repo_data(self): - """ - This will get language, stars and forks for the projects listed in Home.projects. - - Returns a dictionary with the data, in a template-friendly manner. The rate limit for - this particular endpoint is 30 requests per minute. This should be plenty for now, - but if we ever run into rate limiting issues, we should implement some form of caching - for this data. - """ - - # Gotta authenticate, or we get terrible rate limits. - - # We need to query the Search API https://developer.github.com/v3/search/, using a single - # query to query for all of the projects at the same time, and making sure we cache that data - # and make the request no more often than once per minute or something reasonable - # like that. - - endpoint = "https://api.github.com/search/repositories?q=" + "repo+name+separated+by+pluses" - - # And finally - - - +# https://api.github.com/users/python-discord/repos gets all the data in one query. +class Home(View): + def _get_repo_data(self, repo_name): + """This will get language, stars and forks for the requested GitHub repo.""" + + # Try to get the data from the cache + try: + repo_data = RepoData.objects.get(repo_name=repo_name) + + # If the data is older than 2 minutes, we should refresh it + if (timezone.now() - repo_data.last_updated).seconds > 120: + + # Fetch the data from the GitHub API + api_data = requests.get(f"{GITHUB_API}/{repo_name}") + api_data = api_data.json() + + # Update the current object, and save it. + repo_data.description = api_data["description"] + repo_data.language = api_data["language"] + repo_data.forks = api_data["forks_count"] + repo_data.stargazers = api_data["stargazers_count"] + repo_data.save() + return repo_data + + # Otherwise, if the data is fresher than 2 minutes old, we should just return it. + else: + return repo_data + + # If this is raised, the data isn't there at all, so we'll need to create it. + except RepoData.DoesNotExist: + api_data = requests.get(f"{GITHUB_API}/{repo_name}") + api_data = api_data.json() + repo_data = RepoData( + description=api_data["description"], + forks=api_data["forks_count"], + stargazers=api_data["stargazers_count"], + language=api_data["language"], + ) + repo_data.save() + return repo_data def get(self, request): + # Collect the repo data + repo_data = [] + for repo in REPOS: + repo_data.append(self._get_repo_data(repo)) + # Call the GitHub API and ask it for some data - return render(request, "home/index.html", {}) + return render(request, "home/index.html", {"repo_data": repo_data}) |