ASCAP parser (already did and need help for others)

Greetings.

May be some of u noticed that in several threads i often mention ASCAP (and others PROs) and how it would be nice to easily to “scan” them for data that could be useful in MB.

At last i was able to create a such “parser” script for ASCAP. Made it via javascript on google sheets. Here is the example…

So basically i load MB data through picard then export some fields using mp3tag and paste them in google sheets and script submits search requests in ASCAP in form “trackname - writer”. Ofc there are some nuances like it return only first record in case of several ones etc., but still it gives a good picture in case where u need to know/check composers.

I could share script code in case someone needs it, but moreover i am seeking help with similar script for parsing GEMA, because i discovered that it contains more data than ASCAP esp. in case movie soundtracks and production music. GEMA uses POST http requests, some cookie politics and AJAX form to supply parameters. And regretfully my knowledge is limited here.

5 Likes

Sound great, I will follow this for sure. Thanks ^^

1 Like

That’d be way cool. Definitely would use.

Well, since at least someone interested in this, i will paste script code here. Hope more people will be interested and may be there would programmers as well.

So here is the script code:

// Создаёт кнопку в меню, по нажатию которой и происходит работа скрипта


function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Fetch')
      .addItem('ASCAP','fillData')
      .addToUi();
}


function fetchASCAP(title,surname) {
  
  // Call the ASCAP API
  var response = UrlFetchApp.fetch("https://www.ascap.com/api/wservice/MobileWeb/service/ace/api/v2.0/search/title/"
                                   // сюда надо подставить название трека из named range "TITLE" в листе; +нужна функция замена пробелов на %20
                                   + title //"Dark%20Underworld"
                                   //кол-во выдающихся результатов на страницу (по умолчанию)
                                   + "?limit=100&page=1"
                                   // хз что это
                                   + "&universe=OTTOnly"
                                   // второе условие поиска, выбираемое в комбо-боксе на сайте
                                   // wrtName = writer
                                   + "&searchType2=wrtName"
                                   // значение второго условия поиска; сюда надо подставить имя/фамилию композитора из named range "WRITER" в листе
                                   + "&searchValue2="
                                   + surname);  //"Dinletir");
  
  // Разбор ответа с сайта
  
  // записываем ответ в "чистом" виде
  var json = response.getContentText();
  // записываем "отпарсированный" ответ; если оставить строку с return, тогда вывод лога далее работать не будет
  //var data= JSON.parse(json);
  return JSON.parse(json);
  
  // отображение в логе "чистого" ответа
  //Logger.log(json);
  // отображение в логе "отпарсированного" ответа
  //Logger.log(data);
/*  
  //Вывод в логе конкретных значений. Дата трактуется как объект и мы обращаемся к нему поэлементно. Неконечные элементы представляют собой массив и [0] - обращение к конкретному элементу массива
  
  Logger.log(data["result"][0]["workTitle"]);
  Logger.log(data["result"][0]["ISWCCde"]);
  Logger.log(data["result"][0]["workId"]); //Почему добавляются левые значения???
     
  //Механизм вывода композиторов. Смотрим writerCount и выводим в цикле по очереди.
  
  for (var i = 0; i <= data["result"][0]["writerCount"] - 1; i++) {
  
  //Logger.log(i);
  Logger.log(data["result"][0]["interestedParties"][i]["fullName"]);
  Logger.log(data["result"][0]["interestedParties"][i]["ipiNaNum"]);
    
  }
*/    
}


function fillData() {

  // текущая книга
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  // текущий лист
  var sheet = ss.getActiveSheet();
    
  for (var rowCurrent = 2; ; rowCurrent++) {
  
    // проверяем пустая ли ячейка или нет и если да, то стопаем цикл
    if (sheet.getRange(rowCurrent,8).isBlank()) {
      break;
    }
    // берем название трека из конкретной (первой) ячейки  
    var title = sheet.getRange(rowCurrent,8).getValue();
      
    // берем фамилию композитора из конкретной (первой) ячейки
    var surname = sheet.getRange(rowCurrent,7).getValue();
    
    // запускаем функцию запроса к сайту и передаем в нее параметры выше
    for (var i = 0; i < 3; i++) {
      try {
        var ascap = fetchASCAP(title,surname) //(title,surname) ("Dark%20Underworld","Nielsen");
        break;
      }
      catch(e) {}
    }
      
      //Logger.log(ascap["result"][0]["workTitle"]);
      //Logger.log(ascap["result"][0]["interestedParties"][0]["fullName"]);
      //Logger.log(ascap["result"][0]["interestedParties"][1]["fullName"]);
    
    // clear any previous content
    sheet.getRange(rowCurrent,9).clearContent();
      
    //проверяем, исполнился ли запрос
    if (!ascap) {
      // сервер не ответил - можно об этом сообщить...
      continue;
    }
  
  
    //проверяем "добыл" ли запрос название трека из базы и если да, тогда пишем в ячейки
    if (ascap["result"] && ascap["result"][0]) {
      // название трека
      sheet.getRange(rowCurrent,9).setValue(ascap["result"][0]["workTitle"]);
    
      // композиторы; сначала смотрим сколько из во writerCount
      // новая переменная, которую будем пополнять значениями из цикла
      var composer = '';
      var j = ascap["result"][0]["writerCount"] - 1;
      for (var i = 0; i <= j; i++) {
        if(i == 0) composer += ascap["result"][0]["interestedParties"][i]["fullName"]
        else composer += "\n" + ascap["result"][0]["interestedParties"][i]["fullName"]
        sheet.getRange(rowCurrent,10).setValue(composer);
      }
    
      // iswc
      sheet.getRange(rowCurrent,11).setValue(ascap["result"][0]["ISWCCde"]);
      // db id
      sheet.getRange(rowCurrent,12).setValue(ascap["result"][0]["workId"]);
      // publisher name
      try {
        sheet.getRange(rowCurrent,13).setValue(ascap["result"][0]["interestedParties"][j+1]["fullName"]);
        sheet.getRange(rowCurrent,14).setValue(ascap["result"][0]["interestedParties"][j+2]["fullName"]);
        
        //break;
      }
      catch(e) {}
      
          
      //очищаем наш массив с инфой
      ascap = '';
    }
    else {
      // ничего не найдено
    }
  }  
}

To make it work you need to create google sheet with the column structure as shown on screenshot.
Two fields are necessary: “Surnames” (G) and “Title ASCAP” (H). In my case they are filled by sheet functions, but u can just copy/paste - just paste only writer surname in certain column.

Then go “Tools” -> “Script editor”, create a new script file and paste a code. To actually use it on sheet - from script editor go to “Run” -> “Test as addon” and select ur sheet. Google then will ask about granting some permissions to use it. After sheet loaded u can use the script via “Add-ons” - > “ASCAP”.

6 Likes