@@ -19,7 +19,6 @@ class HomeView(View):
19
19
20
20
github_api = "https://api.github.com/users/python-discord/repos?per_page=100"
21
21
repository_cache_ttl = 3600
22
- headers = {"Authorization" : f"token { GITHUB_TOKEN } " }
23
22
24
23
# Which of our GitHub repos should be displayed on the front page, and in which order?
25
24
repos = [
@@ -35,6 +34,16 @@ def __init__(self):
35
34
"""Clean up stale RepositoryMetadata."""
36
35
RepositoryMetadata .objects .exclude (repo_name__in = self .repos ).delete ()
37
36
37
+ # If no token is defined (for example in local development), then
38
+ # it does not make sense to pass the Authorization header. More
39
+ # specifically, GitHub will reject any requests from us due to the
40
+ # invalid header. We can make a limited number of anonymous requests
41
+ # though, which is useful for testing.
42
+ if GITHUB_TOKEN :
43
+ self .headers = {"Authorization" : f"token { GITHUB_TOKEN } " }
44
+ else :
45
+ self .headers = {}
46
+
38
47
def _get_api_data (self ) -> Dict [str , Dict [str , str ]]:
39
48
"""
40
49
Call the GitHub API and get information about our repos.
@@ -74,58 +83,52 @@ def _get_api_data(self) -> Dict[str, Dict[str, str]]:
74
83
75
84
def _get_repo_data (self ) -> List [RepositoryMetadata ]:
76
85
"""Build a list of RepositoryMetadata objects that we can use to populate the front page."""
77
- database_repositories = []
78
-
79
- # First, let's see if we have any metadata cached.
80
- cached_data = RepositoryMetadata .objects .all ()
86
+ # First off, load the timestamp of the least recently updated entry.
87
+ last_update = (
88
+ RepositoryMetadata .objects .values_list ("last_updated" , flat = True )
89
+ .order_by ("last_updated" ).first ()
90
+ )
81
91
82
- # If we don't , we have to create some !
83
- if not cached_data :
92
+ # If we did not retrieve any results here , we should import them !
93
+ if last_update is None :
84
94
85
95
# Try to get new data from the API. If it fails, we'll return an empty list.
86
96
# In this case, we simply don't display our projects on the site.
87
97
api_repositories = self ._get_api_data ()
88
98
89
99
# Create all the repodata records in the database.
90
- for api_data in api_repositories . values ():
91
- repo_data = RepositoryMetadata (
100
+ return RepositoryMetadata . objects . bulk_create (
101
+ RepositoryMetadata (
92
102
repo_name = api_data ["full_name" ],
93
103
description = api_data ["description" ],
94
104
forks = api_data ["forks_count" ],
95
105
stargazers = api_data ["stargazers_count" ],
96
106
language = api_data ["language" ],
97
107
)
98
-
99
- repo_data .save ()
100
- database_repositories .append (repo_data )
101
-
102
- return database_repositories
108
+ for api_data in api_repositories .values ()
109
+ )
103
110
104
111
# If the data is stale, we should refresh it.
105
- if (timezone .now () - cached_data [ 0 ]. last_updated ).seconds > self .repository_cache_ttl :
112
+ if (timezone .now () - last_update ).seconds > self .repository_cache_ttl :
106
113
# Try to get new data from the API. If it fails, return the cached data.
107
114
api_repositories = self ._get_api_data ()
108
115
109
116
if not api_repositories :
110
117
return RepositoryMetadata .objects .all ()
111
118
112
119
# Update or create all RepoData objects in self.repos
113
- for repo_name , api_data in api_repositories .items ():
114
- try :
115
- repo_data = RepositoryMetadata .objects .get (repo_name = repo_name )
116
- repo_data .description = api_data ["description" ]
117
- repo_data .language = api_data ["language" ]
118
- repo_data .forks = api_data ["forks_count" ]
119
- repo_data .stargazers = api_data ["stargazers_count" ]
120
- except RepositoryMetadata .DoesNotExist :
121
- repo_data = RepositoryMetadata (
122
- repo_name = api_data ["full_name" ],
123
- description = api_data ["description" ],
124
- forks = api_data ["forks_count" ],
125
- stargazers = api_data ["stargazers_count" ],
126
- language = api_data ["language" ],
127
- )
128
- repo_data .save ()
120
+ database_repositories = []
121
+ for api_data in api_repositories .values ():
122
+ repo_data , _created = RepositoryMetadata .objects .update_or_create (
123
+ repo_name = api_data ["full_name" ],
124
+ defaults = {
125
+ 'repo_name' : api_data ["full_name" ],
126
+ 'description' : api_data ["description" ],
127
+ 'forks' : api_data ["forks_count" ],
128
+ 'stargazers' : api_data ["stargazers_count" ],
129
+ 'language' : api_data ["language" ],
130
+ }
131
+ )
129
132
database_repositories .append (repo_data )
130
133
return database_repositories
131
134
0 commit comments