SP_LIBEXPORT(sp_error) sp_session_logout (sp_session *session) { DSFYDEBUG("Posting REQ_TYPE_LOGOUT\n"); request_post(session, REQ_TYPE_LOGOUT, NULL); return SP_ERROR_OK; }
static int login(struct lastfm_command *cmd) { request_post("auth.getMobileSession", cmd->arg.kv, 1); keyval_clear(cmd->arg.kv); return 0; }
/* 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; }
SP_LIBEXPORT(sp_error) sp_session_login (sp_session *session, const char *username, const char *password) { strncpy(session->username, username, sizeof(session->username) - 1); session->username[sizeof(session->username) - 1] = 0; strncpy(session->password, password, sizeof(session->password) - 1); session->password[sizeof(session->password) - 1] = 0; session->user = user_add(session, username); user_add_ref(session->user); DSFYDEBUG("Posting REQ_TYPE_LOGIN\n"); request_post(session, REQ_TYPE_LOGIN, NULL); return SP_ERROR_OK; }
int answer_to_connection (void *cls, struct MHD_Connection *connection,const char *url, const char *method,const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { struct MHD_Response *response; puts(page); if (strcmp(method,"GET") == 0) { printf("%s New %s request for %s using version %s",__func__, method, url, version); request_get(cls, connection, url, method, version, upload_data, upload_data_size, con_cls); return 1; } else if (strcmp(method,"PUT") == 0) { printf("%s New %s request for %s using version %s",__func__, method, url, version); request_put( cls, connection, url, method, version, upload_data, upload_data_size,con_cls); return 1; } else if (strcmp(method,"DELETE") == 0) { printf("%s New %s request for %s using version %s",__func__, method, url, version); request_delete( cls, connection, url, method, version, upload_data, upload_data_size,con_cls); } else if (strcmp(method,"HEAD") == 0) { printf("%s New %s request for %s using version %s",__func__, method, url, version); request_head( cls, connection, url, method, version, upload_data, upload_data_size,con_cls); return 1; } else if (strcmp(method,"POST") == 0) { printf("%s New %s request for %s using version %s",__func__, method, url, version); request_post(cls, connection, url, method, version, upload_data, upload_data_size, con_cls); return 1; } else printf("%s ERROR %s request for %s using version %s",__func__, method, url, version); return 0; }
SP_LIBEXPORT(sp_image *) sp_image_create(sp_session *session, const byte image_id[20]) { sp_image *image; void **container; struct image_ctx *image_ctx; image = osfy_image_create(session, image_id); sp_image_add_ref(image); if(sp_image_is_loaded(image)) return image; /* Prevent the image from being loaded twice */ if(image->error == SP_ERROR_IS_LOADING) return image; image->error = SP_ERROR_IS_LOADING; image_ctx = malloc(sizeof(struct image_ctx)); image_ctx->session = session; image_ctx->req = NULL; image_ctx->image = image; container = (void **)malloc(sizeof(void *)); *container = image_ctx; { char buf[41]; hex_bytes_to_ascii(image->id, buf, 20); DSFYDEBUG("Requesting download of image '%s'\n", buf); } request_post(session, REQ_TYPE_IMAGE, container); return image; }
/* int print_out_key (void *cls, enum MHD_ValueKind kind, const char *key, const char *value) { SimpleLog_Write(SL_DEBUG, __func__, "%s: %s", key, value); return MHD_YES; } */ int answer_to_connection (void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { /*the info of this thread, so we need there to be defined in function, not be defined as global variables. */ // json_object * Response_page = json_object_new_object(); //json_object * Response_heads = json_object_new_object(); //const char *page = "hello, cloud store!"; struct MHD_Response *response; //puts(page); //int ret; char pathname[128]; char pathname_mnt[128]; get_sonstr(url,pathname); memset(pathname_mnt,0,sizeof(pathname_mnt)); strcat(strcat(pathname_mnt,"/mnt/supercache/"),pathname); //printf("pathname %s pathname_mnt %s \n",pathname,pathname_mnt); if (strcmp(method,"GET") == 0) { printf("haha\n"); //SimpleLog_Write(SL_DEBUG, __func__, "New %s request for %s using version %s", method, url, version); printf("%s New %s request for %s using version %s",__func__, method, url, version); /******************add by Jin*********************************/ /*time_t arrive_time; time(&arrive_time); IO_Type io_type=READ; queue_in_wait(pathname_mnt,io_type,arrive_time); int already_queue_out=0;//the mark of read out early Meta_Data * meta_data=(Meta_Data*)malloc(sizeof(Meta_Data)); if(md_get(pathname_mnt,meta_data)==0) { u32 head_next=((*meta_data).ioq.head+1)%IO_Q_LEN; //if one read comes after one read ,queue out early if((*meta_data).ioq.io_q_node[head_next].io_type==READ) { read_queue_out(pathname_mnt,io_type,arrive_time); already_queue_out=1; } }*/ /*******************************************************/ request_get(cls, connection, url, method, version, upload_data, upload_data_size, con_cls); /* if(already_queue_out==0) { read_queue_out(pathname_mnt,io_type,arrive_time); }*/ return 1; } else if (strcmp(method,"PUT") == 0) { //SimpleLog_Write(SL_DEBUG, __func__, "New %s request for %s using version %s", method, url, version); printf("%s New %s request for %s using version %s",__func__, method, url, version); /******************************************************/ /*time_t arrive_time; time(&arrive_time); IO_Type io_type=WRITE; queue_in_wait(pathname_mnt,io_type,arrive_time);*/ /********************************************************/ request_put( cls, connection, url, method, version, upload_data, upload_data_size,con_cls); /*********************************************************/ /*u64 offset=0;char *data="never mind!";size_t size1=11; write_queue_out(pathname_mnt,io_type,arrive_time,offset,data,size1);//should change it*/ /*********************************************************/ return 1; } else if (strcmp(method,"DELETE") == 0) { //SimpleLog_Write(SL_DEBUG, __func__, "New %s request for %s using version %s", method, url, version); printf("%s New %s request for %s using version %s",__func__, method, url, version); /************************************************/ /* time_t arrive_time; time(&arrive_time); IO_Type io_type=REMOVE; queue_in_wait(pathname_mnt,io_type,arrive_time);*/ /************************************************/ request_delete( cls, connection, url, method, version, upload_data, upload_data_size,con_cls); //remove_queue_out(pathname_mnt,io_type); } else if (strcmp(method,"HEAD") == 0) { //SimpleLog_Write(SL_DEBUG, __func__, "New %s request for %s using version %s", method, url, version); printf("%s New %s request for %s using version %s",__func__, method, url, version); request_head( cls, connection, url, method, version, upload_data, upload_data_size,con_cls); return 1; } else if (strcmp(method,"POST") == 0) { //printf("()()()()\n"); //SimpleLog_Write(SL_DEBUG, __func__, "New %s request for %s using version %s", method, url, version); //printf("%s New %s request for %s using version %s\n",__func__, method, url, version); //printf("up_load_size:%u %s\n",upload_data_size,upload_data); /******************************************************/ /*time_t arrive_time; time(&arrive_time); IO_Type io_type=WRITE; queue_in_wait(pathname_mnt,io_type,arrive_time);*/ /********************************************************/ request_post(cls, connection, url, method, version, upload_data, upload_data_size, con_cls); /*********************************************************/ /*u64 offset=0;char *data="never mind!";size_t size1=11; write_queue_out(pathname_mnt,io_type,arrive_time,offset,data,size1);//should change it*/ /*********************************************************/ return 1; } else printf("%s ERROR %s request for %s using version %s",__func__, method, url, version); return 0; }
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; }
SP_LIBEXPORT(sp_artistbrowse *) sp_artistbrowse_create(sp_session *session, sp_artist *artist, artistbrowse_complete_cb *callback, void *userdata) { sp_artistbrowse *arb; void **container; struct browse_callback_ctx *brctx; arb = malloc(sizeof(sp_artistbrowse)); DSFYDEBUG("Allocated artistbrowse at %p\n", arb); if(arb == NULL) return NULL; arb->artist = artist; sp_artist_add_ref(artist); DSFYDEBUG("Referenced artist at %p\n", arb->artist); arb->num_tracks = 0; arb->tracks = NULL; arb->num_portraits = 0; arb->portraits = 0; arb->num_similar_artists = 0; arb->similar_artists = NULL; arb->num_albums = 0; arb->albums = NULL; arb->biography = NULL; arb->callback = callback; arb->userdata = userdata; arb->error = SP_ERROR_IS_LOADING; arb->is_loaded = 0; arb->ref_count = 1; /* * Temporarily increase ref count for the albumbrowse so it's not free'd * accidentily. It will be decreaed by the chanel callback. * */ sp_artistbrowse_add_ref(arb); /* The album callback context */ brctx = (struct browse_callback_ctx *)malloc(sizeof(struct browse_callback_ctx)); brctx->session = session; brctx->req = NULL; /* Filled in by the request processor */ brctx->buf = NULL; /* Filled in by the request processor */ brctx->type = REQ_TYPE_ARTISTBROWSE; brctx->data.artistbrowses = (sp_artistbrowse **)malloc(sizeof(sp_artistbrowse *)); brctx->data.artistbrowses[0] = arb; brctx->num_total = 1; brctx->num_browsed = 0; brctx->num_in_request = 0; /* Our gzip'd XML parser */ brctx->browse_parser = osfy_artistbrowse_browse_callback; /* Request input container. Will be free'd when the request is finished. */ container = (void **)malloc(sizeof(void *)); *container = brctx; request_post(session, REQ_TYPE_ARTISTBROWSE, container); return arb; }
SP_LIBEXPORT(sp_search *) sp_search_create(sp_session *session, const char *query, int track_offset, int track_count, int album_offset, int album_count, int artist_offset, int artist_count, search_complete_cb *callback, void *userdata) { sp_search *search; void **container; struct search_ctx *search_ctx; search = malloc(sizeof(sp_search)); if(search == NULL) return NULL; search->query = strdup(query); search->did_you_mean = NULL; search->track_offset = track_offset; search->track_count = track_count; /* Currently not used due to lack of support in cmd_search() */ search->album_offset = album_offset; search->album_count = album_count; search->artist_offset = artist_offset; search->artist_count = artist_count; search->callback = callback; search->userdata = userdata; search->num_albums = 0; search->albums = NULL; search->num_artists = 0; search->artists = NULL; search->num_tracks = 0; search->tracks = NULL; search->error = SP_ERROR_IS_LOADING; search->is_loaded = 0; search->ref_count = 1; /* * Temporarily increase ref count for the albumbrowse so it's not free'd * accidentily. It will be decreaed by the chanel callback. * */ sp_search_add_ref(search); /* The album callback context */ search_ctx = (struct search_ctx *)malloc(sizeof(struct search_ctx)); search_ctx->session = session; search_ctx->req = NULL; /* Filled in by the request processor */ search_ctx->buf = buf_new(); search_ctx->search = search; /* Request input container. Will be free'd when the request is finished. */ container = (void **)malloc(sizeof(void *)); *container = search_ctx; request_post(session, REQ_TYPE_SEARCH, container); return search; }
SP_LIBEXPORT(sp_error) sp_session_init (const sp_session_config *config, sp_session **psession) { sp_session *session; if(!config) // XXX - verify return SP_ERROR_INVALID_INDATA; /* Check if API version matches. */ if(config->api_version < SPOTIFY_API_VERSION || config->api_version > SPOTIFY_API_VERSION) return SP_ERROR_BAD_API_VERSION; /* Maximum user-agent length is 4096 bytes (including null-terminator). */ if(config->user_agent == NULL || strlen(config->user_agent) > 4095) return SP_ERROR_BAD_USER_AGENT; /* Application key needs to have 321 bytes with the first byte being 0x01. */ if(config->application_key == NULL || config->application_key_size != 321 || ((char *)config->application_key)[0] != 0x01) return SP_ERROR_BAD_APPLICATION_KEY; /* Allocate memory for our session. */ if((session = (sp_session *)malloc(sizeof(sp_session))) == NULL) return SP_ERROR_API_INITIALIZATION_FAILED; memset(session, 0, sizeof(sp_session)); /* Allocate memory for callbacks and copy them to our session. */ session->userdata = config->userdata; session->callbacks = (sp_session_callbacks *)malloc(sizeof(sp_session_callbacks)); memcpy(session->callbacks, config->callbacks, sizeof(sp_session_callbacks)); /* Connection state is undefined (We were never logged in).*/ session->connectionstate = SP_CONNECTION_STATE_UNDEFINED; session->user = NULL; memset(session->country, 0, sizeof(session->country)); /* Login context, needed by network.c and login.c */ session->login = NULL; memset(session->username, 0, sizeof(session->username)); memset(session->password, 0, sizeof(session->password)); /* Playlist container object */ playlistcontainer_create(session); /* Albums/artists/tracks memory management */ session->hashtable_albums = hashtable_create(16); session->hashtable_artists = hashtable_create(16); session->hashtable_images = hashtable_create(20); session->hashtable_tracks = hashtable_create(16); session->hashtable_users = hashtable_create(256); /* Allocate memory for user info. */ if((session->user = (sp_user *)malloc(sizeof(sp_user))) == NULL) return SP_ERROR_API_INITIALIZATION_FAILED; /* Low-level networking stuff. */ session->sock = -1; /* Incoming packet buffer */ session->packet = NULL; /* To allow main thread to communicate with network thread */ session->requests = NULL; /* Channels */ session->channels = NULL; session->next_channel_id = 0; session->num_channels = 0; /* Spawn networking thread. */ #ifdef _WIN32 session->request_mutex = CreateMutex(NULL, FALSE, NULL); session->idle_wakeup = CreateEvent(NULL, FALSE, FALSE, NULL); session->thread_main = GetCurrentThread(); session->thread_io = CreateThread(NULL, 0, iothread, session, 0, NULL); #else pthread_mutex_init(&session->request_mutex, NULL); pthread_cond_init(&session->idle_wakeup, NULL); session->thread_main = pthread_self(); if(pthread_create(&session->thread_io, NULL, iothread, session)) return SP_ERROR_OTHER_TRANSIENT; #endif /* Player thread */ if(player_init(session)) return SP_ERROR_OTHER_TRANSIENT; /* Helper function for sp_link_create_from_string() */ libopenspotify_link_init(session); /* Load album, artist and track cache */ cache_init(session); /* Run garbage collector and save metadata to disk periodically */ request_post(session, REQ_TYPE_CACHE_PERIODIC, NULL); DSFYDEBUG("Session initialized at %p\n", session); *psession = session; return SP_ERROR_OK; }