updates the ghuser on login
This commit is contained in:
		
							parent
							
								
									603c29c8b4
								
							
						
					
					
						commit
						055e10b97e
					
				
					 9 changed files with 166 additions and 62 deletions
				
			
		|  | @ -25,8 +25,11 @@ class GitHub(object): | |||
|         """ | ||||
|         Gets a resource, eg 'users/ojii'. | ||||
| 
 | ||||
|         Returns tuple (jsondata, response) | ||||
|         Returns parsed json data as a python dictionary | ||||
|         """ | ||||
|         return self._get(path, params)[0] | ||||
| 
 | ||||
|     def _get(self, path, params=None): | ||||
|         if params is None: | ||||
|             params = {} | ||||
|         params['per_page'] = 100 | ||||
|  | @ -34,12 +37,13 @@ class GitHub(object): | |||
|         response.raise_for_status() | ||||
|         return response.json, response | ||||
| 
 | ||||
| 
 | ||||
|     def get_iter(self, path, params=None): | ||||
|         """ | ||||
|         Returns an iterator over a resource, eg 'repos/divio/django-cms/watchers' that automatically handles | ||||
|         pagination. | ||||
|         """ | ||||
|         data, response = self.get(path, params) | ||||
|         data, response = self._get(path, params) | ||||
|         for thing in data: | ||||
|             yield thing | ||||
|         next_page = get_next_page(response) | ||||
|  |  | |||
							
								
								
									
										7
									
								
								githubnetwork/admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								githubnetwork/admin.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from django.contrib import admin | ||||
| from githubnetwork.models import GHUser, Repo | ||||
| 
 | ||||
| 
 | ||||
| admin.site.register(GHUser) | ||||
| admin.site.register(Repo) | ||||
							
								
								
									
										1
									
								
								githubnetwork/management/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								githubnetwork/management/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| # -*- coding: utf-8 -*- | ||||
							
								
								
									
										1
									
								
								githubnetwork/management/commands/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								githubnetwork/management/commands/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| # -*- coding: utf-8 -*- | ||||
							
								
								
									
										8
									
								
								githubnetwork/management/commands/make_admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								githubnetwork/management/commands/make_admin.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.management.base import BaseCommand | ||||
| 
 | ||||
| 
 | ||||
| class Command(BaseCommand): | ||||
|     def handle(self, username, **option): | ||||
|         User.objects.filter(username=username).update(is_staff=True, is_superuser=True) | ||||
							
								
								
									
										8
									
								
								githubnetwork/management/commands/revoke_admin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								githubnetwork/management/commands/revoke_admin.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from django.contrib.auth.models import User | ||||
| from django.core.management.base import BaseCommand | ||||
| 
 | ||||
| 
 | ||||
| class Command(BaseCommand): | ||||
|     def handle(self, username, **option): | ||||
|         User.objects.filter(username=username).update(is_staff=False, is_superuser=False) | ||||
|  | @ -12,26 +12,27 @@ class Migration(SchemaMigration): | |||
|         db.create_table('githubnetwork_ghuser', ( | ||||
|             ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), | ||||
|             ('last_sync', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)), | ||||
|             ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True)), | ||||
|             ('created_at', self.gf('django.db.models.fields.DateTimeField')()), | ||||
|             ('acct_type', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||||
|             ('gh_login', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||||
|             ('blog', self.gf('django.db.models.fields.URLField')(max_length=255)), | ||||
|             ('email', self.gf('django.db.models.fields.EmailField')(max_length=255)), | ||||
|             ('avatar_url', self.gf('django.db.models.fields.URLField')(max_length=255)), | ||||
|             ('public_gists', self.gf('django.db.models.fields.IntegerField')()), | ||||
|             ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], unique=True, null=True, blank=True)), | ||||
|             ('created_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), | ||||
|             ('acct_type', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), | ||||
|             ('gh_login', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)), | ||||
|             ('blog', self.gf('django.db.models.fields.URLField')(max_length=255, blank=True)), | ||||
|             ('email', self.gf('django.db.models.fields.EmailField')(max_length=255, blank=True)), | ||||
|             ('avatar_url', self.gf('django.db.models.fields.URLField')(max_length=255, blank=True)), | ||||
|             ('public_gists', self.gf('django.db.models.fields.IntegerField')(default=0)), | ||||
|             ('hireable', self.gf('django.db.models.fields.BooleanField')(default=False)), | ||||
|             ('followers_count', self.gf('django.db.models.fields.IntegerField')()), | ||||
|             ('html_url', self.gf('django.db.models.fields.URLField')(max_length=255)), | ||||
|             ('bio', self.gf('django.db.models.fields.TextField')()), | ||||
|             ('name', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||||
|             ('company', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||||
|             ('url', self.gf('django.db.models.fields.URLField')(max_length=255)), | ||||
|             ('gravatar_id', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||||
|             ('gh_id', self.gf('django.db.models.fields.IntegerField')()), | ||||
|             ('public_repos', self.gf('django.db.models.fields.IntegerField')()), | ||||
|             ('following_count', self.gf('django.db.models.fields.IntegerField')()), | ||||
|             ('location', self.gf('django.db.models.fields.CharField')(max_length=255)), | ||||
|             ('followers_count', self.gf('django.db.models.fields.IntegerField')(default=0)), | ||||
|             ('html_url', self.gf('django.db.models.fields.URLField')(max_length=255, blank=True)), | ||||
|             ('bio', self.gf('django.db.models.fields.TextField')(blank=True)), | ||||
|             ('name', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), | ||||
|             ('company', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), | ||||
|             ('url', self.gf('django.db.models.fields.URLField')(max_length=255, blank=True)), | ||||
|             ('gravatar_id', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), | ||||
|             ('gh_id', self.gf('django.db.models.fields.IntegerField')(default=-1)), | ||||
|             ('public_repos', self.gf('django.db.models.fields.IntegerField')(default=0)), | ||||
|             ('following_count', self.gf('django.db.models.fields.IntegerField')(default=0)), | ||||
|             ('location', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)), | ||||
|             ('complete', self.gf('django.db.models.fields.BooleanField')(default=False)), | ||||
|         )) | ||||
|         db.send_create_signal('githubnetwork', ['GHUser']) | ||||
| 
 | ||||
|  | @ -125,29 +126,30 @@ class Migration(SchemaMigration): | |||
|         }, | ||||
|         'githubnetwork.ghuser': { | ||||
|             'Meta': {'object_name': 'GHUser'}, | ||||
|             'acct_type': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||||
|             'avatar_url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), | ||||
|             'bio': ('django.db.models.fields.TextField', [], {}), | ||||
|             'blog': ('django.db.models.fields.URLField', [], {'max_length': '255'}), | ||||
|             'company': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||||
|             'created_at': ('django.db.models.fields.DateTimeField', [], {}), | ||||
|             'email': ('django.db.models.fields.EmailField', [], {'max_length': '255'}), | ||||
|             'followers_count': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'following': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'following_rel_+'", 'to': "orm['githubnetwork.GHUser']"}), | ||||
|             'following_count': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'gh_id': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'gh_login': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||||
|             'gravatar_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||||
|             'acct_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'avatar_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'bio': ('django.db.models.fields.TextField', [], {'blank': 'True'}), | ||||
|             'blog': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'company': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'complete': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||||
|             'created_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), | ||||
|             'email': ('django.db.models.fields.EmailField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'followers_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||||
|             'following': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'following_rel_+'", 'blank': 'True', 'to': "orm['githubnetwork.GHUser']"}), | ||||
|             'following_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||||
|             'gh_id': ('django.db.models.fields.IntegerField', [], {'default': '-1'}), | ||||
|             'gh_login': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), | ||||
|             'gravatar_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'hireable': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | ||||
|             'html_url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), | ||||
|             'html_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | ||||
|             'last_sync': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), | ||||
|             'location': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||||
|             'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), | ||||
|             'public_gists': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'public_repos': ('django.db.models.fields.IntegerField', [], {}), | ||||
|             'url': ('django.db.models.fields.URLField', [], {'max_length': '255'}), | ||||
|             'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'}) | ||||
|             'location': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'public_gists': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||||
|             'public_repos': ('django.db.models.fields.IntegerField', [], {'default': '0'}), | ||||
|             'url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}), | ||||
|             'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True', 'null': 'True', 'blank': 'True'}) | ||||
|         }, | ||||
|         'githubnetwork.repo': { | ||||
|             'Meta': {'object_name': 'Repo'}, | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| import datetime | ||||
| from django.contrib.auth.signals import user_logged_in | ||||
| from django.db import models | ||||
| from django.contrib.auth.models import User | ||||
| 
 | ||||
|  | @ -9,33 +10,94 @@ class BaseAPIModel(models.Model): | |||
|     class Meta: | ||||
|         abstract = True | ||||
| 
 | ||||
|     def needs_refresh(self): | ||||
|         now = datetime.datetime.now() | ||||
|         return now - self.last_sync > datetime.timedelta(days=7) | ||||
| 
 | ||||
|     def refresh(self, api): | ||||
|         """ | ||||
|         Refresh the data on this object | ||||
|         """ | ||||
|         pass # TODO | ||||
| 
 | ||||
| 
 | ||||
| class GHUserManager(models.Manager): | ||||
|     def create_from_api(self, username, api): | ||||
|         obj = self.model(complete=True, gh_login=username) | ||||
|         obj.refresh(api) | ||||
|         return obj | ||||
| 
 | ||||
| 
 | ||||
| class GHUser(BaseAPIModel): | ||||
|     user = models.ForeignKey(User, unique=True) | ||||
|     following = models.ManyToManyField('self', related_name='followers') | ||||
|     created_at = models.DateTimeField('date account created') | ||||
|     acct_type = models.CharField(max_length=255) | ||||
|     gh_login = models.CharField(max_length=255) | ||||
|     blog = models.URLField(max_length=255) | ||||
|     email = models.EmailField(max_length=255) | ||||
|     avatar_url = models.URLField(max_length=255) | ||||
|     public_gists = models.IntegerField() | ||||
|     hireable = models.BooleanField() | ||||
|     followers_count = models.IntegerField() | ||||
|     html_url = models.URLField(max_length=255) | ||||
|     bio = models.TextField() | ||||
|     name = models.CharField(max_length=255) | ||||
|     company = models.CharField(max_length=255) | ||||
|     url = models.URLField(max_length=255) | ||||
|     gravatar_id = models.CharField(max_length=255) | ||||
|     gh_id = models.IntegerField() | ||||
|     public_repos = models.IntegerField() | ||||
|     following_count = models.IntegerField() | ||||
|     location = models.CharField(max_length=255) | ||||
|     user = models.ForeignKey(User, unique=True, null=True, blank=True) | ||||
|     following = models.ManyToManyField('self', related_name='followers', blank=True) | ||||
|     created_at = models.DateTimeField('date account created', blank=True, null=True ) | ||||
|     acct_type = models.CharField(max_length=255, blank=True) | ||||
|     gh_login = models.CharField(max_length=255, unique=True) | ||||
|     blog = models.URLField(max_length=255, blank=True) | ||||
|     email = models.EmailField(max_length=255, blank=True) | ||||
|     avatar_url = models.URLField(max_length=255, blank=True) | ||||
|     public_gists = models.IntegerField(default=0) | ||||
|     hireable = models.BooleanField(default=False) | ||||
|     followers_count = models.IntegerField(default=0) | ||||
|     html_url = models.URLField(max_length=255, blank=True) | ||||
|     bio = models.TextField(blank=True) | ||||
|     name = models.CharField(max_length=255, blank=True) | ||||
|     company = models.CharField(max_length=255, blank=True) | ||||
|     url = models.URLField(max_length=255, blank=True) | ||||
|     gravatar_id = models.CharField(max_length=255, blank=True) | ||||
|     gh_id = models.IntegerField(default=-1) | ||||
|     public_repos = models.IntegerField(default=0) | ||||
|     following_count = models.IntegerField(default=0) | ||||
|     location = models.CharField(max_length=255, blank=True) | ||||
|     complete = models.BooleanField(default=False) | ||||
| 
 | ||||
|     objects = GHUserManager() | ||||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return self.gh_login | ||||
| 
 | ||||
|     def _translate(self, data): | ||||
|         data['acct_type'] = data.pop('type', '') | ||||
|         data['followers_count'] = data.pop('followers', '0') | ||||
|         data['following_count'] = data.pop('following', '0') | ||||
|         data['gh_login'] = data.pop('login') | ||||
|         data['gh_id'] = data.pop('id', '0') | ||||
|         return data | ||||
| 
 | ||||
|     def refresh(self, api): | ||||
|         data = api.get('users/%s' % self.gh_login) | ||||
|         data = self._translate(data) | ||||
|         for key, value in data.items(): | ||||
|             setattr(self, key, value) | ||||
|         self.complete = True | ||||
|         self.save() | ||||
|         # set followers/following | ||||
|         followers = [] | ||||
|         cache = {} | ||||
|         for shortuser in api.get_iter('users/%s/followers' % self.gh_login): | ||||
|             follower = cache.get(shortuser['login'], None) | ||||
|             if not follower: | ||||
|                 try: | ||||
|                     follower = GHUser.objects.get(gh_login=shortuser['login']) | ||||
|                 except self.DoesNotExist: | ||||
|                     follower = GHUser.objects.create(**self._translate(shortuser)) | ||||
|             followers.append(follower) | ||||
|             cache[follower.gh_login] = follower | ||||
|         self.followers = followers | ||||
|         following = [] | ||||
|         for shortuser in api.get_iter('users/%s/following' % self.gh_login): | ||||
|             follower = cache.get(shortuser['login'], None) | ||||
|             if not follower: | ||||
|                 try: | ||||
|                     follower = GHUser.objects.get(gh_login=shortuser['login']) | ||||
|                 except self.DoesNotExist: | ||||
|                     follower = GHUser.objects.create(**self._translate(shortuser)) | ||||
|             following.append(follower) | ||||
|         self.following = following | ||||
|         return self | ||||
| 
 | ||||
| 
 | ||||
| class Repo(BaseAPIModel): | ||||
|     owner = models.ForeignKey(GHUser, unique=True) | ||||
|     forks = models.IntegerField() | ||||
|  | @ -64,3 +126,13 @@ class Repo(BaseAPIModel): | |||
| 
 | ||||
|     def __unicode__(self): | ||||
|         return self.name | ||||
| 
 | ||||
| def update_user(request, user, **kwargs): | ||||
|     try: | ||||
|         ghuser = GHUser.objects.get(gh_login=user.username) | ||||
|     except GHUser.DoesNotExist: | ||||
|         return GHUser.objects.create_from_api(user.username, request.github) | ||||
|     ghuser.user = user | ||||
|     ghuser.refresh(request.github) | ||||
| 
 | ||||
| user_logged_in.connect(update_user) | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ assert 'SECRET_KEY' in os.environ, 'Set SECRET_KEY in your .env file!' | |||
| SECRET_KEY = os.environ['SECRET_KEY'] | ||||
| 
 | ||||
| USE_L10N = USE_I18N = False | ||||
| USE_TZ = True | ||||
| 
 | ||||
| MEDIA_ROOT = os.path.join(PROJECT_DIR, 'media') | ||||
| MEDIA_URL = '/media/' | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jonas Obrist
						Jonas Obrist