Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception: Could not parse text #10

Open
pc-amaral opened this issue Jun 28, 2022 · 4 comments
Open

Exception: Could not parse text #10

pc-amaral opened this issue Jun 28, 2022 · 4 comments

Comments

@pc-amaral
Copy link

Hey @bplmp , how have you been?
I'm struggling in here with this:
image

Can you please help me out?

Thanks in advance.

@pc-amaral pc-amaral changed the title Exception: Could not parse the text Exception: Could not parse text Jun 28, 2022
@manghat
Copy link

manghat commented Jul 11, 2022

Same issue here. There seems to be particular queries that are running into this issue.

@pc-amaral
Copy link
Author

@manghat I was able to solve the issue.
I had to change some things:

  • The code now don't ask if I want to run
  • Now it runs all queries only
  • There is the need of putting the question numbers in the code (line 159)
  • You should put the dates in the code (it's in Brazilian Portuguese, dataInicio and dataFim

I'll paste all of it down here

function onInstall() {
  onOpen();
}

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Metabase')
    .addItem('Import All Questions in Sheets', 'importAllQuestions')
    .addToUi();
}

function importQuestion() {
  var metabaseQuestionNum = Browser.inputBox('Metabase question number (This will replace all data in the current tab with the result)', Browser.Buttons.OK_CANCEL);
  if (metabaseQuestionNum != 'cancel' && !isNaN(metabaseQuestionNum)) {
    var status = getQuestionAsCSV(metabaseQuestionNum, false);

    var log = {
      'user': Session.getActiveUser().getEmail(),
      'function': 'importQuestion',
      'questionNumber': metabaseQuestionNum,
      'status': status
    };
    if (log.status === true) {
      console.log(log);
    } else {
      console.error(log);
    }

    if (status.success === true) {
      SpreadsheetApp.getUi().alert('Question ' + metabaseQuestionNum + ' successfully imported.');
    } else {
      SpreadsheetApp.getUi().alert('Question ' + metabaseQuestionNum + ' failed to import. ' + status.error);
    }
  } else if (metabaseQuestionNum == 'cancel') {
    SpreadsheetApp.getUi().alert('You have canceled.');
  } else {
    SpreadsheetApp.getUi().alert('You did not enter a number.');
  }
}

function importAllQuestions() {

    var questions = getSheetNumbers();
    for (var i = 0; i < questions.length; i++) {
      questions[i].done = false;
    }

    if (questions.length === 0) {
      return;
    }

    var questionNumbers = [];
    for (var i = 0; i < questions.length; i++) {
      questionNumbers.push(questions[i].questionNumber);
    }

      var startDate = new Date().toLocaleTimeString();
      var htmlOutput = HtmlService.createHtmlOutput('<p>Started running at ' + startDate + '...</p>');
      var questionsSuccess = [];
      var questionsError = [];
      for (var i = 0; i < questions.length; i++) {
        var questionNumber = questions[i].questionNumber;
        var sheetName = questions[i].sheetName;
        var status = getQuestionAsCSV(questionNumber, sheetName);
        if (status.success === true) {
          questionsSuccess.push(questionNumber);
        } else if (status.success === false) {
          questionsError.push({
            'number': questionNumber,
            'errorMessage': status.error
          });
        }
      }

      var endDate = new Date().toLocaleTimeString();
      htmlOutput.append('<p>Finished at ' + endDate + '.</p></hr>');
      if (questionsSuccess.length > 0) {
        htmlOutput.append('<p>Successfully imported:</p>');
        for (var i = 0; i < questionsSuccess.length; i++) {
          htmlOutput.append('<li>' + questionsSuccess[i] + '</li>');
        }
      }
      if (questionsError.length > 0) {
        htmlOutput.append('<p>Failed to import:</p>');
        for (var i = 0; i < questionsError.length; i++) {
          htmlOutput.append('<li>' + questionsError[i].number + '</br>(' + questionsError[i].errorMessage + ')</li>');
        }
      }

      var finalStatus;
      if (questionsError.length === 0) {
        finalStatus = true;
      } else {
        finalStatus = false;
      }
      var log = {
        'user': Session.getActiveUser().getEmail(),
        'function': 'importAllQuestions',
        'questionNumber': questionNumbers,
        'status': {
          'success': finalStatus,
          'questionsSuccess': questionsSuccess,
          'questionsError': questionsError
        }
      };
      if (log.status === true) {
        console.log(log);
      } else {
        console.error(log);
      }
}

function getSheetNumbers() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  var questionNumbers = [];
  for (var i in sheets) {
    var sheetName = sheets[i].getName();
    if (sheetName.indexOf('(metabase/') > -1) {
      var questionMatch = sheetName.match('\(metabase\/[0-9]+\)');
      if (questionMatch !== null) {
        var questionNumber = questionMatch[0].match('[0-9]+')[0];
        if (!isNaN(questionNumber) && questionNumber !== '') {
          questionNumbers.push({
            'questionNumber': questionNumber,
            'sheetName': sheetName
          });
        }
      }
    }
  }
  return questionNumbers;
}

function getToken(baseUrl, username, password) {
  var sessionUrl = baseUrl + "api/session";
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json"
    },
    "payload": JSON.stringify({
      username: username,
      password: password
    })
  };
  var response;
  try {
    response = UrlFetchApp.fetch(sessionUrl, options);
  } catch (e) {
    throw (e);
  }
  var token = JSON.parse(response).id;
  return token;
}

function getQuestionAndFillSheet(baseUrl, token, metabaseQuestionNum, sheetName) {
  var questionUrl = baseUrl + "api/card/" + metabaseQuestionNum + "/query/csv";
  if(metabaseQuestionNum === "XXXX" || metabaseQuestionNum === "YYY"){
    var currentDate = new Date();
    currentDate.setDate(currentDate.getDate() -1);
    var strCurrentDate = currentDate.toISOString().split('T')[0];
    var datainicio = "data_inicial";
    var dataFim = "data_final";
    if(metabaseQuestionNum === "1897"){
      datainicio = "datainicial";
      dataFim = "datafinal";
    }
    var data = [
      {
        "type": "date/single",
        "value": "2022-01-01",
        "target": [
          "variable",
          [
            "template-tag",
            datainicio
          ]
        ],
        "id": "7c104fe5-1a8f-7876-dba9-589f73a03758"
      },
      {
        "type": "date/single",
        "value": strCurrentDate,
        "target": [
          "variable",
          [
            "template-tag",
            dataFim
          ]
        ],
        "id": "3d6f5315-3f68-22d6-8605-3f9f4df4db79"
      }
    ];
    questionUrl = questionUrl + `?parameters=${JSON.stringify(data)}`;
  }
  var options = {
    "method": "post",
    "headers": {
      "Content-Type": "application/json",
      "X-Metabase-Session": token
    },
    "muteHttpExceptions": true
  };

  var response;
  try {
    response = UrlFetchApp.fetch(encodeURI(questionUrl), options);
  } catch (e) {
    return {
      'success': false,
      'error': e
    };
  }
  var statusCode = response.getResponseCode();

  if (statusCode == 200 || statusCode == 202) {
    var values = Utilities.parseCsv(response.getContentText());
    try {
      fillSheet(values, sheetName);
      return {
        'success': true
      };
    } catch (e) {
      return {
        'success': false,
        'error': e
      };
    }
  } else if (statusCode == 401) {
    var scriptProp = PropertiesService.getScriptProperties();
    var username = scriptProp.getProperty('USERNAME');
    var password = scriptProp.getProperty('PASSWORD');

    var token = getToken(baseUrl, username, password);
    scriptProp.setProperty('TOKEN', token);
    var e = "Error: Could not retrieve question. Metabase says: '" + response.getContentText() + "'. Please try again in a few minutes.";
    return {
      'success': false,
      'error': e
    };
  } else {
    var e = "Error: Could not retrieve question. Metabase says: '" + response.getContentText() + "'. Please try again later.";
    return {
      'success': false,
      'error': e
    };
  }
}

function fillSheet(values, sheetName) {
  var colLetters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH", "AI", "AJ", "AK", "AL", "AM", "AN", "AO", "AP", "AQ", "AR", "AS", "AT", "AU", "AV", "AW", "AX", "AY", "AZ", "BA", "BB", "BC", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BK", "BL", "BM", "BN", "BO", "BP", "BQ", "BR", "BS", "BT", "BU", "BV", "BW", "BX", "BY", "BZ", "CA", "CB", "CC", "CD", "CE", "CF", "CG", "CH", "CI", "CJ", "CK", "CL", "CM", "CN", "CO", "CP", "CQ", "CR", "CS", "CT", "CU", "CV", "CW", "CX", "CY", "CZ", "DA", "DB", "DC", "DD", "DE", "DF", "DG", "DH", "DI", "DJ", "DK", "DL", "DM", "DN", "DO", "DP", "DQ", "DR", "DS", "DT", "DU", "DV", "DW", "DX", "DY", "DZ", "EA", "EB", "EC", "ED", "EE", "EF", "EG", "EH", "EI", "EJ", "EK", "EL", "EM", "EN", "EO", "EP", "EQ", "ER", "ES", "ET", "EU", "EV", "EW", "EX", "EY", "EZ", "FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FI", "FJ", "FK", "FL", "FM", "FN", "FO", "FP", "FQ", "FR", "FS", "FT", "FU", "FV", "FW", "FX", "FY", "FZ", "GA", "GB", "GC", "GD", "GE", "GF", "GG", "GH", "GI", "GJ", "GK", "GL", "GM", "GN", "GO", "GP", "GQ", "GR", "GS", "GT", "GU", "GV", "GW", "GX", "GY", "GZ", "HA", "HB", "HC", "HD", "HE", "HF", "HG", "HH", "HI", "HJ", "HK", "HL", "HM", "HN", "HO", "HP", "HQ", "HR", "HS", "HT", "HU", "HV", "HW", "HX", "HY", "HZ", "IA", "IB", "IC", "ID", "IE", "IF", "IG", "IH", "II", "IJ", "IK", "IL", "IM", "IN", "IO", "IP", "IQ", "IR", "IS", "IT", "IU", "IV", "IW", "IX", "IY", "IZ", "JA", "JB", "JC", "JD", "JE", "JF", "JG", "JH", "JI", "JJ", "JK", "JL", "JM", "JN", "JO", "JP", "JQ", "JR", "JS", "JT", "JU", "JV", "JW", "JX", "JY", "JZ"];

  var sheet;
  if (sheetName == false) {
    sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  } else {
    sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  }

  sheet.clear({
    contentsOnly: true
  });

  var rows = values;
  var header = rows[0];
  var minCol = colLetters[0];
  var maxCol = colLetters[header.length - 1];
  var minRow = 1;
  var maxRow = rows.length;
  var range = sheet.getRange(minCol + minRow + ":" + maxCol + maxRow);
  range.setValues(rows);
}

function getQuestionAsCSV(metabaseQuestionNum, sheetName) {
  var scriptProp = PropertiesService.getScriptProperties();
  var baseUrl = scriptProp.getProperty('BASE_URL');
  var username = scriptProp.getProperty('USERNAME');
  var password = scriptProp.getProperty('PASSWORD');
  var token = scriptProp.getProperty('TOKEN');

  if (!token) {
    token = getToken(baseUrl, username, password);
    scriptProp.setProperty('TOKEN', token);
  }

  status = getQuestionAndFillSheet(baseUrl, token, metabaseQuestionNum, sheetName);
  return status;
}

@johannkaupen
Copy link

@pc-amaral could you share why it is necessary to add dates and which dates to add?
Thank you!

@pc-amaral
Copy link
Author

Hey @johannkaupen
Most of the questions that failed for me were questions that needed a date range. The original script doesn't have a place to define it.
The questions that worked didn't need it. I believe that the dates were the main issue to show the parse error.

If I'm not wrong, dataInicio is 2022-01-01 and dataFim is D-1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants