No issues found
1 /*
2 * Database adapter class for DMAP 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 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include "rhythmdb.h"
35 #include "rb-rhythmdb-dmap-db-adapter.h"
36 #include "rb-daap-record.h"
37
38 #include <glib/gi18n.h>
39 #include <libdmapsharing/dmap.h>
40
41 struct RBRhythmDBDMAPDbAdapterPrivate {
42 RhythmDB *db;
43 RhythmDBEntryType *entry_type;
44 };
45
46 typedef struct ForeachAdapterData {
47 gpointer data;
48 GHFunc func;
49 } ForeachAdapterData;
50
51 static DMAPRecord *
52 rb_rhythmdb_dmap_db_adapter_lookup_by_id (const DMAPDb *db, guint id)
53 {
54 RhythmDBEntry *entry;
55
56 g_assert (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db != NULL);
57
58 entry = rhythmdb_entry_lookup_by_id (
59 RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db,
60 id);
61
62 return DMAP_RECORD (rb_daap_record_new (entry));
63 }
64
65 static void
66 foreach_adapter (RhythmDBEntry *entry, gpointer data)
67 {
68 gulong id;
69 DMAPRecord *record;
70 ForeachAdapterData *foreach_adapter_data;
71
72 id = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
73 foreach_adapter_data = data;
74 record = DMAP_RECORD (rb_daap_record_new (entry));
75
76 foreach_adapter_data->func (GUINT_TO_POINTER (id),
77 record,
78 foreach_adapter_data->data);
79
80 g_object_unref (record);
81 }
82
83 static void
84 rb_rhythmdb_dmap_db_adapter_foreach (const DMAPDb *db,
85 GHFunc func,
86 gpointer data)
87 {
88 ForeachAdapterData *foreach_adapter_data;
89
90 g_assert (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db != NULL);
91
92 foreach_adapter_data = g_new (ForeachAdapterData, 1);
93 foreach_adapter_data->data = data;
94 foreach_adapter_data->func = func;
95
96 rhythmdb_entry_foreach_by_type (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db,
97 RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->entry_type,
98 (GFunc) foreach_adapter,
99 foreach_adapter_data);
100
101 g_free (foreach_adapter_data);
102 }
103
104 static gint64
105 rb_rhythmdb_dmap_db_adapter_count (const DMAPDb *db)
106 {
107 g_assert (RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db != NULL);
108 return rhythmdb_entry_count_by_type (
109 RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->db,
110 RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv->entry_type);
111 }
112
113 static void
114 entry_set_string_prop (RhythmDB *db,
115 RhythmDBEntry *entry,
116 RhythmDBPropType propid,
117 const char *str)
118 {
119 GValue value = {0,};
120 const gchar *tmp;
121
122 if (str == NULL || *str == '\0' || !g_utf8_validate (str, -1, NULL)) {
123 tmp = _("Unknown");
124 } else {
125 tmp = str;
126 }
127
128 g_value_init (&value, G_TYPE_STRING);
129 g_value_set_string (&value, tmp);
130 rhythmdb_entry_set (RHYTHMDB (db), entry, propid, &value);
131 g_value_unset (&value);
132 }
133
134 static guint
135 rb_rhythmdb_dmap_db_adapter_add (DMAPDb *db, DMAPRecord *record)
136 {
137 gchar *uri = NULL;
138 const gchar *title = NULL;
139 const gchar *album = NULL;
140 const gchar *artist = NULL;
141 const gchar *format = NULL;
142 const gchar *genre = NULL;
143 gint length = 0;
144 gint track = 0;
145 gint disc = 0;
146 gint year = 0;
147 gint filesize = 0;
148 gint bitrate = 0;
149 GValue value = { 0, };
150 RhythmDBEntry *entry = NULL;
151 RBRhythmDBDMAPDbAdapterPrivate *priv = RB_RHYTHMDB_DMAP_DB_ADAPTER (db)->priv;
152
153 g_assert (priv->db != NULL);
154
155 g_object_get (record,
156 "location", &uri,
157 "year", &year,
158 "track", &track,
159 "disc", &disc,
160 "bitrate", &bitrate,
161 "duration", &length,
162 "filesize", &filesize,
163 "format", &format,
164 "title", &title,
165 "songalbum", &album,
166 "songartist", &artist,
167 "songgenre", &genre,
168 NULL);
169
170 entry = rhythmdb_entry_new (priv->db, priv->entry_type, uri);
171
172 if (entry == NULL) {
173 g_warning ("cannot create entry for daap track %s", uri);
174 return FALSE;
175 }
176
177 /* year */
178 if (year != 0) {
179 GDate date;
180 gulong julian;
181
182 /* create dummy date with given year */
183 g_date_set_dmy (&date, 1, G_DATE_JANUARY, year);
184 julian = g_date_get_julian (&date);
185
186 g_value_init (&value, G_TYPE_ULONG);
187 g_value_set_ulong (&value,julian);
188 rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DATE, &value);
189 g_value_unset (&value);
190 }
191
192 /* track number */
193 g_value_init (&value, G_TYPE_ULONG);
194 g_value_set_ulong (&value,(gulong)track);
195 rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_TRACK_NUMBER, &value);
196 g_value_unset (&value);
197
198 /* disc number */
199 g_value_init (&value, G_TYPE_ULONG);
200 g_value_set_ulong (&value,(gulong)disc);
201 rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DISC_NUMBER, &value);
202 g_value_unset (&value);
203
204 /* bitrate */
205 g_value_init (&value, G_TYPE_ULONG);
206 g_value_set_ulong (&value,(gulong)bitrate);
207 rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_BITRATE, &value);
208 g_value_unset (&value);
209
210 /* length */
211 g_value_init (&value, G_TYPE_ULONG);
212 g_value_set_ulong (&value,(gulong)length);
213 rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_DURATION, &value);
214 g_value_unset (&value);
215
216 /* file size */
217 g_value_init (&value, G_TYPE_UINT64);
218 g_value_set_uint64(&value,(gint64)filesize);
219 rhythmdb_entry_set (priv->db, entry, RHYTHMDB_PROP_FILE_SIZE, &value);
220 g_value_unset (&value);
221
222 /* title */
223 entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_TITLE, title);
224
225 /* album */
226 entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ALBUM, album);
227
228 /* artist */
229 entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_ARTIST, artist);
230
231 /* genre */
232 entry_set_string_prop (priv->db, entry, RHYTHMDB_PROP_GENRE, genre);
233
234 rhythmdb_commit (priv->db);
235
236 return rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_ENTRY_ID);
237 }
238
239 static void
240 rb_rhythmdb_dmap_db_adapter_init (RBRhythmDBDMAPDbAdapter *db)
241 {
242 db->priv = RB_RHYTHMDB_DMAP_DB_ADAPTER_GET_PRIVATE (db);
243 }
244
245 static void
246 rb_rhythmdb_dmap_db_adapter_class_init (RBRhythmDBDMAPDbAdapterClass *klass)
247 {
248 g_type_class_add_private (klass, sizeof (RBRhythmDBDMAPDbAdapterPrivate));
249 }
250
251 static void
252 rb_rhythmdb_dmap_db_adapter_class_finalize (RBRhythmDBDMAPDbAdapterClass *klass)
253 {
254 }
255
256 static void
257 rb_rhythmdb_dmap_db_adapter_interface_init (gpointer iface, gpointer data)
258 {
259 DMAPDbIface *dmap_db = iface;
260
261 g_assert (G_TYPE_FROM_INTERFACE (dmap_db) == DMAP_TYPE_DB);
262
263 dmap_db->add = rb_rhythmdb_dmap_db_adapter_add;
264 dmap_db->lookup_by_id = rb_rhythmdb_dmap_db_adapter_lookup_by_id;
265 dmap_db->foreach = rb_rhythmdb_dmap_db_adapter_foreach;
266 dmap_db->count = rb_rhythmdb_dmap_db_adapter_count;
267 }
268
269 G_DEFINE_DYNAMIC_TYPE_EXTENDED (RBRhythmDBDMAPDbAdapter,
270 rb_rhythmdb_dmap_db_adapter,
271 G_TYPE_OBJECT,
272 0,
273 G_IMPLEMENT_INTERFACE_DYNAMIC (DMAP_TYPE_DB,
274 rb_rhythmdb_dmap_db_adapter_interface_init))
275
276 RBRhythmDBDMAPDbAdapter *
277 rb_rhythmdb_dmap_db_adapter_new (RhythmDB *rdb, RhythmDBEntryType *entry_type)
278 {
279 RBRhythmDBDMAPDbAdapter *db;
280
281 db = RB_RHYTHMDB_DMAP_DB_ADAPTER (g_object_new (RB_TYPE_DMAP_DB_ADAPTER,
282 NULL));
283
284 db->priv->db = rdb;
285 db->priv->entry_type = entry_type;
286
287 return db;
288 }
289
290 void
291 _rb_rhythmdb_dmap_db_adapter_register_type (GTypeModule *module)
292 {
293 rb_rhythmdb_dmap_db_adapter_register_type (module);
294 }