1 /*
2  *  Copyright (C) 2005 Marc Pavot <marc.pavot@gmail.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2, or (at your option)
7  *  any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19 
20 #include "covers/ario-cover-manager.h"
21 #include <gtk/gtk.h>
22 #include <string.h>
23 #include <config.h>
24 #include <glib/gi18n.h>
25 #include "lib/ario-conf.h"
26 #include "covers/ario-cover-lastfm.h"
27 #include "covers/ario-cover-local.h"
28 #include "preferences/ario-preferences.h"
29 #include "ario-debug.h"
30 
31 struct ArioCoverManagerPrivate
32 {
33         GSList *providers;
34 };
35 
36 #define ARIO_COVER_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_ARIO_COVER_MANAGER, ArioCoverManagerPrivate))
G_DEFINE_TYPE(ArioCoverManager,ario_cover_manager,G_TYPE_OBJECT)37 G_DEFINE_TYPE (ArioCoverManager, ario_cover_manager, G_TYPE_OBJECT)
38 
39 static void
40 ario_cover_manager_class_init (ArioCoverManagerClass *klass)
41 {
42         ARIO_LOG_FUNCTION_START;
43         g_type_class_add_private (klass, sizeof (ArioCoverManagerPrivate));
44 }
45 
46 static void
ario_cover_manager_init(ArioCoverManager * cover_manager)47 ario_cover_manager_init (ArioCoverManager *cover_manager)
48 {
49         ARIO_LOG_FUNCTION_START;
50 
51         cover_manager->priv = ARIO_COVER_MANAGER_GET_PRIVATE (cover_manager);
52 }
53 
54 ArioCoverManager *
ario_cover_manager_get_instance(void)55 ario_cover_manager_get_instance (void)
56 {
57         ARIO_LOG_FUNCTION_START;
58         static ArioCoverManager *cover_manager = NULL;
59 
60         if (!cover_manager) {
61                 ArioCoverProvider *cover_provider;
62 
63                 cover_manager = g_object_new (TYPE_ARIO_COVER_MANAGER,
64                                               NULL);
65                 g_return_val_if_fail (cover_manager->priv != NULL, NULL);
66 
67                 cover_provider = ario_cover_local_new ();
68                 ario_cover_manager_add_provider (cover_manager,
69                                                  ARIO_COVER_PROVIDER (cover_provider));
70 
71                 cover_provider = ario_cover_lastfm_new ();
72                 ario_cover_manager_add_provider (cover_manager,
73                                                  ARIO_COVER_PROVIDER (cover_provider));
74 
75                 ario_cover_manager_update_providers (cover_manager);
76         }
77 
78         return cover_manager;
79 }
80 
81 static void
ario_cover_manager_shutdown_foreach(ArioCoverProvider * cover_provider,GSList ** providers)82 ario_cover_manager_shutdown_foreach (ArioCoverProvider *cover_provider,
83                                      GSList **providers)
84 {
85         *providers = g_slist_append (*providers, ario_cover_provider_get_id (cover_provider));
86 }
87 
88 static void
ario_cover_manager_shutdown_active_foreach(ArioCoverProvider * cover_provider,GSList ** providers)89 ario_cover_manager_shutdown_active_foreach (ArioCoverProvider *cover_provider,
90                                             GSList **providers)
91 {
92         if (ario_cover_provider_is_active (cover_provider))
93                 *providers = g_slist_append (*providers, ario_cover_provider_get_id (cover_provider));
94 }
95 
96 void
ario_cover_manager_shutdown(ArioCoverManager * cover_manager)97 ario_cover_manager_shutdown (ArioCoverManager *cover_manager)
98 {
99 
100         GSList *providers = NULL;
101         GSList *active_providers = NULL;
102 
103         g_slist_foreach (cover_manager->priv->providers, (GFunc) ario_cover_manager_shutdown_foreach, &providers);
104         g_slist_foreach (cover_manager->priv->providers, (GFunc) ario_cover_manager_shutdown_active_foreach, &active_providers);
105 
106         ario_conf_set_string_slist (PREF_COVER_PROVIDERS_LIST, providers);
107         ario_conf_set_string_slist (PREF_COVER_ACTIVE_PROVIDERS_LIST, active_providers);
108         g_slist_free (providers);
109         g_slist_free (active_providers);
110 }
111 
112 static gint
ario_cover_manager_compare_providers(ArioCoverProvider * cover_provider,const gchar * id)113 ario_cover_manager_compare_providers (ArioCoverProvider *cover_provider,
114                                       const gchar *id)
115 {
116         return strcmp (ario_cover_provider_get_id (cover_provider), id);
117 }
118 
119 void
ario_cover_manager_update_providers(ArioCoverManager * cover_manager)120 ario_cover_manager_update_providers (ArioCoverManager *cover_manager)
121 {
122         ARIO_LOG_FUNCTION_START;
123         GSList *conf_tmp;
124         GSList *conf_providers;
125         GSList *conf_active_providers;
126         GSList *found;
127         GSList *providers = NULL;
128         ArioCoverProvider *cover_provider;
129 
130         conf_providers = ario_conf_get_string_slist (PREF_COVER_PROVIDERS_LIST, PREF_COVER_PROVIDERS_LIST_DEFAULT);
131         for (conf_tmp = conf_providers; conf_tmp; conf_tmp = g_slist_next (conf_tmp)) {
132                 found = g_slist_find_custom (cover_manager->priv->providers,
133                                              conf_tmp->data,
134                                              (GCompareFunc) ario_cover_manager_compare_providers);
135                 if (found) {
136                         providers = g_slist_append (providers, found->data);
137                 }
138         }
139         g_slist_foreach (conf_providers, (GFunc) g_free, NULL);
140         g_slist_free (conf_providers);
141 
142         conf_active_providers = ario_conf_get_string_slist (PREF_COVER_ACTIVE_PROVIDERS_LIST, PREF_COVER_ACTIVE_PROVIDERS_LIST_DEFAULT);
143         for (conf_tmp = conf_active_providers; conf_tmp; conf_tmp = g_slist_next (conf_tmp)) {
144                 found = g_slist_find_custom (providers,
145                                              conf_tmp->data,
146                                              (GCompareFunc) ario_cover_manager_compare_providers);
147                 if (found) {
148                         cover_provider = found->data;
149                         ario_cover_provider_set_active (cover_provider, TRUE);
150                 }
151         }
152         g_slist_foreach (conf_active_providers, (GFunc) g_free, NULL);
153         g_slist_free (conf_active_providers);
154 
155         for (conf_tmp = cover_manager->priv->providers; conf_tmp; conf_tmp = g_slist_next (conf_tmp)) {
156                 if (!g_slist_find (providers, conf_tmp->data)) {
157                         providers = g_slist_append (providers, conf_tmp->data);
158                 }
159         }
160 
161         g_slist_free (cover_manager->priv->providers);
162         cover_manager->priv->providers = providers;
163 }
164 
165 GSList*
ario_cover_manager_get_providers(ArioCoverManager * cover_manager)166 ario_cover_manager_get_providers (ArioCoverManager *cover_manager)
167 {
168         ARIO_LOG_FUNCTION_START;
169         return cover_manager->priv->providers;
170 }
171 
172 void
ario_cover_manager_set_providers(ArioCoverManager * cover_manager,GSList * providers)173 ario_cover_manager_set_providers (ArioCoverManager *cover_manager,
174                                   GSList *providers)
175 {
176         ARIO_LOG_FUNCTION_START;
177         cover_manager->priv->providers = providers;
178 }
179 
180 ArioCoverProvider*
ario_cover_manager_get_provider_from_id(ArioCoverManager * cover_manager,const gchar * id)181 ario_cover_manager_get_provider_from_id (ArioCoverManager *cover_manager,
182                                          const gchar *id)
183 {
184         ARIO_LOG_FUNCTION_START;
185         GSList *found;
186 
187         found = g_slist_find_custom (cover_manager->priv->providers,
188                                      id,
189                                      (GCompareFunc) ario_cover_manager_compare_providers);
190 
191         return ARIO_COVER_PROVIDER (found->data);
192 }
193 
194 
195 void
ario_cover_manager_add_provider(ArioCoverManager * cover_manager,ArioCoverProvider * cover_provider)196 ario_cover_manager_add_provider (ArioCoverManager *cover_manager,
197                                  ArioCoverProvider *cover_provider)
198 {
199         ARIO_LOG_FUNCTION_START;
200         cover_manager->priv->providers = g_slist_append (cover_manager->priv->providers, cover_provider);
201 }
202 
203 void
ario_cover_manager_remove_provider(ArioCoverManager * cover_manager,ArioCoverProvider * cover_provider)204 ario_cover_manager_remove_provider (ArioCoverManager *cover_manager,
205                                     ArioCoverProvider *cover_provider)
206 {
207         ARIO_LOG_FUNCTION_START;
208         cover_manager->priv->providers = g_slist_remove (cover_manager->priv->providers, cover_provider);
209 }
210 
211 gboolean
ario_cover_manager_get_covers(ArioCoverManager * cover_manager,const char * artist,const char * album,const char * file,GArray ** file_size,GSList ** file_contents,ArioCoverProviderOperation operation)212 ario_cover_manager_get_covers (ArioCoverManager *cover_manager,
213                                const char *artist,
214                                const char *album,
215                                const char *file,
216                                GArray **file_size,
217                                GSList **file_contents,
218                                ArioCoverProviderOperation operation)
219 {
220         ARIO_LOG_FUNCTION_START;
221         GSList *tmp;
222         ArioCoverProvider *cover_provider;
223         gboolean ret = FALSE;
224 
225         for (tmp = cover_manager->priv->providers; tmp; tmp = g_slist_next (tmp)) {
226                 cover_provider = tmp->data;
227                 if (!ario_cover_provider_is_active (cover_provider))
228                         continue;
229                 ARIO_LOG_DBG ("looking for a cover using provider:%s for album:%s\n", ario_cover_provider_get_name (cover_provider), album);
230 
231                 if (ario_cover_provider_get_covers (cover_provider,
232                                                     artist, album,
233                                                     file,
234                                                     file_size, file_contents,
235                                                     operation)) {
236                         ret = TRUE;
237                         if (operation == GET_FIRST_COVER)
238                                 break;
239                 }
240         }
241         return ret;
242 }
243 
244 
245