Example #1
0
class Boostrap3LabelPlugin(CMSPlugin):
    """
    Component - Label: Model
    http://getbootstrap.com/components/#labels
    """
    label = models.CharField(
        verbose_name=_('Label'),
        blank=True,
        default='',
        max_length=255,
    )
    context = model_fields.Context(
        verbose_name=_('Context'),
        choices=(('default', _('Default')), ) + constants.CONTEXT_CHOICES,
        default='default',
        blank=False,
    )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['class'],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return self.label
Example #2
0
class Boostrap3JumbotronPlugin(CMSPlugin):
    """
    Component - Jumbotron: Model
    http://getbootstrap.com/components/#jumbotron
    """
    label = models.CharField(
        verbose_name=_('Label'),
        blank=True,
        max_length=255,
    )
    grid = models.BooleanField(
        verbose_name=_('Add container'),
        default=False,
        blank=True,
        help_text=_('Adds a ".container" element inside the "Jumbotron" '
                    'for use outside of a grid.'),
    )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['class'],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return self.label or str(self.pk)
Example #3
0
class Bootstrap3CodePlugin(CMSPlugin):
    """
    CSS - Code: Model
    http://getbootstrap.com/css/#code
    """
    CODE_TYPE_CHOICES = (
        ('code', _('Inline')),
        ('kbd', _('User input')),
        ('pre', _('Basic block')),
        ('var', _('Variables')),
        ('samp', _('Sample output')),
    )

    code_type = models.CharField(
        verbose_name=_('Code type'),
        choices=CODE_TYPE_CHOICES,
        default=CODE_TYPE_CHOICES[0][0],
        max_length=255,
    )
    code = models.TextField(
        verbose_name=_('Code'),
        blank=True,
    )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['class'],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return '<{}>'.format(self.code_type)
Example #4
0
class BuriedPointIdent(models.Model):
    """埋点标识"""
    name_info = (
        ('mall_home', '商城首页'),
        ('mall_earn', '商城赚钱'),
        ('mall_learn', '商城学习'),
        ('mall_mine', '商城我的'),
        ('mall_mine_rank', '商城我的同学'),
        ('mall_mine_withdrawal', '商城我的前往提现'),
        ('mall_mine_reward', '商城我的收益明细'),
        ('mall_home_banner', '商城轮播图'),
        ('mall_home_shelf', '商场货架'),
        ('card_list', '大课预约'),
        ('classroom', '手机上课端'),
        ('formal_landing_live', '活数据单课'),
        ('course_cart', '购物车'),
        ('ppt_introduction', 'PPT单课落地页'),
        ('excel_plan', 'Excel单课'),
        ('excel_landing_live', 'Excel活数据小课'),
        ('excel_landing', 'Excel小课'),
        ('word_introduction', 'word单课'),
        ('analysis_introduction', '数据分析精进单课'),
        ('excel_compose_introduction', 'excel+数据分析精进组合'),
        ('red_packet_home', '红包首页'),
        ('red_packet_list', '红包列表页'),
        ('red_packet_record', '红包记录页'),
        ('red_packet_send', '红包发送页'),
    )
    name = models.CharField('名称', max_length=32, default='')
    create_time = models.DateTimeField(auto_now=False, auto_now_add=True)
Example #5
0
class Bootstrap3TabPlugin(CMSPlugin):
    """
    JavaScript - Tab: "Wrapper" Model
    http://getbootstrap.com/javascript/#tabs
    """
    TAB_TYPE_CHOICES = (
        ('nav-tabs', _('Tabs')),
        ('nav-tabs nav-justified', _('Tabs justified')),
        ('nav-pills', _('Pills')),
        ('nav-pills nav-justified', _('Pills justified')),
    )
    TAB_EFFECT_CHOICES = (
        ('fade', _('Fade')),
    )

    index = models.PositiveIntegerField(
        verbose_name=_('Index'),
        null=True,
        blank=True,
        help_text=_('Index of element to open on page load (optional).'),
    )
    style = models.CharField(
        verbose_name=_('Display type'),
        choices=TAB_TYPE_CHOICES,
        default=TAB_TYPE_CHOICES[0][0],
        max_length=255,
    )
    effect = models.CharField(
        verbose_name=_('Animation effect'),
        choices=TAB_EFFECT_CHOICES,
        blank=True,
        max_length=255,
    )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['class'],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return '{} {}'.format(self.style, self.effect)
Example #6
0
class Task(models.Model):
    TASK_STATUS = (
        ('on_hold', 'On Hold'),
        ('complete', 'Complete'),
        ('in_progress', 'In Progress'),
        ('to_do', 'To do'),
    )
    task = models.CharField(max_length=250)
    author = models.ForeignKey(User, related_name='ToDoList')
    body = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=20,
                              choices=TASK_STATUS,
                              default='to_do')

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

    def __str__(self):
        return self.task
Example #7
0
class Bootstrap3CarouselSlidePlugin(CMSPlugin, model_fields.LinkMixin):
    """
    JavaScript - Carousel: "Slide" Model
    http://getbootstrap.com/javascript/#carousel
    """
    image = filer.fields.image.FilerImageField(
        verbose_name=_('Image'),
        blank=False,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    link_text = models.CharField(
        verbose_name=_('Link text'),
        max_length=255,
        blank=True,
    )
    content = djangocms_text_ckeditor.fields.HTMLField(
        verbose_name=_('Content'),
        blank=True,
        default='',
        help_text=_('Content may also be added using child plugins.'),
    )
    classes = model_fields.Classes()

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        image_text = content_text = ''

        if self.image_id:
            if self.image.name:
                image_text = self.image.name
            elif self.image.original_filename \
                    and os.path.split(self.image.original_filename)[1]:
                image_text = os.path.split(self.image.original_filename)[1]
            else:
                image_text = 'Image'
        if self.content:
            text = strip_tags(self.content).strip()
            if len(text) > 100:
                content_text = '{}...'.format(text[:100])
            else:
                content_text = '{}'.format(text)

        if image_text and content_text:
            return '{} ({})'.format(image_text, content_text)
        else:
            return image_text or content_text
Example #8
0
class Bootstrap3ButtonPlugin(CMSPlugin, model_fields.LinkMixin):
    """
    CSS - Buttons: "Button/Link" Model
    http://getbootstrap.com/css/#buttons
    """
    label = models.CharField(
        verbose_name=_('Display name'),
        blank=True,
        default='',
        max_length=255,
    )
    type = model_fields.LinkOrButton(
        verbose_name=_('Type'),
    )
    # button specific fields
    btn_context = model_fields.Context(
        verbose_name=_('Context'),
        choices=constants.BUTTON_CONTEXT_CHOICES,
        default=constants.BUTTON_CONTEXT_DEFAULT,
    )
    btn_size = model_fields.Size(
        verbose_name=_('Size'),
    )
    btn_block = models.BooleanField(
        verbose_name=_('Block'),
        default=False,
    )
    # text link specific fields
    txt_context = model_fields.Context(
        verbose_name=_('Context'),
        choices=constants.TEXT_LINK_CONTEXT_CHOICES,
        default=constants.TEXT_LINK_CONTEXT_DEFAULT,
        blank=True,
    )
    # common fields
    icon_left = model_fields.Icon(
        verbose_name=_('Icon left'),
    )
    icon_right = model_fields.Icon(
        verbose_name=_('Icon right'),
    )
    classes = model_fields.Classes()

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return self.label
Example #9
0
class GridloadingItemPlugin(CMSPlugin):
    """
    Gridloading: "Item" Model
    """
    image = FilerImageField(verbose_name=_('Image'), blank=True, null=True)
    content = HTMLField(verbose_name=_('Content'), blank=True, default='')
    link_url = models.URLField(_("Link"), blank=True, null=True)
    link_page = PageField(
        verbose_name=_('Page'),
        blank=True,
        null=True,
        help_text=_("A link to a page has priority over a text link."))
    link_target = models.CharField(
        verbose_name=_("Target"),
        max_length=100,
        blank=True,
        choices=constants.TARGET_CHOICES,
    )

    def __str__(self):
        image_text = content_text = ''

        if self.image_id:
            image_text = u'%s' % (self.image.name
                                  or self.image.original_filename)
        if self.content:
            text = strip_tags(self.content).strip()
            if len(text) > 100:
                content_text = u'%s...' % text[:100]
            else:
                content_text = u'%s' % text

        if image_text and content_text:
            return u'%s (%s)' % (image_text, content_text)
        else:
            return image_text or content_text

    def copy_relations(self, oldinstance):
        self.image_id = oldinstance.image_id
        self.link_page_id = oldinstance.link_page_id

    def get_link(self):
        link = self.link_url or u''

        if self.link_page_id:
            link = self.link_page.get_absolute_url()
        return link
Example #10
0
class BuriedPointLog(models.Model):
    """用户访问埋点记录"""
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    order = models.ForeignKey(CourseOrder,
                              on_delete=models.SET_NULL,
                              null=True)
    ident = models.ForeignKey('BuriedPointIdent',
                              on_delete=models.SET_NULL,
                              null=True)
    flag = models.CharField('公众号标识', max_length=32, default='')
    create_time = models.DateTimeField(auto_now=False, auto_now_add=True)
    course = models.ForeignKey(Course, on_delete=models.SET_NULL, null=True)
    course_group = models.ForeignKey(CourseGroup,
                                     on_delete=models.SET_NULL,
                                     null=True)
    banner_id = models.IntegerField('banner_id', default=0)
    grand_id = models.IntegerField('祖宗id', default=0)
    parent_id = models.IntegerField('父级id', default=0)
Example #11
0
class Bootstrap3TabItemPlugin(CMSPlugin):
    """
    JavaScript - Tab: "Item" Model
    http://getbootstrap.com/javascript/#tabs
    """
    title = models.CharField(
        verbose_name=_('Tab title'),
        max_length=255,
    )
    icon = model_fields.Icon(verbose_name=_('Title icon'), )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['class'],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return self.title
Example #12
0
class Bootstrap3ListGroupItemPlugin(CMSPlugin):
    """
    Component - List group: "Item" Model
    http://getbootstrap.com/components/#alerts
    """
    title = model_fields.MiniText(
        verbose_name=_('Title'),
        blank=True,
        default='',
    )
    context = model_fields.Context(
        verbose_name=_('Context'),
        choices=(
            ('default', _('Default')),
        ) + constants.CONTEXT_CHOICES,
        default='default',
        blank=False,
    )
    state = models.CharField(
        verbose_name=_('State'),
        choices=(
            ('active', _('Active')),
            ('disabled', _('Disabled')),
        ),
        blank=True,
        max_length=255,
    )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['class'],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        return self.title
Example #13
0
class Bootstrap3CarouselPlugin(CMSPlugin):
    """
    JavaScript - Carousel: "Wrapper" Model
    http://getbootstrap.com/javascript/#carousel
    """
    STYLE_DEFAULT = 'standard'
    STYLE_CHOICES = [
        (STYLE_DEFAULT, _('Standard')),
    ]
    TRANSITION_EFFECT_CHOICES = (('slide', _('Slide')), )

    style = models.CharField(
        verbose_name=_('Style'),
        choices=STYLE_CHOICES + model_fields.get_additional_styles(),
        default=STYLE_DEFAULT,
        max_length=255,
    )
    aspect_ratio = models.CharField(
        verbose_name=_('Aspect ratio'),
        choices=constants.ASPECT_RATIO_CHOICES,
        blank=True,
        default='',
        max_length=255,
        help_text=_('Determines width and height of the image '
                    'according to the selected ratio.'),
    )
    transition_effect = models.CharField(
        verbose_name=_('Transition effect'),
        choices=TRANSITION_EFFECT_CHOICES,
        default='',
        blank=True,
        max_length=255,
    )
    ride = models.BooleanField(
        verbose_name=_('Ride'),
        default=True,
        help_text=_('Auto-starts animation of the carousel.'),
    )
    interval = models.IntegerField(
        verbose_name=_('Interval'),
        default=5000,
        help_text=_('Time (in milliseconds) between items.'),
    )
    wrap = models.BooleanField(
        verbose_name=_('Wrap'),
        default=True,
        blank=True,
        help_text=_('Loops carousel animation.'),
    )
    pause = models.BooleanField(
        verbose_name=_('Pause'),
        default=True,
        blank=True,
        help_text=_('Pauses the carousel on hover.'),
    )
    classes = model_fields.Classes()
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=[
            'class',
            # data attributes et via settings
            'data-ride',
            'data-interval',
            'data-pause',
            'data-wrap'
        ],
    )

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        data = django.forms.models.model_to_dict(self)
        data.update(
            dict(
                style_label=_('Style'),
                transition_effect_label=_('Transition effect'),
                ride_label=_('Ride'),
                interval_label=_('Interval'),
                aspect_ratio_label=_('Aspect ratio'),
            ))
        fields = [
            'style',
            'transition_effect',
            'ride',
            'interval',
            'aspect_ratio',
        ]
        if not data['ride']:
            fields.remove('interval')
        return ', '.join([
            '{key}: {value}'.format(key=data['{}_label'.format(field)],
                                    value=data[field]) for field in fields
        ])

    def srcset(self):
        # more or less copied from image plugin.
        # TODO: replace with generic sizes/srcset solution
        items = collections.OrderedDict()
        if self.aspect_ratio:
            aspect_width, aspect_height = tuple(
                [int(i) for i in self.aspect_ratio.split('x')])
        else:
            aspect_width, aspect_height = None, None
        for device in constants.DEVICES:
            width = device[
                'width_gutter']  # TODO: should this should be based on the containing col size?
            width_tag = str(width)
            if aspect_width is not None and aspect_height is not None:
                height = int(
                    float(width) * float(aspect_height) / float(aspect_width))
                crop = True
            else:
                height = 0
                crop = False
            items[device['identifier']] = {
                'size': (width, height),
                'size_str': '{}x{}'.format(width, height),
                'width_str': '{}w'.format(width),
                # 'subject_location': self.file.subject_location,
                'upscale': True,
                'crop': crop,
                'aspect_ratio': (aspect_width, aspect_height),
                'width_tag': width_tag,
            }

        return items
Example #14
0
class Boostrap3ImagePlugin(CMSPlugin):
    """
    CSS - Images: Model
    http://getbootstrap.com/css/#images
    """
    file = filer.fields.image.FilerImageField(
        verbose_name=_('Image'),
        blank=False,
        null=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )
    alt = model_fields.MiniText(
        verbose_name=_('Alternative text'),
        blank=True,
        default='',
    )
    title = model_fields.MiniText(
        verbose_name=_('Title'),
        blank=True,
        default='',
    )
    use_original_image = models.BooleanField(
        verbose_name=_('Use original image'),
        blank=True,
        default=False,
        help_text=_('Outputs the raw image without cropping.'))
    override_width = models.IntegerField(
        verbose_name=_('Override width'),
        blank=True,
        null=True,
        help_text=_('The image width as number in pixels. '
                    'Example: "720" and not "720px".'),
    )
    override_height = models.IntegerField(
        verbose_name=_('Override height'),
        blank=True,
        null=True,
        help_text=_('The image height as number in pixels. '
                    'Example: "720" and not "720px".'),
    )
    aspect_ratio = models.CharField(
        verbose_name=_('Aspect ratio'),
        choices=constants.ASPECT_RATIO_CHOICES,
        blank=True,
        default='',
        max_length=255,
        help_text=_('Determines width and height of the image '
                    'according to the selected ratio.'),
    )
    shape = models.CharField(
        verbose_name=_('Shape'),
        choices=(
            ('rounded', '.img-rounded'),
            ('circle', '.img-circle'),
        ),
        default='',
        blank=True,
        max_length=255,
    )
    thumbnail = models.BooleanField(
        verbose_name='.img-thumbnail',
        default=False,
        blank=True,
        help_text=_('Adds the Bootstrap 3 ".img-thumbnail" class.'),
    )
    img_responsive = models.BooleanField(
        verbose_name='.img-responsive',
        default=True,
        blank=True,
        help_text=_('Adds the Bootstrap 3 ".img-responsive" class.'))
    attributes = AttributesField(
        verbose_name=_('Attributes'),
        blank=True,
        excluded_keys=['src', 'alt', 'class', 'title'],
    )
    classes = model_fields.Classes()

    cmsplugin_ptr = model_fields.CMSPluginField()

    def __str__(self):
        txt = ''
        if self.file_id and self.file.label:
            txt = self.file.label
        return txt

    def srcset(self):
        if not self.file:
            return []
        items = collections.OrderedDict()
        if self.aspect_ratio:
            aspect_width, aspect_height = tuple(
                [int(i) for i in self.aspect_ratio.split('x')])
        else:
            aspect_width, aspect_height = None, None
        for device in constants.DEVICES:
            if self.override_width:
                width = self.override_width
            else:
                # TODO: should this should be based on the containing col size?
                width = device['width_gutter']
            width_tag = str(width)
            if aspect_width is not None and aspect_height is not None:
                height = int(
                    float(width) * float(aspect_height) / float(aspect_width))
                crop = True
            else:
                if self.override_height:
                    height = self.override_height
                else:
                    height = 0
                crop = False
            items[device['identifier']] = {
                'size': (width, height),
                'size_str': '{}x{}'.format(width, height),
                'width_str': '{}w'.format(width),
                'subject_location': self.file.subject_location,
                'upscale': True,
                'crop': crop,
                'aspect_ratio': (aspect_width, aspect_height),
                'width_tag': width_tag,
            }

        return items
Example #15
0
class BradescoBilletDataAdminForm(forms.ModelForm):

    cedente_cnpj = fields.CNPJField(
        widget=forms.TextInput(attrs={
            "mask": "99.999.999/9999-99",
        }))  #, validators=[CNPJValidator]  )
    sacadoravalista_cnpj = fields.CNPJField(
        widget=forms.TextInput(attrs={
            "mask": "99.999.999/9999-99",
        }))  #, validators=[CNPJValidator] )
    enderecosacaval_cep = forms.CharField(widget=forms.TextInput(
        attrs={
            "mask": "99999-999",
        }))
    contabancaria_numerodaconta = forms.CharField(widget=forms.TextInput(
        attrs={
            "mask": "999999",
        }))
    contabancaria_numerodaconta_digito = forms.CharField(
        widget=forms.TextInput(attrs={
            "mask": "9",
        }))
    contabancaria_agencia = forms.CharField(widget=forms.TextInput(
        attrs={
            "mask": "9999",
        }))
    contabancaria_agencia_digito = forms.CharField(widget=forms.TextInput(
        attrs={
            "mask": "9",
        }))
    #titulo_digitodonossonumero = forms.CharField(widget = forms.TextInput(attrs={"mask": "9",}) )

    #titulo_nossonumero = models.CharField(max_length=20, null=False, blank=False, validators=[MinLengthValidator(11)])
    cedente_nome = models.CharField(max_length=255, null=False, blank=False)
    sacadoravalista_nome = models.CharField(max_length=255,
                                            null=False,
                                            blank=False)
    enderecosacaval_bairro = models.CharField(max_length=255,
                                              null=False,
                                              blank=False)
    enderecosacaval_logradouro = models.CharField(max_length=255,
                                                  null=False,
                                                  blank=False)
    enderecosacaval_numero = models.CharField(max_length=20,
                                              null=False,
                                              blank=False)
    enderecosacaval_uf = models.ForeignKey(State, null=False, blank=False)
    enderecosacaval_localidade = ChainedForeignKey(
        City,
        chained_field='enderecosacaval_uf',
        chained_model_field='state',
        null=False,
        blank=False)
    contabancaria_carteira = models.PositiveIntegerField(
        null=False, blank=False, validators=[MaxValueValidator(99)])
    cedente_nome.verbose_name = _("Seller's name")
    cedente_nome.help_text = _("Seller (company that will receive the money).")
    cedente_cnpj.label = _("Seller's CNPJ")
    cedente_cnpj.help_text = ""
    sacadoravalista_nome.label = _("Guarantor's name")
    sacadoravalista_nome.help_text = _(
        "Guarantor (the person that takes responsibility over the transaction)."
    )
    sacadoravalista_cnpj.label = _("Guarantor's CNPJ")
    sacadoravalista_cnpj.help_text = ""
    enderecosacaval_uf.label = _("State")
    enderecosacaval_uf.help_text = _("State where the the guarantor lives.")
    enderecosacaval_localidade.label = _("City")
    enderecosacaval_localidade.help_text = _(
        "City where the the guarantor lives.")
    enderecosacaval_cep.label = _("CEP")
    enderecosacaval_cep.help_text = _("CEP - Postal code")
    enderecosacaval_bairro.label = _("District")
    enderecosacaval_bairro.help_text = _("District where the guarantor lives")
    enderecosacaval_logradouro.label = _("Street")
    enderecosacaval_logradouro.help_text = _(
        "Street where the guarantor lives.")
    enderecosacaval_numero.label = _("Number")
    enderecosacaval_numero.help_text = _(
        "Number of the house where the guarantor lives.")
    contabancaria_numerodaconta.label = _("Account")
    contabancaria_numerodaconta.help_text = _(
        "Number of the bank account of the seller.")
    contabancaria_numerodaconta_digito.label = _("Verifier digit")
    contabancaria_numerodaconta_digito.help_text = _(
        "Verifier digit of the bank account of the seller.")
    contabancaria_carteira.label = _("Seller's wallet")
    contabancaria_carteira.help_text = _("Seller's bank wallet number")
    contabancaria_agencia.label = _("Agency")
    contabancaria_agencia.help_text = _("Seller's account agency")
    contabancaria_agencia_digito.label = _("Agency digit")
    contabancaria_agencia_digito.help_text = _(
        "Seller's account agency verifier digit")

    #titulo_nossonumero.label = _("\"Our number\"")
    #titulo_nossonumero.help_text = _("Number registered in Bradesco to register the receiving of billets.")
    #titulo_digitodonossonumero.label = _("\"Our number\" digit")
    #titulo_digitodonossonumero.help_text = _("\"Our number\" digit")

    class Meta:
        model = BradescoBilletData

    class Media:
        js = (
            settings.MEDIA_URL + "js/jquery.maskedinput-1.1.3.admin.js",
            settings.MEDIA_URL + "js/boleto.admin.js",
        )
        css = {"all": (settings.MEDIA_URL + "css/boleto.admin.css", )}
Example #16
0
class GridloadingPlugin(CMSPlugin):
    """
    Gridloading: "Wrapper" Model
    """
    effect = models.CharField(
        verbose_name=_('Loading effect'),
        choices=constants.EFFECT_CHOICES + get_additional_effects(),
        default=constants.EFFECT_DEFAULT,
        max_length=255,
    )
    aspect_ratio = models.CharField(
        verbose_name=_('Aspect ratio'),
        choices=constants.ASPECT_RATIO_CHOICES,
        blank=True,
        default='',
        max_length=255,
        help_text=_(
            'Determines width and height of the image according to the '
            'selected ratio. All images will be with same size. '
            'Not select ratio to maintain portrait/landscape of image.'),
    )
    extra_styles = models.CharField(
        _('Extra styles'),
        max_length=50,
        blank=True,
        help_text=_('An arbitrary string of CSS classes to add'))

    def __str__(self):
        data = django.forms.models.model_to_dict(self)
        data.update(
            dict(
                effect_label=_('Effect'),
                aspect_ratio_label=_('Aspect ratio'),
            ))
        fields = [
            'effect',
            'aspect_ratio',
        ]
        return ', '.join([
            u'{key}: {value}'.format(key=data['{}_label'.format(field)],
                                     value=data[field]) for field in fields
        ])

    def srcset(self):
        # more or less copied from image plugin.
        # TODO: replace with generic sizes/srcset solution
        items = collections.OrderedDict()
        if self.aspect_ratio:
            aspect_width, aspect_height = tuple(
                [int(i) for i in self.aspect_ratio.split('x')])
        else:
            aspect_width, aspect_height = None, None
        for device in constants.DEVICES:
            width = device[
                'width_gutter']  # TODO: should this should be based on the containing col size?
            width_tag = str(width)
            if aspect_width is not None and aspect_height is not None:
                height = int(
                    float(width) * float(aspect_height) / float(aspect_width))
                crop = True
            else:
                height = 0
                crop = False
            items[device['identifier']] = {
                'size': (width, height),
                'size_str': '{}x{}'.format(width, height),
                'width_str': '{}w'.format(width),
                # 'subject_location': self.file.subject_location,
                'upscale': True,
                'crop': crop,
                'aspect_ratio': (aspect_width, aspect_height),
                'width_tag': width_tag,
            }
        #import pdb; pdb.set_trace()
        return items
    def handle(self, infile, *args, **options):
        if not os.path.isfile(infile):
            raise Exception(
                '{} doesn\'t exist or is not a file'.format(infile))

        wb = load_workbook(filename=infile, read_only=True, data_only=True)
        ws = wb['Complete']

        col_idx = {
            cell.value: n
            for n, cell in enumerate(next(ws.rows))
            if cell.value in ColumnName.values
        }
        if len(col_idx) != len(ColumnName.values):
            raise Exception(
                'The excel file does not contain one or more of the mandatory columns: {}'
                .format(ColumnName.values))

        rows = list(ws.rows)
        songs_2_syllable_labels = {}
        for idx in range(len(rows)):
            if idx == 0:
                continue
            row = rows[idx]
            excel_row_idx = idx + 1

            label = row[col_idx[ColumnName.LABEL]].value
            family = row[col_idx[ColumnName.FAMILY]].value
            subfamily = row[col_idx[ColumnName.SUBFAMILY]].value
            syl_start = row[col_idx[ColumnName.SYL_START]].value
            syl_end = row[col_idx[ColumnName.SYL_END]].value
            song_name = row[col_idx[ColumnName.SONG_NAME]].value.replace(
                ' ', '').replace('$', '')
            has_error = False

            if not label:
                warning('At line {}, label is missing.'.format(excel_row_idx))
                has_error = True
            if not family:
                warning('At line {}, family is missing.'.format(excel_row_idx))
                has_error = True
            if not subfamily:
                warning(
                    'At line {}, subfamily is missing.'.format(excel_row_idx))
                has_error = True
            if not syl_start:
                warning(
                    'At line {}, syl_start is missing.'.format(excel_row_idx))
                has_error = True
            if not syl_end:
                warning(
                    'At line {}, syl_end is missing.'.format(excel_row_idx))
                has_error = True
            if not song_name:
                warning(
                    'At line {}, song_name is missing.'.format(excel_row_idx))
                has_error = True

            if song_name not in songs_2_syllable_labels:
                syllable_labels = {}
                songs_2_syllable_labels[song_name] = syllable_labels
            else:
                syllable_labels = songs_2_syllable_labels[song_name]

            if syl_start in syllable_labels:
                warning('Duplicate syllable start time = '.format(syl_start))
                has_error = True

            if has_error:
                continue

            syllable_labels[syl_start] = (syl_end, family, subfamily, label,
                                          excel_row_idx)

        song_names = list(songs_2_syllable_labels.keys())
        db_songs = list(AudioFile.objects.all().values_list('name', flat=True))

        songs_in_excel_not_db = [x for x in song_names if x not in db_songs]

        if songs_in_excel_not_db:
            warning(
                'The following songs are found in Excel but not in database: \n{}'
                .format('\n'.join(songs_in_excel_not_db)))

        segment_values_list = Segment.objects.filter(audio_file__name__in=song_names) \
            .annotate(strid=Cast('id', models.CharField())) \
            .values_list('strid', 'audio_file__name', 'start_time_ms', 'end_time_ms')

        songs_2_syllable_endpoints_db = {}
        for seg_id, song_name, syl_start, syl_end in segment_values_list:
            if song_name not in songs_2_syllable_endpoints_db:
                syllable_endpoints = {}
                songs_2_syllable_endpoints_db[song_name] = syllable_endpoints
            else:
                syllable_endpoints = songs_2_syllable_endpoints_db[song_name]
                syllable_endpoints[syl_start] = (syl_end, seg_id)

        seg_ids = []
        label_values = []
        family_values = []
        subfamily_values = []

        for song_name in songs_2_syllable_endpoints_db:
            syllable_endpoints = songs_2_syllable_endpoints_db[song_name]
            syllable_labels = songs_2_syllable_labels[song_name]

            syllable_start_end_db = [(x, y[0])
                                     for x, y in syllable_endpoints.items()]
            syllable_start_end_excel = [(x, y[0])
                                        for x, y in syllable_labels.items()]
            excel_row_idxs = [y[-1] for _, y in syllable_labels.items()]

            syls_in_excel_not_db = []
            for idx, (s, e) in enumerate(syllable_start_end_excel):
                if (s, e) not in syllable_start_end_db:
                    syls_in_excel_not_db.append((excel_row_idxs[idx], s, e))

            for syl_start, (syl_end, seg_id) in syllable_endpoints.items():
                if syl_start in syllable_labels:
                    syl_end, family, subfamily, label, excel_row_idx = syllable_labels[
                        syl_start]

                    seg_ids.append(seg_id)
                    label_values.append(label)
                    family_values.append(family)
                    subfamily_values.append(subfamily)

        print('total_importable = {}'.format(len(seg_ids)))
        bulk_set_attr(Segment, seg_ids, 'label_family', family_values, False)
        bulk_set_attr(Segment, seg_ids, 'label', label_values, False)
        bulk_set_attr(Segment, seg_ids, 'label_subfamily', subfamily_values,
                      False)