/* Thread: filescanner */ int lastfm_login(char *path) { struct keyval *kv; char *username; char *password; int ret; DPRINTF(E_DBG, L_LASTFM, "Got LastFM login request\n"); // Delete any existing session key if (lastfm_session_key) free(lastfm_session_key); lastfm_session_key = NULL; db_admin_delete("lastfm_sk"); // Read the credentials file ret = credentials_read(path, &username, &password); if (ret < 0) return -1; // Enable LastFM now that we got a login attempt lastfm_disabled = 0; kv = keyval_alloc(); if (!kv) { free(username); free(password); return -1; } ret = ( (keyval_add(kv, "api_key", lastfm_api_key) == 0) && (keyval_add(kv, "username", username) == 0) && (keyval_add(kv, "password", password) == 0) ); free(username); free(password); // Send the login request ret = request_post("auth.getMobileSession", kv, 1); keyval_clear(kv); free(kv); return ret; }
/* Thread: filescanner */ void lastfm_login(char *path) { struct lastfm_command *cmd; struct keyval *kv; char *username; char *password; int ret; DPRINTF(E_DBG, L_LASTFM, "Got LastFM login request\n"); // Delete any existing session key if (g_session_key) free(g_session_key); g_session_key = NULL; db_admin_delete("lastfm_sk"); // Read the credentials file ret = credentials_read(path, &username, &password); if (ret < 0) return; // Enable LastFM now that we got a login attempt g_disabled = 0; kv = keyval_alloc(); if (!kv) { free(username); free(password); return; } ret = ( (keyval_add(kv, "api_key", g_api_key) == 0) && (keyval_add(kv, "username", username) == 0) && (keyval_add(kv, "password", password) == 0) ); free(username); free(password); if (!ret) { keyval_clear(kv); return; } // Spawn thread ret = lastfm_init(); if (ret < 0) { g_disabled = 1; return; } g_initialized = 1; // Send login command to the thread cmd = (struct lastfm_command *)malloc(sizeof(struct lastfm_command)); if (!cmd) { DPRINTF(E_LOG, L_LASTFM, "Could not allocate lastfm_command\n"); return; } memset(cmd, 0, sizeof(struct lastfm_command)); cmd->nonblock = 1; cmd->func = login; cmd->arg.kv = kv; nonblock_command(cmd); return; }
static int scrobble(int id) { struct media_file_info *mfi; struct keyval *kv; char duration[4]; char trackNumber[4]; char timestamp[16]; int ret; mfi = db_file_fetch_byid(id); if (!mfi) { DPRINTF(E_LOG, L_LASTFM, "Scrobble failed, track id %d is unknown\n", id); return -1; } // Don't scrobble songs which are shorter than 30 sec if (mfi->song_length < 30000) goto noscrobble; // Don't scrobble non-music and radio stations if ((mfi->media_kind != MEDIA_KIND_MUSIC) || (mfi->data_kind == DATA_KIND_URL)) goto noscrobble; // Don't scrobble songs with unknown artist if (strcmp(mfi->artist, "Unknown artist") == 0) goto noscrobble; kv = keyval_alloc(); if (!kv) goto noscrobble; snprintf(duration, sizeof(duration), "%" PRIu32, mfi->song_length); snprintf(trackNumber, sizeof(trackNumber), "%" PRIu32, mfi->track); snprintf(timestamp, sizeof(timestamp), "%" PRIi64, (int64_t)time(NULL)); ret = ( (keyval_add(kv, "api_key", lastfm_api_key) == 0) && (keyval_add(kv, "sk", lastfm_session_key) == 0) && (keyval_add(kv, "artist", mfi->artist) == 0) && (keyval_add(kv, "track", mfi->title) == 0) && (keyval_add(kv, "album", mfi->album) == 0) && (keyval_add(kv, "albumArtist", mfi->album_artist) == 0) && (keyval_add(kv, "duration", duration) == 0) && (keyval_add(kv, "trackNumber", trackNumber) == 0) && (keyval_add(kv, "timestamp", timestamp) == 0) ); free_mfi(mfi, 0); if (!ret) { keyval_clear(kv); free(kv); return -1; } DPRINTF(E_INFO, L_LASTFM, "Scrobbling '%s' by '%s'\n", keyval_get(kv, "track"), keyval_get(kv, "artist")); ret = request_post("track.scrobble", kv, 0); keyval_clear(kv); free(kv); return ret; noscrobble: free_mfi(mfi, 0); return -1; }
/* Earlier versions of ffmpeg/libav do not seem to allow access to the http * headers, so we must instead open the stream ourselves to get the metadata. * Sorry about the extra connections, you radio streaming people! * * It is not possible to get the packet metadata with these versions of ffmpeg */ struct http_icy_metadata * http_icy_metadata_get(AVFormatContext *fmtctx, int packet_only) { struct http_icy_metadata *metadata; struct http_client_ctx ctx; struct keyval *kv; const char *value; int got_header; int ret; /* Can only get header metadata */ if (packet_only) return NULL; kv = keyval_alloc(); if (!kv) return NULL; memset(&ctx, 0, sizeof(struct http_client_ctx)); ctx.url = fmtctx->filename; ctx.headers = kv; ctx.headers_only = 1; ctx.body = NULL; ret = http_client_request(&ctx); if (ret < 0) { DPRINTF(E_LOG, L_HTTP, "Error fetching %s\n", fmtctx->filename); free(kv); return NULL; } metadata = malloc(sizeof(struct http_icy_metadata)); if (!metadata) return NULL; memset(metadata, 0, sizeof(struct http_icy_metadata)); got_header = 0; if ( (value = keyval_get(ctx.headers, "icy-name")) ) { metadata->name = strdup(value); got_header = 1; } if ( (value = keyval_get(ctx.headers, "icy-description")) ) { metadata->description = strdup(value); got_header = 1; } if ( (value = keyval_get(ctx.headers, "icy-genre")) ) { metadata->genre = strdup(value); got_header = 1; } keyval_clear(kv); free(kv); if (!got_header) { free(metadata); return NULL; } /* DPRINTF(E_DBG, L_HTTP, "Found ICY: N %s, D %s, G %s, T %s, A %s, U %s, I %" PRIu32 "\n", metadata->name, metadata->description, metadata->genre, metadata->title, metadata->artist, metadata->artwork_url, metadata->hash );*/ return metadata; }