Skip to content

Commit

Permalink
members: Add Projects, Portal, Skills
Browse files Browse the repository at this point in the history
  • Loading branch information
harshithpabbati committed Jun 6, 2020
1 parent d4202f3 commit c2dcefc
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 15 deletions.
65 changes: 58 additions & 7 deletions members/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,55 @@ def mentees_display(self, obj):
mentees_display.verbose_name = 'Mentees'


@admin.register(Project)
class ProjectAdmin(admin.ModelAdmin):
fields = [
('name', 'slug'),
'members',
('tagline', 'topics'),
('published', 'cover'),
'detail',
'featured',
]
list_display = ('name', 'featured', 'published')
inlines = (ProjectLinkInline,)
select2 = select2_modelform(Project, attrs={'width': '250px'})
form = select2

def get_readonly_fields(self, request, obj=None):
fields = list(super().get_readonly_fields(request))
if not request.user.is_superuser:
fields.append('featured')
return fields

def get_queryset(self, request):
qs = super(ProjectAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(members=request.user)

def has_view_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None and request.user not in obj.members.all():
return False
return True

def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None and request.user not in obj.members.all():
return False
return True

def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None and request.user not in obj.members.all():
return False
return True


class WebspaceResource(resources.ModelResource):

class Meta:
Expand All @@ -248,18 +297,20 @@ class WebSpaceAdmin(ImportExportModelAdmin, ExportActionMixin, admin.ModelAdmin)

@admin.register(Portal)
class PortalAdmin(admin.ModelAdmin):
def has_module_permission(self, request):
return False
fields = ['name', ('icon', 'color')]


@admin.register(Organization)
class OrganizationAdmin(admin.ModelAdmin):
def has_module_permission(self, request):
return False
list_display = ('name', 'icon', 'color')


@admin.register(Skill)
class SkillAdmin(admin.ModelAdmin):
fields = ['name', ('type', 'icon')]

list_display = ('name', 'type')


@admin.register(Organization)
class OrganizationAdmin(admin.ModelAdmin):
def has_module_permission(self, request):
return False

Expand Down
16 changes: 16 additions & 0 deletions members/api/portal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import graphene


class PortalBasicObj(graphene.ObjectType):
name = graphene.String()
color = graphene.String()
icon = graphene.String()

def resolve_name(self, info):
return self['name']

def resolve_color(self, info):
return self['color']

def resolve_icon(self, info):
return self['icon']
2 changes: 1 addition & 1 deletion members/api/profile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import graphene
from hashlib import md5
from ..models import Profile, SocialProfile, Portal, Group
from ..models import Profile, SocialProfile, Portal, Group, Project
from graphql_jwt.decorators import login_required
from framework.api.APIException import APIException

Expand Down
26 changes: 26 additions & 0 deletions members/api/project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import graphene
from ..models import Project
from members.api.project_basic import ProjectBasicObj


class Query(object):
project = graphene.Field(
ProjectBasicObj,
slug=graphene.String(required=True)
)
projects = graphene.List(
ProjectBasicObj,
username=graphene.String()
)

def resolve_project(self, info, **kwargs):
slug = kwargs.get('slug')
if slug is not None:
return Project.objects.values().get(slug=slug)
raise Exception('Project Slug is a required parameter')

def resolve_projects(self, info, **kwargs):
username = kwargs.get('username')
if username is not None:
return Project.objects.values().filter(members__username=username)
return Project.objects.values().all()
47 changes: 47 additions & 0 deletions members/api/project_basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import graphene
from framework.api.user import UserBasicObj
from django.db.models import F
from members.api.skill import SkillBasicObj
from members.api.social_project import SocialProjectObj
from ..models import Project, SocialProject


class ProjectBasicObj(graphene.ObjectType):
name = graphene.String()
slug = graphene.String()
featured = graphene.Boolean()
tagline = graphene.String()
members = graphene.List(UserBasicObj)
membersCount = graphene.Int()
published = graphene.Date()
cover = graphene.String()
topics = graphene.List(SkillBasicObj)
detail = graphene.String()
links = graphene.List(SocialProjectObj)

def resolve_membersCount(self, info):
return Project.objects.annotate(
username=F('members__username')
).filter(id=self['id']).count()

@graphene.resolve_only_args
def resolve_members(self):
return Project.objects.values().annotate(
username=F('members__username'),
first_name=F('members__first_name'),
last_name=F('members__last_name'),
date_joined=F('members__date_joined'),
is_active=F('members__is_active'),
is_admin=F('members__is_superuser'),
).filter(id=self['id'])

@graphene.resolve_only_args
def resolve_topics(self):
return Project.objects.values().annotate(
name=F('topics__name'),
type=F('topics__type'),
icon=F('topics__icon')
).filter(id=self['id'])

def resolve_links(self, info):
return SocialProject.objects.values('link', 'portal').filter(project__id=self['id'])
16 changes: 16 additions & 0 deletions members/api/skill.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import graphene


class SkillBasicObj(graphene.ObjectType):
name = graphene.String()
type = graphene.String()
icon = graphene.String()

def resolve_name(self, info):
return self['name']

def resolve_type(self, info):
return self['type']

def resolve_icon(self, info):
return self['icon']
11 changes: 11 additions & 0 deletions members/api/social_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import graphene
from members.models import Portal
from members.api.portal import PortalBasicObj


class SocialProjectObj(graphene.ObjectType):
link = graphene.String()
portal = graphene.Field(PortalBasicObj)

def resolve_portal(self, info):
return Portal.objects.values().get(id=self['portal'])
28 changes: 27 additions & 1 deletion members/inlines.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,30 @@ def has_delete_permission(self, request, obj=None):
return True


__all__ = ['sp_inline', ]
class ProjectLinkInline(admin.TabularInline):
model = SocialProject
extra = 0

def has_add_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None and request.user not in obj.members.all():
return False
return True

def has_change_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None and request.user not in obj.members.all():
return False
return True

def has_delete_permission(self, request, obj=None):
if request.user.is_superuser:
return True
if obj is not None and request.user not in obj.members.all():
return False
return True


__all__ = ['sp_inline', 'ProjectLinkInline']
47 changes: 42 additions & 5 deletions members/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from imagekit.models import ProcessedImageField
from django.utils import timezone

SKILL_TYPES = (('T', 'Technical'), ('A', 'Arts'), ('S', 'Social'), ('P', 'Sports'), ('O', 'Others'))
SKILL_TYPES = (('Technical', 'Technical'), ('Arts', 'Arts'), ('Social', 'Social'), ('Sports', 'Sports'), ('Others', 'Others'))
LEAVE_TYPE = (('M', 'Health'), ('F', 'Family/Home'), ('T', 'Tiredness'), ('A', 'Academics/Duty'))
ROLE_TYPE = (('Member', 'Member'), ('Mentor', 'Mentor'))

Expand All @@ -23,9 +23,8 @@ def get_icon_path(self, filename):
return 'static/uploads/images/icons/' + filename

name = models.CharField(max_length=25)
type = models.CharField(choices=SKILL_TYPES, default='O', max_length=1)
type = models.CharField(choices=SKILL_TYPES, default='Others', max_length=10)
icon = ProcessedImageField(
default='./pages/static/pages/defaults/members-skill-icon-default.png',
blank=True,
verbose_name='Icon',
upload_to=get_icon_path,
Expand Down Expand Up @@ -172,7 +171,7 @@ def __str__(self):

class SocialProfile(models.Model):
portal = models.ForeignKey(Portal, on_delete=models.CASCADE, verbose_name='Portal Name')
link = models.URLField(max_length=150,verbose_name='Profile URL')
link = models.URLField(max_length=150, verbose_name='Profile URL')
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)

class Meta:
Expand Down Expand Up @@ -295,6 +294,42 @@ def __str__(self):
return self.name


class Project(models.Model):
def get_poster_path(self, filename):
ext = filename.split('.')[-1]
filename = "%s.%s" % (uuid.uuid4(), ext)
return 'static/uploads/images/projects/' + filename

name = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
featured = models.BooleanField(default=False)
tagline = models.CharField(max_length=100)
members = models.ManyToManyField(User, related_name='Project')
published = models.DateField(default=date.today)
cover = ProcessedImageField(default='', verbose_name='Project Poster', upload_to=get_poster_path, validators=[validate_file_size], **processed_image_field_specs)
topics = models.ManyToManyField(Skill, related_name='ProjectTopics', blank=True)
detail = RichTextField(verbose_name='Details', null=True)
links = models.ManyToManyField(Portal, related_name='ProjectLinks', through='SocialProject')

class Meta:
verbose_name_plural = "Projects"
verbose_name = "Project"

def __str__(self):
return self.name


class SocialProject(models.Model):
portal = models.ForeignKey(Portal, on_delete=models.CASCADE, related_name='project_links_portal',
verbose_name='Portal Name')
link = models.URLField(max_length=100, verbose_name='Project Page URL')
project = models.ForeignKey(Project, on_delete=models.CASCADE)

class Meta:
verbose_name_plural = "Project Profile Links"
verbose_name = "Project Profile Link"


__all__ = [
'LeaveRecord',
'MentorGroup',
Expand All @@ -308,5 +343,7 @@ def __str__(self):
'Skill',
'Portal',
'Organization',
'WebSpace'
'WebSpace',
'SocialProject',
'Project'
]
3 changes: 2 additions & 1 deletion members/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .api.group import Query as groupQuery
from .api.webspace import Query as webspaceQuery
from .api.leaverecord import Query as leaveRecordQuery
from .api.project import Query as projectsQuery
from graphql_jwt.decorators import login_required
#
# Mutations
Expand Down Expand Up @@ -82,6 +83,6 @@ class Mutation(object):
# Queries
#

class Query(profileQuery, groupQuery,leaveRecordQuery, webspaceQuery):
class Query(profileQuery, groupQuery, leaveRecordQuery, webspaceQuery, projectsQuery):
pass

0 comments on commit c2dcefc

Please sign in to comment.