diff options
Diffstat (limited to '')
| -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}) | 
