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 }