Compare commits
	
		
			46 commits
		
	
	
		
			master
			...
			feature/ui
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 0dd428a43d | |||
| 35cb9ab6b2 | |||
| 386c618981 | |||
| ebd371b43f | |||
| dab1b69fb7 | |||
| 9c44419146 | |||
| f306488b01 | |||
| 934ea0a905 | |||
| d0386b475a | |||
| e2aa534e76 | |||
|   | 3c57ff9910 | ||
| 8cd4940215 | |||
|   | 0dbc4c21e0 | ||
|   | 9e1a68aac5 | ||
| dac7766ee7 | |||
|   | 0ab9f790fe | ||
|   | 4bb36f6129 | ||
| 6d9f67d3bf | |||
|   | b456362a47 | ||
| d3a949833d | |||
|   | 8b988be06e | ||
| 6969af178c | |||
| c389dc5581 | |||
| c0bac128d7 | |||
| e34a4aa15d | |||
| 72e2ae9290 | |||
| cc84293480 | |||
| 0314a0f71e | |||
| 6bb4000d30 | |||
| 57ea318fcf | |||
| 8e2decc27e | |||
| 56587aa345 | |||
| e044dbf19a | |||
| 2184fab678 | |||
| 068403f81f | |||
| 2da6b7395c | |||
| 529c932e33 | |||
| fdb900a8a3 | |||
| d2fc4ca84b | |||
| 5435ed5789 | |||
| 99f37ede03 | |||
| 127ae209b1 | |||
| 1fb1bec70e | |||
| 41718d128a | |||
| 2d81fb0143 | |||
| f4218775ae | 
					 14 changed files with 7324 additions and 51 deletions
				
			
		|  | @ -43,6 +43,8 @@ class GitHub(object): | ||||||
|         Returns an iterator over a resource, eg 'repos/divio/django-cms/watchers' that automatically handles |         Returns an iterator over a resource, eg 'repos/divio/django-cms/watchers' that automatically handles | ||||||
|         pagination. |         pagination. | ||||||
|         """ |         """ | ||||||
|  |         if params is None: | ||||||
|  |             params = {} | ||||||
|         data, response = self._get(path, params) |         data, response = self._get(path, params) | ||||||
|         for thing in data: |         for thing in data: | ||||||
|             yield thing |             yield thing | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								githubnetwork/middleware.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								githubnetwork/middleware.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,15 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | from django.utils.functional import SimpleLazyObject | ||||||
|  | from githubnetwork.models import GHUser | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def get_github_user(request): | ||||||
|  |     if not request.user.is_authenticated(): | ||||||
|  |         return None | ||||||
|  |     return GHUser.objects.get(user=request.user) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class GithubUserMiddleware(object): | ||||||
|  |     def process_request(self, request): | ||||||
|  |         request.gh_user = SimpleLazyObject(lambda: get_github_user(request)) | ||||||
|  | 
 | ||||||
|  | @ -1,19 +1,13 @@ | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| from collections import defaultdict |  | ||||||
| 
 |  | ||||||
| from django.contrib.auth.decorators import login_required | from django.contrib.auth.decorators import login_required | ||||||
| from django.http import HttpResponse, Http404, HttpResponseForbidden | from django.http import HttpResponse, HttpResponseBadRequest | ||||||
| from django.shortcuts import render_to_response, redirect | from django.shortcuts import render_to_response | ||||||
| from django.template.context import RequestContext | from django.template.context import RequestContext | ||||||
|  | from django.utils import simplejson | ||||||
| from django.utils.decorators import method_decorator | from django.utils.decorators import method_decorator | ||||||
| from django.views.generic.base import TemplateView, TemplateResponseMixin |  | ||||||
| from django.views.generic.detail import DetailView | from django.views.generic.detail import DetailView | ||||||
| from django.views.generic.edit import CreateView, ModelFormMixin, FormView |  | ||||||
| from django.views.generic.list import ListView |  | ||||||
| 
 |  | ||||||
| from django.contrib.auth.models import User |  | ||||||
| from ghapi import api | from ghapi import api | ||||||
| from models import GHUser, Repo | from models import GHUser | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Graph(object): | class Graph(object): | ||||||
|  | @ -21,10 +15,10 @@ class Graph(object): | ||||||
|         self.nodes = set() |         self.nodes = set() | ||||||
|         self.edges = {} |         self.edges = {} | ||||||
|         self.distances = {} |         self.distances = {} | ||||||
|      | 
 | ||||||
|     def add_node(self, value): |     def add_node(self, value): | ||||||
|         self.nodes.add(value) |         self.nodes.add(value) | ||||||
|      | 
 | ||||||
|     def add_edge(self, from_node, to_node, distance): |     def add_edge(self, from_node, to_node, distance): | ||||||
|         self._add_edge(from_node, to_node, distance) |         self._add_edge(from_node, to_node, distance) | ||||||
|         self._add_edge(to_node, from_node, distance) |         self._add_edge(to_node, from_node, distance) | ||||||
|  | @ -41,48 +35,77 @@ class NetworkView(DetailView): | ||||||
|         return self.user |         return self.user | ||||||
| 
 | 
 | ||||||
|     def get_user_network(self): |     def get_user_network(self): | ||||||
|     	user = self.get_user() |         user = self.get_user() | ||||||
|     	graph = [] |         graph = [] | ||||||
| 
 | 
 | ||||||
|     def get_repo_network(self): |     def get_repo_network(self): | ||||||
|     	user = self.get_user() |         user = self.get_user() | ||||||
|     	graph = [] |         graph = [] | ||||||
|     	for repo in api.get_iter('user/%s/repos' % user): |         for repo in api.get_iter('user/%s/repos' % user): | ||||||
|     		# TODO: (Lynn) this is messy - clean up |             # TODO: (Lynn) this is messy - clean up | ||||||
|     		links = {} |             links = {} | ||||||
|     		repo_info = api.get('repos/%s/%s' % (user, repo)) |             repo_info = api.get('repos/%s/%s' % (user, repo)) | ||||||
|     		parent = repo_info['parent']['owner']['login'] |             parent = repo_info['parent']['owner']['login'] | ||||||
|     		child = repo_info['owner']['login'] |             child = repo_info['owner']['login'] | ||||||
|     		watchers = repo_info['parent']['watchers'] |             watchers = repo_info['parent']['watchers'] | ||||||
|     		network = repo_info['network_count'] |             network = repo_info['network_count'] | ||||||
|     		date_updated_parent = repo_info['parent']['updated_at'] |             date_updated_parent = repo_info['parent']['updated_at'] | ||||||
|     		date_updated_child = repo_info['updated_at'] |             date_updated_child = repo_info['updated_at'] | ||||||
|     		links['source'] = parent |             links['source'] = parent | ||||||
|     		links['target'] = child |             links['target'] = child | ||||||
|     		links['weight'] = {'watchers': watchers, 'network' : network,  |             links['weight'] = {'watchers': watchers, 'network': network, | ||||||
|     		                    'date_updated_parent' : date_updated_parent,  |                                'date_updated_parent': date_updated_parent, | ||||||
|     		                    'date_updated_child' : date_updated_child } |                                'date_updated_child': date_updated_child} | ||||||
|     		graph.append(links) |             graph.append(links) | ||||||
|     	return graph |         return graph | ||||||
| 
 | 
 | ||||||
|     def get_queryset(self): |     def get_queryset(self): | ||||||
|     	self.get_user() |         self.get_user() | ||||||
|     	if repos: |         if repos: | ||||||
|     		# do repo-y things |             # do repo-y things | ||||||
|     		self.get_repo_network() |             self.get_repo_network() | ||||||
|     	else: |         else: | ||||||
|     		# do user-y things |             # do user-y things | ||||||
|     		self.get_user_network() |             self.get_user_network() | ||||||
| 
 | 
 | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
|         # TODO: (Lynn) figure out what's needed for context data |         # TODO: (Lynn) figure out what's needed for context data | ||||||
|         context_object_name = self.get_context_object_name(queryset) |         context_object_name = self.get_context_object_name(queryset) | ||||||
| 
 | 
 | ||||||
|     def get(self): |     def get(self): | ||||||
|     	self.object_list = self.get_queryset() |         self.object_list = self.get_queryset() | ||||||
|         context = self.get_context_data(object_list=self.object_list) |         context = self.get_context_data(object_list=self.object_list) | ||||||
|         return self.render_to_response(context) |         return self.render_to_response(context) | ||||||
| 
 | 
 | ||||||
|     @method_decorator(login_required) |     @method_decorator(login_required) | ||||||
|     def dispatch(self, *args. **kwargs): |     def dispatch(self, *args, ** kwargs): | ||||||
| 	    return super(ProtectedView, self).dispatch(*args, **kwargs) |         return super(ProtectedView, self).dispatch(*args, **kwargs) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _sorted_repos(request): | ||||||
|  |     '''Get a list of repos for the currently authorized user, sort it, and | ||||||
|  |     return it.''' | ||||||
|  |     repos = [r for r in request.github.get_iter('users/%s/repos' % | ||||||
|  |         request.user.username)] | ||||||
|  |     repos.sort(key=lambda x: x['name']) | ||||||
|  |     return repos | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @login_required | ||||||
|  | def me(request): | ||||||
|  |     context = RequestContext(request) | ||||||
|  |     context['followers'] = simplejson.dumps( | ||||||
|  |         [{'name': unicode(follower), 'avatar': follower.avatar_url} | ||||||
|  |          for follower in GHUser.objects.filter(following=request.gh_user)]) | ||||||
|  |     context['repos'] = _sorted_repos(request) | ||||||
|  |     return render_to_response('me.html', context) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @login_required | ||||||
|  | def get_user_followers(request): | ||||||
|  |     name = request.GET.get('user', None) | ||||||
|  |     if not name: | ||||||
|  |         raise HttpResponseBadRequest() | ||||||
|  |     names = simplejson.dumps([user['login'] | ||||||
|  |         for user in request.github.get_iter('users/%s/followers' % name)]) | ||||||
|  |     return HttpResponse(names, content_type='application/json') | ||||||
|  |  | ||||||
|  | @ -43,6 +43,7 @@ MIDDLEWARE_CLASSES = [ | ||||||
|     'django.contrib.auth.middleware.AuthenticationMiddleware', |     'django.contrib.auth.middleware.AuthenticationMiddleware', | ||||||
|     'django.contrib.messages.middleware.MessageMiddleware', |     'django.contrib.messages.middleware.MessageMiddleware', | ||||||
|     'ghapi.middleware.GithubAPIMiddleware', |     'ghapi.middleware.GithubAPIMiddleware', | ||||||
|  |     'githubnetwork.middleware.GithubUserMiddleware', | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| TEMPLATE_CONTEXT_PROCESSORS = [ | TEMPLATE_CONTEXT_PROCESSORS = [ | ||||||
|  | @ -85,7 +86,7 @@ AUTHENTICATION_BACKENDS = [ | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| LOGIN_URL          = '/login/' | LOGIN_URL          = '/login/' | ||||||
| LOGIN_REDIRECT_URL = '/' | LOGIN_REDIRECT_URL = '/me/' | ||||||
| LOGIN_ERROR_URL    = '/login/failed/' | LOGIN_ERROR_URL    = '/login/failed/' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										7034
									
								
								static/d3/d3.v2.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7034
									
								
								static/d3/d3.v2.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										4
									
								
								static/d3/d3.v2.min.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								static/d3/d3.v2.min.js
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										24
									
								
								templates/graph_base.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								templates/graph_base.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | {# vim: set ft=htmldjango #} | ||||||
|  | {% extends "base.html" %} | ||||||
|  | 
 | ||||||
|  | {% block head_css %} | ||||||
|  | <style text="text/css"> | ||||||
|  | h1.placeholder { | ||||||
|  |   margin-top: 80px; | ||||||
|  |   text-align: center; | ||||||
|  |   color: #ccc; | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  | {% endblock %} | ||||||
|  | 
 | ||||||
|  | {% block container %} | ||||||
|  | {% include "navbar.html" %} | ||||||
|  | <div class="container-fluid"> | ||||||
|  |   {% block graph %}<h1 class="placeholder">PUT A GRAPH HERE</h1>{% endblock %} | ||||||
|  | </div> | ||||||
|  | {% endblock container %} | ||||||
|  | 
 | ||||||
|  | {% block body_js %} | ||||||
|  | <script src="{{ STATIC_URL }}js/jquery.js"></script> | ||||||
|  | <script src="{{ STATIC_URL }}bootstrap/js/bootstrap-dropdown.js"></script> | ||||||
|  | {% endblock %} | ||||||
							
								
								
									
										2
									
								
								templates/graph_followers.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								templates/graph_followers.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | {# vim: set ft=htmldjango #} | ||||||
|  | {% extends "graph_base.html" %} | ||||||
							
								
								
									
										6
									
								
								templates/graph_repo.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								templates/graph_repo.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | {# vim: set ft=htmldjango #} | ||||||
|  | {% extends "graph_base.html" %} | ||||||
|  | 
 | ||||||
|  | {% block graph %} | ||||||
|  | <h1 class="placeholder">PUT A GRAPH OF<br/>{{ username }}'s<br/>{{ repo }} REPO<br/>HERE</h1> | ||||||
|  | {% endblock %} | ||||||
							
								
								
									
										118
									
								
								templates/me.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								templates/me.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,118 @@ | ||||||
|  | {% extends "graph_base.html" %} | ||||||
|  | 
 | ||||||
|  | {% block graph %} | ||||||
|  |     <h1>People following you</h1> | ||||||
|  |     <div id='chart'> </div> | ||||||
|  |     <style> | ||||||
|  |         circle.node { | ||||||
|  |             stroke: #fff; | ||||||
|  |             stroke-width: 1.5px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         line.link { | ||||||
|  |             stroke: #999; | ||||||
|  |             stroke-opacity: .6; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  |     <script src="{{ STATIC_URL }}d3/d3.v2.js"></script> | ||||||
|  |     <script src="{{ STATIC_URL }}/js/jquery.js"></script> | ||||||
|  |     <script> | ||||||
|  |     $(document).ready(function(){ | ||||||
|  | 
 | ||||||
|  |         var followers = {{ followers|safe }}; | ||||||
|  |         var map = {}; | ||||||
|  | 
 | ||||||
|  |         var w = 960, | ||||||
|  |             h = 960; | ||||||
|  |         var color = d3.scale.category20(); | ||||||
|  | 
 | ||||||
|  |         var force = d3.layout.force() | ||||||
|  |                 .gravity(.05) | ||||||
|  |                 .distance(250) | ||||||
|  |                 .charge(-500) | ||||||
|  |                 .size([w, h]); | ||||||
|  | 
 | ||||||
|  |         var nodes = force.nodes(), | ||||||
|  |                 links = force.links(); | ||||||
|  | 
 | ||||||
|  |         var vis = d3.select("#chart").append("svg:svg") | ||||||
|  |                 .attr("width", w) | ||||||
|  |                 .attr("height", h); | ||||||
|  | 
 | ||||||
|  |         force.on("tick", function() { | ||||||
|  |             vis.selectAll("g.node") | ||||||
|  |                     .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | ||||||
|  | 
 | ||||||
|  |             vis.selectAll("line.link") | ||||||
|  |                     .attr("x1", function(d) { return d.source.x; }) | ||||||
|  |                     .attr("y1", function(d) { return d.source.y; }) | ||||||
|  |                     .attr("x2", function(d) { return d.target.x; }) | ||||||
|  |                     .attr("y2", function(d) { return d.target.y; }); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         function restart() { | ||||||
|  |             var link = vis.selectAll("line.link") | ||||||
|  |                     .data(links, function(d) { return d.source.id + "-" + d.target.id; }); | ||||||
|  | 
 | ||||||
|  |             link.enter().insert("svg:line", "g.node") | ||||||
|  |                     .attr("class", "link"); | ||||||
|  | 
 | ||||||
|  |             link.exit().remove(); | ||||||
|  | 
 | ||||||
|  |             var node = vis.selectAll("g.node") | ||||||
|  |                     .data(nodes, function(d) { return d.id;}); | ||||||
|  | 
 | ||||||
|  |             var nodeEnter = node.enter().append("svg:g").attr('class', 'node').call(force.drag); | ||||||
|  |                 nodeEnter.append("svg:image") | ||||||
|  |                     .attr("class", "circle") | ||||||
|  |                     .attr("xlink:href", function(d){return d.avatar;}) | ||||||
|  |                     .attr("x", "-16px") | ||||||
|  |                     .attr("y", "-16px") | ||||||
|  |                     .style("border-radius", "16px;") | ||||||
|  |                     .attr("width", "32px") | ||||||
|  |                     .attr("height", "32px"); | ||||||
|  |                 nodeEnter.append("title") | ||||||
|  |                     .text(function(d) { return d.name }); | ||||||
|  | 
 | ||||||
|  |             node.exit().remove(); | ||||||
|  | 
 | ||||||
|  |             force.start(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Add three nodes and three links. | ||||||
|  |         function init() { | ||||||
|  |             var center = {"name": "{{ request.gh_user.gh_login }}", "avatar": "{{ request.gh_user.avatar_url }}"}; | ||||||
|  |             nodes.push(center); | ||||||
|  |             for (var i = 0; i<followers.length;i++){ | ||||||
|  |                 nodes.push(followers[i]); | ||||||
|  |                 links.push({source:center, target:followers[i]}); | ||||||
|  |                 map[followers[i].name] = followers[i]; | ||||||
|  |             } | ||||||
|  |             restart(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         function addLink(link) { | ||||||
|  |             links.push(link); | ||||||
|  |             restart(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         restart(); | ||||||
|  |         init(); | ||||||
|  |         function loadFollowerFollowers(follower){ | ||||||
|  |             $.getJSON('{%  url get_user_followers %}?user=' + follower.name, function(data){ | ||||||
|  |                 for (var i = 0; i<data.length; i++){ | ||||||
|  |                     var target = map[data[i]]; | ||||||
|  |                     if (target){ | ||||||
|  |                         addLink({source:follower, target:target}) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |             // addLink({source: followers[15], target: followers[5]}); | ||||||
|  |         } | ||||||
|  |         for (var i = 0; i<followers.length; i++){ | ||||||
|  |             loadFollowerFollowers(followers[i]); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |     </script> | ||||||
|  | {% endblock %} | ||||||
|  | 
 | ||||||
							
								
								
									
										29
									
								
								templates/navbar.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								templates/navbar.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | {# vim: set ft=htmldjango #} | ||||||
|  | <div class="navbar navbar-fixed-top"> | ||||||
|  |   <div class="navbar-inner"> | ||||||
|  |     <div class="container-fluid"> | ||||||
|  |       <a class="brand" href="">Cool name</a> | ||||||
|  |       <ul class="nav"> | ||||||
|  |         <li><a href="{% url me %}">Me</a></li> | ||||||
|  |         <li class="dropdown"> | ||||||
|  |           <a href="#" class="dropdown-toggle" data-toggle="dropdown">My Repos</a> | ||||||
|  |           <ul class="dropdown-menu"> | ||||||
|  |             {% for r in repos %} | ||||||
|  |             <li><a href="#">{{ r.name }}</a></li> | ||||||
|  |             {% endfor %} | ||||||
|  |           </ul> | ||||||
|  |         </li> | ||||||
|  |       </ul> | ||||||
|  |       <ul class="nav pull-right"> | ||||||
|  |         <li class="dropdown"> | ||||||
|  |           <a href="#" class="dropdown-toggle" data-toggle="dropdown"> | ||||||
|  |             {{ request.user.username }} | ||||||
|  |           </a> | ||||||
|  |           <ul class="dropdown-menu"> | ||||||
|  |             <li><a href="#">Logout</a></li> | ||||||
|  |           </ul> | ||||||
|  |         </li> | ||||||
|  |       </ul> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
							
								
								
									
										6
									
								
								urls.py
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								urls.py
									
										
									
									
									
								
							|  | @ -11,7 +11,13 @@ admin.autodiscover() | ||||||
| urlpatterns = patterns('', | urlpatterns = patterns('', | ||||||
|     url(r'^%s(?P<path>.*)$' % re.escape(settings.STATIC_URL.lstrip('/')), 'django.contrib.staticfiles.views.serve', {'insecure': True}), |     url(r'^%s(?P<path>.*)$' % re.escape(settings.STATIC_URL.lstrip('/')), 'django.contrib.staticfiles.views.serve', {'insecure': True}), | ||||||
|     url(r'^admin/', include(admin.site.urls)), |     url(r'^admin/', include(admin.site.urls)), | ||||||
|  |     url(r'^followers/', views.graph_followers, | ||||||
|  |         name='graph_followers'), | ||||||
|     url(r'^login/$', views.login, name='login'), |     url(r'^login/$', views.login, name='login'), | ||||||
|  |     url(r'^me/$', 'githubnetwork.views.me', name='me'), | ||||||
|  |     url(r'^~followers/$', 'githubnetwork.views.get_user_followers', name='get_user_followers'), | ||||||
|  |     url(r'^repo/(?P<user>\w+)/(?P<repo>\w+)/', views.graph_repo, | ||||||
|  |         name='graph_repo'), | ||||||
|     url(r'^$', views.index, name='index'), |     url(r'^$', views.index, name='index'), | ||||||
|     url(r'', include('social_auth.urls')), |     url(r'', include('social_auth.urls')), | ||||||
| ) | ) | ||||||
|  |  | ||||||
							
								
								
									
										23
									
								
								views.py
									
										
									
									
									
								
							
							
						
						
									
										23
									
								
								views.py
									
										
									
									
									
								
							|  | @ -1,4 +1,5 @@ | ||||||
| from django.contrib.auth.decorators import login_required | from django.contrib.auth.decorators import login_required | ||||||
|  | from django.http import HttpResponse | ||||||
| from django.shortcuts import redirect, render_to_response | from django.shortcuts import redirect, render_to_response | ||||||
| from django.template import RequestContext | from django.template import RequestContext | ||||||
| 
 | 
 | ||||||
|  | @ -7,12 +8,12 @@ def index(request): | ||||||
|     '''Index page. Everyone starts here. If the user is logged in (that is, they |     '''Index page. Everyone starts here. If the user is logged in (that is, they | ||||||
|     have a session id) return the follower_graph view. Otherwise, render the |     have a session id) return the follower_graph view. Otherwise, render the | ||||||
|     index page.''' |     index page.''' | ||||||
|     if request.session.get('sessionid', False): |     if request.user.is_authenticated(): | ||||||
|         return follower_graph(request) |         return redirect('graph_followers') | ||||||
|     # Set a test cookie. When the user clicks the 'Login' button, test and make |     # Set a test cookie. When the user clicks the 'Login' button, test and make | ||||||
|     # sure this cookie was set properly. |     # sure this cookie was set properly. | ||||||
|     request.session.set_test_cookie() |     request.session.set_test_cookie() | ||||||
|     return render_to_response('login.html', RequestContext(request)) |     return render_to_response('index.html', RequestContext(request)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def login(request): | def login(request): | ||||||
|  | @ -21,13 +22,21 @@ def login(request): | ||||||
|     # Make sure the user can accept cookies. |     # Make sure the user can accept cookies. | ||||||
|     if request.session.test_cookie_worked(): |     if request.session.test_cookie_worked(): | ||||||
|         request.session.delete_test_cookie() |         request.session.delete_test_cookie() | ||||||
|         return redirect('/login/github/') |         return redirect('socialauth_begin', backend='github') | ||||||
|     else: |     else: | ||||||
|  |         # During development, I've landed here a lot, despite having cookies | ||||||
|  |         # enabled. So, set the test cookie so that trying to login from here | ||||||
|  |         # actually works. | ||||||
|  |         request.session.set_test_cookie() | ||||||
|         # Render an error -- fix your damn cookies! |         # Render an error -- fix your damn cookies! | ||||||
|         return render_to_response('login.html', |         return render_to_response('index.html', | ||||||
|                                   { 'error': "Fix your damn cookies!" }) |                                   { 'error': "Fix your damn cookies!" }) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @login_required | @login_required | ||||||
| def follower_graph(request): | def graph_repo(request, user=None, repo=None): | ||||||
|     return 'Hello!' |     return render_to_response('graph_repo.html', { | ||||||
|  |         'graph_user': user, | ||||||
|  |         'graph_repo': repo, | ||||||
|  |         'repos': _sorted_repos(request) | ||||||
|  |     }, RequestContext(request)) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue