From 0951b79c28e695b60db147ad39e83581d362dde2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Apr 2022 01:39:13 +0530 Subject: [PATCH 1/8] Use same border radius for next and prev buttons --- .../js/styles/views/projects/projectsStyles.js | 5 +++++ .../zubhub/src/views/projects/Projects.jsx | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js b/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js index 325dcc81e..6da85c81a 100644 --- a/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js +++ b/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js @@ -131,6 +131,11 @@ const styles = theme => ({ maxWidth: '2000px', width: '100%', }, + buttonGroupStyleAlternative: { + + padding: '7px 21px ' , + + }, floatRight: { float: 'right', }, diff --git a/zubhub_frontend/zubhub/src/views/projects/Projects.jsx b/zubhub_frontend/zubhub/src/views/projects/Projects.jsx index b76b2d80a..f5fbb7115 100644 --- a/zubhub_frontend/zubhub/src/views/projects/Projects.jsx +++ b/zubhub_frontend/zubhub/src/views/projects/Projects.jsx @@ -186,13 +186,15 @@ function Projects(props) { ))} - {prev_page ? ( } onClick={(e, page = prev_page.split('?')[1]) => { @@ -206,7 +208,9 @@ function Projects(props) { ) : null} {next_page ? ( } onClick={(e, page = next_page.split('?')[1]) => { @@ -218,7 +222,7 @@ function Projects(props) { {t('projects.next')} ) : null} - + ); From b1157634b7301b94776439865aa32683042c2de9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Apr 2022 18:56:31 +0530 Subject: [PATCH 2/8] refactor button border radius code --- .../src/assets/js/styles/views/projects/projectsStyles.js | 6 ++---- zubhub_frontend/zubhub/src/views/projects/Projects.jsx | 8 ++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js b/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js index 6da85c81a..b88f94ebc 100644 --- a/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js +++ b/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js @@ -132,10 +132,8 @@ const styles = theme => ({ width: '100%', }, buttonGroupStyleAlternative: { - - padding: '7px 21px ' , - - }, + padding: '7px 21px ' , + }, floatRight: { float: 'right', }, diff --git a/zubhub_frontend/zubhub/src/views/projects/Projects.jsx b/zubhub_frontend/zubhub/src/views/projects/Projects.jsx index f5fbb7115..df17aa4ca 100644 --- a/zubhub_frontend/zubhub/src/views/projects/Projects.jsx +++ b/zubhub_frontend/zubhub/src/views/projects/Projects.jsx @@ -192,9 +192,7 @@ function Projects(props) { > {prev_page ? ( } onClick={(e, page = prev_page.split('?')[1]) => { @@ -208,9 +206,7 @@ function Projects(props) { ) : null} {next_page ? ( } onClick={(e, page = next_page.split('?')[1]) => { From f1575dbe2ae377e012f5e0c7322d1d0b9efe95ad Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Apr 2022 00:46:52 +0530 Subject: [PATCH 3/8] reverted master --- .../styles/views/projects/projectsStyles.js | 5 -- .../zubhub/src/views/projects/Projects.jsx | 88 ------------------- 2 files changed, 93 deletions(-) diff --git a/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js b/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js index 4e96d9da4..912017a15 100644 --- a/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js +++ b/zubhub_frontend/zubhub/src/assets/js/styles/views/projects/projectsStyles.js @@ -132,13 +132,8 @@ const styles = theme => ({ width: '100%', }, buttonGroupStyleAlternative: { -<<<<<<< HEAD - padding: '7px 21px ' , - }, -======= padding: '7px 21px', }, ->>>>>>> 3221337cb6f9df2e256f5d7622563825634b3288 floatRight: { float: 'right', }, diff --git a/zubhub_frontend/zubhub/src/views/projects/Projects.jsx b/zubhub_frontend/zubhub/src/views/projects/Projects.jsx index dd3eac4ce..6a34871c8 100644 --- a/zubhub_frontend/zubhub/src/views/projects/Projects.jsx +++ b/zubhub_frontend/zubhub/src/views/projects/Projects.jsx @@ -272,96 +272,8 @@ function Projects(props) { -<<<<<<< HEAD - - ) : null} - - {staff_picks && - staff_picks.map(staff_pick => ( - - handleSetState( - updateStaffPicks(res, staff_pick.id, props, toast), - ) - } - {...props} - /> - ))} - - {staff_picks && staff_picks.length > 0 ? ( - - - {t('projects.allProjects')} - - - ) : null} - {projects.map(project => ( - - - handleSetState(updateProjects(res, props, toast)) - } - {...props} - /> - - ))} - -
- {prev_page ? ( - } - onClick={(e, page = prev_page.split('?')[1]) => { - handleSetState({ loading: true }); - handleSetState(fetchPage(page, props)); - }} - primaryButtonStyle - > - {t('projects.prev')} - - ) : null} - {next_page ? ( - } - onClick={(e, page = next_page.split('?')[1]) => { - handleSetState({ loading: true }); - handleSetState(fetchPage(page, props)); - }} - primaryButtonStyle - > - {t('projects.next')} - - ) : null} -
-
- -======= )} ->>>>>>> 3221337cb6f9df2e256f5d7622563825634b3288 ); } else { return ; From bdaa31f16ad34efcb86971f39ecc867f04ac855f Mon Sep 17 00:00:00 2001 From: Deepanshu039 Date: Mon, 15 Aug 2022 00:20:06 +0530 Subject: [PATCH 4/8] automated and custom badges on user's profile --- zubhub_backend/zubhub/creators/admin.py | 26 +++++- zubhub_backend/zubhub/creators/models.py | 19 +++- zubhub_backend/zubhub/creators/serializers.py | 17 +++- zubhub_backend/zubhub/creators/utils.py | 91 ++++++++++++++++++- zubhub_backend/zubhub/projects/views.py | 23 ++++- .../zubhub/public/locales/en/translation.json | 4 + .../js/styles/views/profile/profileStyles.js | 42 +++++++++ .../zubhub/src/views/profile/Profile.jsx | 69 ++++++++++---- 8 files changed, 259 insertions(+), 32 deletions(-) diff --git a/zubhub_backend/zubhub/creators/admin.py b/zubhub_backend/zubhub/creators/admin.py index 6a0ed5eaf..16c456513 100644 --- a/zubhub_backend/zubhub/creators/admin.py +++ b/zubhub_backend/zubhub/creators/admin.py @@ -2,7 +2,7 @@ from django.contrib.auth import get_user_model from django.contrib.auth.admin import UserAdmin from django.db import transaction -from .models import PhoneNumber, Setting, CreatorGroup, CreatorTag +from .models import PhoneNumber, Setting, CreatorGroup, CreatorTag, Badge from .utils import (send_group_invite_notification, custom_set_creatortags_queryset, @@ -21,6 +21,13 @@ def tags(obj): return ", ".join(tags) return None +def badges(obj): + if obj: + badges = [] + for badge in obj.badges.all(): + badges.append(badge.badge_title) + return ", ". join(badges) + return None def group_projects(obj): if obj: @@ -142,7 +149,10 @@ class CreatorAdmin(UserAdmin): ('followers',), ('followers_count',), ('following_count',), - ('projects_count',) + ('projects_count',), + ('total_likes',), + ('total_views',), + ('badges',), ) }), ('Important Dates', { @@ -160,9 +170,9 @@ class CreatorAdmin(UserAdmin): ) - list_display = UserAdmin.list_display + (tags, active,) + list_display = UserAdmin.list_display + (tags, active, badges) list_per_page = 50 ## paginate when more than 50 items - readonly_fields = UserAdmin.readonly_fields + ('avatar',) + ('followers_count',) + ('following_count',) + ('projects_count',) + readonly_fields = UserAdmin.readonly_fields + ('avatar',) + ('followers_count',) + ('following_count',) + ('projects_count',) + ('total_likes',) + ('total_views',) actions = ["activate_creators", "deactivate_creators"] ## disable the ability to add a new creator from the admin for now. @@ -211,10 +221,18 @@ def save_model(self, request, obj, form, change): super(CreatorAdmin, self).save_model( request, obj, form, change) +class BadgeAdmin(admin.ModelAdmin): + list_display = ["badge_title", "created_on", used_by] + search_fields = ["badge_title", "created_on"] + list_filter = ["created_on"] + list_per_page = 50 + def get_readonly_fields(self, request, obj=None): + return ["created_on"] admin.site.register(Creator, CreatorAdmin) admin.site.register(PhoneNumber, PhoneNumberAdmin) admin.site.register(Setting, SettingAdmin) admin.site.register(CreatorGroup, CreatorGroupAdmin) admin.site.register(CreatorTag, CreatorTagAdmin) +admin.site.register(Badge, BadgeAdmin) diff --git a/zubhub_backend/zubhub/creators/models.py b/zubhub_backend/zubhub/creators/models.py index ff9a644d1..b4c67dfef 100644 --- a/zubhub_backend/zubhub/creators/models.py +++ b/zubhub_backend/zubhub/creators/models.py @@ -13,6 +13,7 @@ from .tasks import update_creator_tag_index_task from .managers import PhoneNumberManager from .model_utils import user_phone +from django.db.models import Sum try: from allauth.account import app_settings as allauth_settings @@ -54,6 +55,12 @@ def save(self, *args, **kwargs): update_creator_tag_index_task.delay() super().save(*args, **kwargs) +class Badge(models.Model): + badge_title = models.CharField(blank=False, default="", max_length=225) + created_on = models.DateTimeField(default=timezone.now) + + def __str__(self): + return self.badge_title class Creator(AbstractUser): @@ -72,10 +79,20 @@ class Creator(AbstractUser): projects_count = models.IntegerField(blank=True, default=0) tags = models.ManyToManyField(CreatorTag, blank=True, related_name="creators") search_vector = SearchVectorField(null=True) - + badges = models.ManyToManyField(Badge, blank=True, related_name="creators" ) class Meta: indexes = (GinIndex(fields=["search_vector"]),) + @property + def total_likes(self): + total_likes= self.projects.aggregate(Sum("likes_count"))["likes_count__sum"] + return total_likes + + @property + def total_views(self): + total_views= self.projects.aggregate(Sum("views_count"))["views_count__sum"] + return total_views + def save(self, *args, **kwargs): if not self.avatar: self.avatar = 'https://robohash.org/{0}'.format(self.username) diff --git a/zubhub_backend/zubhub/creators/serializers.py b/zubhub_backend/zubhub/creators/serializers.py index b1b111447..53e4401e9 100644 --- a/zubhub_backend/zubhub/creators/serializers.py +++ b/zubhub_backend/zubhub/creators/serializers.py @@ -3,6 +3,8 @@ from django.utils.translation import ugettext_lazy as _ from rest_framework import serializers from django.contrib.auth import get_user_model + +from .admin import badges from .models import Location, PhoneNumber from allauth.account.models import EmailAddress from rest_auth.registration.serializers import RegisterSerializer @@ -25,14 +27,17 @@ class CreatorMinimalSerializer(serializers.ModelSerializer): tags = serializers.SlugRelatedField(slug_field="name", read_only=True, many=True) + badges = serializers.SlugRelatedField(slug_field="badge_title", + read_only=True, + many=True) class Meta: model = Creator fields = ('id', 'username', 'avatar', 'comments', 'bio', 'followers', - 'following_count', 'projects_count', 'members_count', 'tags') + 'following_count', 'projects_count', 'members_count', 'tags', 'badges') - read_only_fields = ["id", "projects_count", "following_count", "tags"] + read_only_fields = ["id", "projects_count", "following_count", "tags", "badges"] def get_members_count(self, obj): if hasattr(obj, "creatorgroup"): @@ -80,16 +85,18 @@ class CreatorSerializer(CreatorMinimalSerializer): tags = serializers.SlugRelatedField(slug_field="name", read_only=True, many=True) - + badges = serializers.SlugRelatedField(slug_field="badge_title", + read_only=True, + many=True) class Meta: model = Creator fields = ('id', 'username', 'email', 'phone', 'avatar', 'location', 'comments', 'dateOfBirth', 'bio', 'followers', - 'following_count', 'projects_count', 'members_count', 'tags') + 'following_count', 'projects_count', 'members_count', 'tags', 'badges') read_only_fields = [ - "id", "projects_count", "following_count", "dateOfBirth", "tags" + "id", "projects_count", "following_count", "dateOfBirth", "tags", "badges" ] def validate_email(self, email): diff --git a/zubhub_backend/zubhub/creators/utils.py b/zubhub_backend/zubhub/creators/utils.py index b551cf612..150445b10 100644 --- a/zubhub_backend/zubhub/creators/utils.py +++ b/zubhub_backend/zubhub/creators/utils.py @@ -11,8 +11,10 @@ from creators.models import Setting from notifications.models import Notification from notifications.utils import push_notification, get_notification_template_name -from creators.models import Creator +from creators.models import Creator, Badge +from projects.models import Project, Comment from django.template.loader import render_to_string +from django.db.models import Sum try: from allauth.account.adapter import get_adapter @@ -456,3 +458,90 @@ def send_notification(users: List[Creator], source: Creator, contexts, # EmailAddress.objects.create( # user=user, email=email, primary=False, verified=False # ) + +def set_badge_view_category(creator): + views_count= Project.objects.filter(creator= creator).aggregate(Sum(('views_count')))["views_count__sum"] + + List = ["Getting Famous", "Person of Interest", "Popular Projects", "Idea Factory"] + + creator.badges.remove(Badge.objects.get(badge_title = List[3])) + creator.badges.remove(Badge.objects.get(badge_title = List[2])) + creator.badges.remove(Badge.objects.get(badge_title = List[1])) + creator.badges.remove(Badge.objects.get(badge_title = List[0])) + + if(views_count > 100000): + creator.badges.add(Badge.objects.get(badge_title = List[3])) + + elif(views_count > 5000): + creator.badges.add(Badge.objects.get(badge_title = List[2])) + + elif(views_count > 100): + creator.badges.add(Badge.objects.get(badge_title = List[1])) + + elif(views_count > 10): + creator.badges.add(Badge.objects.get(badge_title = List[0])) + +def set_badge_like_category(creator): + likes_count= Project.objects.filter(creator= creator).aggregate(Sum(('likes_count')))["likes_count__sum"] + List= ["Interesting Projects", "Favourite Kid", "Captain Projects"] + + creator.badges.remove(Badge.objects.get(badge_title = List[2])) + creator.badges.remove(Badge.objects.get(badge_title = List[1])) + creator.badges.remove(Badge.objects.get(badge_title = List[0])) + + if(likes_count > 1000): + creator.badges.add(Badge.objects.get(badge_title = List[2])) + + elif(likes_count > 500): + creator.badges.add(Badge.objects.get(badge_title = List[1])) + + elif(likes_count > 10): + creator.badges.add(Badge.objects.get(badge_title = List[0])) + +def set_badge_comment_category(creator): + creator_id= creator.id + comments_count = Comment.objects.filter(creator__id= creator_id).count() + + List = ["Helping Hand", "Always Available", "Expert Advisor"] + + creator.badges.remove(Badge.objects.get(badge_title = List[2])) + creator.badges.remove(Badge.objects.get(badge_title = List[1])) + creator.badges.remove(Badge.objects.get(badge_title = List[0])) + + if(comments_count > 1000): + creator.badges.add(Badge.objects.get(badge_title = List[2])) + + elif(comments_count > 500): + creator.badges.add(Badge.objects.get(badge_title = List[1])) + + elif(comments_count > 10): + creator.badges.add(Badge.objects.get(badge_title = List[0])) + +def set_badge_project_category(creator, projects_count): + project_count_before_del = creator.projects_count + if(projects_count < project_count_before_del): + queryset=Project.objects.filter(creator= creator) + if( queryset.exists()): + set_badge_view_category(creator) + set_badge_like_category(creator) + set_badge_comment_category(creator) + + List = ["Hatchling", "Flying Bird", "Master of the sky", "Expert Builder"] + + creator.badges.remove(Badge.objects.get(badge_title = List[3])) + creator.badges.remove(Badge.objects.get(badge_title = List[2])) + creator.badges.remove(Badge.objects.get(badge_title = List[1])) + creator.badges.remove(Badge.objects.get(badge_title = List[0])) + + if(projects_count > 100): + creator.badges.add(Badge.objects.get(badge_title = List[3])) + + elif(projects_count > 50): + creator.badges.add(Badge.objects.get(badge_title = List[2])) + + elif(projects_count > 10): + creator.badges.add(Badge.objects.get(badge_title = List[1])) + + elif(projects_count > 0): + creator.badges.add(Badge.objects.get(badge_title = List[0])) + \ No newline at end of file diff --git a/zubhub_backend/zubhub/projects/views.py b/zubhub_backend/zubhub/projects/views.py index a6ffe2cdc..a6c9b46c4 100644 --- a/zubhub_backend/zubhub/projects/views.py +++ b/zubhub_backend/zubhub/projects/views.py @@ -16,10 +16,13 @@ SustainedRateThrottle, PostUserRateThrottle, GetUserRateThrottle, CustomUserRateThrottle) from .models import Project, Comment, StaffPick, Category, Tag, PublishingRule +from creators.models import Creator from .utils import (ProjectSearchCriteria, project_changed, detect_mentions, perform_project_search, can_view, get_published_projects_for_user) -from creators.utils import activity_notification, send_notification +from creators.utils import (activity_notification, send_notification, set_badge_like_category, + set_badge_project_category, set_badge_view_category, + set_badge_comment_category) from .serializers import (ProjectSerializer, ProjectListSerializer, CommentSerializer, CategorySerializer, TagSerializer, StaffPickSerializer) @@ -56,6 +59,10 @@ def perform_create(self, serializer): obj = serializer.save(creator=self.request.user) self.request.user.save() + creator = Creator.objects.get(id = obj.creator_id) + project_count= creator.projects_count + set_badge_project_category(creator, project_count) + if self.request.user.followers is not None: send_notification( list(self.request.user.followers.all()), @@ -130,9 +137,12 @@ class ProjectDeleteAPIView(DestroyAPIView): def delete(self, request, *args, **kwargs): project = self.get_object() + creator = Creator.objects.get(id = project.creator_id) if project: result = self.destroy(request, *args, **kwargs) + project_count_after_deletion = creator.projects_count -1 request.user.save() + set_badge_project_category(creator, project_count_after_deletion) return result @@ -272,7 +282,8 @@ def get_object(self): obj.views.add(self.request.user) obj.views_count += 1 obj.save() - + creator = Creator.objects.get(id = obj.creator_id) + set_badge_view_category(creator) return obj else: raise PermissionDenied( @@ -335,6 +346,9 @@ def get_object(self): f'/projects/{obj.pk}' ) + creator = Creator.objects.get(id = obj.creator_id) + set_badge_like_category(creator) + return obj else: raise PermissionDenied( @@ -446,6 +460,11 @@ def create(self, request, *args, **kwargs): result = self.get_object() + creator_str= self.request.user.username + creator_id= Creator.objects.get(username= creator_str).id + creator= Creator.objects.get(id = creator_id) + set_badge_comment_category(creator) + if result: detect_mentions({ "text": text, diff --git a/zubhub_frontend/zubhub/public/locales/en/translation.json b/zubhub_frontend/zubhub/public/locales/en/translation.json index 62a25fe56..19eb16153 100644 --- a/zubhub_frontend/zubhub/public/locales/en/translation.json +++ b/zubhub_frontend/zubhub/public/locales/en/translation.json @@ -552,6 +552,10 @@ "placeholder1": "Tell us more about you by clicking on the edit button at the top of the page 😀!", "placeholder2": "Tell us more about your group by clicking on the edit button at the top of the page 😀!" }, + "badge": { + "badges": "Badges", + "addBadges": "Seems like you have not created any project yet, add projects to your profile to get badges 😉!" + }, "projects": { "label": "Latest projects", "viewAll": "View all >>" diff --git a/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js b/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js index 5251e7926..c2b4238df 100644 --- a/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js +++ b/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js @@ -81,6 +81,48 @@ const styles = theme => ({ fontWeight: 900, fontSize: '1.5rem', }, + badgeTitleStyle: { + fontWeight: 900, + fontSize: '1.5rem', + color: '#00B8C4', + }, + aboutMeBadgeBox: { + display: 'flex', + [theme.breakpoints.down('900')]: { + display: 'block', + }, + }, + aboutMeBox: { + flexGrow: 1, + padding: '1em', + margin: '1em 0 0 1em', + [theme.breakpoints.down('900')]: { + margin: '1em', + }, + }, + badgeBox: { + backgroundColor: '#FFF7D4', + margin: '1em 1em 0 0', + padding: '1em', + width: '40%', + [theme.breakpoints.down('900')]: { + width: 'auto', + margin: '1em', + padding: '1em', + }, + }, + badgeContainerStyle: { + display: 'flex', + flexWrap: 'wrap', + }, + badgeStyle: { + backgroundColor: '#FFD11A', + borderRadius: '50px', + color: '#9F861E', + fontWeight: 600, + padding: '0 0.5em', + margin: '0.3em', + }, cardStyle: { border: 0, borderRadius: 15, diff --git a/zubhub_frontend/zubhub/src/views/profile/Profile.jsx b/zubhub_frontend/zubhub/src/views/profile/Profile.jsx index 1158a5edf..d896e42e6 100644 --- a/zubhub_frontend/zubhub/src/views/profile/Profile.jsx +++ b/zubhub_frontend/zubhub/src/views/profile/Profile.jsx @@ -82,6 +82,7 @@ function Profile(props) { dialog_error: null, more_anchor_el: null, drafts: [], + badge_tags: [], }); React.useEffect(() => { @@ -100,11 +101,12 @@ function Profile(props) { Promise.all(promises).then(values => { const obj = values[0]; const drafts = values[1] || {}; + const badges = obj.profile.badges; if (obj.profile) { parseComments(obj.profile.comments); } - handleSetState({ ...obj, ...drafts }); + handleSetState({ ...obj, ...drafts, badge_tags: badges }); }); }, []); @@ -124,6 +126,7 @@ function Profile(props) { dialog_error, more_anchor_el, drafts, + badge_tags, } = state; const more_menu_open = Boolean(more_anchor_el); @@ -292,25 +295,53 @@ function Profile(props) { - - - {!profile.members_count - ? t('profile.about.label1') - : t('profile.about.label2')} - - {profile.bio - ? profile.bio - : !profile.members_count - ? t('profile.about.placeholder1') - : t('profile.about.placeholder2')} - +
+ + + {!profile.members_count + ? t('profile.about.label1') + : t('profile.about.label2')} + + {profile.bio + ? profile.bio + : !profile.members_count + ? t('profile.about.placeholder1') + : t('profile.about.placeholder2')} + + + + {t('profile.badge.badges')} + + {!badge_tags.length > 0 ? ( + t('profile.badge.addBadges') + ) : ( + + {badge_tags.map(tag => ( + + {tag} + + ))} + + )} + +
{profile.projects_count > 0 || drafts.length > 0 ? ( username === props.auth.username ? ( Date: Mon, 15 Aug 2022 23:17:10 +0530 Subject: [PATCH 5/8] initially populate badges table --- zubhub_backend/compose/web/dev/start | 1 + zubhub_backend/compose/web/prod/start | 1 + .../management/commands/initial_badges.txt | 14 ++++++++++++++ .../commands/populate_initial_badges.py | 17 +++++++++++++++++ 4 files changed, 33 insertions(+) create mode 100644 zubhub_backend/zubhub/creators/management/commands/initial_badges.txt create mode 100644 zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py diff --git a/zubhub_backend/compose/web/dev/start b/zubhub_backend/compose/web/dev/start index cde5bcd3d..eefac2be7 100644 --- a/zubhub_backend/compose/web/dev/start +++ b/zubhub_backend/compose/web/dev/start @@ -19,6 +19,7 @@ python /zubhub_backend/zubhub/manage.py createcachetable python /zubhub_backend/zubhub/manage.py populate_countries python /zubhub_backend/zubhub/manage.py populate_categories python /zubhub_backend/zubhub/manage.py populate_initial_creator_tags +python /zubhub_backend/zubhub/manage.py populate_initial_badges exec /usr/local/bin/gunicorn zubhub.wsgi --reload --threads=3 --timeout 155 --bind 0.0.0.0:8000 \ --access-logfile - --error-logfile - --chdir /zubhub_backend/zubhub diff --git a/zubhub_backend/compose/web/prod/start b/zubhub_backend/compose/web/prod/start index 982c6e615..89995e113 100644 --- a/zubhub_backend/compose/web/prod/start +++ b/zubhub_backend/compose/web/prod/start @@ -15,6 +15,7 @@ python /zubhub_backend/zubhub/manage.py createcachetable python /zubhub_backend/zubhub/manage.py populate_countries python /zubhub_backend/zubhub/manage.py populate_initial_creator_tags python /zubhub_backend/zubhub/manage.py populate_categories +python /zubhub_backend/zubhub/manage.py populate_initial_badges exec /usr/local/bin/gunicorn zubhub.wsgi --threads=3 --timeout 155 --bind 0.0.0.0:8000 \ --access-logfile - --error-logfile - --chdir /zubhub_backend/zubhub diff --git a/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt b/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt new file mode 100644 index 000000000..5ff2b5708 --- /dev/null +++ b/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt @@ -0,0 +1,14 @@ +Getting Famous +Person of Interest +Popular Projects +Idea Factory +Interesting Projects +Favourite Kid +Captain Projects +Helping Hand +Always Available +Expert Advisor +Hatchling +Flying Bird +Master of the sky +Expert Builder \ No newline at end of file diff --git a/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py b/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py new file mode 100644 index 000000000..741f0c996 --- /dev/null +++ b/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py @@ -0,0 +1,17 @@ +from creators.models import Badge +from django.core.management.base import BaseCommand + + +class Command(BaseCommand): + help = 'Populate Badge table with initial badges' + + def handle(self, *args, **kwargs): + if Badge.objects.all().count() < 1: + with open("./zubhub/creators/management/commands/initial_badges.txt", "r") as badges: + badges = badges.readlines() + for badge in badges: + self.stdout.write(badge) + Badge.objects.create(badge_title = badge.split("\n")[0]) + self.stdout.write(self.style.SUCCESS('The Badge table has been successfully populated!')) + else: + self.stdout.write(self.style.NOTICE('The Badge table is already populated')) From 4ff73e1a132f6b1a845e549f87ca1c1df5a11190 Mon Sep 17 00:00:00 2001 From: Deepanshu039 Date: Tue, 16 Aug 2022 20:32:36 +0530 Subject: [PATCH 6/8] #1 patch after review --- .../commands/populate_initial_badges.py | 2 +- zubhub_backend/zubhub/creators/utils.py | 116 ++++++++---------- 2 files changed, 51 insertions(+), 67 deletions(-) diff --git a/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py b/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py index 741f0c996..50a8aa848 100644 --- a/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py +++ b/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py @@ -6,7 +6,7 @@ class Command(BaseCommand): help = 'Populate Badge table with initial badges' def handle(self, *args, **kwargs): - if Badge.objects.all().count() < 1: + if Badge.objects.all().count() == 0: with open("./zubhub/creators/management/commands/initial_badges.txt", "r") as badges: badges = badges.readlines() for badge in badges: diff --git a/zubhub_backend/zubhub/creators/utils.py b/zubhub_backend/zubhub/creators/utils.py index 150445b10..18d906da0 100644 --- a/zubhub_backend/zubhub/creators/utils.py +++ b/zubhub_backend/zubhub/creators/utils.py @@ -459,89 +459,73 @@ def send_notification(users: List[Creator], source: Creator, contexts, # user=user, email=email, primary=False, verified=False # ) -def set_badge_view_category(creator): - views_count= Project.objects.filter(creator= creator).aggregate(Sum(('views_count')))["views_count__sum"] - - List = ["Getting Famous", "Person of Interest", "Popular Projects", "Idea Factory"] - creator.badges.remove(Badge.objects.get(badge_title = List[3])) - creator.badges.remove(Badge.objects.get(badge_title = List[2])) - creator.badges.remove(Badge.objects.get(badge_title = List[1])) - creator.badges.remove(Badge.objects.get(badge_title = List[0])) - - if(views_count > 100000): - creator.badges.add(Badge.objects.get(badge_title = List[3])) +def remove_initial_titles(creator, titles): + for title in titles: + creator.badges.remove(Badge.objects.get(badge_title = title)) - elif(views_count > 5000): - creator.badges.add(Badge.objects.get(badge_title = List[2])) +def add_titles(creator, count, dict): + for badge, value in dict.items(): + if count > value: + creator.badges.add(Badge.objects.get(badge_title = badge)) + break - elif(views_count > 100): - creator.badges.add(Badge.objects.get(badge_title = List[1])) - - elif(views_count > 10): - creator.badges.add(Badge.objects.get(badge_title = List[0])) +def set_badge_view_category(creator): + views_count = (Project.objects.filter(creator= creator).aggregate( + Sum(('views_count')))["views_count__sum"]) + + badge_dict = { + "Idea Factory": 100000, + "Popular Projects": 5000, + "Person of Interest": 100, + "Getting Famous": 10 + } + + remove_initial_titles(creator, badge_dict.keys()) + add_titles(creator, views_count, badge_dict) def set_badge_like_category(creator): - likes_count= Project.objects.filter(creator= creator).aggregate(Sum(('likes_count')))["likes_count__sum"] - List= ["Interesting Projects", "Favourite Kid", "Captain Projects"] - - creator.badges.remove(Badge.objects.get(badge_title = List[2])) - creator.badges.remove(Badge.objects.get(badge_title = List[1])) - creator.badges.remove(Badge.objects.get(badge_title = List[0])) - - if(likes_count > 1000): - creator.badges.add(Badge.objects.get(badge_title = List[2])) - - elif(likes_count > 500): - creator.badges.add(Badge.objects.get(badge_title = List[1])) - - elif(likes_count > 10): - creator.badges.add(Badge.objects.get(badge_title = List[0])) + likes_count = (Project.objects.filter(creator= creator) + .aggregate(Sum(('likes_count')))["likes_count__sum"]) + + badge_dict = { + "Captain Projects": 1000, + "Favourite Kid": 500, + "Interesting Projects": 10 + } + + remove_initial_titles(creator, badge_dict.keys()) + add_titles(creator, likes_count, badge_dict) def set_badge_comment_category(creator): - creator_id= creator.id + creator_id = creator.id comments_count = Comment.objects.filter(creator__id= creator_id).count() - List = ["Helping Hand", "Always Available", "Expert Advisor"] + badge_dict = { + "Expert Advisor": 1000, + "Always Available": 500, + "Helping Hand": 10 + } - creator.badges.remove(Badge.objects.get(badge_title = List[2])) - creator.badges.remove(Badge.objects.get(badge_title = List[1])) - creator.badges.remove(Badge.objects.get(badge_title = List[0])) - - if(comments_count > 1000): - creator.badges.add(Badge.objects.get(badge_title = List[2])) - - elif(comments_count > 500): - creator.badges.add(Badge.objects.get(badge_title = List[1])) - - elif(comments_count > 10): - creator.badges.add(Badge.objects.get(badge_title = List[0])) + remove_initial_titles(creator, badge_dict.keys()) + add_titles(creator, comments_count, badge_dict) def set_badge_project_category(creator, projects_count): project_count_before_del = creator.projects_count + if(projects_count < project_count_before_del): - queryset=Project.objects.filter(creator= creator) + queryset = Project.objects.filter(creator= creator) if( queryset.exists()): set_badge_view_category(creator) set_badge_like_category(creator) set_badge_comment_category(creator) - List = ["Hatchling", "Flying Bird", "Master of the sky", "Expert Builder"] - - creator.badges.remove(Badge.objects.get(badge_title = List[3])) - creator.badges.remove(Badge.objects.get(badge_title = List[2])) - creator.badges.remove(Badge.objects.get(badge_title = List[1])) - creator.badges.remove(Badge.objects.get(badge_title = List[0])) - - if(projects_count > 100): - creator.badges.add(Badge.objects.get(badge_title = List[3])) - - elif(projects_count > 50): - creator.badges.add(Badge.objects.get(badge_title = List[2])) - - elif(projects_count > 10): - creator.badges.add(Badge.objects.get(badge_title = List[1])) + badge_dict = { + "Expert Builder": 100, + "Master of the sky": 50, + "Flying Bird": 10, + "Hatchling": 0 + } - elif(projects_count > 0): - creator.badges.add(Badge.objects.get(badge_title = List[0])) - \ No newline at end of file + remove_initial_titles(creator, badge_dict.keys()) + add_titles(creator, projects_count, badge_dict) From 21667c9b48207294a05b3c76e9ddf977a19bdfd8 Mon Sep 17 00:00:00 2001 From: Deepanshu039 Date: Tue, 23 Aug 2022 00:27:07 +0530 Subject: [PATCH 7/8] feature: change original badge title from admin panel --- zubhub_backend/zubhub/creators/admin.py | 16 +++-- .../management/commands/initial_badges.txt | 28 ++++---- .../commands/populate_initial_badges.py | 9 ++- zubhub_backend/zubhub/creators/models.py | 11 ++- zubhub_backend/zubhub/creators/utils.py | 67 +++++++------------ .../js/styles/views/profile/profileStyles.js | 4 ++ 6 files changed, 70 insertions(+), 65 deletions(-) diff --git a/zubhub_backend/zubhub/creators/admin.py b/zubhub_backend/zubhub/creators/admin.py index 16c456513..58f6fe097 100644 --- a/zubhub_backend/zubhub/creators/admin.py +++ b/zubhub_backend/zubhub/creators/admin.py @@ -222,13 +222,17 @@ def save_model(self, request, obj, form, change): request, obj, form, change) class BadgeAdmin(admin.ModelAdmin): - list_display = ["badge_title", "created_on", used_by] - search_fields = ["badge_title", "created_on"] - list_filter = ["created_on"] - list_per_page = 50 + list_display= ["badge_title", "type", "threshold_value", "id", used_by] + fields = ('type', 'badge_title', 'threshold_value', 'id',) + readonly_fields= ( 'id', 'type',) - def get_readonly_fields(self, request, obj=None): - return ["created_on"] + def has_delete_permission(self, request, obj=None): + # Disable delete + return False + + # disable the ability to add a new badge from the admin for now. + def has_add_permission(self, request, obj=None): + return False admin.site.register(Creator, CreatorAdmin) admin.site.register(PhoneNumber, PhoneNumberAdmin) diff --git a/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt b/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt index 5ff2b5708..40b1a8461 100644 --- a/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt +++ b/zubhub_backend/zubhub/creators/management/commands/initial_badges.txt @@ -1,14 +1,14 @@ -Getting Famous -Person of Interest -Popular Projects -Idea Factory -Interesting Projects -Favourite Kid -Captain Projects -Helping Hand -Always Available -Expert Advisor -Hatchling -Flying Bird -Master of the sky -Expert Builder \ No newline at end of file +Hatchling:0:1 +Flying Bird:10:1 +Master of the sky:50:1 +Expert Builder:100:1 +Helping Hand:10:2 +Always Available:500:2 +Expert Advisor:1000:2 +Getting Famous:10:3 +Person of Interest:100:3 +Popular Projects:5000:3 +Idea Factory:100000:3 +Interesting Projects:10:4 +Favourite Kid:500:4 +Captain Projects:1000:4 diff --git a/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py b/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py index 50a8aa848..ad67935f4 100644 --- a/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py +++ b/zubhub_backend/zubhub/creators/management/commands/populate_initial_badges.py @@ -10,8 +10,13 @@ def handle(self, *args, **kwargs): with open("./zubhub/creators/management/commands/initial_badges.txt", "r") as badges: badges = badges.readlines() for badge in badges: - self.stdout.write(badge) - Badge.objects.create(badge_title = badge.split("\n")[0]) + remove_col=badge.split(':') + remove_col[2]=remove_col[2].split('\n')[0] + title=remove_col[0] + value=int(remove_col[1]) + category_type=int(remove_col[2]) + Badge.objects.create(badge_title = title, threshold_value=value, + type= category_type ) self.stdout.write(self.style.SUCCESS('The Badge table has been successfully populated!')) else: self.stdout.write(self.style.NOTICE('The Badge table is already populated')) diff --git a/zubhub_backend/zubhub/creators/models.py b/zubhub_backend/zubhub/creators/models.py index b4c67dfef..4ddac140e 100644 --- a/zubhub_backend/zubhub/creators/models.py +++ b/zubhub_backend/zubhub/creators/models.py @@ -56,8 +56,17 @@ def save(self, *args, **kwargs): super().save(*args, **kwargs) class Badge(models.Model): + class Type(models.IntegerChoices): + PROJECTS = 1 + COMMENTS = 2 + VIEWS = 3 + LIKES = 4 + + type = models.PositiveSmallIntegerField( + choices=Type.choices, + ) + threshold_value = models.IntegerField(blank=True, default=0) badge_title = models.CharField(blank=False, default="", max_length=225) - created_on = models.DateTimeField(default=timezone.now) def __str__(self): return self.badge_title diff --git a/zubhub_backend/zubhub/creators/utils.py b/zubhub_backend/zubhub/creators/utils.py index 18d906da0..5aea316aa 100644 --- a/zubhub_backend/zubhub/creators/utils.py +++ b/zubhub_backend/zubhub/creators/utils.py @@ -460,55 +460,43 @@ def send_notification(users: List[Creator], source: Creator, contexts, # ) -def remove_initial_titles(creator, titles): - for title in titles: - creator.badges.remove(Badge.objects.get(badge_title = title)) +def remove_initial_titles(creator, ids): + for id in ids: + creator.badges.remove(Badge.objects.get(id= id)) -def add_titles(creator, count, dict): - for badge, value in dict.items(): +def add_titles(creator, count, ids): + for id in ids: + value = Badge.objects.get(id= id).threshold_value if count > value: - creator.badges.add(Badge.objects.get(badge_title = badge)) + creator.badges.add(Badge.objects.get(id = id)) break -def set_badge_view_category(creator): - views_count = (Project.objects.filter(creator= creator).aggregate( - Sum(('views_count')))["views_count__sum"]) - - badge_dict = { - "Idea Factory": 100000, - "Popular Projects": 5000, - "Person of Interest": 100, - "Getting Famous": 10 - } - - remove_initial_titles(creator, badge_dict.keys()) - add_titles(creator, views_count, badge_dict) - def set_badge_like_category(creator): likes_count = (Project.objects.filter(creator= creator) .aggregate(Sum(('likes_count')))["likes_count__sum"]) - badge_dict = { - "Captain Projects": 1000, - "Favourite Kid": 500, - "Interesting Projects": 10 - } + badge_ids = [14, 13, 12] + + remove_initial_titles(creator, badge_ids) + add_titles(creator, likes_count, badge_ids) + +def set_badge_view_category(creator): + views_count = (Project.objects.filter(creator= creator).aggregate( + Sum(('views_count')))["views_count__sum"]) + + badge_ids = [11, 10, 9, 8] - remove_initial_titles(creator, badge_dict.keys()) - add_titles(creator, likes_count, badge_dict) + remove_initial_titles(creator, badge_ids) + add_titles(creator, views_count, badge_ids) def set_badge_comment_category(creator): creator_id = creator.id comments_count = Comment.objects.filter(creator__id= creator_id).count() - badge_dict = { - "Expert Advisor": 1000, - "Always Available": 500, - "Helping Hand": 10 - } + badge_ids = [7, 6, 5] - remove_initial_titles(creator, badge_dict.keys()) - add_titles(creator, comments_count, badge_dict) + remove_initial_titles(creator, badge_ids) + add_titles(creator, comments_count, badge_ids) def set_badge_project_category(creator, projects_count): project_count_before_del = creator.projects_count @@ -520,12 +508,7 @@ def set_badge_project_category(creator, projects_count): set_badge_like_category(creator) set_badge_comment_category(creator) - badge_dict = { - "Expert Builder": 100, - "Master of the sky": 50, - "Flying Bird": 10, - "Hatchling": 0 - } + badge_ids = [4, 3, 2, 1] - remove_initial_titles(creator, badge_dict.keys()) - add_titles(creator, projects_count, badge_dict) + remove_initial_titles(creator, badge_ids) + add_titles(creator, projects_count, badge_ids) diff --git a/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js b/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js index c2b4238df..43dba4958 100644 --- a/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js +++ b/zubhub_frontend/zubhub/src/assets/js/styles/views/profile/profileStyles.js @@ -96,8 +96,10 @@ const styles = theme => ({ flexGrow: 1, padding: '1em', margin: '1em 0 0 1em', + borderRadius: '4px 0 0 4px', [theme.breakpoints.down('900')]: { margin: '1em', + borderRadius: '4px', }, }, badgeBox: { @@ -105,10 +107,12 @@ const styles = theme => ({ margin: '1em 1em 0 0', padding: '1em', width: '40%', + borderRadius: '0 4px 4px 0', [theme.breakpoints.down('900')]: { width: 'auto', margin: '1em', padding: '1em', + borderRadius: '4px', }, }, badgeContainerStyle: { From 3d075753ef3dc28cd7736a6b551e9172306fcc57 Mon Sep 17 00:00:00 2001 From: Deepanshu039 Date: Mon, 5 Sep 2022 18:46:18 +0530 Subject: [PATCH 8/8] migration file of badge table --- .../migrations/0009_auto_20220822_0842.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 zubhub_backend/zubhub/creators/migrations/0009_auto_20220822_0842.py diff --git a/zubhub_backend/zubhub/creators/migrations/0009_auto_20220822_0842.py b/zubhub_backend/zubhub/creators/migrations/0009_auto_20220822_0842.py new file mode 100644 index 000000000..c4fcebe44 --- /dev/null +++ b/zubhub_backend/zubhub/creators/migrations/0009_auto_20220822_0842.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2 on 2022-08-22 08:42 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('creators', '0008_auto_20220222_0254'), + ] + + operations = [ + migrations.CreateModel( + name='Badge', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('type', models.PositiveSmallIntegerField(choices=[(1, 'Projects'), (2, 'Comments'), (3, 'Views'), (4, 'Likes')])), + ('threshold_value', models.IntegerField(blank=True, default=0)), + ('badge_title', models.CharField(default='', max_length=225)), + ], + ), + migrations.AlterField( + model_name='setting', + name='contact', + field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'WHATSAPP'), (2, 'EMAIL'), (3, 'SMS'), (4, 'WEB')], default=3, null=True), + ), + migrations.AddField( + model_name='creator', + name='badges', + field=models.ManyToManyField(blank=True, related_name='creators', to='creators.Badge'), + ), + ]