Coverage for oc_ocdm/metadata/entities/distribution.py: 65%
89 statements
« prev ^ index » next coverage.py v6.5.0, created at 2025-05-30 22:05 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2025-05-30 22:05 +0000
1#!/usr/bin/python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2016, Silvio Peroni <essepuntato@gmail.com>
4#
5# Permission to use, copy, modify, and/or distribute this software for any purpose
6# with or without fee is hereby granted, provided that the above copyright notice
7# and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
11# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
12# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
13# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15# SOFTWARE.
16from __future__ import annotations
18from typing import TYPE_CHECKING
20from rdflib import XSD
22from oc_ocdm.decorators import accepts_only
23from oc_ocdm.metadata.metadata_entity import MetadataEntity
25if TYPE_CHECKING:
26 from typing import Optional
27 from rdflib import URIRef
30class Distribution(MetadataEntity):
31 """Distribution (short: di): an accessible form of a dataset, for example a downloadable
32 file."""
34 @accepts_only('di')
35 def merge(self, other: Distribution) -> None:
36 """
37 The merge operation allows combining two ``Distribution`` entities into a single one,
38 by marking the second entity as to be deleted while also copying its data into the current
39 ``Distribution``. Moreover, every triple from the containing ``MetadataSet`` referring to the second
40 entity gets "redirected" to the current entity: **every other reference contained inside a
41 different source (e.g. a triplestore) must be manually handled by the user!**
43 In case of functional properties, values from the current entity get overwritten
44 by those coming from the second entity while, in all other cases, values from the
45 second entity are simply appended to those of the current entity. In this context,
46 ``rdfs:label`` is considered as a functional property, while ``rdf:type`` is not.
48 :param other: The entity which will be marked as to be deleted and whose properties will
49 be merged into the current entity.
50 :type other: Distribution
51 :raises TypeError: if the parameter is of the wrong type
52 :return: None
53 """
54 super(Distribution, self).merge(other)
56 title: Optional[str] = other.get_title()
57 if title is not None:
58 self.has_title(title)
60 description: Optional[str] = other.get_description()
61 if description is not None:
62 self.has_description(description)
64 pub_date: Optional[str] = other.get_publication_date()
65 if pub_date is not None:
66 self.has_publication_date(pub_date)
68 byte_size: Optional[str] = other.get_byte_size()
69 if byte_size is not None:
70 self.has_byte_size(byte_size)
72 license_uri: Optional[URIRef] = other.get_license()
73 if license_uri is not None:
74 self.has_license(license_uri)
76 download_url: Optional[URIRef] = other.get_download_url()
77 if download_url is not None:
78 self.has_download_url(download_url)
80 media_type: Optional[URIRef] = other.get_media_type()
81 if media_type is not None:
82 self.has_media_type(media_type)
84 # HAS TITLE
85 def get_title(self) -> Optional[str]:
86 """
87 Getter method corresponding to the ``dcterms:title`` RDF predicate.
89 :return: The requested value if found, None otherwise
90 """
91 return self._get_literal(MetadataEntity.iri_title)
93 @accepts_only('literal')
94 def has_title(self, string: str) -> None:
95 """
96 Setter method corresponding to the ``dcterms:title`` RDF predicate.
98 **WARNING: this is a functional property, hence any existing value will be overwritten!**
100 `The title of the distribution.`
102 :param string: The value that will be set as the object of the property related to this method
103 :type string: str
104 :raises TypeError: if the parameter is of the wrong type
105 :return: None
106 """
107 self.remove_title()
108 self._create_literal(MetadataEntity.iri_title, string)
110 def remove_title(self) -> None:
111 """
112 Remover method corresponding to the ``dcterms:title`` RDF predicate.
114 :return: None
115 """
116 self.g.remove((self.res, MetadataEntity.iri_title, None))
118 # HAS DESCRIPTION
119 def get_description(self) -> Optional[str]:
120 """
121 Getter method corresponding to the ``dcterms:description`` RDF predicate.
123 :return: The requested value if found, None otherwise
124 """
125 return self._get_literal(MetadataEntity.iri_description)
127 @accepts_only('literal')
128 def has_description(self, string: str) -> None:
129 """
130 Setter method corresponding to the ``dcterms:description`` RDF predicate.
132 **WARNING: this is a functional property, hence any existing value will be overwritten!**
134 `A short textual description of the content of the distribution.`
136 :param string: The value that will be set as the object of the property related to this method
137 :type string: str
138 :raises TypeError: if the parameter is of the wrong type
139 :return: None
140 """
141 self.remove_description()
142 self._create_literal(MetadataEntity.iri_description, string)
144 def remove_description(self) -> None:
145 """
146 Remover method corresponding to the ``dcterms:description`` RDF predicate.
148 :return: None
149 """
150 self.g.remove((self.res, MetadataEntity.iri_description, None))
152 # HAS PUBLICATION DATE
153 def get_publication_date(self) -> Optional[str]:
154 """
155 Getter method corresponding to the ``dcterms:issued`` RDF predicate.
157 :return: The requested value if found, None otherwise
158 """
159 return self._get_literal(MetadataEntity.iri_issued)
161 @accepts_only('literal')
162 def has_publication_date(self, string: str) -> None:
163 """
164 Setter method corresponding to the ``dcterms:issued`` RDF predicate.
166 **WARNING: this is a functional property, hence any existing value will be overwritten!**
168 `The date of first publication of the distribution.`
170 :param string: The value that will be set as the object of the property related to this method. **It must
171 be a string compliant with the** ``xsd:dateTime`` **datatype.**
172 :type string: str
173 :raises TypeError: if the parameter is of the wrong type
174 :return: None
175 """
176 self.remove_publication_date()
177 self._create_literal(MetadataEntity.iri_issued, string, XSD.dateTime, False)
179 def remove_publication_date(self) -> None:
180 """
181 Remover method corresponding to the ``dcterms:issued`` RDF predicate.
183 :return: None
184 """
185 self.g.remove((self.res, MetadataEntity.iri_issued, None))
187 # HAS BYTE SIZE
188 def get_byte_size(self) -> Optional[str]:
189 """
190 Getter method corresponding to the ``dcat:byte_size`` RDF predicate.
192 :return: The requested value if found, None otherwise
193 """
194 return self._get_literal(MetadataEntity.iri_byte_size)
196 @accepts_only('literal')
197 def has_byte_size(self, string: str) -> None:
198 """
199 Setter method corresponding to the ``dcat:byte_size`` RDF predicate.
201 **WARNING: this is a functional property, hence any existing value will be overwritten!**
203 `The size in bytes of the distribution.`
205 :param string: The value that will be set as the object of the property related to this method. **It must
206 be a string compliant with the** ``xsd:decimal`` **datatype.**
207 :type string: str
208 :raises TypeError: if the parameter is of the wrong type
209 :return: None
210 """
211 self.remove_byte_size()
212 self._create_literal(MetadataEntity.iri_byte_size, string, XSD.decimal)
214 def remove_byte_size(self) -> None:
215 """
216 Remover method corresponding to the ``dcat:byte_size`` RDF predicate.
218 :return: None
219 """
220 self.g.remove((self.res, MetadataEntity.iri_byte_size, None))
222 # HAS LICENSE
223 def get_license(self) -> Optional[URIRef]:
224 """
225 Getter method corresponding to the ``dcterms:license`` RDF predicate.
227 :return: The requested value if found, None otherwise
228 """
229 return self._get_literal(MetadataEntity.iri_license)
231 @accepts_only('thing')
232 def has_license(self, thing_res: URIRef) -> None:
233 """
234 Setter method corresponding to the ``dcterms:license`` RDF predicate.
236 **WARNING: this is a functional property, hence any existing value will be overwritten!**
238 `The resource describing the license associated with the data in the distribution.`
240 :param thing_res: The value that will be set as the object of the property related to this method
241 :type thing_res: URIRef
242 :raises TypeError: if the parameter is of the wrong type
243 :return: None
244 """
245 self.remove_license()
246 self.g.add((self.res, MetadataEntity.iri_license, thing_res))
248 def remove_license(self) -> None:
249 """
250 Remover method corresponding to the ``dcterms:license`` RDF predicate.
252 :return: None
253 """
254 self.g.remove((self.res, MetadataEntity.iri_license, None))
256 # HAS DOWNLOAD URL
257 def get_download_url(self) -> Optional[URIRef]:
258 """
259 Getter method corresponding to the ``dcat:downloadURL`` RDF predicate.
261 :return: The requested value if found, None otherwise
262 """
263 return self._get_literal(MetadataEntity.iri_download_url)
265 @accepts_only('thing')
266 def has_download_url(self, thing_res: URIRef) -> None:
267 """
268 Setter method corresponding to the ``dcat:downloadURL`` RDF predicate.
270 **WARNING: this is a functional property, hence any existing value will be overwritten!**
272 `The URL of the document where the distribution is stored.`
274 :param thing_res: The value that will be set as the object of the property related to this method
275 :type thing_res: URIRef
276 :raises TypeError: if the parameter is of the wrong type
277 :return: None
278 """
279 self.remove_download_url()
280 self.g.add((self.res, MetadataEntity.iri_download_url, thing_res))
282 def remove_download_url(self) -> None:
283 """
284 Remover method corresponding to the ``dcat:downloadURL`` RDF predicate.
286 :return: None
287 """
288 self.g.remove((self.res, MetadataEntity.iri_download_url, None))
290 # HAS_MEDIA_TYPE
291 def get_media_type(self) -> Optional[URIRef]:
292 """
293 Getter method corresponding to the ``dcat:mediaType`` RDF predicate.
295 :return: The requested value if found, None otherwise
296 """
297 return self._get_literal(MetadataEntity.iri_media_type)
299 @accepts_only('thing')
300 def has_media_type(self, thing_res: URIRef) -> None:
301 """
302 Setter method corresponding to the ``dcat:mediaType`` RDF predicate.
304 **WARNING: this is a functional property, hence any existing value will be overwritten!**
306 `The file type of the representation of the distribution (according to IANA media types).`
308 :param thing_res: The value that will be set as the object of the property related to this method
309 :type thing_res: URIRef
310 :raises TypeError: if the parameter is of the wrong type
311 :return: None
312 """
313 self.remove_media_type()
314 self.g.add((self.res, MetadataEntity.iri_media_type, thing_res))
316 def remove_media_type(self) -> None:
317 """
318 Remover method corresponding to the ``dcat:mediaType`` RDF predicate.
320 :return: None
321 """
322 self.g.remove((self.res, MetadataEntity.iri_media_type, None))