Ejemplo n.º 1
0
class Event(models.Model):
    NOW = datetime.datetime.now()
    YEAR = NOW.year
    if NOW.month > 7:
        YEAR += 1

    YEAR_CHOICES = [(5000, 'Alle (inkludert alumni)'),
                    (YEAR + 4, '1. - 5. klasse'), (YEAR + 3, '2. - 5. klasse'),
                    (YEAR + 2, '3. - 5. klasse'),
                    (YEAR + 1, '4. og 5. klasse'), (YEAR, '5. klasse')]

    def get_class_year(self, graduation_year):
        return graduation_year - self.YEAR

    title = models.CharField(max_length=200, unique=True)
    short_description = models.TextField(blank=True, null=True)
    description = models.TextField()
    location = models.CharField(max_length=50, blank=True, null=True)
    event_start_time = models.DateTimeField()
    event_end_time = models.DateTimeField(blank=True, null=True)
    registration_required = models.BooleanField(default=False)
    registration_start_time = models.DateTimeField(blank=True, null=True)
    alumni = models.BooleanField(default=False)
    class_1 = models.BooleanField(default=False)
    class_2 = models.BooleanField(default=False)
    class_3 = models.BooleanField(default=False)
    class_4 = models.BooleanField(default=False)
    class_5 = models.BooleanField(default=False)
    only_komite = models.BooleanField(default=False)
    available_spots = models.IntegerField(blank=True, null=True)
    registered_users = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                              blank=True,
                                              related_name='registerd_users')
    waiting_list = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                          blank=True,
                                          related_name='waiting_list_users')
    external_link = models.CharField(blank=True, null=True, max_length=150)
    link_text = models.CharField(blank=True, null=True, max_length=150)
    slug = models.SlugField(max_length=60, blank=True)
    image = ProcessedImageField(upload_to='events/',
                                processors=[ResizeToFit(2000, 2000, False)],
                                format='JPEG',
                                options={'quality': 85})
    thumbnail = ImageSpecField(source='image',
                               processors=[ResizeToFill(300, 300, False)],
                               format='JPEG',
                               options={'quality': 100})

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.id:
            # Only set the slug when the object is created.
            # Or whatever you want the slug to use
            self.slug = slugify(self.title)
        if not self.registration_start_time:
            self.registration_start_time = self.event_start_time
        super(Event, self).save(*args, **kwargs)

    def is_now(self, month):
        if month == datetime.datetime.now().month:
            return True
        else:
            return True

    class Meta:
        # ordering = ['event_start_date']
        verbose_name = 'Arrangement'
        verbose_name_plural = 'Arrangementer'
        ordering = ['event_start_time', 'title']
Ejemplo n.º 2
0
class AutoCrop(ImageSpec):
    processors = [ResizeToFill(500, 500)]
    format = 'JPEG'
    options = {'quality': 100}
Ejemplo n.º 3
0
class MainPhoto(models.Model):
    photo = ProcessedImageField(verbose_name='ФОТО | JPEG | 1920х500',
                                upload_to='media/',
                                format='JPEG',
                                options={'quality': 90})
    photo_low = ImageSpecField(source='photo',
                               format='JPEG',
                               options={'quality': 1})
    photo_webp = models.CharField(verbose_name='ФОТО | WEBP | 1920х500',
                                  max_length=600,
                                  null=True,
                                  blank=True)
    photo_jp2 = models.CharField(verbose_name='ФОТО | JPEG 2000 | 1920х500',
                                 max_length=600,
                                 null=True,
                                 blank=True)
    photo768 = ProcessedImageField(verbose_name='ФОТО | JPEG | 768х',
                                   upload_to='media/',
                                   format='JPEG',
                                   options={'quality': 90},
                                   null=True,
                                   blank=True)
    photo_768_low = ImageSpecField(source='photo768',
                                   format='JPEG',
                                   options={'quality': 1})
    photo_768_webp = models.CharField(verbose_name='ФОТО | WEBP | 768х',
                                      max_length=600,
                                      null=True,
                                      blank=True)
    photo_768_jp2 = models.CharField(verbose_name='ФОТО | JPEG 2000 | 768х',
                                     max_length=600,
                                     null=True,
                                     blank=True)
    photo576 = ProcessedImageField(
        verbose_name='Фото для главного слайдера(576px)',
        upload_to='media/',
        format='JPEG',
        options={'quality': 90},
        null=True,
        blank=True)
    photo_576_low = ImageSpecField(source='photo576',
                                   format='JPEG',
                                   options={'quality': 1})
    photo_576_webp = models.CharField(verbose_name='ФОТО | WEBP | 576х',
                                      max_length=600,
                                      null=True,
                                      blank=True)
    photo_576_jp2 = models.CharField(verbose_name='ФОТО | JPEG 2000 | 576х',
                                     max_length=600,
                                     null=True,
                                     blank=True)
    avatarphoto = ImageSpecField(source='photo',
                                 processors=[ResizeToFill(150, 100)],
                                 format='JPEG',
                                 options={'quality': 50})

    class Meta:
        verbose_name = ('ГЛАВНЫЙ СЛАЙДЕР | ФОТО')
        verbose_name_plural = ('ГЛАВНЫЙ СЛАЙДЕР | ФОТО')

    def __str__(self):
        self.title = "Изображение"
        return u'%s' % self.title
Ejemplo n.º 4
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"), auto_now_add=True, editable=False)
    updated = models.DateTimeField(_("updated"), auto_now=True, editable=False)
    published = models.DateTimeField(_("published"), null=True, blank=True, editable=False)

    shows = models.ManyToManyField(Show, verbose_name=_("Podcasts"))

    enable_comments = models.BooleanField(default=True)

    author_text = models.CharField(_("author text"), max_length=255, blank=True, help_text=_("""
        The person or musician name(s) featured on this specific episode.
        The suggested format is: '[email protected] (Full Name)' but 'Full Name' only,
        is acceptable. Multiple authors should be comma separated."""))

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

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

    description_pretty = models.TextField(
        _("pretty description"), blank=True,
        help_text="May be longer than 4000 characters and contain HTML tags and styling.")

    description = models.TextField(
        _("description"), max_length=4000, blank=True, 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 plain text characters.
            No HTML tags or styling allowed."""))

    tracklist = models.TextField(
        _("tracklist"), 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)

    if 'photologue' in settings.INSTALLED_APPS:
        original_image = models.ForeignKey(Photo, verbose_name=_("image"), default=None, null=True, blank=True, help_text=_("""
                A podcast must have 1400 x 1400 pixel cover art in JPG or PNG
                format using RGB color space. See our technical spec for
                details. To be eligible for featuring on iTunes Stores,
                choose an attractive, original, and square JPEG (.jpg) or
                PNG (.png) image at a size of 1400x1400 pixels. The image
                will be scaled down to 50x50 pixels at smallest in iTunes.
                For reference see the <a
                href="http://www.apple.com/itunes/podcasts/specs.html#metadata">iTunes
                Podcast specs</a>.<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!"""))
    else:
        original_image = ImageField(
            _("image"), upload_to=get_episode_upload_folder, blank=True, help_text=_("""
                A podcast must have 1400 x 1400 pixel cover art in JPG or PNG
                format using RGB color space. See our technical spec for
                details. To be eligible for featuring on iTunes Stores,
                choose an attractive, original, and square JPEG (.jpg) or
                PNG (.png) image at a size of 1400x1400 pixels. The image
                will be scaled down to 50x50 pixels at smallest in iTunes.
                For reference see the <a
                href="http://www.apple.com/itunes/podcasts/specs.html#metadata">iTunes
                Podcast specs</a>.<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 ImageSpecField:
        admin_thumb_sm = ImageSpecField(source="original_image",
                                        processors=[ResizeToFill(50, 50)],
                                        options={"quality": 100})
        admin_thumb_lg = ImageSpecField(source="original_image",
                                        processors=[ResizeToFill(450, 450)],
                                        options={"quality": 100})
        img_episode_sm = ImageSpecField(source="original_image",
                                        processors=[ResizeToFill(120, 120)],
                                        options={"quality": 100})
        img_episode_lg = ImageSpecField(source="original_image",
                                        processors=[ResizeToFill(550, 550)],
                                        options={"quality": 100})
        img_itunes_sm = ImageSpecField(source="original_image",
                                       processors=[ResizeToFill(144, 144)],
                                       options={"quality": 100})
        img_itunes_lg = ImageSpecField(source="original_image",
                                       processors=[ResizeToFill(1400, 1400)],
                                       options={"quality": 100})

    # iTunes specific fields
    hours = models.SmallIntegerField(_("hours"), default=0)
    minutes = models.SmallIntegerField(_("minutes"), default=0, choices=SIXTY_CHOICES)
    seconds = models.SmallIntegerField(_("seconds"), default=0, choices=SIXTY_CHOICES)
    keywords = models.CharField(
        _("keywords"), max_length=255, blank=True,
        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 = EpisodeQuerySet.as_manager()
    tags = TaggableManager(blank=True)

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

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("podcasting_episode_detail",
                       kwargs={"show_slug": self.shows.all()[0].slug, "slug": self.slug})

    def get_next(self):
        next = self.__class__.objects.filter(published__gt=self.published)
        try:
            return next[0]
        except IndexError:
            return False

    def get_prev(self):
        prev = self.__class__.objects.filter(published__lt=self.published).order_by("-published")
        try:
            return prev[0]
        except IndexError:
            return False

    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 = urlopen("{0}?url=http://{1}{2}".format(
                api_url,
                current_site.domain,
                self.get_absolute_url(),
            ))
            result = json.loads(u.read())
            self.tweet_text = "{0} {1} - {2}".format(
                self.shows.all()[0].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://{0}{1}".format(Site.objects.get_current(), self.get_absolute_url())

    def get_share_title(self):
        return self.title

    def get_share_description(self):
        return "{0}...".format(self.description[:512])

    def is_show_published(self):
        for show in self.shows.all():
            if show.published:
                return True
        return False
Ejemplo n.º 5
0
class Article(models.Model):

    """
    A simple model.
    Use Article.get_articles(CATEGORY=None, TAG=None, NUM=100) to
        get available articles list.
    Use Article.get_recently_articles(RECENTLY_ARTICLES_NUM) to get
        recently(RECENTLY_ARTICLES_NUM) articles.
    Use Article.get_hots_articles(HOT_ARTICLES_NUM) to
        get hot(HOT_ARTICLES_NUM) articles.
    Use article_object.related_articles(REALITVE_ARTICLES_NUM) to
        get related_articles of an object.
    """
    author = models.ForeignKey(User, verbose_name=_(u"Author"))
    category = models.ForeignKey(Category, verbose_name=_(u'Category'))

    title = models.CharField(max_length=100, verbose_name=_(u'Title'))
    tags = models.CharField(max_length=100,
                            null=True,
                            blank=True,
                            verbose_name=_(u'Tags'),
                            help_text=_(u"Use the comma(',') separated")
                            )

    summary = models.TextField(
        verbose_name=_(u'Summary'),
        validators=[MinLengthValidator(30)],
        error_messages={"min_length":
                        _("At least %(limit_value)d word,please!(it has %(show_value)d).")
                        }
    )
    content = wmd_models.MarkDownField(verbose_name=_(u'Content'))

    title_image = ProcessedImageField(upload_to='thumbnail',
                                      processors=[ResizeToFill(70, 70)],
                                      format='JPEG',
                                      options={'quality': 60}
                                      )

    status = models.IntegerField(
        default=0, choices=STATUS.items(), verbose_name=_(u'Status'))
    view_times = models.IntegerField(default=1)
    like_times = models.IntegerField(default=1)

    liked_ip = models.TextField(verbose_name=_(u'liked_ip'))
    disliked_ip = models.TextField(verbose_name=_(u'disliked_ip'))

    is_top = models.BooleanField(default=False, verbose_name=_(u'Top'))

    create_time = models.DateTimeField(
        _(u'Create Time'), auto_now_add=True, editable=True)
    update_time = models.DateTimeField(_(u'Update Time'), auto_now=True)

    def __unicode__(self):
        return self.title

    def tags_list(self):
        """
        Use article_object.tags_list() to split and get article_object's tags.
        """
        return [tag.strip() for tag in self.tags.split(',')]

    def related_articles(self, num):
        """
        A simple method.
        Use article_object.related_articles(REALITVE_ARTICLES_NUM) to
            get related_articles of an object.
        """
        related_articles = None
        try:
            related_articles = Article.objects.values('id', 'title', 'view_times', 'update_time', 'author').\
                filter(tags__icontains=self.tags_list()[0]).\
                exclude(id=self.id)[:num]
        except IndexError:
            pass

        if not related_articles:
            related_articles = Article.objects.values('id', 'title', 'view_times', 'update_time', 'author').\
                filter(category=self.category).\
                exclude(id=self.id)[:num]

        return related_articles

    @classmethod
    def get_articles(cls, CATEGORY=None, TAG=None, NUM=100):
        """
        A simple classmethod.
        Use Article.get_articles(CATEGORY=None, TAG=None, NUM=100) to
            get articles list.
        """
        if CATEGORY:
            article_list = cls.objects.filter(
                Q(status=0) & Q(category__name__icontains=CATEGORY))[:NUM]
            return article_list
        if TAG:
            article_list = cls.objects.filter(
                Q(status=0) & Q(tags__icontains=TAG))[:NUM]
            return article_list
        return cls.objects.filter(status=0)[:NUM]

    @classmethod
    def get_all_tags_list(cls):
        """
        A simple classmethod.
        Use Article.get_all_tags_list() to get all articles' tags list.
        """
        all_tags_list = []
        # obj_list = cls.objects.filter(status=0).order_by('-update_time')
        obj_list = Article.objects.all()
        for obj in obj_list:
            all_tags_list = all_tags_list + obj.tags_list()
            # for tag in obj.tags.split(','):
            #     all_tags_list.append(tag)
        return all_tags_list

    @classmethod
    def get_recently_articles(cls, num):
        """
        A simple classmethod.
        Use Article.get_recently_articles(RECENTLY_ARTICLES_NUM) to
            get recently(RECENTLY_ARTICLES_NUM) articles.
        """
        return cls.objects.values('title', 'view_times', 'update_time', 'author')\
            .filter(status=0).order_by('-update_time')[:num]

    @classmethod
    def get_hots_articles(cls, num):
        """
        A simple classmethod.
        Use Article.get_hots_articles(HOT_ARTICLES_NUM) to
            get hot(HOT_ARTICLES_NUM) articles.
        """
        return cls.objects.values('id', 'title', 'view_times', 'update_time', 'author').\
            filter(status=0).order_by('-view_times'
                                      )[:num]

    class Meta:
        ordering = ['-is_top', '-update_time', '-create_time']
        verbose_name_plural = verbose_name = _(u"Article")
Ejemplo n.º 6
0
class ProfileImage(ImageSpec):
    processors = [ResizeToFill(50, 50)]
    format = 'JPEG'
    options = {'quality': 60}
Ejemplo n.º 7
0
class Post(models.Model):
    title = models.CharField(max_length=50, verbose_name='文章标题')
    excerpt = models.CharField(max_length=200, verbose_name='文章摘要')
    content = RichTextUploadingField(verbose_name='文章内容')
    click_count = models.PositiveIntegerField(default=0, verbose_name='点击次数')
    is_recommended = models.BooleanField(default=False, verbose_name='是否推荐')
    date_created = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
    date_modified = models.DateTimeField(auto_now=True, verbose_name='修改时间')
    author = models.ForeignKey(User, verbose_name='作者')
    category = models.ForeignKey(Category, verbose_name='分类')
    tag = models.ManyToManyField(Tag, verbose_name='标签')
    cover = ProcessedImageField(upload_to='cover', default='', verbose_name='封面', processors=[ResizeToFill(160, 120)],
                                format='JPEG',
                                options={"quality": 60})
    favours = GenericRelation(Favour, related_query_name='posts')

    class Meta:
        verbose_name = '文章'
        verbose_name_plural = verbose_name
        ordering = ['-date_created']

    def __str__(self):
        return self.title

    def favour_count(self, update=0):
        key = 'post_{}_favour_count'.format(self.id)
        count = cache.get(key)
        if count is None:
            count = self.favours.filter(liked=True).count()
            cache.set(key, count, timeout=300)
        elif update:
            count += update
            cache.set(key, count, timeout=300)
        return count

    def click_increase(self):
        self.click_count += 1
        self.save(update_fields=['click_count'])

    def get_absolute_url(self):
        return reverse('blog:detail', kwargs={'pk': self.pk})

    def to_comments_html(self):
        key = 'post_{}_comments'.format(self.id)
        html = ''
        comments = self.comment_set.all().order_by('-submit_date')[:15]
        for comment in comments:
            comment_html = comment.to_html()
            html += comment_html
        cache.set(key, html, timeout=300)
        return html

    def comment_user_count(self):
        key = "post_{}_comments_user_num".format(self.id)
        user_num = cache.get(key, None)
        if not user_num:
            user_list = []
            key1 = "post_{}_comments_user".format(self.id)
            for comment in self.comment_set.all():
                if comment.user not in user_list:
                    user_list.append(comment.user)
            user_num = len(user_list)
            cache.set(key, user_num, timeout=300)
            cache.set(key1, user_list, timeout=300)
        return user_num

    def comment_count(self):
        key = "post_{}_comments_num".format(self.id)
        comment_num = cache.get(key, None)
        if not comment_num:
            comment_num = self.comment_set.all().count()
            cache.set(key, comment_num, timeout=300)
        return comment_num

    def comment_update(self, new_comment):
        comment_list_html = self.to_comments_html()
        key2 = "post_{}_comments_user".format(self.id)
        key3 = "post_{}_comments_user_num".format(self.id)
        user_list = cache.get(key2, None)
        if user_list:
            if new_comment.user not in user_list:
                user_list.append(new_comment.user)
            user_num = len(user_list)
            cache.set(key3, user_num, timeout=300)
            cache.set(key2, user_list, timeout=300)
        else:
            user_num = self.comment_user_count()
        key4 = "post_{}_comments_num".format(self.id)
        comment_num = cache.get(key4, None)
        if comment_num:
            comment_num += 1
            cache.set(key4, comment_num, timeout=300)
        else:
            comment_num = self.comment_count()
        return comment_list_html, user_num, comment_num
Ejemplo n.º 8
0
class Event(models.Model):
    title = models.CharField(max_length=160, blank=False)
    status = models.CharField(max_length=2, choices=STATUS_CHOICES)
    event_type = models.CharField(max_length=11, choices=EVENT_TYPE_CHOICES)
    mode = models.CharField(max_length=9, choices=MODE_CHOICES)
    location = models.ForeignKey("authentication.Chapter",
                                 related_name="event",
                                 on_delete=models.CASCADE)
    host = models.CharField(max_length=50, blank=True)
    presenter_first_name = models.CharField(max_length=50,
                                            blank=False,
                                            verbose_name="First Name")
    presenter_last_name = models.CharField(max_length=50,
                                           blank=False,
                                           verbose_name="Last Name")
    presenter_designation = models.CharField(max_length=80,
                                             blank=False,
                                             verbose_name="Designation")
    pres_img = ProcessedImageField(
        upload_to="events/presenters",
        blank=True,
        verbose_name="Presenter Picture")  # processedimagefield
    presenter_picture = ImageSpecField(source="pres_img",
                                       processors=[ResizeToFill(300, 300)
                                                   ])  # sized image
    presenter_picture_thumbnail = ImageSpecField(
        source="pres_img", processors=[ResizeToFill(90,
                                                    90)])  # thumbnail image
    presenter_profile_url = models.URLField(blank=False,
                                            verbose_name="Public Profile URL")
    presenter_company_name = models.CharField(max_length=100,
                                              blank=False,
                                              verbose_name="Company Name")
    pres_com_log = ProcessedImageField(
        upload_to="events/company_logos",
        blank=True,
        verbose_name="Company Logo")  # prcessedimagefield
    presenter_company_logo = ImageSpecField(
        source="pres_com_log", processors=[ResizeToFill(200,
                                                        200)])  # sized image
    presenter_company_website = models.URLField(blank=True,
                                                verbose_name="Company Website")
    presenter_bio = models.TextField(blank=False, verbose_name="Bio")
    event_description = models.TextField(blank=False)
    event_address = models.TextField(blank=True)
    link = models.URLField(blank=True)
    timezone = models.CharField(max_length=100,
                                blank=False,
                                choices=TIMEZONE_CHOICES)
    start_date = models.DateField(blank=False)
    start_time = models.TimeField(blank=False)
    end_date = models.DateField(blank=False)
    end_time = models.TimeField(blank=False)

    added_by = models.ForeignKey("authentication.User",
                                 related_name="event",
                                 null=True,
                                 on_delete=models.CASCADE)
    added_on = models.DateTimeField(auto_now_add=True)
    slides = models.FileField(upload_to="slides/", null=True, blank=True)

    def __str__(self):
        return self.title
Ejemplo n.º 9
0
class Post(models.Model):
    """ Post model """
    id = models.UUIDField(primary_key=True, default=uuid4, editable=False)

    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    title = models.CharField(max_length=200)
    text = models.TextField(null=True, max_length=2000)
    image = models.ImageField(upload_to=settings.POST_IMAGE_UPLOAD_DIR,
                              verbose_name='post image')
    image_thumbnail = ImageSpecField(source='image',
                                     processors=[ResizeToFill(640, 360)],
                                     format='JPEG',
                                     options={'quality': 60})
    created_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True,
                                          null=True,
                                          default=timezone.now)
    hits = models.PositiveIntegerField(blank=True, null=True, default=0)
    goods = models.PositiveIntegerField(blank=True, null=True, default=0)
    bads = models.PositiveIntegerField(blank=True, null=True, default=0)

    def __str__(self):
        return self.title

    def publish(self):
        """ Publish this post now """
        self.published_date = timezone.now()
        self.save()

    def create(self, author):
        """ Create post """
        self.author = author
        self.publish()

    def was_published_recently(self):
        """ Whether the post was published within 1 day """
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.published_date <= now

    was_published_recently.admin_order_field = 'published_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

    def change_image_name(self, name):
        """ Change the post image name """
        self.image.name = name

    def count_hits(self):
        self.hits = PostHit.objects.filter(post=self.pk).count()
        return self.hits

    def count_goods(self):
        self.goods = PostEval.objects.filter(post=self.pk,
                                             good=True,
                                             bad=False).count()
        return self.goods

    def count_bads(self):
        self.bads = PostEval.objects.filter(post=self.pk, good=False,
                                            bad=True).count()
        return self.bads
Ejemplo n.º 10
0
class ThumbnailsImage(models.Model):
    image = models.ForeignKey(Image, on_delete=models.CASCADE)
    avatar_thumbnail = ProcessedImageField(upload_to='avatars',
                                           processors=[ResizeToFill(250, 150)],
                                           format='JPEG',
                                           options={'quality': 60})
Ejemplo n.º 11
0
class Product(models.Model):
    category = models.ForeignKey(ProductCategory, null=True)
    name = models.CharField(max_length=100,
                            default="fill in your product name here")
    image_1 = ProcessedImageField(upload_to="products",
                                  processors=[ResizeToFill(360, 360)],
                                  format="PNG",
                                  options={'quality': 80},
                                  null=True,
                                  blank=True)
    image_2 = ProcessedImageField(upload_to="products",
                                  processors=[ResizeToFill(360, 360)],
                                  format="PNG",
                                  options={'quality': 80},
                                  null=True,
                                  blank=True)
    image_3 = ProcessedImageField(upload_to="products",
                                  processors=[ResizeToFill(360, 360)],
                                  format="PNG",
                                  options={'quality': 80},
                                  null=True,
                                  blank=True)
    image_4 = ProcessedImageField(upload_to="products",
                                  processors=[ResizeToFill(360, 360)],
                                  format="PNG",
                                  options={'quality': 80},
                                  null=True,
                                  blank=True)
    definition = models.CharField(
        max_length=300, default="Fill in product short definition here")
    optional_definition_switch = models.BooleanField(default=True)
    optional_definition = models.TextField(
        default="Fill in extra definition in HTML form here if switch = true")
    original_price = models.DecimalField(max_digits=10, decimal_places=2)
    discount_switch = models.BooleanField(default=False)
    discount = models.DecimalField(max_digits=10,
                                   decimal_places=2,
                                   default="5.00")
    in_stock = models.BooleanField(default=True)
    discounted_price = models.DecimalField(max_digits=10,
                                           decimal_places=2,
                                           default="50.00")
    member_price_switch = models.BooleanField(default=False)
    discount_member = models.DecimalField(max_digits=10,
                                          decimal_places=2,
                                          default="7.50")
    discounted_member_price = models.DecimalField(max_digits=10,
                                                  decimal_places=2,
                                                  default="50.00")
    slug = models.SlugField(default="will-be-generated-once-save")
    created_date = models.DateTimeField(default=timezone.now)

    def calculate_general_price(self):
        value = ((100 - self.discount) / 100) * self.original_price
        return float(round(value))

    def calculate_member_price(self):
        value = ((100 - self.discount_member) / 100) * self.original_price
        return float(round(value))

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        self.discounted_price = self.calculate_general_price()
        self.discounted_member_price = self.calculate_member_price()
        super(Product, self).save(*args, **kwargs)

    def __str__(self):
        return self.name
Ejemplo n.º 12
0
class ProgrammeEvent(models.Model):
    EVENT_TYPES = (
        (0, 'Yksinkertainen'),
        (1, 'Yksityiskohtainen'),
    )

    event = models.ForeignKey(Event,
                              verbose_name='Tapahtuma',
                              on_delete=models.PROTECT)
    start = models.DateTimeField('Alku', help_text='Tapahtuman alkamisaika.')
    end = models.DateTimeField('Loppu',
                               help_text='Tapahtuman loppumisaika.',
                               null=True,
                               blank=True)
    description = models.TextField('Kuvaus', blank=True)
    title = models.CharField('Otsikko',
                             help_text='Lyhyt otsikko.',
                             max_length=128)
    presenters = models.CharField('Henkilöt',
                                  help_text='Esityksen pitäjät tms.',
                                  max_length=256,
                                  blank=True)
    presenters_titles = models.CharField(
        'Nimikkeet',
        help_text='Henkilön arvo-, ammatti- tai virkanimike.',
        max_length=256,
        blank=True)
    place = models.CharField('Paikka',
                             help_text='Tarkka paikka tapahtuma-areenalla',
                             max_length=64,
                             blank=True)

    # This is such a hackish solution that it makes me want to throw up. Oh well.
    icon_original = models.ImageField('Kuva 1',
                                      upload_to='programme/images/',
                                      help_text="Kuva 1 tapahtumalle.",
                                      blank=True)
    icon_small = ImageSpecField([ResizeToFill(64, 64)],
                                source='icon_original',
                                format='PNG')
    icon2_original = models.ImageField('Kuva 2',
                                       upload_to='programme/images/',
                                       help_text="Kuva 2 tapahtumalle.",
                                       blank=True)
    icon2_small = ImageSpecField([ResizeToFill(64, 64)],
                                 source='icon2_original',
                                 format='PNG')

    email = models.EmailField(
        'Sähköposti',
        help_text='Tapahtumaan liittyvä sähköposti-osoite (esim. esiintyjän).',
        blank=True)
    home_url = models.URLField('Kotiurli',
                               help_text='Tapahtumaan liittyvä URL.',
                               blank=True)
    twitter_url = models.URLField(
        'Twitter', help_text='Tapahtumaan liittyvä Twitter-url.', blank=True)
    github_url = models.URLField('Github',
                                 help_text='Tapahtumaan liittyvä Github-url',
                                 blank=True)
    facebook_url = models.URLField(
        'Facebook', help_text='Tapahtumaan liittyvä facebook-url.', blank=True)
    linkedin_url = models.URLField(
        'LinkedIn', help_text='Tapahtumaan liittyvä LinkedIn-url.', blank=True)
    wiki_url = models.URLField('Wikipedia',
                               help_text='Tapahtumaan liittyvä Wikipedia-url.',
                               blank=True)
    gplus_url = models.URLField(
        'Google+',
        help_text='Tapahtumaan liittyvä Google Plus-url.',
        blank=True)
    event_type = models.IntegerField(
        'Tapahtuman tyyppi',
        choices=EVENT_TYPES,
        default=0,
        help_text=
        "Määrittää tapahtuman tyypin. Yksityiskohtaiset tapahtumat näkyvät etusivun tapahtumalistassa."
    )
    active = models.BooleanField('Aktiivinen',
                                 help_text='Deaktivoidut piilotetaan.',
                                 default=True)

    @property
    def short_start_time(self):
        if self.start:
            start = arrow.get(self.start).to(settings.TIME_ZONE)
            return "{} {}".format(short_days[start.weekday()],
                                  start.format("HH:mm"))
        return ""

    def save(self, *args, **kwargs):
        # Delete old icon file when editing
        try:
            this = ProgrammeEvent.objects.get(id=self.id)
            if this.icon_original != self.icon_original:
                this.icon_original.delete(save=False)
        except ProgrammeEvent.DoesNotExist:
            pass

        # Continue with normal save
        super(ProgrammeEvent, self).save(*args, **kwargs)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = "ohjelmatapahtuma"
        verbose_name_plural = "ohjelmatapahtumat"
Ejemplo n.º 13
0
class StoryImage(models.Model):
    image = ProcessedImageField(processors=[ResizeToFill(300, 300)],
                                format='JPEG',
                                options={'quality': 90},
                                upload_to='storys')
    story = models.ForeignKey(Story, on_delete=models.CASCADE)
Ejemplo n.º 14
0
class Picture(models.Model):
    text = models.TextField()
    image = models.ImageField(upload_to="blogimg")
    image_thumbnail = ImageSpecField(source='image',
                                     processors=[ResizeToFill(130, 130)])
Ejemplo n.º 15
0
class Project(models.Model):
    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Published')
    )
    title = models.CharField(max_length=255)
    slug = models.SlugField(
        max_length=255,
        unique=True)
    image = models.ImageField(
        upload_to=project_image_folder,
        blank=True)
    image_thumbnail = ImageSpecField(
        source='image',
        processors=[ResizeToFill(850, 550)],
        format='JPEG',
        options={'quality': 90})
    thumb = ImageSpecField(
        source='image',
        processors=[ResizeToFit(600, 600)],
        format='JPEG',
        options={'quality': 90})
    project_url = models.URLField(
        'Project URL',
        null=True,
        blank=True)
    description = models.TextField(blank=True)
    technology = models.CharField(max_length=255)
    report_file = models.FileField(
        upload_to='report/%Y/%m/%d/',
        null=True,
        blank=True)
    meta_keywords = models.CharField(
        max_length=255,
        null=True,
        blank=True,
        help_text='Comma-delimited set of SEO keywords for meta tag')
    meta_description = models.TextField(
        max_length=255,
        null=True,
        blank=True,
        help_text='Content for description meta tag, maximum are 200 characters')
    publish = models.DateTimeField(default=timezone.now)
    added = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    category = models.ForeignKey(
        'ProjectCategory',
        null=True,
        blank=True,
        on_delete=models.CASCADE)
    status = models.CharField(
        max_length=10,
        choices=STATUS_CHOICES,
        default='draft')
    object = models.Manager()
    published = PublishedManager()

    class Meta:
        ordering = ('-added',)
        verbose_name = 'Project'
        verbose_name_plural = 'Projects'

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('project_detail',
                       args=[self.pk, self.slug])
Ejemplo n.º 16
0
 def processors(self):
     model, field_name = get_field_info(self.source)
     return [ResizeToFill(model.width, model.height)]
Ejemplo n.º 17
0
class Post(models.Model):
    STATUS_CHOICES = (
        ('draft', 'Draft'),
        ('published', 'Published'),
    )
    title = models.CharField(max_length=255)
    slug = models.SlugField(
        max_length=250,
        unique_for_date='publish')
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE)
    body = models.TextField()

    image = models.ImageField(
        upload_to=blog_image_folder,
        blank=True)
    image_thumbnail = ImageSpecField(
        source='image',
        processors=[ResizeToFill(50, 50)],
        format='JPEG',
        options={'quality': 90})
    thumb = ImageSpecField(
        source='image',
        processors=[ResizeToFill(600, 600)],
        format='JPEG',
        options={'quality': 90})
    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(
        max_length=10,
        choices=STATUS_CHOICES,
        default='draft')
    meta_keywords = models.CharField(
        max_length=250,
        help_text='Comma-delimited set of SEO keywords for keywords meta tag',
        blank=True)
    meta_description = models.CharField(
        max_length=250,
        help_text='Content for description meta tag',
        blank=True)
    objects = models.Manager()
    published = PublishedManager()
    tags = TaggableManager()

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

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post_detail',
                       args=[self.publish.year,
                             self.publish.month,
                             self.publish.day,
                             self.slug])

    @property
    def comments(self):
        instance = self
        qs = Comment.objects.filter_by_instance(instance)
        return qs

    @property
    def get_content_type(self):
        instance = self
        content_type = ContentType.objects.get_for_model(instance.__class__)
        return content_type
Ejemplo n.º 18
0
Archivo: models.py Proyecto: Siyet/ccp
class Shirt(models.Model):
    related_fields = ["collection", "fabric", "size_option", "size", "hem", "placket", "pocket", "back",
                      "custom_buttons_type", "custom_buttons", "shawl", "yoke"]

    CLASP_OPTIONS = Choices((False, _(u'Не использовать застежку')), (True, _(u'Использовать застежку')))

    is_template = models.BooleanField(_(u'Используется как шаблон'), default=False)
    is_standard = models.BooleanField(_(u'Используется как стандартный вариант'), default=False, editable=False)
    collection = models.ForeignKey(Collection, verbose_name=_(u'Коллекция'), related_name='shirts', null=True)
    code = models.CharField(_(u'Артикул'), max_length=255, null=True)
    individualization = models.TextField(_(u'Индивидуализация'), null=True, blank=True)

    fabric = models.ForeignKey(Fabric, verbose_name=_(u'Ткань'), null=True)

    showcase_image = models.ImageField(_(u'Изображение для витрины'), blank=False, null=True, upload_to='showcase')
    showcase_image_list = ImageSpecField(source='showcase_image',
                                         processors=[ResizeToFill(*settings.SHOWCASE_IMAGE_SIZE)],
                                         format='JPEG',
                                         options={'quality': 100})

    showcase_image_detail = ImageSpecField(source='showcase_image',
                                           processors=[ResizeToFill(*settings.SHOWCASE_DETAILS_IMAGE_SIZE)],
                                           format='JPEG',
                                           options={'quality': 100})

    size_option = models.ForeignKey('dictionaries.SizeOptions', verbose_name=_(u'Выбранный вариант размера'))
    size = models.ForeignKey('dictionaries.Size', verbose_name=_(u'Размер'), blank=True, null=True)

    hem = models.ForeignKey('dictionaries.HemType', verbose_name=_(u'Низ'), related_name='hem_shirts')
    placket = models.ForeignKey('dictionaries.PlacketType', verbose_name=_(u'Полочка'), related_name='placket_shirts')
    pocket = models.ForeignKey('dictionaries.PocketType', verbose_name=_(u'Карман'), related_name='pocket_shirts')
    sleeve = models.ForeignKey('dictionaries.SleeveType', verbose_name=_(u'Рукав'), related_name='sleeve_shirts',
                               default=ResolveDefault(SleeveType))
    fit = ChainedForeignKey(Fit, verbose_name=_(u'Талия'), chained_field='collection',
                            chained_model_field='collections', show_all=False, blank=True, null=True)

    tuck = ChainedForeignKey('dictionaries.TuckType', verbose_name=_(u'Вытачки'), chained_field='collection',
                             chained_model_field='collections', show_all=False)

    back = models.ForeignKey('dictionaries.BackType', verbose_name=_(u'Спинка'), related_name='back_shirts')

    custom_buttons_type = models.ForeignKey('dictionaries.CustomButtonsType', verbose_name=_(u'Тип кастомных пуговиц'),
                                            null=True, blank=True, related_name='back_shirts')
    custom_buttons = ChainedForeignKey(CustomButtons, verbose_name=_(u'Кастомные пуговицы'),
                                       chained_field='custom_buttons_type',
                                       chained_model_field='type', show_all=False, null=True, blank=True)

    shawl = models.ForeignKey(ShawlOptions, verbose_name=_(u'Платок'), null=True, related_name='shirts',
                              default=ResolveDefault(ShawlOptions))
    yoke = models.ForeignKey('dictionaries.YokeType', verbose_name=_(u'Кокетка'), null=True)
    clasp = models.BooleanField(_(u'Застежка под штифты'), choices=CLASP_OPTIONS, default=False)

    STITCH = Choices(('none', _(u'0 мм (без отстрочки)')), ('1mm', _(u'1 мм (только со съемными косточками)')),
                     ('5mm', _(u'5 мм')))
    stitch = models.CharField(_(u'Ширина отстрочки'), max_length=10, choices=STITCH)

    price = models.DecimalField(_(u'Цена'), max_digits=10, decimal_places=2, editable=False, null=True)

    def save(self, *args, **kwargs):
        cuff = getattr(self, 'cuff', None)
        if cuff and not self.sleeve.cuffs:
            if cuff.id:
                cuff.delete()

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

    class Meta:
        ordering = ('code',)
        verbose_name = _(u'Сорочка')
        verbose_name_plural = _(u'Сорочки')

    def __unicode__(self):
        return self.code if self.code else self.id
Ejemplo n.º 19
0
class Movie(BaseAddModify, BaseNameSlug):
    """Movie model"""
    name = models.CharField(_('Name'), max_length=100)
    slug = models.SlugField(_('Slug'), max_length=110, unique=True, blank=True)

    release_year = models.CharField(_('Release Year'), max_length=4)
    duration = models.SmallIntegerField(_('Duration'),
                                        default=0,
                                        blank=True,
                                        help_text=_('in minutes'))
    imdb_rating = models.FloatField(_('IMDB Rating'),
                                    default=0,
                                    blank=True,
                                    help_text=_('e.g. 6.8'))

    content = models.TextField(_('Content'), default='', blank=True)
    source_content = models.URLField(  # credits
        _('Content Source'), default='', blank=True)
    trailer = models.URLField(
        _('Trailer'),
        default='',
        blank=True,
        help_text=_('trailer url (ONLY for youtube videos yet)'))

    image = models.ImageField(_('Image'),
                              default='movies/default-movie.jpg',
                              upload_to=movie_directory_path,
                              blank=True,
                              null=True)
    image_thumbnail = ImageSpecField(source='image',
                                     processors=[ResizeToFill(250, 400)],
                                     format='JPEG',
                                     options={'quality': 80})
    credit_image = models.CharField(  # credits
        _('Image Credit'), max_length=250, default='', blank=True)

    pg_rating = models.ForeignKey(PgRating,
                                  on_delete=models.SET_NULL,
                                  blank=True,
                                  null=True,
                                  related_name='movies',
                                  verbose_name=_('PG Rating'))

    genres = models.ManyToManyField(Genre,
                                    related_name='movies',
                                    verbose_name=_('Genres'))

    crews = models.ManyToManyField('celebs.Celebrity',
                                   through='MovieCrew',
                                   related_name='movies',
                                   verbose_name=_('Crews'))

    @property
    def casts(self):
        return self._get_crew('C')

    @property
    def directors(self):
        return self._get_crew('D')

    @property
    def producers(self):
        return self._get_crew('P')

    @property
    def writers(self):
        return self._get_crew('W')

    @property
    def youtube_video(self):
        return video_code(self.trailer)

    class Meta:
        verbose_name = _('Movie')
        verbose_name_plural = _('Movies')
        ordering = ('-release_year', 'name')

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(unidecode(self.name) + '-' + random_name(5))
        super().save(*args, **kwargs)

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

    def _get_crew(self, duty_code):
        if hasattr(self, '_prefetched_objects_cache'
                   ) and 'moviecrews' in self._prefetched_objects_cache:
            return [
                c for c in self._prefetched_objects_cache['moviecrews']
                if c.duty.code == duty_code
            ]
        else:
            return self.moviecrews.filter(duty__code=duty_code)
Ejemplo n.º 20
0
class Recipe(models.Model):
    """
    Django Model to hold Recipes.

    Courses have a one to Many relation with Recipes.
    Cuisines have a one to Many relation with Recipes.
    Tags have a Many to Many relation with Recipes.
    Ingredient Groups have a Many to one relation with Recipes.
    Subrecipes have a Many to Many relation with Recipes. 
        They allow another recipe to be show in the Ingredient section.

    :title: = Title of the Recipe
    :author: = Creator of the Recipe
    :photo: = Raw Image of a Recipe
    :photo_thumbnail: = compressed image of the photo
    :info: = Description of the recipe
    :directions: = How to make the recipe
    :prep_time: = How long it takes to prepare the recipe
    :cook_time: = How long the recipe takes to cook
    :servings: = How many people the recipe with serve
    :rating: = Rating of the recipe
    :pub_date: = When the recipe was created
    :update_date: = When the recipe was updated
    """
    title = models.CharField(_("Recipe Title"), max_length=250)
    slug = AutoSlugField(_('slug'), populate_from='title', unique=True)
    author = models.ForeignKey(User, verbose_name=_('user'), null=True)
    photo = models.ImageField(_('photo'),
                              blank=True,
                              upload_to="upload/recipe_photos")
    photo_thumbnail = ImageSpecField(source='photo',
                                     processors=[ResizeToFill(300, 200)],
                                     format='JPEG',
                                     options={'quality': 70})
    cuisine = models.ForeignKey(Cuisine, verbose_name=_('cuisine'))
    course = models.ForeignKey(Course, verbose_name=_('course'))
    tags = models.ManyToManyField(Tag, verbose_name=_('tag'), blank=True)
    subrecipes = models.ManyToManyField('self',
                                        verbose_name=_('subrecipes'),
                                        through='SubRecipe',
                                        symmetrical=False)
    info = models.TextField(_('info'),
                            help_text="enter information about the recipe",
                            blank=True)
    directions = models.TextField(_('direction_text'),
                                  help_text="directions",
                                  blank=True)
    source = models.CharField(_('course'), max_length=200, blank=True)
    prep_time = models.IntegerField(_('prep time'),
                                    help_text="enter time in minutes")
    cook_time = models.IntegerField(_('cook time'),
                                    help_text="enter time in minutes")
    servings = models.IntegerField(_('servings'),
                                   help_text="enter total number of servings")
    rating = models.IntegerField(_('rating'),
                                 help_text="rating of the meal",
                                 default=0)
    pub_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-pub_date', 'title']

    def __unicode__(self):
        return '%s' % self.title
Ejemplo n.º 21
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"), auto_now_add=True, editable=False)
    updated = models.DateTimeField(_("updated"), auto_now=True, editable=False)
    published = models.DateTimeField(_("published"), null=True, blank=True, editable=False)

    sites = models.ManyToManyField(Site, verbose_name=_('Sites'))

    ttl = models.PositiveIntegerField(
        _("ttl"), default=1440,
        help_text=_("""``Time to Live,`` the number of minutes a channel can be
        cached before refreshing."""))

    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, related_name="podcast_shows",
        verbose_name=_("owner"),
        help_text=_("""Make certain the user account has a name and e-mail address."""))

    editor_email = models.EmailField(
        _("editor email"), blank=True,
        help_text=_("Email address of the person responsible for the feed's content."))
    webmaster_email = models.EmailField(
        _("webmaster email"), blank=True,
        help_text=_("Email address of the person responsible for channel publishing."))

    if 'licenses' in settings.INSTALLED_APPS:
        license = models.ForeignKey(License, verbose_name=_("license"))
    else:
        license = models.CharField(
            _("license"), max_length=255,
            help_text=_("To publish a podcast to iTunes it is required to set a license type."))

    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)

    author_text = models.CharField(
        _("author text"), max_length=255, help_text=_("""
            This tag contains the name of the person or company that is most
            widely attributed to publishing the Podcast and will be
            displayed immediately underneath the title of the Podcast.
            The suggested format is: '[email protected] (Full Name)'
            but 'Full Name' only, is acceptable. Multiple authors
            should be comma separated."""))

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

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

    # If the show is not on iTunes, many fields may be ignored in your user forms
    on_itunes = models.BooleanField(
        _("iTunes"), default=True,
        help_text=_("Checked if the podcast is submitted to iTunes"))

    description_pretty = models.TextField(
        _("pretty description"), blank=True,
        help_text="May be longer than 4000 characters and contain HTML tags and styling.")

    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 yourp 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."""))

    if 'photologue' in settings.INSTALLED_APPS:
        original_image = models.ForeignKey(Photo, verbose_name=_("image"), default=None, null=True, blank=True, help_text=_("""
                A podcast must have 1400 x 1400 pixel cover art in JPG or PNG
                format using RGB color space. See our technical spec for
                details. To be eligible for featuring on iTunes Stores,
                choose an attractive, original, and square JPEG (.jpg) or
                PNG (.png) image at a size of 1400x1400 pixels. The image
                will be scaled down to 50x50 pixels at smallest in iTunes.
                For reference see the <a
                href="http://www.apple.com/itunes/podcasts/specs.html#metadata">iTunes
                Podcast specs</a>.<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!"""))
    else:
        original_image = ImageField(
            _("image"), upload_to=get_show_upload_folder, blank=True, help_text=_("""
                A podcast must have 1400 x 1400 pixel cover art in JPG or PNG
                format using RGB color space. See our technical spec for
                details. To be eligible for featuring on iTunes Stores,
                choose an attractive, original, and square JPEG (.jpg) or
                PNG (.png) image at a size of 1400x1400 pixels. The image
                will be scaled down to 50x50 pixels at smallest in iTunes.
                For reference see the <a
                href="http://www.apple.com/itunes/podcasts/specs.html#metadata">iTunes
                Podcast specs</a>.<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 ResizeToFill:
        admin_thumb_sm = ImageSpecField(source="original_image",
                                        processors=[ResizeToFill(50, 50)],
                                        options={"quality": 100})
        admin_thumb_lg = ImageSpecField(source="original_image",
                                        processors=[ResizeToFill(450, 450)],
                                        options={"quality": 100})
        img_show_sm = ImageSpecField(source="original_image",
                                     processors=[ResizeToFill(120, 120)],
                                     options={"quality": 100})
        img_show_lg = ImageSpecField(source="original_image",
                                     processors=[ResizeToFill(550, 550)],
                                     options={"quality": 100})
        img_itunes_sm = ImageSpecField(source="original_image",
                                       processors=[ResizeToFill(144, 144)],
                                       options={"quality": 100})
        img_itunes_lg = ImageSpecField(source="original_image",
                                       processors=[ResizeToFill(1400, 1400)],
                                       options={"quality": 100})

    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, blank=True,
        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 = ShowQuerySet.as_manager()
    tags = TaggableManager(blank=True)

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

    def __str__(self):
        return self.title

    def get_share_url(self):
        return "http://{0}{1}".format(Site.objects.get_current(), self.get_absolute_url())

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

    @property
    def current_episode(self):
        try:
            return self.episode_set.published().order_by("-published")[0]
        except IndexError:
            return None
Ejemplo n.º 22
0
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    location = models.CharField(max_length=50, default='')
    bio = models.TextField(default='')
    gender = models.CharField(max_length=6, choices=GENDER_CHOICES, default='')
    role = models.CharField(max_length=6,
                            blank=False,
                            default='mentee',
                            choices=ROLE_CHOICES)
    phone_number = models.CharField(max_length=32, default='')
    mentorship_areas = MultiSelectField(choices=MENTORSHIP_AREAS_CHOICES,
                                        max_choices=3,
                                        default='')
    highest_level_of_study = models.CharField(max_length=255,
                                              choices=EDUCATION_CHOICES,
                                              default='')
    is_previously_logged_in = models.CharField(max_length=5, default=False)
    email_confirmed = models.BooleanField(default=False)
    profile_picture = ProcessedImageField(
        upload_to='profiles',
        processors=[ResizeToFill(300, 300)],
        format='JPEG',
        options={'quality': 99},
        default=DEFAULT,
    )

    def is_mentor(self):
        return self.role == 'mentor'

    def is_mentee(self):
        return self.role == 'mentee'

    class Meta:
        db_table = 'auth_profile'

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

    def get_gravatar(self):
        gravatar_url = 'https://www.gravatar.com/avatar/{0}?{1}'.format(
            hashlib.md5(self.user.email.lower().encode('utf-8')).hexdigest(),
            urlencode({'s': '256'}))
        return gravatar_url

    def get_screen_name(self):
        if self.user.get_full_name():
            return self.user.get_full_name()
        else:
            return self.user.username

    def notify_favorited(self, question):
        if self.user != question.user:
            Notification(notification_type=Notification.FAVORITED,
                         from_user=self.user,
                         to_user=question.user,
                         question=question).save()

    def unotify_favorited(self, question):
        if self.user != question.user:
            Notification.objects.filter(
                notification_type=Notification.FAVORITED,
                from_user=self.user,
                to_user=question.user,
                question=question).delete()

    def notify_answered(self, question):
        if self.user != question.user:
            Notification(notification_type=Notification.ANSWERED,
                         from_user=self.user,
                         to_user=question.user,
                         question=question).save()

    def notify_also_answered(self, question):
        answers = question.get_answers()
        users = []
        for answer in answers:
            if answer.user != self.user and answer.user != question.user:
                users.append(answer.user.pk)
        users = list(set(users))
        for user in users:
            Notification(notification_type=Notification.ALSO_ANSWERED,
                         from_user=self.user,
                         to_user=User(id=user),
                         question=question).save()

    def notify_accepted(self, answer):
        if self.user != answer.user:
            Notification(notification_type=Notification.ACCEPTED_ANSWER,
                         from_user=self.user,
                         to_user=answer.user,
                         answer=answer).save()

    def unotify_accepted(self, answer):
        if self.user != answer.user:
            Notification.objects.filter(
                notification_type=Notification.ACCEPTED_ANSWER,
                from_user=self.user,
                to_user=answer.user,
                answer=answer).delete()

    def notify_article_commented(self, article):
        if self.user != article.create_user:
            Notification(notification_type=Notification.COMMENTED,
                         from_user=self.user,
                         to_user=article.create_user,
                         article=article).save()

    def also_article_commented(self, article):
        comments = article.get_comments()
        users = []
        for comment in comments:
            if comment.user != self.user and comment.user != article.create_user:
                users.append(article.create_user.pk)
        users = list(set(users))
        for user in users:
            Notification(notification_type=Notification.ALSO_COMMENTED,
                         from_user=self.user,
                         to_user=User(id=user),
                         article=article).save()
Ejemplo n.º 23
0
class Post(ModerationBaseModel, HitCountMixin):
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        verbose_name=_('Автор'))
    title = models.CharField(
        _('Заголовок'),
        max_length=150)
    slug = models.SlugField(
        _('Слаг'),
        max_length=60,
        unique=False,
        help_text=_('Слаг — это вариант названия, подходящий для URL. '
                    'Обычно содержит только латинские буквы в нижнем регистре, цифры и дефисы.'))
    content = models.TextField(
        _('Контент'),)
    excerpt = models.TextField(
        _('Описание'),
        blank=True,
        help_text=_('По Умолчанию первый абзац Контента, при необходимости можно изменить.'))
    main = models.BooleanField(
        _('Главная страница'),
        default=False,
        help_text=_('Решает будет ли запись видна на главной странице.'))
    ordering = models.SmallIntegerField(
        _('Сортировка'),
        default=0,
        blank=True,
        null=True)
    hit_count_generic = GenericRelation(
        HitCount,
        object_id_field='object_pk',
        related_query_name='hit_count_generic_relation')
    thumbnail = models.ImageField(
        _('Миниатюра'),
        blank=True,
        null=True)
    video_link = models.TextField(
        _('Video from YpuTube or Vimeo'),
        blank=True,
        default='')
    big_thumbnail = models.BooleanField(
        _('Большая миниатюра'),
        default=False,
        help_text=_('Если отмечено, на превью будет большая миниатюра.'))
    thumbnail_big = ImageSpecField(
        source='thumbnail',
        processors=[ResizeToFit(width=620)],
        format='JPEG')
    thumbnail_small = ImageSpecField(
        source='thumbnail',
        processors=[ResizeToFill(100, 100)],
        format='JPEG')

    tags = TaggableManager(blank=True)

    class Meta:
        ordering = ["-created_at"]
        verbose_name = _('Пост')
        verbose_name_plural = _('Посты')

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("blog:detail", kwargs={"slug": self.slug, "id": self.id})

    def save(self, *args, **kwargs):
        if self.slug == '':
            self.slug = slugify(unidecode(self.title)[:60])
        if self.thumbnail is None or self.thumbnail == '':
            self.thumbnail = get_image(self.content)
        if self.excerpt == '':
            self.excerpt = strip_tags(get_excerpt(self.content))

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

    def get_conttent_type(self):
        conttent_type = ContentType.objects.get_for_model(self.__class__)
        return conttent_type
Ejemplo n.º 24
0
class Tour(models.Model):
    
    name = models.CharField(max_length=250)
    alias = models.CharField(max_length=250, unique=True)  # url-safe
    date_start = models.DateField('Tour Started', null=True)
    track = MultiLineStringField(null=True, blank=True)
    #date_end = models.CharField('Tour Finished', null=True)
    #countries = models.ManyToMany(Country, blank=True)
    color = RGBColorField(default='#000000')
    #length = models.FloatField(blank=True)
    img = models.ImageField(upload_to='header', null=True, blank=True)
    img_thumb = ImageSpecField(source='img', processors=[ResizeToFill(100,100)],
                                format='JPEG', options={'quality': 60})
    #tourlog = models.TextField(blank=True)  # html or md content?
    text = models.TextField(blank=True, null=True)
    # bericht = MarkdownxField(blank=True, null=True)
    bericht = RichTextUploadingField(blank=True, null=True)
    listed = models.BooleanField(default=True)
    short_text = models.CharField(max_length=600, default='Kurzbeschreibung')


    def __str__(self):
        """
        Diese Funktion wird automatisch von python/django aufgerufen um
        ein Objekt zu bennen.
        """
        return self.name

    def get_duration(self):
        """
        returns duration of the tour if start and finish date are set correct.
        :return duration: <datetime.timedelta>
        """
        try:
            #duration = date_start - date_end
            duration = 5
        except:
            duration = dt.timedelta(days=0)
        return duration

    @property
    def dauer(self):
        """Berechnet die anzahl der tage aus start-enddatum oder anzahl der tagebuch einträge
        """
        try:
            duration = self.date_finish - self.date_start
            days = duration.days
        except:
            from logbuch.models import Logbucheintrag
            logs = Logbucheintrag.objects.filter(tour=self)
            days = len(logs)
        return days

    @property
    def strecke(self):
        """Berechnet strecke als summe aller tageskilometer"""
        from logbuch.models import Logbucheintrag
        logs = Logbucheintrag.objects.filter(tour=self)
        km = 0
        for log in logs:
            try:
                km += log.strecke
            except:
                pass
        return km

    @property
    def hoehe(self):
        """Hoehe als summe aller tagesdaten"""
        from logbuch.models import Logbucheintrag
        logs = Logbucheintrag.objects.filter(tour=self)
        hm = 0
        for log in logs:
            try:
                hm += log.hoehe
            except:
                pass
        return hm

    def bericht_html(self):
        return markdownify(self.bericht)
Ejemplo n.º 25
0
class Images(models.Model):
    photo = ProcessedImageField(upload_to=user_path,
                                processors=[ResizeToFill(80, 80)],
                                format='JPEG',
                                options={'qulity': 60},
                                null=True)
Ejemplo n.º 26
0
class User(models.Model):
    gender = (
        ('male', "男"),
        ('female', "女"),
    )
    # zone = models.OneToOneField(to='forum.Zone', to_field='id', null=True, on_delete=models.CASCADE)
    avatar = ProcessedImageField(verbose_name='头像',
                                 upload_to='user_avatar/',
                                 blank=True,
                                 null=False,
                                 default='avatar.png',
                                 processors=[ResizeToFill(150, 150)])
    name = models.CharField(verbose_name='用户名', max_length=128, unique=True)
    age = models.IntegerField(verbose_name='年龄', blank=True, null=True)
    password = models.CharField(verbose_name='密码', max_length=256)
    email = models.EmailField(verbose_name='邮箱', unique=True)
    sex = models.CharField(verbose_name='性别',
                           max_length=32,
                           choices=gender,
                           default="男")
    school = models.CharField(verbose_name='学校',
                              max_length=128,
                              null=True,
                              blank=True)
    major = models.CharField(verbose_name='专业',
                             max_length=128,
                             null=True,
                             blank=True)
    is_admin = models.BooleanField(verbose_name='管理员', default=False)
    c_time = models.DateTimeField(verbose_name='注册时间', auto_now_add=True)
    exp = models.IntegerField(verbose_name='经验值', default=0)
    level = models.IntegerField(verbose_name='等级', default=1)
    is_ban = models.BooleanField(verbose_name='禁言', default=False)
    is_read = models.BooleanField(verbose_name='已阅读新手教程', default=False)
    levelname = models.CharField(verbose_name='称号',
                                 default='新手',
                                 max_length=128)

    def save(self):
        if self.avatar is None:
            self.avatar = 'avatar.png'
        if int(self.exp) < 0:
            self.exp = 0
        self.level = int(math.sqrt(int(self.exp)) // 10 + 1)
        if self.level <= 2:
            self.levelname = '新手'
        elif self.level <= 4:
            self.levelname = '咸鱼'
        elif self.level <= 6:
            self.levelname = '熟练'
        elif self.level <= 8:
            self.levelname = '高手'
        elif self.level <= 10:
            self.levelname = '水怪'
        else:
            self.levelname = '水怪'
            self.level = 10
        if self.is_admin:
            self.is_read = True

        super(User, self).save()

    def __str__(self):
        return self.name

    class Meta:
        ordering = ["-c_time"]

    def get_absolute_url(self):
        # return reverse('space', args=str(self.id))
        return reverse('space', kwargs={"id": str(self.id)})
Ejemplo n.º 27
0
class Film(models.Model):
    CERTIFICATES = [
        ("U", "U"),
        ("PG", "PG"),
        ("12A", "12A"),
        ("12", "12"),
        ("15", "15"),
        ("18", "18"),
        ("TBC", "TBC"),
    ]
    name = models.CharField(max_length=100, null=True)
    director = models.CharField(max_length=100, null=True)
    cast = models.CharField(max_length=100, null=True)
    country = models.CharField(max_length=50, null=True)
    year = models.CharField(max_length=10, null=True)
    certificate = models.CharField(max_length=10,
                                   choices=CERTIFICATES,
                                   null=True)
    length = models.PositiveIntegerField(
        null=True,
        help_text="In minutes",
    )
    trailer = models.URLField(max_length=100,
                              help_text="Youtube or Vimeo link",
                              blank=True,
                              null=True)
    copy = HTMLField("Text",
                     help_text="Only if the screening needs special copy",
                     null=True)
    quote = models.TextField(max_length=500, blank=True)
    quote_source = models.CharField(max_length=100, blank=True)
    image = models.ImageField(
        default="default.jpg",
        help_text="Dimensions 1200px+ width work best",
        upload_to="films",
    )
    image_credit = models.CharField(max_length=100, blank=True)
    slug = models.SlugField(default="film", editable=False)
    image_thumbnail = ImageSpecField(
        source="image",
        processors=[ResizeToFill(350, 350)],
        format="JPEG",
        options={"quality": 100},
    )

    def __str__(self):
        return self.name

    class Meta:
        ordering = ["name"]

    def get_absolute_url(self):
        kwargs = {"slug": self.slug, "pk": self.pk}
        return reverse("film-detail", kwargs=kwargs)

    def save(self, *args, **kwargs):
        value = self.name
        self.slug = slugify(value)
        super().save(*args, **kwargs)

        img = Image.open(self.image.path)

        if img.width > 1400 or img.height > 1000:
            img.thumbnail((1400, 1000), Image.ANTIALIAS)
            img.save(self.image.path, optimize=True)
Ejemplo n.º 28
0
class AdminThumbnailSpec(ImageSpec):
    processors = [ResizeToFill(100, 100)]
    format = 'JPEG'
    options = {'quality': 90 }
Ejemplo n.º 29
0
class Project(models.Model):
    """
    Project model. Stores basic metadata, information about the project,
    donations, energy impact, goals, and info about the organization.

    Note about project statuses: there are five kinds of statuses that a
    project can have, and we show projects to different users in different
    ways based on their status.

    When an ambassador or admin first creates a project, it becomes DRAFTED,
    which means that it's a draft and can be edited, but is not in a complete
    state yet (description may need editing, etc). Eventualy the ambassador
    can propose the project for review from the admins, at which time it becomes
    PROPOSED. A proposed project is viewable by admins in their dashboard, as
    well as by the ambassadors that created it.

    When an admin approves a project, it becomes STAGED, which means it is ready
    to go but is not active yet, and as such is not viewable by the public. Staged
    projects are also visible to all admins in their dashboards. When it's time
    for the project to go live and start accepting donations, the admin can mark
    it as ACTIVE, which means it will actually be public and people can donate to
    it. When a project is done, the admin can mark it as COMPLETED, at which point
    it will stop accepting donations and start using repayments.
    """
    ACTIVE = 'AC'
    STAGED = 'ST'
    PROPOSED = 'PR'
    COMPLETED = 'CO'
    DRAFTED = 'DR'
    PROJECT_STATUS_CHOICES = (
        (ACTIVE, 'Active'),
        (STAGED, 'Staged'),
        (PROPOSED, 'Proposed'),
        (COMPLETED, 'Completed'),
        (DRAFTED, 'Drafted'),
    )
    LESS_THAN_ONE_DAY_LEFT_STATEMENT = "only hours left"
    NO_DAYS_LEFT_STATEMENT = "deadline reached"

    funding_goal = models.DecimalField(
        max_digits=15,
        decimal_places=2,
        help_text='How much do you aim to raise for this project?')
    total_kwh_value = models.DecimalField(
        max_digits=15,
        decimal_places=2,
        default=0,
        help_text=
        'How much is the total kWH value for 25 years to this project?')
    project_url = models.CharField(
        max_length=255,
        null=True,
        blank=False,
        help_text='How to show project url for this project?')
    title = models.CharField(
        max_length=255, help_text='How would you like to title this project?')
    tagline = models.CharField(
        max_length=100,
        null=True,
        blank=False,
        help_text=
        'Select a short tag line that describes this project. (No more than 100 characters.)'
    )
    video_url = models.URLField(
        'Video URL',
        max_length=255,
        blank=False,
        help_text='Link to a Youtube video about the project or community.',
    )
    # power output of array in kilowatts
    impact_power = models.FloatField(
        'Expected Killowatt Output',
        help_text=
        'What is the expected output in killowatts of the proposed solar array?'
    )
    # solar log graphics url
    solar_url = models.URLField(
        'Solar Log Graphics URL',
        max_length=255,
        blank=True,
        help_text=
        'This can be found by going to http://home.solarlog-web.net/, going to the \
            solar log profile for your site, and clicking on the Graphics sub-page. Copy and paste \
            the URL in the address bar into here.')
    location = models.CharField(
        'Organization Address',
        max_length=255,
        help_text=
        'What is the address of the organization where the solar panels will be installed?'
    )
    # latitude and longitude of the organization location
    location_latitude = models.DecimalField(max_digits=17,
                                            decimal_places=14,
                                            default=0.0)
    location_longitude = models.DecimalField(max_digits=17,
                                             decimal_places=14,
                                             default=0.0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    end_date = models.DateField(
        help_text='When will this crowdfunding project end?')
    # the start date of a project is whenever the project becomes live,
    # so we have to set it dynamically. Accordingly, the start_date
    # field is blank=True.
    start_date = models.DateField(blank=True, null=True)
    project_status = models.CharField(max_length=2,
                                      choices=PROJECT_STATUS_CHOICES,
                                      default=DRAFTED)
    cover_photo = ProcessedImageField(
        upload_to='covers/',
        processors=[ResizeToFill(1200, 500)],
        format='JPEG',
        options={'quality': 80},
        default=None,
        help_text=
        'Choose a beautiful high resolution image to represent this project.',
        blank=False,
    )
    preview_photo = ImageSpecField(
        source='cover_photo',
        processors=[ResizeToFill(400, 300)],
        format='JPEG',
        options={'quality': 80},
    )
    org_start_date = models.DateField(
        'Organization Founding Date',
        blank=True,
        null=True,
        help_text='When was the organization being helped established?')

    org_name = models.CharField(
        'Organization Name',
        max_length=255,
        help_text='What is the name of the organization being helped?')

    people_affected = models.PositiveIntegerField(
        default=0,
        help_text='How many people will be impacted by this project?')

    mission_statement = models.TextField(
        'Organization Mission',
        help_text=
        'What is the mission statement of the organization being helped by this project?',
    )

    org_about = models.TextField(
        'Organization Description',
        help_text=
        'Elaborate more about the organization, what it does, who it serves, etc.'
    )

    description = RichTextField(
        'Project description',
        help_text=
        'This is the body of content that shows up on the project page.')

    donors = models.ManyToManyField(RevolvUserProfile, blank=True)

    created_by_user = models.ForeignKey(RevolvUserProfile,
                                        related_name='created_by_user')

    ambassadors = models.ManyToManyField(RevolvUserProfile,
                                         related_name='ambassadors',
                                         null=True)

    # energy produced in kilowatt hours
    actual_energy = models.FloatField(default=0.0)
    internal_rate_return = models.DecimalField(
        'Internal Rate of Return',
        max_digits=6,
        decimal_places=3,
        default=0.0,
        help_text='The internal rate of return for this project.')

    # solar data csv files
    daily_solar_data = models.FileField(blank=True,
                                        null=True,
                                        upload_to="projects/daily/")
    monthly_solar_data = models.FileField(blank=True,
                                          null=True,
                                          upload_to="projects/monthly/")
    annual_solar_data = models.FileField(blank=True,
                                         null=True,
                                         upload_to="projects/annual/")

    monthly_reinvestment_cap = models.FloatField(blank=True, default=0.0)
    is_paid_off = models.BooleanField(blank=True, default=False)

    objects = ProjectManager()
    factories = ImportProxy("revolv.project.factories", "ProjectFactories")

    def has_owner(self, creator):
        return self.created_by_user == creator

    def approve_project(self):
        self.project_status = Project.ACTIVE
        if self.start_date is None:
            self.start_date = datetime.date.today()
        self.save()
        return self

    # TODO(noah): change this verbiage. we should probably call the STAGED -> ACTIVE
    # transition "activate_project" and the PROPOSED -> STAGED transition "approve_project"
    # instead.
    def stage_project(self):
        self.project_status = Project.STAGED
        self.save()
        return self

    def unapprove_project(self):
        self.project_status = Project.STAGED
        self.start_date = None
        self.save()
        return self

    def propose_project(self):
        self.project_status = Project.PROPOSED
        self.save()
        return self

    def deny_project(self):
        self.project_status = Project.DRAFTED
        self.save()
        return self

    def complete_project(self):
        self.project_status = Project.COMPLETED
        self.save()
        return self

    def mark_as_incomplete_project(self):
        self.project_status = Project.ACTIVE
        self.save()
        return self

    def update_categories(self, category_list):
        """ Updates the categories list for the project.

        :category_list The list of categories in the submitted form
        """
        # Clears all the existing categories
        self.category_set.clear()

        # Adds the list of categories to the project
        for category in category_list:
            category_object = Category.objects.get(title=category)
            self.category_set.add(category_object)

    def get_absolute_url(self):
        return reverse("project:view", kwargs={"title": str(self.project_url)})

    def get_organic_donations(self):
        return self.payment_set.exclude(user__isnull=True).filter(
            entrant__pk=models.F('user__pk'))

    def proportion_donated(self, user):
        """
        :return:
            The proportion that this user has organically donated to this
            project as a float in the range [0, 1] (inclusive)
        """
        user_donation = Payment.objects.donations(
            project=self, user=user, organic=True).aggregate(
                models.Sum('amount'))['amount__sum'] or 0.0
        prop = user_donation / self.amount_donated_organically
        assert 0 <= prop <= 1, "proportion_donated is incorrect!"
        return prop

    def get_anonymous_donors_count(self):
        """
        Total number of anonymous donors count for project
        :return:
        Return anonymous donors count for project
        """
        user_id = User.objects.get(username='******').pk
        anonymous_user = RevolvUserProfile.objects.get(user_id=user_id)
        return Payment.objects.donations(anonymous_user,
                                         self).values("user").count()

    def total_donors(self):
        """
        Total number of donors for the project. This include distinct
        number of donors to project and all anonymous donors for the project
        :return:
            Return total number of donors
        """
        user_id = User.objects.get(username='******').pk
        anonymous_user = RevolvUserProfile.objects.get(user_id=user_id)

        donor_count = Payment.objects.filter(
            project=self, admin_reinvestment__isnull=True).exclude(
                user=anonymous_user).values("user").distinct().count()
        anonymous_donors_count = Payment.objects.filter(
            project=self, user=anonymous_user).values("user").count()

        return donor_count + anonymous_donors_count

    def total_donors_user(self):
        user_id = User.objects.get(username='******').pk
        anonymous_user = RevolvUserProfile.objects.get(user_id=user_id).id
        payments = Payment.objects.filter(project=self, admin_reinvestment__isnull=True).distinct('user__id')\
            .exclude(user_id=anonymous_user)
        return payments

    @property
    def amount_donated_organically(self):
        """
        :return: the current total amount that has been organically donated to
        this project, as a float.
        """
        return self.get_organic_donations().aggregate(
            models.Sum('amount'))["amount__sum"] or 0.0

    @property
    def location_street(self):
        """
        :return: a string of the street name of the location of this project.
        If the project location is malformed, will return an empty string.
        """
        try:
            return self.location.split(',')[0]
        except IndexError:
            return ""

    @property
    def location_city_state_zip(self):
        """
        :return: a string of the city, state, and zip code of the location of this project.
        If the project location is malformed, will return an empty string.
        """
        try:
            pieces = self.location.split(',')
            if len(pieces) >= 3:
                return pieces[1] + "," + pieces[2]
            elif len(pieces) == 2:
                return pieces[1]
            return pieces[0]
        except IndexError:
            return ""

    @property
    def amount_donated(self):
        """
        :return: the current total amount that has been donated to this project,
            as a float.
        """
        return self.payment_set.aggregate(
            models.Sum('amount'))["amount__sum"] or 0.0

    @property
    def amount_left(self):
        """
        :return: the current amount of money needed for this project to
            reach its goal, as a float.
        """
        amt_left = float(self.funding_goal) - self.amount_donated
        if amt_left < 0:
            return 0.0
        return amt_left

    @property
    def amount_repaid(self):
        """
        :return: the current amount of money repaid by the project to RE-volv.
        """
        return self.adminrepayment_set.aggregate(
            models.Sum('amount'))["amount__sum"] or 0.0

    @property
    def total_amount_to_be_repaid(self):
        """
        :return: the total amount of money to be repaid by the project to RE-volv.
        """
        # TODO (https://github.com/calblueprint/revolv/issues/291): Actually
        # calculate this amount based off of interest, but using the project's
        # funding goal is sufficient for now.
        return self.funding_goal

    @property
    def rounded_amount_left(self):
        """
        :return: The amount needed to complete this project, floored to the nearest
            dollar.

        Note: if for some reason the amount left is negative, this will perform a
        ceiling operation instead of a floor, but that should never happen.
        """
        return int(self.amount_left)

    @property
    def partial_completeness(self):
        """
        :return: a float between 0 and 1, representing the completeness of this
            project with respect to its goal (1 if exactly the goal amount, or
            more, has been donated, 0 if nothing has been donated).
        """
        ratio = self.amount_donated / float(self.funding_goal)
        return min(ratio, 1.0)

    @property
    def percent_complete(self):
        """
        :return: a floored int between 0 and 100, representing the completeness of this
            project with respect to its goal (100 if exactly the goal amount, or
            more, has been donated, 0 if nothing has been donated).
        """
        return int(self.partial_completeness * 100)

    def partial_completeness_as_js(self):
        return unicode(self.partial_completeness)

    @property
    def percent_repaid(self):
        """
        :return: a floored int between 0 and 100, representing the amount repaid
        in respect to its repayment goal (100 if exactly the goal amount, or
        more, has been donated, 0 if nothing has been donated).
        """
        return int(self.partial_repayment * 100)

    @property
    def partial_repayment(self):
        """
        :return: a float between 0 and 1, representing the repayment progress
        of this project with respect to the repayment goal (1 if exactly the
        goal amount, or more, has been donated, 0 if nothing has been donated).
        """
        ratio = self.amount_repaid / float(self.total_amount_to_be_repaid)
        return min(ratio, 1.0)

    def partial_repayment_as_js(self):
        return unicode(self.partial_repayment)

    @property
    def total_days(self):
        """
        :return the total length of the campaign of this project,
        or None if the project hasn't started yet.

        Note: if a project's campaign starts and ends on the same day, it is
        defined to be one day long, not zero days long.
        """
        if self.start_date is None:
            return None
        return max((self.end_date - self.start_date).days + 1, 0)

    @property
    def days_until_end(self):
        """
        :return: the difference between today and the end date of this project.
        May be negative.
        """
        return (self.end_date - datetime.date.today()).days

    @property
    def days_so_far(self):
        """
        :return: the integer number of days that have passed since
        this project's campaign began, or None if it has not started
        yet.
        """
        if self.start_date is None:
            return None
        difference = (datetime.date.today() - self.start_date).days
        if difference < 0:
            return 0
        if difference > self.total_days:
            return self.total_days
        return difference

    @property
    def days_left(self):
        """
        :return: the integer number of days until the end of this project,
        or 0 if the project's campaign has finished.
        """
        return max(self.days_until_end, 0)

    def formatted_days_left(self):
        """
        :return: the number of days left in this project's campaign, formatted
        according to how many days left there are. This includes a default message
        when there are 0 days left instead of just saying "0".

        TODO: this should probably be moved to the template logic.
        """
        days_left = self.days_until_end
        if days_left == 1:
            return "1 day left"
        if days_left == 0:
            return self.LESS_THAN_ONE_DAY_LEFT_STATEMENT
        if days_left < 0:
            return self.NO_DAYS_LEFT_STATEMENT
        return unicode(days_left) + " days left"

    @property
    def is_active(self):
        return self.project_status == Project.ACTIVE

    @property
    def is_proposed(self):
        return self.project_status == Project.PROPOSED

    @property
    def is_drafted(self):
        return self.project_status == Project.DRAFTED

    @property
    def is_staged(self):
        return self.project_status == Project.STAGED

    @property
    def is_completed(self):
        return self.project_status == Project.COMPLETED

    @property
    def status_display(self):
        return dict(Project.PROJECT_STATUS_CHOICES)[self.project_status]

    @property
    def categories(self):
        return [category.title for category in self.category_set.all()]

    @property
    def updates(self):
        """
        :return: The set of all ProjectUpdate models associated with this project.
        """
        return self.updates.all()

    @property
    def donation_levels(self):
        """
        :return: The set of all DonationLevel models associated with this project.
        """
        return self.donationlevel_set.all()

    @property
    def statistics(self):
        """
        Return a revolv.project.stats.KilowattStatsAggregator for this project.
        Having this as a property is usefule in templates where we need to display
        statistics about the project (e.g. lbs carbon saved, $ saved, etc).
        """
        return KilowattStatsAggregator.from_project(self)

    def add_update(self, text):
        update = ProjectUpdate(update_text=text, project=self)
        update.save()

    @property
    def reinvest_amount_left(self):
        """
        :return max reinvestment can be receive
        """
        return min(self.amount_left, self.monthly_reinvestment_cap)

    def get_statistic_for_project(self):
        user_impact = 0
        project_funding_total = (int)(self.funding_goal)
        amount_donated = (int)(self.amount_donated)
        project_total_kwh_value = self.total_kwh_value
        total_carbon_avoided = float(project_total_kwh_value) * 1.5
        per_doller_co2_avoided = total_carbon_avoided / project_funding_total
        project_impact = per_doller_co2_avoided * amount_donated
        user_impact += project_impact
        return user_impact

    def paid_off(self):
        """Set the project PAID_OFF flag
        """
        self.is_paid_off = True
        self.save()

    def __unicode__(self):
        return self.title + '-' + self.project_status
class Background(ImageSpec):
    processors = [ResizeToFill(1920, 1200)]
    format = "JPEG"
    options = {"quality": 60}