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

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 

17 

18from typing import TYPE_CHECKING 

19 

20from rdflib import XSD 

21 

22from oc_ocdm.decorators import accepts_only 

23from oc_ocdm.metadata.metadata_entity import MetadataEntity 

24 

25if TYPE_CHECKING: 

26 from typing import Optional 

27 from rdflib import URIRef 

28 

29 

30class Distribution(MetadataEntity): 

31 """Distribution (short: di): an accessible form of a dataset, for example a downloadable 

32 file.""" 

33 

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!** 

42 

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. 

47 

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) 

55 

56 title: Optional[str] = other.get_title() 

57 if title is not None: 

58 self.has_title(title) 

59 

60 description: Optional[str] = other.get_description() 

61 if description is not None: 

62 self.has_description(description) 

63 

64 pub_date: Optional[str] = other.get_publication_date() 

65 if pub_date is not None: 

66 self.has_publication_date(pub_date) 

67 

68 byte_size: Optional[str] = other.get_byte_size() 

69 if byte_size is not None: 

70 self.has_byte_size(byte_size) 

71 

72 license_uri: Optional[URIRef] = other.get_license() 

73 if license_uri is not None: 

74 self.has_license(license_uri) 

75 

76 download_url: Optional[URIRef] = other.get_download_url() 

77 if download_url is not None: 

78 self.has_download_url(download_url) 

79 

80 media_type: Optional[URIRef] = other.get_media_type() 

81 if media_type is not None: 

82 self.has_media_type(media_type) 

83 

84 # HAS TITLE 

85 def get_title(self) -> Optional[str]: 

86 """ 

87 Getter method corresponding to the ``dcterms:title`` RDF predicate. 

88 

89 :return: The requested value if found, None otherwise 

90 """ 

91 return self._get_literal(MetadataEntity.iri_title) 

92 

93 @accepts_only('literal') 

94 def has_title(self, string: str) -> None: 

95 """ 

96 Setter method corresponding to the ``dcterms:title`` RDF predicate. 

97 

98 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

99 

100 `The title of the distribution.` 

101 

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) 

109 

110 def remove_title(self) -> None: 

111 """ 

112 Remover method corresponding to the ``dcterms:title`` RDF predicate. 

113 

114 :return: None 

115 """ 

116 self.g.remove((self.res, MetadataEntity.iri_title, None)) 

117 

118 # HAS DESCRIPTION 

119 def get_description(self) -> Optional[str]: 

120 """ 

121 Getter method corresponding to the ``dcterms:description`` RDF predicate. 

122 

123 :return: The requested value if found, None otherwise 

124 """ 

125 return self._get_literal(MetadataEntity.iri_description) 

126 

127 @accepts_only('literal') 

128 def has_description(self, string: str) -> None: 

129 """ 

130 Setter method corresponding to the ``dcterms:description`` RDF predicate. 

131 

132 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

133 

134 `A short textual description of the content of the distribution.` 

135 

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) 

143 

144 def remove_description(self) -> None: 

145 """ 

146 Remover method corresponding to the ``dcterms:description`` RDF predicate. 

147 

148 :return: None 

149 """ 

150 self.g.remove((self.res, MetadataEntity.iri_description, None)) 

151 

152 # HAS PUBLICATION DATE 

153 def get_publication_date(self) -> Optional[str]: 

154 """ 

155 Getter method corresponding to the ``dcterms:issued`` RDF predicate. 

156 

157 :return: The requested value if found, None otherwise 

158 """ 

159 return self._get_literal(MetadataEntity.iri_issued) 

160 

161 @accepts_only('literal') 

162 def has_publication_date(self, string: str) -> None: 

163 """ 

164 Setter method corresponding to the ``dcterms:issued`` RDF predicate. 

165 

166 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

167 

168 `The date of first publication of the distribution.` 

169 

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) 

178 

179 def remove_publication_date(self) -> None: 

180 """ 

181 Remover method corresponding to the ``dcterms:issued`` RDF predicate. 

182 

183 :return: None 

184 """ 

185 self.g.remove((self.res, MetadataEntity.iri_issued, None)) 

186 

187 # HAS BYTE SIZE 

188 def get_byte_size(self) -> Optional[str]: 

189 """ 

190 Getter method corresponding to the ``dcat:byte_size`` RDF predicate. 

191 

192 :return: The requested value if found, None otherwise 

193 """ 

194 return self._get_literal(MetadataEntity.iri_byte_size) 

195 

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. 

200 

201 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

202 

203 `The size in bytes of the distribution.` 

204 

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) 

213 

214 def remove_byte_size(self) -> None: 

215 """ 

216 Remover method corresponding to the ``dcat:byte_size`` RDF predicate. 

217 

218 :return: None 

219 """ 

220 self.g.remove((self.res, MetadataEntity.iri_byte_size, None)) 

221 

222 # HAS LICENSE 

223 def get_license(self) -> Optional[URIRef]: 

224 """ 

225 Getter method corresponding to the ``dcterms:license`` RDF predicate. 

226 

227 :return: The requested value if found, None otherwise 

228 """ 

229 return self._get_literal(MetadataEntity.iri_license) 

230 

231 @accepts_only('thing') 

232 def has_license(self, thing_res: URIRef) -> None: 

233 """ 

234 Setter method corresponding to the ``dcterms:license`` RDF predicate. 

235 

236 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

237 

238 `The resource describing the license associated with the data in the distribution.` 

239 

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)) 

247 

248 def remove_license(self) -> None: 

249 """ 

250 Remover method corresponding to the ``dcterms:license`` RDF predicate. 

251 

252 :return: None 

253 """ 

254 self.g.remove((self.res, MetadataEntity.iri_license, None)) 

255 

256 # HAS DOWNLOAD URL 

257 def get_download_url(self) -> Optional[URIRef]: 

258 """ 

259 Getter method corresponding to the ``dcat:downloadURL`` RDF predicate. 

260 

261 :return: The requested value if found, None otherwise 

262 """ 

263 return self._get_literal(MetadataEntity.iri_download_url) 

264 

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. 

269 

270 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

271 

272 `The URL of the document where the distribution is stored.` 

273 

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)) 

281 

282 def remove_download_url(self) -> None: 

283 """ 

284 Remover method corresponding to the ``dcat:downloadURL`` RDF predicate. 

285 

286 :return: None 

287 """ 

288 self.g.remove((self.res, MetadataEntity.iri_download_url, None)) 

289 

290 # HAS_MEDIA_TYPE 

291 def get_media_type(self) -> Optional[URIRef]: 

292 """ 

293 Getter method corresponding to the ``dcat:mediaType`` RDF predicate. 

294 

295 :return: The requested value if found, None otherwise 

296 """ 

297 return self._get_literal(MetadataEntity.iri_media_type) 

298 

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. 

303 

304 **WARNING: this is a functional property, hence any existing value will be overwritten!** 

305 

306 `The file type of the representation of the distribution (according to IANA media types).` 

307 

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)) 

315 

316 def remove_media_type(self) -> None: 

317 """ 

318 Remover method corresponding to the ``dcat:mediaType`` RDF predicate. 

319 

320 :return: None 

321 """ 

322 self.g.remove((self.res, MetadataEntity.iri_media_type, None))