add wordpress migration

This commit is contained in:
2024-08-09 01:56:00 +02:00
parent d1be264bc5
commit 1bb0fd252f
36 changed files with 1234 additions and 63 deletions

View File

@ -1,7 +1,9 @@
from django import forms
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Min, Q, UniqueConstraint
from django.utils import timezone
from django.utils.html import mark_safe
from django.utils.translation import gettext_lazy as _
from grapple.helpers import register_query_field, register_singular_query_field
from grapple.models import (
@ -9,7 +11,6 @@ from grapple.models import (
GraphQLCollection,
GraphQLForeignKey,
GraphQLImage,
GraphQLInt,
GraphQLStreamfield,
GraphQLString,
)
@ -27,6 +28,7 @@ from wagtail.admin.panels import (
from wagtail.models import Orderable, Page, PageManager, PageQuerySet
from wagtail.search import index
from wagtail.snippets.models import register_snippet
from wagtail_wordpress_import.models import WPImportedPageMixin
from associations.widgets import AssociationChooserWidget
from dnscms.fields import CommonStreamField
@ -226,7 +228,7 @@ class EventPageQuerySet(PageQuerySet):
EventPageManager = PageManager.from_queryset(EventPageQuerySet)
class EventPage(Page):
class EventPage(WPImportedPageMixin, Page):
subpage_types = []
parent_page_types = ["events.EventIndex"]
show_in_menus = False
@ -283,19 +285,19 @@ class EventPage(Page):
ticket_url = models.URLField(
blank=True,
max_length=512,
max_length=1024,
help_text="Lenke direkte til billettkjøp, f.eks. TicketCo eller Ticketmaster",
)
facebook_url = models.URLField(
blank=True,
max_length=512,
max_length=1024,
help_text="Lenke direkte til arrangementet på Facebook",
)
free = models.BooleanField(null=False, default=False)
price_regular = models.IntegerField(null=True, blank=True)
price_student = models.IntegerField(null=True, blank=True)
price_member = models.IntegerField(null=True, blank=True)
price_regular = models.CharField(max_length=32, blank=True)
price_student = models.CharField(max_length=32, blank=True)
price_member = models.CharField(max_length=32, blank=True)
ticket_panels = [
FieldPanel("free", heading="Gratis", help_text="Er dette arrangementet gratis for alle?"),
@ -309,7 +311,11 @@ class EventPage(Page):
],
help_text="",
),
HelpPanel(content="La alle prisfeltene stå tomme om arrangementet er gratis."),
HelpPanel(
content=mark_safe(
"Skriv <strong>0</strong> om gratis. Tomt felt skjuler priskategorien. Om mulig, skriv kun tall."
)
),
],
attrs={"id": "specific_pricing_panel"},
),
@ -328,7 +334,7 @@ class EventPage(Page):
content=("Hvem står bak arrangementet?"),
),
MultipleChooserPanel(
"organizer_links", chooser_field_name="organizer", min_num=1, label="Arrangør"
"organizer_links", chooser_field_name="organizer", label="Arrangør"
),
],
),
@ -361,9 +367,9 @@ class EventPage(Page):
GraphQLString("ticket_url"),
GraphQLString("facebook_url"),
GraphQLBoolean("free"),
GraphQLInt("price_regular"),
GraphQLInt("price_student"),
GraphQLInt("price_member"),
GraphQLString("price_regular"),
GraphQLString("price_student"),
GraphQLString("price_member"),
GraphQLCollection(
GraphQLForeignKey,
"categories",
@ -404,9 +410,133 @@ class EventPage(Page):
# if the event is free, all specific pricing is unset
if self.free:
self.price_regular = None
self.price_student = None
self.price_member = None
self.price_regular = ""
self.price_student = ""
self.price_member = ""
settings_panels = Page.settings_panels + WPImportedPageMixin.wordpress_panels
def import_wordpress_data(self, data):
import datetime
import html
from django.core.validators import URLValidator
from zoneinfo import ZoneInfo
validate_url = URLValidator(schemes=["http", "https"])
def fix_url(url):
if not url:
return None
url = url.strip()
try:
validate_url(url)
except Exception:
print(f"Bogus URL for {self.wp_post_id}: {url}")
return None
return url
# Wagtail page model fields
self.title = html.unescape(data["title"])
self.slug = data["slug"]
self.first_published_at = data["first_published_at"]
self.last_published_at = data["last_published_at"]
self.latest_revision_created_at = data["latest_revision_created_at"]
self.search_description = data["search_description"]
# debug fields
self.wp_post_id = data["wp_post_id"]
self.wp_post_type = data["wp_post_type"]
self.wp_link = data["wp_link"]
self.wp_raw_content = data["wp_raw_content"]
self.wp_block_json = data["wp_block_json"]
self.wp_processed_content = data["wp_processed_content"]
self.wp_normalized_styles = data["wp_normalized_styles"]
self.wp_post_meta = data["wp_post_meta"]
# own model fields
self.body = data["body"] or ""
# categories (organizers and event types)
wp_categories = data["wp_categories"]
# organizers
organizer_cats = [x for x in wp_categories if x["domain"] == "event_organizer"]
organizers = []
for x in organizer_cats:
try:
organizer = EventOrganizer.objects.get(slug=x["nicename"])
except EventOrganizer.DoesNotExist:
organizer = EventOrganizer.objects.create(name=x["name"], slug=x["nicename"])
organizers.append(organizer)
self.organizer_links.set(
[EventOrganizerLink(event=self, organizer=organizer) for organizer in organizers]
)
## event types
# type_cats = [x for x in wp_categories if x["domain"] == "event_type"]
# event_categories = []
# for x in type_cats:
# try:
# event_category = EventCategory.objects.get(slug=x["nicename"])
# except EventCategory.DoesNotExist:
# event_category = EventCategory.objects.create(
# name=x["name"], slug=x["nicename"], show_in_filters=False
# )
# event_categories.append(event_category)
# self.categories.set(event_categories)
meta = data["wp_post_meta"]
start_ts = meta.get("neuf_events_starttime") or 1337
end_ts = meta.get("neuf_events_endtime")
tz = ZoneInfo("Europe/Oslo")
start = start_ts and datetime.datetime.fromtimestamp(start_ts, datetime.UTC).replace(
tzinfo=tz
)
end = end_ts and datetime.datetime.fromtimestamp(end_ts, datetime.UTC).replace(tzinfo=tz)
venue_id = meta.get("neuf_events_venue_id")
venue_custom = meta.get("neuf_events_venue")
venue = None
if venue_id:
venue = VenuePage.objects.get(wp_post_id=venue_id)
venue_custom = ""
else:
venue_custom = venue_custom or ""
occurrence = EventOccurrence(
event=self, start=start, end=end, venue=venue, venue_custom=venue_custom
)
self.occurrences.set([occurrence])
self.ticket_url = fix_url(meta.get("neuf_events_bs_url")) or ""
self.facebook_url = fix_url(meta.get("neuf_events_fb_url")) or ""
def parse_price(price):
if price is None:
return ""
if type(price) is int:
return price
p = price.strip()
if p == "":
return ""
try:
return int(p)
except ValueError:
pass
free = ["gratis", "free", "gratis/free", "free/gratis"]
if p.lower() in free:
return 0
return price
price_regular = parse_price(meta.get("neuf_events_price_regular"))
price_member = parse_price(meta.get("neuf_events_price_member"))
if not price_regular and not price_member:
self.free = True
else:
self.price_regular = parse_price(meta.get("neuf_events_price_regular"))
self.price_member = parse_price(meta.get("neuf_events_price_member"))
class EventOccurrence(Orderable):
@ -414,7 +544,19 @@ class EventOccurrence(Orderable):
start = models.DateTimeField()
end = models.DateTimeField(null=True, blank=True)
venue = models.ForeignKey(
VenuePage, on_delete=models.PROTECT, related_name="event_occurrences"
VenuePage,
on_delete=models.PROTECT,
related_name="event_occurrences",
blank=True,
null=True,
)
venue_custom = models.CharField(
blank=True,
max_length=128,
help_text=mark_safe(
"Bruk denne <em>om ingen av lokalene som kan velges til venstre</em> passer. "
"F.eks. <em>Frederikkeplassen</em> eller <em>Sirkusteltet</em>."
),
)
panels = [
@ -424,7 +566,12 @@ class EventOccurrence(Orderable):
FieldPanel("end", heading="Slutt"),
],
),
FieldPanel("venue", heading="Lokale"),
FieldRowPanel(
children=[
FieldPanel("venue", heading="Lokale"),
FieldPanel("venue_custom", heading="Lokale som fritekst"),
],
),
]
graphql_fields = [
@ -433,6 +580,14 @@ class EventOccurrence(Orderable):
GraphQLForeignKey("venue", "venues.VenuePage"),
]
def clean(self):
if self.venue and self.venue_custom:
raise ValidationError(
{"venue_custom": "Du kan ikke både velge et lokale og skrive noe i dette feltet."}
)
if not self.venue and not self.venue_custom:
raise ValidationError({"venue": "Lokale er påkrevd."})
def __str__(self):
return f"{self.start}--{self.end}"