Exemplo n.º 1
0
class Image(models.Model):
    title = models.CharField(max_length=255, blank=True)
    image = models.ImageField(upload_to='images')
    caption = models.TextField(blank=True)
    medium_image = ImageSpec([
        resize.Fit(580, 1080),
    ],
                             image_field='image',
                             format='JPEG',
                             options={'quality': 90})
    feature_image = ImageSpec([
        resize.SmartCrop(260, 260),
    ],
                              image_field='image',
                              format='JPEG',
                              options={'quality': 90})

    def __unicode__(self):
        return self.title

    def save(self):
        if not self.title:
            self.title = self.image.name

        super(Image, self).save()
Exemplo n.º 2
0
class WallItem(models.Model):
    """
    A simple note to post on a shared wall.
    """
    wall       = models.ForeignKey('Wall')
    author     = models.ForeignKey(User, related_name="wall_item_author")
    body       = models.TextField(_('item_body'), help_text='Use the editor to add links; no embedded html allowed.')
    created_at = models.DateTimeField(_('created at'), default=datetime.now)
    deleted = models.BooleanField(default=False)
    item_pic = models.ImageField(upload_to='upload',null=True,)
    item_pic_800x600 = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
            resize.Fit(800,600, False)], image_field='item_pic',
            format='JPEG', options={'quality': 90})
    item_pic_resized = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
            resize.Fit(300, 300)], image_field='item_pic',
            format='JPEG', options={'quality': 90})

    class Meta:
        verbose_name        = _('wallitem')
        verbose_name_plural = _('wallitems')
        ordering            = ('-created_at',) 
        get_latest_by       = 'created_at'
        
    def deleteable_by(self, user):
        return user == self.author or user.is_superuser
    
    def active_comments_set(self):
        return WallComment.objects.filter(wallitem=self, deleted=False)

    def __unicode__(self):
        return 'wall item created by %s on %s ( %s )' % ( self.author.username, self.created_at, truncatewords(self.body, 9 ))
Exemplo n.º 3
0
class Profile(ProfileBase):
    name = models.CharField(
        _("Display name"),
        max_length=50,
        null=True,
        blank=True,
        help_text='This will be shown to others when you use the site')
    about = models.TextField(
        _("About"),
        null=True,
        blank=True,
        help_text='Tell others about yourself, your gear, or your ride')

    profile_pic = models.ImageField(
        upload_to='upload',
        null=True,
        help_text="A picture of yourself, your bike, or something else")
    profile_pic_med = ImageSpec(
        [Adjust(contrast=1.2, sharpness=1.1),
         resize.Crop(80, 80)],
        image_field='profile_pic',
        format='JPEG',
        options={'quality': 90})
    profile_pic_small = ImageSpec(
        [Adjust(contrast=1.2, sharpness=1.1),
         resize.Crop(40, 40)],
        image_field='profile_pic',
        format='JPEG',
        options={'quality': 90})
    profile_pic_small_border = ImageSpec(
        [Adjust(contrast=1.2, sharpness=1.1),
         resize.Crop(40, 40),
         Border()],
        image_field='profile_pic',
        format='JPEG',
        options={'quality': 90})

    #TODO use postgis?
    location = models.ForeignKey(Location, null=True, blank=True)

    days_per_week = models.DecimalField(
        "How many days per week do you commute by bike?",
        max_digits=1,
        decimal_places=0,
        choices=DAYS_PER_WEEK_CHOICES,
        null=True,
        blank=True)
    oneway_dist = models.DecimalField("How many miles is your one-way commute",
                                      max_digits=4,
                                      decimal_places=2,
                                      null=True,
                                      blank=True)
    oneway_time = models.DecimalField(
        "How many minutes does your one-way commute typically take?",
        max_digits=3,
        decimal_places=0,
        null=True,
        blank=True)
Exemplo n.º 4
0
class Photo(models.Model):
    title = models.CharField(max_length=50)
    caption = models.CharField(max_length=100)
    original_image = models.ImageField(upload_to='galleries')
    full = ImageSpec([ResizeToFit(400, 200)])
    thumbnail = ImageSpec([ResizeToFit(50, 50)], source='original_image')

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ['title']
Exemplo n.º 5
0
class BeerImage(BeerDBModel):
    original_image = models.ImageField(upload_to=beer_file_name)
    resized = ImageSpec([resize.Crop(320, 320)],
                        image_field='original_image',
                        format='PNG')
    thumbnail = ImageSpec(
        [Adjust(contrast=1.2, sharpness=1.1),
         resize.Crop(128, 128)],
        image_field='original_image',
        format='PNG')
    num_views = models.PositiveIntegerField(editable=False, default=0)

    def __str__(self):
        return '%s' % self.original_image.name
Exemplo n.º 6
0
class Photo(models.Model):
    original_image = models.ImageField(upload_to='photos')

    thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
                           Crop(50, 50)],
                          image_field='original_image',
                          format='JPEG',
                          options={'quality': 90})

    smartcropped_thumbnail = ImageSpec(
        [Adjust(contrast=1.2, sharpness=1.1),
         SmartCrop(50, 50)],
        image_field='original_image',
        format='JPEG',
        options={'quality': 90})
Exemplo n.º 7
0
class Photo(models.Model):
    original_image = models.ImageField(upload_to='photos')
    thumbnail = ImageSpec([Adjust(contrast=1.2, sharpness=1.1),
                           Crop(50, 50)],
                          image_field='original_image',
                          format='JPEG',
                          quality=90)
Exemplo n.º 8
0
class Photo(models.Model):
    """Stores a photo for a carousel
    """
    carousel = models.ForeignKey(Carousel,
                                 help_text="""
        The carousel to which this photo belongs.""")
    caption = models.TextField()
    url = models.URLField()
    original_image = models.ImageField(upload_to='photos')
    formatted_image = ImageSpec(image_field='original_image', format='JPEG')

    def get_absolute_url(self):
        if self.formatted_image:
            return self.formatted_image.url
        else:
            return ''

    def as_dict(self, moar={}):
        res = {
            'id': self.id,
            'caption': self.caption,
            'url': self.url,
            'image_url': self.get_absolute_url()
        }
        res.update(moar)
        return res
Exemplo n.º 9
0
class Entry(models.Model):
    compo = models.ForeignKey(Compo)
    name = models.CharField('Nimi', max_length=32)
    description = models.TextField('Kuvaus')
    creator = models.CharField('Tekijä', max_length=64)
    file = models.FileField('Tiedosto', upload_to='arkisto/entryfiles/')
    imagefile_original = models.ImageField(u'Kuva', upload_to='arkisto/entryimages/', blank=True, null=True)
    imagefile_small = ImageSpec([resize.Fit(160, 100)], image_field='imagefile_original', format='JPEG', options={'quality': 90})
    imagefile_medium = ImageSpec([resize.Fit(640, 420)], image_field='imagefile_original', format='JPEG', options={'quality': 90})
    youtube_url = models.URLField('Youtube URL', blank=True)
    tags = models.ManyToManyField(Tag)
    position = models.IntegerField('Sijoitus')
    def __unicode__(self):
        return self.compo.name + " " + self.name
    class Meta:
        verbose_name=u"tuotos"
        verbose_name_plural=u"tuotokset"
Exemplo n.º 10
0
class Picture(models.Model):
  class IKOptions:
    spec_module = 'pykeg.core.imagespecs'
    image_field = 'image'

  seqn = models.PositiveIntegerField(editable=False)
  site = models.ForeignKey(KegbotSite, related_name='pictures',
      blank=True, null=True,
      help_text='Site owning this picture')
  image = models.ImageField(upload_to=_pics_file_name,
      help_text='The image')

  resized = ImageSpec(
      [resize.Crop(320, 320)],
      image_field='image', format='PNG')
  thumbnail = ImageSpec(
      [Adjust(contrast=1.2, sharpness=1.1), resize.Crop(128, 128)],
      image_field='image', format='PNG')

  created_date = models.DateTimeField(default=datetime.datetime.now)
  caption = models.TextField(blank=True, null=True,
      help_text='Caption for the picture')
  user = models.ForeignKey(User, blank=True, null=True,
      help_text='User this picture is associated with, if any')
  keg = models.ForeignKey(Keg, blank=True, null=True, related_name='pictures',
      help_text='Keg this picture is associated with, if any')
  session = models.ForeignKey(DrinkingSession, blank=True, null=True,
      on_delete=models.SET_NULL,
      related_name='pictures',
      help_text='Session this picture is associated with, if any')
  drink = models.ForeignKey(Drink, blank=True, null=True,
      related_name='pictures',
      help_text='Drink this picture is associated with, if any')

  def GetCaption(self):
    if self.caption:
      return self.caption
    elif self.drink:
      if self.user:
        return '%s pouring drink %s' % (self.user.username, self.drink.seqn)
      else:
        return 'An unknown drinker pouring drink %s' % (self.drink.seqn,)
    else:
      return ''
Exemplo n.º 11
0
class AuthorProfile(models.Model):
    user = models.OneToOneField(User)
    avatar = models.ImageField(upload_to='images', blank=True, null=True)
    bio = models.TextField(blank=True)

    profile_image = ImageSpec([
        resize.SmartCrop(100, 100),
    ],
                              image_field='avatar',
                              format='JPEG',
                              options={'quality': 90})

    def __unicode__(self):
        return self.user.username
Exemplo n.º 12
0
class Show(models.Model):
    """
    A podcast show, which has many episodes.
    """
    EXPLICIT_CHOICES = (
        (1, _("yes")),
        (2, _("no")),
        (3, _("clean")),
    )
    uuid = UUIDField(_("id"), unique=True)

    created = models.DateTimeField(_("created"),
                                   default=datetime.now,
                                   editable=False)
    updated = models.DateTimeField(null=True, blank=True, editable=False)
    published = models.DateTimeField(null=True, blank=True, editable=False)

    site = models.ForeignKey(Site, default=settings.SITE_ID)

    ttl = models.PositiveIntegerField(
        _("TTL"),
        default=1440,
        help_text=_("""``Time to Live,`` the number of minutes a channel can be
        cached before refreshing."""))
    webmaster = models.ForeignKey(
        User,
        related_name="webmaster",
        help_text=_(
            """Remember to save the user"s name and e-mail address in the
        <a href="../../../auth/user/">User application</a>."""))

    # license is disabled for the moment due to the following issue:
    # https://bitbucket.org/jezdez/django-licenses/issue/1/using-024-results-in-a-related_name-error

    #license = LicenseField()

    organization = models.CharField(
        _("organization"),
        max_length=255,
        help_text=
        _("Name of the organization, company or Web site producing the podcast."
          ))
    link = models.URLField(_("link"),
                           help_text=_("""URL of either the main website or the
        podcast section of the main website."""))

    enable_comments = models.BooleanField(default=True)

    authors = models.ManyToManyField(
        User,
        related_name="show_authors",
        help_text=_(
            """Remember to save the user's name and e-mail address in the
        <a href="../../../auth/user/">User application</a>.<br />"""))

    title = models.CharField(_("title"), max_length=255)
    slug = AutoSlugField(_("slug"), populate_from="title")

    subtitle = models.CharField(
        _("subtitle"),
        max_length=255,
        help_text=_("Looks best if only a few words, like a tagline."))

    description = models.TextField(_("description"),
                                   max_length=4000,
                                   help_text=_("""
        This is your chance to tell potential subscribers all about your podcast.
        Describe your subject matter, media format, episode schedule, and other
        relevant info so that they know what they'll be getting when they
        subscribe. In addition, make a list of the most relevant search terms
        that you want your podcast to match, then build them into your
        description. Note that iTunes removes podcasts that include lists of
        irrelevant words in the itunes:summary, description, or
        itunes:keywords tags. This field can be up to 4000 characters."""))

    original_image = models.ImageField(
        _("original image"),
        upload_to="img/podcasts/",
        help_text=_("""An attractive, original square JPEG (.jpg) or PNG (.png)
        image of exactly 1000x1000 pixels at 72 pixels per inch. Image will be
        scaled down to 50x50 pixels at smallest in iTunes.<br /><br />
        For episode artwork to display in iTunes, image must be
        <a href="http://answers.yahoo.com/question/index?qid=20080501164348AAjvBvQ">
        saved to file's <strong>metadata</strong></a> before enclosure uploading!"""
                    ))

    if ImageSpec:
        admin_thumb_sm = ImageSpec([resize.Crop(50, 50)],
                                   image_field="original_image",
                                   quality=100,
                                   pre_cache=True)
        admin_thumb_lg = ImageSpec([resize.Crop(450, 450)],
                                   image_field="original_image",
                                   quality=100,
                                   pre_cache=True)
        img_show_sm = ImageSpec([resize.Crop(120, 120)],
                                image_field="original_image",
                                quality=100,
                                pre_cache=True)
        img_show_lg = ImageSpec([resize.Crop(550, 550)],
                                image_field="original_image",
                                quality=100,
                                pre_cache=True)
        img_itunes_sm = ImageSpec([resize.Crop(144, 144)],
                                  image_field="original_image",
                                  quality=100,
                                  pre_cache=True)
        img_itunes_lg = ImageSpec([resize.Crop(1000, 1000)],
                                  image_field="original_image",
                                  quality=100,
                                  pre_cache=True)

    feedburner = models.URLField(
        _("feedburner url"),
        blank=True,
        help_text=_("""Fill this out after saving this show and at least one
        episode. URL should look like "http://feeds.feedburner.com/TitleOfShow".
        See <a href="http://code.google.com/p/django-podcast/">documentation</a>
        for more. <a href="http://www.feedburner.com/fb/a/ping">Manually ping</a>"""
                    ))

    # iTunes specific fields
    explicit = models.PositiveSmallIntegerField(
        _("explicit"),
        default=1,
        choices=EXPLICIT_CHOICES,
        help_text=_("``Clean`` will put the clean iTunes graphic by it."))
    redirect = models.URLField(
        _("redirect"),
        blank=True,
        help_text=_("""The show's new URL feed if changing
        the URL of the current show feed. Must continue old feed for at least
        two weeks and write a 301 redirect for old feed."""))
    keywords = models.CharField(
        _("keywords"),
        max_length=255,
        help_text=_("""A comma-demlimitedlist of up to 12 words for iTunes
        searches. Perhaps include misspellings of the title."""))
    itunes = models.URLField(
        _("itunes store url"),
        blank=True,
        help_text=_("""Fill this out after saving this show and at least one
        episode. URL should look like:
        "http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=000000000".
        See <a href="http://code.google.com/p/django-podcast/">documentation</a> for more."""
                    ))

    twitter_tweet_prefix = models.CharField(_("Twitter tweet prefix"),
                                            max_length=80,
                                            help_text=_("""
        Enter a short ``tweet_text`` prefix for new episodes on this show."""),
                                            blank=True)

    objects = manager_from(ShowManager)
    tags = TaggableManager()

    class Meta:
        verbose_name = _("Show")
        verbose_name_plural = _("Shows")
        ordering = ("organization", "slug")

    def __unicode__(self):
        return u"%s" % (self.title)

    def save(self, **kwargs):
        self.updated = datetime.now()
        super(Show, self).save(**kwargs)

    def get_share_url(self):
        return "http://%s%s" % (Site.objects.get_current(),
                                self.get_absolute_url())

    def get_absolute_url(self):
        return reverse("podcasting_show_detail", kwargs={"slug": self.slug})
Exemplo n.º 13
0
class Episode(models.Model):
    """
    An individual podcast episode and it's unique attributes.
    """
    SIXTY_CHOICES = tuple((x, x) for x in range(60))
    uuid = UUIDField("ID", unique=True)

    created = models.DateTimeField(_("created"),
                                   default=datetime.now,
                                   editable=False)
    updated = models.DateTimeField(null=True, blank=True, editable=False)
    published = models.DateTimeField(null=True, blank=True, editable=False)

    show = models.ForeignKey(Show)

    enable_comments = models.BooleanField(default=True)

    authors = models.ManyToManyField(
        User,
        related_name="episode_authors",
        help_text=_(
            """Remember to save the user's name and e-mail address in the
        <a href="../../../auth/user/">User application</a>."""))

    title = models.CharField(_("title"), max_length=255)
    slug = AutoSlugField(_("slug"), populate_from="title")

    subtitle = models.CharField(
        _("subtitle"),
        max_length=255,
        help_text=_("Looks best if only a few words like a tagline."))

    description = models.TextField(_("description"),
                                   max_length=4000,
                                   help_text=_("""
        This is your chance to tell potential subscribers all about your podcast.
        Describe your subject matter, media format, episode schedule, and other
        relevant info so that they know what they'll be getting when they
        subscribe. In addition, make a list of the most relevant search terms
        that you want your podcast to match, then build them into your
        description. Note that iTunes removes podcasts that include lists of
        irrelevant words in the itunes:summary, description, or
        itunes:keywords tags. This field can be up to 4000 characters."""))
    tracklist = models.TextField(
        _("tracklist"),
        null=True,
        blank=True,
        help_text=
        _("""One track per line, machine will automatically add the numbers."""
          ))

    tweet_text = models.CharField(_("tweet text"),
                                  max_length=140,
                                  editable=False)

    # iTunes specific fields
    original_image = models.ImageField(
        _("original image"),
        upload_to=get_episode_upload_folder,
        help_text=_("""An attractive, original square JPEG (.jpg) or PNG (.png)
        image of 300x300 pixles to 1000x1000 pixels at 72 pixels per inch. Image will be
        scaled down to 50x50 pixels at smallest in iTunes.<br /><br />
        For episode artwork to display in iTunes, image must be
        <a href="http://answers.yahoo.com/question/index?qid=20080501164348AAjvBvQ">
        saved to file's <strong>metadata</strong></a> before enclosure uploading!"""
                    ))

    if ImageSpec:
        admin_thumb_sm = ImageSpec([resize.Crop(50, 50)],
                                   image_field="original_image",
                                   quality=100,
                                   pre_cache=True)
        admin_thumb_lg = ImageSpec([resize.Crop(450, 450)],
                                   image_field="original_image",
                                   quality=100,
                                   pre_cache=True)
        img_episode_sm = ImageSpec([resize.Crop(120, 120)],
                                   image_field="original_image",
                                   quality=100,
                                   pre_cache=True)
        img_episode_lg = ImageSpec([resize.Crop(550, 550)],
                                   image_field="original_image",
                                   quality=100,
                                   pre_cache=True)
        img_itunes_sm = ImageSpec([resize.Crop(144, 144)],
                                  image_field="original_image",
                                  quality=100,
                                  pre_cache=True)
        img_itunes_lg = ImageSpec([resize.Crop(1000, 1000)],
                                  image_field="original_image",
                                  quality=100,
                                  pre_cache=True)

    hours = models.SmallIntegerField(_("hours"), max_length=2, default=0)
    minutes = models.SmallIntegerField(_("minutes"),
                                       max_length=2,
                                       default=0,
                                       choices=SIXTY_CHOICES)
    seconds = models.SmallIntegerField(_("seconds"),
                                       max_length=2,
                                       default=0,
                                       choices=SIXTY_CHOICES)
    keywords = models.CharField(
        _("keywords"),
        max_length=255,
        help_text=_("""A comma-delimited list of words for searches, up to 12;
        perhaps include misspellings."""))
    explicit = models.PositiveSmallIntegerField(
        _("explicit"),
        choices=Show.EXPLICIT_CHOICES,
        help_text=_("``Clean`` will put the clean iTunes graphic by it."),
        default=1)
    block = models.BooleanField(
        _("block"),
        default=False,
        help_text=_(
            """Check to block this episode from iTunes because <br />its
        content might cause the entire show to be <br />removed from iTunes."""
        ))

    objects = manager_from(EpisodeManager)
    tags = TaggableManager()

    class Meta:
        verbose_name = _("Episode")
        verbose_name_plural = _("Episodes")
        ordering = ("-published", "slug")

    def __unicode__(self):
        return u"%s" % (self.title)

    def save(self, **kwargs):
        self.updated = datetime.now()
        super(Episode, self).save(**kwargs)

    def get_absolute_url(self):
        return reverse("podcasting_episode_detail",
                       kwargs={
                           "show_slug": self.show.slug,
                           "slug": self.slug
                       })

    def as_tweet(self):
        if not self.tweet_text:
            current_site = Site.objects.get_current()
            api_url = "http://api.tr.im/api/trim_url.json"
            u = urllib2.urlopen("%s?url=http://%s%s" % (
                api_url,
                current_site.domain,
                self.get_absolute_url(),
            ))
            result = json.loads(u.read())
            self.tweet_text = u"%s %s — %s" % (
                self.show.episode_twitter_tweet_prefix,
                self.title,
                result["url"],
            )
        return self.tweet_text

    def tweet(self):
        if can_tweet():
            account = twitter.Api(
                username=settings.TWITTER_USERNAME,
                password=settings.TWITTER_PASSWORD,
            )
            account.PostUpdate(self.as_tweet())
        else:
            raise ImproperlyConfigured(
                "Unable to send tweet due to either "
                "missing python-twitter or required settings.")

    def seconds_total(self):
        try:
            return self.minutes * 60 + self.seconds
        except:
            return 0

    def get_share_url(self):
        return "http://%s%s" % (Site.objects.get_current(),
                                self.get_absolute_url())

    def get_share_title(self):
        return self.title

    def get_share_description(self):
        return "%s..." % self.description[:512]
Exemplo n.º 14
0
#
# Pykeg is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Pykeg.  If not, see <http://www.gnu.org/licenses/>.

from imagekit.models import ImageSpec
from imagekit.processors import Adjust
from imagekit.processors import resize

resized = ImageSpec(
    processors=[resize.ResizeToFit(1024, 1024)],
    image_field='image',
    format='JPEG',
    options={'quality': 90},
)

small_resized = ImageSpec(
    processors=[resize.ResizeToFit(256, 256)],
    image_field='image',
    format='JPEG',
    options={'quality': 100},
)

thumbnail = ImageSpec(
    processors=[
        Adjust(contrast=1.2, sharpness=1.1),
        resize.SmartResize(128, 128)
    ],
Exemplo n.º 15
0
class Profile(CommonModel):
    """ This represents a user's profile.

    To sort players by rating, sort by their exposure. For instance, best to
    worst would be:
        Profile.object.order_by('-exposure')

    To figure out what this player's rank is in the league, something like
    this should work:
        Profile.objects.filter(exposure__gte=self.exposure).order_by(
            '-exposure').count()

    Exposures which are <= 0 should appear as "unranked" to the user.
    """
    user = models.OneToOneField(User, unique=True)
    slug = models.SlugField("Slug", max_length=255)
    bio = models.TextField(blank=True, null=True)
    include_in_team = models.BooleanField(default=True)

    # TrueSkill Rating
    mu = models.FloatField(editable=False, blank=True, null=True)
    sigma = models.FloatField(editable=False, blank=True, null=True)
    exposure = models.FloatField(editable=False, default=0)

    # Avatarz
    THUMB_SIZE = (46, 46)
    AVATAR_FORMAT = "JPEG"
    avatar = models.ImageField(upload_to=get_path, blank=True, null=True)
    pixelate_avatar = ImageSpec(
            [Pixelate(), resize.Fit(*THUMB_SIZE), resize.Crop(*THUMB_SIZE)],
            image_field='avatar',
            format=AVATAR_FORMAT,
            )
    thumbnail_avatar = ImageSpec(
            [resize.Fit(*THUMB_SIZE), resize.Crop(*THUMB_SIZE)],
            image_field='avatar',
            format=AVATAR_FORMAT,
            )

    # Social
    twitter = models.CharField("Twitter handle", blank=True, null=True,
            max_length=20)
    facebook = models.CharField("Facebook username", blank=True, null=True,
            max_length=50)
    linked_in = models.CharField(blank=True, null=True, max_length=50)
    website = models.URLField(blank=True, null=True, verify_exists=False)

    team = models.ForeignKey(Team, related_name="profile_team")

    class Meta:
        ordering = ('-exposure',)

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

    @models.permalink
    def get_absolute_url(self):
        return ('theleague_team_member', [str(self.team.slug), str(self.slug)])

    def ranking(self):
        """ Where this player ranks compared to the other players. """
        if self.exposure <= 0:
            return "Unranked"
        else:
            return Profile.objects.filter(
                    exposure__gte=self.exposure).order_by('-exposure').count()

    def rating(self):
        if self.exposure <= 0:
            return "Unrated"
        else:
            return "%0.2f" % (self.exposure * 10,)

    @property
    def full_name(self):
        if self.user.first_name == "":
            return self.user.username
        return ("%s %s" % (self.user.first_name, self.user.last_name)).strip()

    @property
    def facebook_url(self):
        if self.facebook:
            return "http://facebook.com/%s" % self.facebook.strip()
        else:
            return ""

    @property
    def twitter_url(self):
        if self.twitter:
            return "http://twitter.com/%s" % self.twitter.strip()
        else:
            return ""

    @property
    def linked_in_url(self):
        if self.linked_in:
            return "http://www.linkedin.com/%s" % self.linked_in.strip()
        else:
            return ""