Skip to content

Commit

Permalink
Add copyright notices and licenses to files (#2048)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartfeenstra authored Sep 29, 2024
1 parent fc9ce3e commit 7321911
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 8 deletions.
49 changes: 49 additions & 0 deletions betty/ancestry/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,19 @@
from betty.ancestry.has_notes import HasNotes
from betty.ancestry.link import HasLinks, Link
from betty.ancestry.media_type import HasMediaType
from betty.json.schema import Enum
from betty.locale.localizable import _, ShorthandStaticTranslations, Localizable
from betty.model import UserFacingEntity, Entity
from betty.model.association import BidirectionalToMany, ToManyResolver
from betty.plugin import ShorthandPluginBase
from betty.privacy import HasPrivacy, Privacy

if TYPE_CHECKING:
from betty.json.linked_data import JsonLdObject
from betty.project import Project
from betty.serde.dump import DumpMapping, Dump
from betty.copyright_notice import CopyrightNotice
from betty.license import License
from betty.ancestry.citation import Citation
from betty.ancestry.note import Note
from betty.ancestry.file_reference import FileReference # noqa F401
Expand Down Expand Up @@ -63,6 +69,12 @@ class File(
linked_data_embedded=True,
)

#: The copyright notice for this file.
copyright_notice: CopyrightNotice | None

#: The license for this file.
license: License | None

def __init__(
self,
path: Path,
Expand All @@ -77,6 +89,8 @@ def __init__(
public: bool | None = None,
private: bool | None = None,
links: MutableSequence[Link] | None = None,
copyright_notice: CopyrightNotice | None = None,
license: License | None = None, # noqa A002
):
super().__init__(
id,
Expand All @@ -91,6 +105,8 @@ def __init__(
)
self._path = path
self._name = name
self.copyright_notice = copyright_notice
self.license = license

@property
def name(self) -> str:
Expand All @@ -115,3 +131,36 @@ def path(self) -> Path:
@property
def label(self) -> Localizable:
return self.description or super().label

@override
@classmethod
async def linked_data_schema(cls, project: Project) -> JsonLdObject:
schema = await super().linked_data_schema(project)
schema.add_property(
"copyrightNotice",
Enum(
*[plugin.plugin_id() async for plugin in project.copyright_notices], # noqa A002
title="Copyright notice",
description="A copyright notice plugin ID",
),
False,
)
schema.add_property(
"license",
Enum(
*[plugin.plugin_id() async for plugin in project.licenses], # noqa A002
title="License",
description="A license plugin ID",
),
False,
)
return schema

@override
async def dump_linked_data(self, project: Project) -> DumpMapping[Dump]:
dump = await super().dump_linked_data(project)
if self.copyright_notice:
dump["copyrightNotice"] = self.copyright_notice.plugin_id()
if self.license:
dump["license"] = self.license.plugin_id()
return dump
8 changes: 7 additions & 1 deletion betty/assets/locale/betty.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Betty VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-29 20:26+0100\n"
"POT-Creation-Date: 2024-09-30 00:24+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -156,6 +156,12 @@ msgstr ""
msgid "Betty is unfamiliar with Gramps event \"{event_id}\"'s type of \"{gramps_event_type}\". The event was imported, but its type was set to \"{betty_event_type}\"."
msgstr ""

msgid "Betty is unfamiliar with Gramps file \"{file_id}\"'s copyright notice ID of \"{copyright_notice_id}\" and ignored it."
msgstr ""

msgid "Betty is unfamiliar with Gramps file \"{file_id}\"'s license ID of \"{license_id}\" and ignored it."
msgstr ""

msgid "Betty is unfamiliar with Gramps person \"{person_id}\"'s gender of \"{gramps_gender}\". The person was imported, but their gender was set to \"{betty_gender}\"."
msgstr ""

Expand Down
12 changes: 11 additions & 1 deletion betty/assets/locale/de-DE/betty.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Betty VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-29 20:26+0100\n"
"POT-Creation-Date: 2024-09-30 00:24+0100\n"
"PO-Revision-Date: 2024-02-08 13:24+0000\n"
"Last-Translator: Bart Feenstra <bart@bartfeenstra.com>\n"
"Language: de\n"
Expand Down Expand Up @@ -210,6 +210,16 @@ msgstr ""
"\"{event_id}\" nicht vertraut. Das Ereignis wurde importiert, aber sein "
"Typ wurde auf \"{betty_event_type}\" gesetzt."

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s copyright notice ID "
"of \"{copyright_notice_id}\" and ignored it."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s license ID of "
"\"{license_id}\" and ignored it."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps person \"{person_id}\"'s gender of "
"\"{gramps_gender}\". The person was imported, but their gender was set to"
Expand Down
12 changes: 11 additions & 1 deletion betty/assets/locale/fr-FR/betty.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-29 20:26+0100\n"
"POT-Creation-Date: 2024-09-30 00:24+0100\n"
"PO-Revision-Date: 2024-02-08 13:24+0000\n"
"Last-Translator: Bart Feenstra <bart@bartfeenstra.com>\n"
"Language: fr\n"
Expand Down Expand Up @@ -181,6 +181,16 @@ msgid ""
"\"{betty_event_type}\"."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s copyright notice ID "
"of \"{copyright_notice_id}\" and ignored it."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s license ID of "
"\"{license_id}\" and ignored it."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps person \"{person_id}\"'s gender of "
"\"{gramps_gender}\". The person was imported, but their gender was set to"
Expand Down
21 changes: 18 additions & 3 deletions betty/assets/locale/nl-NL/betty.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-29 20:26+0100\n"
"POT-Creation-Date: 2024-09-30 00:24+0100\n"
"PO-Revision-Date: 2024-02-11 15:31+0000\n"
"Last-Translator: Bart Feenstra <bart@bartfeenstra.com>\n"
"Language: nl\n"
Expand Down Expand Up @@ -215,6 +215,20 @@ msgstr ""
"gebeurtenis \"{event_id}\" niet. De gebeurtenis is geladen, maar zijn "
"type is nu \"{betty_event_type}\"."

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s copyright notice ID "
"of \"{copyright_notice_id}\" and ignored it."
msgstr ""
"Betty kent copyrightvermelding-ID \"{copyright_notice_id}\" van Gramps-"
"bestand \"{file_id}\" niet en heeft het genegeerd."

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s license ID of "
"\"{license_id}\" and ignored it."
msgstr ""
"Betty kent licentie-ID \"{license_id}\" van Gramps-bestand \"{file_id}\" "
"niet en heeft het genegeerd."

msgid ""
"Betty is unfamiliar with Gramps person \"{person_id}\"'s gender of "
"\"{gramps_gender}\". The person was imported, but their gender was set to"
Expand Down Expand Up @@ -649,8 +663,9 @@ msgid ""
"No part may be reproduced or distributed in any form or by any means, "
"without express written permission from the copyright holder, or unless "
"permitted by copyright law."
msgstr "Geen deel mag worden gereproduceerd of gedistribueerd, in welke "
"vorm of of welke manier, zonder expliciete geschreven toestemming van de "
msgstr ""
"Geen deel mag worden gereproduceerd of gedistribueerd, in welke vorm of "
"of welke manier, zonder expliciete geschreven toestemming van de "
"copyrighthouder, of indien toegestaan door copyrightwetgeving."

msgid "Non-binary"
Expand Down
12 changes: 11 additions & 1 deletion betty/assets/locale/uk/betty.po
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Betty VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-09-29 20:26+0100\n"
"POT-Creation-Date: 2024-09-30 00:24+0100\n"
"PO-Revision-Date: 2024-02-08 13:08+0000\n"
"Last-Translator: Rainer Thieringer <rainerthi@gmail.com>\n"
"Language: uk\n"
Expand Down Expand Up @@ -182,6 +182,16 @@ msgid ""
"\"{betty_event_type}\"."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s copyright notice ID "
"of \"{copyright_notice_id}\" and ignored it."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps file \"{file_id}\"'s license ID of "
"\"{license_id}\" and ignored it."
msgstr ""

msgid ""
"Betty is unfamiliar with Gramps person \"{person_id}\"'s gender of "
"\"{gramps_gender}\". The person was imported, but their gender was set to"
Expand Down
36 changes: 35 additions & 1 deletion betty/gramps/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
from betty.ancestry.place_type.place_types import Unknown as UnknownPlaceType
from betty.ancestry.presence import Presence
from betty.ancestry.presence_role.presence_roles import Unknown as UnknownPresenceRole
from betty.privacy import HasPrivacy
from betty.ancestry.source import Source
from betty.date import DateRange, Datey, Date
from betty.error import FileNotFound
Expand All @@ -54,8 +53,14 @@
)
from betty.model.collections import MultipleTypesEntityCollection
from betty.path import rootname
from betty.privacy import HasPrivacy
from betty.typing import internal
from betty.plugin import PluginNotFound

if TYPE_CHECKING:
from betty.copyright_notice import CopyrightNotice
from betty.license import License
from betty.plugin import PluginRepository
from betty.ancestry import Ancestry
from betty.ancestry.has_notes import HasNotes
from betty.ancestry.has_citations import HasCitations
Expand Down Expand Up @@ -143,6 +148,7 @@ def resolve(self) -> Iterable[_EntityT]:
yield cast(_EntityT, self._handles_to_entities[handle])


@internal
class GrampsLoader:
"""
Load Gramps family history data into a project.
Expand All @@ -154,6 +160,8 @@ def __init__(
*,
factory: Factory[Any],
localizer: Localizer,
copyright_notices: PluginRepository[CopyrightNotice],
licenses: PluginRepository[License],
attribute_prefix_key: str | None = None,
event_type_map: Mapping[str, type[EventType]] | None = None,
gender_map: Mapping[str, type[Gender]] | None = None,
Expand All @@ -173,6 +181,8 @@ def __init__(
self._gramps_tree_directory_path: Path | None = None
self._loaded = False
self._localizer = localizer
self._copyright_notices = copyright_notices
self._licenses = licenses
self._event_type_map = event_type_map or {}
self._gender_map = gender_map or {}
self._place_type_map = place_type_map or {}
Expand Down Expand Up @@ -518,6 +528,30 @@ async def _load_object(
element,
"attribute",
)
copyright_notice_id = self._load_attribute(
"copyright-notice", element, "attribute"
)
if copyright_notice_id:
try:
file.copyright_notice = await self._copyright_notices.new(
copyright_notice_id
)
except PluginNotFound:
getLogger(__name__).warning(
self._localizer._(
'Betty is unfamiliar with Gramps file "{file_id}"\'s copyright notice ID of "{copyright_notice_id}" and ignored it.',
).format(file_id=file_id, copyright_notice_id=copyright_notice_id)
)
license_id = self._load_attribute("license", element, "attribute")
if license_id:
try:
file.license = await self._licenses.new(license_id)
except PluginNotFound:
getLogger(__name__).warning(
self._localizer._(
'Betty is unfamiliar with Gramps file "{file_id}"\'s license ID of "{license_id}" and ignored it.',
).format(file_id=file_id, license_id=license_id)
)

self._add_entity(file, file_handle)
file.citations = self._resolve(
Expand Down
2 changes: 2 additions & 0 deletions betty/project/extension/gramps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ async def _load_ancestry(event: LoadAncestryEvent) -> None:
attribute_prefix_key=project.configuration.name,
factory=project.new,
localizer=project.app.localizer,
copyright_notices=project.copyright_notices,
licenses=project.licenses,
event_type_map=await family_tree_configuration.event_types.to_plugins(
project.event_types
),
Expand Down
8 changes: 8 additions & 0 deletions betty/tests/ancestry/test_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
from betty.ancestry.note import Note
from betty.ancestry.person import Person
from betty.ancestry.source import Source
from betty.copyright_notice.copyright_notices import (
PublicDomain as PublicDomainCopyrightNotice,
)
from betty.license.licenses import PublicDomain as PublicDomainLicense
from betty.locale.localizer import DEFAULT_LOCALIZER
from betty.media_type.media_types import PLAIN_TEXT
from betty.privacy import Privacy
Expand Down Expand Up @@ -171,6 +175,8 @@ async def test_dump_linked_data_should_dump_full(self) -> None:
id="the_file",
path=Path(f.name),
media_type=PLAIN_TEXT,
copyright_notice=PublicDomainCopyrightNotice(),
license=PublicDomainLicense(),
)
file.notes.add(
Note(
Expand Down Expand Up @@ -209,6 +215,8 @@ async def test_dump_linked_data_should_dump_full(self) -> None:
},
],
"description": {},
"copyrightNotice": "public-domain",
"license": "public-domain",
}
actual = await assert_dumps_linked_data(file)
assert actual == expected
Expand Down
Loading

0 comments on commit 7321911

Please sign in to comment.