Example #1
0
class Conference(models.Model):
    """
    the full conference for a specific year, e.g. US PyCon 2012.
    """

    title = models.CharField(_("title"), max_length=100)

    # when the conference runs
    start_date = models.DateField(_("start date"), null=True, blank=True)
    end_date = models.DateField(_("end date"), null=True, blank=True)

    # timezone the conference is in
    timezone = TimeZoneField(_("timezone"), blank=True)

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        super(Conference, self).save(*args, **kwargs)
        if self.id in CONFERENCE_CACHE:
            del CONFERENCE_CACHE[self.id]

    def delete(self):
        pk = self.pk
        super(Conference, self).delete()
        try:
            del CONFERENCE_CACHE[pk]
        except KeyError:
            pass

    class Meta(object):
        verbose_name = _("conference")
        verbose_name_plural = _("conferences")
Example #2
0
class Person(TendenciBaseModel):
    user = models.OneToOneField(User,
                                related_name="profile",
                                verbose_name=_('user'))
    phone = models.CharField(_('phone'), max_length=50, blank=True)
    address = models.CharField(_('address'), max_length=150, blank=True)
    address2 = models.CharField(_('address2'),
                                max_length=100,
                                default='',
                                blank=True)
    member_number = models.CharField(_('member number'),
                                     max_length=50,
                                     blank=True)
    city = models.CharField(_('city'), max_length=50, blank=True)
    state = models.CharField(_('state'), max_length=50, blank=True)
    zipcode = models.CharField(_('zipcode'), max_length=50, blank=True)
    county = models.CharField(_('county'), max_length=50, blank=True)
    country = models.CharField(_('country'), max_length=50, blank=True)

    url = models.CharField(_('url'), max_length=100, blank=True)

    time_zone = TimeZoneField(_('timezone'))
    language = models.CharField(_('language'),
                                max_length=10,
                                choices=settings.LANGUAGES,
                                default=settings.LANGUAGE_CODE)

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

    class Meta:
        abstract = True
Example #3
0
class Profile(ModelBase):
    """Profile model for django users, get it with user.get_profile()."""

    user = models.OneToOneField(User,
                                primary_key=True,
                                verbose_name=_lazy(u'User'))
    name = models.CharField(max_length=255,
                            null=True,
                            blank=True,
                            verbose_name=_lazy(u'Display name'))
    public_email = models.BooleanField(  # show/hide email
        default=False,
        verbose_name=_lazy(u'Make my email public'))
    avatar = models.ImageField(upload_to=settings.USER_AVATAR_PATH,
                               null=True,
                               blank=True,
                               verbose_name=_lazy(u'Avatar'),
                               max_length=settings.MAX_FILEPATH_LENGTH)
    bio = models.TextField(null=True,
                           blank=True,
                           verbose_name=_lazy(u'Biography'))
    website = models.URLField(max_length=255,
                              null=True,
                              blank=True,
                              verbose_name=_lazy(u'Website'))
    twitter = models.URLField(max_length=255,
                              null=True,
                              blank=True,
                              verbose_name=_lazy(u'Twitter URL'))
    facebook = models.URLField(max_length=255,
                               null=True,
                               blank=True,
                               verbose_name=_lazy(u'Facebook URL'))
    irc_handle = models.CharField(max_length=255,
                                  null=True,
                                  blank=True,
                                  verbose_name=_lazy(u'IRC nickname'))
    timezone = TimeZoneField(null=True,
                             blank=True,
                             verbose_name=_lazy(u'Timezone'))
    country = models.CharField(max_length=2,
                               choices=COUNTRIES,
                               null=True,
                               blank=True,
                               verbose_name=_lazy(u'Country'))
    # No city validation
    city = models.CharField(max_length=255,
                            null=True,
                            blank=True,
                            verbose_name=_lazy(u'City'))
    livechat_id = models.CharField(default=None,
                                   null=True,
                                   blank=True,
                                   max_length=255,
                                   verbose_name=_lazy(u'Livechat ID'))

    def __unicode__(self):
        return unicode(self.user)
Example #4
0
class Server(models.Model):
    """Guild Wars 2 Server"""
    class Meta:
        ordering = ['name']

    name = models.CharField(max_length=50)
    tz = TimeZoneField('server time zone')

    def __unicode__(self):
        return self.name
Example #5
0
class Account(models.Model):
    user = models.ForeignKey(User, unique=True, verbose_name=_("user"))

    timezone = TimeZoneField(_("timezone"))
    language = models.CharField(_("language"),
                                max_length=10,
                                choices=settings.LANGUAGES,
                                default=settings.LANGUAGE_CODE)

    def __unicode__(self):
        return self.user.username
Example #6
0
class Profile(ModelBase):
    """Profile model for django users, get it with user.get_profile()."""

    user = models.OneToOneField(User, primary_key=True,
                                verbose_name=_lazy(u'User'))
    name = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'Display name'))
    public_email = models.BooleanField(  # show/hide email
        default=False, verbose_name=_lazy(u'Make my email public'))
    avatar = models.ImageField(upload_to=settings.USER_AVATAR_PATH, null=True,
                               blank=True, verbose_name=_lazy(u'Avatar'),
                               max_length=settings.MAX_FILEPATH_LENGTH)
    bio = models.TextField(null=True, blank=True,
                           verbose_name=_lazy(u'Biography'))
    website = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Website'))
    twitter = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Twitter URL'))
    facebook = models.URLField(max_length=255, null=True, blank=True,
                               verbose_name=_lazy(u'Facebook URL'))
    irc_handle = models.CharField(max_length=255, null=True, blank=True,
                                  verbose_name=_lazy(u'IRC nickname'))
    timezone = TimeZoneField(null=True, blank=True,
                             verbose_name=_lazy(u'Timezone'))
    country = models.CharField(max_length=2, choices=COUNTRIES, null=True,
                               blank=True, verbose_name=_lazy(u'Country'))
    # No city validation
    city = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'City'))
    locale = LocaleField(default=settings.LANGUAGE_CODE,
                         verbose_name=_lazy(u'Preferred language'))

    class Meta(object):
        permissions = (('view_karma_points', 'Can view karma points'),
                       ('deactivate_users', 'Can deactivate users'),)

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

    def get_absolute_url(self):
        return reverse('users.profile', args=[self.user_id])

    def clear(self):
        """Clears out the users profile"""
        self.name = ''
        self.public_email = False
        self.avatar = None
        self.bio = ''
        self.website = ''
        self.twitter = ''
        self.facebook = ''
        self.irc_handle = ''
        self.city = ''
Example #7
0
class Setting(models.Model):
    """
    Settings model for specific blog settings
    """
    blog_title = models.CharField(max_length=75, null=True, blank=True)
    blog_tagline = models.CharField(max_length=150, null=True, blank=True)
    name = models.CharField(max_length=30, null=True, blank=True)
    bio = models.TextField(null=True, blank=True)
    disqus_shortname = models.CharField(max_length=75, null=True, blank=True)
    user = models.ForeignKey(User, editable=False)
    timezone = TimeZoneField(default="US/Central")

    objects = SettingManager()
Example #8
0
class Contact(TendenciBaseModel):
    """
    Contact records are created when someone fills out a form.
    The form creates the contact with a message.
    Later the contact can be updated to include comments for
    further communication.
    """
    guid = models.CharField(max_length=40)
    timezone = TimeZoneField()
    user = models.ForeignKey(User, null=True, related_name='contact_user')

    first_name = models.CharField(max_length=100, blank=True)
    middle_name = models.CharField(max_length=100, blank=True)
    last_name = models.CharField(max_length=100, blank=True)
    suffix = models.CharField(max_length=5, blank=True)

    addresses = models.ManyToManyField(Address, blank=True)
    phones = models.ManyToManyField(Phone, blank=True)
    emails = models.ManyToManyField(Email, blank=True)
    urls = models.ManyToManyField(URL, blank=True)
    companies = models.ManyToManyField(Company, blank=True)

    message = models.TextField()

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

    # TODO: consider attachments

    objects = ContactManager()

    class Meta:
        permissions = (("view_contact", _("Can view contact")), )
        app_label = 'contacts'

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

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

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

    def __unicode__(self):
        if self.first_name:
            return '%s %s' % (self.first_name, self.last_name)
        else:
            return '%s' % self.user
Example #9
0
class Conference(models.Model):
    """
    the full conference for a specific year, e.g. US PyCon 2012.
    """

    title = models.CharField(_("title"), max_length=100)
    slug = models.SlugField(_("slug"), null=True, blank=True)

    # when the conference runs
    start_date = models.DateField(_("start date"), null=True, blank=True)
    end_date = models.DateField(_("end date"), null=True, blank=True)

    # timezone the conference is in
    timezone = TimeZoneField(_("timezone"), blank=True)

    reviews_start_date = models.DateTimeField(null=True, blank=True)
    reviews_end_date = models.DateTimeField(null=True, blank=True)
    reviews_active = models.NullBooleanField()

    tickets_editable = models.BooleanField(default=True)
    tickets_editable_until = models.DateTimeField(null=True, blank=True)

    anonymize_proposal_author = models.BooleanField(
        _("anonymize proposal author"), default=True)

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        super(Conference, self).save(*args, **kwargs)
        if self.id in CONFERENCE_CACHE:
            del CONFERENCE_CACHE[self.id]

    def delete(self):
        pk = self.pk
        super(Conference, self).delete()
        try:
            del CONFERENCE_CACHE[pk]
        except KeyError:
            pass

    def get_reviews_active(self):
        if self.reviews_active is not None:
            return self.reviews_active
        if self.reviews_start_date and self.reviews_end_date:
            return self.reviews_start_date <= now() <= self.reviews_end_date
        return False

    class Meta(object):
        verbose_name = _("conference")
        verbose_name_plural = _("conferences")
Example #10
0
class Person(TendenciBaseModel):
    user = UnsavedOneToOne(User, related_name="profile", verbose_name=_('user'))
    phone = models.CharField(_('phone'), max_length=50, blank=True)
    address = models.CharField(_('address'), max_length=150, blank=True)
    address2 = models.CharField(_('address2'), max_length=100, default='', blank=True)
    member_number = models.CharField(_('member number'), max_length=50, blank=True)
    city = models.CharField(_('city'), max_length=50, blank=True)
    state = models.CharField(_('state'), max_length=50, blank=True)
    zipcode = models.CharField(_('zipcode'), max_length=50, blank=True)
    county = models.CharField(_('county'), max_length=50, blank=True)
    country = models.CharField(_('country'), max_length=255, blank=True)

    # fields to be used for the alternate address
    address_2 = models.CharField(_('address'), max_length=150, blank=True)
    address2_2 = models.CharField(_('address2'), max_length=100, default='', blank=True)
    member_number_2 = models.CharField(_('member number'), max_length=50, blank=True)
    city_2 = models.CharField(_('city'), max_length=50, blank=True)
    state_2 = models.CharField(_('state'), max_length=50, blank=True)
    zipcode_2 = models.CharField(_('zipcode'), max_length=50, blank=True)
    county_2 = models.CharField(_('county'), max_length=50, blank=True)
    country_2 = models.CharField(_('country'), max_length=255, blank=True)

    url = models.CharField(_('url'), max_length=100, blank=True)

    time_zone = TimeZoneField(_('timezone'))
    language = models.CharField(_('language'), max_length=10, choices=settings.LANGUAGES, default=settings.LANGUAGE_CODE)

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

    class Meta:
        abstract = True

    def get_address(self):
        """
        Returns full address depending on which attributes are available.
        """
        state_zip = ' '.join([s for s in (self.state, self.zipcode) if s])
        city_state_zip = ', '.join([s for s in (self.city, state_zip, self.country) if s])

        return '%s %s %s' % (self.address, self.address2, city_state_zip)

    def get_alternate_address(self):
        """
        Returns full alternate address depending on which attributes are available.
        """
        state_zip = ' '.join([s for s in (self.state_2, self.zipcode_2) if s])
        city_state_zip = ', '.join([s for s in (self.city_2, state_zip, self.country_2) if s])

        return '%s %s %s' % (self.address_2, self.address2_2, city_state_zip)
Example #11
0
class Profile(models.Model):
    user = models.OneToOneField(User)
    skype = models.CharField("Skype ID", max_length=20, null=True, blank=True)
    aim = models.CharField("AIM", max_length=20, null=True, blank=True)
    gchat = models.CharField("Google Chat",
                             max_length=20,
                             null=True,
                             blank=True)
    phone = models.CharField("Phone number",
                             max_length=20,
                             null=True,
                             blank=True)
    is_available = models.BooleanField("Available now")
    timezone = TimeZoneField(choices=sorted(
        PRETTY_TIMEZONE_CHOICES, key=lambda x: (int(x[1][4:9]), x[1])))
    skills = models.ManyToManyField('Skill', blank=True)

    def __unicode__(self):
        return unicode(self.user)
Example #12
0
class UserProfile(ModelBase):
    """
    The UserProfile *must* exist for each
    django.contrib.auth.models.User object. This may be relaxed
    once Dekiwiki isn't the definitive db for user info.

    timezone and language fields are syndicated to Dekiwiki
    """
    # Website fields defined for the profile form
    # TODO: Someday this will probably need to allow arbitrary per-profile
    # entries, and these will just be suggestions.
    website_choices = [('website',
                        dict(
                            label=_(u'Website'),
                            prefix='http://',
                            regex='^https?://',
                            fa_icon='icon-link',
                        )),
                       ('twitter',
                        dict(
                            label=_(u'Twitter'),
                            prefix='https://twitter.com/',
                            regex='^https?://twitter.com/',
                            fa_icon='icon-twitter',
                        )),
                       ('github',
                        dict(
                            label=_(u'GitHub'),
                            prefix='https://github.com/',
                            regex='^https?://github.com/',
                            fa_icon='icon-github',
                        )),
                       ('stackoverflow',
                        dict(
                            label=_(u'Stack Overflow'),
                            prefix='https://stackoverflow.com/users/',
                            regex='^https?://stackoverflow.com/users/',
                            fa_icon='icon-stackexchange',
                        )),
                       ('linkedin',
                        dict(
                            label=_(u'LinkedIn'),
                            prefix='https://www.linkedin.com/',
                            regex='^https?:\/\/www.linkedin.com\/(in|pub)',
                            fa_icon='icon-linkedin',
                        )),
                       ('mozillians',
                        dict(
                            label=_(u'Mozillians'),
                            prefix='https://mozillians.org/u/',
                            regex='^https?://mozillians.org/u/',
                            fa_icon='icon-group',
                        )),
                       ('facebook',
                        dict(
                            label=_(u'Facebook'),
                            prefix='https://www.facebook.com/',
                            regex='^https?://www.facebook.com/',
                            fa_icon='icon-facebook',
                        ))]
    # This could be a ForeignKey, except wikidb might be
    # a different db
    deki_user_id = models.PositiveIntegerField(default=0, editable=False)
    timezone = TimeZoneField(null=True,
                             blank=True,
                             verbose_name=_(u'Timezone'))
    locale = LocaleField(null=True,
                         blank=True,
                         db_index=True,
                         verbose_name=_(u'Language'))
    homepage = models.URLField(max_length=255,
                               blank=True,
                               default='',
                               error_messages={
                                   'invalid':
                                   _(u'This URL has an invalid format. '
                                     u'Valid URLs look like '
                                     u'http://example.com/my_page.')
                               })
    title = models.CharField(_(u'Title'),
                             max_length=255,
                             default='',
                             blank=True)
    fullname = models.CharField(_(u'Name'),
                                max_length=255,
                                default='',
                                blank=True)
    organization = models.CharField(_(u'Organization'),
                                    max_length=255,
                                    default='',
                                    blank=True)
    location = models.CharField(_(u'Location'),
                                max_length=255,
                                default='',
                                blank=True)
    bio = models.TextField(_(u'About Me'), blank=True)

    irc_nickname = models.CharField(_(u'IRC nickname'),
                                    max_length=255,
                                    default='',
                                    blank=True)

    tags = NamespacedTaggableManager(_(u'Tags'), blank=True)

    # should this user receive contentflagging emails?
    content_flagging_email = models.BooleanField(default=False)
    user = models.ForeignKey(User, null=True, editable=False, blank=True)

    # HACK: Grab-bag field for future expansion in profiles
    # We can store arbitrary data in here and later migrate to relational
    # tables if the data ever needs to be indexed & queried. Otherwise,
    # this keeps things nicely denormalized. Ideally, access to this field
    # should be gated through accessors on the model to make that transition
    # easier.
    misc = JSONField(blank=True, null=True)

    class Meta:
        db_table = 'user_profiles'

    def __unicode__(self):
        return '%s: %s' % (self.id, self.deki_user_id)

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

    @property
    def websites(self):
        if 'websites' not in self.misc:
            self.misc['websites'] = {}
        return self.misc['websites']

    @websites.setter
    def websites(self, value):
        self.misc['websites'] = value

    @cached_property
    def beta_tester(self):
        return (constance.config.BETA_GROUP_NAME
                in self.user.groups.values_list('name', flat=True))

    @property
    def is_banned(self):
        return self.user.bans.filter(is_active=True).exists()

    def active_ban(self):
        if self.is_banned:
            return self.user.bans.filter(is_active=True)[:1][0]

    def gravatar(self):
        return gravatar_url(self.user)

    def allows_editing_by(self, user):
        if user == self.user:
            return True
        if user.is_staff or user.is_superuser:
            return True
        return False

    def wiki_activity(self):
        return (Revision.objects.filter(
            creator=self.user).order_by('-created')[:5])
Example #13
0
class News(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)
    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), 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)
    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)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    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)  # 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'))

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

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

    perms = generic.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"

    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())
        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']
        ])
Example #14
0
class Profile(ModelBase, SearchMixin):
    """Profile model for django users, get it with user.get_profile()."""

    user = models.OneToOneField(User,
                                primary_key=True,
                                verbose_name=_lazy(u'User'))
    name = models.CharField(max_length=255,
                            null=True,
                            blank=True,
                            verbose_name=_lazy(u'Display name'))
    public_email = models.BooleanField(  # show/hide email
        default=False,
        verbose_name=_lazy(u'Make my email public'))
    avatar = models.ImageField(upload_to=settings.USER_AVATAR_PATH,
                               null=True,
                               blank=True,
                               verbose_name=_lazy(u'Avatar'),
                               max_length=settings.MAX_FILEPATH_LENGTH)
    bio = models.TextField(null=True,
                           blank=True,
                           verbose_name=_lazy(u'Biography'))
    website = models.URLField(max_length=255,
                              null=True,
                              blank=True,
                              verbose_name=_lazy(u'Website'))
    twitter = models.URLField(max_length=255,
                              null=True,
                              blank=True,
                              verbose_name=_lazy(u'Twitter URL'))
    facebook = models.URLField(max_length=255,
                               null=True,
                               blank=True,
                               verbose_name=_lazy(u'Facebook URL'))
    irc_handle = models.CharField(max_length=255,
                                  null=True,
                                  blank=True,
                                  verbose_name=_lazy(u'IRC nickname'))
    timezone = TimeZoneField(null=True,
                             blank=True,
                             verbose_name=_lazy(u'Timezone'))
    country = models.CharField(max_length=2,
                               choices=COUNTRIES,
                               null=True,
                               blank=True,
                               verbose_name=_lazy(u'Country'))
    # No city validation
    city = models.CharField(max_length=255,
                            null=True,
                            blank=True,
                            verbose_name=_lazy(u'City'))
    locale = LocaleField(default=settings.LANGUAGE_CODE,
                         verbose_name=_lazy(u'Preferred language'))

    class Meta(object):
        permissions = (
            ('view_karma_points', 'Can view karma points'),
            ('deactivate_users', 'Can deactivate users'),
        )

    def __unicode__(self):
        try:
            return unicode(self.user)
        except Exception as exc:
            return unicode('%d (%r)' % (self.pk, exc))

    def get_absolute_url(self):
        return reverse('users.profile', args=[self.user_id])

    def clear(self):
        """Clears out the users profile"""
        self.name = ''
        self.public_email = False
        self.avatar = None
        self.bio = ''
        self.website = ''
        self.twitter = ''
        self.facebook = ''
        self.irc_handle = ''
        self.city = ''

    @property
    def display_name(self):
        return self.name if self.name else self.user.username

    @property
    def twitter_usernames(self):
        from kitsune.customercare.models import Reply
        return list(
            Reply.objects.filter(user=self.user).values_list(
                'twitter_username', flat=True).distinct())

    @classmethod
    def get_mapping_type(cls):
        return UserMappingType

    @property
    def last_contribution_date(self):
        """Get the date of the user's last contribution."""
        from kitsune.customercare.models import Reply
        from kitsune.questions.models import Answer
        from kitsune.wiki.models import Revision

        dates = []

        # Latest Army of Awesome reply:
        try:
            aoa_reply = Reply.objects.filter(user=self.user).latest('created')
            dates.append(aoa_reply.created)
        except Reply.DoesNotExist:
            pass

        # Latest Support Forum answer:
        try:
            answer = Answer.objects.filter(creator=self.user).latest('created')
            dates.append(answer.created)
        except Answer.DoesNotExist:
            pass

        # Latest KB Revision edited:
        try:
            revision = Revision.objects.filter(
                creator=self.user).latest('created')
            dates.append(revision.created)
        except Revision.DoesNotExist:
            pass

        # Latest KB Revision reviewed:
        try:
            revision = Revision.objects.filter(
                reviewer=self.user).latest('reviewed')
            # Old revisions don't have the reviewed date.
            dates.append(revision.reviewed or revision.created)
        except Revision.DoesNotExist:
            pass

        if len(dates) == 0:
            return None

        return max(dates)
Example #15
0
class Profile(models.Model):
    """User profile"""
    json_fields = [
        ('user', 'user__json'),
        'rate',
        'rate_count',
    ]
    user = models.ForeignKey(User, unique=True, verbose_name=_('User'))
    city = models.ForeignKey(City,
                             blank=True,
                             null=True,
                             verbose_name=_('City'))
    icq = models.CharField(max_length=10,
                           blank=True,
                           null=True,
                           verbose_name=_('Icq'))
    jabber = models.EmailField(max_length=60,
                               blank=True,
                               null=True,
                               verbose_name=_('Jabber'))
    site = models.URLField(blank=True, null=True, verbose_name=_('Web site'))
    rate = models.IntegerField(default=0, verbose_name=_('Personal rate'))
    rate_count = models.IntegerField(default=0,
                                     verbose_name=_('Count of raters'))
    posts_rate = models.IntegerField(default=0,
                                     verbose_name=_('Rate earned by posts'))
    comments_rate = models.IntegerField(
        default=0, verbose_name=_('Rate earned by comments'))
    blogs_rate = models.IntegerField(default=0,
                                     verbose_name=_('Rate earned by blogs'))
    timezone = TimeZoneField(default=TIME_ZONE, verbose_name=_('Timezone'))
    avatar = models.ImageField(upload_to=file_upload_path,
                               blank=True,
                               null=True,
                               verbose_name=_('User picture'))
    hide_mail = models.BooleanField(default=True,
                                    verbose_name=_('Show email?'))
    reply_post = models.BooleanField(
        default=True, verbose_name=_('Send notify about reply to post?'))
    reply_comment = models.BooleanField(
        default=True, verbose_name=_('Send notify about reply to comment?'))
    reply_pm = models.BooleanField(default=True,
                                   verbose_name=_('Send notify about PM?'))
    reply_mention = models.BooleanField(
        default=True, verbose_name=_('Send notify about mention?'))
    reply_spy = models.BooleanField(default=True,
                                    verbose_name=_('Send notify about spy?'))
    about = models.TextField(blank=True, null=True, verbose_name=_('About'))
    other = models.TextField(blank=True,
                             null=True,
                             verbose_name=_('Field for addition'))

    def get_posts(self):
        """Get posts by user"""
        return Post.objects.filter(author=self.user)

    def get_city(self):
        """Get user city"""
        if self.city:
            return self.city.name
        else:
            return False

    def get_friends(self, friend_with_me=False):
        """Get user friends"""
        if friend_with_me:
            return Friends.objects.select_related('user').filter(
                friend=self.user)
        return Friends.objects.select_related('friend').filter(user=self)

    def get_blogs(self):
        """Get blogs contain it"""
        return UserInBlog.objects.select_related('blog').filter(user=self.user)

    def rate_user(self, user, value):
        """Rate user
        
        Keyword arguments:
        user -- User
        value -- Integer
        
        Returns: Integer
        
        """
        if not UserRate.objects.filter(user=self).count():
            self.rate += value
            self.rate_count += 1
            rate = UserRate.objects.create(profile=self,
                                           user=user,
                                           negative=(value == -1))
            return True
        else:
            return False

    def get_rate(self):
        """Get user rate"""
        return (self.rate + self.posts_rate * POST_RATE_COEFFICIENT +
                self.blogs_rate * BLOG_RATE_COEFFICIENT +
                self.comments_rate * COMMENT_RATE_COEFFICIENT)

    def check_access(self, type):
        """Check user access

        Keyword arguments:
        type -- Access:

        Returns: Boolean

        """
        rate = self.get_rate()
        if type == Access.new_blog and rate >= NEWBLOG_RATE:
            return True
        elif type == Access.new_comment and rate >= NEWCOMMENT_RATE:
            return True
        elif type == Access.new_post and rate >= NEWPOST_RATE:
            return True
        elif type == Access.rate_comment and rate >= RATECOM_RATE:
            return True
        elif type == Access.rate_blog and rate >= RATEBLOG_RATE:
            return True
        elif type == Access.rate_post and rate >= RATEPOST_RATE:
            return True
        elif type == Access.rate_user and rate >= RATEUSER_RATE:
            return True
        else:
            return False

    def post_count(self):
        """Return post count"""
        return int(Post.objects.filter(author=self.user).count() or 0)

    def comment_count(self):
        """Return comment count"""
        return int(Comment.objects.filter(author=self.user).count())

    def get_avatar(self):
        """Get url of user avatar"""
        try:
            return self.avatar.url
        except ValueError:
            return DEFAULT_AVATAR

    def get_me_on(self):
        """Return array of sites, where user is registered"""
        try:
            return self._getmeon
        except:
            pass
        try:

            class num:
                val = -1

                def inc(self):
                    self.val += 1
                    return True

            num = num()
            meon = MeOn.objects.filter(user=self.user)
            statused = Statused.objects.filter(user=self.user).all()
            for site in statused:
                meon = meon.exclude(url=site.url)
            action = lambda site: num.inc() and {
                'url': site.url,
                'title': site.title,
                'statused': False,
                'show': False,
                'num': num.val
            }
            action_statused = lambda site: site.get_status() and num.inc(
            ) and {
                'url': site.url,
                'title': site.title,
                'statused': True,
                'show': site.show,
                'num': num.val
            }
            self._getmeon = ([action(site) for site in meon] +
                             [action_statused(site) for site in statused])
            return self._getmeon
        except MeOn.DoesNotExist:
            return False

    def get_status(self):
        """Get array of user statuses from other sites"""
        try:
            return self._status
        except:
            self._status = [{
                'obj': service,
                'text': service.get_status()
            } for service in Statused.objects.filter(user=self.user, show=True)
                            ]
            return self._status

    def is_my_friend(self, user):
        """Check friends

        Keyword arguments:
        user -- User

        Returns: Integer
        """
        if user.is_authenticated():
            try:
                Friends.objects.get(user=user, friend=self.user)
                is_my_friend = 1
            except Friends.DoesNotExist:
                is_my_friend = 0
        else:
            is_my_friend = -1
        return is_my_friend

    def update_last_visit(self):
        """Update last site visit time"""
        try:
            view = LastVisit.objects.get(user=self.user)
            view.date = datetime.datetime.now()
            view.save()
        except LastVisit.DoesNotExist:
            view = LastVisit(user=self.user)
            view.save()

    def is_online(self):
        """Check online status"""
        try:
            LastVisit.objects.get(user=self.user,
                                  date__gt=datetime.datetime.now() -
                                  datetime.timedelta(seconds=ONLINE_TIME))
            return True
        except LastVisit.DoesNotExist:
            return False

    def get_block(self):
        """Get bans and blocks"""
        try:
            block = Blocks.objects.get(who=self.user)
            if block.check():
                return block
            else:
                return None
        except Blocks.DoesNotExist:
            return None

    def get_rates(self):
        return UserRate.objects.select_related('user').filter(profile=self)

    def __unicode__(self):
        """Return username"""
        return self.user.username

    @property
    def user__json(self):
        return to_json(self.user)

    class Meta:
        verbose_name = _("User profile")
        verbose_name_plural = _("User profiles")
Example #16
0
class Profile(ModelBase, SearchMixin):
    """Profile model for django users."""

    user = models.OneToOneField(User, primary_key=True,
                                verbose_name=_lazy(u'User'))
    name = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'Display name'))
    public_email = models.BooleanField(  # show/hide email
        default=False, verbose_name=_lazy(u'Make my email public'))
    avatar = models.ImageField(upload_to=settings.USER_AVATAR_PATH, null=True,
                               blank=True, verbose_name=_lazy(u'Avatar'),
                               max_length=settings.MAX_FILEPATH_LENGTH)
    bio = models.TextField(null=True, blank=True,
                           verbose_name=_lazy(u'Biography'))
    website = models.URLField(max_length=255, null=True, blank=True,
                              verbose_name=_lazy(u'Website'))
    twitter = models.CharField(max_length=15, null=True, blank=True, validators=[TwitterValidator],
                               verbose_name=_lazy(u'Twitter Username'))
    facebook = models.URLField(max_length=255, null=True, blank=True,
                               verbose_name=_lazy(u'Facebook URL'))
    mozillians = models.CharField(max_length=255, null=True, blank=True,
                                  verbose_name=_lazy(u'Mozillians Username'))
    irc_handle = models.CharField(max_length=255, null=True, blank=True,
                                  verbose_name=_lazy(u'IRC nickname'))
    timezone = TimeZoneField(null=True, blank=True,
                             verbose_name=_lazy(u'Timezone'))
    country = models.CharField(max_length=2, choices=COUNTRIES, null=True,
                               blank=True, verbose_name=_lazy(u'Country'))
    # No city validation
    city = models.CharField(max_length=255, null=True, blank=True,
                            verbose_name=_lazy(u'City'))
    locale = LocaleField(default=settings.LANGUAGE_CODE,
                         verbose_name=_lazy(u'Preferred language'))
    first_answer_email_sent = models.BooleanField(
        default=False, help_text=_lazy(u'Has been sent a first answer contribution email.'))
    first_l10n_email_sent = models.BooleanField(
        default=False, help_text=_lazy(u'Has been sent a first revision contribution email.'))
    involved_from = models.DateField(null=True, blank=True,
                                     verbose_name=_lazy(u'Involved with Mozilla from'))
    csat_email_sent = models.DateField(null=True, blank=True,
                                       verbose_name=_lazy(u'When the user was sent a community '
                                                          u'health survey'))

    class Meta(object):
        permissions = (('view_karma_points', 'Can view karma points'),
                       ('deactivate_users', 'Can deactivate users'),
                       ('screen_share', 'Can screen share'),)

    def __unicode__(self):
        try:
            return unicode(self.user)
        except Exception as exc:
            return unicode('%d (%r)' % (self.pk, exc))

    def get_absolute_url(self):
        return reverse('users.profile', args=[self.user_id])

    def clear(self):
        """Clears out the users profile"""
        self.name = ''
        self.public_email = False
        self.avatar = None
        self.bio = ''
        self.website = ''
        self.twitter = ''
        self.facebook = ''
        self.mozillians = ''
        self.irc_handle = ''
        self.city = ''

    @property
    def display_name(self):
        return self.name if self.name else self.user.username

    @property
    def twitter_usernames(self):
        from kitsune.customercare.models import Reply
        return list(
            Reply.objects.filter(user=self.user)
                         .values_list('twitter_username', flat=True)
                         .distinct())

    @classmethod
    def get_mapping_type(cls):
        return UserMappingType

    @classmethod
    def get_serializer(cls, serializer_type='full'):
        # Avoid circular import
        from kitsune.users import api
        if serializer_type == 'full':
            return api.ProfileSerializer
        elif serializer_type == 'fk':
            return api.ProfileFKSerializer
        else:
            raise ValueError('Unknown serializer type "{}".'.format(serializer_type))

    @property
    def last_contribution_date(self):
        """Get the date of the user's last contribution."""
        from kitsune.customercare.models import Reply
        from kitsune.questions.models import Answer
        from kitsune.wiki.models import Revision

        dates = []

        # Latest Army of Awesome reply:
        try:
            aoa_reply = Reply.objects.filter(
                user=self.user).latest('created')
            dates.append(aoa_reply.created)
        except Reply.DoesNotExist:
            pass

        # Latest Support Forum answer:
        try:
            answer = Answer.objects.filter(
                creator=self.user).latest('created')
            dates.append(answer.created)
        except Answer.DoesNotExist:
            pass

        # Latest KB Revision edited:
        try:
            revision = Revision.objects.filter(
                creator=self.user).latest('created')
            dates.append(revision.created)
        except Revision.DoesNotExist:
            pass

        # Latest KB Revision reviewed:
        try:
            revision = Revision.objects.filter(
                reviewer=self.user).latest('reviewed')
            # Old revisions don't have the reviewed date.
            dates.append(revision.reviewed or revision.created)
        except Revision.DoesNotExist:
            pass

        if len(dates) == 0:
            return None

        return max(dates)

    @property
    def settings(self):
        return self.user.settings

    @property
    def answer_helpfulness(self):
        # Avoid circular import
        from kitsune.questions.models import AnswerVote
        return AnswerVote.objects.filter(answer__creator=self.user, helpful=True).count()
Example #17
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(_('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)
    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)

    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)

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

    @models.permalink
    def get_version_url(self, hash):
        return ("article.version", [hash])

    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()
        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__name',
                                                  'parent__name'):
            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
Example #18
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
Example #19
0
class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    timezone = TimeZoneField()
Example #20
0
class UserProfile(ModelBase):
    """
    The UserProfile *must* exist for each
    django.contrib.auth.models.User object. This may be relaxed
    once Dekiwiki isn't the definitive db for user info.

    timezone and language fields are syndicated to Dekiwiki
    """

    # Website fields defined for the profile form
    # TODO: Someday this will probably need to allow arbitrary per-profile
    # entries, and these will just be suggestions.
    website_choices = [
        ('website',
         dict(
             label=_(u'Website'),
             prefix='http://',
             regex='^https?://',
         )),
        ('twitter',
         dict(
             label=_(u'Twitter'),
             prefix='http://twitter.com/',
             regex='^https?://twitter.com/',
         )),
        ('github',
         dict(
             label=_(u'GitHub'),
             prefix='http://github.com/',
             regex='^https?://github.com/',
         )),
        ('stackoverflow',
         dict(
             label=_(u'StackOverflow'),
             prefix='http://stackoverflow.com/users/',
             regex='^https?://stackoverflow.com/users/',
         )),
        ('linkedin',
         dict(
             label=_(u'LinkedIn'),
             prefix='http://www.linkedin.com/in/',
             regex='^https?://www.linkedin.com/in/',
         )),
    ]

    class Meta:
        db_table = 'user_profiles'

    # This could be a ForeignKey, except wikidb might be
    # a different db
    deki_user_id = models.PositiveIntegerField(default=0, editable=False)
    timezone = TimeZoneField(null=True,
                             blank=True,
                             verbose_name=_(u'Timezone'))
    locale = LocaleField(null=True,
                         blank=True,
                         db_index=True,
                         verbose_name=_(u'Language'))
    homepage = models.URLField(max_length=255,
                               blank=True,
                               default='',
                               error_messages={
                                   'invalid':
                                   _(u'This URL has an invalid format. '
                                     u'Valid URLs look like '
                                     u'http://example.com/my_page.')
                               })
    title = models.CharField(_(u'Title'),
                             max_length=255,
                             default='',
                             blank=True)
    fullname = models.CharField(_(u'Name'),
                                max_length=255,
                                default='',
                                blank=True)
    organization = models.CharField(_(u'Organization'),
                                    max_length=255,
                                    default='',
                                    blank=True)
    location = models.CharField(_(u'Location'),
                                max_length=255,
                                default='',
                                blank=True)
    bio = models.TextField(_(u'About Me'), blank=True)

    irc_nickname = models.CharField(_(u'IRC nickname'),
                                    max_length=255,
                                    default='',
                                    blank=True)

    tags = NamespacedTaggableManager(_(u'Tags'), blank=True)

    # should this user receive contentflagging emails?
    content_flagging_email = models.BooleanField(default=False)
    user = models.ForeignKey(DjangoUser, null=True, editable=False, blank=True)

    # HACK: Grab-bag field for future expansion in profiles
    # We can store arbitrary data in here and later migrate to relational
    # tables if the data ever needs to be indexed & queried. Otherwise,
    # this keeps things nicely denormalized. Ideally, access to this field
    # should be gated through accessors on the model to make that transition
    # easier.
    misc = JSONField(blank=True, null=True)

    @models.permalink
    def get_absolute_url(self):
        return ('devmo.views.profile_view', [self.user.username])

    @property
    def websites(self):
        if 'websites' not in self.misc:
            self.misc['websites'] = {}
        return self.misc['websites']

    @websites.setter
    def websites(self, value):
        self.misc['websites'] = value

    _deki_user = None

    @property
    def deki_user(self):
        if not settings.DEKIWIKI_ENDPOINT:
            # There is no deki_user, if the MindTouch API is disabled.
            return None
        if not self._deki_user:
            # Need to find the DekiUser corresponding to the ID
            from dekicompat.backends import DekiUserBackend
            self._deki_user = (DekiUserBackend().get_deki_user(
                self.deki_user_id))
        return self._deki_user

    def gravatar_url(self,
                     secure=True,
                     size=220,
                     rating='pg',
                     default=DEFAULT_AVATAR):
        """Produce a gravatar image URL from email address."""
        base_url = (secure and 'https://secure.gravatar.com'
                    or 'http://www.gravatar.com')
        m = hashlib.md5(self.user.email.lower().encode('utf8'))
        return '%(base_url)s/avatar/%(hash)s?%(params)s' % dict(
            base_url=base_url,
            hash=m.hexdigest(),
            params=urllib.urlencode(dict(s=size, d=default, r=rating)))

    @property
    def gravatar(self):
        return self.gravatar_url()

    def __unicode__(self):
        return '%s: %s' % (self.id, self.deki_user_id)

    def allows_editing_by(self, user):
        if user == self.user:
            return True
        if user.is_staff or user.is_superuser:
            return True
        return False

    @property
    def mindtouch_language(self):
        if not self.locale:
            return ''
        return settings.LANGUAGE_DEKI_MAP[self.locale]

    @property
    def mindtouch_timezone(self):
        if not self.timezone:
            return ''
        base_seconds = self.timezone._utcoffset.days * 86400
        offset_seconds = self.timezone._utcoffset.seconds
        offset_hours = (base_seconds + offset_seconds) / 3600
        return "%03d:00" % offset_hours

    def save(self, *args, **kwargs):
        skip_mindtouch_put = kwargs.get('skip_mindtouch_put', False)
        if 'skip_mindtouch_put' in kwargs:
            del kwargs['skip_mindtouch_put']
        super(UserProfile, self).save(*args, **kwargs)
        if skip_mindtouch_put:
            return
        if not settings.DEKIWIKI_ENDPOINT:
            # Skip if the MindTouch API is unavailable
            return
        from dekicompat.backends import DekiUserBackend
        DekiUserBackend.put_mindtouch_user(self.user)

    def wiki_activity(self):
        return Revision.objects.filter(
            creator=self.user).order_by('-created')[:5]
Example #21
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
Example #22
0
class News(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)
    first_name = models.CharField(_('First Name'), max_length=100, blank=True)
    last_name = models.CharField(_('Last Name'), 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)
    release_dt = models.DateTimeField(_('Release Date/Time'),
                                      null=True,
                                      blank=True)
    syndicate = models.BooleanField(_('Include in RSS feed'), default=True)
    design_notes = models.TextField(_('Design Notes'), blank=True)
    group = models.ForeignKey(Group,
                              null=True,
                              default=None,
                              on_delete=models.SET_NULL)
    tags = TagField(blank=True)

    #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'))

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

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

    perms = generic.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"

    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())
        super(News, self).save(*args, **kwargs)

    @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
Example #23
0
class User(AbstractBaseUser, PlModelMixIn):
    @property
    def remote_password(self):
        return hashlib.md5(self.password).hexdigest()[:12]

    class Meta:
        app_label = "core"

    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
        db_index=True,
    )

    username = StrippedCharField(max_length=255, default="Something" )

    firstname = StrippedCharField(help_text="person's given name", max_length=200)
    lastname = StrippedCharField(help_text="person's surname", max_length=200)

    phone = StrippedCharField(null=True, blank=True, help_text="phone number contact", max_length=100)
    user_url = models.URLField(null=True, blank=True)
    site = models.ForeignKey(Site, related_name='users', help_text="Site this user will be homed too")
    public_key = models.TextField(null=True, blank=True, max_length=1024, help_text="Public key string")

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=True)
    is_readonly = models.BooleanField(default=False)
    is_registering = models.BooleanField(default=False)

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    enacted = models.DateTimeField(null=True, default=None)
    policed = models.DateTimeField(null=True, default=None)
    backend_status = StrippedCharField(max_length=1024,
                                      default="Provisioning in progress")
    deleted = models.BooleanField(default=False)
    write_protect = models.BooleanField(default=False)

    timezone = TimeZoneField()

    dashboards = models.ManyToManyField('DashboardView', through='UserDashboardView', blank=True)

    objects = UserManager()
    deleted_objects = DeletedUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['firstname', 'lastname']

    PI_FORBIDDEN_FIELDS = ["is_admin", "site", "is_staff"]
    USER_FORBIDDEN_FIELDS = ["is_admin", "is_active", "site", "is_staff", "is_readonly"]

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self._initial = self._dict # for PlModelMixIn

    def isReadOnlyUser(self):
        return self.is_readonly

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def delete(self, *args, **kwds):
        # so we have something to give the observer
        purge = kwds.get('purge',False)
        if purge:
            del kwds['purge']
        try:
            purge = purge or observer_disabled
        except NameError:
            pass
            
        if (purge):
            super(User, self).delete(*args, **kwds)
        else:
            if (not self.write_protect):
                    self.deleted = True
                    self.enacted=None
                    self.save(update_fields=['enacted','deleted'])

    @property
    def keyname(self):
        return self.email[:self.email.find('@')]

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    def is_superuser(self):
        return False

    def get_dashboards(self):
        DEFAULT_DASHBOARDS=["Tenant"]

        dashboards = sorted(list(self.userdashboardviews.all()), key=attrgetter('order'))
        dashboards = [x.dashboardView for x in dashboards]

        if not dashboards:
            for dashboardName in DEFAULT_DASHBOARDS:
                dbv = DashboardView.objects.filter(name=dashboardName)
                if dbv:
                    dashboards.append(dbv[0])

        return dashboards

#    def get_roles(self):
#        from core.models.site import SitePrivilege
#        from core.models.slice import SliceMembership
#
#        site_privileges = SitePrivilege.objects.filter(user=self)
#        slice_memberships = SliceMembership.objects.filter(user=self)
#        roles = defaultdict(list)
#        for site_privilege in site_privileges:
#            roles[site_privilege.role.role_type].append(site_privilege.site.login_base)
#        for slice_membership in slice_memberships:
#            roles[slice_membership.role.role_type].append(slice_membership.slice.name)
#        return roles   

    def save(self, *args, **kwds):
        if not self.id:
            self.set_password(self.password)
        print "XXX", self, self.is_active, self.is_registering
        if self.is_active and self.is_registering:
            self.send_temporary_password()
            self.is_registering=False

        self.username = self.email
        super(User, self).save(*args, **kwds)

        self._initial = self._dict

    def send_temporary_password(self):
        password = User.objects.make_random_password()
        self.set_password(password)
        subject, from_email, to = 'OpenCloud Account Credentials', '*****@*****.**', str(self.email)
        text_content = 'This is an important message.'
        userUrl="http://%s/" % get_request().get_host()
        html_content = """<p>Your account has been created on OpenCloud. Please log in <a href="""+userUrl+""">here</a> to activate your account<br><br>Username: """+self.email+"""<br>Temporary Password: """+password+"""<br>Please change your password once you successully login into the site.</p>"""
        msg = EmailMultiAlternatives(subject,text_content, from_email, [to])
        msg.attach_alternative(html_content, "text/html")
        msg.send()

    def can_update(self, user):
        from core.models import SitePrivilege
        _cant_update_fieldName = None
        if user.can_update_root():
            return True

        # site pis can update
        site_privs = SitePrivilege.objects.filter(user=user, site=self.site)
        for site_priv in site_privs:
            if site_priv.role.role == 'admin':
                return True 
            if site_priv.role.role == 'pi':
                for fieldName in self.diff.keys():
                    if fieldName in self.PI_FORBIDDEN_FIELDS:
                        _cant_update_fieldName = fieldName
                        return False
                return True
        if (user.id == self.id):
            for fieldName in self.diff.keys():
                if fieldName in self.USER_FORBIDDEN_FIELDS:
                    _cant_update_fieldName = fieldName
                    return False
            return True

        return False

    def can_update_root(self):
        """
        Return True if user has root (global) write access. 
        """
        if self.is_readonly:
            return False
        if self.is_admin:
            return True

        return False 

    def can_update_deployment(self, deployment):
        from core.models.site import DeploymentPrivilege
        if self.can_update_root():
            return True    
                          
        if DeploymentPrivilege.objects.filter(
            deployment=deployment,
            user=self,
            role__role__in=['admin', 'Admin']):
            return True
        return False    

    def can_update_site(self, site, allow=[]):
        from core.models.site import SitePrivilege
        if self.can_update_root():
            return True
        if SitePrivilege.objects.filter(
            site=site, user=self, role__role__in=['admin', 'Admin']+allow):
            return True
        return False
    
    def can_update_slice(self, slice):
        from core.models.slice import SlicePrivilege
        if self.can_update_root():
            return True
        if self == slice.creator:
            return True
        if self.can_update_site(slice.site, allow=['pi']):
            return True
                     
        if SlicePrivilege.objects.filter(
            slice=slice, user=self, role__role__in=['admin', 'Admin']):
            return True
        return False

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = User.objects.all()
        else:
            # can see all users at any site where this user has pi role
            from core.models.site import SitePrivilege
            site_privs = SitePrivilege.objects.filter(user=user)
            sites = [sp.site for sp in site_privs if sp.role.role in ['Admin', 'admin', 'pi']]
            # get site privs of users at these sites
            site_privs = SitePrivilege.objects.filter(site__in=sites)
            user_ids = [sp.user.id for sp in site_privs] + [user.id]
            qs = User.objects.filter(Q(site__in=sites) | Q(id__in=user_ids))
        return qs

    def save_by_user(self, user, *args, **kwds):
        if not self.can_update(user):
            if getattr(self, "_cant_update_fieldName", None) is not None:
                raise PermissionDenied("You do not have permission to update field %s on object %s" % (self._cant_update_fieldName, self.__class__.__name__))
            else:
                raise PermissionDenied("You do not have permission to update %s objects" % self.__class__.__name__)

        self.save(*args, **kwds)

    def delete_by_user(self, user, *args, **kwds):
        if not self.can_update(user):
            raise PermissionDenied("You do not have permission to delete %s objects" % self.__class__.__name__)
        self.delete(*args, **kwds)
Example #24
0
File: user.py Project: sg3629/xos
class User(AbstractBaseUser, PlModelMixIn):
    @property
    def remote_password(self):
        return hashlib.md5(self.password).hexdigest()[:12]

    class Meta:
        app_label = "core"

    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
        db_index=True,
    )

    username = StrippedCharField(max_length=255, default="Something")

    firstname = StrippedCharField(help_text="person's given name",
                                  max_length=200)
    lastname = StrippedCharField(help_text="person's surname", max_length=200)

    phone = StrippedCharField(null=True,
                              blank=True,
                              help_text="phone number contact",
                              max_length=100)
    user_url = models.URLField(null=True, blank=True)
    site = models.ForeignKey(Site,
                             related_name='users',
                             help_text="Site this user will be homed too")
    public_key = models.TextField(null=True,
                                  blank=True,
                                  max_length=1024,
                                  help_text="Public key string")

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=True)
    is_readonly = models.BooleanField(default=False)
    is_registering = models.BooleanField(default=False)
    is_appuser = models.BooleanField(default=False)

    login_page = StrippedCharField(
        help_text="send this user to a specific page on login",
        max_length=200,
        null=True,
        blank=True)

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    enacted = models.DateTimeField(null=True, default=None)
    policed = models.DateTimeField(null=True, default=None)
    backend_status = StrippedCharField(max_length=1024,
                                       default="Provisioning in progress")
    deleted = models.BooleanField(default=False)
    write_protect = models.BooleanField(default=False)
    lazy_blocked = models.BooleanField(default=False)
    no_sync = models.BooleanField(default=False)  # prevent object sync
    no_policy = models.BooleanField(default=False)  # prevent model_policy run

    timezone = TimeZoneField()

    dashboards = models.ManyToManyField('DashboardView',
                                        through='UserDashboardView',
                                        blank=True)

    objects = UserManager()
    deleted_objects = DeletedUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['firstname', 'lastname']

    PI_FORBIDDEN_FIELDS = ["is_admin", "site", "is_staff"]
    USER_FORBIDDEN_FIELDS = [
        "is_admin", "is_active", "site", "is_staff", "is_readonly"
    ]

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self._initial = self._dict  # for PlModelMixIn

    def isReadOnlyUser(self):
        return self.is_readonly

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    def delete(self, *args, **kwds):
        # so we have something to give the observer
        purge = kwds.get('purge', False)
        if purge:
            del kwds['purge']
        try:
            purge = purge or observer_disabled
        except NameError:
            pass

        if (purge):
            super(User, self).delete(*args, **kwds)
        else:
            if (not self.write_protect):
                self.deleted = True
                self.enacted = None
                self.save(update_fields=['enacted', 'deleted'])

    @property
    def keyname(self):
        return self.email[:self.email.find('@')]

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    def is_superuser(self):
        return False

    def get_dashboards(self):
        DEFAULT_DASHBOARDS = ["Tenant"]

        dashboards = sorted(list(self.userdashboardviews.all()),
                            key=attrgetter('order'))
        dashboards = [x.dashboardView for x in dashboards]

        if (not dashboards) and (not self.is_appuser):
            for dashboardName in DEFAULT_DASHBOARDS:
                dbv = DashboardView.objects.filter(name=dashboardName)
                if dbv:
                    dashboards.append(dbv[0])

        return dashboards


#    def get_roles(self):
#        from core.models.site import SitePrivilege
#        from core.models.slice import SliceMembership
#
#        site_privileges = SitePrivilege.objects.filter(user=self)
#        slice_memberships = SliceMembership.objects.filter(user=self)
#        roles = defaultdict(list)
#        for site_privilege in site_privileges:
#            roles[site_privilege.role.role_type].append(site_privilege.site.login_base)
#        for slice_membership in slice_memberships:
#            roles[slice_membership.role.role_type].append(slice_membership.slice.name)
#        return roles

    def save(self, *args, **kwds):
        if not self.id:
            self.set_password(self.password)
        if self.is_active and self.is_registering:
            self.send_temporary_password()
            self.is_registering = False

        self.username = self.email
        super(User, self).save(*args, **kwds)

        self._initial = self._dict

    def send_temporary_password(self):
        password = User.objects.make_random_password()
        self.set_password(password)
        subject, from_email, to = 'OpenCloud Account Credentials', '*****@*****.**', str(
            self.email)
        text_content = 'This is an important message.'
        userUrl = "http://%s/" % get_request().get_host()
        html_content = """<p>Your account has been created on OpenCloud. Please log in <a href=""" + userUrl + """>here</a> to activate your account<br><br>Username: """ + \
            self.email + """<br>Temporary Password: """ + password + \
            """<br>Please change your password once you successully login into the site.</p>"""
        msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
        msg.attach_alternative(html_content, "text/html")
        msg.send()

    def can_update(self, user):
        from core.models import SitePrivilege
        _cant_update_fieldName = None
        if user.can_update_root():
            return True

        # site pis can update
        site_privs = SitePrivilege.objects.filter(user=user, site=self.site)
        for site_priv in site_privs:
            if site_priv.role.role == 'admin':
                return True
            if site_priv.role.role == 'pi':
                for fieldName in self.diff.keys():
                    if fieldName in self.PI_FORBIDDEN_FIELDS:
                        _cant_update_fieldName = fieldName
                        return False
                return True
        if (user.id == self.id):
            for fieldName in self.diff.keys():
                if fieldName in self.USER_FORBIDDEN_FIELDS:
                    _cant_update_fieldName = fieldName
                    return False
            return True

        return False

    def can_update_root(self):
        """
        Return True if user has root (global) write access.
        """
        if self.is_readonly:
            return False
        if self.is_admin:
            return True

        return False

    def can_update_deployment(self, deployment):
        from core.models.site import DeploymentPrivilege
        if self.can_update_root():
            return True

        if DeploymentPrivilege.objects.filter(
                deployment=deployment,
                user=self,
                role__role__in=['admin', 'Admin']):
            return True
        return False

    def can_update_site(self, site, allow=[]):
        from core.models.site import SitePrivilege
        if self.can_update_root():
            return True
        if SitePrivilege.objects.filter(site=site,
                                        user=self,
                                        role__role__in=['admin', 'Admin'] +
                                        allow):
            return True
        return False

    def can_update_slice(self, slice):
        from core.models.slice import SlicePrivilege
        if self.can_update_root():
            return True
        if self == slice.creator:
            return True
        if self.can_update_site(slice.site, allow=['pi']):
            return True

        if SlicePrivilege.objects.filter(slice=slice,
                                         user=self,
                                         role__role__in=['admin', 'Admin']):
            return True
        return False

    def can_update_service(self, service, allow=[]):
        from core.models.service import ServicePrivilege
        if self.can_update_root():
            return True
        if ServicePrivilege.objects.filter(service=service,
                                           user=self,
                                           role__role__in=['admin', 'Admin'] +
                                           allow):
            return True
        return False

    def can_update_tenant_root(self, tenant_root, allow=[]):
        from core.models.service import TenantRoot, TenantRootPrivilege
        if self.can_update_root():
            return True
        if TenantRootPrivilege.objects.filter(
                tenant_root=tenant_root,
                user=self,
                role__role__in=['admin', 'Admin'] + allow):
            return True
        return False

    def can_update_tenant(self, tenant, allow=[]):
        from core.models.service import Tenant, TenantPrivilege
        if self.can_update_root():
            return True
        if TenantPrivilege.objects.filter(tenant=tenant,
                                          user=self,
                                          role__role__in=['admin', 'Admin'] +
                                          allow):
            return True
        return False

    def can_update_tenant_root_privilege(self,
                                         tenant_root_privilege,
                                         allow=[]):
        return self.can_update_tenant_root(tenant_root_privilege.tenant_root,
                                           allow)

    def can_update_tenant_privilege(self, tenant_privilege, allow=[]):
        return self.can_update_tenant(tenant_privilege.tenant, allow)

    def get_readable_objects(self, filter_by=None):
        """ Returns a list of objects that the user is allowed to read. """
        from core.models import Deployment, Flavor, Image, Network, NetworkTemplate, Node, PlModelMixIn, Site, Slice, SliceTag, Instance, Tag, User, DeploymentPrivilege, SitePrivilege, SlicePrivilege
        models = []
        if filter_by and isinstance(filter_by, list):
            models = [m for m in filter_by if issubclass(m, PlModelMixIn)]
        if not models:
            models = [
                Deployment, Network, Site, Slice, SliceTag, Instance, Tag, User
            ]
        readable_objects = []
        for model in models:
            readable_objects.extend(model.select_by_user(self))
        return readable_objects

    def get_permissions(self, filter_by=None):
        """ Return a list of objects for which the user has read or read/write
        access. The object will be an instance of a django model object.
        Permissions will be either 'r' or 'rw'.

        e.g.
        [{'object': django_object_instance, 'permissions': 'rw'}, ...]

        Returns:
          list of dicts

        """
        from core.models import Deployment, Flavor, Image, Network, NetworkTemplate, Node, PlModelMixIn, Site, Slice, SliceTag, Instance, Tag, User, DeploymentPrivilege, SitePrivilege, SlicePrivilege
        READ = 'r'
        READWRITE = 'rw'
        models = []
        if filter_by and isinstance(filter_by, list):
            models = [m for m in filter_by if issubclass(m, PlModelMixIn)]

        deployment_priv_objs = [Image, NetworkTemplate, Flavor]
        site_priv_objs = [Node, Slice, User]
        slice_priv_objs = [Instance, Network]

        # maps the set of objects a paticular role has write access
        write_map = {
            DeploymentPrivilege: {
                'admin': deployment_priv_objects,
            },
            SitePrivilege: {
                'admin': site_priv_objs,
                'pi': [Slice, User],
                'tech': [Node],
            },
            SlicePrivilege: {
                'admin': slice_priv_objs,
            },
        }

        privilege_map = {
            DeploymentPrivilege: (Deployment, deployment_priv_objs),
            SitePrivilege: (Site, site_priv_objs),
            SlicePrivilege: (Slice, slice_priv_objs)
        }
        permissions = []
        permission_dict = lambda x, y: {'object': x, 'permission': y}
        for privilege_model, (model, affected_models) in privileg_map.items():
            if models and model not in models:
                continue

            # get the objects affected by this privilege model
            affected_objects = []
            for affected_model in affected_models:
                affected_objects.extend(affected_model.select_by_user(self))

            if self.is_admin:
                # assume admin users have read/write access to all objects
                for affected_object in affected_objects:
                    permissions.append(
                        permission_dict(affected_object, READWRITE))
            else:
                # create a dict of the user's per object privileges
                # ex:  {princeton_tmack : ['admin']
                privileges = privilege_model.objects.filter(user=self)
                for privilege in privileges:
                    object_roles = defaultdict(list)
                    obj = None
                    roles = []
                    for field in dir(privilege):
                        if field == model.__name__.lower():
                            obj = getattr(privilege, field)
                    if obj:
                        object_roles[obj].append(privilege.role.role)

                # loop through all objects the user has access to and determine
                # if they also have write access
                for affected_object in affected_objects:
                    if affected_object not in objects_roles:
                        permissions.append(
                            permission_dict(affected_object, READ))
                    else:
                        has_write_permission = False
                        for write_role, models in write_dict.items():
                            if affected_object._meta.model in models and \
                                    write_role in object_roles[affected_object]:
                                has_write_permission = True
                                break
                        if has_write_permission:
                            permissions.append(
                                permission_dict(affected_object, WRITE))
                        else:
                            permissions.append(
                                permission_dict(affected_object, READ))

        return permissions

    def get_tenant_permissions(self):
        from core.models import Site, Slice
        return self.get_object_permissions(filter_by=[Site, Slice])

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = User.objects.all()
        else:
            # can see all users at any site where this user has pi role
            from core.models.site import SitePrivilege
            site_privs = SitePrivilege.objects.filter(user=user)
            sites = [
                sp.site for sp in site_privs
                if sp.role.role in ['Admin', 'admin', 'pi']
            ]
            # get site privs of users at these sites
            site_privs = SitePrivilege.objects.filter(site__in=sites)
            user_ids = [sp.user.id for sp in site_privs] + [user.id]
            qs = User.objects.filter(Q(site__in=sites) | Q(id__in=user_ids))
        return qs

    def save_by_user(self, user, *args, **kwds):
        if not self.can_update(user):
            if getattr(self, "_cant_update_fieldName", None) is not None:
                raise PermissionDenied(
                    "You do not have permission to update field %s on object %s"
                    % (self._cant_update_fieldName, self.__class__.__name__))
            else:
                raise PermissionDenied(
                    "You do not have permission to update %s objects" %
                    self.__class__.__name__)

        self.save(*args, **kwds)

    def delete_by_user(self, user, *args, **kwds):
        if not self.can_update(user):
            raise PermissionDenied(
                "You do not have permission to delete %s objects" %
                self.__class__.__name__)
        self.delete(*args, **kwds)

    def apply_profile(self, profile):
        if profile == "regular":
            self.is_appuser = False
            self.is_admin = False

        elif profile == "cp":
            self.is_appuser = True
            self.is_admin = False
            for db in self.userdashboardviews.all():
                db.delete()
Example #25
0
class UserProfile(ModelBase):
    """
    The UserProfile *must* exist for each
    django.contrib.auth.models.User object. This may be relaxed
    once Dekiwiki isn't the definitive db for user info.

    timezone and language fields are syndicated to Dekiwiki
    """
    # This could be a ForeignKey, except wikidb might be
    # a different db
    deki_user_id = models.PositiveIntegerField(default=0, editable=False)
    timezone = TimeZoneField(null=True,
                             blank=True,
                             verbose_name=_(u'Timezone'))
    locale = LocaleField(null=True,
                         blank=True,
                         db_index=True,
                         verbose_name=_(u'Language'))
    homepage = models.URLField(max_length=255,
                               blank=True,
                               default='',
                               error_messages={
                                   'invalid':
                                   _(u'This URL has an invalid format. '
                                     u'Valid URLs look like '
                                     u'http://example.com/my_page.')
                               })
    title = models.CharField(_(u'Title'),
                             max_length=255,
                             default='',
                             blank=True)
    fullname = models.CharField(_(u'Name'),
                                max_length=255,
                                default='',
                                blank=True)
    organization = models.CharField(_(u'Organization'),
                                    max_length=255,
                                    default='',
                                    blank=True)
    location = models.CharField(_(u'Location'),
                                max_length=255,
                                default='',
                                blank=True)
    bio = models.TextField(_(u'About Me'), blank=True)

    irc_nickname = models.CharField(_(u'IRC nickname'),
                                    max_length=255,
                                    default='',
                                    blank=True)

    tags = NamespacedTaggableManager(_(u'Tags'), blank=True)

    # should this user receive contentflagging emails?
    content_flagging_email = models.BooleanField(default=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             null=True,
                             editable=False,
                             blank=True)

    # HACK: Grab-bag field for future expansion in profiles
    # We can store arbitrary data in here and later migrate to relational
    # tables if the data ever needs to be indexed & queried. Otherwise,
    # this keeps things nicely denormalized. Ideally, access to this field
    # should be gated through accessors on the model to make that transition
    # easier.
    misc = JSONField(blank=True, null=True)

    @property
    def websites(self):
        if 'websites' not in self.misc:
            self.misc['websites'] = {}
        return self.misc['websites']

    @websites.setter
    def websites(self, value):
        self.misc['websites'] = value

    class Meta:
        db_table = 'user_profiles'

    def __unicode__(self):
        return '%s: %s' % (self.id, self.deki_user_id)

    def get_absolute_url(self):
        return self.user.get_absolute_url()
Example #26
0
class Profile(models.Model):
    name = models.CharField(max_length=100)
    timezone = TimeZoneField()
Example #27
0
class UserProfile(models.Model):
    user = models.OneToOneField(User)
    created_at = models.DateTimeField('Created at', auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    timezone = TimeZoneField('your local timezone', default=settings.TIME_ZONE)
Example #28
0
class User(AbstractBaseUser, PlModelMixIn):
    plural_name = "Users"

    @property
    def remote_password(self):
        return hashlib.md5(self.password).hexdigest()[:12]

    class Meta:
        app_label = "core"

    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
        db_index=True,
    )

    username = StrippedCharField(max_length=255, default="Something")

    firstname = StrippedCharField(help_text="person's given name",
                                  max_length=200)
    lastname = StrippedCharField(help_text="person's surname", max_length=200)

    phone = StrippedCharField(null=True,
                              blank=True,
                              help_text="phone number contact",
                              max_length=100)
    user_url = models.URLField(null=True, blank=True)
    site = models.ForeignKey('Site',
                             related_name='users',
                             help_text="Site this user will be homed too")
    public_key = models.TextField(null=True,
                                  blank=True,
                                  max_length=1024,
                                  help_text="Public key string")

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    is_staff = models.BooleanField(default=True)
    is_readonly = models.BooleanField(default=False)
    is_registering = models.BooleanField(default=False)
    is_appuser = models.BooleanField(default=False)

    login_page = StrippedCharField(
        help_text="send this user to a specific page on login",
        max_length=200,
        null=True,
        blank=True)

    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    enacted = models.DateTimeField(null=True, default=None)
    policed = models.DateTimeField(null=True, default=None)
    backend_status = StrippedCharField(max_length=1024,
                                       default="Provisioning in progress")
    backend_need_delete = models.BooleanField(default=False)
    backend_need_reap = models.BooleanField(default=False)
    deleted = models.BooleanField(default=False)
    write_protect = models.BooleanField(default=False)
    lazy_blocked = models.BooleanField(default=False)
    no_sync = models.BooleanField(default=False)  # prevent object sync
    no_policy = models.BooleanField(default=False)  # prevent model_policy run

    timezone = TimeZoneField()

    dashboards = models.ManyToManyField('DashboardView',
                                        through='UserDashboardView',
                                        blank=True)

    policy_status = models.CharField(default="0 - Policy in process",
                                     max_length=1024,
                                     null=True)

    objects = UserManager()
    deleted_objects = DeletedUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['firstname', 'lastname']

    PI_FORBIDDEN_FIELDS = ["is_admin", "site", "is_staff"]
    USER_FORBIDDEN_FIELDS = [
        "is_admin", "is_active", "site", "is_staff", "is_readonly"
    ]

    def __init__(self, *args, **kwargs):
        super(User, self).__init__(*args, **kwargs)
        self._initial = self._dict  # for PlModelMixIn
        self.silent = False

    def isReadOnlyUser(self):
        return self.is_readonly

    def get_full_name(self):
        # The user is identified by their email address
        return self.email

    def get_short_name(self):
        # The user is identified by their email address
        return self.email

    @property
    def keyname(self):
        return self.email[:self.email.find('@')]

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    def is_superuser(self):
        return False

    def get_dashboards(self):
        DEFAULT_DASHBOARDS = ["Tenant"]

        dashboards = sorted(list(self.userdashboardviews.all()),
                            key=attrgetter('order'))
        dashboards = [x.dashboardView for x in dashboards]

        if (not dashboards) and (not self.is_appuser):
            for dashboardName in DEFAULT_DASHBOARDS:
                dbv = dashboardview.DashboardView.objects.filter(
                    name=dashboardName)
                if dbv:
                    dashboards.append(dbv[0])

        return dashboards


#    def get_roles(self):
#        from core.models.site import SitePrivilege
#        from core.models.slice import SliceMembership
#
#        site_privileges = SitePrivilege.objects.filter(user=self)
#        slice_memberships = SliceMembership.objects.filter(user=self)
#        roles = defaultdict(list)
#        for site_privilege in site_privileges:
#            roles[site_privilege.role.role_type].append(site_privilege.site.login_base)
#        for slice_membership in slice_memberships:
#            roles[slice_membership.role.role_type].append(slice_membership.slice.name)
#        return roles

    def delete(self, *args, **kwds):
        # so we have something to give the observer
        purge = kwds.get('purge', False)
        if purge:
            del kwds['purge']
        silent = kwds.get('silent', False)
        if silent:
            del kwds['silent']
        try:
            purge = purge or observer_disabled
        except NameError:
            pass

        if (purge):
            super(User, self).delete(*args, **kwds)
        else:
            if (not self.write_protect):
                self.deleted = True
                self.enacted = None
                self.policed = None
                self.save(update_fields=['enacted', 'deleted', 'policed'],
                          silent=silent)

                collector = XOSCollector(
                    using=router.db_for_write(self.__class__, instance=self))
                collector.collect([self])
                with transaction.atomic():
                    for (k, models) in collector.data.items():
                        for model in models:
                            if model.deleted:
                                # in case it's already been deleted, don't delete again
                                continue
                            model.deleted = True
                            model.enacted = None
                            model.policed = None
                            model.save(update_fields=[
                                'enacted', 'deleted', 'policed'
                            ],
                                       silent=silent)

    def save(self, *args, **kwargs):

        if not self.id:
            self.set_password(self.password)
        if self.is_active and self.is_registering:
            self.send_temporary_password()
            self.is_registering = False

        # let the user specify silence as either a kwarg or an instance varible
        silent = self.silent
        if "silent" in kwargs:
            silent = silent or kwargs.pop("silent")

        caller_kind = "unknown"

        if ('synchronizer' in threading.current_thread().name):
            caller_kind = "synchronizer"

        if "caller_kind" in kwargs:
            caller_kind = kwargs.pop("caller_kind")

        always_update_timestamp = False
        if "always_update_timestamp" in kwargs:
            always_update_timestamp = always_update_timestamp or kwargs.pop(
                "always_update_timestamp")

        # SMBAKER: if an object is trying to delete itself, or if the observer
        # is updating an object's backend_* fields, then let it slip past the
        # composite key check.
        ignore_composite_key_check = False
        if "update_fields" in kwargs:
            ignore_composite_key_check = True
            for field in kwargs["update_fields"]:
                if not (field in [
                        "backend_register", "backend_status", "deleted",
                        "enacted", "updated"
                ]):
                    ignore_composite_key_check = False

        if (caller_kind != "synchronizer") or always_update_timestamp:
            self.updated = timezone.now()

        self.username = self.email

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

        self.push_redis_event()

        self._initial = self._dict

    def send_temporary_password(self):
        password = User.objects.make_random_password()
        self.set_password(password)
        subject, from_email, to = 'OpenCloud Account Credentials', '*****@*****.**', str(
            self.email)
        text_content = 'This is an important message.'
        userUrl = "http://%s/" % get_request().get_host()
        html_content = """<p>Your account has been created on OpenCloud. Please log in <a href=""" + userUrl + """>here</a> to activate your account<br><br>Username: """ + \
            self.email + """<br>Temporary Password: """ + password + \
            """<br>Please change your password once you successully login into the site.</p>"""
        msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
        msg.attach_alternative(html_content, "text/html")
        msg.send()

    def apply_profile(self, profile):
        if profile == "regular":
            self.is_appuser = False
            self.is_admin = False

        elif profile == "cp":
            self.is_appuser = True
            self.is_admin = False
            for db in self.userdashboardviews.all():
                db.delete()

    def get_content_type_key(self):
        ct = ContentType.objects.get_for_model(self.__class__)
        return "%s.%s" % (ct.app_label, ct.model)

    @staticmethod
    def get_content_type_from_key(key):
        (app_name, model_name) = key.split(".")
        return ContentType.objects.get_by_natural_key(app_name, model_name)

    @staticmethod
    def get_content_object(content_type, object_id):
        ct = User.get_content_type_from_key(content_type)
        cls = ct.model_class()
        return cls.objects.get(id=object_id)

    ''' This function is hardcoded here because we do not yet
    generate the User class'''

    def can_access(self, ctx):
        return security.user_policy_security_check(self, ctx), "user_policy"
Example #29
0
class Profile(BaseProfile):
    """
    The base profile model which contains fields that pertain to everyone.
    Should be left out of the admin since only subclasses are created. (??? -sfh)

    Who is this person following?
    pr = Profile.objects.get(id=7455)
    pr.followees.all()

    Who is following this person?
    pr.followers.all()

    Add a new followee:
    otheruser = Profile.objects.get(id=38)
    pr.followees.add(otheruser)

    Remove a followee:
    pr.followees.remove(otheruser)
    """

    user = models.OneToOneField(User, primary_key=True)
    suffix = models.IntegerField(max_length=2,
                                 blank=True,
                                 null=True,
                                 choices=constants.PROFILE_SUFFIX_CHOICES)
    salutation = models.IntegerField(
        max_length=2,
        blank=True,
        null=True,
        choices=constants.PROFILE_SALUTATION_CHOICES)
    middle_name = models.CharField(max_length=50, blank=True, null=True)
    title = models.CharField(blank=True, null=True, max_length=128)
    about = models.TextField(
        blank=True,
        null=True,
        help_text=
        "A few sentences about yourself - capsule biography. No HTML allowed.")
    email2 = models.EmailField('Secondary Email', blank=True, null=True)
    home_phone1 = models.CharField('Home Phone',
                                   max_length=60,
                                   blank=True,
                                   null=True)
    biz_phone1 = models.CharField('Business Phone',
                                  max_length=60,
                                  blank=True,
                                  null=True)
    mobile_phone1 = models.CharField('Mobile Phone',
                                     max_length=60,
                                     blank=True,
                                     null=True)
    fax = models.CharField(max_length=60, blank=True, null=True)
    timezone = TimeZoneField()
    allow_contact = models.BooleanField(
        default=True,
        help_text='Allow the public to contact you through CalCentral.')
    show_name = models.BooleanField(
        default=True, help_text='Not currently implemented, for future use.')
    avatar = ImageField(
        upload_to=get_avatar_path,
        blank=True,
        null=True,
        help_text=
        'Upload an avatar/image/icon to represent you on the site.<br />Please make sure your image is mostly square, not rectangular.'
    )
    url_personal = models.URLField('Personal website',
                                   blank=True,
                                   null=True,
                                   verify_exists=True)
    url_org = models.URLField('Organization website',
                              blank=True,
                              null=True,
                              verify_exists=True)
    accepted_terms = models.BooleanField(
        default=False,
        help_text=
        "All users must accept our terms and conditions before doing anything on the site."
    )
    followees = models.ManyToManyField(
        'self',
        blank=True,
        null=True,
        related_name='followers',
        symmetrical=False,
        help_text='People this person is following.')

    # Preferences
    email_on_follow = models.BooleanField(
        default=True, help_text='Receive email when someone follows you.')

    # Model Managers
    active_objects = ActiveProfileManager()
    alumni_objects = ActiveProfileAlumniManager()
    staff_objects = StaffProfileManager()
    emp_objects = EmployeeProfileManager()

    def __unicode__(self):
        return self.get_display_name()

    def get_display_name(self):
        if self.user.first_name and self.user.last_name:  # and self.show_real_name:

            display_name = "%s %s" % (
                self.user.first_name,
                self.user.last_name,
            )
            return display_name
        else:
            return self.user.username

    def phones_all(self):
        """
        Return a dict of all phone data.
        """
        return dict(home=self.home_phone1,
                    mobile=self.mobile_phone1,
                    work=self.biz_phone1)

    def is_staff(self):
        """
        Return True if the person is in the Staff group.
        Note: this is different from user.is_staff() which is a similar
        boolean flag that allows users to access the django admin.
        """
        if not self.user.is_active:
            return False
        #if self.user.is_staff(): return True
        if Group.objects.get(name="Staff") in self.user.groups.all():
            return True
        return False

    def is_instructor(self):
        """
        Return True if this person is in one of the Instructor groups.
        """
        if not self.user.is_active:
            return False
        for g in INSTRUCTOR_GROUPS:
            if Group.objects.get(name=g) in self.user.groups.all():
                return True
        return False

    def is_student(self):
        """
        Return True if this person is in the Student group.
        """
        if not self.user.is_active:
            return False
        if Group.objects.get(name="Students") in self.user.groups.all():
            return True
        return False

    def is_alumni(self):
        """
        Return True if this person is active and in the Alumni group.
        """
        if not self.user.is_active:
            return False
        if Group.objects.get(name="Alumni") in self.user.groups.all():
            return True
        return False

    def is_affiliated(self):
        """
        Need this in some places such as whether to show Private events (we
        don't show) them to alumni or to "basic" users.
        """
        if not self.user.is_active:
            return False
        if self.is_staff() or self.is_instructor() or self.is_student():
            return True
        return False

    def in_group(self, group):
        """
        Return True if the user/profile is in the group. Requires a string or a
        Group object as argument.
        """
        if type(group) == unicode or type(group) == str:
            return bool(self.user.groups.filter(name=group))

        if group in self.user.groups.all():
            return True

        return False

    def is_alumni_only(self):
        """
        Return True if a profile is only in the alumni group but not also staff
        or instructor.  Useful to rendering the correct nav, for example.
        """
        if self.is_alumni(
        ) and not self.is_staff() and not self.is_instructor():
            return True
        else:
            return False

    def get_form_name(self):
        return "%sForm" % self._meta.module_name.title()

    def get_primary_email(self):
        """
        Return user's primary email address.
        """
        return self.user.email