@@ -67,6 +67,72 @@ def reduce_commits_by_repo(aggr, commit):
6767 def get_option (self , name , defval ):
6868 return False if self .request .get (name , defval ) == '0' else True
6969
70+ def calculate_user_values (self , username ):
71+ try :
72+ github_user = User .get (username )
73+ except pyresto .Error :
74+ self .response .set_status (404 ) # not 100% sure but good enough
75+ self .render ('errors/404' )
76+ return
77+ except Exception as err :
78+ self .response .set_status (500 )
79+ logging .error (err )
80+ return
81+
82+ languages = User .sort_languages (github_user .language_stats )
83+ fork_count = sum ((1 for repo in github_user .repos if repo .fork ))
84+
85+ today = datetime .datetime .today ()
86+ recent_than = today - datetime .timedelta (days = RECENT_DAYS )
87+ own_commits = github_user .get_latest_commits (recent_than )
88+
89+ commits_by_repo = reduce (self .reduce_commits_by_repo ,
90+ own_commits , dict ())
91+ if commits_by_repo :
92+ last_project = max (commits_by_repo , key = commits_by_repo .get )
93+ else :
94+ last_project = ''
95+ logging .info (commits_by_repo )
96+ if last_project :
97+ last_project_url = [repo .html_url for repo in github_user .repos
98+ if repo .name == last_project ][0 ]
99+ else :
100+ last_project_url = None
101+
102+ commits_by_date = reduce (self .reduce_commits_by_date ,
103+ own_commits , dict ())
104+ range = daterange (recent_than , today )
105+ for d in range :
106+ key = unicode (d .date ())
107+ if key not in commits_by_date :
108+ commits_by_date [key ] = 0
109+
110+ commit_data = [commits_by_date [d ] for d in sorted (commits_by_date )]
111+ max_commits = max (commit_data )
112+ logging .debug ('Commit data %s' , str (commit_data ))
113+ commit_sparkline = 'data:image/png;base64,' + \
114+ base64 .b64encode (
115+ sparklines .impulse (commit_data ,
116+ below_color = 'SlateGray' ,
117+ width = 3 ,
118+ dmin = 0 ,
119+ dmax = max (commit_data )
120+ ),
121+ )
122+
123+ return {'user' : github_user .__dict__ ,
124+ 'own_repos' : github_user .public_repos - fork_count ,
125+ 'fork_repos' : fork_count ,
126+ 'languages' : languages ,
127+ 'project_followers' : github_user .project_followers - \
128+ github_user .public_repos ,
129+ 'commit_sparkline' : commit_sparkline ,
130+ 'max_commits' : max_commits ,
131+ 'last_project' : last_project ,
132+ 'last_project_url' : last_project_url ,
133+ 'days' : RECENT_DAYS
134+ }
135+
70136 def get (self , username ):
71137 support = self .get_option ('s' , '0' )
72138 analytics = self .get_option ('a' , '1' )
@@ -78,72 +144,18 @@ def get(self, username):
78144 if cached_data :
79145 return self .write (cached_data )
80146 else :
81- try :
82- github_user = User .get (username )
83- except pyresto .Error :
84- self .response .set_status (404 ) # not 100% sure but good enough
85- self .render ('errors/404' )
86- return
87- except Exception as err :
88- self .response .set_status (500 )
89- logging .error (err )
90- return
147+ memcache_data_key = '!data!{}' .format (username )
148+ values = json .loads (memcache .get (memcache_data_key ) or '{}' )
149+ if not values :
150+ # Caution, the method below may alter state.
151+ values = self .calculate_user_values (username )
91152
92- languages = User .sort_languages (github_user .language_stats )
93- fork_count = sum ((1 for repo in github_user .repos if repo .fork ))
94-
95- today = datetime .datetime .today ()
96- recent_than = today - datetime .timedelta (days = RECENT_DAYS )
97- own_commits = github_user .get_latest_commits (recent_than )
153+ if not values : # still don't have the values, something went wrong
154+ return
98155
99- commits_by_repo = reduce (self .reduce_commits_by_repo ,
100- own_commits , dict ())
101- if commits_by_repo :
102- last_project = max (commits_by_repo , key = commits_by_repo .get )
103- else :
104- last_project = ''
105- logging .info (commits_by_repo )
106- if last_project :
107- last_project_url = [repo .html_url for repo in github_user .repos
108- if repo .name == last_project ][0 ]
109- else :
110- last_project_url = None
111-
112- commits_by_date = reduce (self .reduce_commits_by_date ,
113- own_commits , dict ())
114- range = daterange (recent_than , today )
115- for d in range :
116- key = unicode (d .date ())
117- if key not in commits_by_date :
118- commits_by_date [key ] = 0
119-
120- commit_data = [commits_by_date [d ] for d in sorted (commits_by_date )]
121- max_commits = max (commit_data )
122- logging .debug ('Commit data %s' , str (commit_data ))
123- commit_sparkline = 'data:image/png;base64,' + \
124- base64 .b64encode (
125- sparklines .impulse (commit_data ,
126- below_color = 'SlateGray' ,
127- width = 3 ,
128- dmin = 0 ,
129- dmax = max (commit_data )
130- ),
131- )
132-
133- values = {'user' : github_user .__dict__ ,
134- 'own_repos' : github_user .public_repos - fork_count ,
135- 'fork_repos' : fork_count ,
136- 'languages' : languages ,
137- 'project_followers' : github_user .project_followers - \
138- github_user .public_repos ,
139- 'commit_sparkline' : commit_sparkline ,
140- 'max_commits' : max_commits ,
141- 'last_project' : last_project ,
142- 'last_project_url' : last_project_url ,
143- 'support' : support ,
144- 'analytics' : analytics ,
145- 'days' : RECENT_DAYS
146- }
156+ if not memcache .set (memcache_data_key ,
157+ json .dumps (values ), MEMCACHE_EXPIRATION ):
158+ logging .error ('Memcache set failed for user data %s' , username )
147159
148160 if jsonp :
149161 values = {'jsonp' : jsonp , 'data' : json .dumps (values )}
@@ -152,6 +164,7 @@ def get(self, username):
152164 charset = 'utf-8' )
153165 output = self .render ('jsonp' , values , '.js' , False )
154166 else :
167+ values .update ({'support' : support , 'analytics' : analytics })
155168 output = self .render ('badge' , values )
156169
157170 if not memcache .set (memcache_key , output , MEMCACHE_EXPIRATION ):
0 commit comments