예제 #1
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)
예제 #2
0
파일: models.py 프로젝트: iniForum/tendenci
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
파일: models.py 프로젝트: zaid100/tendenci
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
예제 #4
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 ''
예제 #5
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
예제 #6
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
예제 #7
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'
예제 #8
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)
예제 #9
0
class Group(TendenciBaseModel):

    TYPE_DISTRIBUTION = 'distribution'
    TYPE_SECURITY = 'security'
    TYPE_SYSTEM_GENERATED = 'system_generated'

    TYPE_CHOICES = (
        (TYPE_DISTRIBUTION, _('Distribution')),
        (TYPE_SECURITY, _('Security')),
        (TYPE_SYSTEM_GENERATED, _('System Generated')),
    )

    name = models.CharField(_('Group Name'), max_length=255, unique=True)
    slug = SlugField(_('URL Path'), unique=True)
    guid = models.CharField(max_length=40)
    label = models.CharField(_('Group Label'), max_length=255, blank=True)
    dashboard_url = models.CharField(
        _('Dashboard URL'),
        max_length=255,
        default='',
        blank=True,
        help_text=
        _('Enable Group Dashboard Redirect in site settings to use this feature.'
          ))
    type = models.CharField(max_length=75,
                            blank=True,
                            choices=TYPE_CHOICES,
                            default=TYPE_DISTRIBUTION)
    email_recipient = models.CharField(_('Recipient Email'),
                                       max_length=255,
                                       blank=True)
    show_as_option = models.BooleanField(_('Display Option'),
                                         default=True,
                                         blank=True)
    allow_self_add = models.BooleanField(_('Allow Self Add'), default=True)
    show_for_memberships = models.BooleanField(
        default=True,
        help_text=
        _('If checked and allows self add, this group will show as an option for the group field on membership applications'
          ),
    )
    show_for_events = models.BooleanField(
        default=True,
        help_text=
        _('If checked, this group will show as an option for the group field on events'
          ),
    )
    allow_self_remove = models.BooleanField(_('Allow Self Remove'),
                                            default=True)
    sync_newsletters = models.BooleanField(_('Sync for newsletters'),
                                           default=True)
    description = models.TextField(blank=True)
    auto_respond = models.BooleanField(_('Auto Responder'), default=False)
    auto_respond_priority = models.FloatField(_('Priority'),
                                              blank=True,
                                              default=0)
    notes = models.TextField(blank=True)
    members = models.ManyToManyField(User,
                                     through='GroupMembership',
                                     related_name='user_groups')

    group = models.OneToOneField(AuthGroup,
                                 null=True,
                                 default=None,
                                 on_delete=models.CASCADE)
    permissions = models.ManyToManyField(Permission,
                                         related_name='group_permissions',
                                         blank=True)
    # use_for_membership = models.BooleanField(_('User for Membership Only'), default=0, blank=True)

    objects = GroupManager()

    class Meta:
        #         permissions = (("view_group", _("Can view group")),)
        verbose_name = _("Group")
        verbose_name_plural = _("Groups")
        ordering = ("name", )
        app_label = 'user_groups'

    def __str__(self):
        return self.name

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

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        if not self.guid:
            self.guid = uuid.uuid4()

        if not self.slug:
            self.slug = slugify(self.name)

        # add the default entity
        if not self.entity:
            self.entity = Entity.objects.first()

        super(Group, self).save(force_insert, force_update, *args, **kwargs)

        if not self.group:
            # create auth group if not exists
            # note that the name of auth group is also unique
            group_name = self.get_unique_auth_group_name()
            self.group = AuthGroup.objects.create(name=group_name)
            self.save()

    @property
    def active_members(self):
        return GroupMembership.objects.filter(group=self,
                                              status=True,
                                              status_detail='active')

    def get_unique_auth_group_name(self):
        # get the unique name for auth group.
        # the max length of the name of the auth group is 80.
        name = self.name
        if not name:
            name = str(self.id)

        if len(name) > 80:
            name = name[:80]

        if AuthGroup.objects.filter(name=name).exists():
            name = 'User Group %d' % self.id

        return name

    def is_member(self, user):
        # impersonation
        user = getattr(user, 'impersonated_user', user)

        if isinstance(user, User):
            return self.members.filter(id=user.id).exists()

        return False

    def add_user(self, user, **kwargs):
        """
        add a user to the group; check for duplicates
        return (user, created)
        """
        if isinstance(user, User):

            # first check if user exists
            if not self.is_member(user):

                params = {
                    'group': self,
                    'member': user,
                    'creator_id': kwargs.get('creator_id') or user.pk,
                    'creator_username': kwargs.get('creator_username')
                    or user.username,
                    'owner_id': kwargs.get('owner_id') or user.pk,
                    'owner_username': kwargs.get('owner_username')
                    or user.username,
                    'status': kwargs.get('status') or True,
                    'status_detail': kwargs.get('status_detail') or 'active'
                }
                try:
                    GroupMembership.objects.create(**params)
                except IntegrityError:
                    return user, False

                return user, True  # created

        return user, False

    def remove_user(self, user, **kwargs):
        if self.is_member(user):
            GroupMembership.objects.get(group=self, member=user).delete()
예제 #10
0
class Location(TendenciBaseModel):
    guid = models.CharField(max_length=40)
    location_name = models.CharField(_('Name'), max_length=200, blank=True)
    slug = SlugField(_('URL Path'), unique=True)
    description = models.TextField(blank=True)

    # contact/location information
    contact = models.CharField(max_length=100, blank=True)
    address = models.CharField(max_length=100, blank=True)
    address2 = models.CharField(max_length=100, blank=True)
    city = models.CharField(max_length=100, blank=True)
    state = models.CharField(max_length=50, blank=True)
    zipcode = models.CharField(_('Zip Code'), max_length=50, blank=True)
    country = models.CharField(max_length=100, 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)

    latitude = models.FloatField(blank=True, null=True)
    longitude = models.FloatField(blank=True, null=True)
    logo = models.ForeignKey(File,
                             null=True,
                             default=None,
                             help_text=_('Only jpg, gif, or png images.'),
                             on_delete=models.SET_NULL)
    hq = models.BooleanField(_('Headquarters'), default=False)

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

    objects = LocationManager()

    class Meta:
        permissions = (("view_location", _("Can view location")), )
        app_label = 'locations'

    def __str__(self):
        return self.location_name

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

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

    def get_distance(self, **kwargs):
        """
        Pings the Google Map API (DistanceMatrix).
        Returns the distance in miles.
        """
        origin = kwargs.get('origin')
        result = distance_api(**{'origin': origin})

        if result['status'] == 'OK':
            # return result['rows'][0]['elements'][0]['duration']['value']
            return result['rows'][0]['elements'][0]['distance']['value']

        return None

    def get_distance2(self, lat, lng):
        """
        http://www.johndcook.com/python_longitude_latitude.html
        Distance in miles multiply by 3960
        Distance in kilometers multiply by 6373
        """
        import math

        # if we don't have latitude or longitude
        # we return a none type object instead of int
        if not all((self.latitude, self.longitude)):
            return None

        # Convert latitude and longitude to
        # spherical coordinates in radians.
        degrees_to_radians = math.pi / 180.0

        # phi = 90 - latitude
        phi1 = (90.0 - self.latitude) * degrees_to_radians
        phi2 = (90.0 - lat) * degrees_to_radians

        # theta = longitude
        theta1 = self.longitude * degrees_to_radians
        theta2 = lng * degrees_to_radians

        cos = (math.sin(phi1) * math.sin(phi2) * math.cos(theta1 - theta2) +
               math.cos(phi1) * math.cos(phi2))
        try:
            arc = math.acos(cos)
        except:
            arc = 0

        # Remember to multiply arc by the radius of the earth
        # in your favorite set of units to get length.
        return arc * 3960

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

        # update latitude and longitude
        if not all((self.latitude, self.longitude)):
            self.latitude, self.longitude = get_coordinates(self.get_address())

        photo_upload = kwargs.pop('photo', None)
        super(Location, 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.logo = image
            self.save()
예제 #11
0
파일: models.py 프로젝트: chendong0444/ams
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