1 /* gmpc-lyricsplugin (GMPC plugin)
2 * Copyright (C) 2008-2009 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpcwiki.sarine.nl/
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.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <glib/gi18n-lib.h>
26 #include <libxml/parser.h>
27 #include <libxml/tree.h>
28 #include <gmpc/gmpc_easy_download.h>
29 #include <gmpc/plugin.h>
30 #include <gmpc/gmpc-extras.h>
33 #define LYRIC_PLUGINs_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), lyricsplugin_plugin_get_type(), LyricsPlugin))
35 const GType
lyricsplugin_plugin_get_type(void);
39 static int lyricsplugin_get_enabled(GmpcPluginBase
*base
)
41 return cfg_get_single_value_as_int_with_default(config
, "lyricsplugin-plugin", "enable", TRUE
);
43 static void lyricsplugin_set_enabled(GmpcPluginBase
*base
,int enabled
)
45 cfg_set_single_value_as_int(config
, "lyricsplugin-plugin", "enable", enabled
);
49 static int lyricsplugin_fetch_cover_priority(GmpcPluginMetaDataIface
*base
){
50 return cfg_get_single_value_as_int_with_default(config
, "lyricsplugin-plugin", "priority", 80);
52 static void lyricsplugin_fetch_cover_priority_set(GmpcPluginMetaDataIface
*base
, int priority
){
53 cfg_set_single_value_as_int(config
, "lyricsplugin-plugin", "priority", priority
);
55 typedef struct Query
{
57 void (*callback
)(GList
*, gpointer
);
61 static void lyricsplugin_download_callback(const GEADAsyncHandler
*handle
, GEADStatus status
, gpointer data
)
63 Query
*q
= (Query
*)data
;
65 if(status
== GEAD_PROGRESS
) return;
66 if(status
== GEAD_DONE
)
69 const char *data
= gmpc_easy_handler_get_data(handle
, &size
);
70 xmlDocPtr doc
= xmlReadMemory(data
, (int)size
, gmpc_easy_handler_get_uri(handle
), NULL
, XML_PARSE_NOERROR
|XML_PARSE_RECOVER
);//xmlParseMemory(data,(int)size);
73 xmlNodePtr root
= xmlDocGetRootElement(doc
);
74 xmlNodePtr cur
= root
->xmlChildrenNode
;
75 for(;cur
;cur
= cur
->next
){
76 if(xmlStrEqual(cur
->name
, (xmlChar
*)"body")){
77 xmlNodePtr cur2
= cur
->xmlChildrenNode
;
78 for(;cur2
;cur2
= cur2
->next
)
80 if(xmlStrEqual(cur2
->name
, (xmlChar
*)"div"))
82 xmlChar
*property
= xmlGetProp(cur2
, "id");
83 if(property
&& xmlStrEqual(property
, "lyrics"))
85 xmlChar
*lyric
= xmlNodeGetContent(cur2
);
86 if(lyric
&& strlen(lyric
) > 10)
88 MetaData
*mtd
= meta_data_new();
89 mtd
->type
= META_SONG_TXT
;
90 mtd
->plugin_name
= _("Lyrics Plugin");
91 mtd
->content_type
= META_DATA_CONTENT_TEXT
;
92 mtd
->content
= g_strdup(g_strstrip(lyric
));
94 list
= g_list_append(list
,mtd
);
98 if(property
)xmlFree(property
);
107 q
->callback(list
, q
->user_data
);
111 static void lyricsplugin_get_uri(GmpcPluginMetaDataIface
*base
, const mpd_Song
*song
, MetaDataType type
, GmpcPluginMetaDataCallback callback
, void *user_data
)
113 g_debug("Lyricwiki plugin api V2");
114 if(lyricsplugin_get_enabled(GMPC_PLUGIN_BASE(base
)) && type
== META_SONG_TXT
&& song
&& song
->artist
&&song
->title
)
116 Query
*q
= g_malloc0(sizeof(*q
));
117 gchar
*artist
= gmpc_easy_download_uri_escape(song
->artist
);
118 gchar
*title
= gmpc_easy_download_uri_escape(song
->title
);
120 gchar
*uri_path
= g_strdup_printf(
121 "http://www.lyricsplugin.com/winamp03/plugin/?artist=%s&title=%s",
123 q
->callback
= callback
;
124 q
->song
= (mpd_Song
*) song
;
125 q
->user_data
= user_data
;
127 g_free(artist
); g_free(title
);
128 g_debug("Trying: '%s'", uri_path
);
129 if(gmpc_easy_async_downloader(uri_path
, lyricsplugin_download_callback
, q
)!= NULL
)
137 /* Return nothing found */
138 callback(NULL
, user_data
);
144 static void lyricsplugin_plugin_class_init (LyricsPluginClass
*klass
);
146 static int *lyricsplugin_plugin_get_version(GmpcPluginBase
*plug
, int *length
)
148 static int version
[3] = {PLUGIN_MAJOR_VERSION
,PLUGIN_MINOR_VERSION
,PLUGIN_MICRO_VERSION
};
149 if(length
) *length
= 3;
150 return (int *)version
;
153 static const char *lyricsplugin_plugin_get_name(GmpcPluginBase
*plug
)
155 return _("Lyrics Plugin");
157 static GObject
*lyricsplugin_plugin_constructor(GType type
, guint n_construct_properties
, GObjectConstructParam
* construct_properties
) {
158 LyricsPluginClass
* klass
;
160 GObjectClass
* parent_class
;
161 klass
= (g_type_class_peek (lyricsplugin_plugin_get_type()));
162 parent_class
= G_OBJECT_CLASS (g_type_class_peek_parent (klass
));
163 self
= (LyricsPlugin
*) parent_class
->constructor (type
, n_construct_properties
, construct_properties
);
166 /* Setup textdomain */
167 bindtextdomain(GETTEXT_PACKAGE
, PACKAGE_LOCALE_DIR
);
168 bind_textdomain_codeset(GETTEXT_PACKAGE
, "UTF-8");
170 GMPC_PLUGIN_BASE(self
)->translation_domain
= GETTEXT_PACKAGE
;
171 GMPC_PLUGIN_BASE(self
)->plugin_type
= GMPC_PLUGIN_META_DATA
;
173 return G_OBJECT(self
);
175 static void lyricsplugin_plugin_finalize(GObject
*obj
) {
176 LyricsPlugin
*self
= (LyricsPlugin
*)obj
;
177 LyricsPluginClass
* klass
= (g_type_class_peek (play_queue_plugin_get_type()));
178 gpointer parent_class
= g_type_class_peek_parent (klass
);
181 G_OBJECT_CLASS(parent_class
)->finalize(obj
);
185 static void lyricsplugin_plugin_class_init (LyricsPluginClass
*klass
)
187 G_OBJECT_CLASS(klass
)->finalize
= lyricsplugin_plugin_finalize
;
188 G_OBJECT_CLASS(klass
)->constructor
= lyricsplugin_plugin_constructor
;
189 /* Connect plugin functions */
190 GMPC_PLUGIN_BASE_CLASS(klass
)->get_version
= lyricsplugin_plugin_get_version
;
191 GMPC_PLUGIN_BASE_CLASS(klass
)->get_name
= lyricsplugin_plugin_get_name
;
193 GMPC_PLUGIN_BASE_CLASS(klass
)->get_enabled
= lyricsplugin_get_enabled
;
194 GMPC_PLUGIN_BASE_CLASS(klass
)->set_enabled
= lyricsplugin_set_enabled
;
198 static void lyricsplugin_plugin_meta_data_iface_init(GmpcPluginMetaDataIfaceIface
* iface
) {
199 (iface
)->get_priority
= lyricsplugin_fetch_cover_priority
;
200 (iface
)->set_priority
= lyricsplugin_fetch_cover_priority_set
;
201 (iface
)->get_data
= lyricsplugin_get_uri
;
204 const GType
lyricsplugin_plugin_get_type(void) {
205 static GType lyricsplugin_plugin_type_id
= 0;
206 if(lyricsplugin_plugin_type_id
== 0) {
207 static const GTypeInfo info
= {
208 .class_size
= sizeof(LyricsPluginClass
),
209 .class_init
= (GClassInitFunc
)lyricsplugin_plugin_class_init
,
210 .instance_size
= sizeof(LyricsPlugin
),
214 lyricsplugin_plugin_type_id
= g_type_register_static(GMPC_PLUGIN_TYPE_BASE
, "LyricsPlugin", &info
, 0);
216 /** Browser interface */
217 static const GInterfaceInfo iface_info
= { (GInterfaceInitFunc
) lyricsplugin_plugin_meta_data_iface_init
,
218 (GInterfaceFinalizeFunc
) NULL
, NULL
};
219 g_type_add_interface_static (lyricsplugin_plugin_type_id
, GMPC_PLUGIN_TYPE_META_DATA_IFACE
, &iface_info
);
221 return lyricsplugin_plugin_type_id
;
224 GType
plugin_get_type(void);
226 G_MODULE_EXPORT GType
plugin_get_type(void)
228 return lyricsplugin_plugin_get_type();