hythmbox-2.98/plugins/daap/rb-daap-record.c

No issues found

  1 /*
  2  *  Database record class for DAAP sharing
  3  *
  4  *  Copyright (C) 2008 W. Michael Petullo <mike@flyn.org>
  5  *
  6  *  This program is free software; you can redistribute it and/or modify
  7  *  it under the terms of the GNU General Public License as published by
  8  *  the Free Software Foundation; either version 2 of the License, or
  9  *  (at your option) any later version.
 10  *
 11  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
 12  *  GStreamer plugins to be used and distributed together with GStreamer
 13  *  and Rhythmbox. This permission is above and beyond the permissions granted
 14  *  by the GPL license by which Rhythmbox is covered. If you modify this code
 15  *  you may extend this exception to your version of the code, but you are not
 16  *  obligated to do so. If you do not wish to do so, delete this exception
 17  *  statement from your version.
 18  *
 19  *  This program is distributed in the hope that it will be useful,
 20  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 21  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 22  *  GNU General Public License for more details.
 23  *
 24  *  You should have received a copy of the GNU General Public License
 25  *  along with this program; if not, write to the Free Software
 26  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 27  *
 28  */
 29 
 30 #include <sys/stat.h>
 31 #include <stdlib.h>
 32 #include <stdio.h>
 33 #include <string.h>
 34 
 35 #include "rhythmdb.h"
 36 #include "rb-daap-record.h"
 37 
 38 struct RBDAAPRecordPrivate {
 39 	guint64 filesize;
 40 	char *location;
 41 	char *format;	 /* Format, possibly after transcoding. */
 42 	char *real_format;
 43 	char *title;
 44 	char *album;
 45 	char *artist;
 46 	char *genre;
 47 	gboolean has_video;
 48 	gint mediakind;
 49 	gint rating;
 50 	int duration;
 51 	int track;
 52 	int year;
 53 	int firstseen;
 54 	int mtime;
 55 	int disc;
 56 	int bitrate;
 57 	char *sort_artist;
 58 	char *sort_album;
 59 	gint64 albumid;
 60 };
 61 
 62 enum {
 63 	PROP_0,
 64 	PROP_LOCATION,
 65 	PROP_TITLE,
 66 	PROP_RATING,
 67 	PROP_FILESIZE,
 68 	PROP_ALBUM,
 69 	PROP_ARTIST,
 70 	PROP_GENRE,
 71 	PROP_MEDIAKIND,
 72 	PROP_FORMAT,
 73 	PROP_DURATION,
 74 	PROP_TRACK,
 75 	PROP_YEAR,
 76 	PROP_FIRSTSEEN,
 77 	PROP_MTIME,
 78 	PROP_DISC,
 79 	PROP_BITRATE,
 80 	PROP_HAS_VIDEO,
 81 	PROP_REAL_FORMAT,
 82 	PROP_ARTIST_SORT_NAME,
 83 	PROP_ALBUM_SORT_NAME,
 84 	PROP_ALBUM_ID
 85 };
 86 
 87 static void rb_daap_record_finalize (GObject *object);
 88 
 89 static void
 90 rb_daap_record_set_property (GObject *object,
 91 				guint prop_id,
 92 				const GValue *value,
 93 				GParamSpec *pspec)
 94 {
 95 	RBDAAPRecord *record = RB_DAAP_RECORD (object);
 96 
 97 	switch (prop_id) {
 98 		case PROP_LOCATION:
 99 			g_free (record->priv->location);
100 			record->priv->location = g_value_dup_string (value);
101 			break;
102 		case PROP_TITLE:
103 			g_free (record->priv->title);
104 			record->priv->title = g_value_dup_string (value);
105 			break;
106 		case PROP_ALBUM:
107 			g_free (record->priv->album);
108 			record->priv->album = g_value_dup_string (value);
109 			break;
110 		case PROP_ALBUM_ID:
111 			record->priv->albumid = g_value_get_int64 (value);
112 			break;
113 		case PROP_ARTIST:
114 			g_free (record->priv->artist);
115 			record->priv->artist = g_value_dup_string (value);
116 			break;
117 		case PROP_GENRE:
118 			g_free (record->priv->genre);
119 			record->priv->genre = g_value_dup_string (value);
120 			break;
121 		case PROP_MEDIAKIND:
122 			record->priv->mediakind = g_value_get_enum (value);
123 			break;
124 		case PROP_FORMAT:
125 			g_free (record->priv->format);
126 			record->priv->format = g_value_dup_string (value);
127 			break;
128 		case PROP_RATING:
129 			record->priv->rating = g_value_get_int (value);
130 			break;
131 		case PROP_FILESIZE:
132 			record->priv->filesize = g_value_get_uint64 (value);
133 			break;
134 		case PROP_DURATION:
135 			record->priv->duration = g_value_get_int (value);
136 			break;
137 		case PROP_TRACK:
138 			record->priv->track = g_value_get_int (value);
139 			break;
140 		case PROP_YEAR:
141 			record->priv->year = g_value_get_int (value);
142 			break;
143 		case PROP_FIRSTSEEN:
144 			record->priv->firstseen = g_value_get_int (value);
145 			break;
146 		case PROP_MTIME:
147 			record->priv->mtime = g_value_get_int (value);
148 			break;
149 		case PROP_DISC:
150 			record->priv->disc = g_value_get_int (value);
151 			break;
152 		case PROP_BITRATE:
153 			record->priv->bitrate = g_value_get_int (value);
154 			break;
155 		case PROP_HAS_VIDEO:
156 			record->priv->has_video = g_value_get_boolean (value);
157 			break;
158 		case PROP_REAL_FORMAT:
159 			g_free (record->priv->real_format);
160 			record->priv->real_format = g_value_dup_string (value);
161 			break;
162 		case PROP_ARTIST_SORT_NAME:
163 			g_free (record->priv->sort_artist);
164 			record->priv->sort_artist = g_value_dup_string (value);
165 			break;
166 		case PROP_ALBUM_SORT_NAME:
167 			g_free (record->priv->sort_album);
168 			record->priv->sort_album = g_value_dup_string (value);
169 			break;
170 		default:
171 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
172 			break;
173 	}
174 }
175 
176 static void
177 rb_daap_record_get_property (GObject *object,
178 				guint prop_id,
179 				GValue *value,
180 				GParamSpec *pspec)
181 {
182 	RBDAAPRecord *record = RB_DAAP_RECORD (object);
183 
184 	switch (prop_id) {
185 		case PROP_LOCATION:
186 			g_value_set_string (value, record->priv->location);
187 			break;
188 		case PROP_TITLE:
189 			g_value_set_string (value, record->priv->title);
190 			break;
191 		case PROP_ALBUM:
192 			g_value_set_string (value, record->priv->album);
193 			break;
194 		case PROP_ALBUM_ID:
195 			g_value_set_int64 (value, record->priv->albumid);
196 			break;
197 		case PROP_ARTIST:
198 			g_value_set_string (value, record->priv->artist);
199 			break;
200 		case PROP_GENRE:
201 			g_value_set_string (value, record->priv->genre);
202 			break;
203 		case PROP_MEDIAKIND:
204 			g_value_set_enum (value, record->priv->mediakind);
205 			break;
206 		case PROP_FORMAT:
207 			g_value_set_string (value, record->priv->format);
208 			break;
209 		case PROP_RATING:
210 			g_value_set_int (value, record->priv->rating);
211 			break;
212 		case PROP_FILESIZE:
213 			g_value_set_uint64 (value, record->priv->filesize);
214 			break;
215 		case PROP_DURATION:
216 			g_value_set_int (value, record->priv->duration);
217 			break;
218 		case PROP_TRACK:
219 			g_value_set_int (value, record->priv->track);
220 			break;
221 		case PROP_YEAR:
222 			g_value_set_int (value, record->priv->year);
223 			break;
224 		case PROP_FIRSTSEEN:
225 			g_value_set_int (value, record->priv->firstseen);
226 			break;
227 		case PROP_MTIME:
228 			g_value_set_int (value, record->priv->mtime);
229 			break;
230 		case PROP_DISC:
231 			g_value_set_int (value, record->priv->disc);
232 			break;
233 		case PROP_BITRATE:
234 			g_value_set_int (value, record->priv->bitrate);
235 			break;
236 		case PROP_HAS_VIDEO:
237 			g_value_set_boolean (value, record->priv->has_video);
238 			break;
239 		case PROP_REAL_FORMAT:
240 			g_value_set_string (value, record->priv->real_format);
241 			break;
242 		case PROP_ARTIST_SORT_NAME:
243 			g_value_set_string (value, record->priv->sort_artist);
244 			break;
245 		case PROP_ALBUM_SORT_NAME:
246 			g_value_set_string (value, record->priv->sort_album);
247 			break;
248 		default:
249 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
250 			break;
251 	}
252 }
253 
254 gboolean
255 rb_daap_record_itunes_compat (DAAPRecord *record)
256 {
257 	const gchar *format = RB_DAAP_RECORD (record)->priv->real_format;
258 
259 	if (! strcmp (format, "mp3"))
260 		return TRUE;
261 	else
262 		return FALSE;
263 }
264 
265 GInputStream *
266 rb_daap_record_read (DAAPRecord *record, GError **error)
267 {
268 	GFile *file;
269 	GInputStream *fnval = NULL;
270 
271 	file = g_file_new_for_uri (RB_DAAP_RECORD (record)->priv->location);
272 	fnval = G_INPUT_STREAM (g_file_read (file, NULL, error));
273 
274 	g_object_unref (file);
275 
276 	return fnval;
277 }
278 
279 static void
280 rb_daap_record_init (RBDAAPRecord *record)
281 {
282 	record->priv = RB_DAAP_RECORD_GET_PRIVATE (record);
283 
284         record->priv->location		= NULL;
285         record->priv->format		= NULL;
286         record->priv->real_format	= NULL;
287         record->priv->title		= NULL;
288         record->priv->album		= NULL;
289         record->priv->artist		= NULL;
290         record->priv->genre		= NULL;
291         record->priv->sort_artist	= NULL;
292         record->priv->sort_album	= NULL;
293 	record->priv->filesize		= 0;
294         record->priv->mediakind		= 0;
295         record->priv->rating		= 0;
296         record->priv->duration		= 0;
297         record->priv->track		= 0;
298         record->priv->year		= 0;
299         record->priv->firstseen		= 0;
300         record->priv->mtime		= 0;
301         record->priv->disc		= 0;
302         record->priv->bitrate		= 0;
303         record->priv->has_video		= FALSE;
304 }
305 
306 static void
307 rb_daap_record_class_init (RBDAAPRecordClass *klass)
308 {
309 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
310 
311 	g_type_class_add_private (klass, sizeof (RBDAAPRecordPrivate));
312 
313 	gobject_class->set_property = rb_daap_record_set_property;
314 	gobject_class->get_property = rb_daap_record_get_property;
315 	gobject_class->finalize     = rb_daap_record_finalize;
316 
317 	g_object_class_override_property (gobject_class, PROP_LOCATION, "location");
318 	g_object_class_override_property (gobject_class, PROP_TITLE, "title");
319 	g_object_class_override_property (gobject_class, PROP_ALBUM, "songalbum");
320 	g_object_class_override_property (gobject_class, PROP_ARTIST, "songartist");
321 	g_object_class_override_property (gobject_class, PROP_GENRE, "songgenre");
322 	g_object_class_override_property (gobject_class, PROP_MEDIAKIND, "mediakind");
323 	g_object_class_override_property (gobject_class, PROP_FORMAT, "format");
324 	g_object_class_override_property (gobject_class, PROP_RATING, "rating");
325 	g_object_class_override_property (gobject_class, PROP_FILESIZE, "filesize");
326 	g_object_class_override_property (gobject_class, PROP_DURATION, "duration");
327 	g_object_class_override_property (gobject_class, PROP_TRACK, "track");
328 	g_object_class_override_property (gobject_class, PROP_YEAR, "year");
329 	g_object_class_override_property (gobject_class, PROP_FIRSTSEEN, "firstseen");
330 	g_object_class_override_property (gobject_class, PROP_MTIME, "mtime");
331 	g_object_class_override_property (gobject_class, PROP_DISC, "disc");
332 	g_object_class_override_property (gobject_class, PROP_BITRATE, "bitrate");
333 	g_object_class_override_property (gobject_class, PROP_HAS_VIDEO, "has-video");
334 	g_object_class_override_property (gobject_class, PROP_ARTIST_SORT_NAME, "sort_artist");
335 	g_object_class_override_property (gobject_class, PROP_ALBUM_SORT_NAME, "sort_album");
336 	g_object_class_override_property (gobject_class, PROP_ALBUM_ID, "songalbumid");
337 
338 	g_object_class_install_property (gobject_class, PROP_REAL_FORMAT,
339 	                        g_param_spec_string ("real-format",
340 			     "Real format of song data",
341 			     "Real format of song data",
342 			       NULL,
343 			    G_PARAM_READWRITE));
344 }
345 
346 static void
347 rb_daap_record_class_finalize (RBDAAPRecordClass *klass)
348 {
349 }
350 
351 static void
352 rb_daap_record_daap_iface_init (gpointer iface, gpointer data)
353 {
354 	DAAPRecordIface *daap_record = iface;
355 
356 	g_assert (G_TYPE_FROM_INTERFACE (daap_record) == DAAP_TYPE_RECORD);
357 
358 	daap_record->itunes_compat = rb_daap_record_itunes_compat;
359 	daap_record->read = rb_daap_record_read;
360 }
361 
362 static void
363 rb_daap_record_dmap_iface_init (gpointer iface, gpointer data)
364 {
365 	DMAPRecordIface *dmap_record = iface;
366 
367 	g_assert (G_TYPE_FROM_INTERFACE (dmap_record) == DMAP_TYPE_RECORD);
368 }
369 
370 G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBDAAPRecord,
371 				rb_daap_record,
372 				G_TYPE_OBJECT,
373 				0,
374 				G_IMPLEMENT_INTERFACE_DYNAMIC (DAAP_TYPE_RECORD, rb_daap_record_daap_iface_init)
375 				G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_RECORD, rb_daap_record_dmap_iface_init))
376 
377 static void
378 rb_daap_record_finalize (GObject *object)
379 {
380 	RBDAAPRecord *record = RB_DAAP_RECORD (object);
381 
382         g_free (record->priv->location);
383 	g_free (record->priv->title);
384 	g_free (record->priv->format);
385 	g_free (record->priv->album);
386 	g_free (record->priv->artist);
387 	g_free (record->priv->genre);
388 	g_free (record->priv->real_format);
389 
390 	G_OBJECT_CLASS (rb_daap_record_parent_class)->finalize (object);
391 }
392 
393 RBDAAPRecord *
394 rb_daap_record_new (RhythmDBEntry *entry)
395 {
396 	RBDAAPRecord *record = NULL;
397 	record = RB_DAAP_RECORD (g_object_new (RB_TYPE_DAAP_RECORD, NULL));
398 
399 	/* When browsing, entry will be NULL because we will pull
400 	 * the metadata from the DAAP query. When sharing, entry will
401 	 * point to an existing entry from the Rhythmbox DB.
402 	 */
403 	if (entry) {
404 		gchar *ext;
405 
406 		record->priv->filesize = rhythmdb_entry_get_uint64
407 						(entry, RHYTHMDB_PROP_FILE_SIZE);
408 
409 		record->priv->location = rhythmdb_entry_dup_string
410 						(entry, RHYTHMDB_PROP_LOCATION);
411 
412 		record->priv->title    = rhythmdb_entry_dup_string
413 						(entry, RHYTHMDB_PROP_TITLE);
414 
415 		record->priv->artist   = rhythmdb_entry_dup_string
416 						(entry, RHYTHMDB_PROP_ARTIST);
417 
418 		record->priv->album    = rhythmdb_entry_dup_string
419 						(entry, RHYTHMDB_PROP_ALBUM);
420 
421 		/* Since we don't support album id's on Rhythmbox, "emulate" it */
422 		record->priv->albumid  = (gintptr) rhythmdb_entry_get_refstring
423 						(entry, RHYTHMDB_PROP_ALBUM);
424 
425 		record->priv->genre    = rhythmdb_entry_dup_string
426 						(entry, RHYTHMDB_PROP_GENRE);
427 
428 		/* FIXME: Support transcoding: */
429 		/* FIXME: we should use RHYTHMDB_PROP_MEDIA_TYPE instead */
430 		ext = strrchr (record->priv->location, '.');
431 		if (ext == NULL) {
432 			ext = "mp3";
433 		} else {
434 			ext++;
435 		}
436 		record->priv->mediakind = DMAP_MEDIA_KIND_MUSIC;
437 		record->priv->real_format = g_strdup (ext);
438 		record->priv->format = g_strdup (record->priv->real_format);
439 
440 		record->priv->track    = rhythmdb_entry_get_ulong
441 						(entry, RHYTHMDB_PROP_TRACK_NUMBER);
442 
443 		record->priv->duration = rhythmdb_entry_get_ulong
444 						(entry, RHYTHMDB_PROP_DURATION);
445 
446 		record->priv->rating   = (gint) rhythmdb_entry_get_double
447 						(entry, RHYTHMDB_PROP_RATING);
448 
449 		record->priv->year     = rhythmdb_entry_get_ulong
450 						(entry, RHYTHMDB_PROP_YEAR);
451 
452 		record->priv->firstseen = rhythmdb_entry_get_ulong
453 						(entry, RHYTHMDB_PROP_FIRST_SEEN);
454 
455 		record->priv->mtime     = rhythmdb_entry_get_ulong
456 						(entry, RHYTHMDB_PROP_MTIME);
457 
458 		record->priv->disc      = rhythmdb_entry_get_ulong
459 						(entry, RHYTHMDB_PROP_DISC_NUMBER);
460 
461 		record->priv->bitrate   = rhythmdb_entry_get_ulong
462 						(entry, RHYTHMDB_PROP_BITRATE);
463 	}
464 
465 	return record;
466 }
467 
468 void
469 _rb_daap_record_register_type (GTypeModule *module)
470 {
471 	rb_daap_record_register_type (module);
472 }