Mercurial > audlegacy-plugins
comparison src/lastfm/lastfm.c @ 1358:d2050220659a
threadified the adjust and first metadata fetch, so now it should open a lot faster
author | Cristi Magherusan <majeru@atheme-project.org> |
---|---|
date | Tue, 24 Jul 2007 03:33:13 +0300 |
parents | 59699988d194 |
children | 62ba1e18d1bb |
comparison
equal
deleted
inserted
replaced
1340:7bb2692b3be9 | 1358:d2050220659a |
---|---|
101 #endif | 101 #endif |
102 return NULL; | 102 return NULL; |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 void lastfm_store(gchar *var_name,gchar* var) /*mowgli storage wrapper, for storing global data*/ | 106 void lastfm_store(gchar * var_name, gchar * var) /*mowgli storage wrapper, for storing global data*/ |
107 { | 107 { |
108 if (mowgli_global_storage_get(var_name)) | 108 if (mowgli_global_storage_get(var_name)) |
109 mowgli_global_storage_free(var_name); | 109 mowgli_global_storage_free(var_name); |
110 | 110 |
111 mowgli_global_storage_put(var_name,var); | 111 mowgli_global_storage_put(var_name,var); |
154 return NULL; | 154 return NULL; |
155 | 155 |
156 return g_strdup(strchr(input_string, '=') + 1); | 156 return g_strdup(strchr(input_string, '=') + 1); |
157 } | 157 } |
158 | 158 |
159 gint lastfm_adjust(LastFM * handle,const gchar * uri) /*tunes into a channel*/ | 159 static gpointer lastfm_adjust(gpointer uri) /*tunes into a channel*/ |
160 { | 160 { |
161 gint status, i,ret = LASTFM_ADJUST_FAILED; | |
162 gchar *fetch_url=NULL, | 161 gchar *fetch_url=NULL, |
163 *session_id, | 162 *session_id = g_strdup(mowgli_global_storage_get("lastfm_session_id")); |
164 **split = NULL; | 163 GString *res=NULL; |
165 GString *res; | |
166 session_id=mowgli_global_storage_get("lastfm_session_id"); | |
167 if (!session_id) | 164 if (!session_id) |
168 { | 165 { |
169 #if DEBUG | 166 #if DEBUG |
170 g_print("LASTFM: (adjust) Adjust failed! Session ID not set.\n"); | 167 g_print("LASTFM: (adjust) Adjust failed! Session ID not set.\n"); |
171 #endif | 168 #endif |
172 return LASTFM_SESSION_MISSING; | 169 return NULL ; |
173 } | 170 } |
174 fetch_url=g_strdup_printf(LASTFM_ADJUST_URL, session_id, uri); | 171 fetch_url=g_strdup_printf(LASTFM_ADJUST_URL, session_id, (char*)uri); |
175 res= g_string_new(NULL); | 172 res= g_string_new(NULL); |
176 status = lastfm_get_data_from_uri(fetch_url, res); | 173 lastfm_get_data_from_uri(fetch_url, res); /*the output doesn't matter*/ |
177 | |
178 if (status == CURLE_OK) | |
179 { | |
180 split = g_strsplit(res->str, "\n", 2); | |
181 for (i = 0; split && split[i]; i++) | |
182 { | |
183 if (g_str_has_prefix(split[i], "response=OK")) | |
184 ret = LASTFM_ADJUST_OK; | |
185 } | |
186 #if DEBUG | |
187 g_print("LASTFM: (adjust) Adjust to '%s' has completed successfully.\n",uri); | |
188 #endif | |
189 } | |
190 g_string_erase(res, 0, -1); | 174 g_string_erase(res, 0, -1); |
191 g_strfreev(split); | 175 g_free(session_id); |
192 return ret; | 176 g_free(fetch_url); |
177 return NULL ; | |
193 } | 178 } |
194 | 179 |
195 gboolean parse_metadata(LastFM * handle,GString * metadata_strings) | 180 gboolean parse_metadata(LastFM * handle,GString * metadata_strings) |
196 { | 181 { |
197 int i; | 182 int i; |
217 if (handle->lastfm_album) | 202 if (handle->lastfm_album) |
218 { | 203 { |
219 g_free(handle->lastfm_album); | 204 g_free(handle->lastfm_album); |
220 handle->lastfm_album=NULL; | 205 handle->lastfm_album=NULL; |
221 } | 206 } |
222 if (handle->lastfm_cover) | |
223 { | |
224 g_free(handle->lastfm_cover); | |
225 handle->lastfm_cover=NULL; | |
226 } | |
227 if (handle->lastfm_station_name) | 207 if (handle->lastfm_station_name) |
228 { | 208 { |
229 g_free(handle->lastfm_station_name); | 209 g_free(handle->lastfm_station_name); |
230 handle->lastfm_station_name=NULL; | 210 handle->lastfm_station_name=NULL; |
231 } | 211 } |
250 | 230 |
251 if (g_str_has_prefix(split[i], "album=")) | 231 if (g_str_has_prefix(split[i], "album=")) |
252 handle->lastfm_album = parse(split[i],"album=" ); | 232 handle->lastfm_album = parse(split[i],"album=" ); |
253 | 233 |
254 if (g_str_has_prefix(split[i], "albumcover_medium=")) | 234 if (g_str_has_prefix(split[i], "albumcover_medium=")) |
255 handle->lastfm_cover = parse(split[i],"albumcover_medium="); | 235 lastfm_store("lastfm_cover", parse(split[i],"albumcover_medium=")); |
256 | 236 |
237 | |
257 if (g_str_has_prefix(split[i], "station=")) | 238 if (g_str_has_prefix(split[i], "station=")) |
258 handle->lastfm_station_name = parse(split[i],"station="); | 239 handle->lastfm_station_name = parse(split[i],"station="); |
259 | 240 |
260 if (g_str_has_prefix(split[i], "trackduration=")) | 241 if (g_str_has_prefix(split[i], "trackduration=")) |
261 handle->lastfm_duration = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); | 242 handle->lastfm_duration = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); |
279 { | 260 { |
280 gchar *uri=NULL; | 261 gchar *uri=NULL; |
281 gint status,res=METADATA_FETCH_FAILED; | 262 gint status,res=METADATA_FETCH_FAILED; |
282 if(!handle) | 263 if(!handle) |
283 return res; | 264 return res; |
284 handle->lastfm_session_id=mowgli_global_storage_get("lastfm_session_id"); | 265 handle->lastfm_session_id=g_strdup(mowgli_global_storage_get("lastfm_session_id")); |
285 if (handle->lastfm_session_id == NULL) | 266 if (handle->lastfm_session_id == NULL) |
286 return res; | 267 return res; |
287 uri=g_strdup_printf(LASTFM_METADATA_URL, handle->lastfm_session_id); | 268 uri=g_strdup_printf(LASTFM_METADATA_URL, handle->lastfm_session_id); |
288 GString *fetched_metadata = g_string_new(NULL); | 269 GString *fetched_metadata = g_string_new(NULL); |
289 status = lastfm_get_data_from_uri(uri, fetched_metadata); | 270 status = lastfm_get_data_from_uri(uri, fetched_metadata); |
311 count=1, | 292 count=1, |
312 status=0, | 293 status=0, |
313 err=0; | 294 err=0; |
314 gboolean track_end_expected=FALSE,track_beginning=TRUE; | 295 gboolean track_end_expected=FALSE,track_beginning=TRUE; |
315 LastFM *handle = (LastFM *)arg; | 296 LastFM *handle = (LastFM *)arg; |
297 /*get it right after opened the stream, so it doesnt need the mutex */ | |
298 fetch_metadata(handle); | |
299 | |
316 /* metadata is fetched 1 second after the stream is opened, | 300 /* metadata is fetched 1 second after the stream is opened, |
317 * and again after 2 seconds. | 301 * and again after 2 seconds. |
318 * if metadata was fetched ok i'm waiting for | 302 * if metadata was fetched ok i'm waiting for |
319 * track_length - fetch_duration - 10 seconds | 303 * track_length - fetch_duration - 10 seconds |
320 * then start polling for new metadata each 2 seconds, until | 304 * then start polling for new metadata each 2 seconds, until |
322 */ | 306 */ |
323 do | 307 do |
324 { | 308 { |
325 if(count%sleep_duration==0) | 309 if(count%sleep_duration==0) |
326 { | 310 { |
327 if(t0->tv_usec==-1) | |
328 g_get_current_time (t0); | |
329 g_mutex_lock(metadata_mutex); | 311 g_mutex_lock(metadata_mutex); |
330 if(handle==NULL) | 312 if(handle==NULL) |
331 break; | 313 break; |
314 if(t0->tv_usec==-1) | |
315 g_get_current_time (t0); | |
332 #if DEBUG | 316 #if DEBUG |
333 g_print("LASTFM: (thread) Fetching metadata:\n"); | 317 g_print("LASTFM: (thread) Fetching metadata:\n"); |
334 #endif | 318 #endif |
335 status=fetch_metadata(handle); | 319 status=fetch_metadata(handle); |
336 g_mutex_unlock(metadata_mutex); | |
337 g_get_current_time (t1); | 320 g_get_current_time (t1); |
338 if(status==METADATA_FETCH_SUCCEEDED) | 321 if(status==METADATA_FETCH_SUCCEEDED) |
339 { | 322 { |
340 if(!track_end_expected) | 323 if(!track_end_expected) |
341 { | 324 { |
399 sleep_duration<<=1; | 382 sleep_duration<<=1; |
400 } | 383 } |
401 #if DEBUG | 384 #if DEBUG |
402 g_print("LASTFM: (thread) Thread_count: %d\n",thread_count); | 385 g_print("LASTFM: (thread) Thread_count: %d\n",thread_count); |
403 g_print("LASTFM: (thread) sleepping for %d seconds. ",err? sleep_duration/2 :sleep_duration); | 386 g_print("LASTFM: (thread) sleepping for %d seconds. ",err? sleep_duration/2 :sleep_duration); |
404 | 387 g_print("Track length = %d sec\n",handle->lastfm_duration); |
405 | 388 #endif |
406 if((handle!= NULL)) | 389 g_mutex_unlock(metadata_mutex); |
407 g_print("Track length = %d sec\n",handle->lastfm_duration); | |
408 #endif | |
409 | |
410 } | 390 } |
411 sleep(1); | 391 sleep(1); |
412 count++; | 392 count++; |
413 | 393 } |
414 } | 394 while ((g_thread_self()==metadata_thread )&& (err<7)); |
415 while ((g_thread_self()==metadata_thread )&& (err<7) && (handle != NULL)); | |
416 | 395 |
417 #if DEBUG | 396 #if DEBUG |
418 g_print("LASTFM: (thread) Exiting thread, ID = %p\n", (void *)g_thread_self()); | 397 g_print("LASTFM: (thread) Exiting thread, ID = %p\n", (void *)g_thread_self()); |
419 #endif | 398 #endif |
420 thread_count--; | 399 thread_count--; |
426 VFSFile *file = g_new0(VFSFile, 1); | 405 VFSFile *file = g_new0(VFSFile, 1); |
427 LastFM *handle = g_new0(LastFM, 1); | 406 LastFM *handle = g_new0(LastFM, 1); |
428 handle->lastfm_artist=NULL; | 407 handle->lastfm_artist=NULL; |
429 handle->lastfm_title=NULL; | 408 handle->lastfm_title=NULL; |
430 handle->lastfm_album=NULL; | 409 handle->lastfm_album=NULL; |
431 handle->lastfm_cover=NULL; | |
432 handle->lastfm_session_id=NULL; | 410 handle->lastfm_session_id=NULL; |
433 handle->lastfm_mp3_stream_url=NULL; | 411 handle->lastfm_mp3_stream_url=NULL; |
434 handle->lastfm_station_name=NULL; | 412 handle->lastfm_station_name=g_strdup(path); |
435 int login_count = 0; | 413 int login_count = 0; |
436 | 414 gchar * temp_path=g_strdup(path); |
437 if(!mowgli_global_storage_get("lastfm_session_id")) /*login only if really needed*/ | 415 if(!mowgli_global_storage_get("lastfm_session_id")) /*login only if really needed*/ |
438 { | 416 { |
439 while((login_count++ <= 3)&&(lastfm_login()!= LASTFM_LOGIN_OK)) | 417 while((login_count++ <= 3)&&(lastfm_login()!= LASTFM_LOGIN_OK)) |
440 sleep(5); | 418 sleep(5); |
441 if(login_count>3) | 419 if(login_count>3) |
443 g_free(handle); | 421 g_free(handle); |
444 g_free(file); | 422 g_free(file); |
445 return NULL; | 423 return NULL; |
446 } | 424 } |
447 } | 425 } |
448 handle->lastfm_mp3_stream_url = mowgli_global_storage_get("lastfm_stream_uri"); | 426 handle->lastfm_session_id = g_strdup(mowgli_global_storage_get("lastfm_session_id")); |
449 handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode); | 427 handle->lastfm_mp3_stream_url = g_strdup(mowgli_global_storage_get("lastfm_stream_uri")); |
450 | |
451 handle->lastfm_session_id = mowgli_global_storage_get("lastfm_session_id"); | |
452 lastfm_adjust(handle,path); | |
453 file->handle = handle; | |
454 g_get_current_time(t0); | 428 g_get_current_time(t0); |
429 g_thread_create(lastfm_adjust,temp_path,FALSE,NULL); | |
455 metadata_thread = g_thread_create(lastfm_metadata_thread_func, handle, FALSE, NULL); | 430 metadata_thread = g_thread_create(lastfm_metadata_thread_func, handle, FALSE, NULL); |
456 thread_count++; | 431 thread_count++; |
457 fetch_metadata(handle); | 432 handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode); |
433 file->handle = handle; | |
458 #if DEBUG | 434 #if DEBUG |
459 g_print("LASTFM: (fopen) Thread_count: %d\n",thread_count); | 435 g_print("LASTFM: (fopen) Thread_count: %d\n",thread_count); |
460 #endif | 436 #endif |
461 return file; | 437 return file; |
462 } | 438 } |
471 g_mutex_lock(metadata_mutex); | 447 g_mutex_lock(metadata_mutex); |
472 LastFM *handle = file->handle; | 448 LastFM *handle = file->handle; |
473 ret = vfs_fclose(handle->proxy_fd); | 449 ret = vfs_fclose(handle->proxy_fd); |
474 if (!ret) | 450 if (!ret) |
475 handle->proxy_fd = NULL; | 451 handle->proxy_fd = NULL; |
476 g_free(handle); | 452 g_free(file->handle); |
477 file->handle = NULL; | 453 file->handle = NULL; |
478 g_mutex_unlock(metadata_mutex); | 454 g_mutex_unlock(metadata_mutex); |
479 } | 455 } |
480 return ret; | 456 return ret; |
481 } | 457 } |
499 } | 475 } |
500 | 476 |
501 gint lastfm_vfs_ungetc_impl(gint c, VFSFile * stream) | 477 gint lastfm_vfs_ungetc_impl(gint c, VFSFile * stream) |
502 { | 478 { |
503 LastFM *handle = stream->handle; | 479 LastFM *handle = stream->handle; |
504 | |
505 return vfs_ungetc(c, handle->proxy_fd); | 480 return vfs_ungetc(c, handle->proxy_fd); |
506 } | 481 } |
507 | 482 |
508 gint lastfm_vfs_fseek_impl(VFSFile * file, glong offset, gint whence) | 483 gint lastfm_vfs_fseek_impl(VFSFile * file, glong offset, gint whence) |
509 { | 484 { |
539 return 0; | 514 return 0; |
540 } | 515 } |
541 | 516 |
542 gchar *lastfm_vfs_metadata_impl(VFSFile * file, const gchar * field) | 517 gchar *lastfm_vfs_metadata_impl(VFSFile * file, const gchar * field) |
543 { | 518 { |
544 LastFM *handle = file->handle; | 519 LastFM * handle; |
520 if(file->handle!= NULL) | |
521 handle = file->handle; | |
522 else | |
523 return NULL; | |
545 | 524 |
546 if (!g_ascii_strncasecmp(field, "stream-name", 11) && (handle->lastfm_station_name != NULL)) | 525 if (!g_ascii_strncasecmp(field, "stream-name", 11) && (handle->lastfm_station_name != NULL)) |
547 return g_strdup_printf("last.fm radio: %s", handle->lastfm_station_name); | 526 return g_strdup_printf("last.fm radio: %s", handle->lastfm_station_name); |
548 if (!g_ascii_strncasecmp(field, "track-name", 10) && (handle->lastfm_title != NULL) && (handle->lastfm_artist != NULL)) | 527 if (!g_ascii_strncasecmp(field, "track-name", 10) && (handle->lastfm_title != NULL) && (handle->lastfm_artist != NULL)) |
549 return g_strdup_printf("%s - %s", handle->lastfm_artist, handle->lastfm_title); | 528 return g_strdup_printf("%s - %s", handle->lastfm_artist, handle->lastfm_title); |
575 vfs_register_transport(&lastfm_const); | 554 vfs_register_transport(&lastfm_const); |
576 if (!metadata_mutex) | 555 if (!metadata_mutex) |
577 metadata_mutex = g_mutex_new (); | 556 metadata_mutex = g_mutex_new (); |
578 t0=g_new0(GTimeVal,1); | 557 t0=g_new0(GTimeVal,1); |
579 t1=g_new0(GTimeVal,1); | 558 t1=g_new0(GTimeVal,1); |
580 | |
581 | |
582 } | 559 } |
583 | 560 |
584 static void cleanup(void) | 561 static void cleanup(void) |
585 { | 562 { |
586 g_mutex_free(metadata_mutex); | 563 g_mutex_free(metadata_mutex); |