use json format for crew & actors
This commit is contained in:
parent
26c8b42e64
commit
6c9dd620f3
8 changed files with 113 additions and 23 deletions
|
@ -1,8 +1,35 @@
|
|||
from catalog.common import *
|
||||
from functools import cached_property
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.db import models
|
||||
from catalog.common import *
|
||||
from catalog.common.utils import DEFAULT_ITEM_COVER
|
||||
from functools import cached_property
|
||||
|
||||
|
||||
_CREW_SCHEMA = {
|
||||
"type": "list",
|
||||
"items": {
|
||||
"type": "dict",
|
||||
"keys": {
|
||||
"name": {"type": "string", "title": _("名字")},
|
||||
"role": {"type": "string", "title": _("职能")},
|
||||
},
|
||||
"required": ["role", "name"],
|
||||
},
|
||||
"uniqueItems": True,
|
||||
}
|
||||
|
||||
_ACTOR_SCHEMA = {
|
||||
"type": "list",
|
||||
"items": {
|
||||
"type": "dict",
|
||||
"keys": {
|
||||
"name": {"type": "string", "title": _("名字"), "placeholder": _("演员名字,必填")},
|
||||
"role": {"type": "string", "title": _("角色"), "placeholder": _("也可不填写")},
|
||||
},
|
||||
"required": ["name"],
|
||||
},
|
||||
"uniqueItems": True,
|
||||
}
|
||||
|
||||
|
||||
class Performance(Item):
|
||||
|
@ -69,8 +96,15 @@ class Performance(Item):
|
|||
blank=True,
|
||||
default=list,
|
||||
)
|
||||
performer = jsondata.ArrayField(
|
||||
actor = jsondata.JSONField(
|
||||
verbose_name=_("演员"),
|
||||
null=False,
|
||||
blank=True,
|
||||
default=list,
|
||||
schema=_ACTOR_SCHEMA,
|
||||
)
|
||||
performer = jsondata.ArrayField(
|
||||
verbose_name=_("表演者"),
|
||||
base_field=models.CharField(blank=True, default="", max_length=500),
|
||||
null=False,
|
||||
blank=True,
|
||||
|
@ -83,12 +117,12 @@ class Performance(Item):
|
|||
blank=True,
|
||||
default=list,
|
||||
)
|
||||
crew = jsondata.ArrayField(
|
||||
crew = jsondata.JSONField(
|
||||
verbose_name=_("其他演职人员和团体"),
|
||||
base_field=models.CharField(blank=True, default="", max_length=500),
|
||||
null=False,
|
||||
blank=True,
|
||||
default=list,
|
||||
schema=_CREW_SCHEMA,
|
||||
)
|
||||
location = jsondata.ArrayField(
|
||||
verbose_name=_("剧场空间"),
|
||||
|
@ -98,7 +132,10 @@ class Performance(Item):
|
|||
default=list,
|
||||
)
|
||||
opening_date = jsondata.CharField(
|
||||
verbose_name=_("首演日期"), max_length=100, null=True, blank=True
|
||||
verbose_name=_("首演日期"),
|
||||
max_length=100,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
closing_date = jsondata.CharField(
|
||||
verbose_name=_("结束日期"), max_length=100, null=True, blank=True
|
||||
|
@ -122,6 +159,7 @@ class Performance(Item):
|
|||
"orig_creator",
|
||||
"composer",
|
||||
"choreographer",
|
||||
"actor",
|
||||
"performer",
|
||||
"crew",
|
||||
"official_site",
|
||||
|
@ -196,8 +234,15 @@ class PerformanceProduction(Item):
|
|||
blank=True,
|
||||
default=list,
|
||||
)
|
||||
performer = jsondata.ArrayField(
|
||||
actor = jsondata.JSONField(
|
||||
verbose_name=_("演员"),
|
||||
null=False,
|
||||
blank=True,
|
||||
default=list,
|
||||
schema=_ACTOR_SCHEMA,
|
||||
)
|
||||
performer = jsondata.ArrayField(
|
||||
verbose_name=_("表演者"),
|
||||
base_field=models.CharField(blank=True, default="", max_length=500),
|
||||
null=False,
|
||||
blank=True,
|
||||
|
@ -210,12 +255,12 @@ class PerformanceProduction(Item):
|
|||
blank=True,
|
||||
default=list,
|
||||
)
|
||||
crew = jsondata.ArrayField(
|
||||
crew = jsondata.JSONField(
|
||||
verbose_name=_("其他演职人员和团体"),
|
||||
base_field=models.CharField(blank=True, default="", max_length=500),
|
||||
null=False,
|
||||
blank=True,
|
||||
default=list,
|
||||
schema=_CREW_SCHEMA,
|
||||
)
|
||||
location = jsondata.ArrayField(
|
||||
verbose_name=_("剧场空间"),
|
||||
|
@ -248,6 +293,7 @@ class PerformanceProduction(Item):
|
|||
"orig_creator",
|
||||
"composer",
|
||||
"choreographer",
|
||||
"actor",
|
||||
"performer",
|
||||
"crew",
|
||||
"official_site",
|
||||
|
|
|
@ -70,11 +70,31 @@ class DoubanDramaTestCase(TestCase):
|
|||
# )
|
||||
self.assertEqual(item.director, ["小池修一郎", "小池 修一郎", "石丸さち子"])
|
||||
self.assertEqual(item.playwright, ["小池修一郎", "Baroness Orczy(原作)", "小池 修一郎"])
|
||||
self.assertEqual(item.performer, ["安蘭けい", "柚希礼音", "遠野あすか", "霧矢大夢", "龍真咲"])
|
||||
self.assertEqual(
|
||||
item.actor,
|
||||
[
|
||||
{"name": "安蘭けい", "role": ""},
|
||||
{"name": "柚希礼音", "role": ""},
|
||||
{"name": "遠野あすか", "role": ""},
|
||||
{"name": "霧矢大夢", "role": ""},
|
||||
{"name": "龍真咲", "role": ""},
|
||||
],
|
||||
)
|
||||
self.assertEqual(len(resource.related_resources), 4)
|
||||
crawl_related_resources_task(resource.id) # force the async job to run now
|
||||
productions = list(item.productions.all().order_by("title"))
|
||||
self.assertEqual(len(productions), 4)
|
||||
self.assertEqual(
|
||||
productions[3].actor,
|
||||
[
|
||||
{"name": "石丸幹二", "role": "パーシー・ブレイクニー"},
|
||||
{"name": "石井一孝", "role": "ショーヴラン"},
|
||||
{"name": "安蘭けい", "role": "マルグリット・サン・ジュスト"},
|
||||
{"name": "上原理生", "role": ""},
|
||||
{"name": "泉見洋平", "role": ""},
|
||||
{"name": "松下洸平", "role": "アルマン"},
|
||||
],
|
||||
)
|
||||
self.assertEqual(productions[0].opening_date, "2008-06-20")
|
||||
self.assertEqual(productions[0].closing_date, "2008-08-04")
|
||||
self.assertEqual(productions[2].opening_date, "2017-03-10")
|
||||
|
@ -82,7 +102,7 @@ class DoubanDramaTestCase(TestCase):
|
|||
self.assertEqual(productions[3].opening_date, "2017-11-13")
|
||||
self.assertEqual(productions[3].closing_date, None)
|
||||
self.assertEqual(productions[3].title, "ミュージカル(2017年)版")
|
||||
self.assertEqual(len(productions[3].performer), 6)
|
||||
self.assertEqual(len(productions[3].actor), 6)
|
||||
self.assertEqual(productions[3].language, ["日语"])
|
||||
self.assertEqual(productions[3].opening_date, "2017-11-13")
|
||||
self.assertEqual(productions[3].location, ["梅田芸術劇場メインホール"])
|
||||
|
|
|
@ -63,7 +63,7 @@ class DoubanDramaVersion(AbstractSite):
|
|||
"title": title,
|
||||
"director": [x.strip() for x in h.xpath(q.format("导演"))],
|
||||
"playwright": [x.strip() for x in h.xpath(q.format("编剧"))],
|
||||
"performer": [x.strip() for x in h.xpath(q.format("主演"))],
|
||||
# "actor": [x.strip() for x in h.xpath(q.format("主演"))],
|
||||
"composer": [x.strip() for x in h.xpath(q.format("作曲"))],
|
||||
"language": [x.strip() for x in h.xpath(q2.format("语言"))],
|
||||
"opening_date": " ".join(h.xpath(q2.format("演出日期"))).strip(),
|
||||
|
@ -76,6 +76,14 @@ class DoubanDramaVersion(AbstractSite):
|
|||
if l > 3:
|
||||
data["opening_date"] = "-".join(d[:3])
|
||||
data["closing_date"] = "-".join(d[0 : 6 - l] + d[3:l])
|
||||
actor_elem = h.xpath(p + "//dt[text()='主演:']/following-sibling::dd[1]/a")
|
||||
data["actor"] = []
|
||||
for e in actor_elem:
|
||||
n = "".join(e.xpath("span/text()")).strip()
|
||||
t = "".join(e.xpath("following-sibling::text()[1]")).strip()
|
||||
t = re.sub(r"^[\s\(饰]*(.+)\)[\s\/]*$", r"\1", t).strip()
|
||||
t = t if t != "/" else ""
|
||||
data["actor"].append({"name": n, "role": t})
|
||||
img_url_elem = h.xpath("//img[@itemprop='image']/@src")
|
||||
data["cover_image_url"] = img_url_elem[0].strip() if img_url_elem else None
|
||||
pd = ResourceContent(metadata=data)
|
||||
|
@ -184,8 +192,8 @@ class DoubanDrama(AbstractSite):
|
|||
"//div[@class='meta']/dl//dt[text()='编剧:']/following-sibling::dd/a[@itemprop='author']//text()"
|
||||
)
|
||||
]
|
||||
data["performer"] = [
|
||||
s.strip()
|
||||
data["actor"] = [
|
||||
{"name": s.strip(), "role": ""}
|
||||
for s in h.xpath(
|
||||
"//div[@class='meta']/dl//dt[text()='主演:']/following-sibling::dd/a[@itemprop='actor']//text()"
|
||||
)
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
<div>{% include '_people.html' with people=item.orig_creator role='原作' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.director role='导演' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.playwright role='编剧' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.performer role='演员' max=10 %}</div>
|
||||
<div>{% include '_crew.html' with people=item.actor role='演员' max=10 %}</div>
|
||||
<div>{% include '_people.html' with people=item.performer role='表演者' max=10 %}</div>
|
||||
<div>{% include '_people.html' with people=item.composer role='作曲' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.choreographer role='编舞' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.crew role='演职人员' max=10 %}</div>
|
||||
<div>{% include '_crew.html' with people=item.crew role='演职人员' max=10 %}</div>
|
||||
<div>
|
||||
{% if item.official_site %}
|
||||
{% trans '官方网站' %}: <span>{{ item.official_site|urlizetrunc:24 }}</span>
|
||||
|
@ -58,10 +59,11 @@
|
|||
{% include '_people.html' with people=prod.orig_creator role='原作' max=2 %}
|
||||
{% include '_people.html' with people=prod.director role='导演' max=2 %}
|
||||
{% include '_people.html' with people=prod.playwright role='编剧' max=2 %}
|
||||
{% include '_people.html' with people=prod.performer role='演员' max=5 %}
|
||||
{% include '_crew.html' with people=prod.actor role='演员' max=5 %}
|
||||
{% include '_people.html' with people=prod.performer role='表演者' max=5 %}
|
||||
{% include '_people.html' with people=prod.composer role='作曲' max=2 %}
|
||||
{% include '_people.html' with people=prod.choreographer role='编舞' max=2 %}
|
||||
{% include '_people.html' with people=prod.crew role='演职人员' max=5 %}
|
||||
{% include '_crew.html' with people=prod.crew role='演职人员' max=5 %}
|
||||
</div>
|
||||
</hgroup>
|
||||
{% endfor %}
|
||||
|
|
|
@ -30,10 +30,11 @@
|
|||
<div>{% include '_people.html' with people=item.orig_creator role='原作' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.director role='导演' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.playwright role='编剧' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.performer role='演员' max=10 %}</div>
|
||||
<div>{% include '_crew.html' with people=item.actor role='演员' max=50 %}</div>
|
||||
<div>{% include '_people.html' with people=item.performer role='表演者' max=50 %}</div>
|
||||
<div>{% include '_people.html' with people=item.composer role='作曲' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.choreographer role='编舞' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.crew role='演职人员' max=10 %}</div>
|
||||
<div>{% include '_crew.html' with people=item.crew role='演职人员' max=50 %}</div>
|
||||
<div>
|
||||
{% if item.official_site %}
|
||||
{% trans '官方网站' %}: <span>{{ item.official_site|urlizetrunc:24 }}</span>
|
||||
|
|
|
@ -183,7 +183,14 @@ def edit(request, item_path, item_uuid):
|
|||
form.instance.save()
|
||||
return redirect(form.instance.url)
|
||||
else:
|
||||
raise BadRequest(form.errors)
|
||||
e = form.errors
|
||||
e.additonal_detail = []
|
||||
for f, v in e.as_data().items():
|
||||
for validation_error in v:
|
||||
if hasattr(validation_error, "error_map"):
|
||||
for f2, v2 in validation_error.error_map.items():
|
||||
e.additonal_detail.append(f"{f}§{f2}: {'; '.join(v2)}")
|
||||
raise BadRequest(e)
|
||||
else:
|
||||
raise BadRequest()
|
||||
|
||||
|
|
|
@ -21,8 +21,13 @@
|
|||
<header>
|
||||
<h3>🤦🏻 无效的请求</h3>
|
||||
</header>
|
||||
{{ exception }}
|
||||
您可能提交了无效的数据,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||
<section>
|
||||
{{ exception }}
|
||||
{% if exception.additonal_detail %}
|
||||
{% for e in exception.additonal_detail %}<p>{{ e }}</p>{% endfor %}
|
||||
{% endif %}
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
{% include "partial/_footer.html" %}
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
<div>{% include '_people.html' with people=item.other_title role='又名' max=2 %}</div>
|
||||
<div>{% include '_people.html' with people=item.director role='导演' max=2 %}</div>
|
||||
<div>{% include '_people.html' with people=item.playwright role='编剧' max=2 %}</div>
|
||||
<div>{% include '_people.html' with people=item.performer role='演员' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.actor role='演员' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.performer role='表演者' max=5 %}</div>
|
||||
<div>{% include '_people.html' with people=item.composer role='作曲' max=2 %}</div>
|
||||
<div>{% include '_people.html' with people=item.choreographer role='编舞' max=2 %}</div>
|
||||
<div>{% include '_people.html' with people=item.crew role='演职人员' max=2 %}</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue