From a0289027e14b294d8b4ec3be5c72121ef9beea28 Mon Sep 17 00:00:00 2001 From: Daniil Date: Sun, 6 Aug 2023 15:44:51 +0400 Subject: [PATCH 1/3] Add achievement list page --- config/settings.py | 1 + contributors/models/contributor.py | 10 + contributors/urls.py | 5 + contributors/views/__init__.py | 1 + contributors/views/achievements.py | 60 +++ poetry.lock | 96 +---- pyproject.toml | 1 + templates/achievements_list.html | 10 + .../tables/achievement_percentage_field.html | 11 + .../components/tables/achievements_list.html | 380 ++++++++++++++++++ templates/contributor_details.html | 4 +- 11 files changed, 496 insertions(+), 83 deletions(-) create mode 100644 contributors/views/achievements.py create mode 100644 templates/achievements_list.html create mode 100644 templates/components/tables/achievement_percentage_field.html create mode 100644 templates/components/tables/achievements_list.html diff --git a/config/settings.py b/config/settings.py index 212ada10..43b914bc 100644 --- a/config/settings.py +++ b/config/settings.py @@ -47,6 +47,7 @@ 'crispy_forms', "crispy_bootstrap5", 'django_extensions', + 'mathfilters', ] MIDDLEWARE = [ diff --git a/contributors/models/contributor.py b/contributors/models/contributor.py index 290a5823..c0ae1a16 100644 --- a/contributors/models/contributor.py +++ b/contributors/models/contributor.py @@ -40,6 +40,16 @@ def with_contributions(self): comments=models.Count( 'contribution', filter=models.Q(contribution__type='cnt'), ), + editions=(models.F('additions') + models.F('deletions')), + contribution_amount=sum( + ( + models.F('commits'), + models.F('editions'), + models.F('pull_requests'), + models.F('issues'), + models.F('comments'), + ), + ), ) def for_month(self): diff --git a/contributors/urls.py b/contributors/urls.py index a10a2d09..65305c23 100644 --- a/contributors/urls.py +++ b/contributors/urls.py @@ -81,4 +81,9 @@ ), path('event-handler', views.webhook.EventHandler.as_view()), path('about', views.about.AboutView.as_view(), name="about"), + path( + 'achievements', + views.achievements.AchievementListView.as_view(), + name='achievements', + ), ] diff --git a/contributors/views/__init__.py b/contributors/views/__init__.py index 3f94d2f5..dd60834c 100644 --- a/contributors/views/__init__.py +++ b/contributors/views/__init__.py @@ -1,5 +1,6 @@ from contributors.views import ( # noqa: WPS235 about, + achievements, config, contributor, contributor_issues, diff --git a/contributors/views/achievements.py b/contributors/views/achievements.py new file mode 100644 index 00000000..0d6d1f10 --- /dev/null +++ b/contributors/views/achievements.py @@ -0,0 +1,60 @@ +from django.views import generic + +from contributors.models import Contributor + + +class AchievementListView(generic.ListView): + """Achievement list.""" + + template_name = 'achievements_list.html' + model = Contributor + contributors_amount = Contributor.objects.count() + contributors = Contributor.objects.with_contributions() + + pull_request_ranges_for_achievements = [100, 50, 25, 10, 1] + commit_ranges_for_achievements = [200, 100, 50, 25, 1] + issue_ranges_for_achievements = [50, 25, 10, 5, 1] + comment_ranges_for_achievements = [200, 100, 50, 25, 1] + edition_ranges_for_achievements = [1000, 500, 250, 100, 1] + + def get_context_data(self, **kwargs): + """Add context data for achievement list.""" + context = super().get_context_data(**kwargs) + contributors = Contributor.objects.with_contributions() + + context['contributors_amount'] = self.contributors_amount + context['contributors_with_any_contribution'] = ( + contributors.filter(contribution_amount__gte=1).count() + ) + + # Pull request achievements: + for pr_num in self.pull_request_ranges_for_achievements: + context[f'contributors_pull_requests_gte_{pr_num}'] = ( + contributors.filter(pull_requests__gte=pr_num).count() + ) + + # Commit achievements: + for commit_num in self.commit_ranges_for_achievements: + context[f'contributors_commits_gte_{commit_num}'] = ( + contributors.filter(commits__gte=commit_num).count() + ) + + # Issue achievements: + for issue_num in self.issue_ranges_for_achievements: + context[f'contributors_issues_gte_{issue_num}'] = ( + contributors.filter(issues__gte=issue_num).count() + ) + + # Comment achievements: + for comment_num in self.comment_ranges_for_achievements: + context[f'contributors_comments_gte_{comment_num}'] = ( + contributors.filter(comments__gte=comment_num).count() + ) + + # Edition achievements: + for ed_num in self.edition_ranges_for_achievements: + context[f'contributors_editions_gte_{ed_num}'] = ( + contributors.filter(editions__gte=ed_num).count() + ) + + return context diff --git a/poetry.lock b/poetry.lock index 7a575a70..418c7c15 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "apscheduler" version = "3.10.0" description = "In-process task scheduler with Cron-like capabilities" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -16,7 +15,7 @@ files = [ pytz = "*" setuptools = ">=0.7" six = ">=1.4.0" -tzlocal = ">=2.0,<3.0.0 || >=4.0.0" +tzlocal = ">=2.0,<3.dev0 || >=4.dev0" [package.extras] doc = ["sphinx", "sphinx-rtd-theme"] @@ -34,7 +33,6 @@ zookeeper = ["kazoo"] name = "asgiref" version = "3.6.0" description = "ASGI specs, helper code, and adapters" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -49,7 +47,6 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "astor" version = "0.8.1" description = "Read/rewrite/write Python ASTs" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" files = [ @@ -61,7 +58,6 @@ files = [ name = "attrs" version = "22.2.0" description = "Classes Without Boilerplate" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -80,7 +76,6 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy name = "backports-zoneinfo" version = "0.2.1" description = "Backport of the standard library zoneinfo module" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -109,7 +104,6 @@ tzdata = ["tzdata"] name = "bandit" version = "1.7.4" description = "Security oriented static analyser for python code." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -132,7 +126,6 @@ yaml = ["PyYAML"] name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -182,7 +175,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "certifi" version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -194,7 +186,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -271,7 +262,6 @@ pycparser = "*" name = "charset-normalizer" version = "3.0.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = "*" files = [ @@ -369,7 +359,6 @@ files = [ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -384,7 +373,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -396,7 +384,6 @@ files = [ name = "coverage" version = "6.5.0" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -459,7 +446,6 @@ toml = ["tomli"] name = "crispy-bootstrap5" version = "0.6" description = "Bootstrap5 template pack for django-crispy-forms" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -478,7 +464,6 @@ test = ["pytest", "pytest-django"] name = "cryptography" version = "41.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -520,7 +505,6 @@ test-randomorder = ["pytest-randomly"] name = "darglint" version = "1.8.1" description = "A utility for ensuring Google-style docstrings stay up to date with the source code." -category = "dev" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -532,7 +516,6 @@ files = [ name = "dj-database-url" version = "0.5.0" description = "Use Database URLs in your Django Application." -category = "main" optional = false python-versions = "*" files = [ @@ -544,7 +527,6 @@ files = [ name = "django" version = "4.1.9" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -566,7 +548,6 @@ bcrypt = ["bcrypt"] name = "django-crispy-forms" version = "1.14.0" description = "Best way to have Django DRY forms" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -578,7 +559,6 @@ files = [ name = "django-cte" version = "1.2.1" description = "Common Table Expressions (CTE) for Django" -category = "main" optional = false python-versions = "*" files = [ @@ -590,7 +570,6 @@ files = [ name = "django-debug-toolbar" version = "3.8.1" description = "A configurable set of panels that display various debug information about the current request/response." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -606,7 +585,6 @@ sqlparse = ">=0.2" name = "django-extensions" version = "3.2.1" description = "Extensions for Django" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -617,11 +595,21 @@ files = [ [package.dependencies] Django = ">=3.2" +[[package]] +name = "django-mathfilters" +version = "1.0.0" +description = "A set of simple math filters for Django" +optional = false +python-versions = "*" +files = [ + {file = "django-mathfilters-1.0.0.tar.gz", hash = "sha256:c9b892ef6dfc893683e75cfd0279c187a601ca68f4684c38f9da44657fb64b07"}, + {file = "django_mathfilters-1.0.0-py3-none-any.whl", hash = "sha256:64200a21bb249fbf27be601d4bbb788779e09c6e063170c097cd82c4d18ebb83"}, +] + [[package]] name = "docutils" version = "0.19" description = "Docutils -- Python Documentation Utilities" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -633,7 +621,6 @@ files = [ name = "eradicate" version = "2.1.0" description = "Removes commented-out code." -category = "dev" optional = false python-versions = "*" files = [ @@ -645,7 +632,6 @@ files = [ name = "faker" version = "13.16.0" description = "Faker is a Python package that generates fake data for you." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -660,7 +646,6 @@ python-dateutil = ">=2.4" name = "flake8" version = "4.0.1" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -677,7 +662,6 @@ pyflakes = ">=2.4.0,<2.5.0" name = "flake8-bandit" version = "3.0.0" description = "Automated security testing with bandit and flake8." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -695,7 +679,6 @@ pycodestyle = "*" name = "flake8-broken-line" version = "0.4.0" description = "Flake8 plugin to forbid backslashes for line breaks" -category = "dev" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -710,7 +693,6 @@ flake8 = ">=3.5,<5" name = "flake8-bugbear" version = "22.12.6" description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -729,7 +711,6 @@ dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit", "tox"] name = "flake8-commas" version = "2.1.0" description = "Flake8 lint for trailing commas." -category = "dev" optional = false python-versions = "*" files = [ @@ -744,7 +725,6 @@ flake8 = ">=2" name = "flake8-comprehensions" version = "3.10.1" description = "A flake8 plugin to help you write better list/set/dict comprehensions." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -759,7 +739,6 @@ flake8 = ">=3.0,<3.2.0 || >3.2.0" name = "flake8-debugger" version = "4.1.2" description = "ipdb/pdb statement checker plugin for flake8" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -775,7 +754,6 @@ pycodestyle = "*" name = "flake8-docstrings" version = "1.7.0" description = "Extension for flake8 which uses pydocstyle to check docstrings" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -791,7 +769,6 @@ pydocstyle = ">=2.1" name = "flake8-eradicate" version = "1.4.0" description = "Flake8 plugin to find commented out code" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -808,7 +785,6 @@ flake8 = ">=3.5,<6" name = "flake8-isort" version = "4.2.0" description = "flake8 plugin that integrates isort ." -category = "dev" optional = false python-versions = "*" files = [ @@ -827,7 +803,6 @@ test = ["pytest-cov"] name = "flake8-polyfill" version = "1.0.2" description = "Polyfill package for Flake8 plugins" -category = "dev" optional = false python-versions = "*" files = [ @@ -842,7 +817,6 @@ flake8 = "*" name = "flake8-quotes" version = "3.3.2" description = "Flake8 lint for quotes." -category = "dev" optional = false python-versions = "*" files = [ @@ -856,7 +830,6 @@ flake8 = "*" name = "flake8-rst-docstrings" version = "0.2.7" description = "Python docstring reStructuredText (RST) validator" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -873,7 +846,6 @@ restructuredtext-lint = "*" name = "flake8-string-format" version = "0.3.0" description = "string format checker, plugin for flake8" -category = "dev" optional = false python-versions = "*" files = [ @@ -888,7 +860,6 @@ flake8 = "*" name = "gitdb" version = "4.0.10" description = "Git Object Database" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -903,7 +874,6 @@ smmap = ">=3.0.1,<6" name = "gitpython" version = "3.1.30" description = "GitPython is a python library used to interact with Git repositories" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -918,7 +888,6 @@ gitdb = ">=4.0.1,<5" name = "gunicorn" version = "20.1.0" description = "WSGI HTTP Server for UNIX" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -939,7 +908,6 @@ tornado = ["tornado (>=0.2)"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -951,7 +919,6 @@ files = [ name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -969,7 +936,6 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = "*" files = [ @@ -981,7 +947,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -993,7 +958,6 @@ files = [ name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1005,7 +969,6 @@ files = [ name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1017,7 +980,6 @@ files = [ name = "pbr" version = "5.11.1" description = "Python Build Reasonableness" -category = "dev" optional = false python-versions = ">=2.6" files = [ @@ -1029,7 +991,6 @@ files = [ name = "pep8-naming" version = "0.12.1" description = "Check PEP-8 naming conventions, plugin for flake8" -category = "dev" optional = false python-versions = "*" files = [ @@ -1045,7 +1006,6 @@ flake8-polyfill = ">=1.0.2,<2" name = "platformdirs" version = "3.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1061,7 +1021,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest- name = "psycopg2" version = "2.9.5" description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -1084,7 +1043,6 @@ files = [ name = "psycopg2-binary" version = "2.9.5" description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -1165,7 +1123,6 @@ files = [ name = "pycodestyle" version = "2.8.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1177,7 +1134,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1189,7 +1145,6 @@ files = [ name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1207,7 +1162,6 @@ toml = ["tomli (>=1.2.3)"] name = "pyflakes" version = "2.4.0" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1219,7 +1173,6 @@ files = [ name = "pygments" version = "2.14.0" description = "Pygments is a syntax highlighting package written in Python." -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1234,7 +1187,6 @@ plugins = ["importlib-metadata"] name = "pyjwt" version = "2.6.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1252,7 +1204,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1267,7 +1218,6 @@ six = ">=1.5" name = "python-dotenv" version = "0.20.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1282,7 +1232,6 @@ cli = ["click (>=5.0)"] name = "pytz" version = "2022.7.1" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -1294,7 +1243,6 @@ files = [ name = "pytz-deprecation-shim" version = "0.1.0.post0" description = "Shims to make deprecation of pytz easier" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -1310,7 +1258,6 @@ tzdata = {version = "*", markers = "python_version >= \"3.6\""} name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1360,7 +1307,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1382,7 +1328,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "restructuredtext-lint" version = "1.4.0" description = "reStructuredText linter" -category = "dev" optional = false python-versions = "*" files = [ @@ -1396,7 +1341,6 @@ docutils = ">=0.11,<1.0" name = "setuptools" version = "67.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1413,7 +1357,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1425,7 +1368,6 @@ files = [ name = "smmap" version = "5.0.0" description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1437,7 +1379,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" optional = false python-versions = "*" files = [ @@ -1449,7 +1390,6 @@ files = [ name = "sqlparse" version = "0.4.4" description = "A non-validating SQL parser." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1466,7 +1406,6 @@ test = ["pytest", "pytest-cov"] name = "stevedore" version = "4.1.1" description = "Manage dynamic plugins for Python applications" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1481,7 +1420,6 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1493,7 +1431,6 @@ files = [ name = "typing-extensions" version = "4.4.0" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1505,7 +1442,6 @@ files = [ name = "tzdata" version = "2022.7" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ @@ -1517,7 +1453,6 @@ files = [ name = "tzlocal" version = "4.2" description = "tzinfo object for the local timezone" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1538,7 +1473,6 @@ test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] name = "urllib3" version = "1.26.14" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -1555,7 +1489,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "wemake-python-styleguide" version = "0.16.1" description = "The strictest and most opinionated python linter ever" -category = "dev" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -1588,7 +1521,6 @@ typing_extensions = ">=3.6,<5.0" name = "whitenoise" version = "6.3.0" description = "Radically simplified static file serving for WSGI applications" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1606,4 +1538,4 @@ psycopg2-binary = ["psycopg2-binary"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "273655775699bfea634ce71aef529f71e42777d73410aa331b5adf7999d57e0c" +content-hash = "c16c2e7949284089e8c889d162ad548f323202e0a6c2c51c70b5bff82ea0b520" diff --git a/pyproject.toml b/pyproject.toml index 28bd3c4f..1dc005b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,6 +24,7 @@ crispy-bootstrap5 = "^0.6" django-extensions = "^3.2.1" black = "^23.3.0" django-debug-toolbar = "^3.8.1" +django-mathfilters = "^1.0.0" [tool.poetry.dev-dependencies] wemake-python-styleguide = "^0.16.1" diff --git a/templates/achievements_list.html b/templates/achievements_list.html new file mode 100644 index 00000000..324af259 --- /dev/null +++ b/templates/achievements_list.html @@ -0,0 +1,10 @@ +{% extends 'base.html' %} +{% load i18n static %} + + +{% block content %} +

Achievements

+ +{% include 'components/tables/achievements_list.html' %} + +{% endblock %} \ No newline at end of file diff --git a/templates/components/tables/achievement_percentage_field.html b/templates/components/tables/achievement_percentage_field.html new file mode 100644 index 00000000..89f3e508 --- /dev/null +++ b/templates/components/tables/achievement_percentage_field.html @@ -0,0 +1,11 @@ +{% load i18n static mathfilters %} + +
+
+
+
{% trans achievement_name %}
+
{% trans achievement_description %}
+
+
+
{{ achievement_made_count|div:contributors_amount|mul:100|floatformat:1 }}%
+
diff --git a/templates/components/tables/achievements_list.html b/templates/components/tables/achievements_list.html new file mode 100644 index 00000000..40d6e128 --- /dev/null +++ b/templates/components/tables/achievements_list.html @@ -0,0 +1,380 @@ +{% extends './list_as_table.html' %} +{% load i18n static mathfilters %} + +{% block tbody %} + + + {% trans 'Hexlet friend' %} + + + + {% with achievement_name="Hexlet friend" achievement_description="Make any contribution to Hexlet projects" achievement_made_count=contributors_with_any_contribution %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + + + + {% trans 'Pull requests (equal to or more than 1)' %} + + + {% with achievement_name="Pull requests (equal to or more than 1)" achievement_description="Make pull requests in amount of equal to or more than 1" achievement_made_count=contributors_pull_requests_gte_1 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Pull requests (equal to or more than 10)' %} + + + {% with achievement_name="Pull requests (equal to or more than 10)" achievement_description="Make pull requests in amount of equal to or more than 10" achievement_made_count=contributors_pull_requests_gte_10 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Pull requests (equal to or more than 25)' %} + + + {% with achievement_name="Pull requests (equal to or more than 25)" achievement_description="Make pull requests in amount of equal to or more than 25" achievement_made_count=contributors_pull_requests_gte_25 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Pull requests (equal to or more than 50)' %} + + + {% with achievement_name="Pull requests (equal to or more than 50)" achievement_description="Make pull requests in amount of equal to or more than 50" achievement_made_count=contributors_pull_requests_gte_50 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Pull requests (equal to or more than 100)' %} + + + {% with achievement_name="Pull requests (equal to or more than 100)" achievement_description="Make pull requests in amount of equal to or more than 100" achievement_made_count=contributors_pull_requests_gte_100 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + + + {% trans 'Commits (equal to or more than 1)' %} + + + {% with achievement_name="Commits (equal to or more than 1)" achievement_description="Make commits in amount of equal to or more than 1" achievement_made_count=contributors_commits_gte_1 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Commits (equal to or more than 25)' %} + + + {% with achievement_name="Commits (equal to or more than 25)" achievement_description="Make commits in amount of equal to or more than 25" achievement_made_count=contributors_commits_gte_25 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Commits (equal to or more than 50)' %} + + + {% with achievement_name="Commits (equal to or more than 50)" achievement_description="Make commits in amount of equal to or more than 50" achievement_made_count=contributors_commits_gte_50 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Commits (equal to or more than 100)' %} + + + {% with achievement_name="Commits (equal to or more than 100)" achievement_description="Make commits in amount of equal to or more than 100" achievement_made_count=contributors_commits_gte_100 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Commits (equal to or more than 200)' %} + + + {% with achievement_name="Commits (equal to or more than 200)" achievement_description="Make commits in amount of equal to or more than 200" achievement_made_count=contributors_commits_gte_200 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + + + {% trans 'Issues (equal to or more than 1)' %} + + + {% with achievement_name="Issues (equal to or more than 1)" achievement_description="Make issues in amount of equal to or more than 1" achievement_made_count=contributors_issues_gte_1 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Issues (equal to or more than 5)' %} + + + {% with achievement_name="Issues (equal to or more than 5)" achievement_description="Make issues in amount of equal to or more than 5" achievement_made_count=contributors_issues_gte_5 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Issues (equal to or more than 10)' %} + + + {% with achievement_name="Issues (equal to or more than 10)" achievement_description="Make issues in amount of equal to or more than 10" achievement_made_count=contributors_issues_gte_10 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Issues (equal to or more than 25)' %} + + + {% with achievement_name="Issues (equal to or more than 25)" achievement_description="Make issues in amount of equal to or more than 25" achievement_made_count=contributors_issues_gte_25 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Issues (equal to or more than 50)' %} + + + {% with achievement_name="Issues (equal to or more than 50)" achievement_description="Make issues in amount of equal to or more than 50" achievement_made_count=contributors_issues_gte_50 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + + + {% trans 'Comments (equal to or more than 1)' %} + + + {% with achievement_name="Comments (equal to or more than 1)" achievement_description="Make comments in amount of equal to or more than 1" achievement_made_count=contributors_comments_gte_1 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Comments (equal to or more than 25)' %} + + + {% with achievement_name="Comments (equal to or more than 25)" achievement_description="Make comments in amount of equal to or more than 25" achievement_made_count=contributors_comments_gte_25 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Comments (equal to or more than 50)' %} + + + {% with achievement_name="Comments (equal to or more than 50)" achievement_description="Make comments in amount of equal to or more than 50" achievement_made_count=contributors_comments_gte_50 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Comments (equal to or more than 100)' %} + + + {% with achievement_name="Comments (equal to or more than 100)" achievement_description="Make comments in amount of equal to or more than 100" achievement_made_count=contributors_comments_gte_100 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Comments (equal to or more than 200)' %} + + + {% with achievement_name="Comments (equal to or more than 200)" achievement_description="Make comments in amount of equal to or more than 200" achievement_made_count=contributors_comments_gte_200 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + + {% trans 'Additions and deletions (equal to or more than 1)' %} + + + {% with achievement_name="Additions and deletions (equal to or more than 1)" achievement_description="Make additions and deletions in amount of equal to or more than 1" achievement_made_count=contributors_editions_gte_1 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Additions and deletions (equal to or more than 100)' %} + + + {% with achievement_name="Additions and deletions (equal to or more than 100)" achievement_description="Make additions and deletions in amount of equal to or more than 100" achievement_made_count=contributors_editions_gte_100 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Additions and deletions (equal to or more than 250)' %} + + + {% with achievement_name="Additions and deletions (equal to or more than 250)" achievement_description="Make additions and deletions in amount of equal to or more than 250" achievement_made_count=contributors_editions_gte_250 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Additions and deletions (equal to or more than 500)' %} + + + {% with achievement_name="Additions and deletions (equal to or more than 500)" achievement_description="Make additions and deletions in amount of equal to or more than 500" achievement_made_count=contributors_editions_gte_500 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + + + + {% trans 'Additions and deletions (equal to or more than 1000)' %} + + + {% with achievement_name="Additions and deletions (equal to or more than 1000)" achievement_description="Make additions and deletions in amount of equal to or more than 1000" achievement_made_count=contributors_editions_gte_1000 %} + {% include './achievement_percentage_field.html' %} + {% endwith %} + + +{% endblock %} diff --git a/templates/contributor_details.html b/templates/contributor_details.html index cdc5076e..fd378a64 100644 --- a/templates/contributor_details.html +++ b/templates/contributor_details.html @@ -19,7 +19,9 @@

{{ contributor.login }}

GitHub

- {% trans 'Achievements' %} + + {% trans 'Achievements' %} +

{% if contributor.additions|add:contributor.deletions|add:contributor.pull_requests|add:contributor.issues|add:contributor.comments > 0 %} From 372b54771bd21c7187818b6e832cae93614528e2 Mon Sep 17 00:00:00 2001 From: Daniil Penkov <49104777+danokp@users.noreply.github.com> Date: Tue, 5 Sep 2023 21:58:16 +0400 Subject: [PATCH 2/3] Update achievements_list.html --- templates/achievements_list.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/templates/achievements_list.html b/templates/achievements_list.html index 324af259..0bd84066 100644 --- a/templates/achievements_list.html +++ b/templates/achievements_list.html @@ -1,10 +1,9 @@ {% extends 'base.html' %} {% load i18n static %} - {% block content %}

Achievements

{% include 'components/tables/achievements_list.html' %} -{% endblock %} \ No newline at end of file +{% endblock %} From 130c9cd294283501768a5da331d5bf4db2432284 Mon Sep 17 00:00:00 2001 From: Daniil Date: Tue, 5 Sep 2023 23:21:35 +0400 Subject: [PATCH 3/3] Fix AchievementListView bug with database --- contributors/views/achievements.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributors/views/achievements.py b/contributors/views/achievements.py index 0d6d1f10..dac43af4 100644 --- a/contributors/views/achievements.py +++ b/contributors/views/achievements.py @@ -8,7 +8,6 @@ class AchievementListView(generic.ListView): template_name = 'achievements_list.html' model = Contributor - contributors_amount = Contributor.objects.count() contributors = Contributor.objects.with_contributions() pull_request_ranges_for_achievements = [100, 50, 25, 10, 1] @@ -19,6 +18,7 @@ class AchievementListView(generic.ListView): def get_context_data(self, **kwargs): """Add context data for achievement list.""" + self.contributors_amount = Contributor.objects.count() context = super().get_context_data(**kwargs) contributors = Contributor.objects.with_contributions()