示例#1
0
class AboutPage(RoutablePageMixin, Page):
    body = MarkdownField(null=True, blank=True)

    content_panels = Page.content_panels + [
        MarkdownPanel('body', classname="full"),
    ]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context["posts"] = IndexDetailPage.objects.live().public()
        json_list = list(context["posts"].values(
            'slug', 'title', 'author_founder', 'rownum', 'pub_date',
            'end_date', 'about', 'location', 'external_link',
            'external_link_two', 'images_list', 'page_ptr_id'))
        context['json_dict'] = json.dumps(json_list)
        context["image_entries"] = []

        for index in context["posts"]:
            for c in index.images_list.all():
                context["image_entries"].append({
                    "slug": index.slug,
                    "img_name": str(c)
                })

        context['json_img_dict'] = json.dumps(list(context["image_entries"]))
        return context

    @route(r'^submit/$', name="submit_page")
    def submit_page(self, request):
        return TemplateResponse(request, 'about/about_submit_page.html')
示例#2
0
文件: models.py 项目: uktrade/invest
class ContactFormSuccessPage(Page):
    body_text = MarkdownField()

    content_panels = [
        FieldPanel('title'),
        FieldPanel('body_text'),
    ]
示例#3
0
class PortfolioPageJobCareer(GraphQLEnabledModel, Orderable):
    portfolio = ParentalKey(PortfolioPage,
                            on_delete=models.CASCADE,
                            related_name='job_career',
                            verbose_name=u'職務経歴')
    title = models.CharField(verbose_name=u'タイトル', max_length=50)
    start_date = models.DateField(u'開始日', auto_now=False, auto_now_add=False)
    end_date = models.DateField(u'終了日',
                                auto_now=False,
                                auto_now_add=False,
                                blank=True,
                                null=True)
    job_role = models.CharField(u'役割', max_length=50, blank=True, null=True)
    description = MarkdownField(verbose_name=u'説明', blank=True, null=True)

    panels = [
        FieldPanel('title'),
        FieldPanel('start_date'),
        FieldPanel('end_date'),
        FieldPanel('job_role'),
        MarkdownPanel('description')
    ]

    graphql_fields = [
        GraphQLField('title'),
        GraphQLField('start_date'),
        GraphQLField('end_date'),
        GraphQLField('job_role'),
        GraphQLField('description'),
    ]
示例#4
0
文件: models.py 项目: uktrade/invest
class ContactUserEmail(BaseSetting):

    title = CharField(
        max_length=255,
        default="Invest in GREAT Britain",
    )

    heading = CharField(max_length=255,
                        default="Invest in GREAT Britain Contact Confirmation")

    body_text = MarkdownField(default=dedent("""
            Thank you for contacting the Department for International Trade about your investment plans.
            
            We have received the information you sent through the Invest in Great Britain website and will aim to follow up with
            you in the next 7 days. Your enquiry may be forwarded to a local post for follow up.
            
            The Department for International Trade provides free and impartial advice to companies around the world interested in
            doing business in the UK. We look forward to welcoming you as one of the many companies to enjoy success in the UK.
            Find our Terms and Conditions [here](http://https://invest.great.gov.uk/int/terms-and-conditions/).
            
            See below for your submitted form:"""))  # noqa

    body_text_continued = MarkdownField(default=dedent("""
            Many Thanks
            
            DIT"""

                                                       # noqa
                                                       ))

    footer = MarkdownField(default=dedent("""
            Department for International Trade (DIT) is the Government Department that helps UK‑based companies succeed in the
            global economy. We also help overseas companies bring their high-quality investment to the UK’s dynamic economy,
            acknowledged as Europe’s best place in which to succeed in global business.
            
            [invest.great.gov.uk](http://https://invest.great.gov.uk)""")
                           )  # noqa

    panels = [
        FieldPanel('title'),
        FieldPanel('heading'),
        FieldPanel('body_text'),
        FieldPanel('body_text_continued'),
        FieldPanel('footer'),
    ]
示例#5
0
class StaticContent(models.Model):
    text = MarkdownField()

    panels = [
        MarkdownPanel('text'),
    ]

    def __str__(self):
        return self.text
示例#6
0
文件: models.py 项目: uktrade/invest
class InfoPage(Page):
    """
    Markdown page - used for terms and conditions
    and privacy policy
    """
    content = MarkdownField()

    content_panels = Page.content_panels + [
        FieldPanel('content'),
    ]
class PostPage(Page):
    body = MarkdownField()
    date = models.DateTimeField(verbose_name="Post date",
                                default=datetime.datetime.today)
    excerpt = MarkdownField(
        verbose_name='excerpt',
        blank=True,
    )

    header_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )

    categories = ParentalManyToManyField('blog.BlogCategory', blank=True)
    tags = ClusterTaggableManager(through='blog.BlogPageTag', blank=True)

    content_panels = Page.content_panels + [
        ImageChooserPanel('header_image'),
        MarkdownPanel("body"),
        MarkdownPanel("excerpt"),
        FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
        FieldPanel('tags'),
    ]

    settings_panels = Page.settings_panels + [
        FieldPanel('date'),
    ]

    @property
    def blog_page(self):
        return self.get_parent().specific

    def get_context(self, request, *args, **kwargs):
        context = super(PostPage, self).get_context(request, *args, **kwargs)
        context['blog_page'] = self.blog_page
        context['post'] = self
        return context
示例#8
0
文件: models.py 项目: uktrade/invest
class ContactAgentEmail(BaseSetting):

    title = CharField(
        max_length=255,
        default="Invest in GREAT Britain",
    )

    heading = CharField(max_length=255,
                        default="Invest in GREAT Britain Contact Confirmation")

    body_text = MarkdownField(default=dedent("""
            This is confirmation of an Invest in Great Britain lead via the contact us form on the website.
            
            See below for the user submitted form:""")  # noqa
                              )

    body_text_continued = MarkdownField(default=dedent("""
            Many Thanks
            
            DIT""")  # noqa
                                        )

    footer = MarkdownField(default=dedent("""
            Department for International Trade (DIT) is the Government Department that helps UK‑based companies succeed in the
            global economy. We also help overseas companies bring their high-quality investment to the UK’s dynamic economy,
            acknowledged as Europe’s best place in which to succeed in global business.
            
            [invest.great.gov.uk](http://https://invest.great.gov.uk)"""
                                          )  # noqa
                           )

    panels = [
        FieldPanel('title'),
        FieldPanel('heading'),
        FieldPanel('body_text'),
        FieldPanel('body_text_continued'),
        FieldPanel('footer'),
    ]
示例#9
0
class SitePolicyPage(GraphQLEnabledModel, Page):
    body = MarkdownField(verbose_name=u'本文', blank=True)

    content_panels = Page.content_panels + [
        MarkdownPanel("body", classname="full"),
    ]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration"),
    ]

    graphql_fields = [
        GraphQLField('body'),
    ]
示例#10
0
class CharacterPage(GraphQLEnabledModel, Page):
    """A page of character list."""
    nickname = models.CharField(u"称号", max_length=15, null=True)
    name = models.CharField(u"名前", max_length=35, null=True)
    character_id = models.CharField(u"キャラクターID", max_length=6, null=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'画像',
    )
    description = models.CharField(u'概要', max_length=255, null=True)
    introduction = MarkdownField(verbose_name=u"説明", null=True)
    game_name = models.CharField(u"登録されているゲーム", max_length=20, null=True)
    character_page_url = models.CharField(u"キャラクターのページ", max_length=255, null=True)

    content_panels = Page.content_panels + [
        FieldPanel('nickname'),
        FieldPanel('name'),
        FieldPanel('character_id'),
        ImageChooserPanel('image'),
        FieldPanel('description'),
        MarkdownPanel('introduction'),
        FieldPanel('game_name'),
        FieldPanel('character_page_url'),
    ]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration"),
    ]

    graphql_fields = [
        GraphQLField("nickname"),
        GraphQLField("name"),
        GraphQLField("character_id"),
        GraphQLField("image"),
        GraphQLField("description"),
        GraphQLField("introduction"),
        GraphQLField("game_name"),
        GraphQLField("character_page_url"),
    ]

    def clean(self):
        super().clean()
        new_title = '%s(%s)' % (self.name, self.character_id)
        new_slug = '%s' % self.character_id
        self.title = new_title
        self.slug = slugify(new_slug)
示例#11
0
class PuzzlePostPage(Page):
    date = models.DateField('Post date')
    body = MarkdownField(blank=True)
    answer = MarkdownField(blank=True)

    def main_image(self):
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None

    search_fields = Page.search_fields + [
        index.SearchField('body'),
        index.SearchField('answer'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        MarkdownPanel('body'),
        MarkdownPanel('answer'),
        InlinePanel('gallery_images', label='Gallery images'),
    ]
示例#12
0
class Branding(BaseSetting):
    logo = models.ForeignKey('wagtailimages.Image',
                             null=True,
                             blank=True,
                             on_delete=models.SET_NULL,
                             related_name='+')

    favicon = models.ForeignKey('wagtailimages.Image',
                                null=True,
                                blank=True,
                                on_delete=models.SET_NULL,
                                related_name='+')

    language_choice_icon = models.ForeignKey('wagtailimages.Image',
                                             null=True,
                                             blank=True,
                                             on_delete=models.SET_NULL,
                                             related_name='+')

    footer_logo = models.ForeignKey('wagtailimages.Image',
                                    null=True,
                                    blank=True,
                                    on_delete=models.SET_NULL,
                                    related_name='+')

    footer_secondary_nav = StreamField([
        ('internal_link', PageChooserBlock()),
        ('external_link', ExternalLinkBlock()),
    ],
                                       blank=True)

    footer_copyright = models.CharField(max_length=255)

    is_beta = models.BooleanField(default=True)
    beta_bar_text = MarkdownField(
        default="This is a new service - your feedback will help improve it.")
    skip_to_main_text = models.CharField(default="Skip to main content",
                                         max_length=40)

    panels = [
        ImageChooserPanel('logo'),
        ImageChooserPanel('favicon'),
        ImageChooserPanel('language_choice_icon'),
        ImageChooserPanel('footer_logo'),
        StreamFieldPanel('footer_secondary_nav'),
        FieldPanel('footer_copyright'),
        FieldPanel('is_beta'),
        FieldPanel('beta_bar_text'),
    ]
示例#13
0
class BookIndexPage(GraphQLEnabledModel, Page):
    intro = MarkdownField(null=True)

    def child_pages(self):
        return BookPage.objects.live().child_of(self)

    content_panels = Page.content_panels + [
        MarkdownPanel('intro', classname='full')
    ]

    graphql_fields = [
        GraphQLField('intro'),
    ]

    subpage_types = ['BookPage']
示例#14
0
class BlogIndexPage(MetadataPageMixin, Page):
    sub_title = models.CharField(max_length=600, blank=True)
    body = MarkdownField(blank=True)
    image = models.ForeignKey('wagtailimages.Image', blank=True, null=True, on_delete=models.PROTECT, related_name='blog_index_image')

    content_panels = Page.content_panels + [
        FieldPanel("sub_title", classname="blog index title"),
        MarkdownPanel("body"),
        FieldPanel('image', classname="blog index image"),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('sub_title'),
        index.SearchField('body'),
    ]
示例#15
0
class ArticlePage(GraphQLEnabledModel, Page):
    """Article Pages"""

    date = models.DateTimeField(u"投稿日")
    tags = ClusterTaggableManager(verbose_name=u'タグ',
                                  through=ArticlePageTag,
                                  blank=True)
    body = MarkdownField(verbose_name=u'本文', blank=True)
    feed_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'画像',
    )
    author = models.ForeignKey(
        'author.AuthorPage',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'著者',
    )

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('tags'),
        MarkdownPanel("body", classname="full"),
        ImageChooserPanel('feed_image'),
        PageChooserPanel('author', 'author.AuthorPage'),
        InlinePanel('related_links', label=u'関連リンク'),
    ]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration"),
    ]

    graphql_fields = [
        GraphQLField('author'),
        GraphQLField('date'),
        GraphQLField('tags'),
        GraphQLField('slug'),
        GraphQLField('body'),
        GraphQLField('feed_image'),
        GraphQLField('related_links')
    ]
示例#16
0
class EntryAbstract(models.Model):
    body = MarkdownField(blank=True)
    verbose_name = _('body')
    tags = ClusterTaggableManager(through='puput.TagEntryPage', blank=True)
    date = models.DateTimeField(verbose_name=_("Post date"),
                                default=datetime.datetime.today)
    header_image = models.ForeignKey(get_image_model_path(),
                                     verbose_name=_('Header image'),
                                     null=True,
                                     blank=True,
                                     on_delete=models.SET_NULL,
                                     related_name='+')
    categories = models.ManyToManyField('puput.Category',
                                        through='puput.CategoryEntryPage',
                                        blank=True)
    excerpt = RichTextField(
        verbose_name=_('excerpt'),
        blank=True,
        help_text=_(
            "Entry excerpt to be displayed on entries list. "
            "If this field is not filled, a truncate version of body text will be used."
        ))
    num_comments = models.IntegerField(default=0, editable=False)

    content_panels = [
        MultiFieldPanel([
            FieldPanel('title', classname="title"),
            ImageChooserPanel('header_image'),
            FieldPanel('body', classname="full"),
            FieldPanel('excerpt', classname="full"),
        ],
                        heading=_("Content")),
        MultiFieldPanel([
            FieldPanel('tags'),
            InlinePanel('entry_categories', label=_("Categories")),
            InlinePanel('related_entrypage_from',
                        label=_("Related Entries"),
                        panels=[PageChooserPanel('entrypage_to')]),
        ],
                        heading=_("Metadata")),
    ]

    class Meta:
        abstract = True
示例#17
0
class HomePage(Page):
    home_title = models.CharField(max_length=600, blank=True)
    body = MarkdownField(blank=True)
    image = models.ForeignKey('wagtailimages.Image',
                              blank=True,
                              null=True,
                              on_delete=models.PROTECT,
                              related_name='home_image')

    content_panels = Page.content_panels + [
        FieldPanel("home_title", classname="Home title"),
        MarkdownPanel("body"),
        FieldPanel('image', classname="Home image"),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('title'),
        index.SearchField('body'),
    ]
示例#18
0
class BaseCompany(TimeStampedModel):
    name = models.CharField(max_length=200,
                            unique=True)
    location = models.ForeignKey('crm.City',
                                 on_delete=models.CASCADE)
    channel = models.ForeignKey('Channel',
                                on_delete=models.SET_NULL,
                                help_text="Lead channel this company came from",
                                null=True,
                                blank=True)
    url = models.URLField(blank=True,
                          null=True)
    notes = MarkdownField(default="", blank=True)

    def __str__(self):
        return self.name

    class Meta:
        abstract = True
        verbose_name_plural = 'clients'
        verbose_name = 'client'
示例#19
0
class BlogPage(MetadataPageMixin, Page):
    sub_title = models.CharField(max_length=600, blank=True)
    body = MarkdownField(blank=True)
    image = models.ForeignKey('wagtailimages.Image', blank=True, null=True, on_delete=models.PROTECT, related_name='blog_image')

    content_panels = Page.content_panels + [
        FieldPanel("sub_title", classname="blog title"),
        MarkdownPanel("body"),
        FieldPanel('image', classname="blog image"),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('sub_title'),
        index.SearchField('body'),
    ]

    def get_context(self, request):
        context = super(BlogPage, self).get_context(request)
        context['recommended'] = BlogPage.objects.live().exclude(id=self.id).order_by('?')[:5]
        context['surah'] = Chapter.objects.order_by('?')[:10]
        return context
示例#20
0
class BookPage(GraphQLEnabledModel, Page):

    price = models.IntegerField()
    published_date = models.DateField()
    published_event = models.CharField(max_length=50)
    description = MarkdownField(verbose_name=u'説明')
    booth_url = models.URLField(max_length=255, null=True)
    bookwalker_url = models.URLField(max_length=255, null=True)
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
    )

    content_panels = Page.content_panels + [
        FieldPanel('price'),
        FieldPanel('published_date'),
        FieldPanel('published_event'),
        MarkdownPanel('description'),
        FieldPanel('booth_url'),
        FieldPanel('bookwalker_url'),
        ImageChooserPanel('image'),
    ]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration"),
    ]

    graphql_fields = [
        GraphQLField('price'),
        GraphQLField('published_date'),
        GraphQLField('published_event'),
        GraphQLField('description'),
        GraphQLField('booth_url'),
        GraphQLField('bookwalker_url'),
        GraphQLField('image'),
        GraphQLField('slug')
    ]
示例#21
0
class Project(ProjectStateMixin, TimeStampedModel):
    company = models.ForeignKey('ClientCompany',
                                on_delete=models.SET_NULL,
                                null=True,
                                blank=True,
                                related_name='projects')

    manager = models.ForeignKey('Employee',
                                on_delete=models.SET_NULL,
                                null=True,
                                blank=True,
                                related_name='projects')
    location = models.ForeignKey('crm.City',
                                 related_name='projects',
                                 on_delete=models.CASCADE)

    original_description = RichTextField()
    original_url = models.URLField(null=True, blank=True)

    notes = MarkdownField(null=True, blank=True)
    daily_rate = models.DecimalField(
        decimal_places=2,
        max_digits=6,
        null=True,
        blank=True
    )

    start_date = models.DateField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)

    project_page = models.ForeignKey('home.ProjectPage',
                                     on_delete=models.SET_NULL,
                                     null=True,
                                     blank=True)

    messages = models.ManyToManyField('django_mailbox.Message',
                                      through='ProjectMessage',
                                      related_name="projects",
                                      editable=False)

    @property
    def recruiter(self):
        return self.manager.company if self.manager else None

    @property
    def duration(self):
        try:
            return math.ceil((self.end_date - self.start_date).days / 30)
        except TypeError:
            pass

    def get_duration_display(self):
        return f"{self.duration} months"

    def get_original_description_display(self):
        return SafeText(self.original_description)

    def get_notes_display(self):
        return SafeText(render_markdown(self.notes))

    def get_project_page_display(self):
        if not self.project_page:
            return
        url = reverse("wagtailadmin_pages:edit", args=(self.project_page.pk,))
        return SafeText(
            f"<a href='{url}'>{self.project_page}</a>"
        )

    @property
    def budget(self):
        if not self.start_date or not self.end_date:
            return
        working_days = len(get_working_days(self.start_date, self.end_date))
        if not self.daily_rate:
            return
        return self.daily_rate * working_days

    @property
    def vat(self):
        if not self.budget:
            return
        return self.budget * settings.VAT_RATE

    @property
    def invoice_amount(self):
        if not self.vat:
            return
        return self.budget + self.vat

    @property
    def income_tax(self):
        if not self.budget:
            return
        return self.budget * settings.INCOME_TAX_RATE

    @property
    def nett_income(self):
        if not self.budget or not self.income_tax:
            return
        return self.budget - self.income_tax

    @property
    def working_days(self):
        if not self.start_date or not self.end_date:
            return
        return len(get_working_days(self.start_date, self.end_date))

    def get_budget_display(self):
        return f"{self.budget} €" if self.budget else None

    def get_vat_display(self):
        return f"{self.vat:.2f} €" if self.vat else None

    def get_invoice_amount_display(self):
        return f"{self.invoice_amount:.2f} €" if self.invoice_amount else None

    def get_income_tax_display(self):
        return f"{self.income_tax:.2f} €" if self.income_tax else None

    def get_nett_income_display(self):
        return f"{self.nett_income:.2f} €" if self.nett_income else None

    def clean(self):
        if self.start_date and self.end_date and self.start_date >= self.end_date:
            raise ValidationError(
                {
                    "start_date": "End date can't be earlier than start date",
                    "end_date": "End date can't be earlier than start date",
                }
            )

    def save(self, *args, **kwargs):
        if not self.daily_rate and self.recruiter:
            self.daily_rate = self.recruiter.default_daily_rate
        super().save(*args, **kwargs)

    def __str__(self):
        return str(self.company or self.recruiter)

    class Meta:
        verbose_name_plural = "projects"
示例#22
0
class AuthorPage(GraphQLEnabledModel, Page):
    profile = MarkdownField(verbose_name=u'プロフィール')
    nickname = models.CharField(verbose_name=u'ニックネーム',
                                max_length=25,
                                null=True,
                                blank=True)
    first_name = models.CharField(verbose_name=u'名',
                                  max_length=10,
                                  null=True,
                                  blank=True)
    middle_name = models.CharField(verbose_name=u'ミドルネーム',
                                   max_length=10,
                                   null=True,
                                   blank=True)
    family_name = models.CharField(verbose_name=u'姓',
                                   max_length=10,
                                   null=True,
                                   blank=True)
    name = models.CharField(verbose_name=u'表示名',
                            max_length=80,
                            null=True,
                            blank=True)
    is_surname_first = models.BooleanField(verbose_name=u'姓が先の表記',
                                           null=True,
                                           blank=True)
    use_nickname = models.BooleanField(verbose_name=u'ニックネームの使用',
                                       null=True,
                                       blank=True)
    portrait = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        verbose_name=u'画像',
    )
    interest = ClusterTaggableManager(verbose_name=u'興味を持っていること',
                                      through=AuthorPageInterest,
                                      blank=True)

    content_panels = Page.content_panels + [
        MarkdownPanel('profile'),
        ImageChooserPanel('portrait'),
        FieldPanel('interest'),
        FieldPanel('nickname'),
        FieldPanel('first_name'),
        FieldPanel('middle_name'),
        FieldPanel('family_name'),
        FieldPanel('name'),
        FieldPanel('is_surname_first'),
        FieldPanel('use_nickname'),
        InlinePanel('portfolio_links', label=u'ポートフォリオ'),
        InlinePanel('amazon_wish_list_links', label=u'Amazonのほしいものリスト'),
        InlinePanel('sns_links', label=u'SNSなどのリンク'),
    ]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration"),
    ]

    graphql_fields = [
        GraphQLField('name'),
        GraphQLField('profile'),
        GraphQLField('portrait'),
        GraphQLField('interest'),
        GraphQLField('portfolio_links'),
        GraphQLField('amazon_wish_list_links'),
        GraphQLField('sns_links'),
    ]

    def clean(self):
        """Rename title when posted."""
        if self.nickname is not None and self.use_nickname is True:
            self.name = self.nickname
        elif self.is_surname_first is True:
            if self.middle_name is None:
                self.name = self.family_name + u' ' + self.first_name
            else:
                self.name = (self.family_name + u' ' + self.middle_name +
                             u' ' + self.first_name)
        else:
            if self.middle_name is None:
                self.name = self.first_name + u' ' + self.family_name
            else:
                self.name = (self.first_name + u' ' + self.middle_name + u' ' +
                             self.family_name)

        self.title = '%s のプロフィール' % self.name
示例#23
0
class TestPage(Page):
    body = MarkdownField(blank=True)
    content_panels = Page.content_panels + [FieldPanel("body")]
示例#24
0
class Action(models.Model):
    name = models.CharField(max_length=255, db_index=True)
    when = models.DateTimeField(db_index=True)
    description = MarkdownField(default="", blank=True, help_text="Markdown formatted")
    slug = models.SlugField(unique=True, help_text="Short form of the title, for URLs")
    public = models.BooleanField(
        default=True,
        blank=True,
        help_text="Whether this action should be listed publicly",
    )
    location = models.TextField(
        default="",
        blank=True,
        help_text="Event location will be converted to a google maps link, unless you format it as a Markdown link -- [link text](http://example.com)",
    )
    virtual = models.BooleanField(
        default=False,
        help_text="Check this if the event is online (virtual zoom or other video conferencing)",
    )
    available_roles = models.CharField(
        default="",
        blank=True,
        max_length=255,
        help_text="List of comma-separated strings",
    )
    # Will need to figure out how to migrate this over.
    photos = models.ManyToManyField(Photo, blank=True)
    image = models.ForeignKey(
        "vaquita.CustomImage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )

    modified = models.DateTimeField(auto_now=True)
    show_commitment = models.BooleanField(
        blank=True,
        default=False,
        help_text="Whether to show the conditional commitment fields",
    )
    max_participants = models.IntegerField(
        blank=True, default=0, help_text="Maximun number of people allowed to register"
    )
    accessibility = models.TextField(
        default="",
        help_text="Indicate what the accessibility accomodations are for this location.",
    )
    contact_email = models.TextField(
        default="", null=True, help_text="Contact info of event organizer."
    )

    tags = TaggableManager(
        blank=True, help_text="Attendees will automatically be tagged with these tags"
    )
    objects = ActionManager()

    panels = [
        MultiFieldPanel(
            [
                FieldPanel("name", widget=forms.TextInput(attrs={"id": "id_title"})),
                FieldPanel("when"),
                FieldPanel("virtual"),
                FieldPanel("location"),
                FieldPanel("slug"),
            ]
        ),
        FieldPanel("contact_email"),
        MarkdownPanel("description", widget=ZOrderMarkdownTextarea),
        ImageChooserPanel("image"),
        FieldPanel("tags"),
        FieldRowPanel(
            [
                FieldPanel("public"),
                FieldPanel("max_participants"),
                FieldPanel("show_commitment"),
            ]
        ),
        FieldPanel("accessibility"),
    ]

    @property
    def available_role_choices(self):
        for role in self.available_roles.split(","):
            role = role.strip()
            if role:
                yield role

    def is_full(self):
        return (
            self.max_participants and self.attendee_set.count() >= self.max_participants
        )

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

    @property
    def full_url(self):
        return f"{base_url()}{self.get_absolute_url()}"

    def signup(self, email, role, name="", notes="", promised=None, commit=0):
        if not isinstance(role, ActionRole):
            role = ActionRole.objects.get_or_create(name=role or "")[0]

        user = get_contact(email, name=name)
        atten, created = Attendee.objects.get_or_create(
            action=self, contact=user, role=role
        )
        if not created:
            if notes:
                atten.notes = notes
        else:
            atten.notes = notes
            atten.mutual_commitment = commit
        if promised:
            atten.promised = now()
        atten.save()
        return atten

    @property
    def html_title(self):
        return mark_safe(self.name.replace("\n", "<br>").replace("\\n", "<br>"))

    @property
    def text_title(self):
        return self.name.replace("\\n", " ")

    def __str__(self):
        return f"{self.name} on {self.when.strftime('%b %e, %Y @ %H:%M')}"

    def save(self, *args, **kwargs):
        ret = super().save(*args, **kwargs)
        for role in self.available_role_choices:
            ActionRole.objects.get_or_create(name=role)
        return ret

    @property
    def location_link(self):
        if self.location.startswith("["):
            link = markdown(self.location)
        else:
            if self.virtual:
                link_text = "Online Meeting"
            else:
                link_text = self.location
            # See if the text is already a valid url.
            url_validator = URLValidator(schemes=["http", "https"])
            try:
                url_validator(self.location)
                link = f"<a href={self.location}>{link_text}</a>"
            except ValidationError:
                if self.virtual:
                    link = "/" # validation should have seen to this.
                else:
                    link = '<a href="https://maps.google.com/?q={}">{}</a>'.format(
                        quote(self.location), linebreaks(self.location)
                    )
                pass
        return mark_safe(link)

    @property
    def card_thumbnail_url(self):
        if self.photos:
            photo = self.photos.first()
            if photo:
                return photo.photo.url
        return None
示例#25
0
class BaseResumePage(MetadataMixin, Page):
    page_ptr = models.OneToOneField(Page,
                                    parent_link=True,
                                    related_name="+",
                                    on_delete=models.CASCADE)
    is_creatable = False

    font = models.CharField(max_length=100, null=True, blank=True)
    background_color = models.CharField(max_length=100, null=True, blank=True)

    full_name = models.CharField(max_length=100, null=True, blank=True)

    role = models.CharField(max_length=100, null=True, blank=True)
    about = MarkdownField(max_length=2500, null=True, blank=True)
    photo = models.ForeignKey(Image,
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name="+")
    social_links = fields.StreamField(
        [
            (
                "social_link",
                blocks.StructBlock(
                    [
                        ("text", blocks.TextBlock()),
                        ("url", blocks.URLBlock()),
                        ("logo", ImageChooserBlock()),
                    ],
                    icon="group",
                ),
            ),
        ],
        null=True,
        blank=True,
    )

    resume = fields.StreamField(
        [
            ("work_experience", WorkExperienceBlock()),
            ("contributions", ContributionsBlock()),
            ("writing", WritingsBlock()),
            ("education", EducationBlock()),
        ],
        null=True,
        blank=True,
    )

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel("font"),
                FieldPanel("background_color"),
            ],
            heading="Customization",
        ),
        MultiFieldPanel(
            [
                FieldPanel("full_name"),
                FieldPanel("role"),
                MarkdownPanel("about"),
                ImageChooserPanel("photo"),
                StreamFieldPanel("social_links"),
            ],
            heading="Personal details",
        ),
        StreamFieldPanel("resume"),
    ]

    def get_template(self, request):
        return "wagtail_resume/resume_page.html"

    def get_meta_title(self):
        return self.full_name

    def get_meta_description(self):
        return f"{self.full_name} - {self.role}"

    def get_meta_image(self):
        return self.photo

    def get_meta_url(self):
        return self.get_full_url

    def get_meta_twitter_card_type(self):
        return self.photo
示例#26
0
 def test_markdown_field(self):
     field = MarkdownField()
     self.assertEqual(type(field.formfield().widget), MarkdownTextarea)
示例#27
0
class BlogPage(Page):
    """ This is the core of the Blog app. BlogPage are individual articles
    """
    subtitle = models.CharField(blank=True, max_length=255)

    body = MarkdownField(blank=True)

    extended_body = StreamField([
        ('content', MarkdownBlock(template='blog/markdown_block.html')),
        ('newsletter', NewsletterSubscribe()),
        ('book', BookInline()),
    ],
                                null=True)

    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text='Header Image, used also for social sharing')

    image_data = RichTextField(
        blank=True,
        null=True,
        help_text=
        'Information about the header image, to appear after the article')

    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
    date_published = models.DateField("Date article published",
                                      blank=True,
                                      null=True)

    allow_comments = models.BooleanField(default=True)

    content_panels = Page.content_panels + [
        FieldPanel('subtitle'),
        StreamFieldPanel('extended_body'),
        MarkdownPanel('body'),
        ImageChooserPanel('image'),
        FieldPanel('image_data'),
        FieldPanel('date_published'),
        InlinePanel('blog_person_relationship',
                    label="Author(s)",
                    panels=None,
                    min_num=1),
        FieldPanel('tags'),
    ]

    promote_panels = Page.promote_panels + [
        FieldPanel('allow_comments'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('body'),
    ]

    def authors(self):
        """
        Returns the BlogPage's related People. Again note that we are using
        the ParentalKey's related_name from the BlogPeopleRelationship model
        to access these objects. This allows us to access the People objects
        with a loop on the template. If we tried to access the blog_person_
        relationship directly we'd print `blog.BlogPeopleRelationship.None`
        """
        authors = [n.people for n in self.blog_person_relationship.all()]

        return authors

    @property
    def first_author(self):
        return self.authors()[-1]

    @property
    def get_tags(self):
        """
        Similar to the authors function above we're returning all the tags that
        are related to the blog post into a list we can access on the template.
        We're additionally adding a URL to access BlogPage objects with that tag
        """
        tags = self.tags.all()
        for tag in tags:
            tag.url = '/' + '/'.join(
                s.strip('/')
                for s in [self.get_parent().url, 'tags', tag.slug])
        return tags

    # Specifies parent to BlogPage as being BlogIndexPages
    parent_page_types = ['BlogIndexPage']

    # Specifies what content types can exist as children of BlogPage.
    # Empty list means that no child content types are allowed.
    subpage_types = []

    def get_absolute_url(self):
        return self.specific.url

    def get_context(self, request):
        context = super(BlogPage, self).get_context(request)
        context['latest_articles'] = BlogPage.objects.live().order_by(
            '-date_published')[:5]
        context['intro_class'] = 'blog article'
        return context

    @property
    def introduction(self):
        html = render_markdown(self.body)
        soup = BeautifulSoup(html, "html.parser")
        try:
            introduction = soup.find('p').text
            return introduction
        except AttributeError:
            return None

    class Meta:
        ordering = ['-date_published']
示例#28
0
class IndexDetailPage(Page):
    about = MarkdownField(null=True, blank=True)
    sourceforabouttext = models.CharField("Source for about text",
                                          max_length=255,
                                          null=True,
                                          blank=True)
    categories = ParentalManyToManyField("index.IndexCategory", blank=True)
    pub_date = models.PositiveSmallIntegerField("Date Published / Created",
                                                null=True,
                                                blank=True)
    end_date = models.PositiveSmallIntegerField("End Date",
                                                null=True,
                                                blank=True)
    author_founder = models.CharField("Author/Founder",
                                      max_length=500,
                                      null=True,
                                      blank=True)
    contributed_by = models.CharField("Contributed By",
                                      max_length=500,
                                      null=True,
                                      blank=True)
    external_link = models.URLField(null=True, blank=True)
    external_link_two = models.URLField(null=True, blank=True)
    autoincrement_num = models.PositiveSmallIntegerField(null=True, blank=True)
    rownum = models.PositiveSmallIntegerField(null=True, blank=True)
    location = models.CharField("location",
                                max_length=255,
                                null=True,
                                blank=True)
    # slug = models.SlugField(verbose_name=_('slug'), allow_unicode=True, max_length=255)

    search_fields = Page.search_fields + [
        index.SearchField('title'),
        index.SearchField('author_founder'),
        index.SearchField('about'),
        index.SearchField('contributed_by'),
        index.SearchField('location'),
        index.SearchField('pub_date'),
        index.SearchField('end_date'),
    ]

    content_panels = Page.content_panels + [
        MarkdownPanel('about', classname="full"),
        MultiFieldPanel([
            FieldRowPanel([
                FieldPanel('pub_date'),
                FieldPanel('end_date'),
            ]),
            FieldRowPanel([
                FieldPanel('author_founder'),
                FieldPanel('location'),
            ]),
            FieldRowPanel([
                FieldPanel('external_link'),
                FieldPanel('external_link_two'),
            ]),
            FieldRowPanel([
                FieldPanel('contributed_by'),
            ]),
        ], 'Details'),
        MultiFieldPanel(
            [
                InlinePanel('images_list', label='Image'),
            ],
            heading="Image(s)",
        ),
        MultiFieldPanel(
            [FieldPanel("categories", widget=forms.CheckboxSelectMultiple)],
            heading="Categories"),
        MultiFieldPanel(
            [
                InlinePanel('collections_list', label='Curator'),
            ],
            heading="Curator(s)",
        ),
    ]

    promote_panels = []

    class Meta:  # noqa
        verbose_name = "Index Detail Page"
        verbose_name_plural = "Index Detail Pages"