kopia lustrzana https://github.com/wagtail/bakerydemo
Porównaj commity
5 Commity
1397be4c41
...
39356b7522
Autor | SHA1 | Data |
---|---|---|
rachelhsmith | 39356b7522 | |
Rohit Sharma | baff48b7d9 | |
Rachel Smith | bd375e783a | |
Rachel Smith | ccd4526a2d | |
Rachel Smith | 12c69b9679 |
|
@ -0,0 +1,157 @@
|
|||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils import timezone
|
||||
from django.utils.text import slugify
|
||||
from wagtail.rich_text import RichText
|
||||
from django.core.files.base import ContentFile
|
||||
from wagtail.images.models import Image
|
||||
from django.db import IntegrityError
|
||||
|
||||
from bakerydemo.blog.models import BlogIndexPage, BlogPage, BlogPersonRelationship
|
||||
from bakerydemo.base.models import Person
|
||||
import requests
|
||||
import json
|
||||
import random
|
||||
import datetime
|
||||
from wagtail.models import Collection
|
||||
|
||||
from openai import OpenAI
|
||||
|
||||
FIXTURE_MEDIA_DIR = Path(settings.PROJECT_DIR) / "base/fixtures/media/original_images"
|
||||
client = OpenAI()
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Creates generated Page data using chatGPT. Useful for demonstrating different use cases."
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--page_count",
|
||||
type=int,
|
||||
help="How many blog pages to create",
|
||||
)
|
||||
|
||||
def make_stream_field_content(self, title, subtitle, collection_name):
|
||||
# get random images for the blog from the generated set
|
||||
image_1 = self.get_random_image(Image, collection_name)
|
||||
image_2 = self.get_random_image(Image, collection_name)
|
||||
# generate rich text for the content
|
||||
prompt = f"""Please give me three paragraphs of content for a blog post called '{title}' with the subtitle '{subtitle}'. They should in JSON of the form {{"paragraph_1": "<p>example</p>", "paragraph_2": "<p>example</p>", "paragraph_3: "<p>example<p>"}} where example is replaced with html content. You may use <p>,<h2>,<h3> and <h4> tags as well as lists. It is the entire blog post so make sure to conclude at the end."""
|
||||
chat_completion = client.chat.completions.create(
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": prompt,
|
||||
}
|
||||
],
|
||||
model="gpt-4",
|
||||
)
|
||||
streamfield_chat_completion = chat_completion.choices[0].message.content.replace('\n', "")
|
||||
json_streamfield_chat_completion = json.loads(streamfield_chat_completion)
|
||||
|
||||
return [('paragraph_block', RichText(json_streamfield_chat_completion["paragraph_1"])),
|
||||
('image_block', {'image': image_1}),
|
||||
('paragraph_block', RichText(json_streamfield_chat_completion["paragraph_2"])),
|
||||
('image_block', {'image': image_2}),
|
||||
('paragraph_block', RichText(json_streamfield_chat_completion["paragraph_3"])),
|
||||
]
|
||||
|
||||
|
||||
def generate_images(self, theme, number_of_images, collection_name):
|
||||
for _ in range(number_of_images):
|
||||
print("Generating image...")
|
||||
prompt = f"an image for blog post about {theme}"
|
||||
response = client.images.generate(
|
||||
model="dall-e-3",
|
||||
prompt=prompt,
|
||||
size="1024x1024",
|
||||
quality="standard",
|
||||
n=1,
|
||||
)
|
||||
# Download the image
|
||||
image_url = response.data[0].url
|
||||
response = requests.get(image_url)
|
||||
# Get or create a collection for the generated images
|
||||
try:
|
||||
collection, created = Collection.objects.get_or_create(name=collection_name)
|
||||
except IntegrityError:
|
||||
root_coll = Collection.get_first_root_node()
|
||||
collection = root_coll.add_child(name=collection_name)
|
||||
|
||||
if response.status_code == 200:
|
||||
# Create a Django ContentFile with the image content
|
||||
image_content = ContentFile(response.content)
|
||||
wagtail_image = Image(title=prompt, collection=collection)
|
||||
wagtail_image.file.save(f"{prompt}.jpg", image_content, save=True)
|
||||
|
||||
def make_title(self, theme):
|
||||
chat_completion = client.chat.completions.create(
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Create a unique and creative title for a blog post about {theme}. Aim for originality and surprise me with your choice. It should be of the format title: subtitle. Don't include the words title or subtitle in your response",
|
||||
}
|
||||
],
|
||||
model="gpt-4",
|
||||
)
|
||||
content = chat_completion.choices[0].message.content.strip("'").strip('"')
|
||||
title, subtitle = content.split(":", 1)
|
||||
print(f'title: {title}, subtitle: {subtitle}')
|
||||
return title, subtitle
|
||||
|
||||
def make_intro(self, title, subtitle):
|
||||
chat_completion = client.chat.completions.create(
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"Based on the title '{title}' and the subtitle '{subtitle}', create an introduction paragraph for this blog post. Don't repeat the title or the subtitle.",
|
||||
}
|
||||
],
|
||||
model="gpt-4",
|
||||
)
|
||||
content = chat_completion.choices[0].message.content.strip("'")
|
||||
return content
|
||||
|
||||
def get_random_image(self, model, collection_name):
|
||||
return model.objects.filter(collection__name=collection_name).order_by("?").first()
|
||||
|
||||
def get_random_model(self, model):
|
||||
return model.objects.order_by("?").first()
|
||||
|
||||
def get_random_recent_date(self):
|
||||
now = timezone.now()
|
||||
random_day_diff = random.randint(0, 365)
|
||||
random_date = now - datetime.timedelta(days=random_day_diff)
|
||||
return random_date
|
||||
|
||||
def create_pages(self, page_count, theme, collection_name):
|
||||
self.stdout.write("Creating blog pages...")
|
||||
blog_index = BlogIndexPage.objects.live().first()
|
||||
for _ in range(page_count):
|
||||
title, subtitle = self.make_title(theme)
|
||||
new_blog_page = BlogPage(
|
||||
title=title,
|
||||
image=self.get_random_image(Image, collection_name),
|
||||
slug=slugify(title),
|
||||
introduction=self.make_intro(title, subtitle),
|
||||
body=self.make_stream_field_content(title, subtitle, collection_name),
|
||||
subtitle=subtitle,
|
||||
date_published=self.get_random_recent_date(),
|
||||
)
|
||||
blog_index.add_child(instance=new_blog_page)
|
||||
# add an author
|
||||
BlogPersonRelationship.objects.create(page=new_blog_page, person=self.get_random_model(Person))
|
||||
|
||||
def handle(self, **options):
|
||||
theme = input('What should the blog posts be about? ')
|
||||
page_count = int(input('How many blog posts should be created? '))
|
||||
generate_images = input('Do you want to create new images? (y/n): ').lower().strip()
|
||||
if generate_images == 'y':
|
||||
number_of_images = int(input('How many images should be created? '))
|
||||
collection_name = input('What should the collection to keep these images in be called? (Or what is the name of an existing one?) ')
|
||||
else:
|
||||
number_of_images = 0
|
||||
collection_name = input('Which collection do you want to take images from? ')
|
||||
self.generate_images(theme, number_of_images, collection_name)
|
||||
self.create_pages(page_count, theme, collection_name)
|
|
@ -480,7 +480,7 @@ class FormPage(AbstractEmailForm):
|
|||
]
|
||||
|
||||
|
||||
@register_setting
|
||||
@register_setting(icon="cog")
|
||||
class GenericSettings(ClusterableModel, BaseGenericSetting):
|
||||
twitter_url = models.URLField(verbose_name="Twitter URL", blank=True)
|
||||
github_url = models.URLField(verbose_name="GitHub URL", blank=True)
|
||||
|
@ -498,7 +498,7 @@ class GenericSettings(ClusterableModel, BaseGenericSetting):
|
|||
]
|
||||
|
||||
|
||||
@register_setting
|
||||
@register_setting(icon="site")
|
||||
class SiteSettings(BaseSiteSetting):
|
||||
title_suffix = models.CharField(
|
||||
verbose_name="Title suffix",
|
||||
|
|
Ładowanie…
Reference in New Issue