Пример #1
0
class StudyGroup(BasePage):
    """
    StudyGroups Plugin. Similar to Pages with extra fields.
    """

    mission = tinymce_models.HTMLField(null=True, blank=True)
    notes = tinymce_models.HTMLField(null=True, blank=True)
    contact_name = models.CharField(max_length=200, null=True, blank=True)
    contact_email = models.CharField(max_length=200, null=True, blank=True)
    join_link = models.CharField(max_length=200, null=True, blank=True)
    group = models.ForeignKey(Group)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = StudyGroupManager()

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

    class Meta:
        permissions = (("view_studygroup", "Can view studygroup"), )
        app_label = 'studygroups'

    @models.permalink
    def get_absolute_url(self):
        return ("studygroups.detail", [self.slug])

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        meta information niche to this model.
        """
        return StudyGroupMeta().get_meta(self, name)

    def officers(self):
        return Officer.objects.filter(study_group=self).order_by('pk')
Пример #2
0
class Committee(BasePage):
    """
    Committees Plugin. Similar to Pages with extra fields.
    """
    slug = SlugField(_('URL Path'), unique=True)
    mission = tinymce_models.HTMLField(null=True, blank=True)
    notes = tinymce_models.HTMLField(null=True, blank=True)
    sponsors = tinymce_models.HTMLField(blank=True, default='')
    contact_name = models.CharField(max_length=200, null=True, blank=True)
    contact_email = models.CharField(max_length=200, null=True, blank=True)
    join_link = models.CharField(max_length=200, null=True, blank=True)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = CommitteeManager()

    def __str__(self):
        return str(self.title)

    class Meta:
        #         permissions = (("view_committee", "Can view committee"),)
        app_label = 'committees'

    def get_absolute_url(self):
        return reverse('committees.detail', args=[self.slug])

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        meta information niche to this model.
        """
        return CommitteeMeta().get_meta(self, name)

    def officers(self):
        return Officer.objects.filter(committee=self).order_by('pk')
Пример #3
0
class EmergencyAnnouncement(TendenciBaseModel):
    title = models.CharField(_('Title'), max_length=250)
    content = tinymce_models.HTMLField(_('Content'))
    enabled = models.BooleanField(_('Enabled'), default=True)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")
    objects = EmergencyAnnouncementManager()

    class Meta:
        #         permissions = (("view_emergencyannouncement",_("Can view emergency announcement")),)
        verbose_name = _('Emergency Announcement')
        verbose_name_plural = _('Emergency Announcements')

    def __str__(self):
        return self.title
Пример #4
0
class HelpFile(TendenciBaseModel):
    """Question/Answer infromation"""
    LEVELS = ('basic', 'intermediate', 'advanced', 'expert')
    LEVEL_CHOICES = [(i, i) for i in LEVELS]

    slug = SlugField(_('URL Path'), unique=True)
    topics = models.ManyToManyField(Topic)
    question = models.CharField(max_length=500)
    answer = tinymce_models.HTMLField()
    level = models.CharField(choices=LEVEL_CHOICES,
                             max_length=100,
                             default='basic')
    is_faq = models.BooleanField(default=False)
    is_featured = models.BooleanField(default=False)
    is_video = models.BooleanField(default=False)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    view_totals = models.PositiveIntegerField(default=0)

    group = models.ForeignKey(Group,
                              null=True,
                              default=get_default_group,
                              on_delete=models.SET_NULL)
    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = HelpFileManager()

    class Meta:
        permissions = (("view_helpfile", _("Can view help file")), )
        app_label = 'help_files'

    @models.permalink
    def get_absolute_url(self):
        return ("help_file.details", [self.slug])

    def __unicode__(self):
        return self.question

    def level_is(self):
        "Template helper: {% if file.level_is.basic %}..."
        return dict([i, self.level == i] for i in HelpFile.LEVELS)
Пример #5
0
class Box(OrderingBaseModel, TendenciBaseModel):
    title = models.CharField(max_length=500, blank=True)
    content = tinymce_models.HTMLField()
    tags = TagField(blank=True)
    group = models.ForeignKey(Group,
                              null=True,
                              default=get_default_group,
                              on_delete=models.SET_NULL)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = BoxManager()

    class Meta:
        #         permissions = (("view_box",_("Can view box")),)
        verbose_name_plural = _("Boxes")
        ordering = ['position']
        app_label = 'boxes'

    def __str__(self):
        return self.title

    def safe_content(self):
        return mark_safe(self.content)

    def save(self, *args, **kwargs):
        model = self.__class__

        if self.position is None:
            # Append
            try:
                last = model.objects.order_by('-position')[0]
                self.ordering = last.ordering + 1
            except IndexError:
                # First row
                self.ordering = 0

        return super(Box, self).save(*args, **kwargs)
Пример #6
0
class Email(TendenciBaseModel):

    CONTENT_TYPE_HTML = 'text/html'
    CONTENT_TYPE_TEXT = 'text'

    CONTENT_TYPE_CHOICES = (
        (CONTENT_TYPE_HTML, 'text/html'),
        (CONTENT_TYPE_TEXT, 'text'),
    )

    guid = models.CharField(max_length=50)
    priority = models.IntegerField(default=0)
    subject = models.CharField(max_length=255)
    body = tinymce_models.HTMLField()
    # body = models.TextField()
    sender = models.CharField(max_length=255)
    sender_display = models.CharField(max_length=255)
    reply_to = models.CharField(max_length=255)
    recipient = models.CharField(max_length=255, blank=True, default='')
    recipient_display = models.CharField(max_length=255,
                                         blank=True,
                                         default='')
    recipient_cc = models.CharField(max_length=255, blank=True, default='')
    recipient_cc_display = models.CharField(max_length=255,
                                            blank=True,
                                            default='')
    recipient_bcc = models.CharField(max_length=255, blank=True, default='')
    attachments = models.CharField(max_length=500, blank=True, default='')
    content_type = models.CharField(max_length=255,
                                    default=CONTENT_TYPE_HTML,
                                    choices=CONTENT_TYPE_CHOICES)

    # create_dt = models.DateTimeField(auto_now_add=True)
    # status = models.NullBooleanField(default=True, choices=((True,'Active'),(False,'Inactive'),))

    class Meta:
        app_label = 'emails'

    def get_absolute_url(self):
        return reverse('email.view', args=[self.pk])

    def __unicode__(self):
        return self.subject

    @staticmethod
    def is_blocked(email_to_test):
        if not email_to_test or '@' not in email_to_test:
            return False

        email_to_test = email_to_test.lower()
        email_domain = email_to_test.split('@')[1]
        return EmailBlock.objects.filter(
            Q(email=email_to_test) | Q(email_domain=email_domain)).exists()

    def send(self, fail_silently=False, **kwargs):
        recipient_list = []
        recipient_bcc_list = []
        headers = kwargs.get('headers', {})
        attachments = kwargs.get('attachments', [])

        if isinstance(self.recipient, str):
            recipient_list = self.recipient.split(',')
            recipient_list = [
                recipient.strip() for recipient in recipient_list
                if recipient.strip() != ''
            ]
        else:
            recipient_list = list(self.recipient)
        if isinstance(self.recipient_cc, str):
            recipient_cc_list = self.recipient_cc.split(',')
            recipient_cc_list = [
                recipient_cc.strip() for recipient_cc in recipient_cc_list
                if recipient_cc.strip() != ''
            ]
            recipient_list += recipient_cc_list
        else:
            recipient_list += list(self.recipient_cc)
        if isinstance(self.recipient_bcc, str):
            recipient_bcc_list = self.recipient_bcc.split(',')
            recipient_bcc_list = [
                recipient_bcc.strip() for recipient_bcc in recipient_bcc_list
                if recipient_bcc.strip() != ''
            ]
        else:
            recipient_bcc_list = list(self.recipient_bcc)

        if self.reply_to:
            headers['Reply-To'] = self.reply_to
        if not self.sender:
            self.sender = get_setting(
                'site', 'global',
                'siteemailnoreplyaddress') or settings.DEFAULT_FROM_EMAIL
        if self.sender_display:
            # Add quotes around display name to prevent errors on sending
            # When display name contains comma or other control characters,
            headers['From'] = '"%s"<%s>' % (self.sender_display, self.sender)
        if self.priority and self.priority == 1:
            headers['X-Priority'] = '1'
            headers['X-MSMail-Priority'] = 'High'

        # remove blocked from recipient_list and recipient_bcc_list
        temp_recipient_list = copy.copy(recipient_list)
        for e in temp_recipient_list:
            if self.is_blocked(e):
                recipient_list.remove(e)
        temp_recipient_bcc_list = copy.copy(recipient_bcc_list)
        for e in temp_recipient_bcc_list:
            if self.is_blocked(e):
                recipient_bcc_list.remove(e)

        if recipient_list or recipient_bcc_list:
            msg = EmailMessage(self.subject,
                               add_tendenci_footer(self.body),
                               self.sender,
                               recipient_list,
                               recipient_bcc_list,
                               headers=headers,
                               connection=kwargs.get('connection', None))
            if self.content_type == 'html' or self.content_type == self.CONTENT_TYPE_HTML:
                msg.content_subtype = 'html'
            if attachments:
                msg.attachments = attachments
            msg.send(fail_silently=fail_silently)

    def save(self, user=None, *args, **kwargs):
        if not self.id:
            self.guid = uuid.uuid1()
            if user and not user.is_anonymous:
                self.creator = user
                self.creator_username = user.username
        if user and not user.is_anonymous:
            self.owner = user
            self.owner_username = user.username

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

    # if this email allows view by user2_compare
    def allow_view_by(self, user2_compare):
        boo = False

        if user2_compare.profile.is_superuser:
            boo = True
        else:
            if user2_compare == self.creator or user2_compare == self.owner:
                if self.status:
                    boo = True
            else:
                if user2_compare.has_perm('emails.view_email', self):
                    if self.status == 1 and self.status_detail == 'active':
                        boo = True
        return boo

    # if this email allows edit by user2_compare
    def allow_edit_by(self, user2_compare):
        boo = False
        if user2_compare.profile.is_superuser:
            boo = True
        else:
            if user2_compare == self.user:
                boo = True
            else:
                if user2_compare == self.creator or user2_compare == self.owner:
                    if self.status:
                        boo = True
                else:
                    if user2_compare.has_perm('emails.edit_email', self):
                        if self.status:
                            boo = True
        return boo

    def template_body(self, email_d):
        """
            build the email body from the template and variables passed in by a dictionary
        """
        import os.path
        from django.template.loader import render_to_string

        template = email_d.get('template_path_name', '')

        # check if this template exists
        boo = False
        for dir in settings.TEMPLATE_DIRS:
            if os.path.isfile(os.path.join(dir, template)):
                boo = True
                break

        if not boo:
            # log an event

            # notify admin of missing template

            pass
        else:
            self.body = render_to_string(template_name=template)
            for key in email_d:
                # need to convert [blah] to %5Bblah%5D for replace line
                tmp_value = "%5B" + key[1:-1] + "%5D"
                if email_d[key] is not None:
                    self.body = self.body.replace(key, email_d[key])
                    self.body = self.body.replace(tmp_value, email_d[key])
                else:
                    self.body = self.body.replace(key, '')
                    self.body = self.body.replace(tmp_value, '')

        return boo
Пример #7
0
class BasePage(TendenciBaseModel):
    guid = models.CharField(max_length=40)
    title = models.CharField(max_length=500, blank=True)
    slug = SlugField(_('URL Path'))
    header_image = models.ForeignKey(HeaderImage,
                                     null=True,
                                     on_delete=models.SET_NULL)
    content = tinymce_models.HTMLField()
    view_contact_form = models.BooleanField(default=False)
    design_notes = models.TextField(_('Design Notes'), blank=True)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=False)
    template = models.CharField(_('Template'), max_length=50, blank=True)
    tags = TagField(blank=True)
    meta = models.OneToOneField(MetaTags, null=True, on_delete=models.SET_NULL)
    categories = GenericRelation(CategoryItem,
                                 object_id_field="object_id",
                                 content_type_field="content_type")

    class Meta:
        abstract = True
        app_label = 'pages'

    def save(self, *args, **kwargs):
        if not self.guid:
            self.guid = str(uuid.uuid4())
        super(BasePage, self).save(*args, **kwargs)
        if self.header_image:
            if self.is_public():
                set_s3_file_permission(self.header_image.file, public=True)
            else:
                set_s3_file_permission(self.header_image.file, public=False)

    def __str__(self):
        return self.title

    def get_header_image_url(self):
        if not self.header_image:
            return ''

        if self.is_public():
            return self.header_image.file.url

        return reverse('page.header_image', args=[self.id])

    def is_public(self):
        return all([
            self.allow_anonymous_view, self.status, self.status_detail
            in ['active']
        ])

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category', 'parent'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    @property
    def version(self):
        if self.status and self.status_detail:
            return self.status_detail + '-' + str(self.pk) + ' ' + str(
                self.create_dt)
        elif not self.status:
            return 'deleted-' + str(self.pk) + ' ' + str(self.create_dt)
        return ''
Пример #8
0
class BaseJob(TendenciBaseModel):
    guid = models.CharField(max_length=40)
    title = models.CharField(max_length=250)
    slug = SlugField(_('URL Path'), unique=True)
    description = tinymce_models.HTMLField()
    list_type = models.CharField(max_length=50)  # premium or regular

    code = models.CharField(max_length=50, blank=True)  # internal job-code
    location = models.CharField(max_length=500, null=True, blank=True)  # cannot be foreign, needs to be open 'Texas' 'All 50 States' 'US and International'
    skills = models.TextField(blank=True)
    experience = models.TextField(blank=True)
    education = models.TextField(blank=True)
    level = models.CharField(max_length=50, blank=True)  # e.g. entry, part-time, permanent, contract
    period = models.CharField(max_length=50, blank=True)  # full time, part time, contract
    is_agency = models.BooleanField(default=False)  # defines if the job posting is by a third party agency

    contact_method = models.TextField(blank=True)  # preferred method - email, phone, fax. leave open field for user to define
    position_reports_to = models.CharField(max_length=200, blank=True)  # manager, CEO, VP, etc
    salary_from = models.CharField(max_length=50, blank=True)
    salary_to = models.CharField(max_length=50, blank=True)
    computer_skills = models.TextField(blank=True)

    # date related fields
    requested_duration = models.IntegerField()  # 30, 60, 90 days - should be relational table
    pricing = models.ForeignKey('JobPricing', null=True, on_delete=models.SET_NULL)  # selected pricing based on requested_duration
    activation_dt = models.DateTimeField(null=True, blank=True)  # date job listing was activated
    post_dt = models.DateTimeField(null=True, blank=True)  # date job was posted (same as create date?)
    expiration_dt = models.DateTimeField(null=True, blank=True)  # date job expires based on activation date and duration
    start_dt = models.DateTimeField(null=True, blank=True)  # date job starts(defined by job poster)

    job_url = models.CharField(max_length=300, blank=True)  # link to other (fuller) job posting
    syndicate = models.BooleanField(_('Include in RSS feed'), blank=True, default=True)
    design_notes = models.TextField(blank=True)

    #TODO: foreign
    contact_company = models.CharField(max_length=300, blank=True)
    contact_name = models.CharField(max_length=150, blank=True)
    contact_address = models.CharField(max_length=50, blank=True)
    contact_address2 = models.CharField(max_length=50, blank=True)
    contact_city = models.CharField(max_length=50, blank=True)
    contact_state = models.CharField(max_length=50, blank=True)
    contact_zip_code = models.CharField(max_length=50, blank=True)
    contact_country = models.CharField(max_length=50, blank=True)
    contact_phone = models.CharField(max_length=50, blank=True)
    contact_fax = models.CharField(max_length=50, blank=True)
    contact_email = models.CharField(max_length=300, blank=True)
    contact_website = models.CharField(max_length=300, blank=True)

    meta = models.OneToOneField(MetaTags, null=True, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, null=True, default=get_default_group, on_delete=models.SET_NULL)
    tags = TagField(blank=True)

    invoice = models.ForeignKey(Invoice, blank=True, null=True, on_delete=models.SET_NULL)
    payment_method = models.CharField(max_length=50, blank=True, default='')
    member_price = models.DecimalField(max_digits=20, decimal_places=2, blank=True, null=True)
    member_count = models.IntegerField(blank=True, null=True)
    non_member_price = models.DecimalField(max_digits=20, decimal_places=2, blank=True, null=True)
    non_member_count = models.IntegerField(blank=True, null=True)

    cat = models.ForeignKey(Category, verbose_name=_("Category"),
                                 related_name="job_cat", null=True, on_delete=models.SET_NULL)
    sub_cat = models.ForeignKey(Category, verbose_name=_("Sub Category"),
                                 related_name="job_subcat", null=True, on_delete=models.SET_NULL)

    # needed for migration 0003
    categories = GenericRelation(
        CategoryItem,
        object_id_field="object_id",
        content_type_field="content_type"
    )

    perms = GenericRelation(
        ObjectPermission,
        object_id_field="object_id",
        content_type_field="content_type"
    )

    objects = JobManager()

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = str(uuid.uuid4())

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

    def __str__(self):
        return self.title

    # Called by payments_pop_by_invoice_user in Payment model.
    def get_payment_description(self, inv):
        """
        The description will be sent to payment gateway and displayed on invoice.
        If not supplied, the default description will be generated.
        """
        return 'Tendenci Invoice %d for Job: %s (%d).' % (
            inv.id,
            self.title,
            inv.object_id,
        )

    def make_acct_entries(self, user, inv, amount, **kwargs):
        """
        Make the accounting entries for the job sale
        """
        from tendenci.apps.accountings.models import Acct, AcctEntry, AcctTran
        from tendenci.apps.accountings.utils import make_acct_entries_initial, make_acct_entries_closing

        ae = AcctEntry.objects.create_acct_entry(user, 'invoice', inv.id)
        if not inv.is_tendered:
            make_acct_entries_initial(user, ae, amount)
        else:
            # payment has now been received
            make_acct_entries_closing(user, ae, amount)

            # #CREDIT job SALES
            acct_number = self.get_acct_number()
            acct = Acct.objects.get(account_number=acct_number)
            AcctTran.objects.create_acct_tran(user, ae, acct, amount * (-1))

    def get_acct_number(self, discount=False):
        if discount:
            return 462500
        else:
            return 402500

    def auto_update_paid_object(self, request, payment):
        """
        Update the object after online payment is received.
        """
        if not request.user.profile.is_superuser:
            self.status_detail = 'paid - pending approval'

        self.activation_dt = datetime.now()
        self.expiration_dt = self.activation_dt + timedelta(days=self.requested_duration)
        self.save()

    @property
    def opt_app_label(self):
        return self._meta.app_label

    @property
    def opt_module_name(self):
        return self._meta.model_name
Пример #9
0
class Directory(TendenciBaseModel):

    guid = models.CharField(max_length=40)
    slug = SlugField(_('URL Path'), unique=True)
    timezone = TimeZoneField(_('Time Zone'))
    headline = models.CharField(max_length=200, blank=True)
    summary = models.TextField(blank=True)
    body = tinymce_models.HTMLField()
    source = models.CharField(max_length=300, blank=True)
    # logo = models.FileField(max_length=260, upload_to=file_directory,
    #                         help_text=_('Company logo. Only jpg, gif, or png images.'),
    #                         blank=True)

    logo_file = models.ForeignKey(File, null=True)

    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), max_length=100, blank=True)
    address = models.CharField(_('Address'), max_length=100, blank=True)
    address2 = models.CharField(_('Address 2'), max_length=100, blank=True)
    city = models.CharField(_('City'), max_length=50, blank=True)
    state = models.CharField(_('State'), max_length=50, blank=True)
    zip_code = models.CharField(_('Zip Code'), max_length=50, blank=True)
    country = models.CharField(_('Country'), max_length=50, blank=True)
    phone = models.CharField(max_length=50, blank=True)
    phone2 = models.CharField(_('Phone 2'), max_length=50, blank=True)
    fax = models.CharField(_('Fax'), max_length=50, blank=True)
    email = models.CharField(_('Email'), max_length=120, blank=True)
    email2 = models.CharField(_('Email 2'), max_length=120, blank=True)
    website = models.CharField(max_length=300, blank=True)

    renewal_notice_sent = models.BooleanField(default=False)
    list_type = models.CharField(_('List Type'), max_length=50, blank=True)
    requested_duration = models.IntegerField(_('Requested Duration'), default=0)
    pricing = models.ForeignKey('DirectoryPricing', null=True)
    activation_dt = models.DateTimeField(_('Activation Date/Time'), null=True, blank=True)
    expiration_dt = models.DateTimeField(_('Expiration Date/Time'), null=True, blank=True)
    invoice = models.ForeignKey(Invoice, blank=True, null=True)
    payment_method = models.CharField(_('Payment Method'), max_length=50, blank=True)

    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    design_notes = models.TextField(_('Design Notes'), blank=True)
    admin_notes = models.TextField(_('Admin Notes'), blank=True)
    tags = TagField(blank=True)

    # for podcast feeds
    enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True)
    enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True)
    enclosure_length = models.IntegerField(_('Enclosure Length'), default=0)

    # html-meta tags
    meta = models.OneToOneField(MetaTags, null=True)

    categories = GenericRelation(CategoryItem,
                                          object_id_field="object_id",
                                          content_type_field="content_type")
    perms = GenericRelation(ObjectPermission,
                                          object_id_field="object_id",
                                          content_type_field="content_type")

    objects = DirectoryManager()

    class Meta:
        permissions = (("view_directory",_("Can view directory")),)
        verbose_name = _("Directory")
        verbose_name_plural = _("Directories")
        app_label = 'directories'

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        methods coupled to this instance.
        """
        return DirectoryMeta().get_meta(self, name)

    @models.permalink
    def get_absolute_url(self):
        return ("directory", [self.slug])

    @models.permalink
    def get_renew_url(self):
        return ("directory.renew", [self.id])

    def __unicode__(self):
        return self.headline

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = str(uuid.uuid1())

        super(Directory, self).save(*args, **kwargs)
        if self.logo:
            if self.is_public():
                set_s3_file_permission(self.logo.name, public=True)
            else:
                set_s3_file_permission(self.logo.name, public=False)

    def is_public(self):
        return all([self.allow_anonymous_view,
                self.status,
                self.status_detail in ['active']])

    @property
    def logo(self):
        """
        This represents the logo FileField

        Originally this was a FileField, but later
        we added the attribute logo_file to leverage
        the File model.  We then replaced the logo
        property with this convience method for
        backwards compatibility.
        """
        if self.logo_file:
            return self.logo_file.file

    def get_logo_url(self):
        if not self.logo_file:
            return u''

        return reverse('file', args=[self.logo_file.pk])

    # Called by payments_pop_by_invoice_user in Payment model.
    def get_payment_description(self, inv):
        """
        The description will be sent to payment gateway and displayed on invoice.
        If not supplied, the default description will be generated.
        """
        return 'Tendenci Invoice %d for Directory: %s (%d).' % (
            inv.id,
            self.headline,
            inv.object_id,
        )

    def make_acct_entries(self, user, inv, amount, **kwargs):
        """
        Make the accounting entries for the directory sale
        """
        from tendenci.apps.accountings.models import Acct, AcctEntry, AcctTran
        from tendenci.apps.accountings.utils import make_acct_entries_initial, make_acct_entries_closing

        ae = AcctEntry.objects.create_acct_entry(user, 'invoice', inv.id)
        if not inv.is_tendered:
            make_acct_entries_initial(user, ae, amount)
        else:
            # payment has now been received
            make_acct_entries_closing(user, ae, amount)

            # #CREDIT directory SALES
            acct_number = self.get_acct_number()
            acct = Acct.objects.get(account_number=acct_number)
            AcctTran.objects.create_acct_tran(user, ae, acct, amount*(-1))

    def get_acct_number(self, discount=False):
        if discount:
            return 464400
        else:
            return 404400

    def auto_update_paid_object(self, request, payment):
        """
        Update the object after online payment is received.
        """
        if not request.user.profile.is_superuser:
            self.status_detail = 'paid - pending approval'
            self.save()

    def age(self):
        return datetime.now() - self.create_dt

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category__name', 'parent__name'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    def renew_window(self):
        days = get_setting('module', 'directories', 'renewaldays')
        days = int(days)
        if self.expiration_dt and datetime.now() + timedelta(days) > self.expiration_dt:
            return True
        else:
            return False
Пример #10
0
class Directory(TendenciBaseModel):

    guid = models.CharField(max_length=40)
    slug = SlugField(_('URL Path'), unique=True)
    entity = models.OneToOneField(Entity, blank=True, null=True,
                                  on_delete=models.SET_NULL,)
    timezone = TimeZoneField(verbose_name=_('Time Zone'), default='US/Central', choices=get_timezone_choices(), max_length=100)
    headline = models.CharField(_('Name'), max_length=200, blank=True)
    summary = models.TextField(blank=True)
    body = tinymce_models.HTMLField(_('Description'))
    source = models.CharField(max_length=300, blank=True)
    # logo = models.FileField(max_length=260, upload_to=file_directory,
    #                         help_text=_('Company logo. Only jpg, gif, or png images.'),
    #                         blank=True)

    logo_file = models.ForeignKey(File, null=True, on_delete=models.CASCADE)

    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), max_length=100, blank=True)
    address = models.CharField(_('Address'), max_length=100, blank=True)
    address2 = models.CharField(_('Address 2'), max_length=100, blank=True)
    city = models.CharField(_('City'), max_length=50, blank=True)
    state = models.CharField(_('State'), max_length=50, blank=True)
    zip_code = models.CharField(_('Zip Code'), max_length=50, blank=True)
    country = models.CharField(_('Country'), max_length=50, blank=True)
    region = models.ForeignKey(Region, blank=True, null=True, on_delete=models.SET_NULL)
    phone = models.CharField(max_length=50, blank=True)
    phone2 = models.CharField(_('Phone 2'), max_length=50, blank=True)
    fax = models.CharField(_('Fax'), max_length=50, blank=True)
    email = models.CharField(_('Email'), max_length=120, blank=True)
    email2 = models.CharField(_('Email 2'), max_length=120, blank=True)
    website = models.CharField(max_length=300, blank=True)

    renewal_notice_sent = models.BooleanField(default=False)
    list_type = models.CharField(_('List Type'), max_length=50, blank=True)
    requested_duration = models.IntegerField(_('Requested Duration'), default=0)
    pricing = models.ForeignKey('DirectoryPricing', null=True, on_delete=models.CASCADE)
    activation_dt = models.DateTimeField(_('Activation Date/Time'), null=True, blank=True)
    expiration_dt = models.DateTimeField(_('Expiration Date/Time'), null=True, blank=True)
    invoice = models.ForeignKey(Invoice, blank=True, null=True, on_delete=models.CASCADE)
    payment_method = models.CharField(_('Payment Method'), max_length=50, blank=True)
    
    # social media links
    linkedin = models.URLField(_('LinkedIn'), blank=True, default='')
    facebook = models.URLField(_('Facebook'), blank=True, default='')
    twitter = models.URLField(_('Twitter'), blank=True, default='')
    instagram = models.URLField(_('Instagram'), blank=True, default='')
    youtube = models.URLField(_('YouTube'), blank=True, default='')

    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    design_notes = models.TextField(_('Design Notes'), blank=True)
    admin_notes = models.TextField(_('Admin Notes'), blank=True)
    tags = TagField(blank=True)

    # for podcast feeds
    enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True)
    enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True)
    enclosure_length = models.IntegerField(_('Enclosure Length'), default=0)

    # html-meta tags
    meta = models.OneToOneField(MetaTags, null=True, on_delete=models.SET_NULL)

    cat = models.ForeignKey(Category, verbose_name=_("Category"),
                                 related_name="directory_cat", null=True, on_delete=models.SET_NULL)
    sub_cat = models.ForeignKey(Category, verbose_name=_("Sub Category"),
                                 related_name="directory_subcat", null=True, on_delete=models.SET_NULL)
    cats = models.ManyToManyField(Category, verbose_name=_("Categories"),
                                  related_name="directory_cats",)
    sub_cats = models.ManyToManyField(Category, verbose_name=_("Sub Categories"),
                                  related_name="directory_subcats",)
    # legacy categories needed for data migration
    categories = GenericRelation(CategoryItem,
                                          object_id_field="object_id",
                                          content_type_field="content_type")
    perms = GenericRelation(ObjectPermission,
                                          object_id_field="object_id",
                                          content_type_field="content_type")
    
    affiliates = models.ManyToManyField("Directory", through='Affiliateship')

    objects = DirectoryManager()

    class Meta:
#         permissions = (("view_directory",_("Can view directory")),)
        verbose_name = _("Directory")
        verbose_name_plural = _("Directories")
        app_label = 'directories'

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        methods coupled to this instance.
        """
        return DirectoryMeta().get_meta(self, name)

    def __str__(self):
        return self.headline

    def get_absolute_url(self):
        return reverse('directory', args=[self.slug])

    def get_renew_url(self):
        return reverse('directory.renew', args=[self.id])

    def set_slug(self):
        if not self.slug:
            slug = slugify(self.headline)
            count = str(Directory.objects.count())
            if len(slug) + len(count) >= 99:
                self.slug = '%s-%s' % (slug[:99-len(count)], count)
            else:
                self.slug = '%s-%s' % (slug, count)

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = str(uuid.uuid4())

        super(Directory, self).save(*args, **kwargs)
        if self.logo:
            if self.is_public():
                set_s3_file_permission(self.logo.name, public=True)
            else:
                set_s3_file_permission(self.logo.name, public=False)

    def is_public(self):
        return all([self.allow_anonymous_view,
                self.status,
                self.status_detail in ['active']])

    def has_social_media(self):
        return any([self.linkedin, self.facebook, self.twitter, self.instagram, self.youtube])

    @property
    def logo(self):
        """
        This represents the logo FileField

        Originally this was a FileField, but later
        we added the attribute logo_file to leverage
        the File model.  We then replaced the logo
        property with this convience method for
        backwards compatibility.
        """
        if self.logo_file:
            return self.logo_file.file

    def get_logo_url(self):
        if not self.logo_file:
            return u''

        return reverse('file', args=[self.logo_file.pk])

    # Called by payments_pop_by_invoice_user in Payment model.
    def get_payment_description(self, inv):
        """
        The description will be sent to payment gateway and displayed on invoice.
        If not supplied, the default description will be generated.
        """
        return 'Tendenci Invoice %d for Directory: %s (%d).' % (
            inv.id,
            self.headline,
            inv.object_id,
        )

    def make_acct_entries(self, user, inv, amount, **kwargs):
        """
        Make the accounting entries for the directory sale
        """
        from tendenci.apps.accountings.models import Acct, AcctEntry, AcctTran
        from tendenci.apps.accountings.utils import make_acct_entries_initial, make_acct_entries_closing

        ae = AcctEntry.objects.create_acct_entry(user, 'invoice', inv.id)
        if not inv.is_tendered:
            make_acct_entries_initial(user, ae, amount)
        else:
            # payment has now been received
            make_acct_entries_closing(user, ae, amount)

            # #CREDIT directory SALES
            acct_number = self.get_acct_number()
            acct = Acct.objects.get(account_number=acct_number)
            AcctTran.objects.create_acct_tran(user, ae, acct, amount*(-1))

    def get_acct_number(self, discount=False):
        if discount:
            return 464400
        else:
            return 404400

    def auto_update_paid_object(self, request, payment):
        """
        Update the object after online payment is received.
        """
        if not request.user.profile.is_superuser:
            self.status_detail = 'paid - pending approval'
            self.save()

    def age(self):
        return datetime.now() - self.create_dt
    
    def cats_list(self):
        items = []
        for cat in self.cats.all():
            sub_cats = self.sub_cats.filter(parent=cat)
            items.append((cat, list(sub_cats)))
        return items

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category', 'parent'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    def renew_window(self):
        days = get_setting('module', 'directories', 'renewaldays')
        days = int(days)
        if self.expiration_dt and datetime.now() + timedelta(days) > self.expiration_dt:
            return True
        else:
            return False
        
    def has_membership_with(self, this_user):
        """
        Check if this directory is associated with a membership or a corporate membership
        that this user owns. 
        
        Return ``True`` if this directory is associated with an active membership
        or corporate membership, and this_user owns the membership or is a representative
        of the corporate membership, or is the ``creator`` or ``owner`` of this directory.
        """
        [m] = self.membershipdefault_set.filter(status_detail='active')[:1] or [None]
        if m:
            if any([this_user==self.creator,
                   this_user==self.owner,
                   this_user==m.user]):
                return True

        if hasattr(self, 'corpprofile'):
            corp_membership = self.corpprofile.corp_membership
            if corp_membership and corp_membership.status_detail == 'active':
                if any([this_user==self.creator,
                       this_user==self.owner,
                       self.corpprofile.is_rep(this_user)]):
                    return True
        return False

    def get_owner_emails_list(self):
        """
        Returns a list of owner's email addresses.
        
        It's tricky because directory doesn't have a clear owner. 
        Since the owner field can be changed to whoever last edited, we'll
        check the creator, the email address field, member or reps if 
        it is created from memberships and corp memberships, respectively.
        """
        emails_list = []
        # creator
        if self.creator and validate_email(self.creator.email):
            emails_list.append(self.creator.email)

        # the email field  
        if validate_email(self.email):
            emails_list.append(self.email)

        # member
        [m] = self.membershipdefault_set.filter(status_detail='active')[:1] or [None]
        if m and validate_email(m.user.email):
            emails_list.append(m.user.email)

        # corp reps
        if hasattr(self, 'corpprofile'):
            corp_reps = self.corpprofile.reps.all()
            for rep in corp_reps:
                if validate_email(rep.user.email):
                    emails_list.append(rep.user.email)

        return list(set(emails_list))

    def get_corp_profile(self):
        if hasattr(self, 'corpprofile'):
            return self.corpprofile

    def get_corp_type(self):
        """
        Returns the corporate membership type that associates with the directory.
        """
        corp_profile = self.get_corp_profile()
        if corp_profile:
            corp_membership = corp_profile.corp_membership
            if corp_membership:
                return corp_membership.corporate_membership_type

    def get_membership(self):
        [membership] = list(self.membershipdefault_set.filter(status_detail='active'))[:1] or [None]
        return membership

    def get_member_type(self):
        """
        Returns the membership type that associates with the directory.
        """
        membership = self.get_membership()
        if membership:
            return membership.membership_type

    def is_owner(self, user_this):
        if not user_this or not user_this.is_authenticated:
            return False

        # is creator or owner
        if user_this == self.creator or user_this == self.owner:
            return True

        # is corp rep
        if hasattr(self, 'corpprofile'):
            if self.corpprofile.reps.filter(user__in=[user_this]):
                return True
        
        # member
        membership = self.get_membership()
        if membership and membership.user == user_this:
            return True
        
        return False


    def can_connect_from(self, directory_from=None, directory_from_cat=None):
        """
        Check if this directory can be connected from ``directory_from``.
        """
        affliated_cats = self.get_affliated_cats()
        if directory_from_cat:
            return directory_from_cat in affliated_cats
        
        if directory_from:
            for cat in directory_from.cats.all():
                if cat in affliated_cats:
                    return True
        return False

    def get_affliated_cats(self):
        """
        Get a list of categories that are allowed to connect with the categories of this directory.
        """
        affliated_cats = []
        for cat in self.cats.all():
            if hasattr(cat, 'connections'):
                if cat.connections.affliated_cats.count() > 0:
                    affliated_cats += list(cat.connections.affliated_cats.all())
        return affliated_cats

    def get_parent_cats(self):
        """
        Get a list of parent categories that this directory can associate to.
        """
        parent_cats = []
        for cat in self.cats.all():
            connections = cat.allowed_connections.all()
            for c in connections:
                if not c.cat in parent_cats:
                    parent_cats.append(c.cat)
        return parent_cats

    def get_list_affiliates(self):
        """
        Return a sorted list of list of affiliate directories, 
        grouped by category.
        ex: [(category_name, [d1, d2, ..]),...]
        """
        affiliates_dict = {}
        affliated_cats = self.get_affliated_cats()
        for affiliateship in Affiliateship.objects.filter(directory=self):
            affiliate = affiliateship.affiliate
            if affiliate.status_detail =='active':
                cat = affiliateship.connected_as
                if cat in affliated_cats:
                    if cat in affiliates_dict:
                        affiliates_dict[cat].append(affiliate)
                    else:
                        affiliates_dict[cat] = [affiliate]

        return sorted(list(affiliates_dict.items()), key=lambda item: item[0].position)

    def get_list_parent_directories(self):
        """
        Return a sorted list of list of parent directories, 
        grouped by category, 
        ex: [(category_name, [d1, d2, ..]),...]
        """
        parents_dict = {}
        parent_cats = self.get_parent_cats()
        for affiliateship in Affiliateship.objects.filter(affiliate=self):
            parent_d = affiliateship.directory
            if parent_d.status_detail =='active':
                connected_cat = affiliateship.connected_as
                for cat in parent_d.cats.all():
                    if cat in parent_cats and connected_cat in cat.connections.affliated_cats.all():
                        if cat in parents_dict:
                            parents_dict[cat].append(parent_d)
                        else:
                            parents_dict[cat] = [parent_d]

        return sorted(list(parents_dict.items()), key=lambda item: item[0].position)

    def allow_associate_by(self, user_this):
        """
        Check if user_this is allowed to submit affiliate requests.
        
        If the connection is limited to the allowed connection, 
        this user will need to have a valid membership with the
        membership type is in the allowed types. 
        """
        affliated_cats = self.get_affliated_cats()

        if affliated_cats:
            if user_this.is_superuser:
                return True

            # check if user_this is the owner of a directory with the category in affliated_cats
            for directory in Directory.objects.filter(cats__in=affliated_cats):
                if directory.is_owner(user_this):
                    return True

    def allow_approve_affiliations_by(self, user_this):
        """
        Check if user_this is allowed to approve affiliate requests.
        
        Superuser or the directory owner can approve.
        The directory owners include creator, owner, and associated corp reps.
        """
        if not user_this or not user_this.is_authenticated:
            return False

        if user_this.is_superuser:
            return True

        # is creator or owner
        if user_this == self.creator or user_this == self.owner:
            return True

        # is a corp rep
        if hasattr(self, 'corpprofile'):
            if self.corpprofile.reps.filter(user__in=[user_this]):
                return True

        return False

    def allow_reject_affiliations_by(self, user_this):
        """
        Check if user_this is allowed to reject affiliate requests.
        
        Superuser or the directory owner can reject.
        The directory owners include creator, owner, and associated corp reps.
        """
        return self.allow_approve_affiliations_by(user_this)
Пример #11
0
class News(TendenciBaseModel):
    CONTRIBUTOR_AUTHOR = 1
    CONTRIBUTOR_PUBLISHER = 2
    CONTRIBUTOR_CHOICES = ((CONTRIBUTOR_AUTHOR, _('Author')),
                           (CONTRIBUTOR_PUBLISHER, _('Publisher')))

    guid = models.CharField(max_length=40)
    slug = SlugField(_('URL Path'), unique=True)
    timezone = TimeZoneField(_('Time Zone'))
    headline = models.CharField(max_length=200, blank=True)
    summary = models.TextField(blank=True)
    body = tinymce_models.HTMLField()
    source = models.CharField(max_length=300, blank=True)
    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), max_length=100, blank=True)
    contributor_type = models.IntegerField(choices=CONTRIBUTOR_CHOICES,
                                           default=CONTRIBUTOR_AUTHOR)
    google_profile = models.URLField(_('Google+ URL'), blank=True)
    phone = models.CharField(max_length=50, blank=True)
    fax = models.CharField(max_length=50, blank=True)
    email = models.CharField(max_length=120, blank=True)
    website = models.CharField(max_length=300, blank=True)
    thumbnail = models.ForeignKey(
        'NewsImage',
        default=None,
        null=True,
        help_text=
        _('The thumbnail image can be used on your homepage or sidebar if it is setup in your theme. The thumbnail image will not display on the news page.'
          ))
    release_dt = models.DateTimeField(_('Release Date/Time'),
                                      null=True,
                                      blank=True)
    # used for better performance when retrieving a list of released news
    release_dt_local = models.DateTimeField(null=True, blank=True)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    design_notes = models.TextField(_('Design Notes'), blank=True)
    groups = models.ManyToManyField(Group,
                                    default=get_default_group,
                                    related_name='group_news')
    tags = TagField(blank=True)
    uploaded_wechat_mp = models.BooleanField(default=False)

    #for podcast feeds
    enclosure_url = models.CharField(_('Enclosure URL'),
                                     max_length=500,
                                     blank=True)  # for podcast feeds
    enclosure_type = models.CharField(_('Enclosure Type'),
                                      max_length=120,
                                      blank=True)  # for podcast feeds
    enclosure_length = models.IntegerField(_('Enclosure Length'),
                                           default=0)  # for podcast feeds

    use_auto_timestamp = models.BooleanField(_('Auto Timestamp'),
                                             default=False)

    # html-meta tags
    meta = models.OneToOneField(MetaTags, null=True)

    categories = GenericRelation(CategoryItem,
                                 object_id_field="object_id",
                                 content_type_field="content_type")

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = NewsManager()

    class Meta:
        permissions = (("view_news", _("Can view news")), )
        verbose_name_plural = _("News")
        app_label = 'news'

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        meta information niche to this model.
        """
        return NewsMeta().get_meta(self, name)

    @models.permalink
    def get_absolute_url(self):
        return ("news.detail", [self.slug])

    def __unicode__(self):
        return self.headline

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = str(uuid.uuid1())
        self.assign_release_dt_local()

        photo_upload = kwargs.pop('photo', None)
        super(News, self).save(*args, **kwargs)

        if photo_upload and self.pk:
            image = NewsImage(object_id=self.pk,
                              creator=self.creator,
                              creator_username=self.creator_username,
                              owner=self.owner,
                              owner_username=self.owner_username)
            photo_upload.file.seek(0)
            image.file.save(photo_upload.name, photo_upload)  # save file row
            image.save()  # save image row

            if self.thumbnail:
                self.thumbnail.delete()  # delete image and file row
            self.thumbnail = image  # set image

            self.save()

        if self.thumbnail:
            if self.is_public():
                set_s3_file_permission(self.thumbnail.file, public=True)
            else:
                set_s3_file_permission(self.thumbnail.file, public=False)

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category__name',
                                                  'parent__name'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    def is_public(self):
        return all([
            self.allow_anonymous_view, self.status, self.status_detail
            in ['active']
        ])

    @property
    def is_released(self):
        return self.release_dt_local <= datetime.now()

    @property
    def has_google_author(self):
        return self.contributor_type == self.CONTRIBUTOR_AUTHOR

    @property
    def has_google_publisher(self):
        return self.contributor_type == self.CONTRIBUTOR_PUBLISHER

    def assign_release_dt_local(self):
        """
        convert release_dt to the corresponding local time

        example:

        if
            release_dt: 2014-05-09 03:30:00
            timezone: US/Pacific
            settings.TIME_ZONE: US/Central
        then
            the corresponding release_dt_local will be: 2014-05-09 05:30:00
        """
        now = datetime.now()
        now_with_tz = adjust_datetime_to_timezone(now, settings.TIME_ZONE)
        if self.timezone and self.release_dt and self.timezone.zone != settings.TIME_ZONE:
            time_diff = adjust_datetime_to_timezone(
                now, self.timezone) - now_with_tz
            self.release_dt_local = self.release_dt + time_diff
        else:
            self.release_dt_local = self.release_dt
Пример #12
0
class ReliefAssessment(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    # Additional Personal Information
    id_number = models.CharField(_('ID number'), max_length=50, blank=True, null=True)
    issuing_authority = models.CharField(_('issuing authority'), max_length=100,
                                         blank=True, null=True)
    health_insurance = models.BooleanField(_('health insurance'), default=False)
    insurance_provider = models.CharField(_('insurance provider'), max_length=100,
                                          blank=True, null=True)
    # Disaster Area Address
    address = models.CharField(_('address'), max_length=150)
    address2 = models.CharField(_('address2'), max_length=100, blank=True, null=True)
    city = models.CharField(_('city'), max_length=50)
    state = models.CharField(_('state'), max_length=50)
    zipcode = models.CharField(_('ZIP'), max_length=50)
    country = models.CharField(_('country'), max_length=50)
    # Alternate Address
    alt_address = models.CharField(_('address'), max_length=150, blank=True, null=True)
    alt_address2 = models.CharField(_('address2'), max_length=100, blank=True, null=True)
    alt_city = models.CharField(_('city'), max_length=50, blank=True, null=True)
    alt_state = models.CharField(_('state'), max_length=50, blank=True, null=True)
    alt_zipcode = models.CharField(_('ZIP'), max_length=50, blank=True, null=True)
    alt_country = models.CharField(_('country'), max_length=50, blank=True, null=True)
    # Ethnicity
    ethnicity = models.CharField("", max_length=10, choices=ETHNICITY_CHOICES,
                                 blank=True, null=True)
    other_ethnicity = models.CharField("", max_length=50, blank=True, null=True,
                                       help_text="Specify here if your ethnicity is not included above.")
    # Household
    below_2 = models.IntegerField(_('0 - 2 yrs'), blank=True, null=True)
    between_3_11 = models.IntegerField(_('3 - 11 yrs'), blank=True, null=True)
    between_12_18 = models.IntegerField(_('12 - 18 yrs'), blank=True, null=True)
    between_19_59 = models.IntegerField(_('19 - 59 yrs'), blank=True, null=True)
    above_60 = models.IntegerField(_('over 60 yrs'), blank=True, null=True)
    # Services
    ssa = models.BooleanField(_('social security administration'), default=False,
                              help_text="current recipient of Social Security")
    dhs = models.BooleanField(_('department human services'), default=False,
                              help_text="food stamps, WIC, TANF")
    children_needs = models.BooleanField(
        _('children needs'), default=False,
        help_text="school supplies, uniforms, clothing, child care, diapers, wipes")
    toiletries = models.BooleanField(_('toiletries'), default=False)
    employment = models.BooleanField(_('employment'), default=False)
    training = models.BooleanField(_('training'), default=False)
    food = models.BooleanField(_('food'), default=False)
    gas = models.BooleanField(_('gas'), default=False)
    prescription = models.BooleanField(_('prescription care'), default=False)
    other_service = models.CharField(_('other'), max_length=100, blank=True, null=True,
                                     help_text="Specify additional services needed.")
    # Internal
    case_notes = tinymce_models.HTMLField(_('case notes'), blank=True, null=True)
    items_provided = tinymce_models.HTMLField(_('items provided'), blank=True, null=True)

    loc = models.PointField(blank=True, null=True)

    def get_absolute_url(self):
        return reverse('social-services.relief_area', args=[self.pk])

    def get_ethnicity(self):
        if self.ethnicity == 'other':
            return self.other_ethnicity
        return self.ethnicity

    def get_address(self):
        return "%s %s %s, %s %s %s" % (
            self.address,
            self.address2,
            self.city,
            self.state,
            self.zipcode,
            self.country
        )

    def save(self, *args, **kwargs):
        params = {'format': 'json',
                  'street': self.address,
                  'city': self.city,
                  'country': self.country}
        url = 'http://nominatim.openstreetmap.org/search'
        result = requests.get(url, params=params).json()
        if result:
            lat = result[0]['lat']
            lng = result[0]['lon']
            self.loc = "POINT(%s %s)" % (lng, lat)
        super(ReliefAssessment, self).save(*args, **kwargs)
Пример #13
0
class Chapter(BasePage):
    """
    Chapters module. Similar to Pages with extra fields.
    """
    entity = models.OneToOneField(
        Entity,
        null=True,
        on_delete=models.SET_NULL,
    )
    mission = tinymce_models.HTMLField(null=True, blank=True)
    notes = tinymce_models.HTMLField(null=True, blank=True)
    sponsors = tinymce_models.HTMLField(blank=True, default='')
    featured_image = models.ForeignKey(
        File,
        null=True,
        default=None,
        related_name='chapters',
        help_text=_('Only jpg, gif, or png images.'),
        on_delete=models.SET_NULL)
    contact_name = models.CharField(max_length=200, null=True, blank=True)
    contact_email = models.CharField(max_length=200, null=True, blank=True)
    join_link = models.CharField(max_length=200, null=True, blank=True)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = ChapterManager()

    def __str__(self):
        return str(self.title)

    class Meta:
        app_label = 'chapters'

    def get_absolute_url(self):
        return reverse('chapters.detail', args=[self.slug])

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        meta information niche to this model.
        """
        return ChapterMeta().get_meta(self, name)

    def officers(self):
        return Officer.objects.filter(chapter=self).order_by('pk')

    def save(self, *args, **kwargs):
        photo_upload = kwargs.pop('photo', None)

        super(Chapter, self).save(*args, **kwargs)
        if photo_upload and self.pk:
            image = File(content_type=ContentType.objects.get_for_model(
                self.__class__),
                         object_id=self.pk,
                         creator=self.creator,
                         creator_username=self.creator_username,
                         owner=self.owner,
                         owner_username=self.owner_username)
            photo_upload.file.seek(0)
            image.file.save(photo_upload.name, photo_upload)
            image.save()

            self.featured_image = image
            self.save()
Пример #14
0
class Video(TendenciBaseModel):
    """
    Videos plugin to add embedding based on video url. Uses embed.ly
    """
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True, max_length=200)
    category = models.ForeignKey(Category)
    video_type = models.ForeignKey(VideoType, null=True, blank=True)
    image = models.ImageField(upload_to='uploads/videos/%y/%m', blank=True)
    video_url = models.CharField(max_length=500,
                                 help_text='Youtube, Vimeo, etc..')
    description = tinymce_models.HTMLField()
    tags = TagField(blank=True, help_text='Tag 1, Tag 2, ...')
    ordering = models.IntegerField(blank=True, null=True)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = VideoManager()

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        model = self.__class__

        if self.ordering is None:
            # Append
            try:
                last = model.objects.order_by('-ordering')[0]
                self.ordering = last.ordering + 1
            except IndexError:
                # First row
                self.ordering = 0

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

    class Meta:
        permissions = (("view_video", "Can view video"), )
        ordering = ('ordering', )
        verbose_name = get_setting('module', 'videos', 'label') or "Video"
        verbose_name_plural = get_setting('module', 'videos',
                                          'label_plural') or "Videos"
        app_label = 'videos'

    @models.permalink
    def get_absolute_url(self):
        return ("video.details", [self.slug])

    def video_embed_url(self):
        """
        Returns a youtube embed URL
        Attempts to convert common YouTube URL patterns
        to the URL embed pattern.

        TODO: Contribute more video service embed URL's
        """
        import re

        url_pattern = r'http:\/\/www\.youtube\.com\/watch\?v=(\w+)'
        share_pattern = r'http:\/\/youtu\.be\/(\w+)'
        repl = lambda x: 'http://www.youtube.com/embed/%s' % x.group(1)

        if re.match(url_pattern, self.video_url):
            return re.sub(url_pattern, repl, self.video_url)

        if re.match(share_pattern, self.video_url):
            return re.sub(share_pattern, repl, self.video_url)

        return self.video_url

    def embed_code(self, **kwargs):
        width = kwargs.get('width') or 600
        return get_oembed_code(self.video_url, width, 400)

    def thumbnail(self):
        return get_oembed_thumbnail(self.video_url, 600, 400)
Пример #15
0
class Article(TendenciBaseModel):
    CONTRIBUTOR_AUTHOR = 1
    CONTRIBUTOR_PUBLISHER = 2
    CONTRIBUTOR_CHOICES = ((CONTRIBUTOR_AUTHOR, _('Author')),
                           (CONTRIBUTOR_PUBLISHER, _('Publisher')))

    guid = models.CharField(max_length=40)
    slug = SlugField(_('URL Path'), unique=True)
    timezone = TimeZoneField(verbose_name=_('Time Zone'), default='US/Central', choices=get_timezone_choices(), max_length=100)
    headline = models.CharField(max_length=200, blank=True)
    summary = models.TextField(blank=True)
    body = tinymce_models.HTMLField()
    source = models.CharField(max_length=300, blank=True)
    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), max_length=100, blank=True)
    contributor_type = models.IntegerField(choices=CONTRIBUTOR_CHOICES,
                                           default=CONTRIBUTOR_AUTHOR)
    phone = models.CharField(max_length=50, blank=True)
    fax = models.CharField(max_length=50, blank=True)
    email = models.CharField(max_length=120, blank=True)
    website = models.CharField(max_length=300, blank=True)
    thumbnail = models.ForeignKey(File, null=True,
                                  on_delete=models.SET_NULL,
                                  help_text=_('The thumbnail image can be used on your homepage ' +
                                 'or sidebar if it is setup in your theme. The thumbnail image ' +
                                 'will not display on the news page.'))
    release_dt = models.DateTimeField(_('Release Date/Time'), null=True, blank=True)
    # used for better performance when retrieving a list of released articles
    release_dt_local = models.DateTimeField(null=True, blank=True)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    featured = models.BooleanField(default=False)
    design_notes = models.TextField(_('Design Notes'), blank=True)
    group = models.ForeignKey(Group, null=True, default=get_default_group, on_delete=models.SET_NULL)
    tags = TagField(blank=True)

    # for podcast feeds
    enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True)
    enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True)
    enclosure_length = models.IntegerField(_('Enclosure Length'), default=0)

    not_official_content = models.BooleanField(_('Official Content'), blank=True, default=True)

    # html-meta tags
    meta = models.OneToOneField(MetaTags, null=True, on_delete=models.SET_NULL)

    categories = GenericRelation(CategoryItem,
                                          object_id_field="object_id",
                                          content_type_field="content_type")
    perms = GenericRelation(ObjectPermission,
                                          object_id_field="object_id",
                                          content_type_field="content_type")

    objects = ArticleManager()

    class Meta:
#         permissions = (("view_article", _("Can view article")),)
        verbose_name = _("Article")
        verbose_name_plural = _("Articles")
        app_label = 'articles'

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        methods coupled to this instance.
        """
        return ArticleMeta().get_meta(self, name)

    def get_absolute_url(self):
        return reverse('article', args=[self.slug])

    def get_version_url(self, hash):
        return reverse('article.version', args=[hash])

    def __str__(self):
        return self.headline

    def get_thumbnail_url(self):
        if not self.thumbnail:
            return u''

        return reverse('file', args=[self.thumbnail.pk])

    def save(self, *args, **kwargs):
        if not self.id:
            self.guid = str(uuid.uuid4())
        self.assign_release_dt_local()
        super(Article, self).save(*args, **kwargs)

    def assign_release_dt_local(self):
        """
        convert release_dt to the corresponding local time

        example:

        if
            release_dt: 2014-05-09 03:30:00
            timezone: US/Pacific
            settings.TIME_ZONE: US/Central
        then
            the corresponding release_dt_local will be: 2014-05-09 05:30:00
        """
        now = datetime.now()
        now_with_tz = adjust_datetime_to_timezone(now, settings.TIME_ZONE)
        if self.timezone and self.release_dt and self.timezone.zone != settings.TIME_ZONE:
            time_diff = adjust_datetime_to_timezone(now, self.timezone) - now_with_tz
            self.release_dt_local = self.release_dt + time_diff
        else:
            self.release_dt_local = self.release_dt

    def age(self):
        return datetime.now() - self.create_dt

    @property
    def category_set(self):
        items = {}
        for cat in self.categories.select_related('category', 'parent'):
            if cat.category:
                items["category"] = cat.category
            elif cat.parent:
                items["sub_category"] = cat.parent
        return items

    @property
    def has_google_author(self):
        return self.contributor_type == self.CONTRIBUTOR_AUTHOR

    @property
    def has_google_publisher(self):
        return self.contributor_type == self.CONTRIBUTOR_PUBLISHER
Пример #16
0
class Resume(TendenciBaseModel):
    guid = models.CharField(max_length=40)
    title = models.CharField(max_length=250)
    slug = SlugField(_('URL Path'), unique=True)
    description = tinymce_models.HTMLField()

    location = models.CharField(
        max_length=500, blank=True
    )  # cannot be foreign, needs to be open 'Texas' 'All 50 States' 'US and International'
    skills = models.TextField(blank=True)
    experience = models.TextField(blank=True)
    awards = models.TextField(_('Awards and Certifications'), blank=True)
    education = models.TextField(blank=True)
    is_agency = models.BooleanField(
        default=False
    )  # defines if the resume posting is by a third party agency

    #TODO: do we need these fields?
    #desiredlocationstate = models.CharField(max_length=50)
    #desiredlocationcountry = models.CharField(max_length=50)
    #willingtorelocate = models.NullBooleanField()
    #workschedulepreferred = models.CharField(max_length=100)
    #compensationdesired = models.CharField(max_length=50)
    #licenses = models.CharField(max_length=100)
    #certifications = models.CharField(max_length=100)
    #expertise = models.CharField(max_length=800)
    #languages = models.CharField(max_length=120)

    # date related fields
    list_type = models.CharField(max_length=50,
                                 default='regular')  # premium or regular
    requested_duration = models.IntegerField(default=30)

    activation_dt = models.DateTimeField(
        null=True, blank=True)  # date resume listing was activated
    expiration_dt = models.DateTimeField(
        null=True, blank=True
    )  # date resume expires based on activation date and duration

    resume_url = models.CharField(
        max_length=300, blank=True)  # link to other (fuller) resume posting
    resume_file = models.FileField(_('Upload your resume here'),
                                   max_length=260,
                                   upload_to=file_directory,
                                   blank=True,
                                   default="")
    syndicate = models.BooleanField(_('Include in RSS feed'),
                                    blank=True,
                                    default=False)

    #TODO: foreign
    contact_name = models.CharField(max_length=150, blank=True)
    contact_address = models.CharField(max_length=50, blank=True)
    contact_address2 = models.CharField(max_length=50, blank=True)
    contact_city = models.CharField(max_length=50, blank=True)
    contact_state = models.CharField(max_length=50, blank=True)
    contact_zip_code = models.CharField(max_length=50, blank=True)
    contact_country = models.CharField(max_length=50, blank=True)
    contact_phone = models.CharField(max_length=50, blank=True)
    contact_phone2 = models.CharField(max_length=50, blank=True)
    contact_fax = models.CharField(max_length=50, blank=True)
    contact_email = models.CharField(max_length=300, blank=True)
    contact_website = models.CharField(max_length=300, blank=True)

    # authority fields
    # allow_anonymous_view = models.NullBooleanField(_("Public can view"))
    # allow_user_view = models.NullBooleanField(_("Signed in user can view"))
    # allow_member_view = models.NullBooleanField()
    # allow_anonymous_edit = models.NullBooleanField()
    # allow_user_edit = models.NullBooleanField(_("Signed in user can change"))
    # allow_member_edit = models.NullBooleanField()

    # create_dt = models.DateTimeField(auto_now_add=True)
    # update_dt = models.DateTimeField(auto_now=True)
    # creator = models.ForeignKey(User, related_name="%(class)s_creator", editable=False, null=True, on_delete=models.SET_NULL)
    # creator_username = models.CharField(max_length=50, null=True)
    # owner = models.ForeignKey(User, related_name="%(class)s_owner", null=True, on_delete=models.SET_NULL)
    # owner_username = models.CharField(max_length=50, null=True)
    # status = models.NullBooleanField("Active", default=True)
    # status_detail = models.CharField(max_length=50, default='active')

    meta = models.OneToOneField(MetaTags, null=True, on_delete=models.SET_NULL)
    tags = TagField(blank=True)

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = ResumeManager()

    class Meta:
        permissions = (("view_resume", _("Can view resume")), )
        app_label = 'resumes'

    def get_meta(self, name):
        """
        This method is standard across all models that are
        related to the Meta model.  Used to generate dynamic
        meta information niche to this model.
        """
        return ResumeMeta().get_meta(self, name)

    def get_absolute_url(self):
        return reverse('resume', args=[self.slug])

    def save(self, *args, **kwargs):
        self.guid = self.guid or uuid.uuid4()
        super(Resume, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

    def is_pending(self):
        return self.status == 0 and self.status_detail == 'pending'
Пример #17
0
class Video(OrderingBaseModel, TendenciBaseModel):
    """
    Videos plugin to add embedding based on video url. Uses embed.ly
    """
    title = models.CharField(max_length=200)
    slug = models.SlugField(_('URL Path'), unique=True, max_length=200)
    category = models.ForeignKey(Category,
                                 null=True,
                                 on_delete=models.SET_NULL)
    video_type = models.ForeignKey(VideoType,
                                   null=True,
                                   blank=True,
                                   on_delete=models.SET_NULL)
    image = models.ImageField(upload_to='uploads/videos/%y/%m', blank=True)
    video_url = models.CharField(max_length=500,
                                 help_text='Youtube, Vimeo, etc..')
    description = tinymce_models.HTMLField()
    release_dt = models.DateTimeField(_("Release Date"), null=True)
    tags = TagField(blank=True, help_text='Tag 1, Tag 2, ...')

    perms = GenericRelation(ObjectPermission,
                            object_id_field="object_id",
                            content_type_field="content_type")

    objects = VideoManager()

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        model = self.__class__

        if self.pk is None:
            # Append
            try:
                last = model.objects.order_by('-position')[0]
                self.position = last.position + 1
            except IndexError:
                # First row
                self.position = 0

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

    class Meta:
        #permissions = (("view_video","Can view video"),)
        ordering = ('position', )
        verbose_name = get_setting('module', 'videos', 'label') or "Video"
        verbose_name_plural = get_setting('module', 'videos',
                                          'label_plural') or "Videos"
        app_label = 'videos'

    def get_absolute_url(self):
        return reverse('video.details', args=[self.slug])

    def video_embed_url(self):
        """
        Returns a youtube embed URL
        Attempts to convert common YouTube URL patterns
        to the URL embed pattern.

        TODO: Contribute more video service embed URL's
        """
        url_pattern = r'https:\/\/www\.youtube\.com\/watch\?v=(\w+)'
        share_pattern = r'https:\/\/youtu\.be\/(\w+)'

        def repl(x):
            return 'https://www.youtube.com/embed/%s' % x.group(1)

        if re.match(url_pattern, self.video_url):
            return re.sub(url_pattern, repl, self.video_url)

        if re.match(share_pattern, self.video_url):
            return re.sub(share_pattern, repl, self.video_url)

        return self.video_url

    def embed_code(self, **kwargs):
        width = kwargs.get('width') or 600
        height = kwargs.get('height') or 400
        return get_oembed_code(self.video_url, width, height)

    def thumbnail(self):
        return get_oembed_thumbnail(self.video_url, 600, 400)

    def is_youtube_video(self):
        return 'www.youtube.com' in self.video_url

    def youtube_video_id(self):
        if self.is_youtube_video():
            return get_embed_ready_url(self.video_url).replace(
                'https://www.youtube.com/embed/', '')
        return None
Пример #18
0
class Email(TendenciBaseModel):
    guid = models.CharField(max_length=50)
    priority = models.IntegerField(default=0)
    subject =models.CharField(max_length=255)
    body = tinymce_models.HTMLField()
    #body = models.TextField()
    sender = models.CharField(max_length=255)
    sender_display = models.CharField(max_length=255)
    reply_to = models.CharField(max_length=255)
    recipient = models.CharField(max_length=255, blank=True, default='')
    recipient_dispaly = models.CharField(max_length=255, blank=True, default='')
    recipient_cc = models.CharField(max_length=255, blank=True, default='')
    recipient_cc_display = models.CharField(max_length=255, blank=True, default='')
    recipient_bcc = models.CharField(max_length=255, blank=True, default='')
    attachments = models.CharField(max_length=500, blank=True, default='')
    content_type = models.CharField(max_length=255, default='text/html', choices=(('text/html','text/html'),('text','text'),))

    #create_dt = models.DateTimeField(auto_now_add=True)
    #status = models.NullBooleanField(default=True, choices=((True,'Active'),(False,'Inactive'),))

    class Meta:
        app_label = 'emails'


    @models.permalink
    def get_absolute_url(self):
        return ("email.view", [self.pk])

    def __unicode__(self):
        return self.subject

    def send(self, fail_silently=False, **kwargs):
        recipient_list = []
        recipient_bcc_list = []
        headers = kwargs.get('headers', {})
        attachments = kwargs.get('attachments', [])

        if isinstance(self.recipient, basestring):
            recipient_list = self.recipient.split(',')
            recipient_list = [recipient.strip() for recipient in recipient_list \
                              if recipient.strip() <> '']
        else:
            recipient_list = list(self.recipient)
        if isinstance(self.recipient_cc, basestring):
            recipient_cc_list = self.recipient_cc.split(',')
            recipient_cc_list = [recipient_cc.strip() for recipient_cc in recipient_cc_list if \
                                  recipient_cc.strip() <> '']
            recipient_list += recipient_cc_list
        else:
            recipient_list += list(self.recipient_cc)
        if isinstance(self.recipient_bcc, basestring):
            recipient_bcc_list = self.recipient_bcc.split(',')
            recipient_bcc_list = [recipient_bcc.strip() for recipient_bcc in recipient_bcc_list if \
                                   recipient_bcc.strip() <> '']
        else:
            recipient_bcc_list = list(self.recipient_bcc)

        if self.reply_to:
            headers['Reply-To'] = self.reply_to
        if not self.sender:
            self.sender = get_setting('site', 'global', 'siteemailnoreplyaddress') or settings.DEFAULT_FROM_EMAIL
        if self.sender_display:
            headers['From'] = '%s<%s>' % (self.sender_display, self.sender)
        if self.priority and self.priority == 1:
            headers['X-Priority'] = '1'
            headers['X-MSMail-Priority'] = 'High'

        if recipient_list or recipient_bcc_list:
            msg = EmailMessage(self.subject,
                               self.body,
                               self.sender,
                               recipient_list,
                               recipient_bcc_list,
                               headers=headers,
                               connection=kwargs.get('connection', None))
            if self.content_type == 'html' or self.content_type == 'text/html':
                msg.content_subtype = 'html'
            if attachments:
                msg.attachments = attachments
            msg.send(fail_silently=fail_silently)

    def save(self, user=None, *args, **kwargs):
        if not self.id:
            self.guid = uuid.uuid1()
            if user and not user.is_anonymous():
                self.creator=user
                self.creator_username=user.username
        if user and not user.is_anonymous():
            self.owner=user
            self.owner_username=user.username

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

    # if this email allows view by user2_compare
    def allow_view_by(self, user2_compare):
        boo = False

        if user2_compare.profile.is_superuser:
            boo = True
        else:
            if user2_compare == self.creator or user2_compare == self.owner:
                if self.status:
                    boo = True
            else:
                if user2_compare.has_perm('emails.view_email', self):
                    if self.status == 1 and self.status_detail=='active':
                        boo = True
        return boo

    # if this email allows edit by user2_compare
    def allow_edit_by(self, user2_compare):
        boo = False
        if user2_compare.profile.is_superuser:
            boo = True
        else:
            if user2_compare == self.user:
                boo = True
            else:
                if user2_compare == self.creator or user2_compare == self.owner:
                    if self.status:
                        boo = True
                else:
                    if user2_compare.has_perm('emails.edit_email', self):
                        if self.status:
                            boo = True
        return boo


    def template_body(self, email_d):
        """
            build the email body from the template and variables passed in by a dictionary
        """
        import os.path
        from django.template.loader import render_to_string

        template = email_d.get('template_path_name', '')

        # check if this template exists
        boo = False
        for dir in settings.TEMPLATE_DIRS:
            if os.path.isfile(os.path.join(dir, template)):
                boo = True
                break

        if not boo:
            # log an event

            # notify admin of missing template

            pass
        else:
            self.body = render_to_string(template)
            for key in email_d.keys():
                # need to convert [blah] to %5Bblah%5D for replace line
                tmp_value = "%5B" + key[1:-1] + "%5D"
                if email_d[key] <> None:
                    self.body = self.body.replace(key, email_d[key])
                    self.body = self.body.replace(tmp_value, email_d[key])
                else:
                    self.body = self.body.replace(key, '')
                    self.body = self.body.replace(tmp_value, '')

        return boo