hythmbox-2.98/plugins/generic-player/rb-psp-source.c

No issues found

  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2  *
  3  *  Copyright (C) 2006 James Livingston  <doclivingston@gmail.com>
  4  *
  5  *  This program is free software; you can redistribute it and/or modify
  6  *  it under the terms of the GNU General Public License as published by
  7  *  the Free Software Foundation; either version 2 of the License, or
  8  *  (at your option) any later version.
  9  *
 10  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
 11  *  GStreamer plugins to be used and distributed together with GStreamer
 12  *  and Rhythmbox. This permission is above and beyond the permissions granted
 13  *  by the GPL license by which Rhythmbox is covered. If you modify this code
 14  *  you may extend this exception to your version of the code, but you are not
 15  *  obligated to do so. If you do not wish to do so, delete this exception
 16  *  statement from your version.
 17  *
 18  *  This program is distributed in the hope that it will be useful,
 19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 21  *  GNU General Public License for more details.
 22  *
 23  *  You should have received a copy of the GNU General Public License
 24  *  along with this program; if not, write to the Free Software
 25  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
 26  *
 27  */
 28 
 29 #define __EXTENSIONS__
 30 
 31 #include "config.h"
 32 
 33 #include <string.h>
 34 
 35 #include <glib/gi18n.h>
 36 #include <gtk/gtk.h>
 37 
 38 #include "mediaplayerid.h"
 39 
 40 #include "rb-psp-source.h"
 41 #include "rb-debug.h"
 42 #include "rb-util.h"
 43 #include "rb-file-helpers.h"
 44 #include "rb-auto-playlist-source.h"
 45 #include "rhythmdb.h"
 46 
 47 
 48 static void rb_psp_source_create_playlists (RBGenericPlayerSource *source);
 49 
 50 G_DEFINE_DYNAMIC_TYPE (RBPspSource, rb_psp_source, RB_TYPE_GENERIC_PLAYER_SOURCE)
 51 
 52 
 53 static void
 54 rb_psp_source_class_init (RBPspSourceClass *klass)
 55 {
 56 	RBGenericPlayerSourceClass *generic_class = RB_GENERIC_PLAYER_SOURCE_CLASS (klass);
 57 	generic_class->impl_load_playlists = rb_psp_source_create_playlists;
 58 }
 59 
 60 static void
 61 rb_psp_source_class_finalize (RBPspSourceClass *klass)
 62 {
 63 }
 64 
 65 static void
 66 rb_psp_source_init (RBPspSource *source)
 67 {
 68 }
 69 
 70 RBSource *
 71 rb_psp_source_new (GObject *plugin, RBShell *shell, GMount *mount, MPIDDevice *device_info)
 72 {
 73 	RBPspSource *source;
 74 	RhythmDBEntryType *entry_type;
 75 	RhythmDB *db;
 76 	char *name;
 77 	char *path;
 78 	GVolume *volume;
 79 
 80 	g_assert (rb_psp_is_mount_player (mount, device_info));
 81 
 82 	volume = g_mount_get_volume (mount);
 83 
 84 	g_object_get (G_OBJECT (shell), "db", &db, NULL);
 85 	path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
 86 	name = g_strdup_printf ("psp: %s", path);
 87 	entry_type = g_object_new (RHYTHMDB_TYPE_ENTRY_TYPE,
 88 				   "db", db,
 89 				   "name", name,
 90 				   "save-to-disk", FALSE,
 91 				   "category", RHYTHMDB_ENTRY_NORMAL,
 92 				   NULL);
 93 	rhythmdb_register_entry_type (db, entry_type);
 94 	g_object_unref (db);
 95 	g_free (name);
 96 	g_free (path);
 97 	g_object_unref (volume);
 98 
 99 	source = RB_PSP_SOURCE (g_object_new (RB_TYPE_PSP_SOURCE,
100 					  "plugin", plugin,
101 					  "entry-type", entry_type,
102 					  "mount", mount,
103 					  "shell", shell,
104 					  "device-info", device_info,
105 					  NULL));
106 
107 	rb_shell_register_entry_type_for_source (shell, RB_SOURCE (source), entry_type);
108 
109 	return RB_SOURCE (source);
110 }
111 
112 static GFile *
113 find_dir_no_case (GFile *root, gboolean look_for_psp)
114 {
115 	GFileEnumerator *e;
116 	GFileInfo *info;
117 	GFile *ret;
118 	GFile *music_dir;
119 
120 	ret = music_dir = NULL;
121 	e = g_file_enumerate_children (root, G_FILE_ATTRIBUTE_STANDARD_NAME","G_FILE_ATTRIBUTE_STANDARD_TYPE,
122 				       G_FILE_QUERY_INFO_NONE, NULL, NULL);
123 	if (e == NULL)
124 		return ret;
125 
126 	while ((info = g_file_enumerator_next_file (e, NULL, NULL)) != NULL) {
127 		const char *name;
128 
129 		name = g_file_info_get_name (info);
130 		if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY) {
131 			g_object_unref (info);
132 			continue;
133 		}
134 
135 		if (g_ascii_strcasecmp (name, "MUSIC") == 0) {
136 			music_dir = g_file_resolve_relative_path (root, name);
137 			g_object_unref (info);
138 			if (look_for_psp)
139 				continue;
140 			else
141 				break;
142 		}
143 
144 		if (look_for_psp) {
145 			if (g_ascii_strcasecmp (name, "PSP") == 0) {
146 				GFile *psp_dir;
147 
148 				psp_dir = g_file_resolve_relative_path (root, name);
149 				ret = find_dir_no_case (psp_dir, FALSE);
150 				g_object_unref (psp_dir);
151 
152 				if (ret != NULL) {
153 					g_object_unref (info);
154 					if (music_dir != NULL)
155 						g_object_unref (music_dir);
156 					music_dir = NULL;
157 					break;
158 				}
159 			}
160 		}
161 		g_object_unref (info);
162 	}
163 	g_object_unref (e);
164 
165 	if (ret == NULL)
166 		ret = music_dir;
167 
168 	return ret;
169 }
170 
171 static GFile *
172 find_music_dir (GMount *mount)
173 {
174 	GFile *root;
175 	GFile *music_dir = NULL;
176 
177 	root = g_mount_get_root (mount);
178 	if (root != NULL) {
179 		music_dir = find_dir_no_case (root, TRUE);
180 		/* FIXME create directories if they don't exist */
181 		g_object_unref (root);
182 	}
183 
184 	return music_dir;
185 }
186 
187 static void
188 visit_playlist_dirs (RBPspSource *source,
189 		     GFile *file)
190 {
191 	RBShell *shell;
192 	RhythmDB *db;
193 	RhythmDBEntryType *entry_type;
194 	char *playlist_path;
195 	char *playlist_name;
196 	RBSource *playlist;
197 	GPtrArray *query;
198 
199 	playlist_path = g_file_get_uri (file);		/* or _get_path? */
200 
201 	g_object_get (source,
202 		      "shell", &shell,
203 		      "entry-type", &entry_type,
204 		      NULL);
205 	g_object_get (shell,
206 		      "db", &db,
207 		      NULL);
208 
209 	/* FIXME this isn't good enough, we only need the files directly under the playlist directory,
210 	 * not sub-dirs */
211 	query = rhythmdb_query_parse (db,
212 				      RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type,
213 				      RHYTHMDB_QUERY_PROP_PREFIX, RHYTHMDB_PROP_LOCATION, playlist_path,
214 				      RHYTHMDB_QUERY_END);
215 	g_free (playlist_path);
216         g_object_unref (entry_type);
217 
218 	playlist_name = g_file_get_basename (file);
219 	playlist = rb_auto_playlist_source_new (shell, playlist_name, FALSE);
220 	g_free (playlist_name);
221 
222 	rb_auto_playlist_source_set_query (RB_AUTO_PLAYLIST_SOURCE (playlist), query,
223 					   RHYTHMDB_QUERY_MODEL_LIMIT_NONE, NULL,
224 					   NULL, 0);
225 	rb_generic_player_source_add_playlist (RB_GENERIC_PLAYER_SOURCE (source), shell, RB_SOURCE (playlist));
226 	rhythmdb_query_free (query);
227 
228 	g_object_unref (shell);
229 	g_object_unref (db);
230 }
231 
232 
233 static void
234 rb_psp_source_create_playlists (RBGenericPlayerSource *source)
235 {
236 	GMount *mount;
237 	GFile *music_dir;
238 
239 	g_object_get (source, "mount", &mount, NULL);
240 	music_dir = find_music_dir (mount);
241 	g_object_unref (mount);
242 
243 	if (music_dir != NULL) {
244 		GFileEnumerator *e;
245 		GFileInfo *info;
246 
247 		e = g_file_enumerate_children (music_dir, G_FILE_ATTRIBUTE_STANDARD_NAME","G_FILE_ATTRIBUTE_STANDARD_TYPE,
248 					       G_FILE_QUERY_INFO_NONE, NULL, NULL);
249 		if (e != NULL) {
250 			while ((info = g_file_enumerator_next_file (e, NULL, NULL)) != NULL) {
251 				GFile *file;
252 				const char *name;
253 				if (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY) {
254 					g_object_unref (info);
255 					continue;
256 				}
257 				name = g_file_info_get_name (info);
258 				file = g_file_resolve_relative_path (music_dir, name);
259 				visit_playlist_dirs (RB_PSP_SOURCE (source), file);
260 				g_object_unref (file);
261 				g_object_unref (info);
262 			}
263 			g_object_unref (e);
264 		}
265 		g_object_unref (music_dir);
266 	}
267 }
268 
269 gboolean
270 rb_psp_is_mount_player (GMount *mount, MPIDDevice *device_info)
271 {
272 	char *model;
273 	gboolean result = FALSE;
274 
275 	g_object_get (device_info, "model", &model, NULL);
276 	if (model != NULL && (g_str_equal (model, "PSP") || g_str_equal (model, "\"PSP\" MS"))) {
277 		result = TRUE;
278 	}
279 	g_free (model);
280 
281 	return result;
282 }
283 
284 void
285 _rb_psp_source_register_type (GTypeModule *module)
286 {
287 	rb_psp_source_register_type (module);
288 }