Не удается загрузить треки (пакетно) в API Last.fm. Недопустимая подпись метода

Я пробовал это некоторое время, но я не могу понять, что не так. Может быть, я перепробовал так много способов, что уже даже не уверен, что этот фрагмент кода правильный.

В основном я пытаюсь использовать метод track.scrobble из API Last.fm, отправляя пакет треков.

Это код, который у меня есть, и он всегда возвращает Invalid method signature. Кто-нибудь может помочь мне здесь, пожалуйста?

ОБНОВЛЕНИЕ

Основываясь на ответе mccannf, я изменил код, но все еще получаю сообщение об ошибке:

var apiUrl = "http://ws.audioscrobbler.com/2.0/";
var apiMethod = "track.scrobble";
var apiKey = "MY_API_KEY";
var apiSecret = "MY_API_SECRET";
var key = "MY_SESSION_KEY";
var apiSig = "";

var lastfmScrobble = function (data) {
    var dataToScrobble = setTiming(data);

    var albums = [];
    var artists = [];;
    var timestamps = [];
    var tracks = [];
    var dataToHash = "";

    for (var i = 0; i < dataToScrobble.tracks.length; i++) {
        albums["album["+ i.toString() + "]"] = dataToScrobble.album;        
        artists["artist[" + i.toString() + "]"] = dataToScrobble.artist;
        timestamps["timestamp[" + i.toString() + "]"] = dataToScrobble.tracks[i].split("|")[1];
        tracks["track[" + i.toString() + "]"] = dataToScrobble.tracks[i].split("|")[0];     
    }

    dataToHash += albums.sort().join("");
    dataToHash += "api_key" + apiKey;   
    dataToHash += artists.sort().join("");  
    dataToHash += "method" + apiMethod;
    dataToHash += "sk" + key;   
    dataToHash += timestamps.sort().join("");       
    dataToHash += tracks.sort().join("");
    dataToHash += apiSecret;

    apiSig = $.md5(unescape(encodeURIComponent(dataToHash)));

    var songsToScrobble = {};

    $.extend(songsToScrobble, 
        albums.sort(), 
        { api_key: apiKey }, 
        { api_sig: apiSig }, 
        artists.sort(), 
        { method: apiMethod }, 
        { sk: key }, 
        timestamps.sort(), 
        tracks.sort());

    $.ajax({
        url: apiUrl,
        type: "POST",
        data: songsToScrobble,
        success: function (data) { 
            console.log(data);
        }
    });
}

Теперь отправленный объект имеет правильный формат (JSON). Что еще может быть не так?


person melancia    schedule 16.09.2013    source источник


Ответы (1)


Я сделал быстрый пример JS Fiddle вашего кода.

dataToHash выглядит так:

 album[0]Achtung Babyalbum[1]Achtung Babyapi_keyxxxBLAHxxxartist[0]U2artist[1]U2methodtrack.scrobbleskkkkFOOkkktimestamp[0]1379368800timestamp[1]1379369000track[0]Onetrack[1]The FlymmmySecrettt 

Переменная songsToScrobble в приведенном выше коде выглядела так:

 { "album": [ 
              "album[0]Achtung Baby",
              "album[1]Achtung Baby"
            ], 
   "api_key":"xxxBLAHxxx",
   "api_sig":"8dbc147e533411a41ba9169f59e65b3a",
   "artist":["artist[0]U2","artist[1]U2"],          
   "method": "track.scrobble", 
   "sk":"kkkFOOkkk" 
   "timestamp": [
                  "timestamp[0]1379368800",
                  "timestamp[1]1379369000"
                ],
   "track": [ 
              "track[0]One",
              "track[1]The Fly"
            ]
  } 

Я полагаю, что songsToScrobble должно выглядеть так:

 { "album[0]": "Achtung Baby",
   "album[1]": "Achtung Baby",
   "api_key":"xxxBLAHxxx",
   "api_sig":"8dbc147e533411a41ba9169f59e65b3a",
   "artist[0]": "U2",
   "artist[1]": "U2",          
   "method": "track.scrobble", 
   "sk":"kkkFOOkkk" 
   "timestamp[0]": "1379368800",
   "timestamp[1]": "1379369000",
   "track[0]": "One",
   "track[1]": "The Fly"
  } 

Единственный другой второстепенный момент - убедиться, что dataToHash закодирован в UTF-8, прежде чем конвертировать в хэш MD5.

Изменить

Вот как я создал данные для вызова ajax. ПРИМЕЧАНИЕ: это не проверено — у меня нет учетной записи last.fm.

var songsToScrobble = {};

function addDataToScrobble(parentElement, inputData) {
    if ($.isArray(inputData)) {
      $.each(inputData, function(index ,element) {
         songsToScrobble[parentElement + "[" + index + "]"] = element;
         dataToHash += parentElement + "[" + index + "]" + element;
      });
    } else {
      songsToScrobble[parentElement] = inputData;
      dataToHash += parentElement + inputData;
    }
}

for (var i = 0; i < data.tracks.length; i++) {
     albums.push(data.album);
     artists.push(data.artist);
     // The tracks are coming in the format: title|timestamp
     timestamps.push(data.tracks[i].split("|")[1]);
     tracks.push(data.tracks[i].split("|")[0]);     
}

addDataToScrobble("album", albums);
addDataToScrobble("api_key", apiKey);
addDataToScrobble("artist", artists);
addDataToScrobble("method", apiMethod);
addDataToScrobble("sk", key);
addDataToScrobble("timestamp", timestamps);
addDataToScrobble("track", tracks);

apiSig = $.md5(unescape(encodeURIComponent(dataToHash+apiSecret)));

songsToScrobble["api_sig"] = apiSig;

$.ajax({
    url: apiUrl,
    type: "POST",
    data: songsToScrobble,
    success: function (data) { 
        console.log(data);
    }
});
person mccannf    schedule 16.09.2013
comment
Вы правы насчет формата. Я так сильно изменил этот код с тех пор, как начал со скрипта, что уже не могу его исправить. Как я могу перевести свой объект, чтобы он возвращал только пары, как вы упомянули? Спасибо! - person melancia; 17.09.2013