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);