hythmbox-2.98/plugins/audioscrobbler/rb-audioscrobbler-entry.c

No issues found

  1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2  *
  3  *  Copyright (C) 2007 Christophe Fergeau <teuf@gnome.org>
  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 #include <time.h>
 35 
 36 #include <glib.h>
 37 #include <glib/gi18n.h>
 38 
 39 #include "rb-debug.h"
 40 #include "rhythmdb.h"
 41 #include <libsoup/soup.h>
 42 
 43 #include "rb-audioscrobbler-entry.h"
 44 #include "rb-audioscrobbler-radio-track-entry-type.h"
 45 
 46 
 47 void
 48 rb_audioscrobbler_entry_init (AudioscrobblerEntry *entry)
 49 {
 50 	entry->artist = g_strdup ("");
 51 	entry->album = g_strdup ("");
 52 	entry->title = g_strdup ("");
 53 	entry->length = 0;
 54 	entry->play_time = 0;
 55 	entry->mbid = g_strdup ("");
 56 	entry->source = g_strdup ("P");
 57 }
 58 
 59 void
 60 rb_audioscrobbler_entry_free (AudioscrobblerEntry *entry)
 61 {
 62 	g_free (entry->artist);
 63 	g_free (entry->album);
 64 	g_free (entry->title);
 65 	g_free (entry->mbid);
 66 	g_free (entry->source);
 67 
 68 	g_free (entry);
 69 }
 70 
 71 void
 72 rb_audioscrobbler_encoded_entry_free (AudioscrobblerEncodedEntry *entry)
 73 {
 74 	g_free (entry->artist);
 75 	g_free (entry->album);
 76 	g_free (entry->title);
 77 	g_free (entry->mbid);
 78 	g_free (entry->timestamp);
 79 	g_free (entry->source);
 80 	g_free (entry->track);
 81 
 82 	g_free (entry);
 83 }
 84 
 85 
 86 AudioscrobblerEntry *
 87 rb_audioscrobbler_entry_create (RhythmDBEntry *rb_entry, RBAudioscrobblerService *service)
 88 {
 89 	AudioscrobblerEntry *as_entry = g_new0 (AudioscrobblerEntry, 1);
 90 
 91 	as_entry->title = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_TITLE);
 92 	as_entry->track = rhythmdb_entry_get_ulong (rb_entry, RHYTHMDB_PROP_TRACK_NUMBER);
 93 	as_entry->artist = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_ARTIST);
 94 	as_entry->album = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_ALBUM);
 95 	if (strcmp (as_entry->album, _("Unknown")) == 0) {
 96 		g_free (as_entry->album);
 97 		as_entry->album = g_strdup ("");
 98 	}
 99 
100 	as_entry->length = rhythmdb_entry_get_ulong (rb_entry, RHYTHMDB_PROP_DURATION);
101 	as_entry->mbid = rhythmdb_entry_dup_string (rb_entry, RHYTHMDB_PROP_MUSICBRAINZ_TRACKID);
102 	if (strcmp (as_entry->mbid, _("Unknown")) == 0) {
103 		g_free (as_entry->mbid);
104 		as_entry->mbid = g_strdup ("");
105 	}
106 
107 	/* identify the source type. Currently we use:
108 	 * L for an audioscrobbler-provided radio track when scrobbling to its own service
109 	 * E for an audioscrobbler-provided radio track when scrobbling to a different service
110 	 * P for everything else
111 	 * TODO: Use R or E in some cases instead of P
112 	 */
113 	if (rhythmdb_entry_get_entry_type (rb_entry) == RHYTHMDB_ENTRY_TYPE_AUDIOSCROBBLER_RADIO_TRACK) {
114 		RBAudioscrobblerRadioTrackData *track_data;
115 		track_data = RHYTHMDB_ENTRY_GET_TYPE_DATA (rb_entry, RBAudioscrobblerRadioTrackData);
116 
117 		/* only use L if we have an auth code,
118 		 * and the track is from the correct service (ie not for a Libre.fm track scrobbling to Last.fm)
119 		 */
120 		if (track_data->track_auth != NULL && track_data->service == service) {
121 			as_entry->source = g_strdup_printf ("L%s", track_data->track_auth);
122 		} else {
123 			as_entry->source = g_strdup ("E");
124 		}
125 	} else {
126 		as_entry->source = g_strdup ("P");
127 	}
128 
129 	return as_entry;
130 }
131 
132 AudioscrobblerEncodedEntry *
133 rb_audioscrobbler_entry_encode (AudioscrobblerEntry *entry)
134 {
135 
136 	AudioscrobblerEncodedEntry *encoded;
137 
138 	encoded = g_new0 (AudioscrobblerEncodedEntry, 1);
139 	
140 	encoded->artist = soup_uri_encode (entry->artist, EXTRA_URI_ENCODE_CHARS);
141 	encoded->title = soup_uri_encode (entry->title, EXTRA_URI_ENCODE_CHARS);
142 	encoded->album = soup_uri_encode (entry->album, EXTRA_URI_ENCODE_CHARS);
143 	encoded->track = g_strdup_printf ("%lu", entry->track);
144 
145 	encoded->mbid = soup_uri_encode (entry->mbid, EXTRA_URI_ENCODE_CHARS);
146 
147 	encoded->timestamp = g_strdup_printf("%ld", (long)entry->play_time);
148 	encoded->length = entry->length;
149 	encoded->source = g_strdup (entry->source);
150 
151 	return encoded;
152 }
153 
154 AudioscrobblerEntry*
155 rb_audioscrobbler_entry_load_from_string (const char *string)
156 {
157 	AudioscrobblerEntry *entry;
158 	int i = 0;
159 	char **breaks;
160 
161 	entry = g_new0 (AudioscrobblerEntry, 1);
162 	rb_audioscrobbler_entry_init (entry);
163 
164 	breaks = g_strsplit (string, "&", 6);
165 
166 	for (i = 0; breaks[i] != NULL; i++) {
167 		char **breaks2 = g_strsplit (breaks[i], "=", 2);
168 
169 		if (breaks2[0] != NULL && breaks2[1] != NULL) {
170 			if (g_str_has_prefix (breaks2[0], "a")) {
171 				g_free (entry->artist);
172 				entry->artist = soup_uri_decode (breaks2[1]);
173 			}
174 			if (g_str_has_prefix (breaks2[0], "t")) {
175 				g_free (entry->title);
176 				entry->title = soup_uri_decode (breaks2[1]);
177 			}
178 			if (g_str_has_prefix (breaks2[0], "b")) {
179 				g_free (entry->album);
180 				entry->album = soup_uri_decode (breaks2[1]);
181 			}
182 			if (g_str_has_prefix (breaks2[0], "m")) {
183 				g_free (entry->mbid);
184 				entry->mbid = soup_uri_decode (breaks2[1]);
185 			}
186 			if (g_str_has_prefix (breaks2[0], "l")) {
187 				entry->length = atoi (breaks2[1]);
188 			}
189 			/* 'I' here is for backwards compatibility with queue files
190 			 * saved while we were using the 1.1 protocol.  see bug 508895.
191 			 */
192 			if (g_str_has_prefix (breaks2[0], "i") ||
193 			    g_str_has_prefix (breaks2[0], "I")) {
194 				entry->play_time = strtol (breaks2[1], NULL, 10);
195 			}
196 		}
197 
198 		g_strfreev (breaks2);
199 	}
200 
201 	g_strfreev (breaks);
202 
203 	if (strcmp (entry->artist, "") == 0 || strcmp (entry->title, "") == 0) {
204 		rb_audioscrobbler_entry_free (entry);
205 		entry = NULL;
206 	}
207 
208 	return entry;
209 }
210 
211 void
212 rb_audioscrobbler_entry_save_to_string (GString *string, AudioscrobblerEntry *entry)
213 {
214 	AudioscrobblerEncodedEntry *encoded;
215 
216 	encoded = rb_audioscrobbler_entry_encode (entry);
217 	g_string_append_printf (string,
218 				"a=%s&t=%s&b=%s&m=%s&l=%d&i=%ld\n",
219 				encoded->artist,
220 				encoded->title,
221 				encoded->album,
222 				encoded->mbid,
223 				encoded->length,
224 				(long)entry->play_time);
225 	rb_audioscrobbler_encoded_entry_free (encoded);
226 }
227 
228 void
229 rb_audioscrobbler_entry_debug (AudioscrobblerEntry *entry, int index)
230 {
231 	rb_debug ("%-3d  artist: %s", index, entry->artist);
232 	rb_debug ("      album: %s", entry->album);
233 	rb_debug ("      title: %s", entry->title);
234 	rb_debug ("     length: %d", entry->length);
235 	rb_debug ("   playtime: %ld", (long)entry->play_time);
236 }