1 /*
2  * Copyright (C) 2016, Sam Thursfield <sam@afuera.me.uk>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19 
20 #include "tracker-resource-helpers.h"
21 #include "tracker-guarantee.h"
22 
23 /**
24  * SECTION:tracker-resource-helpers
25  * @title: Resource Helpers
26  * @short_description: Helpers for describing certain common kinds of resource.
27  * @stability: Stable
28  * @include: libtracker-extract/tracker-extract.h
29  *
30  * Some common patterns for resources used in Tracker extractors have helper
31  * functions defined in this module.
32  */
33 
34 /**
35  * tracker_extract_new_music_artist:
36  * @name: the name of the artist
37  *
38  * Create a new nmm:Artist resource. The URI will be set based on the URI, so
39  * there will only be one resource representing the artist in the Tracker store.
40  *
41  * Returns: a newly allocated #TrackerResource instance, of type nmm:Artist.
42  *
43  * Since: 1.10
44  */
45 TrackerResource *
tracker_extract_new_artist(const char * name)46 tracker_extract_new_artist (const char *name)
47 {
48 	TrackerResource *artist;
49 	gchar *uri;
50 
51 	g_return_val_if_fail (name != NULL, NULL);
52 
53 	uri = tracker_sparql_escape_uri_printf ("urn:artist:%s", name);
54 
55 	artist = tracker_resource_new (uri);
56 
57 	tracker_resource_set_uri (artist, "rdf:type", "nmm:Artist");
58 	tracker_guarantee_resource_utf8_string (artist, "nmm:artistName", name);
59 
60 	g_free (uri);
61 
62 	return artist;
63 }
64 
65 /**
66  * tracker_extract_new_contact:
67  * @fullname: the full name of the contact
68  *
69  * Create a new nco:Contact resource. The URI is based on @fullname, so only
70  * one instance will exist in the Tracker store.
71  *
72  * This is used for describing people or organisations, and can be used with
73  * many fields including nco:artist, nco:creator, nco:publisher, and
74  * nco:representative.
75  *
76  * Returns: a newly allocated #TrackerResource instance, of type nco:Contact
77  *
78  * Since: 1.10
79  */
80 TrackerResource *
tracker_extract_new_contact(const char * fullname)81 tracker_extract_new_contact (const char *fullname)
82 {
83 	TrackerResource *publisher;
84 	gchar *uri;
85 
86 	g_return_val_if_fail (fullname != NULL, NULL);
87 
88 	uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", fullname);
89 
90 	publisher = tracker_resource_new (uri);
91 
92 	tracker_resource_set_uri (publisher, "rdf:type", "nco:Contact");
93 	tracker_guarantee_resource_utf8_string (publisher, "nco:fullname", fullname);
94 
95 	g_free (uri);
96 
97 	return publisher;
98 }
99 
100 /**
101  * tracker_extract_new_equipment:
102  * @make: (allow none): the manufacturer of the equipment, or %NULL
103  * @model: (allow none): the model name of the equipment, or %NULL
104  *
105  * Create a new nfo:Equipment resource. The URI is based on @make and @model,
106  * so only one instance will exist in the Tracker store. At least one of @make
107  * and @model must be non-%NULL.
108  *
109  * This is useful for describing equipment used to create something, for
110  * example the camera that was used to take a photograph.
111  *
112  * Returns: a newly allocated #TrackerResource instance, of type nfo:Equipment
113  *
114  * Since: 1.10
115  */
116 TrackerResource *
tracker_extract_new_equipment(const char * make,const char * model)117 tracker_extract_new_equipment (const char *make,
118                                const char *model)
119 {
120 	TrackerResource *equipment;
121 	gchar *equip_uri;
122 
123 	g_return_val_if_fail (make != NULL || model != NULL, NULL);
124 
125 	equip_uri = tracker_sparql_escape_uri_printf ("urn:equipment:%s:%s:", make ? make : "", model ? model : "");
126 
127 	equipment = tracker_resource_new (equip_uri);
128 	tracker_resource_set_uri (equipment, "rdf:type", "nfo:Equipment");
129 
130 	if (make) {
131 		tracker_guarantee_resource_utf8_string (equipment, "nfo:manufacturer", make);
132 	}
133 
134 	if (model) {
135 		tracker_guarantee_resource_utf8_string (equipment, "nfo:model", model);
136 	}
137 
138 	g_free (equip_uri);
139 
140 	return equipment;
141 }
142 
143 /**
144  * tracker_extract_new_external_reference:
145  * @source_uri: the source uri of the external reference
146  * @identifier: the identifier of the external reference
147  *
148  * Create a new tracker:ExternalReference resource and set its source and its
149  * identifier. Both @source and @identifer must be non-%NULL.
150  *
151  * Returns: a newly allocated #TrackerResource instance, of type tracker:ExternalReference
152  *
153  * Since: 2.3.0
154  */
155 TrackerResource *
tracker_extract_new_external_reference(const char * source_uri,const char * identifier)156 tracker_extract_new_external_reference (const char *source_uri,
157 				        const char *identifier)
158 {
159 	TrackerResource *external_reference;
160 	gchar *uri;
161 
162 	g_return_val_if_fail (source_uri != NULL && identifier != NULL, NULL);
163 
164 	uri = tracker_sparql_escape_uri_printf ("urn:ExternalReference:%s:%s", source_uri, identifier);
165 
166 	external_reference = tracker_resource_new (uri);
167 	tracker_resource_set_uri (external_reference, "rdf:type", "tracker:ExternalReference");
168 	tracker_resource_set_uri (external_reference, "tracker:referenceSource", source_uri);
169 	tracker_resource_set_string (external_reference, "tracker:referenceIdentifier", identifier);
170 
171 	g_free(uri);
172 
173 	return external_reference;
174 }
175 
176 /**
177  * tracker_extract_new_location:
178  * @street_address: (allow none): main part of postal address, or %NULL
179  * @state: (allow none): regional part of postal address, or %NULL
180  * @city: (allow none): locality part of postal address, or %NULL
181  * @country: (allow none): country of postal address, or %NULL
182  * @gps_altitude: (allow none): altitude (following WGS 84 reference) as a string, or %NULL
183  * @gps_latitude: (allow none): latitude as a string, or %NULL
184  * @gps_longitude: (allow none): longitude as a string, or %NULL
185  *
186  * Create a new slo:GeoLocation resource, with the given postal address and/or
187  * GPS coordinates.
188  *
189  * No validation is done here -- it's up to you to ensure the postal address
190  * and GPS coordinates describe the same thing.
191  *
192  * Returns: a newly allocated #TrackerResource instance, of type slo:GeoLocation
193  *
194  * Since: 1.10
195  */
196 TrackerResource *
tracker_extract_new_location(const char * street_address,const char * state,const char * city,const char * country,const char * gps_altitude,const char * gps_latitude,const char * gps_longitude)197 tracker_extract_new_location (const char *street_address,
198                               const char *state,
199                               const char *city,
200                               const char *country,
201                               const char *gps_altitude,
202                               const char *gps_latitude,
203                               const char *gps_longitude)
204 {
205 	TrackerResource *location;
206 
207 	g_return_val_if_fail (street_address != NULL || state != NULL || city != NULL ||
208 	                      country != NULL || gps_altitude != NULL ||
209 	                      gps_latitude != NULL || gps_longitude != NULL, NULL);
210 
211 	location = tracker_resource_new (NULL);
212 	tracker_resource_set_uri (location, "rdf:type", "slo:GeoLocation");
213 
214 	if (street_address || state || country || city) {
215 		TrackerResource *address;
216 		gchar *addruri;
217 
218 		addruri = tracker_sparql_get_uuid_urn ();
219 		address = tracker_resource_new (addruri);
220 
221 		tracker_resource_set_uri (address, "rdf:type", "nco:PostalAddress");
222 
223 		g_free (addruri);
224 
225 		if (street_address) {
226 			tracker_guarantee_resource_utf8_string (address, "nco:streetAddress", street_address);
227 		}
228 
229 		if (state) {
230 			tracker_guarantee_resource_utf8_string (address, "nco:region", state);
231 		}
232 
233 		if (city) {
234 			tracker_guarantee_resource_utf8_string (address, "nco:locality", city);
235 		}
236 
237 		if (country) {
238 			tracker_guarantee_resource_utf8_string (address, "nco:country", country);
239 		}
240 
241 		tracker_resource_set_relation (location, "slo:postalAddress", address);
242 		g_object_unref (address);
243 	}
244 
245 	if (gps_altitude) {
246 		tracker_resource_set_string (location, "slo:altitude", gps_altitude);
247 	}
248 
249 	if (gps_latitude) {
250 		tracker_resource_set_string (location, "slo:latitude", gps_latitude);
251 	}
252 
253 	if (gps_longitude) {
254 		tracker_resource_set_string (location, "slo:longitude", gps_longitude);
255 	}
256 
257 	return location;
258 }
259 
260 /**
261  * tracker_extract_new_music_album_disc:
262  * @album_title: title of the album
263  * @album_artist: (allow none): a #TrackerResource for the album artist, or %NULL
264  * @disc_number: disc number of this disc (the first / only disc in a set should be 1, not 0)
265  * @date: (allow none):The release date, or %NULL
266  *
267  * Create new nmm:MusicAlbumDisc and nmm:MusicAlbum resources. The resources are
268  * given fixed URIs based on @album_title and @disc_number, so they will be
269  * merged with existing entries when serialized to SPARQL and sent to the
270  * Tracker store.
271  *
272  * You can get the album resource from the disc resource by calling:
273  *
274  *     tracker_resource_get_first_relation (album_disc, "nmm:albumDiscAlbum");
275  *
276  * Returns: a newly allocated #TrackerResource instance, of type nmm:MusicAlbumDisc
277  *
278  * Since: 1.10
279  */
280 TrackerResource *
tracker_extract_new_music_album_disc(const char * album_title,TrackerResource * album_artist,int disc_number,const char * date)281 tracker_extract_new_music_album_disc (const char      *album_title,
282                                       TrackerResource *album_artist,
283                                       int              disc_number,
284                                       const char      *date)
285 {
286 	GString *album_uri, *disc_uri, *shared;
287 	const gchar *album_artist_name = NULL;
288 	gchar *tmp_album_uri, *tmp_disc_uri;
289 
290 	TrackerResource *album, *album_disc;
291 
292 	g_return_val_if_fail (album_title != NULL, NULL);
293 
294 	if (album_artist)
295 		album_artist_name = tracker_resource_get_first_string (album_artist,
296 		                                                       "nmm:artistName");
297 	shared = g_string_new (NULL);
298 
299 	g_string_append (shared, album_title);
300 
301 	if (album_artist_name)
302 		g_string_append_printf (shared, ":%s", album_artist_name);
303 
304 	if (date)
305 		g_string_append_printf (shared, ":%s", date);
306 
307 	album_uri = g_string_new ("urn:album:");
308 	g_string_append (album_uri, shared->str);
309 	tmp_album_uri = tracker_sparql_escape_uri (album_uri->str);
310 	album = tracker_resource_new (tmp_album_uri);
311 
312 	tracker_resource_set_uri (album, "rdf:type", "nmm:MusicAlbum");
313 	tracker_resource_set_string (album, "nie:title", album_title);
314 
315 	if (album_artist)
316 		tracker_resource_add_relation (album, "nmm:albumArtist", album_artist);
317 
318 	disc_uri = g_string_new ("urn:album-disc:");
319 	g_string_append_printf (disc_uri, "%s:Disc%d", shared->str, disc_number);
320 
321 	tmp_disc_uri = tracker_sparql_escape_uri (disc_uri->str);
322 	album_disc = tracker_resource_new (tmp_disc_uri);
323 
324 	tracker_resource_set_uri (album_disc, "rdf:type", "nmm:MusicAlbumDisc");
325 	tracker_resource_set_int (album_disc, "nmm:setNumber", disc_number > 0 ? disc_number : 1);
326 	tracker_resource_set_relation (album_disc, "nmm:albumDiscAlbum", album);
327 
328 	g_free (tmp_album_uri);
329 	g_free (tmp_disc_uri);
330 	g_string_free (album_uri, TRUE);
331 	g_string_free (disc_uri, TRUE);
332 	g_string_free (shared, TRUE);
333 
334 	g_object_unref (album);
335 
336 	return album_disc;
337 }
338 
339 /**
340  * tracker_extract_new_tag:
341  * @label: the label of the tag
342  *
343  * Create a new nao:Tag resource. The URI will be set based on the tag label,
344  * so there will only be one resource representing the tag in the Tracker store.
345  *
346  * Returns: a newly allocated #TrackerResource instance, of type nao:Tag.
347  *
348  * Since: 1.10
349  */
350 TrackerResource *
tracker_extract_new_tag(const char * label)351 tracker_extract_new_tag (const char *label)
352 {
353 	TrackerResource *tag;
354 	char *uri;
355 
356 	uri = tracker_sparql_escape_uri_printf ("urn:tag:%s", label);
357 	tag = tracker_resource_new (uri);
358 
359 	tracker_resource_set_uri (tag, "rdf:type", "nao:Tag");
360 	tracker_guarantee_resource_utf8_string (tag, "nao:prefLabel", label);
361 
362 	g_free (uri);
363 	return tag;
364 }
365