hythmbox-2.98/plugins/daap/rb-rhythmdb-dmap-db-adapter.c

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 }