Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature regions #18

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 50 additions & 5 deletions core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,56 @@
from __future__ import unicode_literals

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

# Register/Unregister models here.
from core.models import UserRepo, Issue, IssueLabel
from core.models import UserRepo, Issue, IssueLabel, Region, RegionAdmin
from django.contrib.auth.models import *

admin.site.unregister(Group)
admin.site.unregister(User)
admin.site.register(UserRepo)

class UserRepoAdmin(admin.ModelAdmin):
"""Used to alter `UserRepo` admin site."""
fieldsets = (
(None, {
'fields': ('user', 'repo', 'regions')
}),
)

def formfield_for_manytomany(self, db_field, request, **kwargs):
"""Only show regions related to logged in user when filling `userrepo` form"""
if db_field.name == "regions":
kwargs["queryset"] = Region.objects.filter(regionadmin=request.user)
return super(UserRepoAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

def save_form(self, request, form, change):
"""Automatically fills author by extracting it from currunt login user."""
obj = super( UserRepoAdmin, self).save_form(request, form, change)
if not change:
obj.author = request.user
return obj

def get_queryset(self, request):
"""Only let the user view their own `UserRepos`."""
qs = super(UserRepoAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(author=request.user)

def save_model(self, request, obj, form, change):
"""Save Model"""
obj.author = request.user
super(UserRepoAdmin, self).save_model(request, obj, form, change)

def has_change_permission(self, request, obj=None):
"""Only give the user permissions to modify their own `UserRepos`."""
if not obj:
return True
return obj.author == request.user or request.user.is_superuser


# Re-register UserAdmin
admin.site.register(User, UserAdmin)
admin.site.register(RegionAdmin)

admin.site.register(UserRepo, UserRepoAdmin)
admin.site.register(Region)
admin.site.register(Issue)
28 changes: 0 additions & 28 deletions core/migrations/0001_initial.py

This file was deleted.

47 changes: 0 additions & 47 deletions core/migrations/0002_auto_20170601_0658.py

This file was deleted.

Empty file removed core/migrations/__init__.py
Empty file.
80 changes: 64 additions & 16 deletions core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,47 @@

from datetime import timedelta
from django.db import models
from core.utils.services import request_github_issues

from celery.task.schedules import crontab
from django.contrib.auth.models import AbstractUser
from celery.decorators import periodic_task

from core.utils.services import request_github_issues

ISSUE_UPDATE_PERIOD = 15 # in minutes


class Region(models.Model):
"""Used to store data for different regions."""
region_name = models.CharField(max_length=100, unique=True)
region_image = models.URLField(blank=True)

class Meta:
ordering = ('region_name',) # Ascending order according to region name.

def __str__(self):
return '%s' % (self.region_name)


class RegionAdmin(AbstractUser):
regions = models.ManyToManyField(Region)


class UserRepo(models.Model):
"""
UserRepo model is used to store the username and repo-name
for a repository.
"""
user = models.CharField(max_length=100)
repo = models.CharField(max_length=100)
author = models.ForeignKey(RegionAdmin)
regions = models.ManyToManyField(Region)
created = models.DateTimeField(auto_now_add=True)

class Meta:
ordering = ('created',) # Ascending order according to date created.
unique_together = ("user", "repo") # Avoid repo duplicates.
unique_together = ("user", "repo", "author") # Avoid repo duplicates.

def __str__(self):
return '/%s/%s' % (self.user, self.repo)


class IssueLabel(models.Model):
Expand All @@ -32,7 +54,7 @@ class IssueLabel(models.Model):
label_url = models.URLField()
label_name = models.CharField(max_length=100)
label_color = models.CharField(max_length=6)

class Meta:
ordering = ('label_name',) # Ascending order according to label_name.

Expand Down Expand Up @@ -67,7 +89,8 @@ class Issue(models.Model):
issue_labels = models.ManyToManyField(IssueLabel, blank=True)
issue_url = models.URLField()
issue_body = models.TextField()

regions = models.ManyToManyField(Region)

class Meta:
ordering = ('updated_at',) # Ascending order according to updated_at.

Expand All @@ -78,32 +101,56 @@ def periodic_issues_updater():
Update `Issue` model in the database in every
`ISSUE_UPDATE_PERIOD` minutes.
"""
list_of_repos = UserRepo.objects.values('user', 'repo',)
list_of_repos = UserRepo.objects.values('id', 'user', 'repo',)
for repo in list_of_repos:
region_queryset = retrive_regions_for_a_user(repo['id'])
issue_list = request_github_issues(repo['user'], repo['repo'])
if issue_list['error']:
print "Error" + str(issue_list['data'])
else:
for issue in issue_list['data']:
validate_and_store_issue(issue)
validate_and_store_issue(issue, region_queryset)

def retrive_regions_for_a_user(user_repo_id):
"""Fetches all the regions related to a user."""
region_queryset = Region.objects.filter(userrepo=user_repo_id)
return region_queryset

def validate_and_store_issue(issue):
def validate_and_store_issue(issue, region_queryset):
"""
Validate issue:- if valid - store it into database,
else - Do not store in database
"""
if issue['state'] == 'open':
experience_needed, language, expected_time, technology_stack = parse_issue(issue['body'])
if is_issue_state_open(issue):
if is_issue_valid(issue):
store_issue_in_db(issue, region_queryset)

if experience_needed and language and expected_time and technology_stack:
store_issue_in_db(issue, experience_needed, language, expected_time, technology_stack)
else:
print 'Issue with id ' + str(issue['id']) + ' is not valid for our system.'
def is_issue_state_open(issue):
"""
Returns true if issue state is open else
return false and delete the issue from database.
"""
if issue['state'] == 'open':
return True
else:
delete_closed_issues(issue) # Delete closed issues from db.
return False

def store_issue_in_db(issue, experience_needed, language, expected_time, technology_stack):
def is_issue_valid(issue):
"""
Checks if issue is valid for system or not.
Return True if valid else return false.
"""
parsed = parse_issue(issue['body'])
for item in parsed:
if not item:
return False # issue is not valid
print 'Issue with id ' + str(issue['id']) + ' is not valid for our system.'
return True # issue is valid

def store_issue_in_db(issue, region_queryset):
"""Stores issue in db"""
experience_needed, language, expected_time, technology_stack = parse_issue(issue['body'])
experience_needed = experience_needed.strip().lower()
language = language.strip().lower()
expected_time = expected_time.strip().lower()
Expand All @@ -120,6 +167,7 @@ def store_issue_in_db(issue, experience_needed, language, expected_time, technol
label_url=label['url'], label_color=label['color'])
label_instance.save()
issue_instance.issue_labels.add(label_instance)
issue_instance.regions.add(*region_queryset)

def delete_closed_issues(issue):
"""Delete issues that are closed on GitHub but present in our db"""
Expand Down
13 changes: 11 additions & 2 deletions core/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from rest_framework import serializers
from core.models import UserRepo, Issue, IssueLabel
from core.models import UserRepo, Issue, IssueLabel, Region


class UserRepoSerializer(serializers.ModelSerializer):
Expand All @@ -20,6 +20,15 @@ class Meta:
fields = ('label_id', 'label_name', 'label_color', 'label_url',)


class RegionSerializer(serializers.ModelSerializer):
"""
Serializer for `Region` Model.
"""
class Meta:
model = Region
fields = ('id','region_name', 'region_image',)


class IssueSerializer(serializers.ModelSerializer):
"""
Serializer for `Issue` Model.
Expand All @@ -30,4 +39,4 @@ class Meta:
model = Issue
fields = ('issue_id', 'title', 'experience_needed', 'expected_time',
'language', 'tech_stack', 'created_at', 'updated_at',
'issue_number', 'issue_labels', 'issue_url', 'issue_body')
'issue_number', 'issue_labels', 'issue_url', 'issue_body', 'regions',)
Loading