diff --git a/archilance/settings/base.py b/archilance/settings/base.py index ae7c75d..494299f 100644 --- a/archilance/settings/base.py +++ b/archilance/settings/base.py @@ -117,9 +117,10 @@ TEMPLATES = [ # Load these templatetags by default: 'builtins': [ + 'common.templatetags.common_tags', + 'django.contrib.humanize.templatetags.humanize', 'django.templatetags.static', 'mathfilters.templatetags.mathfilters', - 'common.templatetags.common_tags', ], }, }, diff --git a/archilance/util.py b/archilance/util.py index 7a06ed8..d063c88 100644 --- a/archilance/util.py +++ b/archilance/util.py @@ -3,6 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import _get_queryset from django.utils import timezone from pprint import pprint, pformat +import datetime import natsort import pydash as _; _.map = _.map_; _.filter = _.filter_ import random @@ -39,7 +40,7 @@ def random_phone(): def random_date(): - return timezone.datetime(_.random(2012, 2018), _.random(1, 12), _.random(1, 28)) + return timezone.utc.localize(timezone.datetime(_.random(2012, 2018), _.random(1, 12), _.random(1, 28))) def random_amount(): @@ -119,3 +120,34 @@ def validate_phone(text): ) validate(text) + + +def to_local_datetime(obj): + if not isinstance(obj, datetime.date): + raise TypeError('Date expected') + + if not isinstance(obj, datetime.datetime): + obj = datetime.datetime.combine(obj, datetime.time.min) + + if not getattr(obj, 'tzinfo', None): + obj = timezone.utc.localize(obj) + + return obj + + +def morph(number, words): + CHOICES = (2, 0, 1, 1, 1, 2) + + if 4 < number % 100 < 20: + choice = 2 + else: + choice = CHOICES[number % 10 if number % 10 < 5 else 5] + + return words[choice] + +# # Example: +# +# words = ['яблоко', 'яблока', 'яблок'] +# +# for i in range(0, 30): +# print(i, morph(i, words)) diff --git a/assets/js/chat.js b/assets/js/chat.js index 7b72d55..fb25bba 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -1,6 +1,6 @@ var SocketHandler = function () { domain = domain.replace(':' + port, ''); - var url = 'ws://' + domain + '/chat/' + userId + '/'; + var url = 'ws://' + domain + ':8888/chat/' + userId + '/'; var sock = new WebSocket(url); var intervalId; sock.onopen = function () { diff --git a/common/templatetags/common_tags.py b/common/templatetags/common_tags.py index 03fd88c..662f289 100644 --- a/common/templatetags/common_tags.py +++ b/common/templatetags/common_tags.py @@ -1,6 +1,7 @@ from django import template from pprint import pprint, pformat import os +import pydash as _; _.map = _.map_; _.filter = _.filter_ from archilance import util from common.models import Tooltip @@ -107,4 +108,11 @@ def tooltip_placement(**kwargs): if tooltip: return tooltip.position + +@register.simple_tag +def morph(number, words_string): + words = _.split(words_string, ',') + return '%s %s' % (number, util.morph(number, words)) + + # import code; code.interact(local=dict(globals(), **locals())) diff --git a/projects/templates/project_detail.html b/projects/templates/project_detail.html index 1248a37..1801247 100644 --- a/projects/templates/project_detail.html +++ b/projects/templates/project_detail.html @@ -302,12 +302,6 @@ {% endfor %}
-{#
#} -{# #} -{# Ответить#} -{# #} -{#
#} -
{% csrf_token %} @@ -643,21 +637,13 @@ {% endfor %}
- -
{% csrf_token %} -
-
+
+
@@ -801,21 +787,13 @@ {% endfor %}
- -
{% csrf_token %} -
-
+
+
diff --git a/templates/partials/base.html b/templates/partials/base.html index 7ce0708..120d255 100644 --- a/templates/partials/base.html +++ b/templates/partials/base.html @@ -24,7 +24,7 @@ -{# #} + diff --git a/users/models.py b/users/models.py index f33bb5e..bc73a6a 100644 --- a/users/models.py +++ b/users/models.py @@ -1,9 +1,14 @@ +from dateutil.relativedelta import relativedelta from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, AbstractUser, Group, PermissionsMixin from django.contrib.contenttypes.fields import GenericRelation from django.db import models -from django.utils import timezone +from django.utils import timezone, formats from mptt.models import TreeForeignKey, TreeManyToManyField +from pprint import pprint +import datetime +import pydash as _; _.map = _.map_; _.filter = _.filter_ +from archilance import util from specializations.models import Specialization @@ -168,11 +173,14 @@ class User(AbstractBaseUser, PermissionsMixin): def get_profile_image(self): return self.avatar - def get_gender(self): - if self.gender: - return 'Мужчина' if self.gender == 'male' else 'Женщина' - else: - return None + def summary(self): + age = relativedelta(timezone.now(), util.to_local_datetime(self.date_of_birth)).years + + return _.join(_.filter(( + self.get_gender_display(), + '%s %s' % (age, util.morph(age, ('год', 'года', 'лет'))), + formats.date_format(self.date_of_birth, 'DATE_FORMAT'), + ), _.identity), ', ') USERNAME_FIELD = 'username' REQUIRED_FIELDS = [] diff --git a/users/templates/contractor_profile.html b/users/templates/contractor_profile.html index 899da13..c32a22d 100644 --- a/users/templates/contractor_profile.html +++ b/users/templates/contractor_profile.html @@ -359,165 +359,168 @@
-
-
- -
- -

Загрузить резюме

-
-
-
-
-
-
- {% thumbnail contractor.avatar "176x160" crop="center" as im %} - profile-image - {% endthumbnail %} -
-
-
-
-

{{ contractor.get_full_name }}

-
- - {% if contractor.contractor_resume.resume_file %} - - скачать резюме - - {% endif %} +
+
+ -

- {{ contractor.get_gender }}, {{ contractor.date_of_birth }} -

-
-
-
    - {% if contractor.website %} -
  • {{ contractor.website }}
  • - {% endif %} - -
  • {{ contractor.email }}
  • - - {% if contractor.phone %} -
  • {{ contractor.phone }}
  • - {% endif %} -
-
-
- {% specialization_widget contractor.pk %} -
+
+ +

Загрузить резюме

-
+
-
-
- {{ contractor.contractor_resume.text | safe }} + +
+
+
+ {% thumbnail contractor.avatar "176x160" crop="center" as im %} + profile-image + {% endthumbnail %} +
- - - - - -