Exemplo n.º 1
0
 def get_placeholder_image(self):
     storage_class = get_storage_class(settings.STATICFILES_STORAGE)
     storage = storage_class()
     placeholder = storage.open(settings.PLACEHOLDER_PATH)
     image = ThumbnailerImageField(placeholder)
     image.thumbnail_storage = storage
     self.image = image
     return image
Exemplo n.º 2
0
class Klimatik(BaseModel):
    id = models.AutoField(primary_key=True, verbose_name=_("Номер"))

    # Core features
    title = models.CharField(max_length=255, verbose_name=_("Име"))
    slug = models.SlugField()
    price = models.DecimalField(max_digits=8,
                                decimal_places=2,
                                verbose_name=_("Цена"))
    image = ThumbnailerImageField(upload_to='klimatici',
                                  verbose_name=_("Снимка с високо качество"))
    category = models.ForeignKey(Category,
                                 on_delete=models.SET_NULL,
                                 null=True,
                                 verbose_name=_("Категория"))
    available = models.BooleanField(verbose_name=_("В наличност"))
    guarantee_months = models.IntegerField(
        verbose_name=_("Гаранционен период в месеци"))
    description = models.TextField(verbose_name=_("Описание"))
    manufacturer = models.ForeignKey(Manufacturer,
                                     null=True,
                                     related_name="klimatici",
                                     on_delete=models.SET_NULL,
                                     verbose_name=_("Производител"))

    # Detailed specs
    places_size = models.ForeignKey(PlaceSize,
                                    null=True,
                                    related_name="klimatici",
                                    on_delete=models.SET_NULL,
                                    verbose_name=_("Размер на помещенията"))
    energy_class_warm = models.ForeignKey(
        EnergyClass,
        null=True,
        related_name="klimatici_warm",
        on_delete=models.SET_NULL,
        verbose_name=_("Енергиен клас отопление"))
    energy_class_cold = models.ForeignKey(
        EnergyClass,
        null=True,
        related_name="klimatici_cold",
        on_delete=models.SET_NULL,
        verbose_name=_("Енергиен клас охлаждане"))
    power = models.IntegerField(null=True,
                                verbose_name=_("Мощност"),
                                help_text=_("Мерна единица: BTU"))
    output_power_warm = models.CharField(
        max_length=255,
        null=True,
        verbose_name=_("Отдавана мощност(отопление)"),
        help_text=_("Мерна единица: kW"))
    output_power_cold = models.CharField(
        max_length=255,
        null=True,
        verbose_name=_("Отдавана мощност(охлаждане)"),
        help_text=_("Мерна единица: kW"))
    consumed_power_warm = models.CharField(
        max_length=255,
        null=True,
        verbose_name=_("Консумирана мощност(отопление)"),
        help_text=_("Мерна единица: kW"))
    consumed_power_cold = models.CharField(
        max_length=255,
        null=True,
        verbose_name=_("Консумирана мощност(охлаждане)"),
        help_text=_("Мерна единица: kW"))
    input_voltage = models.CharField(max_length=255,
                                     null=True,
                                     verbose_name=_("Входно напрежение"),
                                     help_text=_("Мерна единица: V"))
    inside_size = models.CharField(
        max_length=255,
        null=True,
        verbose_name=_("Размери на вътрешното тяло Ш x В x Д"),
        help_text=_("Мерна единица: MM"))
    outside_size = models.CharField(
        max_length=255,
        null=True,
        verbose_name=_("Размери на външното тяло Ш x В x Д"),
        help_text=_("Мерна единица: MM"))
    inside_weight = models.DecimalField(
        max_digits=8,
        decimal_places=2,
        null=True,
        verbose_name=_("Тегло на вътрешното тяло"),
        help_text=_("Мерна единица: Кг."))
    outside_weight = models.DecimalField(
        max_digits=8,
        decimal_places=2,
        null=True,
        verbose_name=_("Тегло на външното тяло"),
        help_text=_("Мерна единица: Кг."))
    cold_agent = models.CharField(max_length=255,
                                  null=True,
                                  verbose_name=_("Хладилен агент"))
    origin = models.CharField(max_length=255,
                              null=True,
                              verbose_name=_("Произход"),
                              help_text=_("Пример: Германия"))

    __original_image = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__original_image = self.image

    def discount(self):
        if self.discount_inner:
            if self.discount_inner.time_end < timezone.now():
                self.discount_inner.delete()
                return Discount.objects.none()
            else:
                return self.discount_inner
        return Discount.objects.none()

    def has_discount(self):
        has_discount = False
        try:
            has_discount = (self.discount_inner is not None)
        except Discount.DoesNotExist:
            pass
        return has_discount

    def __str__(self):
        return _(u'%s (номер %d)') % (self.title, self.id)

    def save(self, *args, **kwargs):
        # Generate slug from title
        self.slug = slugify(unidecode(self.title))

        # Prevent same slug
        while True:
            try:
                Klimatik.objects.exclude(id=self.id).get(slug=self.slug)
                self.slug = u"%s%d" % (self.slug, 1)
            except Klimatik.DoesNotExist:
                break

        if self.has_discount():
            if self.price != self.discount_inner.new_price:
                self.discount_inner.delete_default()

        # Do actual save
        super(Klimatik, self).save(*args, **kwargs)

        # Only watermark if image has changed
        if self.__original_image != self.image:
            image = Image.open(self.image.path)
            image = Imprint(image,
                            "zdrkp",
                            font=ImageFont.truetype(
                                os.path.join(settings.BASE_DIR, "sold_items",
                                             "static", "sold_items", "fonts",
                                             "ComicSans.ttf"), 18),
                            color=(51, 153, 204, 255),
                            opacity=0.6,
                            margin=(30, 30))
            image.save(self.image.path)

    def rating(self):
        return self.feedbacks.aggregate(
            klima_rating=models.Avg('feedback_rating'))['klima_rating']

    class Meta:
        verbose_name = _("климатик")
        verbose_name_plural = _("климатици")
Exemplo n.º 3
0
class Page(models.Model):
    class Meta:
        verbose_name = "페이지"
        verbose_name_plural = "페이지 목록"

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return "/%s/" % self.code

    SPECIAL_CHOICES = ((None, '일반 페이지'), ('root', '루트 페이지'),
                       ('main', '메인 페이지'), ('home', '루트 + 메인'))

    code = models.SlugField(
        '페이지 코드',
        unique=True,
        help_text='페이지 url로 사용됩니다. 단, "home"의 경우 예외적으로 루트가 됩니다.')
    page_type = models.CharField('특별한 페이지',
                                 null=True,
                                 choices=SPECIAL_CHOICES,
                                 default=None,
                                 max_length=10,
                                 help_text="""
    랜딩 페이지: 처음 사이트에 진입하면 표시되는 사이트 입니다. 페이지 코드와 무관하게 루트 주소 "/"를 갖습니다.<br/>
    메인 페이지: 페이지 내에서 첫 페이지로 돌아갈 때에 목적지가 되는 페이지 입니다. 로고나 '처음으로' 버튼 등에 링크됩니다.<br/>
    랜딩 + 메인: 루트이자 첫 페이지로 대부분의 사이트에서 홈페이지에 해당 됩니다.
    """)

    title = models.CharField('페이지 제목', max_length=40)
    subtitle = models.CharField('페이지 부제목(선택)',
                                max_length=100,
                                blank=True,
                                null=True)
    featured = ThumbnailerImageField(
        '타이틀 이미지',
        upload_to='featured',
        blank=True,
        null=True,
        help_text='이미지 추가 시 페이지 상단에 이미지 타이틀이 표시 됩니다.')

    content = RichTextUploadingField('PC 페이지 내용', config_name='page')
    style = models.TextField('CSS',
                             default='',
                             blank=True,
                             null=True,
                             help_text='스타일 시트에 추가할 내용(테그 없이 작성)')

    mobile_content = RichTextUploadingField('모바일 페이지 내용',
                                            config_name='page',
                                            blank=True,
                                            null=True)
    mobile_style = models.TextField('CSS',
                                    default='',
                                    blank=True,
                                    null=True,
                                    help_text='스타일 시트에 추가할 내용(테그 없이 작성)')

    script = models.TextField('Script',
                              default='',
                              blank=True,
                              null=True,
                              help_text='페이지에 추가할 스크립트 내용(테그 없이 작성)')
    template = models.CharField(
        '커스텀 템플릿',
        max_length=256,
        default='',
        blank=True,
        null=True,
        help_text='사이트 기본 템플릿(page.html)을 사용하지 않고 별도 템플릿을 사용하려는 경우 지정')

    updated = models.DateTimeField('업데이트', auto_now=True)
    created = models.DateTimeField('생성일', auto_now_add=True)

    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):
        if self.page_type == 'main':
            if Page.objects.filter(page_type='main').exists():
                Page.objects.filter(page_type='main').update(page_type=None)

            if Page.objects.filter(page_type='home').exists():
                Page.objects.filter(page_type='home').update(page_type='root')

        elif self.page_type == 'root':
            if Page.objects.filter(page_type__in=['home', 'root']).exists():
                if Page.objects.filter(page_type='main').exists():
                    Page.objects.filter(page_type='main').update(
                        page_type=None)
                Page.objects.filter(page_type__in=['home', 'root']).update(
                    page_type='main')

        elif self.page_type == 'home':
            Page.objects.update(page_type=None)

        super().save(force_insert, force_update, using, update_fields)
Exemplo n.º 4
0
class Profile(AbstractBaseClass):
    """
    Модель профиля пользователя.
    Основная модель, она используется в создаваемых пользователем материалах.
    """
    objects = ProfileManager()

    ROLE_USER = '******'
    ROLE_MODEL = 'm'
    ROLE_COMPANY = 'c'
    ROLE_DEAD_SOUL = 'd'

    ROLE_CHOICES = (
        (ROLE_USER, 'User'),
        (ROLE_MODEL, 'Model'),
        (ROLE_COMPANY, 'Company'),
        (ROLE_DEAD_SOUL, 'Dead soul'),
    )

    role = models.CharField(max_length=1, choices=ROLE_CHOICES)

    name = models.CharField("Profile name", max_length=255)
    city = models.ForeignKey('cities_light.City', null=True)
    short_description = models.CharField("Short description", max_length=255, default='', null=True, blank=True)
    description = models.TextField("Description", default='', null=True, blank=True)
    avatar = ThumbnailerImageField(u"Avatar", upload_to="profile_images", null=True, blank=True)
    # TODO: replace to state
    certified = models.BooleanField("Certified by the moderator", default=True)
    completed = models.BooleanField("Completed information", default=False)
    address = models.CharField("Address", max_length=255, null=True, blank=True)
    position = models.PositiveIntegerField(_('position'), null=True, default=None)
    point = models.PositiveSmallIntegerField(_(u'баллы'), default=0)

    def is_user(self):
        """
        Проверка, что пользователь является заказчиком
        """
        return self.role == self.ROLE_USER

    def is_company(self):
        """
        Проверка, что пользователь является компанией
        """
        return self.role == self.ROLE_COMPANY

    def is_producers(self):
        """
        Проверка, что пользователь имеет права исполнителя
        """
        return self.role in (self.ROLE_MASTER, self.ROLE_COMPANY)

    def phone(self):
        """
        Получение номера телефона. (Устаревшее)
        """
        phones = self.profilephone_set.all()
        return phones[0].phone if phones.count() else ''

    def email(self):
        """
        Получение адреса почты. (Устаревшее)
        """
        emails = self.profileemail_set.all()
        return emails[0].email if emails.count() else ''

    def get_avatar(self):
        """
        Получение аватара, если его нет или файл не найден, то дефолтная картинка
        """
        if self.avatar and path.exists(self.avatar.path):
            ava = self.avatar
        else:
            ava = get_thumbnailer(open(settings.DEFAULT_IMAGE), relative_name='default.png')
        print settings.DEFAULT_IMAGE
        print ava
        return ava

    # Foreign data

    def get_email(self):
        """
        Получение адреса электронной почты пользователя, с которой он регистрировался
        """
        # if self.role == Profile.ROLE_USER:
        #     return self.user_set.all()[0].email
        # emails = self.profileemail_set.all()
        # return emails[0].email if emails.count() else ''
        return self.user_set.all()[0].email

    def get_actual_emails(self):
        """
        Получение актуальных адресов электронной почты.
        Из базы выбираются, только адреса существующих людей.
        Исключены тестовые.
        """
        emails = list(
            user.email for user in self.user_set.filter(
                is_admin=False, is_staff=False, is_active=True
            ).exclude(Q(email__endswith='loc') | Q(email__endswith='amigostone.ru')))
        emails += list(profileemail.email for profileemail in self.profileemail_set.all()
                       .exclude(Q(email__endswith='loc') | Q(email__endswith='amigostone.ru')))
        return emails

    def get_phone(self):
        """
        Получение номера телефона
        """
        phones = self.profilephone_set.all()
        return phones[0].phone if phones.count() else ''

    def get_url(self):
        """
        Получение адреса сайта компании или мастера
        """
        urls = self.profileurl_set.all()
        return urls[0].url if urls.count() else ''

    # FORMS

    def get_profile_account_form(self):
        """
        В зависимости от роли пользователя, для редактирования профиля, ему дается определенная форма.
        Формы в основном отличаются названием полей.
        """
        from accounts.forms import ProfileAccountForm, ProfileMasterForm, ProfileCompanyForm
        if self.is_user():
            return ProfileAccountForm
        elif self.is_company():
            return ProfileCompanyForm
        else:
            return ProfileMasterForm

    def get_profile_account_formset(self):
        """
        Расширенные формы для заполнения профиля. Так же зависят от роли пользователя
        """
        if self.role == 'a':  # (Устаревшее) У обычного заказчика нет дополнительных форм
            return [Profile.get_profile_email_formset(), Profile.get_profile_email_formset()]
        elif self.role == 'c':  # Компания
            return [Profile.get_profile_email_formset(), Profile.get_profile_email_formset(),
                    Profile.get_profile_url_formset(), Profile.get_profile_contact_person_formset()]
        else:  # Мастер-
            return [Profile.get_profile_email_formset(), Profile.get_profile_email_formset()]

    @staticmethod
    def get_profile_phone_formset():
        """
        Форма для добавления номера телефона
        """
        from accounts.forms import ProfilePhoneForm
        return inlineformset_factory(Profile, ProfilePhone, ProfilePhoneForm, extra=1, min_num=1, max_num=1, can_delete=False)

    @staticmethod
    def get_profile_email_formset():
        """
        Форма для добавления электронного почтового адреса
        """
        from accounts.forms import ProfileEmailForm
        return inlineformset_factory(Profile, ProfileEmail, ProfileEmailForm, extra=1, min_num=1, max_num=1, can_delete=False)

    @staticmethod
    def get_profile_url_formset():
        """
        Форма для добавления электроного адреса компании
        """
        from accounts.forms import ProfileUrlForm
        return inlineformset_factory(Profile, ProfileUrl, ProfileUrlForm, extra=1, min_num=1, max_num=1, can_delete=False)

    @staticmethod
    def get_profile_director_form():
        """
        Форма для добавления Гендиректора
        """
        from accounts.forms import ProfileDirectorForm
        return ProfileDirectorForm
        # return inlineformset_factory(Profile, ProfileDirector, ProfileDirectorForm, extra=1, min_num=1, max_num=1,
        # can_delete=False)

    @staticmethod
    def get_profile_bank_details_form():
        """
        Форма для добавления банковских реквизитов
        """
        from accounts.forms import ProfileBankDetailsForm
        return ProfileBankDetailsForm
        # return inlineformset_factory(Profile, ProfileBankDetails, ProfileBankDetailsForm, extra=1, min_num=1,
        # max_num=1, can_delete=False)

    def __unicode__(self):
        return self.name

    def get_public_abs_url(self):
        """
        Ссылка на публичный профиль
        """
        return reverse('companies:profile_view', args=[self.slug])

    def get_email_settings(self):
        """
        Список доступных подписок на рассылки
        """
        if self.is_user():
            f = EmailGroup.PERSON
        else:
            f = EmailGroup.COMPANY
        return EmailSetting.objects.filter(email_groups__title=f)

    def get_email_subs(self, cached=False):
        """
        Формирование списка подписок на рассылки сгрупированного по темам
        """
        if cached:
            try:
                return self._get_email_subs
            except AttributeError:
                pass

        # p = EmailSetting.objects.raw('select es.id, es.group, es.action, es.description, esp.profile_id from email_sender_emailsetting as es '
        #                              'inner join email_sender_emailgroup_settings as egs on (es.id = egs.emailsetting_id) '
        #                              'inner join email_sender_emailgroup as eg on (egs.emailgroup_id = eg.id) '
        #                              'left join email_sender_emailsetting_profiles as esp on (es.id = esp.emailsetting_id and esp.profile_id=%s)'
        #                              'where eg.title="%s" and es.changeable=true' % (self.id, f))

        email_settings = self.get_email_settings().filter(changeable=True)
        accepts = {e.id for e in self.email_settings.all()}
        setting = namedtuple('ESetting', 'action description accept group')
        aggregate = sorted(
            (setting(
                s.action,
                s.description,
                True if s.id in accepts else False,
                EmailSetting.group_name(s.group))
                for s in email_settings
             ),
            key=lambda x: x.group)
        self._get_email_subs = aggregate
        return aggregate

    def update_email_subs(self, settings):
        """
        Обновление подписок на рассылки.
        Получает id-шники, сравнивает с теми которы в базе,
        после чего добавляет или удаляет.
        """
        new_accepts = set(settings)
        aggregate = self.get_email_subs(cached=True)
        all_settings = {s.action for s in aggregate}
        current_accepts = {s.action for s in aggregate if s.accept}
        assert new_accepts.issubset(all_settings)
        to_add = new_accepts - current_accepts
        to_remove = current_accepts - new_accepts
        if to_add:
            to_add = EmailSetting.objects.filter(action__in=to_add)
            self.email_settings.add(*to_add)
        if to_remove:
            to_remove = EmailSetting.objects.filter(action__in=to_remove)
            self.email_settings.remove(*to_remove)

    def get_rating(self):
        from common.models import PointSystem, PointAction
        rating = 0
        for item in self.pointaction_set.all():
            rating += item.content_type.pointsystem.point
        return rating
Exemplo n.º 5
0
class Contact(models.Model):

    frontpage = models.ForeignKey(Landingpage,
                                  verbose_name='Лендинг',
                                  on_delete=models.DO_NOTHING,
                                  related_name='contacts')

    company_name = models.CharField(max_length=255,
                                    null=False,
                                    blank=False,
                                    default='наименование организации',
                                    verbose_name='наименование организации',
                                    help_text='наименование организации')

    phone1 = models.CharField(max_length=20,
                              null=False,
                              blank=False,
                              verbose_name='номер телефона СПб',
                              help_text='не более 20 символов')

    phone2 = models.CharField(max_length=20,
                              null=True,
                              blank=True,
                              verbose_name='номер телефона Москва',
                              help_text='не более 20 символов')

    email = models.EmailField(max_length=60,
                              null=False,
                              blank=False,
                              verbose_name='адрес электронной почты',
                              help_text='не более 60 символов')

    openings = models.CharField(max_length=40,
                                null=True,
                                blank=True,
                                verbose_name='рабочее время',
                                help_text='не более 40 символов')

    openings_full = models.TextField(
        max_length=200,
        null=True,
        blank=True,
        verbose_name='рабочее время, полностью',
        help_text='не более 200 символов, можно использовать HTML тэги')

    facebook = models.URLField(max_length=120,
                               null=True,
                               blank=True,
                               verbose_name='facebook',
                               help_text='не более 120 символов')

    vk = models.URLField(max_length=120,
                         null=True,
                         blank=True,
                         verbose_name='вКонтакте',
                         help_text='не более 120 символов')

    instagram = models.URLField(max_length=120,
                                null=True,
                                blank=True,
                                verbose_name='instagram',
                                help_text='не более 120 символов')

    twitter = models.URLField(max_length=120,
                              null=True,
                              blank=True,
                              verbose_name='twitter',
                              help_text='не более 120 символов')

    googleplus = models.URLField(max_length=120,
                                 null=True,
                                 blank=True,
                                 verbose_name='google+',
                                 help_text='не более 120 символов')

    youtube = models.URLField(max_length=120,
                              null=True,
                              blank=True,
                              verbose_name='youtube',
                              help_text='не более 120 символов')

    odnoklassniki = models.URLField(max_length=120,
                                    null=True,
                                    blank=True,
                                    verbose_name='одноклассники ',
                                    help_text='не более 120 символов')

    address = models.CharField(max_length=200,
                               null=True,
                               blank=True,
                               verbose_name='адрес',
                               help_text='не более 200 символов')

    map = models.TextField(max_length=500,
                           null=True,
                           blank=True,
                           verbose_name='код для вставки карт на сайт',
                           help_text='не более 500 символов')

    slogan = models.TextField(
        max_length=500,
        null=True,
        blank=True,
        verbose_name='промо-текст в подвал',
        help_text=
        'не более 500 символов (рекомендуется 250 и по содержанию близко к SEO-description главной страницы)'
    )

    active = models.BooleanField(verbose_name='активные настройки',
                                 null=False,
                                 blank=False,
                                 default=False)

    htext_contacts = HTMLField(
        null=True,
        blank=True,
        verbose_name='HTML текст на страницу "контакты"')

    htext_about = HTMLField(null=True,
                            blank=True,
                            verbose_name='HTML текст на страницу "о нас"')

    htext_persdata = HTMLField(
        null=True,
        blank=True,
        verbose_name=
        'HTML текст на страницу "политика обработки персональных данных"')

    def get_upload_path(instance, filename):
        file_name, file_extension = os.path.splitext(filename)
        return os.path.join("media/logos/", strftime("%Y/%m/%d/"),
                            str(randint(10000000, 99999999)) + file_extension)

    logo = ThumbnailerImageField(
        null=True,
        blank=True,
        verbose_name='основной логотип',
        upload_to=get_upload_path,
        help_text='соотношение сторон должно быть 315*46')

    main_menu = models.ForeignKey(
        MenuItem,
        null=True,
        blank=True,
        verbose_name='Основное меню (разделы)',
        on_delete=models.SET_NULL,
        related_name='main_menu',
    )

    menu_services = models.ForeignKey(
        MenuItem,
        null=True,
        blank=True,
        verbose_name='Меню услуги',
        on_delete=models.SET_NULL,
        related_name='menu_services',
    )

    menu_countries = models.ForeignKey(
        MenuItem,
        null=True,
        blank=True,
        verbose_name='Меню страны',
        on_delete=models.SET_NULL,
        related_name='menu_countries',
    )

    menu_articles = models.ForeignKey(
        MenuItem,
        null=True,
        blank=True,
        verbose_name='Меню статьи',
        on_delete=models.SET_NULL,
        related_name='menu_articles',
    )

    gallery = models.ForeignKey(GalleryCategory,
                                null=True,
                                blank=True,
                                verbose_name='Фотографии на главной',
                                on_delete=models.SET_NULL)

    def logo_tag(self):
        thumb_url = get_thumbnailer(self.logo.name)['admin'].url
        return mark_safe('<img src="%s" />' % thumb_url)

    logo_tag.short_description = 'Превью'
    logo_tag.allow_tags = True

    def get_logo_url(self):
        return get_thumbnailer(self.logo.name)['logo'].url

    def get_phone1_url(self):
        if self.phone1:
            return 'tel:' + re.sub(r'[^\+0-9]', '', self.phone1)
        return ''

    def get_phone2_url(self):
        if self.phone2:
            return 'tel:' + re.sub(r'[^\+0-9]', '', self.phone2)
        return ''

    def get_email_url(self):
        return 'mailto:' + self.email

    class Meta:
        verbose_name = 'Настройки сайта'
        verbose_name_plural = 'Настройки сайта'

    def __str__(self):
        return 'Настройки #' + str(self.company_name)

    @staticmethod
    def get_active():
        contact = Contact.objects.order_by('-active').first()
        if (not contact):
            #raise Exception("no any contact information detected")
            return None
        return contact

    @staticmethod
    def get_frontpage():
        contact = Contact.objects.order_by('-active').first()
        if (not contact):
            #raise Exception("no any contact information detected")
            return None
        return contact.frontpage

    @staticmethod
    def get_mainmenu():
        contact = Contact.objects.order_by('-active').first()
        if (not contact):
            #raise Exception("no any contact information detected")
            return None
        if (not contact.main_menu):
            return None
        childs = contact.main_menu.get_childs()
        return childs

    def get_photos(self):
        photos = self.gallery.get_photos_all()
        return photos

    def get_latest_8_posts(self):
        return Post.get_latest_posts(8)

    @staticmethod
    def get_favorite_pages():
        pages = Page.objects.filter(favorite_page=True).all()
        if (not pages.count):
            # raise Exception("no any contact information detected")
            return None
        return pages
Exemplo n.º 6
0
class Landingpage(models.Model):

    name = models.CharField(
        max_length=100,
        verbose_name='название страницы',
    )

    slug = models.SlugField(
        max_length=200,
        null=False,
        blank=False,
        unique=True,
        verbose_name='уникальный адрес страницы',
    )

    title = models.CharField(
        null=True,
        blank=True,
        max_length=300,
        verbose_name='поле title страницы',
        help_text='не более 300 символов, по умолчанию будет использовано '
        '"название страницы" (если не знаете что это такое - спросите у своего SEO-шника)'
    )

    description = models.CharField(
        null=True,
        blank=True,
        max_length=500,
        verbose_name='поле description страницы',
        help_text='не более 500 символов, по умолчанию будет использовано '
        '"название страницы" (если не знаете что это такое - спросите у своего SEO-шника)'
    )

    helo_text = models.CharField(null=True,
                                 blank=True,
                                 max_length=50,
                                 verbose_name='приветствие',
                                 help_text='не более 50 символов')

    subhelo_text = models.CharField(null=True,
                                    blank=True,
                                    max_length=100,
                                    verbose_name='под приветствие',
                                    help_text='не более 100 символов')

    content_text = models.TextField(
        null=True,
        blank=True,
        max_length=5000,
        verbose_name='Основной текст',
        help_text=
        'не более 5000 символов. на странице текст выводится в 2 колонки, разбиваясь на 2 более-менее '
        'равные части. Для принудительного разбиения поставьте символ "#" (решетка)'
    )

    def content_text_first(self):
        m = self.content_text.find('#')
        if m != -1:
            return self.content_text[:m]
        l = len(self.content_text)
        m = int(l / 2)
        while self.content_text[m] != ' ':
            m += 1
        return self.content_text[:m]

    def content_text_second(self):
        m = self.content_text.find('#')
        if m != -1:
            return self.content_text[m + 1:]

        l = len(self.content_text)
        m = int(l / 2)
        while self.content_text[m] != ' ':
            m += 1
        return self.content_text[m + 1:]

    ##########################################################

    slides = models.ManyToManyField(Slide,
                                    blank=True,
                                    verbose_name='слайды',
                                    related_name='pages')

    ##########################################################

    use_testimonial_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Полезные советы"',
    )

    testimonial_header = models.CharField(null=True,
                                          blank=True,
                                          max_length=100,
                                          verbose_name='Заголовок секции')

    ##########################################################

    use_fp_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Избранные страницы"',
    )

    fp_header = models.CharField(null=True,
                                 blank=True,
                                 max_length=100,
                                 verbose_name='Заголовок секции')

    fp_action_url = models.CharField(null=True,
                                     blank=True,
                                     max_length=200,
                                     verbose_name='ссылка URL')

    fp_action_text = models.CharField(null=True,
                                      blank=True,
                                      max_length=100,
                                      verbose_name='Текст кнопки')

    def get_upload_path(instance, filename):
        file_name, file_extension = os.path.splitext(filename)
        return os.path.join("media/lcontent/", strftime("%Y/%m/%d/"),
                            str(randint(10000000, 99999999)) + file_extension)

    content_image = ThumbnailerImageField(null=True,
                                          blank=True,
                                          verbose_name='Основное изображение',
                                          upload_to=get_upload_path,
                                          help_text='')

    def content_image_tag(self):
        thumb_url = get_thumbnailer(self.content_image.name)['admin'].url
        return mark_safe('<img src="%s" />' % thumb_url)

    content_image_tag.short_description = 'Превью'
    content_image_tag.allow_tags = True

    def content_image_url(self):
        return get_thumbnailer(self.content_image.name)['content_image'].url

    ##########################################################

    use_cta_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Призыв к действию"',
    )

    cta_header = models.CharField(null=True,
                                  blank=True,
                                  max_length=100,
                                  verbose_name='Заголовок секции')

    cta_text = models.TextField(null=True,
                                blank=True,
                                max_length=500,
                                verbose_name='Текст секции призыв к действию')

    cta_action_url = models.CharField(null=True,
                                      blank=True,
                                      max_length=200,
                                      verbose_name='ссылка URL')

    cta_action_text = models.CharField(null=True,
                                       blank=True,
                                       max_length=100,
                                       verbose_name='Текст кнопки')

    ##########################################################

    use_persons_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Персонал"',
    )

    persons_header = models.CharField(null=True,
                                      blank=True,
                                      max_length=100,
                                      verbose_name='Заголовок секции')

    ##########################################################

    use_banners_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Баннеры"',
    )

    banners_header = models.CharField(null=True,
                                      blank=True,
                                      max_length=100,
                                      verbose_name='Заголовок секции')

    ##########################################################

    use_userhtml_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Пользовательский HTML"',
    )

    userhtml_header = models.CharField(null=True,
                                       blank=True,
                                       max_length=100,
                                       verbose_name='Заголовок секции')

    userhtml_text = models.TextField(null=True,
                                     blank=True,
                                     max_length=10000,
                                     verbose_name='Пользовательский HTML')

    ##########################################################

    use_video_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Видео"',
    )

    video_header = models.CharField(null=True,
                                    blank=True,
                                    max_length=100,
                                    verbose_name='Заголовок секции')

    video_1 = models.CharField(null=True,
                               blank=True,
                               max_length=100,
                               verbose_name='Видео 1')

    video_2 = models.CharField(null=True,
                               blank=True,
                               max_length=100,
                               verbose_name='Видео 2')

    ##########################################################

    use_news_section = models.BooleanField(
        default=True,
        verbose_name='Секция "Новости"',
    )

    news_header = models.CharField(null=True,
                                   blank=True,
                                   max_length=100,
                                   verbose_name='Заголовок секции')

    news_action_url = models.CharField(null=True,
                                       blank=True,
                                       max_length=200,
                                       verbose_name='ссылка URL')

    news_action_text = models.CharField(null=True,
                                        blank=True,
                                        max_length=100,
                                        verbose_name='Текст кнопки')

    ##########################################################

    def __str__(self):
        return self.name

    def get_title(self):
        if (self.title):
            return self.title
        return self.name

    def get_description(self):
        if (self.description):
            return self.description
        return self.name

    def get_header(self):
        if (self.header):
            return self.header
        return self.name

    def get_url(self):
        if (self.slug):
            return reverse('website.page_by_slug', args=(self.slug, ))
        return None

    class Meta:
        verbose_name = 'Посадочная страница'
        verbose_name_plural = 'Посадочные страницы'
        ordering = ('name', )

    def get_testimonials_all(self):
        return Testimonial.objects.filter(frontpage=self).all()

    @staticmethod
    def get_sitemap_info(domain):
        return {
            'name': 'landingpage.xml',
            'loc': urljoin(domain, 'sitemap/landingpage.xml'),
            'lastmod': datetime.now().isoformat()
        }

    @staticmethod
    def get_sitemap(domain, priority):
        sitemap = [{
            'loc': urljoin(domain, ''),
            'lastmod': datetime.now().isoformat(),
            'priority': priority
        }]
        for url in Landingpage.objects.all():
            if Contact.get_frontpage() != url:
                sitemap.append({
                    'loc': urljoin(domain, url.get_url()),
                    'lastmod': datetime.now().isoformat(),
                    'priority': priority * 0.8
                })
        return sitemap
Exemplo n.º 7
0
class EcobasaCommunityProfile(models.Model):
    group = models.OneToOneField(CosinnusGroup,
        editable=False, related_name='profile')
    # mandatory name!
    name = models.CharField(_('name of community'), max_length=255)
    website = models.URLField(_('link of your communities website'), max_length=100,
        blank=True, null=True)
    image = ThumbnailerImageField(
        verbose_name=_('image'),
        help_text=_('Header image for the community-profile, minimum resolution 1200x400'),
        upload_to='community_images',
        blank=True,
        null=True)
    video = models.URLField(
        verbose_name=_('Video'),
        help_text=_('Link to a video showing your community'),
        max_length=255,
        blank=True,
        null=True)

    # contact info
    contact_telephone = models.CharField(_('telephone'),
        max_length=255, 
        blank=True, 
        null=True)
    contact_street = models.CharField(_('street'),
        max_length=255, 
        blank=True, 
        null=True)
    contact_location = OSMField(_('Location'),
        blank=True, 
        null=True)
    contact_location_lat = LatitudeField(
        blank=True, 
        null=True)
    contact_location_lon = LongitudeField(
        blank=True, 
        null=True)
    contact_city = models.CharField(_('city'),
        max_length=255, blank=True, null=True)
    contact_zipcode = models.CharField(_('zipcode'),
        max_length=255, blank=True, null=True)
    contact_country = models.CharField(_('country'),
        max_length=2, blank=True, choices=COUNTRY_CHOICES, default='ZZ')
    contact_show = models.BooleanField(_('show address in profile'),
        default=False, blank=True)

    # visitors
    visitors_num = models.PositiveIntegerField(
        _('maximum number of people you can host'),
        blank=True, null=True, default=0)
    visitors_accommodation = models.TextField(_('accommodation for guests'),
        blank=True, null=True,
        help_text=_('Where can your visitors sleep? Do you have space for a bus, tents? How is the indoor sleeping situation? Do you have matresses, a couch? Do you have a donations or a pricing model? Required daily working amount or epxeriences?'))

    # wishlist
    wishlist_projects = models.TextField(
        _('Do you have any construction projects? List and describe them together with needed materials, tools, experts, time and knowledge.'),
        blank=True, null=True)
    wishlist_materials = TaggableManager(_('What materials do you need?'),
        through=TaggedWishMaterial,
        related_name='_wishlist_material', 
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    wishlist_materials_info = models.TextField(_('Do you have any additional info about materials, or details to your request (like condition, when you need them)?'),
        blank=True, null=True)
    wishlist_tools = TaggableManager(_('What tools or machines do you need?'),
        through=TaggedWishTool,
        related_name='_wishlist_tool', 
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    wishlist_tools_info = models.TextField(
        _('Do you have any additional info about tools, or details to your request (like condition, when you need them)?'),
        blank=True, null=True)
    wishlist_skills = TaggableManager(_('Are you looking for some experts that could help you with a project or problem? Tag their desired skills here:'),
        through=TaggedWishSkill,
        related_name='_wishlist_skill', 
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    wishlist_special_needs = models.TextField(
        _('Special needs (knowledge, information)'), blank=True, null=True)

    # offers
    offers_services = TaggableManager(_('Services offered in your community'),
        through=TaggedOffersService,
        related_name='_offers_service', 
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    offers_skills = TaggableManager(_('Skills people can learn in your community'),
        through=TaggedOffersSkill,
        related_name='_offers_skill', blank=True)
    offers_creations = TaggableManager(_('Creations/Products'),
        through=TaggedOffersCreation,
        related_name='_offers_creation', 
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    offers_materials = TaggableManager(_('Do you have any materials that you produce or that you dont need anymore? (What you throw away, might be useful to somebody else..)'),
        through=TaggedOffersMaterial,
        related_name='_offers_material',
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    offers_tools = TaggableManager(_('Do you have any tools that you produce or that you dont need anymore?'),
        through=TaggedOffersTool,
        related_name='_offers_tool',
        blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    offers_workshop_spaces = models.TextField(_('Do you have workshop spaces, where people can build/construct/manufacture things?'),
        blank=True, null=True)
    offers_learning_seminars = models.TextField(_('Do you offer any seminars that visitors could attend?'),
        blank=True, null=True)

    # basic info
    basic_description = models.TextField(
        _('Describe your community'), blank=True, null=True)
    basic_inhabitants = models.CharField(
        _('how many people live in your community?'),
        max_length=255, null=True, blank=True)
    basic_inhabitants_underage = models.PositiveIntegerField(
        _('how many of them are under 18?'), null=True, blank=True, default=0)
    basic_brings_together = models.TextField(
        _('what brings your community together'), blank=True, null=True)
    MEMBERSHIP_OPEN = 'o'
    MEMBERSHIP_LOOKING = 'l'
    MEMBERSHIP_CLOSED = 'c'
    MEMBERSHIP_CHOICES = (
        (MEMBERSHIP_OPEN, _('looking for members')),
        (MEMBERSHIP_LOOKING, _('looking for volunteers')),
        (MEMBERSHIP_CLOSED, _('closed for the moment')),
    )
    basic_membership_status = models.CharField(_('member status'),
        max_length=2,
        blank=True,
        choices=MEMBERSHIP_CHOICES,
        default=MEMBERSHIP_OPEN)

    class Meta:
        app_label = 'ecobasa'

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        # copy profile name to cosinnus group name
        self.group.name = self.name
        # ensure the CosinnusGroup is always public!
        self.group.public = True
        self.group.save()
        return super(EcobasaCommunityProfile, self).save(*args, **kwargs)
Exemplo n.º 8
0
class ThumbnailedMixin(models.Model):
    '''
Миксин добавляет поле image
необходимо задать:
thumbnaled_image_folder - для указания места хранения
thumbnaled_prefix - для указания префикса размера в настройках
    '''

    thumbnaled_image_folder = 'images'
    thumbnaled_prefix = None

    class Meta:
        abstract = True

    def _get_thumbnail_upload_path(self, filename):
        return get_upload_path(self.thumbnaled_image_folder, filename)

    image = ThumbnailerImageField(
        null=True,
        blank=True,
        verbose_name=_('Images'),
        upload_to=_get_thumbnail_upload_path,
    )

    def image_custom_tag_url(self, thumbnail_name):
        if (self.image):
            try:
                thumb_url = get_thumbnailer(
                    self.image.name)[thumbnail_name].url
                return mark_safe('<img src="%s" />' % thumb_url)
            except InvalidImageFormatError as e:
                logger.error('image_tag({}) : {}'.format(
                    self.image.name, str(e)))
                return None
            except EasyThumbnailsError as e:
                logger.error('image_tag({}) : {}'.format(
                    self.image.name, str(e)))
                return None
        return None

    def image_tag(self):
        return self.image_custom_tag_url('admin')

    image_tag.short_description = 'Image preview'
    image_tag.allow_tags = True

    def image_custom_url(self, thumbnail_name):
        if (self.image):
            try:
                return get_thumbnailer(self.image.name)[thumbnail_name].url
            except InvalidImageFormatError as e:
                logger.error('image_thumb_url({}) : {}'.format(
                    self.image.name, str(e)))
                return None
            except EasyThumbnailsError as e:
                logger.error('image_thumb_url({}) : {}'.format(
                    self.image.name, str(e)))
                return None
        return None

    def image_big_url(self):
        return self.image_custom_url(self.thumbnaled_prefix + '.big')

    def image_small_url(self):
        return self.image_custom_url(self.thumbnaled_prefix + '.small')

    def image_tiny_url(self):
        return self.image_custom_url(self.thumbnaled_prefix + '.tiny')

    def image_thumb_url(self):
        return self.image_custom_url(self.thumbnaled_prefix + '.thumb')


#   v 1.0.1 - добавлены переводы
#   v 1.0.2 - добавлена обработка ошибок
#   v 1.0.2.1 - исправлена ошибка thumbnaled_prefix
#   v 1.0.3 + image_custom_url
Exemplo n.º 9
0
class Book(TimeStampedModel):
    STATUS_CHOICES = Choices(
        (0, 'public', _('public')),
        (1, 'private', _('private')),
    )

    LICENSE_CHOICES = Choices(
        (0, 'BY', _('BY')),
        (1, 'BY-SA', _('BY-SA')),
        (2, 'BY-ND', _('BY-ND')),
        (3, 'BY-NC', _('BY-NC')),
        (4, 'BY-NC-SA', _('BY-NC-SA')),
        (5, 'BY-NC-ND', _('BY-NC-ND')),
    )

    title = models.CharField(
        verbose_name=_('title'),
        max_length=250,
    )

    description = models.TextField(
        verbose_name=_('description'),
        blank=True,
    )

    category = TreeForeignKey(
        'book.Category',
        verbose_name=_('category'),
        null=True,
        blank=True,
        db_index=True,
        on_delete=models.SET_NULL,
    )

    thumbnail = ThumbnailerImageField(
        verbose_name=_('thumbnail'),
        upload_to=upload_directory_path,
        blank=True,
    )

    status = models.IntegerField(
        verbose_name=_('status'),
        choices=STATUS_CHOICES,
        default=STATUS_CHOICES.public,
        db_index=True,
    )

    license = models.IntegerField(
        verbose_name=_('license'),
        choices=LICENSE_CHOICES,
        default=LICENSE_CHOICES.BY,
        db_index=True,
    )

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        verbose_name=_('owner'),
        null=True,
        blank=True,
        editable=True,
        on_delete=models.SET_NULL,
        related_name="%(app_label)s_%(class)s_owned",
    )

    view_count = models.PositiveIntegerField(
        verbose_name=_('view count'),
        default=0,
    )

    updated = models.DateTimeField(
        verbose_name=_('updated date'),
        null=True,
    )

    objects = BookManager()

    class Meta:
        verbose_name = _('book')
        verbose_name_plural = _('books')

    def __str__(self):
        return self.title
Exemplo n.º 10
0
class Challenge(models.Model):
    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('challenge-detail',
                       kwargs={'challenge_id': str(self.id)})

    # Auto-add a new wall object when creating new Challenge
    def save(self, force_insert=False, force_update=False):
        if self.id is None:  #is new
            super(Challenge, self).save(force_insert, force_update)
            self.wall = Wall.objects.create(name=self.name,
                                            slug='challenge-' + str(self.id))
        super(Challenge, self).save(force_insert, force_update)

    def update_sq(self):
        # update
        self.sq = self.questions.aggregate(Avg('sq'))['sq__avg']
        self.save()

    def update_statistics(self):
        time_to_complete = self.questions.aggregate(
            Sum('time_to_complete'
                ))['time_to_complete__sum'] * CHALLENGE_TTC_FAIRNESS_MULTIPLIER
        # Set minimum package time of 1 minute
        time_to_complete = min(time_to_complete, CHALLENGE_TTC_MINIMUM)
        # Round up to nearest minute
        self.time_to_complete = math.ceil(
            time_to_complete / 60) * 60  # Round to nearest minute

    # Home network for e.g. company-specific challenges
    network = models.ForeignKey(Network, blank=True, null=True)
    name = models.CharField(max_length=75)
    description = models.TextField(blank=True)

    # Users
    users = models.ManyToManyField(User,
                                   through='UserChallenge',
                                   related_name='challenges')

    total_questions = models.IntegerField(default=0)  # Number of questions
    total_resources = models.IntegerField(default=0)  # Number of resources

    time_to_complete = models.IntegerField(editable=False,
                                           default=CHALLENGE_TTC_MINIMUM)

    sq = models.IntegerField(editable=False, null=True)

    wall = models.OneToOneField(Wall, editable=False, null=True)

    # Resources (through challengeresource for bookmarks)
    resources = models.ManyToManyField(Resource,
                                       through='ChallengeResource',
                                       related_name='challenges')
    questions = models.ManyToManyField(Question,
                                       blank=True,
                                       related_name='challenges')

    image = ThumbnailerImageField(max_length=255,
                                  upload_to=challenge_file_path,
                                  blank=True,
                                  resize_source=dict(size=(50, 50), crop=True))

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
Exemplo n.º 11
0
class Post(SoftDeletableModel, AbstractPage):
    STATUS_CHOICES = Choices(
        (0, 'draft', _('draft')),
        (1, 'published', _('published')),
        (2, 'hidden', _('hidden')),
    )

    blog = models.ForeignKey(
        'blog.Blog',
        verbose_name=_('blog'),
        related_name='posts',
        on_delete=models.CASCADE,
    )

    slug = models.SlugField(
        verbose_name=_('slug'),
        help_text=
        _('A short label containing only letters, numbers, underscores or hyphens for URL'
          ),
        max_length=255,
        # unique=True,
        allow_unicode=True,
    )

    excerpt = models.TextField(
        verbose_name=_('excerpt'),
        help_text=_('A short description which does not contain HTML tags'),
        blank=True,
    )

    content = models.TextField(verbose_name=_('content'), )

    category = TreeForeignKey(
        'blog.Category',
        verbose_name=_('category'),
        null=True,
        blank=True,
        db_index=True,
        on_delete=models.SET_NULL,
    )

    tags = TaggableManager(
        verbose_name=_('tags'),
        help_text=_('A comma-separated list of tags.'),
        blank=True,
        through=TaggedPost,
    )

    thumbnail = ThumbnailerImageField(
        verbose_name=_('thumbnail'),
        upload_to=upload_directory_path,
        blank=True,
    )

    status = models.IntegerField(
        verbose_name=_('status'),
        choices=STATUS_CHOICES,
        default=STATUS_CHOICES.draft,
        db_index=True,
    )

    allow_highlight = models.BooleanField(
        verbose_name=_('allow code highlighting'),
        default=False,
    )

    allow_comments = models.BooleanField(
        verbose_name=_('allow comments'),
        default=True,
    )

    published = models.DateTimeField(
        verbose_name=_('published date'),
        null=True,
    )

    view_count = models.PositiveIntegerField(
        verbose_name=_('view count'),
        default=0,
    )

    ip_address = models.GenericIPAddressField(verbose_name=_('IP address'), )

    objects = PostManager()

    class Meta:
        verbose_name = _('post')
        verbose_name_plural = _('posts')

    def __str__(self):
        return self.title

    def __init__(self, *args, **kwargs):
        super(Post, self).__init__(*args, **kwargs)
        self.old_status = self.status
        self.old_published = self.published

    def save(self, *args, **kwargs):
        if self.old_status != self.status \
                and self.status == Post.STATUS_CHOICES.published \
                and self.old_published is None:
            self.published = now()

        super(Post, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('blog:post-detail',
                       args=[self.blog.slug, self.pk, self.slug])

    def get_previous_post(self):
        previous_post = Post.objects.published().filter(
            id__lt=self.id).order_by('-published').first()

        if previous_post is None:
            return None

        return reverse(
            'blog:post-detail',
            args=[self.blog.slug, previous_post.pk, previous_post.slug])

    def get_next_post(self):
        next_post = Post.objects.published().filter(
            id__gt=self.id).order_by('-published').last()

        if next_post is None:
            return None

        return reverse('blog:post-detail',
                       args=[self.blog.slug, next_post.pk, next_post.slug])
Exemplo n.º 12
0
class Jurisdiction(models.Model, RequestHelper):
    """A jursidiction that you may file FOIA requests in"""

    levels = (('f', 'Federal'), ('s', 'State'), ('l', 'Local'))

    name = models.CharField(max_length=50)
    # slug should be slugify(unicode(self))
    slug = models.SlugField(max_length=55)
    abbrev = models.CharField(max_length=5, blank=True)
    level = models.CharField(max_length=1, choices=levels)
    parent = models.ForeignKey(
        'self',
        related_name='children',
        blank=True,
        null=True,
        limit_choices_to=~Q(level='l'),
    )
    hidden = models.BooleanField(default=False)
    image = ThumbnailerImageField(upload_to='jurisdiction_images',
                                  blank=True,
                                  null=True)
    image_attr_line = models.CharField(blank=True,
                                       max_length=255,
                                       help_text='May use html')
    public_notes = models.TextField(blank=True, help_text='May use html')
    aliases = models.TextField(blank=True)

    # non local
    observe_sat = models.BooleanField(
        default=False,
        help_text='Are holidays observed on Saturdays? '
        '(or are they moved to Friday?)')
    holidays = models.ManyToManyField(Holiday, blank=True)

    def __unicode__(self):
        if self.level == 'l':
            return u'{}, {}'.format(self.name, self.parent.abbrev)
        else:
            return self.name

    def get_absolute_url(self):
        """The url for this object"""
        return reverse('jurisdiction-detail', kwargs=self.get_slugs())

    def get_slugs(self):
        """Return a dictionary of slugs for this jurisdiction, for constructing URLs."""
        slugs = {}
        if self.level == 'l':
            slugs.update({
                'fed_slug': self.parent.parent.slug,
                'state_slug': self.parent.slug,
                'local_slug': self.slug
            })
        elif self.level == 's':
            slugs.update({
                'fed_slug': self.parent.slug,
                'state_slug': self.slug
            })
        elif self.level == 'f':
            slugs.update({'fed_slug': self.slug})
        return slugs

    def get_url(self, view):
        """The url for this object"""
        view = 'jurisdiction-%s' % view
        slugs = self.get_slugs()
        return reverse(view, kwargs=slugs)

    def save(self, *args, **kwargs):
        """Normalize fields before saving"""
        self.slug = slugify(self.slug)
        self.name = self.name.strip()
        super(Jurisdiction, self).save(*args, **kwargs)

    def get_url_flag(self):
        """So we can call from template"""
        return self.get_url('flag')

    @property
    def legal(self):
        """Return the legal jurisdiction this jurisdiction falls under
        This is the parent state for localities, and itself for all others
        """
        if self.level == 'l':
            return self.parent
        else:
            return self

    def __getattr__(self, attr):
        """Short cut access to properties stored on the legal jurisdiction"""
        if attr in {'days', 'waiver', 'has_appeal'}:
            return getattr(self.legal.law, attr)
        # if looking for a law relation, but this model does not have one,
        # do not error, but return None
        if attr == 'law':
            return None
        raise AttributeError('{!r} object has no attribute {!r}'.format(
            self.__class__.__name__, attr))

    def get_day_type(self):
        """Does this jurisdiction use business or calendar days?"""
        return 'business' if self.legal.law.use_business_days else 'calendar'

    def get_law_name(self, abbrev=False):
        """The law name for the jurisdiction"""
        if abbrev and self.legal.law.shortname:
            return self.legal.law.shortname
        return self.legal.law.name

    def get_calendar(self):
        """Get a calendar of business days for the jurisdiction"""
        if self.legal.law.use_business_days:
            return HolidayCalendar(self.legal.holidays.all(),
                                   self.legal.observe_sat)
        else:
            return Calendar()

    def get_proxy(self):
        """Get a random proxy user for this jurisdiction"""
        return User.objects.filter(
            organizations__plan__slug='proxy',
            profile__state=self.legal.abbrev,
        ).order_by('-profile__preferred_proxy').first()

    def get_requests(self):
        """State level jurisdictions should return requests from their localities as well."""
        if self.level == 's':
            requests = FOIARequest.objects.filter(
                Q(agency__jurisdiction=self)
                | Q(agency__jurisdiction__parent=self))
        else:
            requests = FOIARequest.objects.filter(agency__jurisdiction=self)
        return requests

    def get_days(self):
        """Get days phrase for request language"""
        if self.days:
            return '{} {} days, as the statute requires'.format(
                self.days,
                self.get_day_type(),
            )
        else:
            return '10 business days'

    class Meta:
        ordering = ['name']
        unique_together = ('slug', 'parent')
Exemplo n.º 13
0
class Challenge(models.Model):
    avatar = ThumbnailerImageField(
            upload_to='img/challenges', verbose_name=_("Avatar"))
    name = models.CharField(max_length=80, verbose_name=_("Name"))
    description = models.TextField(
            null=True, blank=True, verbose_name=_("Description"))
    location = models.CharField(
            max_length=80, null=True, blank=True, verbose_name=_("Location"))
    duration = models.PositiveIntegerField(
            default=1, null=True, blank=True, verbose_name=_("Duration"))

    status = models.CharField(
            max_length=2, choices=challenge_status_choices,
            default=CHALLENGE_STATUS.UPCOMING,
            verbose_name=_("Status"))

    # Even if primary contact person isn't set, despite everything,
    # value 'contact_person' can be used to identify who has created challenge
    is_contact_person = models.BooleanField(default=True)
    contact_person = models.ForeignKey(
            User, related_name="contact_chl_set",
            verbose_name=_("Contact Person"))

    is_alt_person = models.BooleanField(default=False)
    alt_person_fullname = models.CharField(
            max_length=80, null=True, blank=True, verbose_name=_("Full name"))
    alt_person_email = models.EmailField(
            max_length=80, null=True, blank=True, verbose_name=_("E-mail"))
    alt_person_phone = models.CharField(
            max_length=15, blank=True, default='',
            verbose_name=_("Phone Number"))

    start_date = models.DateField(verbose_name=_("Start Date"))
    start_time = models.TimeField(verbose_name=_("Start Time"))

    organization = models.ForeignKey(
            Organization, null=True, blank=True,
            verbose_name=_("Organization"))

    application = models.CharField(
            max_length=2, choices=application_choices,
            default=CHALLENGE_MODE.FREE_FOR_ALL,
            verbose_name=_("Application"))

    is_deleted = models.BooleanField(default=False)
    deleted_reason = models.TextField(
            null=True, blank=True, verbose_name=_("Reason for deletion"))

    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name = _('challenge')
        verbose_name_plural = _('challenges')
        ordering = ['name',]

    def __unicode__(self):
        return unicode(self.name)

    def get_absolute_url(self):
        if self.organization:
            return reverse(
                    'participe.challenge.views.challenge_detail',
                    kwargs={
                            "challenge_id": str(self.id),
                            "org_slug": slugify(self.organization.name),
                            "chl_slug": slugify(self.name),
                            })
        else:
            return reverse(
                    'participe.challenge.views.challenge_detail',
                    kwargs={
                            "challenge_id": str(self.id),
                            "chl_slug": slugify(self.name),
                            })

    def get_full_url(self, request):
        url = u"http://{0}{1}".format(
            request.get_host(),
            self.get_absolute_url())
        return url

    def get_edit_url(self):
        return reverse(
                'participe.challenge.views.challenge_edit',
                args=[str(self.id)])

    def get_acknowledged_qs(self):
        """Returns participations with Acknowledged status"""
        return Participation.objects.filter(
                challenge=self,
                status=PARTICIPATION_STATE.ACKNOWLEDGED)

    @property
    def stat_application_name(self):
        for code, name in application_choices:
            if self.application == code:
                return name
        return ''

    @property
    def stat_status_name(self):
        for code, name in challenge_status_choices:
            if self.status == code:
                return name
        return ''

    @property
    def confirmation_required(self):
        return self.application == CHALLENGE_MODE.CONFIRMATION_REQUIRED

    @property
    def get_waiting_count(self):
        return Participation.objects.all().filter(
                challenge=self,
                status=PARTICIPATION_STATE.WAITING_FOR_CONFIRMATION).count()

    @property
    def get_confirmed_count(self):
        return Participation.objects.all().filter(
                challenge=self,
                status=PARTICIPATION_STATE.CONFIRMED).count()

    @property
    def has_waiting_for_confirmation(self):
        if Participation.objects.filter(
                status=PARTICIPATION_STATE.WAITING_FOR_CONFIRMATION,
                challenge=self):
            return True
        return False

    @property
    def has_waiting_for_acknowledgement(self):
        if Participation.objects.filter(
                status=PARTICIPATION_STATE.WAITING_FOR_ACKNOWLEDGEMENT,
                challenge=self):
            return True
        return False

    @property
    def is_overdue(self):
        if self.start_date < date.today():
            return True
        return False
Exemplo n.º 14
0
class UserProfile(AbstractUser):
    avatar = ThumbnailerImageField(_('avatar'),
                                   upload_to='avatars',
                                   null=True,
                                   blank=True)
    met_criteria = ManyToManyField(Criterion,
                                   through=MetCriterion,
                                   verbose_name=_('met criteria'),
                                   related_name='users_met',
                                   blank=True,
                                   db_index=True)

    objects = UserManager()
    unit_related = UserUnitManager()

    def __unicode__(self):
        return "%s (%s)" % (self.get_full_name(), self.username)

    def _criteria_ids_met(self):
        """Returns a list of ids of the criteria the user has met."""
        return self.met_criteria.values_list('id', flat=True)

    def has_met_qualifications(self, qualifications):
        """Has the user met the given qualifications?

        Returns True if all given qualifications has been met

        """
        criteria_met = self._criteria_ids_met()

        qualification_ids = []
        for q in qualifications:
            qualification_ids.append(q.id)

        criteria = Criterion.objects \
            .filter(qualification__id__in=qualification_ids) \
            .values_list('id', flat=True)

        return set(criteria).issuperset(set(criteria_met))

    def qualifications(self):
        """Which qualifications has the user met?

        Returns a list of qualification query objects.

        """
        # TODO Should be limited to the qualifications belonging to
        # TODO the user's units?

        criteria_met = self._criteria_ids_met()

        potential_qualifications = Qualification.objects \
            .filter(criteria__in=criteria_met)

        qualifications_met = []
        for pq in potential_qualifications:
            pqc = pq.criteria.values_list('id', flat=True)
            if set(pqc).issubset(set(criteria_met)):
                qualifications_met.append(pq.id)

        q = Qualification.objects.filter(id__in=qualifications_met)
        return q

    def qualifications_not_met(self):
        """Which qualifications (in his/her units) has the user not met?

        Returns a list of qualification query objects limited by
        the qualifications in the unit the user belongs to.

        """
        qualifications_met = self.qualifications().values_list('id', flat=True)
        user_units = self.units.values_list('id', flat=True)

        qnm = Qualification.objects \
            .exclude(id__in=qualifications_met) \
            .filter(units__in=user_units)

        return qnm

    def qualification_criteria(self, qualification):
        """ Given a specific qualification, which criteria
        has the user met and not met?

        Returns a tuple of met criteria and not met criteria
        lists, each list item a tuple of (criterion, metcriterion),
        if the criterion is met, or (criterion, None) if not met.

        """
        criteria_met = []
        criteria_not_met = []
        for c in qualification.criteria.all():
            try:
                mc = MetCriterion.objects \
                    .filter(user__id=self.id) \
                    .filter(criterion__id=c.id) \
                    .get()
                criteria_met.append((c, mc))
            except MetCriterion.DoesNotExist:
                criteria_not_met.append((c, None))
        return (criteria_met, criteria_not_met)

    def get_avatar(self):
        if self.avatar:
            return self.avatar
        else:
            return "avatars/default.jpg"

    def get_avatar_path(self):
        if self.avatar:
            return self.avatar.path
        else:
            return os.path.join(settings.STATIC_ROOT, "avatars/default.jpg")

    def get_avatar_url(self):
        if self.avatar:
            return self.avatar.url
        else:
            return settings.STATIC_URL + "avatars/default.jpg"
Exemplo n.º 15
0
class Article(models.Model):
    class Meta:
        verbose_name = 'Article'
        verbose_name_plural = 'Articles'

    title = models.CharField('Titre', max_length=80)
    description = models.CharField('Description', max_length=200)
    slug = models.SlugField(max_length=80)

    authors = models.ManyToManyField(User,
                                     verbose_name='Auteurs',
                                     db_index=True)

    create_at = models.DateTimeField('Date de création')
    pubdate = models.DateTimeField('Date de publication',
                                   blank=True,
                                   null=True,
                                   db_index=True)
    update = models.DateTimeField('Date de mise à jour', blank=True, null=True)

    subcategory = models.ManyToManyField(SubCategory,
                                         verbose_name='Sous-Catégorie',
                                         blank=True,
                                         null=True,
                                         db_index=True)

    image = ThumbnailerImageField(upload_to=image_path, blank=True, null=True)

    is_visible = models.BooleanField('Visible en rédaction',
                                     default=False,
                                     db_index=True)

    sha_public = models.CharField('Sha1 de la version publique',
                                  blank=True,
                                  null=True,
                                  max_length=80,
                                  db_index=True)
    sha_validation = models.CharField('Sha1 de la version en validation',
                                      blank=True,
                                      null=True,
                                      max_length=80,
                                      db_index=True)
    sha_draft = models.CharField('Sha1 de la version de rédaction',
                                 blank=True,
                                 null=True,
                                 max_length=80,
                                 db_index=True)

    text = models.CharField('chemin relatif du texte',
                            blank=True,
                            null=True,
                            max_length=200)

    last_reaction = models.ForeignKey('Reaction',
                                      blank=True,
                                      null=True,
                                      related_name='last_reaction',
                                      verbose_name='Derniere réaction')
    is_locked = models.BooleanField('Est verrouillé', default=False)
    js_support = models.BooleanField('Support du Javascript', default=False)

    licence = models.ForeignKey(Licence,
                                verbose_name='Licence',
                                blank=True,
                                null=True,
                                db_index=True)

    objects = ArticleManager()

    def __unicode__(self):
        return self.title

    def delete_entity_and_tree(self):
        """deletes the entity and its filesystem counterpart"""
        shutil.rmtree(self.get_path(), 0)
        Validation.objects.filter(article=self).delete()
        if self.on_line():
            shutil.rmtree(self.get_prod_path())
        self.delete()

    def get_absolute_url(self):
        return reverse('zds.article.views.view',
                       kwargs={
                           'article_pk': self.pk,
                           'article_slug': slugify(self.title)
                       })

    def get_phy_slug(self):
        return str(self.pk) + "_" + self.slug

    def get_absolute_url_online(self):
        return reverse('zds.article.views.view_online',
                       kwargs={
                           'article_pk': self.pk,
                           'article_slug': slugify(self.title)
                       })

    def get_edit_url(self):
        return reverse('zds.article.views.edit') + \
            '?article={0}'.format(self.pk)

    def on_line(self):
        return (self.sha_public
                is not None) and (self.sha_public.strip() != '')

    def in_validation(self):
        return self.sha_validation is not None

    def is_draft(self):
        return self.sha_draft is not None

    def get_path(self, relative=False):
        if relative:
            return None
        else:
            return os.path.join(settings.ZDS_APP['article']['repo_path'],
                                self.get_phy_slug())

    def load_json(self, path=None, online=False):
        if path is None:
            man_path = os.path.join(self.get_path(), 'manifest.json')
        else:
            man_path = path
        if os.path.isfile(man_path):
            json_data = open(man_path)
            data = json_reader.load(json_data)
            json_data.close()
            if 'licence' in data:
                data['licence'] = Licence.objects.get(code=data['licence'])
            return data
        else:
            return None

    def load_json_for_public(self):
        repo = Repo(self.get_path())
        manarticle = get_blob(
            repo.commit(self.sha_public).tree, 'manifest.json')
        data = json_reader.loads(manarticle)
        if 'licence' in data:
            data['licence'] = Licence.objects.get(code=data['licence'])
        return data

    def load_dic(self, article_version):
        article_version['pk'] = self.pk
        article_version['slug'] = slugify(article_version['title'])
        article_version['image'] = self.image
        article_version['pubdate'] = self.pubdate
        article_version['is_locked'] = self.is_locked
        article_version['sha_draft'] = self.sha_draft
        article_version['sha_validation'] = self.sha_validation
        article_version['sha_public'] = self.sha_public
        article_version['last_read_reaction'] = self.last_read_reaction
        article_version[
            'get_reaction_count'] = Reaction.objects.count_reactions(self)
        article_version['get_absolute_url'] = reverse(
            'zds.article.views.view', args=[self.pk, self.slug])
        article_version['get_absolute_url_online'] = reverse(
            'zds.article.views.view_online',
            args=[self.pk, slugify(article_version['title'])])
        article_version['update'] = self.update
        article_version['authors'] = self.authors
        article_version['tags'] = self.subcategory

        return article_version

    def dump_json(self, path=None):
        if path is None:
            man_path = os.path.join(self.get_path(), 'manifest.json')
        else:
            man_path = path

        dct = export_article(self)
        data = json_writer.dumps(dct, indent=4, ensure_ascii=False)
        json_data = open(man_path, "w")
        json_data.write(data.encode('utf-8'))
        json_data.close()

    def get_text(self):
        path = os.path.join(self.get_path(), self.text)
        txt = open(path, "r")
        txt_contenu = txt.read()
        txt.close()

        return txt_contenu.decode('utf-8')

    def save(self, *args, **kwargs):
        self.slug = slugify(self.title)

        if has_changed(self, 'image') and self.image:
            old = get_old_field_value(self, 'image', 'objects')

            if old is not None and len(old.name) > 0:
                root = settings.MEDIA_ROOT
                name = os.path.join(root, old.name)
                os.remove(name)

        super(Article, self).save(*args, **kwargs)

    def get_reaction_count(self):
        """Return the number of reactions in the article."""
        return Reaction.objects.filter(article__pk=self.pk).count()

    def get_last_reaction(self):
        """Gets the last answer in the thread, if any."""
        try:
            last_reaction = Reaction.objects.all()\
                .filter(article__pk=self.pk)\
                .order_by('pubdate').last()
        except:
            last_reaction = None

        return last_reaction

    def first_reaction(self):
        """Return the first post of a topic, written by topic's author."""
        return Reaction.objects\
            .filter(article=self)\
            .order_by('pubdate')\
            .first()

    def last_read_reaction(self):
        """Return the last post the user has read."""
        try:
            return ArticleRead.objects\
                .select_related()\
                .filter(article=self, user=get_current_user())\
                .latest('reaction__pubdate').reaction
        except:
            return self.first_reaction()

    def first_unread_reaction(self):
        """Return the first reaction the user has unread."""
        try:
            last_reaction = ArticleRead.objects\
                .filter(article=self, user=get_current_user())\
                .latest('reaction__pubdate').reaction

            next_reaction = Reaction.objects.filter(
                article__pk=self.pk,
                pubdate__gt=last_reaction.pubdate)\
                .select_related("author").first()

            return next_reaction
        except:
            return self.first_reaction()

    def antispam(self, user=None):
        """Check if the user is allowed to post in an article according to the
        SPAM_LIMIT_SECONDS value.

        If user shouldn't be able to reaction, then antispam is
        activated and this method returns True. Otherwise time elapsed
        between user's last reaction and now is enough, and the method
        will return False.

        """
        if user is None:
            user = get_current_user()

        last_user_reactions = Reaction.objects\
            .filter(article=self)\
            .filter(author=user.pk)\
            .order_by('-position')

        if last_user_reactions \
                and last_user_reactions[0] == self.last_reaction:
            last_user_reaction = last_user_reactions[0]
            t = datetime.now() - last_user_reaction.pubdate
            if t.total_seconds(
            ) < settings.ZDS_APP['forum']['spam_limit_seconds']:
                return True
        return False
Exemplo n.º 16
0
class Profile(models.Model):
    """
    A userprofile model that provides a short_info, twitter handle, website URL, avatar
    field and details about number/age of accompanying children

    This is also used as AUTH_PROFILE_MODULE.
    """
    user = models.OneToOneField(User, related_name='profile')
    short_info = models.TextField(_('short info'), blank=True)
    avatar = ThumbnailerImageField(_('avatar'),
                                   upload_to='avatars',
                                   null=True,
                                   blank=True,
                                   help_text=avatar_help_text,
                                   validators=ValidatorChain().add(
                                       validators.avatar_dimension).add(
                                           validators.avatar_format,
                                           skip_on_error=True))
    num_accompanying_children = models.PositiveIntegerField(
        _('Number of accompanying children'), null=True, blank=True, default=0)
    age_accompanying_children = models.CharField(
        _("Age of accompanying children"), blank=True, max_length=20)
    twitter = models.CharField(_("Twitter"),
                               blank=True,
                               max_length=20,
                               validators=[validators.twitter_username])
    website = models.URLField(_("Website"), blank=True)
    organisation = models.TextField(_('Organisation'), blank=True)
    full_name = models.CharField(_("Full name"), max_length=255, blank=True)
    display_name = models.CharField(
        _("Display name"),
        max_length=255,
        help_text=_('What name should be displayed to other people?'),
        blank=True)
    addressed_as = models.CharField(
        _("Address me as"),
        max_length=255,
        help_text=
        _('How should we call you in mails and dialogs throughout the website?'
          ),
        blank=True)
    accept_pysv_conferences = models.BooleanField(
        _('Allow copying to PySV conferences'), default=False, blank=True)
    accept_ep_conferences = models.BooleanField(
        _('Allow copying to EPS conferences'), default=False, blank=True)
    accept_job_offers = models.BooleanField(
        _('Allow sponsors to send job offers'), default=False, blank=True)

    badge_status = models.ManyToManyField('accounts.BadgeStatus',
                                          blank=True,
                                          verbose_name=_('Badge status'),
                                          related_name='profiles')

    sessions_attending = models.ManyToManyField(
        'schedule.Session',
        blank=True,
        related_name='attendees',
        verbose_name=_('Trainings'),
        limit_choices_to=Q(
            kind__slug__in=settings.SCHEDULE_ATTENDING_POSSIBLE))

    tags = TaggableManager(blank=True)

    class Meta:
        permissions = (('send_user_mails',
                        _('Allow sending mails to users through the website')),
                       ('export_guidebook',
                        _('Allow export of guidebook data')),
                       ('see_checkin_info',
                        _('Allow seeing check-in information')),
                       ('perform_purchase', _('Allow performing purchases')))

    @cached_property
    def short_info_rendered(self):
        return markdown(self.short_info, 'safe')
Exemplo n.º 17
0
class Profile(models.Model):

    GENDER = (
        (1, _('Male')),
        (2, _('Female')),
    )

    AVATAR_SETTINGS = {
        'size': (settings.AVATAR_SIZE, settings.AVATAR_SIZE),
        'crop': settings.AVATAR_CROP,
        'quality': settings.AVATAR_QUALITY,
        'subsampling': settings.AVATAR_SUBSAMPLING,
        'HIGH_RESOLUTION': True
    }

    user = models.OneToOneField(settings.AUTH_USER_MODEL,
                                unique=True,
                                verbose_name=_('name'))
    gender = models.PositiveSmallIntegerField(_('gender'),
                                              choices=GENDER,
                                              null=False,
                                              blank=False)
    avatar = ThumbnailerImageField(_('avatar'),
                                   null=False,
                                   resize_source=AVATAR_SETTINGS)
    birth_date = models.DateTimeField(_('birth date'), null=False, blank=False)
    background = models.ImageField(_('background'),
                                   upload_to=upload,
                                   null=True,
                                   blank=True)
    college = models.CharField(_('college'),
                               max_length=23,
                               null=True,
                               blank=True)
    city = models.CharField(_('city'), max_length=23, null=True, blank=True)
    job = models.CharField(_('job'), max_length=23, null=True, blank=True)
    descriptione = models.CharField(_('descriptione'),
                                    max_length=666,
                                    null=True,
                                    blank=True)

    objects = models.Manager()

    def __str__(self):
        return "%s%s" % (self.user.last_name, self.user.first_name)

    def get_en_name(self):
        return self.user.get_full_name()

    @property
    def age(self):
        if not self.birth_date:
            return False
        else:
            today = timezone.now()
            age = today.year - self.birth_date.year

        return '%s' % age

    def get_age(self):
        return '%s' % self.age
Exemplo n.º 18
0
class EcobasaUserProfile(BaseUserProfile):
    # FIXME: why need tagged* to be part of SKIP_FIELDS? where are they
    # injected into the model fields?
    SKIP_FIELDS = ('id', 'user',
                   'taggedskill', 'taggedinterest', 'taggedproduct', 'taggedwishlist')

    avatar = ThumbnailerImageField(_('avatar'),
        upload_to='avatars', null=True, blank=True)

    GENDER_OTHER = 'o'
    GENDER_FEMALE = 'f'
    GENDER_MALE = 'm'
    GENDER_CHOICES = (
        (GENDER_OTHER, '---'),
        (GENDER_FEMALE, _('Female')),
        (GENDER_MALE, _('Male')),
        (GENDER_OTHER, _('Other')),
    )
    gender = models.CharField(_('"gender"'),
        max_length=2, blank=True, choices=GENDER_CHOICES, default=GENDER_OTHER)

    birth_date = models.DateField(_('birth date'),
        default=None, blank=True, null=True)

    country = models.CharField(_('country'),
        max_length=2, blank=True, choices=COUNTRY_CHOICES, default='ZZ')
    city = models.CharField(_('city'),
        max_length=255, blank=True, null=True)
    zipcode = models.CharField(_('zipcode'),
        max_length=255, blank=True, null=True)

    interests = TaggableManager(_('interests'),
        through=TaggedInterest, related_name='_interest', blank=True,
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))
    about = models.TextField(_('About you'),
        blank=True,
        null=True)
    ecobasa_what = models.TextField(_('What would you like to use ecobasa mainly for?'),
        blank=True, null=True)
    world = models.TextField(_('What do you do to make the world a better place?'),
        blank=True, null=True)

    # Offers
    skills = TaggableManager(_('Skills / Knowledge'),
        through=TaggedSkill, related_name='_skill', blank=True,
	help_text=_('What skills do you have? What can you do to help others? What can you teach someone? Connect two words with a "-" to have one tag.'))
    products = TaggableManager(_('Products'),
        through=TaggedProduct, related_name='_product', blank=True,
        help_text=_('Can you manufacture any products, like jewelery, furniture, clothes, soap etc.. ? Connect two words with a "-" to have one tag.'))

    # Wishlist
    wishlist = TaggableManager(_('Wishlist'),
        through=TaggedWishlist,
        related_name='_wishlist', 
        blank=True, 
        help_text=_('A comma-separated list of tags. You can type anything here. You can also chose from other users tags. Connect two words with a "-" to have one tag.'))

    # bus fields
    has_bus = models.BooleanField(
        _('Do you have a bus or car that you want to take on the tour?'),
        default=False, blank=True)
    bus_image = ThumbnailerImageField(_('bus_image'),
        upload_to='bus_images', null=True, blank=True)
    bus_has_driving_license = models.BooleanField(
        _('I have a driving license'), default=False, blank=True)
    bus_others_can_drive = models.BooleanField(
        _('Other people can drive it too'),
        default=False, blank=True)
    bus_num_passengers = models.PositiveIntegerField(
        _('How many people can it take'), null=True, blank=True, default=0)
    bus_consumption = models.PositiveIntegerField(
        _('Consumption (l/100km)'), null=True, blank=True, default=0)
    bus_transport = models.BooleanField(
        _('Can it transport gifts for the communities like materials, or tools?'), 
        default=True, blank=True)

    objects = BaseUserProfileManager()

    class Meta:
        app_label = 'ecobasa'
Exemplo n.º 19
0
class Event(BaseModel):
    class ACTIVITY_TYPES(object):
        WORKSHOP = 'Workshop'
        MEETING = 'Meeting'
        TALK = 'Talk'
        EVENT = 'Event'
        EXTERNAL = 'Others'
        EXPERIMENTA = 'Experimenta'

        choices = (
            (WORKSHOP, _('Workshop')),
            (MEETING, _('Meeting')),
            (TALK, _('Talk')),
            (EVENT, _('Event')),
            (EXTERNAL, _('Others')),
            (EXPERIMENTA, 'Experimenta'),
        )

        colors = {
            WORKSHOP: 'Workshop',
            MEETING: 'Meeting',
            TALK: 'Talk',
            EVENT: 'Event',
            EXTERNAL: 'others',
        }

    class Meta:
        ordering = ('-highlighted', 'start_date')

    # foreign keys
    region = models.ForeignKey(
        Region,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        verbose_name=_('region'),
    )
    county = models.ForeignKey(
        County,
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        verbose_name=_('county'),
    )
    experts = models.ManyToManyField(
        'users.User',
        verbose_name=_('experts'),
        related_name='%(app_label)s_%(class)s_experts',
        blank=True,
    )
    creator = models.ForeignKey(
        'users.User',
        verbose_name=_('creator'),
        related_name='created_events',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
    )
    manager = models.ForeignKey(
        'users.User',
        verbose_name=_('manager'),
        related_name='%(app_label)s_%(class)s_manager',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
    )
    participants = models.ManyToManyField(
        'users.User',
        verbose_name=_('participants'),
        related_name='%(app_label)s_%(class)s_participants',
        blank=True,
    )
    institutions = models.ManyToManyField(
        'institutions.Institution',
        verbose_name=_('institutions'),
        related_name='%(app_label)s_%(class)s_institutions',
        blank=True,
    )
    files = models.ManyToManyField(
        'documents.File',
        verbose_name=_('files'),
        related_name='%(app_label)s_%(class)s_files',
        blank=True,
    )
    photos = models.ManyToManyField(
        'documents.Photo',
        verbose_name=_('photos'),
        related_name='%(app_label)s_%(class)s_photos',
        blank=True,
    )
    # required fields
    name = models.CharField(
        _('name'),
        max_length=100,
    )
    description = models.TextField(
        _('description'),
    )
    what_does_it_consist_of = models.TextField(
        u'¿En qué consiste el taller/tipo de actividad?',
        default='',
    )
    tags = models.CharField(
        _('tags'),
        default='',
        max_length=255,
    )
    presentation = models.FileField(
        null=True,
        blank=True,
        upload_to=file_path,
    )
    address = models.CharField(
        _('address'),
        max_length=255,
    )
    place = models.CharField(
        _('place'),
        max_length=255,
        default='',
    )
    # optional fields
    start_date = models.DateTimeField(
        _('start date'),
        null=True,
        blank=True,
    )
    end_date = models.DateTimeField(
        _('final date'),
        null=True,
        blank=True,
    )
    principal_image = ThumbnailerImageField(
        _('principal image'),
        upload_to=file_path,
        null=True,
        blank=True,
    )
    activity_type = models.CharField(
        _('type of activity'),
        max_length=50,
        choices=ACTIVITY_TYPES.choices,
        default=ACTIVITY_TYPES.choices[0][0],
    )
    contact_email = models.EmailField(
        _('contact email'),
        null=True,
        blank=True,
    )
    url = models.URLField(
        _('url'),
        null=True,
        blank=True,
    )
    is_active = models.BooleanField(
        _('is active'),
        default=True,
    )
    acreditation = models.BooleanField(
        _('acreditation'),
        default=False,
    )
    quota = models.IntegerField(
        _('quota'),
        null=True,
        blank=True,
    )
    google_maps_iframe = models.TextField(
        _('google maps iframe'),
        default='',
        blank=True,
    )
    highlighted = models.BooleanField(
        _('highlighted'),
        default=False,
    )
    certification_text = models.TextField(
        _('certification text'),
        default='',
        blank=True,
    )
    objects = EventQueryset.as_manager()

    @classmethod
    def get_events_for_calendar(cls, user, start_date, end_date, **kwargs):
        """
        Get events for the calendar by date range
        """
        events = cls.objects.between_dates(
            start_date,
            end_date,
        ).filter(is_active=True)

        if not user.is_experimenta() and not user.is_staff:
            events = events.exclude(
                activity_type=Event.ACTIVITY_TYPES.EXPERIMENTA
            )

        if 'region_id' in kwargs and kwargs['region_id']:
            events = events.filter(region_id=kwargs['region_id'])

        if 'hide_events' in kwargs and kwargs['hide_events']:
            events = events.exclude(activity_type=cls.ACTIVITY_TYPES.EVENT)

        if 'hide_workshops' in kwargs and kwargs['hide_workshops']:
            events = events.exclude(activity_type=cls.ACTIVITY_TYPES.WORKSHOP)

        if 'hide_meetings' in kwargs and kwargs['hide_meetings']:
            events = events.exclude(activity_type=cls.ACTIVITY_TYPES.MEETING)

        if 'hide_talks' in kwargs and kwargs['hide_talks']:
            events = events.exclude(activity_type=cls.ACTIVITY_TYPES.TALK)

        if 'hide_experimenta' in kwargs and kwargs['hide_experimenta']:
            events = events.exclude(
                activity_type=cls.ACTIVITY_TYPES.EXPERIMENTA
            )

        res = []
        for event in events:
            if event.is_activity_active():
                event_dict = {}
                event_dict['title'] = event.name
                event_dict['start'] = timezone.localtime(event.start_date)
                event_dict['end'] = timezone.localtime(event.end_date)
                event_dict['type'] = event.activity_type.lower()
                event_dict['eventUrl'] = event.get_absolute_url()
                event_dict['startStr'] = timezone.localtime(
                    event.start_date).time().strftime('%H:%M')
                event_dict['endStr'] = timezone.localtime(
                    event.end_date).time().strftime('%H:%M')

                if event.region:
                    event_dict['region'] = event.region.name
                else:
                    event_dict['region'] = ''

                if event.county:
                    event_dict['county'] = event.county.name
                else:
                    event_dict['county'] = ''

                if not event.is_over():
                    stage = event.stage_set.active().get_current_stage()
                    if stage:
                        if stage.stage_type == stage.STAGE_TYPE_INSCRIPTION:
                            activity = event.get_base_activity()
                            event_dict['registerUrl'] = reverse(
                                'user_activity_create',
                                kwargs={'pk': activity.id},
                            )

                res.append(event_dict)
        return res

    def __unicode__(self):
        return self.name

    # django methods
    def get_absolute_url(self):
        return str(reverse(
            'event_detail', kwargs={
                'pk': self.pk
            }
        ))

    def save(self, *args, **kwargs):
        if self.name:
            self.name = self.name.strip()

        return super(Event, self).save(*args, **kwargs)

    # public methods
    def get_evaluation_average(self):
        return self.eventevaluation_set.all().aggregate(
            Avg('satisfaction')
        )['satisfaction__avg']

    def get_invitation_link(self, user, use_https=False):
        if not user.token:
            user.set_token()

        protocol = use_https and 'https' or 'http'

        path = reverse(
            'event_detail_with_login', kwargs={
                'pk': self.pk,
                'token': user.token,
                'email': user.email,
            }
        )

        domain = Site.objects.get_current().domain

        return '{}://{}{}'.format(protocol, domain, path)

    def get_activities_list_html(self, user):
        from activities.models import UserActivity

        # TODO: do this in a single query for Activities
        user_activities = UserActivity.objects.filter(
            activity__event=self,
            user=user,
        ).select_related('activity')

        activities = []
        for user_activity in user_activities:
            activity = user_activity.activity
            activities.append(activity)

        html = render_to_string(
            'emails/includes/activities_list.jade',
            context={
                'activities': activities,
            },
        ).replace('\n  ', '').replace('\n', '')
        return html

    def get_base_activity(self):
        if not self.activity_set.exists():
            self.activity_set.create(
                event=self,
                name=self.name,
                region_id=self.region_id,
                start_date=self.start_date,
                quota=self.quota,
            )
        return self.activity_set.first()

    def get_base_comments(self):
        comments = self.comment_set.base_comments()
        return comments.prefetch_related('comment_set', 'images')

    def get_stages(self):
        return self.stage_set.filter(is_active=True)

    def get_tags(self):
        return (tag.strip() for tag in self.tags.split(','))

    def is_over(self):
        if self.end_date:
            return self.end_date.date() < utils.today()
        return False

    def is_activity_active(self):
        stages = self.stage_set.all()
        activity = stages.filter(stage_type=Stage.STAGE_TYPE_ACTIVITY)
        # must be unique
        if activity.exists():
            return activity.first().is_active
        else:
            return True

    def is_experimenta(self):
        """
        Check if this event is an experimenta event
        """
        return self.activity_type == Event.ACTIVITY_TYPES.EXPERIMENTA

    @classmethod
    def add_user_to_experimenta_events(cls, user):
        """
        Add user to experimenta events
        """
        experimenta_events = cls.objects.filter(
            activity_type=cls.ACTIVITY_TYPES.EXPERIMENTA
        )

        for experimenta_event in experimenta_events:
            activity = experimenta_event.get_base_activity()
            activity.register_assistant(user)

    def add_experimenta_users(self):
        """
        Add experimenta users to this event
        """
        experimenta_users = User.experimenta_users()
        activity = self.get_base_activity()
        for user in experimenta_users:
            activity.register_assistant(user)

    @classmethod
    def generate(cls, quantity):
        fake = Faker()
        events = []
        for i in range(quantity):
            activity_type = Event.ACTIVITY_TYPES.choices[randint(0, 5)]
            event = {
                'name': fake.sentence(
                    nb_words=4, variable_nb_words=True, ext_word_list=None
                ),
                'description': fake.text(),
                'activity_type': activity_type[0],
                'get_activity_type_display': activity_type[1],
                'start_date': fake.date_time_this_month(),
            }
            events.append(event)

        return events

    @classmethod
    def get_dict_event_colors(cls):
        res = {}
        res[cls.ACTIVITY_TYPES.WORKSHOP] = '#F6A623'
        res[cls.ACTIVITY_TYPES.MEETING] = '#007AFF'
        res[cls.ACTIVITY_TYPES.TALK] = '#5856D6'
        res[cls.ACTIVITY_TYPES.EVENT] = '#FF2D55'
        res[cls.ACTIVITY_TYPES.EXTERNAL] = '#5AC8FA'
        res[cls.ACTIVITY_TYPES.EXPERIMENTA] = '#BBFFCC'
        return res
Exemplo n.º 20
0
class UserenaBaseProfile(models.Model):
    """ Base model needed for extra profile functionality """
    PRIVACY_CHOICES = (
        ('open', _('Open')),
        ('registered', _('Registered')),
        ('closed', _('Closed')),
    )

    MUGSHOT_SETTINGS = {'size': (userena_settings.USERENA_MUGSHOT_SIZE,
                                 userena_settings.USERENA_MUGSHOT_SIZE),
                        'crop': userena_settings.USERENA_MUGSHOT_CROP_TYPE}

    mugshot = ThumbnailerImageField(_('mugshot'),
                                    blank=True,
                                    upload_to=upload_to_mugshot,
                                    resize_source=MUGSHOT_SETTINGS,
                                    help_text=_('A personal image displayed in your profile.'))

    privacy = models.CharField(_('privacy'),
                               max_length=15,
                               choices=PRIVACY_CHOICES,
                               default=userena_settings.USERENA_DEFAULT_PRIVACY,
                               help_text=_('Designates who can view your profile.'))

    maxNumberOfInvitationTicket = models.IntegerField(default=3)

    invitedBy = models.ForeignKey('self',on_delete=models.SET_NULL,null=True,blank=True,related_name='invited_users' )

    objects = UserenaBaseProfileManager()


    class Meta:
        """
        Meta options making the model abstract and defining permissions.

        The model is ``abstract`` because it only supplies basic functionality
        to a more custom defined model that extends it. This way there is not
        another join needed.

        We also define custom permissions because we don't know how the model
        that extends this one is going to be called. So we don't know what
        permissions to check. For ex. if the user defines a profile model that
        is called ``MyProfile``, than the permissions would be
        ``add_myprofile`` etc. We want to be able to always check
        ``add_profile``, ``change_profile`` etc.

        """
        abstract = True
        permissions = PROFILE_PERMISSIONS

    def __str__(self):
        return 'Profile of %(username)s' % {'username': self.user.username}

    def get_mugshot_url(self):
        """
        Returns the image containing the mugshot for the user.

        The mugshot can be a uploaded image or a Gravatar.

        Gravatar functionality will only be used when
        ``USERENA_MUGSHOT_GRAVATAR`` is set to ``True``.

        :return:
            ``None`` when Gravatar is not used and no default image is supplied
            by ``USERENA_MUGSHOT_DEFAULT``.

        """
        # First check for a mugshot and if any return that.
        if self.mugshot:
            return self.mugshot.url

        # Use Gravatar if the user wants to.
        if userena_settings.USERENA_MUGSHOT_GRAVATAR:
            return get_gravatar(self.user.email,
                                userena_settings.USERENA_MUGSHOT_SIZE,
                                userena_settings.USERENA_MUGSHOT_DEFAULT)

        # Gravatar not used, check for a default image.
        else:
            if userena_settings.USERENA_MUGSHOT_DEFAULT not in ['404', 'mm',
                                                                'identicon',
                                                                'monsterid',
                                                                'wavatar']:
                return userena_settings.USERENA_MUGSHOT_DEFAULT
            else:
                return None

    def get_full_name_or_username(self):
        """
        Returns the full name of the user, or if none is supplied will return
        the username.

        Also looks at ``USERENA_WITHOUT_USERNAMES`` settings to define if it
        should return the username or email address when the full name is not
        supplied.

        :return:
            ``String`` containing the full name of the user. If no name is
            supplied it will return the username or email address depending on
            the ``USERENA_WITHOUT_USERNAMES`` setting.

        """
        user = self.user
        if user.first_name or user.last_name:
            # We will return this as translated string. Maybe there are some
            # countries that first display the last name.
            name = _("%(first_name)s %(last_name)s") % \
                {'first_name': user.first_name,
                 'last_name': user.last_name}
        else:
            # Fallback to the username if usernames are used
            if not userena_settings.USERENA_WITHOUT_USERNAMES:
                name = "%(username)s" % {'username': user.username}
            else:
                name = "%(email)s" % {'email': user.email}
        return name.strip()

    def can_view_profile(self, user):
        """
        Can the :class:`User` view this profile?

        Returns a boolean if a user has the rights to view the profile of this
        user.

        Users are divided into four groups:

            ``Open``
                Everyone can view your profile

            ``Closed``
                Nobody can view your profile.

            ``Registered``
                Users that are registered on the website and signed
                in only.

            ``Admin``
                Special cases like superadmin and the owner of the profile.

        Through the ``privacy`` field a owner of an profile can define what
        they want to show to whom.

        :param user:
            A Django :class:`User` instance.

        """
        # Simple cases first, we don't want to waste CPU and DB hits.
        # Everyone.
        if self.privacy == 'open':
            return True
        # Registered users.
        elif self.privacy == 'registered' \
        and isinstance(user, get_user_model()):
            return True

        # Checks done by guardian for owner and admins.
        elif 'view_profile' in get_perms(user, self):
            return True

        # Fallback to closed profile.
        return False
    def get_remaining_invite_tickets_number(self):
        if(self.user.has_perm('invite_user')):
            return self.maxNumberOfInvitationTicket-self.invited_users.all().count()
        return 0
Exemplo n.º 21
0
class Image(models.Model):
    """Represent an image in database"""
    class Meta:
        verbose_name = _('Image')
        verbose_name_plural = _('Images')

    gallery = models.ForeignKey('Gallery',
                                verbose_name=_('Galerie'),
                                db_index=True)
    title = models.CharField(_('Titre'), max_length=80)
    slug = models.SlugField(max_length=80)
    physical = ThumbnailerImageField(upload_to=image_path, max_length=200)
    legend = models.CharField(_('Légende'),
                              max_length=80,
                              null=True,
                              blank=True)
    pubdate = models.DateTimeField(_('Date de création'),
                                   auto_now_add=True,
                                   db_index=True)
    update = models.DateTimeField(_('Date de modification'),
                                  null=True,
                                  blank=True)

    def __init__(self, *args, **kwargs):
        super(Image, self).__init__(*args, **kwargs)

    def __str__(self):
        """Human-readable representation of the Image model.

        :return: Image slug
        :rtype: unicode
        """
        return self.slug

    def get_absolute_url(self):
        """URL of a single Image.

        :return: Image object URL
        :rtype: str
        """
        return '{0}/{1}'.format(settings.MEDIA_URL,
                                self.physical).replace('//', '/')

    def get_thumbnail_url(self):
        return self.physical['gallery'].url

    def get_extension(self):
        """Get the extension of an image (used in tests).

        :return: the extension of the image
        :rtype: unicode
        """
        return os.path.splitext(self.physical.name)[1][1:]

    @staticmethod
    def has_read_permission(request):
        return request.user.is_authenticated()

    def has_object_read_permission(self, request):
        return UserGallery.objects.filter(gallery=self.gallery,
                                          user=request.user).count() == 1

    @staticmethod
    def has_write_permission(request):
        return request.user.is_authenticated()

    def has_object_write_permission(self, request):
        return UserGallery.objects.filter(gallery=self.gallery,
                                          user=request.user,
                                          mode='W').count() == 1

    def save(self, *args, **kwargs):
        self.update = datetime.datetime.now()
        super().save(*args, **kwargs)
Exemplo n.º 22
0
class Slide(models.Model):
    SLIDE_SIMPLE = 'SS'
    SLIDE_WITH_BANNER = 'SB'
    SLIDE_TYPES_CHOICES = (
        (SLIDE_SIMPLE, 'Простой слайд'),
        (SLIDE_WITH_BANNER, 'Слайд с баннером'),
    )
    type = models.CharField(
        max_length=2,
        choices=SLIDE_TYPES_CHOICES,
        default=SLIDE_SIMPLE,
    )

    def get_upload_path(instance, filename):
        file_name, file_extension = os.path.splitext(filename)
        return os.path.join("media/slides/", strftime("%Y/%m/%d/"),
                            str(randint(10000000, 99999999)) + file_extension)

    background = ThumbnailerImageField(null=True,
                                       blank=True,
                                       verbose_name='Фон слайда',
                                       upload_to=get_upload_path,
                                       help_text='')

    def background_tag(self):
        if (self.background):
            thumb_url = get_thumbnailer(self.background.name)['admin'].url
            return mark_safe('<img src="%s" />' % thumb_url)
        return None

    background_tag.short_description = 'Загруженное изображение'
    background_tag.allow_tags = True

    def get_background_url(self):
        if (self.background):
            return get_thumbnailer(
                self.background.name)['slide_background'].url
        return None

    name = models.CharField(
        max_length=100,
        verbose_name='название слайда',
    )

    header = models.CharField(
        null=True,
        blank=True,
        max_length=100,
        verbose_name='заголовок баннера',
    )

    text1 = models.CharField(
        null=True,
        blank=True,
        max_length=100,
        verbose_name='текст 1-я строка баннера',
    )

    text2 = models.CharField(
        null=True,
        blank=True,
        max_length=100,
        verbose_name='текст 2-я строка баннера',
    )

    text3 = models.CharField(
        null=True,
        blank=True,
        max_length=100,
        verbose_name='текст 3-я строка баннера',
    )

    action_url = models.CharField(
        null=True,
        blank=True,
        max_length=200,
        verbose_name='URL действия',
        help_text='URL кнопки, телефона (в зависимости от макета)')

    action_text = models.CharField(
        null=True,
        blank=True,
        max_length=100,
        verbose_name='текст действия',
        help_text='текст кнопки, телефона (в зависимости от макета)')

    def __str__(self):
        return self.name

    def with_banner(self):
        return self.type == self.SLIDE_WITH_BANNER

    class Meta:
        verbose_name = 'Слайд'
        verbose_name_plural = 'Слайды'
Exemplo n.º 23
0
class Agency(models.Model, RequestHelper):
    """An agency for a particular jurisdiction that has at least one agency type"""

    name = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255)
    jurisdiction = models.ForeignKey(Jurisdiction, related_name='agencies')
    types = models.ManyToManyField(AgencyType, blank=True)
    status = models.CharField(choices=(
        ('pending', 'Pending'),
        ('approved', 'Approved'),
        ('rejected', 'Rejected'),
    ),
                              max_length=8,
                              default='pending')
    user = models.ForeignKey(User, null=True, blank=True)
    appeal_agency = models.ForeignKey('self', null=True, blank=True)
    can_email_appeals = models.BooleanField(default=False)
    payable_to = models.ForeignKey('self',
                                   related_name='receivable',
                                   null=True,
                                   blank=True)
    image = ThumbnailerImageField(upload_to='agency_images',
                                  blank=True,
                                  null=True,
                                  resize_source={
                                      'size': (900, 600),
                                      'crop': 'smart'
                                  })
    image_attr_line = models.CharField(blank=True,
                                       max_length=255,
                                       help_text='May use html')
    public_notes = models.TextField(blank=True, help_text='May use html')
    stale = models.BooleanField(default=False)
    manual_stale = models.BooleanField(
        default=False, help_text='For marking an agency stale by hand.')
    address = models.TextField(blank=True)
    location = PointField(blank=True)
    email = models.EmailField(blank=True)
    other_emails = fields.EmailsListField(blank=True, max_length=255)
    contact_salutation = models.CharField(blank=True, max_length=30)
    contact_first_name = models.CharField(blank=True, max_length=100)
    contact_last_name = models.CharField(blank=True, max_length=100)
    contact_title = models.CharField(blank=True, max_length=255)
    url = models.URLField(blank=True,
                          verbose_name='FOIA Web Page',
                          help_text='Begin with http://')
    phone = models.CharField(blank=True, max_length=30)
    fax = models.CharField(blank=True, max_length=30)
    notes = models.TextField(blank=True)
    aliases = models.TextField(blank=True)
    parent = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               related_name='children')

    website = models.CharField(max_length=255, blank=True)
    twitter = models.CharField(max_length=255, blank=True)
    twitter_handles = models.TextField(blank=True)
    foia_logs = models.URLField(blank=True,
                                verbose_name='FOIA Logs',
                                help_text='Begin with http://')
    foia_guide = models.URLField(blank=True,
                                 verbose_name='FOIA Processing Guide',
                                 help_text='Begin with http://')
    exempt = models.BooleanField(default=False)
    requires_proxy = models.BooleanField(default=False)

    objects = AgencyQuerySet.as_manager()

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        """The url for this object"""
        return reverse('agency-detail',
                       kwargs={
                           'jurisdiction': self.jurisdiction.slug,
                           'jidx': self.jurisdiction.pk,
                           'slug': self.slug,
                           'idx': self.pk,
                       })

    def save(self, *args, **kwargs):
        """Save the agency"""
        self.email = self.email.strip()
        self.slug = slugify(self.slug)
        self.name = self.name.strip()
        super(Agency, self).save(*args, **kwargs)

    def normalize_fax(self):
        """Return a fax number suitable for use with phaxio"""

        fax = ''.join(c for c in self.fax if c.isdigit())
        if len(fax) == 10:
            return '1' + fax
        if len(fax) == 11 and fax[0] == '1':
            return fax
        return None

    def get_email(self):
        """Returns an email address to send to"""

        if self.email:
            return self.email
        elif self.normalize_fax():
            return self.normalize_fax()
        else:
            return ''

    def get_other_emails(self):
        """Returns other emails as a list"""
        return fields.email_separator_re.split(self.other_emails)

    def link_display(self):
        """Returns link if approved"""
        if self.status == 'approved':
            return mark_safe('<a href="%s">%s</a>' %
                             (self.get_absolute_url(), self.name))
        else:
            return self.name

    def is_stale(self):
        """Should this agency be marked as stale?

        If the latest response to any open request is greater than STALE_DURATION
        days ago, or if no responses to any open request, if the oldest open
        request was sent greater than STALE_DURATION days ago.  If no open requests,
        do not mark as stale."""
        # check if agency is manually marked as stale
        if self.manual_stale:
            return True
        # find any open requests, if none, not stale
        foias = self.foiarequest_set.get_open().order_by('date_submitted')
        if not foias:
            return False
        # find the latest response to an open request
        latest_responses = []
        for foia in foias:
            response = foia.latest_response()
            if response:
                latest_responses.append(response)
        if latest_responses:
            return min(latest_responses) >= STALE_DURATION
        # no response to open requests, use oldest open request submit date
        return (date.today() - foias[0].date_submitted).days >= STALE_DURATION

    def mark_stale(self, manual=False):
        """Mark this agency as stale and create a StaleAgencyTask if one doesn't already exist."""
        self.stale = True
        self.manual_stale = manual
        self.save()
        try:
            task, created = StaleAgencyTask.objects.get_or_create(
                resolved=False, agency=self)
            if created:
                logger.info('Created new StaleAgencyTask <%d> for Agency <%d>',
                            task.pk, self.pk)
        except MultipleObjectsReturned as exception:
            # If there are multiple StaleAgencyTasks returned, just return the first one.
            # We only want this method to return a single task.
            # Also, log the exception as a warning.
            task = StaleAgencyTask.objects.filter(resolved=False,
                                                  agency=self).first()
            logger.warning(exception)
        return task

    def unmark_stale(self):
        """Unmark this agency as stale and resolve all of its StaleAgencyTasks."""
        self.stale = False
        self.manual_stale = False
        self.save()
        (StaleAgencyTask.objects.filter(resolved=False,
                                        agency=self).update(resolved=True))

    def count_thanks(self):
        """Count how many thanks this agency has received"""
        return (self.foiarequest_set.filter(
            communications__thanks=True).distinct().count())

    def get_requests(self):
        """Just returns the foiareqest_set value. Used for compatability with RequestHeper mixin"""
        return self.foiarequest_set

    def get_user(self):
        """Get the agency user for this agency"""
        try:
            return self.profile.user
        except Profile.DoesNotExist:
            user = User.objects.create_user(unique_username(self.name))
            Profile.objects.create(
                user=user,
                acct_type='agency',
                date_update=date.today(),
                agency=self,
            )
            return user

    def get_all_known_emails(self):
        """Get all emails we have associated with this agency"""
        emails = (FOIACommunication.objects.filter(
            foia__agency=self,
            response=True).distinct().values_list('priv_from_who',
                                                  flat=True).order_by())
        return [parseaddr(e)[1].lower() for e in emails if parseaddr(e)[1]]

    class Meta:
        # pylint: disable=too-few-public-methods
        verbose_name_plural = 'agencies'
Exemplo n.º 24
0
class Jurisdiction(models.Model, RequestHelper):
    """A jursidiction that you may file FOIA requests in"""

    levels = (('f', 'Federal'), ('s', 'State'), ('l', 'Local'))

    name = models.CharField(max_length=50)
    # slug should be slugify(unicode(self))
    slug = models.SlugField(max_length=55)
    full_name = models.CharField(max_length=55, blank=True)
    abbrev = models.CharField(max_length=5, blank=True)
    level = models.CharField(max_length=1, choices=levels)
    parent = models.ForeignKey('self',
                               related_name='children',
                               blank=True,
                               null=True)
    hidden = models.BooleanField(default=False)
    image = ThumbnailerImageField(upload_to='jurisdiction_images',
                                  blank=True,
                                  null=True)
    image_attr_line = models.CharField(blank=True,
                                       max_length=255,
                                       help_text='May use html')
    public_notes = models.TextField(blank=True, help_text='May use html')

    # non local
    days = models.PositiveSmallIntegerField(blank=True,
                                            null=True,
                                            help_text='How many days do they'
                                            ' have to respond?')
    observe_sat = models.BooleanField(
        default=False,
        help_text='Are holidays observed on Saturdays? '
        '(or are they moved to Friday?)')
    holidays = models.ManyToManyField(Holiday, blank=True)
    use_business_days = models.BooleanField(
        default=True,
        help_text='Response time in business days'
        ' (or calendar days)?')
    intro = models.TextField(blank=True,
                             help_text='Intro paragraph for request - '
                             'usually includes the pertinant FOI law')
    law_name = models.CharField(blank=True,
                                max_length=255,
                                help_text='The pertinant FOIA law')
    waiver = models.TextField(
        blank=True,
        help_text='Optional - custom waiver paragraph if '
        'FOI law has special line for waivers')
    has_appeal = models.BooleanField(
        default=True,
        help_text='Does this jurisdiction have an appeals process?')
    requires_proxy = models.BooleanField(default=False)
    law_analysis = models.TextField(
        blank=True,
        help_text='Our analysis of the state FOIA law, '
        'as a part of FOI95.')

    def __unicode__(self):
        if self.level == 'l' and not self.full_name and self.parent:
            self.full_name = '%s, %s' % (self.name, self.parent.abbrev)
            self.save()
            return self.full_name
        elif self.level == 'l':
            return self.full_name
        else:
            return self.name

    def __repr__(self):
        return '<Jurisdiction: %d>' % self.pk

    def get_absolute_url(self):
        """The url for this object"""
        return reverse('jurisdiction-detail', kwargs=self.get_slugs())

    def get_slugs(self):
        """Return a dictionary of slugs for this jurisdiction, for constructing URLs."""
        slugs = {}
        if self.level == 'l':
            slugs.update({
                'fed_slug': self.parent.parent.slug,
                'state_slug': self.parent.slug,
                'local_slug': self.slug
            })
        elif self.level == 's':
            slugs.update({
                'fed_slug': self.parent.slug,
                'state_slug': self.slug
            })
        elif self.level == 'f':
            slugs.update({'fed_slug': self.slug})
        return slugs

    def get_url(self, view):
        """The url for this object"""
        view = 'jurisdiction-%s' % view
        slugs = self.get_slugs()
        return reverse(view, kwargs=slugs)

    def save(self, *args, **kwargs):
        """Normalize fields before saving"""
        self.slug = slugify(self.slug)
        self.name = self.name.strip()
        super(Jurisdiction, self).save(*args, **kwargs)

    def get_url_flag(self):
        """So we can call from template"""
        return self.get_url('flag')

    def legal(self):
        """Return the jurisdiction abbreviation for which law this jurisdiction falls under"""
        if self.level == 'l':
            return self.parent.abbrev
        else:
            return self.abbrev

    def get_days(self):
        """How many days does an agency have to reply?"""
        if self.level == 'l':
            return self.parent.days
        else:
            return self.days

    def get_day_type(self):
        """Does this jurisdiction use business or calendar days?"""
        if self.level == 'l':
            return 'business' if self.parent.use_business_days else 'calendar'
        else:
            return 'business' if self.use_business_days else 'calendar'

    def get_intro(self):
        """Intro for requests"""
        if self.level == 'l':
            return self.parent.intro
        else:
            return self.intro

    def get_waiver(self):
        """Waiver paragraph for requests"""
        if self.level == 'l':
            return self.parent.waiver
        else:
            return self.waiver

    def get_law_name(self):
        """The law name for the jurisdiction"""
        if self.level == 'l':
            return self.parent.law_name
        else:
            return self.law_name

    def get_calendar(self):
        """Get a calendar of business days for the jurisdiction"""
        if self.level == 'l' and not self.parent.use_business_days:
            return Calendar()
        elif self.level == 'l' and self.parent.use_business_days:
            return HolidayCalendar(self.parent.holidays.all(),
                                   self.parent.observe_sat)
        elif not self.use_business_days:
            return Calendar()
        else:
            return HolidayCalendar(self.holidays.all(), self.observe_sat)

    def get_proxy(self):
        """Get a random proxy user for this jurisdiction"""
        from muckrock.accounts.models import Profile
        proxy = (Profile.objects.filter(
            acct_type='proxy',
            state=self.legal()).order_by('-preferred_proxy').first())
        if proxy:
            return proxy.user
        else:
            return None

    def get_state(self):
        """The state name for the jurisdiction"""
        # pylint: disable=no-member
        if self.level == 'l':
            return self.parent.name
        else:
            return self.name

    def can_appeal(self):
        """Can you appeal to this jurisdiction?"""
        if self.level == 'l':
            return self.parent.has_appeal
        else:
            return self.has_appeal

    def get_requests(self):
        """State level jurisdictions should return requests from their localities as well."""
        if self.level == 's':
            requests = FOIARequest.objects.filter(
                Q(jurisdiction=self) | Q(jurisdiction__parent=self))
        else:
            requests = FOIARequest.objects.filter(jurisdiction=self)
        return requests.exclude(status='started')

    class Meta:
        # pylint: disable=too-few-public-methods
        ordering = ['name']
        unique_together = ('slug', 'parent')
Exemplo n.º 25
0
class Employee(models.Model):
    """
        Сотрудник
    """
    GENDER_CHOICES = (
        ('m', 'мужчина'),
        ('f', 'женщина'),
    )

    last_name = models.CharField(
        _('Фамилия'),
        max_length=255,
        blank=False, null=False,
        default='',
    )
    first_name = models.CharField(
        _('Имя'),
        max_length=255,
        blank=False, null=False,
        default='',
    )
    middle_name = models.CharField(
        _('Отчество'),
        max_length=255,
        blank=True, null=True,
    )
    address = models.CharField(
        _('Адрес проживания'),
        max_length=2000,
        blank=True, null=True,
    )
    birth_date = models.DateField(
        _('Дата рождения'),
        blank=False, null=False,
        default=datetime.date.today,
    )
    gender = models.CharField(
        _('Пол'),
        max_length=1,
        choices=GENDER_CHOICES,
        blank=True, null=True,
    )
    disability = models.BooleanField(
        _('Инвалидность'),
        blank=True, null=True,
    )
    employment_date = models.DateField(
        _('Дата приема на работу'),
        blank=False, null=False,
        default=datetime.date.today,
    )
    pers_number = models.CharField(
        _('Табельный номер'),
        max_length=255,
        blank=True, null=True,
    )
    avatar = ThumbnailerImageField(
        _('Аватарка'),
        upload_to ='avatars/',
        blank=True, null=True,
        resize_source=dict(size=(128, 128), sharpen=True),
    )
    insurance_number = models.CharField(
        _('Страховой номер (СНИЛС)'),
        max_length=255,
        blank=True, null=True,
    )
    workplace = models.ManyToManyField(
        Workplace,
        verbose_name=_('Рабочее место'),
        related_name='employees',
    )
    fire_date = models.DateField(
        _('Дата увольнения'),
        blank=True, null=True,
    )
    company = models.ForeignKey(
        Company,
        on_delete=models.PROTECT,
        blank=False, null=False,
        verbose_name=_('Компания'),
    )

    class Meta:
        db_table = 'employee'
        verbose_name = 'Сотрудник'
        verbose_name_plural = 'Сотрудники'

    def __str__(self):
        return '{} {} {}'.format(self.last_name, self.first_name, self.middle_name if self.middle_name else '')

    def company_name(self):
        return self.company.name
class Profile(models.Model):
    # Gênero
    MASCULINO = 1
    FEMININO = 2

    # Papel
    UNKNOWN = 0
    ADMINISTRATOR = 1
    ASSISTANT_PROFESSOR = 2
    STUDENT = 3
    PROFESSOR = 4
    SUPERVISOR = 5
    RESPOSIBLE = 6
    GESTOR_ESCOLAR = 7
    SUPER_ENSINO_USER = 8

    ROLE_CHOICES = (
        (ADMINISTRATOR, 'Administrador'),
        (ASSISTANT_PROFESSOR, 'Professor Assistente'),
        (STUDENT, 'Aluno'),
        (PROFESSOR, 'Professor'),
        (SUPERVISOR, 'Supervisor'),
        (RESPOSIBLE, 'Responsável'),
        (GESTOR_ESCOLAR, 'Gestor Escolar'),
        (SUPER_ENSINO_USER, 'Super Ensino User'),
    )

    GENERO_OPCOES = (
        (MASCULINO, 'Masculino'),
        (FEMININO, 'Feminino'),
    )

    user = models.OneToOneField(get_user_model(),
                                on_delete=models.CASCADE,
                                blank=True,
                                null=True)
    role = models.PositiveSmallIntegerField(choices=ROLE_CHOICES,
                                            null=True,
                                            blank=True)
    genero = models.PositiveSmallIntegerField(choices=GENERO_OPCOES,
                                              default=MASCULINO,
                                              null=True,
                                              blank=True)
    imagem = ThumbnailerImageField(
        upload_to='profile/%Y/%m/%d/',
        blank=True,
        null=True,
        default='static/img/default_avatar_male.jpg')

    @classmethod
    def create_profile(cls, baseclass, username, password, nome, email):
        """Cria um novo perfil de usuário no sistema

        O perfil do usário é definido pelo valor de role e do tipo da class
        passado em baseclass.

        Ex: Para criar um novo perfil de aluno
            novo_aluno = Aluno.create_profile(Aluno, ...)
        """
        user = get_user_model()()
        user.username = username
        user.set_password(password)
        user.email = email
        user.save()

        if type(baseclass) is Aluno:
            role = cls.STUDENT
        elif type(baseclass) is Responsavel:
            role = cls.RESPOSIBLE
        elif type(baseclass) is Professor:
            role = cls.PROFESSOR
        elif type(baseclass) is Gestor:
            role = cls.GESTOR_ESCOLAR
        else:
            role = cls.UNKNOWN

        instance = baseclass(user=user, nome=nome, role=role)
        instance.save()
        return instance

    def __str__(self):
        return self.user.username

    def get_username(self):
        if self.user is not None:
            return self.user.username
        return ''

    def get_baseclass(self):
        string_class = [v for k, v in self.ROLE_CHOICES if k == self.role][0]
        if string_class == 'Gestor Escolar':
            string_class = 'Gestor'
        if string_class == 'Responsável':
            string_class = 'Responsavel'
        return eval(string_class).objects.get(user=self.user)
Exemplo n.º 27
0
class Profile(models.Model):
    """User profile information for muckrock"""
    # pylint: disable=too-many-public-methods
    # pylint: disable=too-many-instance-attributes

    email_prefs = (
        ('never', 'Never'),
        ('hourly', 'Hourly'),
        ('daily', 'Daily'),
        ('weekly', 'Weekly'),
        ('monthly', 'Monthly'),
    )

    user = models.OneToOneField(User)
    source = models.CharField(
            max_length=20,
            blank=True,
            choices=(
                ('foia machine', 'FOIA Machine'),
                ),
            )

    address1 = models.CharField(
        max_length=50,
        blank=True,
        verbose_name='address'
    )
    address2 = models.CharField(
        max_length=50,
        blank=True,
        verbose_name='address (line 2)'
    )
    city = models.CharField(max_length=60, blank=True)
    state = USStateField(
        blank=True,
        help_text=('Your state will be made public on this site.'
                   'If you do not want this information to be public,'
                   ' please leave blank.')
    )
    zip_code = models.CharField(max_length=10, blank=True)
    phone = PhoneNumberField(blank=True)
    acct_type = models.CharField(max_length=10, choices=ACCT_TYPES)
    organization = models.ForeignKey(
        'organization.Organization',
        blank=True,
        null=True,
        related_name='members',
        on_delete=models.SET_NULL)

    # extended information
    profile = models.TextField(blank=True)
    location = models.ForeignKey('jurisdiction.Jurisdiction', blank=True, null=True)
    public_email = models.EmailField(max_length=255, blank=True)
    pgp_public_key = models.TextField(blank=True)
    website = models.URLField(
        max_length=255,
        blank=True,
        help_text='Begin with http://'
    )
    twitter = models.CharField(max_length=255, blank=True)
    linkedin = models.URLField(
        max_length=255,
        blank=True,
        help_text='Begin with http://'
    )
    avatar = ThumbnailerImageField(
        upload_to='account_images',
        blank=True, null=True,
        resize_source={'size': (600, 600), 'crop': 'smart'},
        storage=get_image_storage(),
    )

    # provide user access to experimental features
    experimental = models.BooleanField(default=False)
    # email confirmation
    email_confirmed = models.BooleanField(default=False)
    confirmation_key = models.CharField(max_length=24, blank=True)
    # email preferences
    email_pref = models.CharField(
        max_length=10,
        choices=email_prefs,
        default='daily',
        verbose_name='Digest Frequency',
        help_text=('Receive updates on site activity as an emailed digest.')
    )
    use_autologin = models.BooleanField(
        default=True,
        help_text=('Links you receive in emails from us will contain'
                   ' a one time token to automatically log you in')
    )
    # notification preferences
    new_question_notifications = models.BooleanField(default=False)

    org_share = models.BooleanField(
            default=False,
            verbose_name='Share',
            help_text='Let other members of my organization view '
            'my embargoed requests',
            )

    # paid for requests
    num_requests = models.IntegerField(default=0)
    # for limiting # of requests / month
    monthly_requests = models.IntegerField(default=0)
    date_update = models.DateField()
    # for Stripe
    customer_id = models.CharField(max_length=255, blank=True)
    subscription_id = models.CharField(max_length=255, blank=True)
    payment_failed = models.BooleanField(default=False)

    preferred_proxy = models.BooleanField(
            default=False,
            help_text='This user will be used over other proxies in the same '
            'state.  The account must still be set to type proxy for this to '
            'take affect')

    # for agency users
    agency = models.OneToOneField(
        'agency.Agency',
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
        )

    def __unicode__(self):
        return u"%s's Profile" % unicode(self.user).capitalize()

    def get_absolute_url(self):
        """The url for this object"""
        return reverse('acct-profile', kwargs={'username': self.user.username})

    def is_advanced(self):
        """Advanced users can access features basic users cannot."""
        advanced_types = ['admin', 'beta', 'pro', 'proxy']
        return self.acct_type in advanced_types or self.is_member_of_active_org()

    def is_member_of(self, organization):
        """Answers whether the profile is a member of the passed organization"""
        return self.organization_id == organization.pk

    def is_member_of_active_org(self):
        """Answers whether the user is a member of an active organization"""
        return self.organization is not None and self.organization.active

    def can_multirequest(self):
        """Is this user allowed to multirequest?"""
        return self.is_advanced()

    def can_view_emails(self):
        """Is this user allowed to view all emails and private contact information?"""
        return self.is_advanced()

    def get_monthly_requests(self):
        """Get the number of requests left for this month"""
        not_this_month = self.date_update.month != date.today().month
        not_this_year = self.date_update.year != date.today().year
        # update requests if they have not yet been updated this month
        if not_this_month or not_this_year:
            self.date_update = date.today()
            self.monthly_requests = settings.MONTHLY_REQUESTS.get(self.acct_type, 0)
            self.save()
        return self.monthly_requests

    def total_requests(self):
        """Get sum of paid for requests and monthly requests"""
        org_reqs = self.organization.get_requests() if self.organization else 0
        return self.num_requests + self.get_monthly_requests() + org_reqs

    def make_request(self):
        """Decrement the user's request amount by one"""
        organization = self.organization
        if organization and organization.get_requests() > 0:
            organization.num_requests -= 1
            organization.save()
            return True
        if self.get_monthly_requests() > 0:
            self.monthly_requests -= 1
        elif self.num_requests > 0:
            self.num_requests -= 1
        else:
            return False
        self.save()
        return True

    def multiple_requests(self, num):
        """How many requests of each type would be used for this user to make num requests"""
        request_dict = {
            'org_requests': 0,
            'monthly_requests': 0,
            'reg_requests': 0,
            'extra_requests': 0
        }
        org_reqs = self.organization.get_requests() if self.organization else 0
        if org_reqs > num:
            request_dict['org_requests'] = num
            return request_dict
        else:
            request_dict['org_requests'] = org_reqs
            num -= org_reqs
        monthly = self.get_monthly_requests()
        if monthly > num:
            request_dict['monthly_requests'] = num
            return request_dict
        else:
            request_dict['monthly_requests'] = monthly
            num -= monthly
        if self.num_requests > num:
            request_dict['reg_requests'] = num
            return request_dict
        else:
            request_dict['reg_requests'] = self.num_requests
            request_dict['extra_requests'] = num - self.num_requests
            return request_dict

    def bundled_requests(self):
        """Returns the number of requests the user gets when they buy a bundle."""
        how_many = settings.BUNDLED_REQUESTS[self.acct_type]
        if self.is_member_of_active_org():
            how_many = 5
        return how_many

    def customer(self):
        """Retrieve the customer from Stripe or create one if it doesn't exist. Then return it."""
        # pylint: disable=redefined-variable-type
        try:
            if not self.customer_id:
                raise AttributeError('No Stripe ID')
            customer = stripe_retry_on_error(
                    stripe.Customer.retrieve,
                    self.customer_id,
                    )
        except (AttributeError, stripe.InvalidRequestError):
            customer = stripe_retry_on_error(
                    stripe.Customer.create,
                    description=self.user.username,
                    email=self.user.email,
                    idempotency_key=True,
                    )
            self.customer_id = customer.id
            self.save()
        return customer

    def card(self):
        """Retrieve the default credit card from Stripe, if one exists."""
        card = None
        customer = self.customer()
        if customer.default_source:
            card = stripe_retry_on_error(
                    customer.sources.retrieve,
                    customer.default_source,
                    )
        return card

    def has_subscription(self):
        """Check Stripe to see if this user has any active subscriptions."""
        customer = self.customer()
        return customer.subscriptions.total_count > 0

    def start_pro_subscription(self, token=None):
        """Subscribe this profile to a professional plan. Return the subscription."""
        # create the stripe subscription
        customer = self.customer()
        if self.subscription_id:
            raise AttributeError('Only allowed one active subscription at a time.')
        if not token and not customer.default_source:
            raise AttributeError('No payment method provided for this subscription.')
        subscription = stripe_retry_on_error(
                customer.subscriptions.create,
                plan='pro',
                source=token,
                idempotency_key=True,
                )
        stripe_retry_on_error(customer.save, idempotency_key=True)
        # modify the profile object (should this be part of a webhook callback?)
        self.subscription_id = subscription.id
        self.acct_type = 'pro'
        self.date_update = date.today()
        self.monthly_requests = settings.MONTHLY_REQUESTS.get('pro', 0)
        self.save()
        return subscription

    def cancel_pro_subscription(self):
        """Unsubscribe this profile from a professional plan. Return the cancelled subscription."""
        customer = self.customer()
        subscription = None
        # subscription reference either exists as a saved field or inside the Stripe customer
        # if it isn't, then they probably don't have a subscription. in that case, just make
        # sure that we demote their account and reset them back to basic.
        try:
            if not self.subscription_id and not len(customer.subscriptions.data) > 0:
                raise AttributeError('There is no subscription to cancel.')
            if self.subscription_id:
                subscription_id = self.subscription_id
            else:
                subscription_id = customer.subscriptions.data[0].id
            subscription = stripe_retry_on_error(
                    customer.subscriptions.retrieve,
                    subscription_id,
                    )
            subscription = subscription.delete()
            customer = stripe_retry_on_error(customer.save, idempotency_key=True)
        except AttributeError as exception:
            logger.warn(exception)
        except stripe.error.StripeError as exception:
            logger.warn(exception)
        self.subscription_id = ''
        self.acct_type = 'basic'
        self.monthly_requests = settings.MONTHLY_REQUESTS.get('basic', 0)
        self.payment_failed = False
        self.save()
        return subscription

    def pay(self, token, amount, metadata, fee=PAYMENT_FEE):
        """
        Creates a Stripe charge for the user.
        Should always expect a 1-cent based integer (e.g. $1.00 = 100)
        Should apply a baseline fee (5%) to all payments.
        """
        # pylint: disable=no-self-use
        modified_amount = int(amount + (amount * fee))
        if not metadata.get('email') or not metadata.get('action'):
            raise ValueError('The charge metadata is malformed.')
        stripe_retry_on_error(
                stripe.Charge.create,
                amount=modified_amount,
                currency='usd',
                source=token,
                metadata=metadata,
                idempotency_key=True,
                )

    def generate_confirmation_key(self):
        """Generate random key used for validating the email address"""
        key = generate_key(24)
        self.confirmation_key = key
        self.save()
        return key

    def autologin(self):
        """Generate an autologin key and value for this user if they set this preference."""
        autologin_dict = {}
        if self.use_autologin:
            lot = LOT.objects.create(user=self.user, type='slow-login')
            autologin_dict = {settings.LOT_MIDDLEWARE_PARAM_NAME: lot.uuid}
        return autologin_dict

    def wrap_url(self, link, **extra):
        """Wrap a URL for autologin"""
        extra.update(self.autologin())
        return link + '?' + urlencode(extra)

    def limit_attachments(self):
        """Does this user need to have their attachments limited?"""
        return self.acct_type not in ('admin', 'agency')
Exemplo n.º 28
0
class User(AbstractBaseUser, PermissionsMixin, AuditModel):

    username = models.CharField(
        'Usuário',
        max_length=30,
        default=uuid.uuid4,
        unique=True,
        validators=[
            validators.RegexValidator(
                re.compile('^[\w.@+-]+$'),
                'Informe um nome de usuário válido. '
                'Este valor deve conter apenas letras, números '
                'e os caracteres: @/./+/-/_ .', 'invalid')
        ],
        help_text=
        'Um nome curto que será usado para identificá-lo de forma única na plataforma'
    )

    name = models.CharField('Nome', max_length=100, blank=False, null=False)
    email = models.EmailField('E-mail', unique=True, blank=False, null=False)
    is_staff = models.BooleanField('Equipe', default=False)
    is_active = models.BooleanField('Ativo', default=True)
    is_superuser = models.BooleanField('Super-Usuário', default=False)
    date_joined = models.DateTimeField('Data de Entrada', auto_now_add=True)
    cpf = models.CharField('CPF', max_length=14, blank=True, null=True)
    MALE = 'M'
    FEMALE = 'F'
    SEX_CHOICES = (
        (MALE, 'Masculino'),
        (FEMALE, 'Feminino'),
    )
    sex = models.CharField('Sexo',
                           max_length=1,
                           choices=SEX_CHOICES,
                           default=FEMALE)

    phone = models.CharField('Celular', max_length=16, blank=True, null=True)
    is_whatsapp = models.BooleanField('O celular é WhatsApp?', default=False)

    avatar = ThumbnailerImageField(upload_to="avatar",
                                   blank=True,
                                   resize_source=dict(size=(215, 215),
                                                      crop=True))

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = 'Usuário'
        verbose_name_plural = 'Usuários'
        ordering = ['name']

    def __str__(self):
        return self.name or self.username

    def get_full_name(self):
        return str(self)

    def get_short_name(self):
        return str(self).split(" ")[0]
Exemplo n.º 29
0
class LandingPage(models.Model):
    BODY_TYPES = {
        "city_council": _("Міська рада"),
        "regional_council": _("Обласна рада"),
        "other": _("Інше"),
    }
    slug = models.SlugField("Ідентифікатор сторінки",
                            primary_key=True,
                            max_length=100)
    title = models.CharField("Заголовок сторінки", max_length=200)
    description = RichTextField("Опис сторінки", blank=True)
    title_en = models.CharField("Заголовок сторінки [en]",
                                max_length=200,
                                blank=True)
    description_en = RichTextField("Опис сторінки [en]", blank=True)
    image = ThumbnailerImageField(blank=True, upload_to="landings")
    region = models.ForeignKey(Region,
                               blank=True,
                               null=True,
                               on_delete=models.SET_NULL)
    body_type = models.CharField(
        "Тип держоргану",
        blank=True,
        null=True,
        choices=BODY_TYPES.items(),
        max_length=30,
    )

    keywords = models.TextField(
        "Ключові слова для пошуку в деклараціях (по одному запиту на рядок)",
        blank=True)

    def pull_declarations(self):
        for p in self.persons.select_related("body").prefetch_related(
                "declarations"):
            p.pull_declarations()

    def get_summary(self):
        persons = {}
        min_years = []
        max_years = []
        for p in self.persons.select_related("body").prefetch_related(
                "declarations"):
            summary = p.get_summary()

            if "min_year" in summary:
                min_years.append(summary["min_year"])

            if "max_year" in summary:
                max_years.append(summary["max_year"])

            persons[p.pk] = summary

        return {
            "max_year": max(max_years),
            "min_year": min(min_years),
            "persons": persons,
        }

    def __str__(self):
        return "%s (%s)" % (self.title, self.slug)

    def get_absolute_url(self):
        return reverse("landing_page_details", kwargs={"pk": self.pk})

    class Meta:
        verbose_name = "Лендінг-сторінка"
        verbose_name_plural = "Лендінг-сторінки"
Exemplo n.º 30
0
class LBForumUserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL,
                                related_name='lbforum_profile',
                                verbose_name=_('User'))

    nickname = models.CharField(_("Nickname"),
                                max_length=255,
                                blank=False,
                                default='')
    avatar = ThumbnailerImageField(_("Avatar"),
                                   upload_to='imgs/avatars',
                                   blank=True,
                                   null=True)
    my_like_classes = models.CharField(max_length=2000, default="[]")
    my_taken_classes = models.CharField(max_length=2000, default="[]")
    friends = models.CharField(max_length=2000, default='[]')

    chatList = models.CharField(max_length=2000, default='{}')

    bio = models.TextField(blank=True)

    def __str__(self):
        return self.nickname or self.user.username

    def change_class(self, class_id, new_att):
        like_classes = self.get_like_classes()
        taken_classes = self.get_taken_classes()
        old = "not interested"
        if class_id in like_classes:
            like_classes.remove(class_id)
            old = "like"
        if class_id in taken_classes:
            taken_classes.remove(class_id)
            old = "taken"
        if new_att == "taken":
            taken_classes.append(class_id)
        if new_att == "like":
            like_classes.append(class_id)
        self.set_class(like_classes, 1)
        self.set_class(taken_classes, 2)
        return old

    def add_friend(self, user_id):
        friends = self.get_friend()
        if user_id not in friends:
            friends.append(user_id)
        self.set_friend(friends)

    def get_like_classes(self):
        return json.loads(self.my_like_classes)

    def get_taken_classes(self):
        return json.loads(self.my_taken_classes)

    def get_class(self):
        classes = self.get_like_classes() + self.get_taken_classes()
        classes = list(set(classes))
        return classes

    def set_class(self, x, op):
        if op == 1:
            self.my_like_classes = json.dumps(x)
        else:
            self.my_taken_classes = json.dumps(x)
        self.save()

    def get_chat_list(self):
        return json.loads(self.chatList)

    def add_chat(self, other, topic_id):
        chat_list = self.get_chat_list()
        if other not in chat_list.keys():
            chat_list[other] = topic_id
        self.chatList = json.dumps(chat_list)
        self.save()

    def get_friend(self):
        return json.loads(self.friends)

    def set_friend(self, x):
        self.friends = json.dumps(x)
        self.save()

    def get_total_topics(self):
        return self.user.topic_set.count()

    def get_total_posts(self):
        return self.user.post_set.count()

    def get_absolute_url(self):
        return self.user.get_absolute_url()

    def get_avatar_url(self, size=48):
        if not self.avatar:
            return '%s%s' % (
                settings.STATIC_URL,
                'lbforum/imgs/avatar.png',
            )
        options = {'size': (size, size), 'crop': True}
        return get_thumbnailer(self.avatar).get_thumbnail(options).url

    def get_large_avatar_url(self):
        return self.get_avatar_url(80)
Exemplo n.º 31
0
class CustomUser(AbstractUser):
    middle_name = models.CharField(max_length=hardcode.user_middlename_length,
                                   blank=True,
                                   null=True,
                                   verbose_name=_ug('Middle Name'))
    mothers_name = models.CharField(
        max_length=hardcode.user_mothersname_length,
        blank=True,
        null=True,
        verbose_name=_ug('Mothers Name'))
    nickname = models.CharField(max_length=hardcode.user_nickname_length,
                                blank=True,
                                null=True,
                                verbose_name=_ug('Nickname'))
    skype = models.CharField(max_length=hardcode.user_skype_length,
                             blank=True,
                             null=True,
                             verbose_name=_ug('Skype'))
    company = models.ForeignKey(Company,
                                related_name='employees',
                                blank=True,
                                null=True,
                                verbose_name=_ug('Company'))
    supervisor = models.ForeignKey('CustomUser',
                                   related_name='subordinates',
                                   blank=True,
                                   null=True,
                                   verbose_name=_ug('Supervisor'))
    avatar = ThumbnailerImageField(upload_to=hardcode.user_avatar_upload,
                                   default=hardcode.user_default_photo,
                                   blank=True,
                                   null=True,
                                   verbose_name=_ug('Profile picture'))
    birthday = models.DateField(blank=True,
                                null=True,
                                verbose_name=_ug('Birthday'))
    # gender = models.IntegerField(
    #     default=hardcode.GENDER_UNDEFINED,
    #     choices=hardcode.GENDER,
    #     blank=True,
    #     null=True,
    #     verbose_name=_ug('Gender')
    # )
    edition_date = models.DateTimeField(auto_now=True,
                                        verbose_name=_ug('Last edition date'))
    role = models.ManyToManyField(Role,
                                  related_name='customusers',
                                  verbose_name=_ug('Custom users'))

    class Meta:
        verbose_name = _ug('User')
        verbose_name_plural = _ug('Users')
        permissions = (
            ('query_customuser', 'Query User'),
            ('list_customuser', 'List Users'),
        )

    def save(self, *args, **kwargs):
        if self.pk is None:
            avatar = self.avatar
            self.avatar = None
            super(CustomUser, self).save(*args, **kwargs)
            self.avatar = avatar
        super(CustomUser, self).save(*args, **kwargs)

    def delete(self, *args):
        if self.active is False:
            super(CustomUser, self).delete(*args)
        else:
            self.active = False
            self.save()

    def __str__(self):
        return "%s - %s %s" % (self.username, self.first_name, self.last_name)

    def get_full_name(self):
        full_name = '%s %s %s %s' % (self.first_name, self.middle_name,
                                     self.last_name, self.mothers_name)
        return full_name.strip()

    def get_username(self):
        return "%s" % self.username

    def get_nickname(self):
        return "%s" % self.nickname

    def get_short_name(self):
        if self.nickname is None or self.nickname == '':
            return "%s" % self.username
        return self.get_nickname()

    def is_authorized(self):
        return self.is_active

    def is_admin(self):
        return self.is_staff

    def is_super(self):
        return self.is_superuser