예제 #1
0
파일: models.py 프로젝트: komsihon/Project2
class SmartCategory(SmartObject):
    UPLOAD_TO = 'commarketing/smart_categories'

    image = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=500)
    description = models.TextField(blank=True,
                                   help_text=_("Description of the category."))
    badge_text = models.CharField(
        max_length=25,
        blank=True,
        help_text=_("Text in the badge that appears on the smart category. "
                    "<strong>E.g.:</strong> -20%, -30%, New, etc."))
    appear_in_menu = models.BooleanField(
        default=False,
        help_text=_("Smart Category will appear in main menu if checked."))
    show_on_home = models.BooleanField(
        _("Show on home ?"),
        default=True,
        help_text=_(
            "Check to show a preview of items contained on home page."))

    def _get_module(self):
        try:
            return Module.objects.get(slug=self.slug)
        except:
            pass

    module = property(_get_module)
예제 #2
0
파일: models.py 프로젝트: komsihon/Project4
class SmartCategory(SmartObject):
    UPLOAD_TO = 'web/smart_categories'

    content_type = models.CharField(
        max_length=15,
        choices=SMART_CATEGORY_TYPE_CHOICES,
        help_text=_("Whether this menu points to a page, a list of items."))
    image = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=500)
    description = models.TextField(blank=True,
                                   help_text=_("Description of the category."))
    badge_text = models.CharField(
        max_length=25,
        blank=True,
        help_text=_("Text in the badge that appears on the smart category. "
                    "<strong>E.g.:</strong> -20%, -30%, New, etc."))
    appear_in_menu = models.BooleanField(
        default=False,
        help_text=_("Smart Category will appear in main menu if checked."))
    target_url = models.URLField(blank=True)

    def _get_module(self):
        try:
            return Module.objects.get(slug=self.slug)
        except:
            pass

    module = property(_get_module)
예제 #3
0
class AbstractProduct(Model):
    """
    Abstract definition of product a customer may subscribe to
    """
    IMAGE_UPLOAD_TO = 'billing/product_images'
    name = models.CharField(
        max_length=100,
        unique=True,
        db_index=True,
        help_text="Name of the product as advertised to the customer.")
    slug = models.SlugField(unique=True, db_index=True)
    short_description = models.TextField(
        blank=True,
        help_text=_("Short description understandable by the customer."))
    duration = models.IntegerField(
        default=30,
        help_text="Number of days covered by the cost this product.")
    duration_text = models.CharField(
        max_length=30,
        blank=True,
        null=True,
        help_text=_(
            "How you want the customer to see the duration.<br>"
            "Eg:<strong>1 month</strong>, <strong>3 months</strong>, etc."))
    cost = models.FloatField(
        help_text=_("Cost of the product on the duration set previously."))
    image = MultiImageField(upload_to=IMAGE_UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=800)
    details = models.TextField(
        blank=True, help_text=_("Detailed description of the product."))
    is_active = models.BooleanField(
        default=True, help_text=_("Check to make the product active."))
    is_main = models.BooleanField(
        default=False, help_text=_("Check to make the product active."))
    is_one_off = models.BooleanField(
        default=False,
        help_text=_("One off product generates a one off subscription."))
    order_of_appearance = models.IntegerField(default=1)

    class Meta:
        abstract = True

    def __unicode__(self):
        from ikwen.core.utils import get_service_instance
        config = get_service_instance().config
        return u'%s: %s %.2f/%d days' % (self.name, config.currency_symbol,
                                         self.cost, self.duration)

    def get_details(self):
        if not self.details:
            return 'N/A'
        return self.details
예제 #4
0
파일: models.py 프로젝트: komsihon/MoodsBox
class Album(AbstractWatchModel):
    artist = models.ForeignKey(Artist)
    title = models.CharField(max_length=100, db_index=True)
    slug = models.SlugField(db_index=True)
    cover = MultiImageField(upload_to='albums_covers',
                            required_width=300,
                            required_height=300,
                            allowed_extensions=['jpg', 'jpeg'],
                            blank=True,
                            null=True,
                            help_text=_("JPEG Image, 300 &times; 300px"))
    release = models.DateField(blank=True, null=True, db_index=True)
    archive = FileField(upload_to='albums_covers',
                        allowed_extensions=['zip', 'rar', '7z'],
                        blank=True,
                        null=True)
    cost = models.IntegerField(default=0)
    is_active = models.BooleanField(default=True)
    is_main = models.BooleanField(default=False)
    show_on_home = models.BooleanField(default=False)
    order_of_appearance = models.IntegerField(default=0)
    tags = models.TextField(blank=True, null=True)

    turnover_history = ListField()
    earnings_history = ListField()
    units_sold_history = ListField()

    total_turnover = models.IntegerField(default=0)
    total_earnings = models.IntegerField(default=0)
    total_units_sold = models.IntegerField(default=0)

    class Meta:
        unique_together = ('artist', 'title')

    def __unicode__(self):
        return "%s - %s (%d)" % (self.artist.name, self.title,
                                 self.release.year)

    def _get_image(self):
        return self.cover

    image = property(_get_image)

    def get_obj_details(self):
        return "XAF %s" % intcomma(self.cost)

    def to_dict(self):
        val = super(Album, self).to_dict()
        val['type'] = 'album'
        val['url'] = reverse('mediashop:music_item_detail',
                             args=(self.artist.slug, self.slug))
        image_url = self.cover.name if self.cover.name else Service.LOGO_PLACEHOLDER
        val['image'] = getattr(settings, 'MEDIA_URL') + image_url
        return val
예제 #5
0
파일: models.py 프로젝트: kiranHR/Project1
class Photo(models.Model):
    UPLOAD_TO = 'photos'
    image = MultiImageField(upload_to=UPLOAD_TO, max_size=800)

    def delete(self, *args, **kwargs):
        try:
            os.unlink(self.image.path)
            os.unlink(self.image.small_path)
            os.unlink(self.image.thumb_path)
        except:
            pass
        super(Photo, self).delete(*args, **kwargs)

    def __unicode__(self):
        return self.image.url
예제 #6
0
class Post(Model):
    UPLOAD_TO = 'blog/blog_img'
    category = models.ForeignKey(PostCategory, blank=True, null=True)
    title = models.CharField(max_length=240, blank=False, unique=True)
    summary = models.CharField(max_length=240, blank=True)
    slug = models.SlugField(max_length=240,
                            blank=False,
                            unique=True,
                            editable=False)
    image = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=800)
    entry = models.TextField()
    pub_date = models.DateField(default=datetime.now, editable=False)
    appear_on_home_page = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)
    member = models.ForeignKey(Member, editable=False)
    tags = models.CharField(max_length=255, blank=True)
    likes = models.SmallIntegerField(default=0, editable=False)
    linked_document = models.FileField(blank=True, upload_to=UPLOAD_TO)
    rand = models.FloatField(default=random.random,
                             db_index=True,
                             editable=False)
    consult_count = models.IntegerField(default=10)

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

    def get_path(self):
        folders = '%s' % (self.slug)
        return '%s' % folders

    def get_uri(self):
        base_uri = getattr(settings, 'BASE_URI')
        return '%s%s' % (base_uri, self.get_path())

    def get_image_url(self):
        if self.image:
            return self.image.url
        else:
            return None

    def delete(self, *args, **kwargs):
        for photo in self.image:
            photo.delete(*args, **kwargs)
예제 #7
0
파일: models.py 프로젝트: komsihon/Project4
class Banner(SmartObject):
    """
    Any of banners owner of the site may use as Slide, Popup, etc
    to market some products on the site.
    """
    UPLOAD_TO = 'web/banners'

    image = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=1920)
    display = models.CharField(
        max_length=30,
        choices=DISPLAY_CHOICES,
        default=SLIDE,
        help_text="How the image is shown on the site. Can be one of "
        "<strong>Slide, Popup, FullWidthSection</strong> "
        "or <strong>FullScreenPopup</strong>")
    # location = models.CharField(max_length=60, blank=True,
    #                             help_text="Bloc of the page where banner should appear. "
    #                                       "Applies to Default banners only.")
    cta = models.CharField(verbose_name=_("Call To Action"),
                           max_length=30,
                           blank=True,
                           help_text=_(
                               'Action you want you visitors to undertake. '
                               '<em><strong>E.g:</strong> "Buy Now"</em>'))
    description = models.TextField(blank=True,
                                   help_text=_("Description of the category."))
    target_url = models.URLField(blank=True)

    class Meta:
        unique_together = (
            'slug',
            'display',
        )
        ordering = (
            '-id',
            'slug',
        )
        permissions = (("ik_manage_marketing", _("Manage marketing tools")), )
예제 #8
0
파일: models.py 프로젝트: komsihon/MoodsBox
class Artist(AbstractWatchModel):
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(unique=True)
    photo = MultiImageField(upload_to='artists_photos',
                            required_width=300,
                            required_height=300,
                            allowed_extensions=['jpg', 'jpeg'],
                            blank=True,
                            null=True,
                            help_text=_("JPEG Image, 300 &times; 300px"))
    is_active = models.BooleanField(default=True)
    tags = models.TextField(blank=True, null=True)

    turnover_history = ListField()
    earnings_history = ListField()
    units_sold_history = ListField()

    total_turnover = models.IntegerField(default=0)
    total_earnings = models.IntegerField(default=0)
    total_units_sold = models.IntegerField(default=0)

    def __unicode__(self):
        return self.name

    def _get_image(self):
        return self.photo

    image = property(_get_image)

    def to_dict(self):
        val = super(Artist, self).to_dict()
        val['type'] = 'artist'
        val['url'] = reverse('mediashop:artist_detail', args=(self.slug, ))
        image_url = self.photo.name if self.photo.name else Service.LOGO_PLACEHOLDER
        val['image'] = getattr(settings, 'MEDIA_URL') + image_url
        return val
예제 #9
0
파일: models.py 프로젝트: komsihon/Project8
class Movie(Media):
    objects = MongoDBManager()
    MAX_RECENT = 96
    TOTAL_RECOMMENDED = 12  # Number of items to recommend in a case where there are enough to recommend
    MIN_RECOMMENDED = 8  # Number of items to recommend in case where there are not enough after the normal algorithm
    slug = models.SlugField(
        unique=True,
        help_text=_(
            "Auto-filled. If edited, use only lowercase letters and -. Space is not allowed"
            " Eg: <strong>tomorrow-never-dies</strong>"))
    release = models.DateField(
        blank=True,
        null=True,
        help_text=_("Date of release of movie in country of origin."))
    synopsis = models.TextField(blank=True)
    resource = models.CharField(
        verbose_name=_("Media resource"),
        max_length=255,
        blank=True,
        help_text=_(
            "Filename (Eg: <strong>Avatar.mp4</strong>) or "
            "URL (Eg: <strong>http://youtube.com/watch?v=2nYwryHPSs</strong>)")
    )
    resource_mob = models.CharField(
        verbose_name=_("Mobile media resource"),
        max_length=255,
        blank=True,
        help_text=_(
            "Filename (Eg: <strong>Avatar.mob.mp4</strong>) or "
            "URL (Eg: <strong>http://m.youtube.com/watch?v=2nYwryHPSs</strong>). "
            "Leave blank to copy the same value as above"))
    poster = MultiImageField(upload_to='movies', blank=True, null=True)
    price = models.PositiveIntegerField(
        default=0,
        editable=is_content_vendor,
        help_text=_("Cost of sale of this movie to VOD operators."))
    view_price = models.FloatField(
        default=0, help_text=_("Cost to view this movie in streaming."))
    download_price = models.FloatField(
        default=0, help_text=_("Cost to download this movie."))
    trailer_resource = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text=_(
            "Filename (Eg: <strong>Avatar.mob.mp4</strong>), URL "
            "Embed code (Eg: <strong>&lt;iframe src='...'&gt;&lt;/iframe&gt;</strong>) "
            "for trailer of this movie."))
    provider = models.ForeignKey(Service,
                                 editable=False,
                                 blank=True,
                                 null=True,
                                 related_name='+',
                                 help_text=_("Provider of this movie."))
    fake_orders = models.IntegerField(
        default=0,
        help_text=_(
            "Random value you want customers to think the movie was ordered "
            "that number of times."))
    orders = models.IntegerField(
        default=0, help_text=_("Number of times movie was actually ordered."))
    fake_clicks = models.PositiveIntegerField(
        default=0,
        help_text=_("Random value you want customers to think the movie was "
                    "viewed that number of times."))
    visible = models.BooleanField(
        default=True,
        help_text=_("Check if you want the movie to be visible on the site."))
    categories = ListField(EmbeddedModelField('Category'),
                           help_text=_("Categories the movie is part of."))
    # Tells whether this Movie is part of an Adult category.
    # Set automatically upon Movie.save() by checking categories
    is_adult = models.BooleanField(default=False,
                                   verbose_name=_("Adult content"))
    groups = models.CharField(
        max_length=100,
        default='',
        blank=True,
        help_text=
        _("Group the movie belongs to (write lowercase). Will be used for suggestions "
          "Eg: Write <strong>matrix</strong> for all movies Matrix 1, 2 and 3"
          ))
    tags = models.CharField(
        max_length=150,
        help_text=
        _("Key words used to retrieve the movie in search. Typically title of movie written "
          "lowercase and main actors, all separated by space. Eg: <strong>matrix keanu reaves</strong>"
          ))
    # Random field used for random selections in MongoDB
    rand = models.FloatField(default=random.random,
                             db_index=True,
                             editable=False)

    owner_fk_list = ListField()

    count_history = ListField(
    )  # count can be the number of orders or views of this Media
    download_history = ListField()
    earnings_history = ListField()

    total_count = models.IntegerField(default=0)
    total_download = models.IntegerField(default=0)
    total_earnings = models.IntegerField(default=0)
    current_earnings = models.IntegerField(
        default=0,
        help_text=
        "Earnings generated by the movie since the last reset. Differs "
        "from total_earnings by the fact that it can be reset at times.")

    class Meta:
        if getattr(settings, 'IS_GAME_VENDOR', False):
            verbose_name = 'Product'

    def _get_display_orders(self):
        """
        Number of orders(based on fake_orders) of movie in a format suitable for display
        """
        if self.fake_orders < 1000:
            return self.fake_orders
        else:
            num500 = self.fake_orders / 500
            return "%d+" % (num500 * 500)

    display_orders = property(_get_display_orders)

    def _get_display_clicks(self):
        """
        Number of clicks(based on fake_clicks) of movie in a format suitable for display
        """
        if self.fake_clicks < 1000:
            return self.fake_clicks
        else:
            num500 = self.fake_clicks / 500
            return "%d+" % (num500 * 500)

    display_clicks = property(_get_display_clicks)

    def _get_categories_to_string(self):
        categories = [category.title for category in self.categories]
        return ", ".join(categories)

    categories_to_string = property(_get_categories_to_string)

    def _get_type(self):
        return "movie"

    type = property(_get_type)

    def _get_trailer(self):
        """
        Gets the trailer of this movie
        """
        if self.trailer_resource:
            return Trailer(title='',
                           slug='',
                           size=0,
                           duration=3,
                           resource=self.trailer_resource)

    trailer = property(_get_trailer)

    def _get_owner_list(self):
        owner_list = []
        for pk in self.owner_fk_list:
            try:
                owner_list.append(Member.objects.get(pk=pk))
            except:
                pass
        return owner_list

    owner_list = property(_get_owner_list)

    def to_dict(self):
        var = to_dict(self)
        var['poster'] = {
            'url':
            from_provider(self.poster.url, self.provider)
            if self.poster.name else 'default_poster.jpg',
            'small_url':
            from_provider(self.poster.small_url, self.provider)
            if self.poster.name else 'default_poster.jpg',
            'thumb_url':
            from_provider(self.poster.thumb_url, self.provider)
            if self.poster.name else 'default_poster.jpg'
        }
        var['type'] = self.type
        var['display_orders'] = self.display_orders
        var['display_clicks'] = self.display_clicks
        var['load'] = self.load
        var['display_load'] = self.display_load
        del (var['filename'])
        del (var['resource'])
        del (var['resource_mob'])
        del (var['synopsis'])
        del (var['provider_id'])
        del (var['visible'])
        del (var['fake_orders'])
        del (var['fake_clicks'])
        del (var['categories'])
        del (var['groups'])
        del (var['rand'])
        return var

    def __unicode__(self):
        return self.title
예제 #10
0
class Student(Model):
    UPLOAD_TO = 'foulassi/students'
    school = models.ForeignKey(Service,
                               blank=True,
                               null=True,
                               related_name='+',
                               default=get_service_instance)
    registration_number = models.CharField(_("Registration number"),
                                           blank=True,
                                           max_length=30,
                                           unique=True)
    first_name = models.CharField(_("First name"),
                                  max_length=100,
                                  db_index=True)
    last_name = models.CharField(_("Last name"), max_length=100, db_index=True)
    gender = models.CharField(_("Gender"),
                              max_length=15,
                              choices=GENDER_CHOICES,
                              db_index=True)
    dob = models.DateField(_("Date of birth"), db_index=True)
    pob = models.CharField(_("Place of birth"),
                           max_length=150,
                           blank=True,
                           null=True,
                           db_index=True)
    birthday = models.IntegerField(blank=True, null=True, db_index=True)
    photo = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=600,
                            small_size=200,
                            thumb_size=100,
                            editable=False)
    classroom = models.ForeignKey('school.Classroom',
                                  verbose_name=_("Classroom"))
    is_repeating = models.BooleanField(_("Repeats the class ?"), default=False)
    year_joined = models.IntegerField(
        _("Year joined"),
        default=get_school_year,
        db_index=True,
        help_text=_("Year when student joined this school"))
    score_history = ListField()
    school_year = models.IntegerField(default=get_school_year, db_index=True)
    is_confirmed = models.BooleanField(
        default=False)  # Confirmed student cannot be deleted again
    is_excluded = models.BooleanField(
        default=False
    )  # Excluded student does not appear in classroom student list
    tags = models.TextField(blank=True, null=True, db_index=True)
    my_kids_expiry = models.DateTimeField(blank=True, null=True)
    my_kids_expired = models.BooleanField(default=True)
    has_new = models.BooleanField(
        default=False,
        help_text="Whether there's a new information published on this student: "
        "score, discipline information or invoice.")

    def __unicode__(self):
        return self.last_name + ' ' + self.first_name

    def save(self, **kwargs):
        if not self.id:  # Generate registration number for newly created students
            self.generate_registration_number()
        if not self.birthday and self.dob:
            self.birthday = int(self.dob.strftime('%m%d'))
        super(Student, self).save(**kwargs)

    def get_score_list(self, subject, using='default'):
        from ikwen_foulassi.school.models import Score
        return Score.objects.using(using).filter(
            student=self, subject=subject).order_by('session')

    def set_has_new(self, using='default'):
        """
        Checks whether there's anything new about the Student and sets
        Student.has_new to True, else sets it to False.
        """
        from ikwen_foulassi.foulassi.models import Invoice
        from ikwen_foulassi.school.models import Score, DisciplineLogEntry, Assignment
        now = datetime.now()
        has_pending_assignment = Assignment.objects.using(using).filter(
            classroom=self.classroom, deadline__lt=now)
        has_pending_invoice = Invoice.objects.using(using).filter(
            student=self, status=Invoice.PENDING).count() > 0
        has_new_discipline_info = DisciplineLogEntry.objects.using(
            using).filter(student=self, was_viewed=False).count() > 0
        has_new_score = Score.objects.using(using).filter(
            student=self, was_viewed=False).count() > 0
        self.has_new = has_pending_assignment or has_pending_invoice or has_new_discipline_info or has_new_score

    def generate_registration_number(self):
        if self.registration_number:
            return
        school_year = str(get_school_year())[-2:]
        classroom = self.classroom
        level = classroom.level
        classroom_info = level.name[0] + level.name[-1] + classroom.name[0]
        inc = Student.objects.filter(classroom=self).count() + 1
        registration_number = ''
        while True:
            try:
                registration_number = "%s%s%s" % (school_year, classroom_info,
                                                  str(inc).zfill(3))
                Student.objects.get(
                    registration_number=registration_number.upper())
                inc += 1
            except:
                break
        self.registration_number = registration_number.upper()
예제 #11
0
파일: models.py 프로젝트: komsihon/Project2
class ProductCategory(AbstractWatchModel):
    """
    Category of :class:`kako.models.Product`. User must select the category from
    a list so, upon installation of the project some categories must be set.
    """
    UPLOAD_TO = 'kakocase/categories'
    PLACE_HOLDER = 'no_photo.png'
    name = models.CharField(_("name"),
                            max_length=100,
                            unique=True,
                            help_text=_("Name of the category."))
    slug = models.SlugField(unique=True, help_text=_("Slug of the category."))
    description = models.TextField(_("description"),
                                   blank=True,
                                   help_text=_("Description of the category."))
    badge_text = models.CharField(
        _("badge text"),
        max_length=25,
        blank=True,
        help_text=_("Text in the badge that appears on the category. "
                    "<strong>E.g.:</strong> -20%, -30%, New, etc."))
    appear_in_menu = models.BooleanField(
        _("appear in menu"),
        default=False,
        help_text=_("Category will appear in main menu if checked."))
    show_on_home = models.BooleanField(
        _("Show on home ?"),
        default=True,
        help_text=_("Check to show a preview of products on home page."))
    is_active = models.BooleanField(verbose_name="Active ?",
                                    default=True,
                                    help_text=_("Make it visible or no."))
    order_of_appearance = models.IntegerField(
        default=1, help_text=_("Order of appearance in a list of categories."))
    previews_count = models.IntegerField(
        _("elements in preview"),
        default=PRODUCTS_PREVIEWS_PER_ROW,
        help_text=_("Number of elements in the category preview on home page. "
                    "Must be a multiple of 4."))
    items_count = models.IntegerField(
        default=0,
        editable=False,
        help_text="Number of products in this category.")
    image = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=500)
    # A list of 366 integer values, each of which representing the number of items of this category
    # that were traded (sold or delivered) on a day out of the 366 previous (current day being the last)
    items_traded_history = ListField()
    turnover_history = ListField()
    earnings_history = ListField()
    orders_count_history = ListField()

    # SUMMARY INFORMATION
    total_items_traded = models.IntegerField(default=0)
    total_turnover = models.IntegerField(default=0)
    total_earnings = models.IntegerField(default=0)
    total_orders_count = models.IntegerField(default=0)

    class Meta:
        verbose_name_plural = 'product categories'

    def __unicode__(self):
        return self.name

    def report_counters_to_umbrella(self):
        try:
            umbrella_obj = ProductCategory.objects.using(UMBRELLA).get(
                slug=self.slug)
        except:
            umbrella_obj = ProductCategory.objects.using(UMBRELLA).create(
                name=self.name, slug=self.slug)
        set_counters(umbrella_obj)
        increment_history_field(umbrella_obj, 'items_traded_history')
        increment_history_field(umbrella_obj, 'turnover_history')
        increment_history_field(umbrella_obj, 'orders_count_history')
        umbrella_obj.save(using=UMBRELLA)

    def delete(self, *args, **kwargs):
        try:
            os.unlink(self.image.path)
            os.unlink(self.image.small_path)
            os.unlink(self.image.thumb_path)
        except:
            pass
        from ikwen_kakocase.commarketing.models import Banner, SmartCategory
        for banner in Banner.objects.all():
            try:
                banner.items_fk_list.remove(self.id)
                banner.items_count = banner.get_category_queryset().count()
                banner.save()
            except ValueError:
                pass
        for smart_category in SmartCategory.objects.all():
            try:
                smart_category.items_fk_list.remove(self.id)
                smart_category.items_count = smart_category.get_category_queryset(
                ).count()
                smart_category.save()
            except ValueError:
                pass
        super(ProductCategory, self).delete(*args, **kwargs)

    def get_visible_items(self):
        product_queryset = self.get_visible_products()
        service_queryset = self.get_visible_recurring_payment_services()
        if product_queryset.count() > 0:
            return list(product_queryset)
        else:
            return list(service_queryset)

    def get_visible_products(self):
        return self.product_set.filter(visible=True, is_duplicate=False)

    def get_visible_recurring_payment_services(self):
        return self.recurringpaymentservice_set.filter(visible=True)

    def get_suited_previews_count(self):
        count = len(self.get_visible_items()) / PRODUCTS_PREVIEWS_PER_ROW
        return count * PRODUCTS_PREVIEWS_PER_ROW
예제 #12
0
class Banner(Model):
    UPLOAD_TO = 'Banner'
    title_header = models.CharField(_("Title's header"), blank=True, null=True)
    image = MultiImageField(_('Banner image'), allowed_extensions=['jpeg', 'png', 'jpg'],
                            upload_to=UPLOAD_TO, required_width=1920, null=True)
예제 #13
0
파일: models.py 프로젝트: kiranHR/Project1
class Module(Model):
    """
    Any application module that might be integrated to 
    a website. Eg. Blog, Donate, Subscriptions
    """
    UPLOAD_TO = 'modules'
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(unique=True)
    logo = models.ImageField(upload_to=UPLOAD_TO,
                             null=True,
                             help_text="Logo of the module (100px x 100px).")
    monthly_cost = models.FloatField(
        default=0, help_text="What user pays monthly for this module.")
    description = models.TextField(blank=True, null=True)
    title = models.CharField(
        max_length=30,
        help_text="Title that appears in the menu bar of the website")
    image = MultiImageField(
        upload_to=UPLOAD_TO,
        max_size=800,
        null=True,
        help_text="Image on the module page as the visitor will see it. "
        "Used to decorate or/and give more explanations.")
    content = models.TextField(
        blank=True,
        null=True,
        help_text="Text on the module page as the visitor will see it. "
        "Can be used to give some explanations")
    is_active = models.BooleanField(
        default=False,
        help_text="Check/Uncheck to turn the module Active/Inactive")
    is_pro = models.BooleanField(
        default=True,
        help_text="Designates whether this modules is available "
        "only to PRO version websites")
    config_model_name = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="Model name of the config for this module.")
    config_model_admin = models.CharField(
        max_length=100,
        blank=True,
        null=True,
        help_text="Model Admin of the config for this module.")
    url_name = models.CharField(
        max_length=60,
        help_text="Django url name of the module "
        "Meaning a name under the form [namespace:]url_name")
    homepage_section_renderer = models.CharField(
        max_length=100,
        help_text="Function that renders the module as "
        "a homepage section.")

    class Meta:
        db_table = 'ikwen_module'

    def __unicode__(self):
        return self.name

    def _get_config_model(self):
        tokens = self.config_model_name.split('.')
        model = get_model(tokens[0], tokens[1])
        return model

    config_model = property(_get_config_model)

    def _get_config(self):
        try:
            return self.config_model._default_manager.all()[0]
        except IndexError:
            pass

    config = property(_get_config)

    def render(self, request=None):
        renderer = import_by_path(self.homepage_section_renderer)
        return renderer(self, request)
예제 #14
0
파일: models.py 프로젝트: komsihon/MoodsBox
class Song(AbstractWatchModel):
    artist = models.ForeignKey(Artist)
    album = models.ForeignKey(Album, blank=True, null=True)
    title = models.CharField(max_length=100, db_index=True)
    slug = models.SlugField(db_index=True)
    cover = MultiImageField(upload_to='songs_covers',
                            required_width=300,
                            required_height=300,
                            allowed_extensions=['jpg', 'jpeg'],
                            blank=True,
                            null=True,
                            help_text=_("JPEG Image, 300 &times; 300px"))
    preview = models.FileField(upload_to='song_previews',
                               blank=True,
                               null=True,
                               editable=False)
    media = FileField(upload_to='songs',
                      blank=True,
                      null=True,
                      allowed_extensions=['mp3'],
                      callback=generate_song_preview)
    download_link = models.URLField(blank=True, null=True)
    cost = models.IntegerField(default=0)
    is_active = models.BooleanField(default=True)
    show_on_home = models.BooleanField(default=False)
    order_of_appearance = models.IntegerField(default=0)
    tags = models.TextField(blank=True, null=True)

    turnover_history = ListField()
    earnings_history = ListField()
    units_sold_history = ListField()

    total_turnover = models.IntegerField(default=0)
    total_earnings = models.IntegerField(default=0)
    total_units_sold = models.IntegerField(default=0)

    class Meta:
        unique_together = ('artist', 'album', 'title')

    def __unicode__(self):
        return "%s - %s" % (self.title, self.artist.name)

    def _get_image(self):
        if self.cover and self.cover.name:
            return self.cover
        if self.album:
            return self.album.cover

    image = property(_get_image)

    def get_obj_details(self):
        return "XAF %d" % self.cost

    def to_dict(self):
        val = super(Song, self).to_dict()
        val['type'] = 'song'
        val['url'] = reverse('mediashop:music_item_detail',
                             args=(self.artist.slug, self.slug))
        image_url = self.image.name if self.image.name else Service.LOGO_PLACEHOLDER
        val['image'] = getattr(settings, 'MEDIA_URL') + image_url
        return val
예제 #15
0
파일: models.py 프로젝트: kiranHR/Project1
class CyclicRevival(Model):
    UPLOAD_TO = 'revival/cyclic_mail_images'

    service = models.ForeignKey(Service, related_name='+')
    profile_tag_id = models.CharField(max_length=24, db_index=True)
    hour_of_sending =  models.IntegerField(default=9, db_index=True)
    days_cycle = models.IntegerField(blank=True, null=True,
                                     help_text=_("Run revival every N days"))
    day_of_week_list = ListField()
    day_of_month_list = ListField()
    mail_subject = models.CharField(max_length=150, blank=True, null=True)
    mail_content = models.TextField(blank=True, null=True)
    mail_image = MultiImageField(upload_to=UPLOAD_TO, max_size=800, blank=True, null=True)
    sms_text = models.TextField(blank=True, null=True)
    next_run_on = models.DateField(default=datetime.now, db_index=True)
    end_on = models.DateField(db_index=True, blank=True, null=True)
    items_fk_list = ListField()
    is_active = models.BooleanField(default=False, db_index=True)
    is_running = models.BooleanField(default=False, db_index=True)

    class Meta:
        unique_together = ('service', 'profile_tag_id', )

    def set_next_run_date(self):
        if self.days_cycle:
            self.next_run_on = self.next_run_on + timedelta(days=self.days_cycle)
        elif len(self.day_of_week_list):
            self.day_of_week_list.sort()
            today = datetime.now().weekday() + 1
            count = len(self.day_of_week_list)
            try:
                i = self.day_of_week_list.index(today)
                if count > 1:
                    i = (i + 1) % count
                next_day = self.day_of_week_list[i]
                if next_day > today:
                    ext = next_day - today
                else:
                    ext = next_day - today + 7
                self.next_run_on = self.next_run_on + timedelta(days=ext)
            except:
                pass
        elif len(self.day_of_month_list):
            self.day_of_month_list.sort()
            now = datetime.now()
            today = now.day
            count = len(self.day_of_month_list)
            days_count = calendar.monthrange(now.year, now.month)[1]
            try:
                i = self.day_of_month_list.index(today)
                if count > 1:
                    i = (i + 1) % count
                next_day = self.day_of_month_list[i]
                if next_day > today:
                    ext = next_day - today
                else:
                    ext = next_day - today + days_count
                self.next_run_on = self.next_run_on + timedelta(days=ext)
            except:
                pass
        self.save()
예제 #16
0
파일: models.py 프로젝트: komsihon/Project8
class Series(AbstractWatchModel, MediaInterface):
    objects = MongoDBManager()
    SLUG = 'series'
    title = models.CharField(max_length=100,
                             help_text=_("Title of the series."))
    season = models.PositiveSmallIntegerField()
    slug = models.SlugField(
        unique=True,
        help_text=
        _("Auto filled. But add -seasonX manually. Eg: <strong>arrow-saison3</strong>"
          ))
    release = models.DateField(
        blank=True,
        null=True,
        help_text=_("Date of release of movie in country of origin."))
    episodes_count = models.PositiveIntegerField(
        help_text="Number of episodes of this series.")  # Number of episodes
    synopsis = models.TextField()
    poster = MultiImageField(upload_to='series', blank=True, null=True)
    provider = models.ForeignKey(Service,
                                 editable=False,
                                 blank=True,
                                 null=True,
                                 related_name='+',
                                 help_text=_("Provider of this series."))
    price = models.IntegerField(
        default=0,
        editable=is_content_vendor,
        help_text=_("Cost of sale of this series to VOD operators."))
    view_price = models.IntegerField(
        default=0,
        help_text=_("Cost to view all episodes of this series in streaming."))
    download_price = models.FloatField(
        default=0,
        help_text=_("Cost to download all episodes of this series."))
    # Tells whether this Movie is part of an Adult category.
    # Set automatically upon Series.save() by checking categories
    is_adult = models.BooleanField(default=False,
                                   verbose_name=_("Adult content"))
    trailer_resource = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text=_(
            "Filename (Eg: <strong>Avatar.mob.mp4</strong>), URL "
            "Embed code (Eg: <strong>&lt;iframe src='...'&gt;&lt;/iframe&gt;</strong>) "
            "for trailer of this movie."))
    categories = ListField(EmbeddedModelField('Category'),
                           help_text=_("Categories the series is part of."))
    visible = models.BooleanField(default=True)
    groups = models.CharField(
        max_length=100,
        default='',
        blank=True,
        help_text=
        _("Group the series belongs to (write lowercase). Will be used for suggestions "
          "Eg: Write <strong>scandal</strong> for Scandal season 1, 2, 3 ..."))
    tags = models.CharField(
        max_length=150,
        help_text=
        _("Key words used to retrieve the series in search. Typically title of movie written "
          "lowercase and main actors, all separated by space. Eg: <strong>scandal keanu reaves</strong>"
          ))
    # Random field used for random selections in MongoDB
    rand = models.FloatField(default=random.random,
                             db_index=True,
                             editable=False)

    owner_fk_list = ListField()

    count_history = ListField(
    )  # count can be the number of orders or views of this Media
    download_history = ListField()
    earnings_history = ListField()

    total_count = models.IntegerField(default=0)
    total_download = models.IntegerField(default=0)
    total_earnings = models.IntegerField(default=0)

    class Meta:
        verbose_name_plural = 'Series'
        unique_together = (
            'title',
            'season',
        )

    def _get_full_title(self):
        """
        Gets full title of the Series; that is the title followed by "Season X"
        """
        return "%s - %s %d" % (self.title, _('Season'), self.season)

    full_title = property(_get_full_title)

    def _get_display_orders(self):
        """
        Number of orders(based on fake_orders) of the series.
        Is arbitrarily considered as the number of fake_orders of the first episode of the series.
        It is returned in a format suitable for display
        """
        query_set = SeriesEpisode.objects.filter(series=self.id)
        first_episode = query_set[0] if len(query_set) > 0 else None
        if first_episode:
            if first_episode.fake_orders < 1000:
                return first_episode.fake_orders
            else:
                num500 = first_episode.fake_orders / 500
                return "%d+" % (num500 * 500)
        else:
            return 20  # This is an arbitrary value

    display_orders = property(_get_display_orders)

    def _get_display_clicks(self):
        """
        Number of clicks(based on fake_clicks) of the series.
        Is arbitrarily considered as the number of fake_clicks of the first episode of the series.
        It is returned in a format suitable for display
        """
        query_set = SeriesEpisode.objects.filter(series=self.id)
        first_episode = query_set[0] if len(query_set) > 0 else None
        if first_episode:
            if first_episode.fake_clicks < 1000:
                return first_episode.fake_clicks
            else:
                num500 = first_episode.fake_clicks / 500
                return "%d+" % (num500 * 500)
        else:
            return 150  # This is an arbitrary value

    display_clicks = property(_get_display_clicks)

    def _get_orders(self):
        """
        Calculate the number of orders of the series as the average number of orders of the episodes.
        """
        episodes = SeriesEpisode.objects.filter(series=self.id)
        if len(episodes) == 0:
            return 0
        total_orders = 0
        for episode in episodes:
            total_orders += episode.orders
        return total_orders / len(episodes)

    orders = property(_get_orders)
    _get_orders.short_description = 'Orders'

    def _get_clicks(self):
        """
        Calculate the number of clicks of the series as the average number of clicks of the episodes.
        """
        episodes = SeriesEpisode.objects.filter(series=self.id)
        if len(episodes) == 0:
            return 0
        total_clicks = 0
        for episode in episodes:
            total_clicks += episode.orders
        return total_clicks / len(episodes)

    clicks = property(_get_clicks)
    _get_clicks.short_description = 'Clicks'

    def _get_size(self):
        """
        Calculate the size of the series by summing up the size of episodes individual files.
        """
        sizes = [
            series_episode.size
            for series_episode in SeriesEpisode.objects.filter(series=self)
        ]
        return reduce(lambda x, y: x + y, sizes) if len(sizes) > 0 else 0

    size = property(_get_size)

    def _get_duration(self):
        """
        Calculate the duration of the series by summing up the duration of episodes individual files.
        """
        durations = [
            series_episode.duration
            for series_episode in SeriesEpisode.objects.filter(series=self)
        ]
        return reduce(lambda x, y: x + y,
                      durations) if len(durations) > 0 else 0

    duration = property(_get_duration)

    def _get_categories_to_string(self):
        categories = [category.title for category in self.categories]
        return ", ".join(categories)

    categories_to_string = property(_get_categories_to_string)

    def _get_episodes(self):
        """
        Gets the list of episodes of this series
        """
        return [
            series_episode
            for series_episode in SeriesEpisode.objects.filter(series=self)
        ]

    episodes = property(_get_episodes)

    def _get_seriesepisode_set(self):
        """
        Gets the query_set containing all episodes of this series. This naturally exists
        in django, but this backward query was intentionally by declaring the field series
        in class SeriesEpisode as such:
            series = models.ForeignKey(Series, related_name='+')
        It was removed because it causes error "RelatedObject has no attribute get_internal_type()"
        when running lookups like "Series.object.filter(title__contains=some_value)".
        Since this is internally used by the admin app. We manually restored it
        by creating the property seriesepisode_set below
        """
        return SeriesEpisode.objects.filter(series=self)

    seriesepisode_set = property(_get_seriesepisode_set)

    def _get_trailer(self):
        """
        Gets the trailer of this series
        """
        if self.trailer_resource:
            return Trailer(title='',
                           slug='',
                           size=0,
                           duration=3,
                           resource=self.trailer_resource)

    trailer = property(_get_trailer)

    def _get_type(self):
        return "series"

    type = property(_get_type)

    def _get_owner_list(self):
        owner_list = []
        for pk in self.owner_fk_list:
            try:
                owner_list.append(Member.objects.get(pk=pk))
            except:
                pass
        return owner_list

    owner_list = property(_get_owner_list)

    def to_dict(self):
        var = to_dict(self)
        var['poster'] = {
            'url':
            from_provider(self.poster.url, self.provider)
            if self.poster.name else 'default_poster.jpg',
            'small_url':
            from_provider(self.poster.small_url, self.provider)
            if self.poster.name else 'default_poster.jpg',
            'thumb_url':
            from_provider(self.poster.thumb_url, self.provider)
            if self.poster.name else 'default_poster.jpg'
        }
        var['type'] = self.type
        var['display_orders'] = self.display_orders
        var['display_clicks'] = self.display_clicks
        var['display_load'] = self.display_load
        var['full_title'] = self.full_title
        del (var['rand'])
        del (var['synopsis'])
        del (var['provider_id'])
        del (var['visible'])
        del (var['groups'])
        del (var['categories'])
        return var

    def __unicode__(self):
        return "%s Season %d" % (self.title, self.season)
예제 #17
0
class Member(AbstractUser):
    AVATAR = settings.STATIC_URL + 'ikwen/img/login-avatar.jpg'
    PROFILE_UPLOAD_TO = 'members/profile_photos'
    COVER_UPLOAD_TO = 'members/cover_images'
    MALE = 'Male'
    FEMALE = 'Female'
    is_ghost = models.BooleanField(
        default=False,
        help_text=
        "Ghost users are created manually by site owner. They can still register "
        "normally afterwards. Ghost members are useful because they can be "
        "enrolled in revivals without actually having an account on the website"
    )
    full_name = models.CharField(max_length=150, db_index=True)
    tags = models.CharField(max_length=255,
                            blank=True,
                            null=True,
                            db_index=True)
    phone = models.CharField(max_length=30,
                             db_index=True,
                             blank=True,
                             null=True)
    gender = models.CharField(max_length=15, blank=True, null=True)
    dob = models.DateField(blank=True, null=True, db_index=True)
    birthday = models.IntegerField(
        blank=True, null=True, db_index=True
    )  # Integer value of birthday only as MMDD. Eg:1009 for Oct. 09
    language = models.CharField(max_length=10,
                                blank=True,
                                null=True,
                                default=get_language)
    photo = MultiImageField(upload_to=PROFILE_UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=600,
                            small_size=200,
                            thumb_size=100)
    cover_image = models.ImageField(upload_to=COVER_UPLOAD_TO,
                                    blank=True,
                                    null=True)
    entry_service = models.ForeignKey(
        Service,
        blank=True,
        null=True,
        related_name='+',
        help_text=_(
            "Service where user registered for the first time on ikwen"))
    is_iao = models.BooleanField(
        'IAO',
        default=False,
        editable=False,
        help_text=_('Designates whether this user is an '
                    '<strong>IAO</strong> (Ikwen Application Operator).'))
    is_bao = models.BooleanField(
        'Bao',
        default=False,
        editable=False,
        help_text=_(
            'Designates whether this user is the Bao in the current service. '
            'Bao is the highest person in a deployed ikwen application. The only that '
            'can change or block Sudo.'))
    collaborates_on_fk_list = ListField(
        editable=False,
        help_text="Services on which member collaborates being the IAO or no.")
    customer_on_fk_list = ListField(
        editable=False,
        help_text="Services on which member was granted mere member access.")
    group_fk_list = ListField(
        editable=False,
        help_text="Groups' ids of the member across different Services.")
    email_verified = models.BooleanField(
        _('Email verification status'),
        default=False,
        help_text=_('Designates whether this email has been verified.'))
    phone_verified = models.BooleanField(
        _('Phone verification status'),
        default=False,
        help_text=_('Designates whether this phone number has been '
                    'verified by sending a confirmation code by SMS.'))
    business_notices = models.IntegerField(
        default=0, help_text="Number of pending business notifications.")
    personal_notices = models.IntegerField(
        default=0, help_text="Number of pending personal notifications.")

    objects = MemberManager()

    class Meta:
        db_table = 'ikwen_member'

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

    def save(self, **kwargs):
        if self.dob:
            self.birthday = int(self.dob.strftime('%m%d'))
        super(Member, self).save(**kwargs)

    def get_short_name(self):
        "Returns the short name for the user."
        return self.full_name.split(' ')[0]

    def _get_display_joined(self):
        return strftime(self.date_joined, '%y/%m/%d %H:%M')

    display_date_joined = property(_get_display_joined)

    def get_from(self, db):
        add_database_to_settings(db)
        return type(self).objects.using(db).get(pk=self.id)

    def get_apps_operated(self):
        return list(Service.objects.filter(member=self))

    def get_status(self):
        if self.is_active:
            return 'Active'
        return 'Blocked'

    def get_notice_count(self):
        return self.business_notices + self.personal_notices

    def get_services(self):
        return list(set(self.collaborates_on) | set(self.customer_on))

    def _get_customer_on(self):
        from ikwen.accesscontrol.backends import UMBRELLA
        res = []
        for pk in self.customer_on_fk_list:
            try:
                res.append(Service.objects.using(UMBRELLA).get(pk=pk))
            except:
                self.customer_on_fk_list.remove(pk)
                self.save()
        return res

    customer_on = property(_get_customer_on)

    def _get_collaborates_on(self):
        from ikwen.accesscontrol.backends import UMBRELLA
        res = []
        for pk in self.collaborates_on_fk_list:
            try:
                res.append(Service.objects.using(UMBRELLA).get(pk=pk))
            except:
                self.collaborates_on_fk_list.remove(pk)
                self.save()
        return res

    collaborates_on = property(_get_collaborates_on)

    def _get_profile_tag_list(self):
        from ikwen.revival.models import MemberProfile, ProfileTag
        member_profile, change = MemberProfile.objects.get_or_create(
            member=self)
        res = []
        for pk in member_profile.tag_fk_list:
            try:
                res.append(
                    ProfileTag.objects.get(pk=pk,
                                           is_active=True,
                                           is_auto=False,
                                           is_reserved=False))
            except:
                member_profile.tag_fk_list.remove(pk)
                member_profile.save()
        return res

    profile_tag_list = property(_get_profile_tag_list)

    def _get_preference_list(self):
        from ikwen.revival.models import MemberProfile, ProfileTag
        member_profile, change = MemberProfile.objects.get_or_create(
            member=self)
        res = []
        for pk in member_profile.tag_fk_list:
            try:
                res.append(
                    ProfileTag.objects.get(pk=pk,
                                           is_active=True,
                                           is_auto=True,
                                           is_reserved=False))
            except:
                member_profile.tag_fk_list.remove(pk)
                member_profile.save()
        return res

    preference_list = property(_get_preference_list)

    def propagate_changes(self):
        for s in self.get_services():
            db = s.database
            add_database_to_settings(db)
            Member.objects.using(db).filter(pk=self.id)\
                .update(email=self.email, phone=self.phone, gender=self.gender, first_name=self.first_name,
                        last_name=self.last_name, full_name=self.first_name + ' ' + self.last_name,
                        photo=self.photo.name, cover_image=self.cover_image.name, phone_verified=self.phone_verified,
                        email_verified=self.email_verified, language=self.language)

    def propagate_password_change(self, new_password):
        for s in self.get_services():
            db = s.database
            add_database_to_settings(db)
            try:
                m = Member.objects.using(db).get(pk=self.id)
                m.set_password(new_password)
                m.save(using=db)
            except Member.DoesNotExist:
                pass

    def add_service(self, service_id):
        """
        Adds the service_id in the collaborates_on_fk_list
        for this Member
        """
        from ikwen.accesscontrol.backends import UMBRELLA
        m = Member.objects.using(UMBRELLA).get(pk=self.id)
        m.customer_on_fk_list.append(service_id)
        m.save(using=UMBRELLA)

    def add_group(self, group_id):
        """
        Adds the service_id in the group_fk_list
        for this Member
        """
        from ikwen.accesscontrol.backends import UMBRELLA
        m = Member.objects.using(UMBRELLA).get(pk=self.id)
        m.group_fk_list.append(group_id)
        m.save(using=UMBRELLA)

    def to_dict(self):
        self.collaborate_on_fk_list = [
        ]  # Empty this as it is useless and may cause error
        self.customer_on_fk_list = [
        ]  # Empty this as it is useless and may cause error
        var = to_dict(self)
        var['date_joined'] = self.display_date_joined
        var['status'] = self.get_status()
        import ikwen.conf.settings
        var['photo'] = ikwen.conf.settings.MEDIA_URL + self.photo.small_name if self.photo.name else Member.AVATAR
        member_detail_view = getattr(settings, 'MEMBER_DETAIL_VIEW',
                                     'ikwen:profile')
        url = reverse(member_detail_view, args=(self.id, ))
        if member_detail_view == 'ikwen:profile':
            url = ikwenize(url)
        var['url'] = url
        try:
            var['permissions'] = ','.join(
                UserPermissionList.objects.get(user=self).permission_fk_list)
        except UserPermissionList.DoesNotExist:
            var['permissions'] = ''
        del (var['password'])
        del (var['is_superuser'])
        del (var['is_staff'])
        del (var['is_active'])
        return var
예제 #18
0
파일: models.py 프로젝트: komsihon/Project4
class HomepageSection(SmartObject):
    """
    Any full-width section on the homepage
    """
    UPLOAD_TO = 'web/homepage_sections'
    LEFT = "Left"
    RIGHT = "Right"
    CENTER = "Center"

    TEXT_POSITIONS = ((LEFT, _("Left")), (CENTER, _("Center")), (RIGHT,
                                                                 _("Right")))

    content_type = models.CharField(
        max_length=15,
        choices=HOME_SECTION_TYPE_CHOICES,
        help_text=_("Whether it is a flat content or a menu preview."))
    image = MultiImageField(upload_to=UPLOAD_TO,
                            blank=True,
                            null=True,
                            max_size=1920)
    background_image = models.BooleanField(
        default=False,
        help_text="Check to make the image cover the "
        "background of this section")
    description = models.TextField(blank=True, help_text="Text in the section")
    text_position = models.CharField(max_length=10,
                                     default=RIGHT,
                                     choices=TEXT_POSITIONS)
    cta = models.CharField(verbose_name=_("Call To Action"),
                           max_length=30,
                           blank=True,
                           help_text=_(
                               'Action you want your visitors to undertake. '
                               '<em><strong>E.g:</strong> "Join Us Now"</em>'))
    target_url = models.URLField(blank=True)
    density = models.CharField(max_length=15,
                               default=COZY,
                               choices=DENSITY_CHOICE)

    class Meta:
        ordering = (
            'order_of_appearance',
            '-id',
        )
        permissions = (("ik_manage_marketing", _("Manage marketing tools")), )

    def __unicode__(self):
        return self.title

    def _get_row_len(self):
        config = get_service_instance().config
        if config.theme and config.theme.display == COMFORTABLE:
            return 2
        elif config.theme and config.theme.display == COZY:
            return 3
        else:
            return getattr(settings, 'PRODUCTS_PREVIEWS_PER_ROW', 4)

    def render(self, request=None):
        if self.content_type == FLAT:
            c = Context({'section': self})
            config = get_service_instance().config
            tpl = 'webnode/snippets/homepage_section_flat.html'
            if config.theme and config.theme.template.slug != "":
                if config.theme.template.slug == 'optimum' or config.theme.template.slug == 'improve':
                    tpl = 'webnode/snippets/homepage_section_flat.html'
                else:
                    tokens = tpl.split('/')
                    tokens.insert(1, config.theme.template.slug)
                    tpl = '/'.join(tokens)
            html_template = get_template(tpl)
            return html_template.render(c)
        else:  # The section points to a Menu
            try:
                # The actual menu points to an Item List
                smart_category = SmartCategory.objects.get(
                    slug=self.description)
                item_list = []
                config = get_service_instance().config
                for category in smart_category.get_category_queryset():
                    item_list.extend(
                        list(
                            Item.objects.filter(category=category,
                                                visible=True,
                                                in_trash=False)))
                c = Context({
                    'item_list': item_list[:self._get_row_len()],
                    'density': self.density,
                    'title': smart_category.title,
                    'config': config
                })
                tpl = 'webnode/snippets/homepage_section_item_list.html'
                # refix template URI according to the theme used
                if config.theme and config.theme.template.slug != "":
                    if config.theme.template.slug == 'optimum' or config.theme.template.slug == 'improve':
                        tpl = 'webnode/snippets/homepage_section_item_list.html'
                    else:
                        tokens = tpl.split('/')
                        tokens.insert(1, config.theme.template.slug)
                        tpl = '/'.join(tokens)
                html_template = get_template(tpl)
                return html_template.render(c)
            except SmartCategory.DoesNotExist:
                # The actual menu points to a Module
                mod = Module.objects.get(slug=self.description)
                renderer = import_by_path(mod.homepage_section_renderer)
                return renderer(self, request)