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

Edit achievements #437

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4c58a85
edit_achievements
AleksandrKosmylev Jun 15, 2024
1dd4735
edit_achievements_addition
AleksandrKosmylev Jun 15, 2024
be4c7d1
Added common statistics in footer
AleksandrKosmylev Jun 18, 2024
df93d1a
Merge branch 'Hexlet:main' into edit_achievements
AleksandrKosmylev Jun 18, 2024
a68db2e
add test for contributors:contributor_achievements and minor linter fix
AleksandrKosmylev Jun 19, 2024
3b4a8fa
Merge remote-tracking branch 'origin/edit_achievements' into edit_ach…
AleksandrKosmylev Jun 20, 2024
883c439
Add helper function to calc achivements percentage
AleksandrKosmylev Jun 30, 2024
c43a264
fix inline styles
AleksandrKosmylev Jun 30, 2024
8ddf4bb
update common and personal stat
AleksandrKosmylev Aug 18, 2024
23abc8c
resolve conflict
AleksandrKosmylev Oct 6, 2024
eb11834
resolve wps
AleksandrKosmylev Oct 6, 2024
3849707
resolve wps editon 1
AleksandrKosmylev Oct 6, 2024
f9c26ed
resolve wps editon 2
AleksandrKosmylev Oct 6, 2024
fa49f24
resolve wps editon 3
AleksandrKosmylev Oct 6, 2024
a068fe8
resolve wps editon 4
AleksandrKosmylev Oct 6, 2024
439944b
resolve wps editon 6
AleksandrKosmylev Oct 6, 2024
be1689c
resolve wps editon 7
AleksandrKosmylev Oct 6, 2024
023b76d
Merge branch 'Hexlet:main' into edit_achievements
AleksandrKosmylev Oct 6, 2024
91289fb
fix linter notifications
AleksandrKosmylev Oct 27, 2024
130b868
fix linter notifications
AleksandrKosmylev Oct 27, 2024
4b3067c
refactor contributor_achievements.py
AleksandrKosmylev Nov 17, 2024
8c312f8
delete sum brackets
AleksandrKosmylev Nov 17, 2024
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
4 changes: 2 additions & 2 deletions auth/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ def setUp(self):
"""Create a test client."""
self.client: Client = Client()

@patch('contributors.utils.github_lib.get_access_token', lambda *args: None) # noqa: E501
@patch('contributors.utils.github_lib.get_data_of_token_holder', lambda *args: None) # noqa: E501
@patch('contributors.utils.github_lib.get_access_token', lambda *args: None)
@patch('contributors.utils.github_lib.get_data_of_token_holder', lambda *args: None)
@patch('auth.backends.GitHubBackend.authenticate', lambda *args: None)
def test_github_auth_view(self):
"""Send a request without authentication and check the response."""
Expand Down
13 changes: 13 additions & 0 deletions contributors/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,16 @@
from contributors.models.organization import Organization
from contributors.models.project import Project
from contributors.models.repository import Repository

__all__ = [
'CommonFields',
'CommitStats',
'Contribution',
'ContributionLabel',
'Contributor',
'IssueInfo',
'Label',
'Organization',
'Project',
'Repository',
]
10 changes: 10 additions & 0 deletions contributors/templatetags/contrib_extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,13 @@ def get_canonical_url(context):
if request:
return request.build_absolute_uri(request.path)
return ''


@register.simple_tag
def calc_percent_achievement(numerator, denominator):
"""Get contributor statistics and required quantity."""
if numerator is not None:
if numerator / denominator > 1:
return 100.0
return numerator / denominator * 100
return 0
10 changes: 10 additions & 0 deletions contributors/tests/test_contributors_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
EXPECTED_CONTRIBUTORS_ISSUE_COUNT = 2
EXPECTED_CONTRIBUTORS_PR_COUNT = 2

TEST_CONTRIBUTORS = ["mintough57", "kinganduld", "indecing", "pilly1964", "suir1948"]


class TestContributorDetailView(TestCase):
"""Test the methods for the contributor's details view."""
Expand Down Expand Up @@ -149,3 +151,11 @@ def test_get_context_data(self):
self.assertEqual(response.context['contributors_issues_gte_1'], 2)
self.assertEqual(response.context['contributors_comments_gte_1'], 0)
self.assertEqual(response.context['contributors_editions_gte_1'], 0)

def test_get_context_data_contributor(self):
for contributor in TEST_CONTRIBUTORS:
response = self.client.get(reverse(
'contributors:contributor_achievements',
args=[contributor]),
)
self.assertEqual(response.status_code, HTTPStatus.OK)
5 changes: 5 additions & 0 deletions contributors/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@
views.achievements.AchievementListView.as_view(),
name='achievements',
),
path(
'contributor_achievements/<slug:slug>',
views.contributor_achievements.ContributorAchievementListView.as_view(),
name='contributor_achievements',
),
path(
'landing/',
views.landing.LandingView.as_view(),
Expand Down
2 changes: 1 addition & 1 deletion contributors/utils/github_lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.conf import settings

GITHUB_API_URL = 'https://api.github.com'
GITHUB_TOKEN_PROVIDER_URL = 'https://github.com/login/oauth/access_token' # noqa: E501,S105
GITHUB_TOKEN_PROVIDER_URL = 'https://github.com/login/oauth/access_token' # noqa: S105


def merge_dicts(*dicts):
Expand Down
1 change: 1 addition & 0 deletions contributors/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
about,
achievements,
config,
contributor_achievements,
contributor_compare,
filters,
home,
Expand Down
234 changes: 234 additions & 0 deletions contributors/views/contributor_achievements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
from django.db import models
from django.db.models.functions import Coalesce
from django.views import generic

from contributors.models import Contributor, Repository

ID = 'id'


class ContributorAchievementListView(generic.ListView):
"""Achievement list."""

template_name = 'contributor/contributor_achievements_list.html'
model = Contributor
contributors = Contributor.objects.with_contributions()

pull_request_ranges_for_achievements = [1, 10, 25, 50, 100]
commit_ranges_for_achievements = [1, 25, 50, 100, 200]
issue_ranges_for_achievements = [1, 5, 10, 25, 50]
comment_ranges_for_achievements = [1, 25, 50, 100, 200]
edition_ranges_for_achievements = [1, 100, 250, 500, 1000]

def get_context_data(self, **kwargs):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я бы разделил метод на несколько. Сейчас это огромная стена кода. Выделите подметоды, сделайте их приватными (_method_name), разделите логику.

"""Add context data for achievement list."""
self.contributors_amount = Contributor.objects.count()
context = super().get_context_data(**kwargs)
contributors = Contributor.objects.with_contributions()
current_contributor = (
Contributor.objects.get(login=self.kwargs['slug'])
)

repositories = Repository.objects.select_related(
'organization',
).filter(
is_visible=True,
contribution__contributor=current_contributor,
).annotate(
commits=models.Count('id', filter=models.Q(contribution__type='cit')),
additions=Coalesce(models.Sum('contribution__stats__additions'), 0),
deletions=Coalesce(models.Sum('contribution__stats__deletions'), 0),
pull_requests=models.Count(
'contribution', filter=models.Q(contribution__type='pr'),
),
issues=models.Count(
'contribution',
filter=models.Q(contribution__type='iss')),
comments=models.Count(
'contribution',
filter=models.Q(contribution__type='cnt')),
).order_by('organization', 'name')

contributions = repositories.values().aggregate(
contributor_deletions=models.Sum('deletions'),
contributor_additions=models.Sum('additions'),
contributor_commits=models.Sum('commits'),
contributor_pull_requests=models.Sum('pull_requests'),
contributor_issues=models.Sum('issues'),
contributor_comments=models.Sum('comments'),
)

finished = []
unfinished = []

context['commits'] = contributions['contributor_commits']
context['pull_requests'] = contributions['contributor_pull_requests']
context['issues'] = contributions['contributor_issues']
context['comments'] = contributions['contributor_comments']
editions = sum([
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для sum() не надо создавать список внутри. Нужно убрать квадратные скобки. И ниже в другом sum тоже

0 if edit is None else edit
for edit in [
contributions['contributor_additions'],
contributions['contributor_deletions'],
]
])
context['total_editions'] = editions

context['total_actions'] = sum([
0 if action is None else action
for action in [
contributions['contributor_commits'],
contributions['contributor_pull_requests'],
contributions['contributor_issues'],
contributions['contributor_comments'],
contributions['contributor_additions'],
contributions['contributor_deletions'],
]
])

context['pull_request_ranges_for_achievements'] = (
self.pull_request_ranges_for_achievements
)
context['current_contributor'] = current_contributor
context['contributors_amount'] = self.contributors_amount
context['contributors_with_any_contribution'] = {
'stat': (
contributors.filter(contribution_amount__gte=1).count()
),
'acomplished': True,
}

# Pull request achievements:
for pr_num in self.pull_request_ranges_for_achievements:
context[f'contributors_pull_requests_gte_{pr_num}'] = {
'stat': (
contributors.filter(pull_requests__gte=pr_num).count()
),
'acomplished': True,
}
a_data = {
'img': f'images/achievments_icons/pull_requests-{pr_num}.svg',
'name': f'Pull requests (equal to or more than {pr_num})',
'description':
f"Make pull requests in amount of equal to or more than {pr_num}",
'accomplished': 'yes',
}
if pr_num > (
0 if contributions['contributor_pull_requests'] is None
else contributions['contributor_pull_requests']
):
unfinished.append(a_data)
context[(f'contributors_pull_requests_gte_'
f'{pr_num}')]['acomplished'] = False
else:
finished.append(a_data)

# Commit achievements:
for commit_num in self.commit_ranges_for_achievements:
context[f'contributors_commits_gte_{commit_num}'] = {
'stat': (
contributors.filter(commits__gte=commit_num).count()
),
'acomplished': True,
}
a_data = {
'img': f'images/achievments_icons/commits-{commit_num}.svg',
'name': f'Commits (equal to or more than {commit_num})',
'description': f"Make commits in amount of equal to or more than "
f"{commit_num}",
}
if commit_num > (
0 if contributions['contributor_commits'] is None
else contributions['contributor_commits']
):
unfinished.append(a_data)
context[f'contributors_commits_gte_{commit_num}']['acomplished'] = False
else:
finished.append(a_data)

# Issue achievements:
for issue_num in self.issue_ranges_for_achievements:
context[f'contributors_issues_gte_{issue_num}'] = {
'stat': (
contributors.filter(issues__gte=issue_num).count()
),
'acomplished': True,
}
a_data = {
'img': f'images/achievments_icons/issues-{issue_num}.svg',
'name': f'Issues (equal to or more than {issue_num})',
'description': f"Make issues in amount of equal to or more than "
f"{issue_num}",
}
if issue_num > (
0 if contributions['contributor_issues'] is None
else contributions['contributor_issues']
):
unfinished.append(a_data)
context[f'contributors_issues_gte_{issue_num}']['acomplished'] = False
else:
finished.append(a_data)

# Comment achievements:
for comment_num in self.comment_ranges_for_achievements:
context[f'contributors_comments_gte_{comment_num}'] = {
'stat': (
contributors.filter(comments__gte=comment_num).count()
),
'acomplished': True,
}
a_data = {
'img': f'images/achievments_icons/comments-{comment_num}.svg',
'name': f'Comments (equal to or more than {comment_num})',
'description': f"Make comments in amount of equal to or more than "
f"{comment_num}",
}
if comment_num > (
0 if contributions['contributor_comments'] is None
else contributions['contributor_comments']
):
unfinished.append(a_data)
context[(f'contributors_comments_gte_'
f'{comment_num}')]['acomplished'] = False
else:
finished.append(a_data)

# Edition achievements:
for ed_num in self.edition_ranges_for_achievements:
context[f'contributors_editions_gte_{ed_num}'] = {
'stat': (
contributors.filter(editions__gte=ed_num).count()
),
'acomplished': True,
}
a_data = {
'img':
f'images/achievments_icons/code_editions-{ed_num}.svg',
'name': f'Additions and deletions (equal to or more than {ed_num})',
'description':
f"Make additions and"
f" deletions in amount of equal to or more than {ed_num}",
}

if ed_num > editions:
unfinished.append(a_data)
context[f'contributors_editions_gte_{ed_num}']['acomplished'] = False
else:
finished.append(a_data)

a_data = {
'img': 'images/achievments_icons/friend.svg',
'name': 'Hexlet friend',
'description': "Make any contribution to Hexlet projects",
}
if finished:
finished.insert(0, a_data)
else:
unfinished.insert(0, a_data)
context['contributors_with_any_contribution']['acomplished'] = False

context['finished'] = finished
context['unfinished'] = unfinished
context['closed'] = len(finished)
context['all_achievements'] = len(finished) + len(unfinished)
return context
7 changes: 4 additions & 3 deletions contributors/views/contributor_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ class CompareWithYourselfView(ListView):
"""View of comparing current user with another one."""

model = Contribution
template_name = 'contributors_sections/contributors/contributor_compare_with_yourself.html' # noqa: E501
template_name = ('contributors_sections/'
'contributors/contributor_compare_with_yourself.html')
slug_field = 'contributor'

def get_queryset(self):
Expand Down Expand Up @@ -54,7 +55,7 @@ def get_context_data(self, **kwargs):
).first().full_name
context['me_top_repo'] = me_repo_full_name
else:
context['me_top_repo'] = '---' # noqa: E501
context['me_top_repo'] = '---'

enemy_qs = context['filter'].qs.filter(
contributor=context['enemy_obj'].pk,
Expand All @@ -75,5 +76,5 @@ def get_context_data(self, **kwargs):
).first().full_name
context['enemy_top_repo'] = enemy_repo_full_name
else:
context['enemy_top_repo'] = '---' # noqa: E501
context['enemy_top_repo'] = '---'
return context
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class ListView(contributors.ListView):
"""A list of contributors with monthly contributions."""

template_name = 'contributors_sections/contributors/contributors_for_period.html' # noqa: E501
template_name = 'contributors_sections/contributors/contributors_for_period.html'
context_object_name = 'contributors_list'

def get_context_data(self, **kwargs):
Expand Down
2 changes: 1 addition & 1 deletion contributors/views/generic_list_views/pull_requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class ListView(TableSortSearchAndPaginationMixin, generic.ListView):
)
ordering = sortable_fields[0]

template_name = 'contributors_sections/pull_requests/pull_requests_list.html' # noqa: E501
template_name = 'contributors_sections/pull_requests/pull_requests_list.html'

def get_queryset(self):
"""Get pull requests.
Expand Down
2 changes: 1 addition & 1 deletion contributors/views/organizations_views/organizations.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class ListView(TableSortSearchAndPaginationMixin, generic.ListView):
queryset = Organization.objects.filter(
repository__is_visible=True,
).distinct().annotate(repository_count=Count('repository'))
template_name = 'contributors_sections/organizations/organizations_list.html' # noqa: E501
template_name = 'contributors_sections/organizations/organizations_list.html'
sortable_fields = (
'name',
('repository_count', _("Repositories")),
Expand Down
2 changes: 1 addition & 1 deletion contributors/views/repositories_views/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class RepoContributorList(contributors.ListView):
"""A repository's details."""

template_name = 'contributors_sections/repositories/repository_details.html' # noqa: E501
template_name = 'contributors_sections/repositories/repository_details.html'

def get_queryset(self):
"""Get a dataset."""
Expand Down
Loading
Loading