I'd like to create a report of storage usage for all my users. To do so I use AdminReports app, like so (found in google example, somewhere. Just had to adapt the "parameters" and the "row" arrays) :
function generateUserUsageReport() {
var today = new Date();
var oneWeekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
var timezone = Session.getScriptTimeZone();
var date = Utilities.formatDate(oneWeekAgo, timezone, 'yyyy-MM-dd');
var parameters = [
'accounts:gmail_used_quota_in_mb',
'accounts:drive_used_quota_in_mb',
'accounts:total_quota_in_mb ',
'accounts:used_quota_in_percentage'
];
var rows = [];
var pageToken;
var page;
do {
page = AdminReports.UserUsageReport.get('all', date, {
parameters: parameters.join(','),
maxResults: 500,
pageToken: pageToken
});
if (page.warnings) {
for (var i = 0; i < page.warnings.length; i++) {
var warning = page.warnings[i];
Logger.log(warning.message);
}
}
var reports = page.usageReports;
if (reports) {
for (var i = 0; i < reports.length; i++) {
var report = reports[i];
var parameterValues = getParameterValues(report.parameters);
var row = [
report.date,
report.entity.userEmail,
parseInt(parameterValues['accounts:drive_used_quota_in_mb']),
parseInt(parameterValues['accounts:gmail_used_quota_in_mb']),
parseInt(parameterValues['accounts:total_quota_in_mb']),
((parseInt(parameterValues['accounts:gmail_used_quota_in_mb'])+parseInt(parameterValues['accounts:drive_used_quota_in_mb']))/parseInt(parameterValues['accounts:total_quota_in_mb']))*100
];
rows.push(row);
}
}
pageToken = page.nextPageToken;
} while (pageToken);
if (rows.length > 0) {
var spreadsheet = SpreadsheetApp.getActive();
var sheet = spreadsheet.getActiveSheet();
// Append the headers.
var headers = [['Date', 'User mail', 'Drive use','Gmail use', 'Total available',
'Total(%)']];
sheet.getRange(1, 1, 1, 6).setValues(headers);
// Append the results.
sheet.getRange(2, 1, rows.length, 6).setValues(rows);
Logger.log('Report spreadsheet created: %s', spreadsheet.getUrl());
} else {
Logger.log('No results returned.');
}
}
/**
* Gets a map of parameter names to values from an array of parameter objects.
* #param {Array} parameters An array of parameter objects.
* #return {Object} A map from parameter names to their values.
*/
function getParameterValues(parameters) {
return parameters.reduce(function(result, parameter) {
var name = parameter.name;
var value;
if (parameter.intValue !== undefined) {
value = parameter.intValue;
} else if (parameter.stringValue !== undefined) {
value = parameter.stringValue;
} else if (parameter.datetimeValue !== undefined) {
value = new Date(parameter.datetimeValue);
} else if (parameter.boolValue !== undefined) {
value = parameter.boolValue;
}
result[name] = value;
return result;
}, {});
}
The issue I have is that the parameters "accounts:drive_used_quota_in_mb" gives you the drive usage WITH the shared files (which is irrelevant to calculate the storage used by a user ( to determine whether he needs more space or not)).
I even tried to use 'accounts:used_quota_in_percentage' which seemed to be exactly what I need, but it calculate the percentage the same way i do : ((drive + mail)/total space)*100, and no way to ignore shared files to do so.
I'm working on the possibility to check every files of the drive, but you know the next problem : slowness.. (just for 1User with few docs, it take 1-2minutes)
Is there a way to do so by script, with another class, or something that is done for it in google that I didn't see ?
Thanks for your reading, forgive my english.
Ok, there is no issue, I just freaked out because a user was at 30Go consumption although he has his account for only 2month.
But after discussing with him, he did upload heavy files one week ago, and since, he deleted it.
And executing the script for only 2days ago gives the correct result, since he deleted these files between these two dates.
The reason of my mistake is that my script was providing stats that was 1 Week old (without me being conscious of that), and I was checking the veracity of theses stats on the web interface, that incidates nowadays stats.
Related
I have a pet project in google sheets that keeps track of the tv shows i've watched and syncs them up with the data in imdb (via some free api from www.omdbapi.com) to tell me what show I'm falling behind on, and should continue watching. I have a free account and I can only make 1k requests per day, so caching is an absolute MUST -- which is why there is caching EVERYWHERE. Issue I'm having is that onEdit runs, and sorts everything (expected), but re runs all the functions and I get these "Loading..." all over the place even though ALL of the functions are cached, I suspect google is making some of these fail?! But they don't "Error" (in the "Execution" tab) and they say "Completed" with no logs.
Does anyone know where the bottleneck is? And more importantly, how to fix it?
Here is the read only link to the sheet to try it out.
/**
* #OnlyCurrentDoc
*/
var APIKEY = 'xxxxxxx';
var CACHE_URL = 60 * 30; // 30 min
var CACHE_FUNCTION = 60 * 60 * 24; // 1 day
function onEdit(event) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets()[0];
var range = sheet.getRange("A3:K100");
range.sort([
{column: 9, ascending: false}, // continue watching
{column: 10, ascending: false}, // my ratings
{column: 8, ascending: true}, // days since
]);
ss.toast('Sort complete.');
}
function _cacheResult(key, callback, format, ttl) {
var cache = CacheService.getScriptCache();
var cached = cache.get(key);
if (cached != null) {
console.log(`found in cache: ${key}`, cached);
return format(cached);
}
var data = callback();
if (data == null) {
console.log(`cannot cache: ${key}`);
return data;
}
console.log(`cached!: ${key}`, data);
cache.put(key, data, ttl);
return format(data);
}
function _getJSON(url) {
var key = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, url)
.map(function(chr){return (chr+256).toString(16).slice(-2)})
.join('');
var callback = function() {
var response = UrlFetchApp.fetch(url)
var rawData = response.getContentText();
console.log(response.getResponseCode(), rawData);
if (response.getResponseCode() == 200) {
return rawData;
}
return null;
}
return _cacheResult(key, callback, JSON.parse, CACHE_URL)
}
function getSeasonDetail(imdbId, season) {
return _getJSON(`https://www.omdbapi.com/?i=${imdbId}&apikey=${APIKEY}&season=${season}`);
}
function _getValidEpisode(episodes) {
var currentDate = new Date();
console.log(episodes);
for (var i = episodes.length - 1; i >= 0; i--) {
if (episodes[i]['Released'] == 'N/A') {
console.log(`Skipping episode ${i+1}: unreleased`);
continue;
}
var dateSince = (currentDate - (new Date(episodes[i]['Released'])));
console.log(`Episode ${i+1}: ${dateSince}`);
if (dateSince > 0) {
console.log(`Episode ${i+1}: found!`);
return episodes[i];
}
}
return null;
}
function getIMDBRating(imdbId) {
if (!imdbId) {
return '';
}
var callback = function() {
var data = _getJSON(`https://www.omdbapi.com/?i=${imdbId}&apikey=${APIKEY}`);
return data['imdbRating'];
}
return _cacheResult(`rating:${imdbId}`, callback, parseFloat, CACHE_FUNCTION);
}
function getCurrentSeason(imdbId) {
if (!imdbId) {
console.log(`Ignoring.. bad id`, imdbId);
return '';
}
var callback = function() {
var data = _getJSON(`https://www.omdbapi.com/?i=${imdbId}&apikey=${APIKEY}`);
var season = data['totalSeasons'];
while (season) {
var seasonDetail = getSeasonDetail(imdbId, season);
var episode = _getValidEpisode(seasonDetail['Episodes']);
if (episode === null) {
console.log(`Season ${season} has no episodes ${imdbId}`);
season -= 1;
continue;
}
return season;
}
}
return _cacheResult(`current_season:${imdbId}`, callback, parseInt, CACHE_FUNCTION);
}
function getCurrentSeasonEpisode(imdbId, season) {
if (!imdbId) {
console.log(`Ignoring.. bad id`, imdbId);
return '';
} else if (!season || isNaN(parseInt(season))) {
console.log(`Ignoring ${imdbId}.. bad season id`, season);
return '?';
}
var callback = function() {
var data = getSeasonDetail(imdbId, season);
var episode = _getValidEpisode(data['Episodes']);
if (episode === null) {
console.log(`Ignoring.. bad episode response`, episode);
return '?';
}
return episode['Episode'];
}
return _cacheResult(`current_episode:${imdbId}:${season}`, callback, parseInt, CACHE_FUNCTION);
}
function getCurrentSeasonEpisodeReleased(imdbId, season) {
if (!imdbId) {
console.log(`Ignoring.. bad id`, imdbId);
return '';
} else if (!season || isNaN(parseInt(season))) {
console.log(`Ignoring ${imdbId}.. bad season id`, season);
return '?';
}
var callback = function() {
var data = getSeasonDetail(imdbId, season);
var episode = _getValidEpisode(data['Episodes']);
if (episode === null) {
console.log(`Ignoring.. bad episode reponse`, episode);
return '?';
}
return episode['Released'];
}
return _cacheResult(`current_episode_released:${imdbId}:${season}`, callback, String, CACHE_FUNCTION);
}
Issue and workaround:
I think that in your situation when onEdit is run, the rows are sorted. By this, the cell coordinates used by the formulas are also changed. By this, the formulas are recalculated. I think that this might be the reason for your issue.
If you don't want to recalculate the formulas, how about the following workaround?
Fix the values from the formulas, that the HTTP request is run, to the values.
In this case, even when the rows are sorted, UrlFetchApp.fetch(url) is not run.
When you want to update the values, the fixed values are updated by putting the formulas in the cells.
With this workaround, I thought that the quotas of the API might be able to be reduced.
In order to use this workaround, please add the following 2 functions.
Sample script:
Please copy and paste the following script to the script editor of your Spreadsheet.
// Values of columns E,F,G and K are fixed.
function fixValues() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lastRow = sheet.getLastRow();
sheet.getRangeList(["E3:G" + lastRow, "K3:K" + lastRow]).getRanges().forEach(r => r.copyTo(r, { contentsOnly: true }));
}
// In order to update values, formulas are put to columns E,F,G and K.
function updateValues() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lastRow = sheet.getLastRow();
var formulas = [
"=getCurrentSeason(R[0]C[-4])", // To column E
"=getCurrentSeasonEpisode(R[0]C[-5], R[0]C[-1])", // To column F
"=getCurrentSeasonEpisodeReleased(R[0]C[-6], R[0]C[-2])", // To column G
"=getIMDBRating(R[0]C[-10])", // To column K
];
sheet.getRangeList(["E3:E" + lastRow, "F3:F" + lastRow, "G3:G" + lastRow, "K3:K" + lastRow]).getRanges().forEach((r, i) => r.setFormulaR1C1(formulas[i]));
}
fixValues(): This function is used for fixing the values of columns E, F, G, and K.
updateValues(): This function is used for updating the values of columns E, F, G, and K using the formulas.
Testing:
In order to test this script, please do the following flow.
Please run fixValues() to your provided sample Spreadsheet. By this, the cells which have the formulas are fixed as the values.
Please edit the cells. By this, the rows are sorted. In this case, the formulas are not recalculated because of no formulas.
Please run updateValues(). By this, the values are updated by putting the formulas to the columns E, F, G, and K.
I thought that by this flow, your issue might be removed.
Note:
This sample script is for your provided sample Spreadsheet. So, when you change the structure of the Spreadsheet, this script might not be able to be used. Please be careful about this.
References:
getRangeList(a1Notations)
copyTo(destination, options)
setFormulaR1C1(formula)
I'm using an API script to pull in a single metric for Google Sheets in realtime. I can get one metrics to work, but I can't figure out how to pull in more than one and display it in the sheet.
// get time stamp of query run
function setTimeStamp(sheetName) {
SpreadsheetApp.getActive().getSheetByName(sheetName)
.getRange('C2').setValue(new Date())
}
// gaGet data
function gaGet(tableId, metrics, options) {
// Apply standard options
options = options || {};
options['max-results'] = options['max-results'] || '10000';
// If errors persist up to 5 times then terminate the program.
for (var i = 0; i < 5; i++) {
try {
return Analytics.Data.Realtime.get(tableId, metrics, options); // 503
} catch (err) {
// https://developers.google.com/analytics/devguides/reporting/core/v3/coreErrors
if (err.message.indexOf('a server error occurred') > -1) {
Logger.log('Backend Error');
// Note: Don't listen to Google's reply and retry request after 2 minutes
Utilities.sleep(2 * 60 * 1000);
} else if (err.message.indexOf('User Rate') > -1) {
Logger.log('Rate Limit Error');
// Exponential Backoff
Utilities.sleep(1000 * Math.pow((i + 1), 2));
} else if (err.message.indexOf('too many concurrent connections') > -1) {
Logger.log('Concurrent Connections Error');
// Exponential Backoff
Utilities.sleep(1000 * Math.pow((i + 1), 2));
} else {
Logger.log(err);
throw err;
}
}
}
throw 'Error. Max retries reached';
}
// rt pages query
function getRtPages(){
// set up the parameters and variables
var sheetName = 'web'; // The name of the sheet (not the Spreadsheet) we want to write the data e.g Sheet1
var tableId = 'ga:214164114'; // The id of the view to query the data from e.g ga:123456
//var startDate = 'yyyy-MM-dd'; // The start date of the query with the appropriate format e.g 2018-04-01 (1 April 2018)
//var endDate = 'yyyy-MM-dd'; // The end date of the query with the appropriate format e.g 2018-04-30 (30 April 2018)
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName(sheetName);
// set Up the query arguments
var metrics = ['rt:pageviews'];
var options = {
'dimensions': 'rt:pagePath',
//'filters': '',
'sort': '-rt:pageviews',
//'segment': '',
'samplingLevel': 'HIGHER_PRECISION',
'max-results': '100' // To limit the results to 100. Maximum number of results: 10000
}
var metrics2 = ['rt:activeUsers'];
var options2 = {
'dimensions': 'rt:country',
//'filters': '',
'sort': '-rt:activeUsers',
//'segment': '',
'samplingLevel': 'HIGHER_PRECISION',
'max-results': '100' // To limit the results to 100. Maximum number of results: 10000
}
// fetch the report
var report = gaGet(tableId, metrics, options, metrics1, options1);
// clear current sheet data
var range = sheet.getRange("A2:D101");
range.clear();
// fetch the report
var report = gaGet(tableId, metrics, options);
// clear current sheet data
var range = sheet.getRange("A2:D101");
range.clear();
// set timestamp of query run
setTimeStamp(sheetName)
var data = report.rows;
// get the range to write and write the results
try {
var writeRange = sheet.getRange(2, 1, data.length, data[0].length) // Read reference for getRange arguments
writeRange.setValues(data);
}
catch(err) {
Logger.log(err);
}
}
// test ga query to return json to log
function test(){
var x = Analytics.Data.Realtime.get('ga:214164114', 'rt:pageviews')
Logger.log(x)
}
I've added the additional metrics variable and tried several ways try and bring them into the sheet, but I'm missing something.
Any thoughts are appreciated.
I hope you can assist me here.
disclaimer: I'm new to Google Sheets and JavaScript, but have many years of programming experience.
I've got a pretty simple Custom Function in a sheet (Contained) that works absolutely fine if the Sheet is open in the browser. It basically takes in 5 arrays from the sheet and outputs 5 arrays from the cell from which it was called.
The sheet provides data to several other sheets that calculate from that data and then in turn share that to a further 'public' sheet that is then shared to a WordPress site.
ThisData -> CalculationSheet -> PublicViewSheet -> WordPress site
The problem kicks in after an hour or two after I close the Google Sheet in my browser, and I notice in the WordPress site that the data that was nicely displaying the leaderboard now outputs no athletes or their scores.
If I then:
merely open ThisData sheet and do nothing else, the calculated data is there and then all the athletes scores appears in the WordPress site 5 mins later due to caching.
instead open CalculationSheet or PublicViewSheet the 'QUERY( IMPORTRANGE(' that retrieves the data from ThisData retrieves no data (merely just the static headers).
I thought it might be the Google Sheets Custom Function caching problem and I've tried the trick of setting a cell to a Date/Time (see 'updateLastEditDate' in code below) and then referencing that cell through the score calculation (CalculateScores) as a dummy variable, and then setting up a trigger every hour to change the date which forces a recalculation... but I'm still getting the same disappearing results issues.
I've got a logger running to take a look at the output every time the CustomFunction runs, and when reviewing the logs, I can see that the output data is correct, but it seems that it's not getting written to the sheet. Or it might be getting written, but it's not showing further down the line ???
I guess I could rather change the CustomFunction to a function that is triggered onEdit as well as once a day (via triggers) and directly read the data from the sheet and then write it back... but a CustomFunction seems a neater solution, and allows me to move data ranges, add columns, etc without having to edit and hardwire the CalculateScores function.
I'm just scratching my head on why it's causing the above behavior... any ideas would be most welcome.
See code below: (for all it's worth... as it produces the expected output)
/** #OnlyCurrentDoc */
/**
* Calculates Precision Rifle scores..
*
* #param {lMatchNames}.
* #return {array} a full array of calculated scores.
* #customfunction
*/
function CalculateScores(lMatchNames, lAthleteIDs, lAthleteDivisions, lAthleteScores, lTieBreakScores, lTieBreakTimes, lDate ){
if(lMatchNames==undefined || lAthleteIDs==undefined || lAthleteDivisions==undefined || lAthleteScores==undefined || lTieBreakScores==undefined || lTieBreakTimes==undefined){
console.log("Setting null parameters");
var lMatchNames = [[]];
var lAthleteIDs = [[]];
var lAthleteDivisions = [[]];
var lAthleteScores = [[]];
var lTieBreakScores = [[]];
var lTieBreakTimes = [[]];
}else{
}
console.log(lNumMatches);
var lNumMatches = lMatchNames.length;
var lMatchData = [];
for (var i = 1; i < lNumMatches; i++) {
//Find Match Object
var lMatchName = lMatchNames[i][0];
var lAthleteID = lAthleteIDs[i][0];
var lAthleteDivision = lAthleteDivisions[i][0];
var lAthleteScore = lAthleteScores[i][0];
var lMatchObject = lMatchData.find(item => item.name == lMatchName);
if (lMatchObject === undefined) {
// Setup new match object in Array
lMatchObject = {
name:lMatchName,
combinedScores:[],
tieBreakScores:[],
};
lMatchData.push(lMatchObject);
}
// Add info to Match Object
if(lAthleteID!="0"){
addAndSort(lMatchObject.combinedScores, lAthleteScore);
var lTieBreakScore = (lAthleteScore * 100000000) + (lTieBreakScores[i][0] * 100000) - lTieBreakTimes[i][0]
addAndSort(lMatchObject.tieBreakScores, lTieBreakScore);
let lKeys = Object.keys(lMatchObject);
if(lKeys.indexOf(lAthleteDivision)==-1){
lMatchObject[lAthleteDivision]=[];
var lAthleteDivisionTieBreak = lAthleteDivision + "TieBreak";
lMatchObject[lAthleteDivisionTieBreak]=[];
}
addAndSort(lMatchObject[lAthleteDivision], lAthleteScore);
addAndSort(lMatchObject[lAthleteDivisionTieBreak], lTieBreakScore);
}
}
//Loop back through the data and calculate outputs
var lOutputArray = [];
lOutputArray.push(["Overall%", "OverallRank", "Division%", "DivisionRank", "RankTotal"]);
for (var i = 1; i < lNumMatches; i++) {
var lMatchName = lMatchNames[i][0];
if (lMatchName != ""){
var lAthleteID = lAthleteIDs[i][0];
var lAthleteDivision = lAthleteDivisions[i][0];
var lAthleteDivisionTieBreak = lAthleteDivision + "TieBreak";
var lAthleteScore = lAthleteScores[i][0];
var lTieBreakScore = (lAthleteScore * 100000000) + (lTieBreakScores[i][0] * 100000) - lTieBreakTimes[i][0]
if(lAthleteID=="0"){
var lOverallPercentage = "";
var lOverallRank = "";
var lDivisionPercentage = "";
var lDivisionRank = "";
var lTieBreakScore = "";
}else{
var lMatchObject = lMatchData.find(item => item.name == lMatchName);
var lOverallPercentage = lAthleteScore / lMatchObject.combinedScores[lMatchObject.combinedScores.length-1];
lOverallPercentage = Math.round(lOverallPercentage * 100000) / 100000;
var lOverallRank = lMatchObject.tieBreakScores.length - lMatchObject.tieBreakScores.lastIndexOf(lTieBreakScore);
var lDivisionPercentage = lAthleteScore / lMatchObject[lAthleteDivision][lMatchObject[lAthleteDivision].length-1];
lDivisionPercentage = Math.round(lDivisionPercentage * 100000) / 100000;
var lDivisionRank = lMatchObject[lAthleteDivisionTieBreak].length - lMatchObject[lAthleteDivisionTieBreak].lastIndexOf(lTieBreakScore);
}
lOutputArray.push([lOverallPercentage, lOverallRank, lDivisionPercentage, lDivisionRank, lTieBreakScore]);
}
}
console.log(lOutputArray);
return lOutputArray;
SpreadsheetApp.flush();
}
function addAndSort(arr, val) {
arr.push(val);
i = arr.length - 1;
item = arr[i];
while (i > 0 && item < arr[i-1]) {
arr[i] = arr[i-1];
i -= 1;
}
arr[i] = item;
return arr;
}
function onEdit() {
updateLastEditDate();
};
function updateLastEditDate() {
SpreadsheetApp.getActiveSpreadsheet().getRange('BC1').setValue(new Date().toTimeString());
};
I have setup a google sheet with a script attached to it that runs a function to pull chromebook device information, works great apart from two fields im interested in, "cpuStatusReports" and "diskVolumeReports" the script logger does show the correct info but my sheet cell values is set to for example
{cpuUtilizationPercentageInfo=[Ljava.lang.Object;#d151552,
cpuTemperatureInfo=[Ljava.lang.Object;#f57094c,
reportTime=2019-03-29T18:15:56.049Z}
my function is :-
function chromebookdetails2() { var domain, chromebooks, page, ss,
sheet, pageToken, i var sheetData4 =
onSheet.getSheetByName("chromebook") //sheetData4.clear(); domain =
"mydomainnamehere" chromebooks= new Array() do{ page =
AdminDirectory.Chromeosdevices.list("my_customer", {domain: domain,
maxResults: 1000, pageToken: pageToken }) for (i in
page.chromeosdevices){ chromebooks.push(page.chromeosdevices[i]) }
pageToken = page.nextPageToken }while(pageToken){ var row = 3
//starting row position for (var i = 0; i < chromebooks.length; i++) {
var sheetData4 = onSheet.getSheetByName("chromebook")
/////////////////////Header////////////////////////////////////////
var date = Utilities.formatDate(new Date(), "GMT+1", "dd/MM/yyyy")
sheetData4.getRange(1,1).setValue("Date Ran - "+date); //(2,1 means
2nd row, 1st column) sheetData4.getRange(2,1).setValue("orgUnitPath");
//(2,1 means 2nd row, 1st column)
sheetData4.getRange(2,2).setValue("annotatedUser");
sheetData4.getRange(2,3).setValue("annotatedLocation");
sheetData4.getRange(2,4).setValue("annotatedAssetId");
sheetData4.getRange(2,5).setValue("serialNumber");
sheetData4.getRange(2,6).setValue("lastEnrollmentTime");
sheetData4.getRange(2,7).setValue("deviceId");
sheetData4.getRange(2,8).setValue("bootMode");
sheetData4.getRange(2,9).setValue("recentUsers");
sheetData4.getRange(2,10).setValue("macAddress");
sheetData4.getRange(2,11).setValue("lastSync");
sheetData4.getRange(2,12).setValue("osVersion");
sheetData4.getRange(2,13).setValue("platformVersion");
sheetData4.getRange(2,14).setValue("activeTimeRanges");
sheetData4.getRange(2,15).setValue("model");
sheetData4.getRange(2,16).setValue("etag");
sheetData4.getRange(2,17).setValue("firmwareVersion");
sheetData4.getRange(2,18).setValue("status");
sheetData4.getRange(2,19).setValue("ethernetMacAddress");
sheetData4.getRange(2,20).setValue("notes");
sheetData4.getRange(2,21).setValue("systemRamTotal");
sheetData4.getRange(2,22).setValue("CPU");
if(chromebooks[i].length == 0){
// array is empty Logger.log('empty'); } else { //array not empty >Logger.log('not empty');
Logger.log(chromebooks[i].cpuStatusReports);
/////////////////////Array Data///////////////////////////////////
sheetData4.getRange(row,1).setValue(chromebooks[i].orgUnitPath);
sheetData4.getRange(row,2).setValue(chromebooks[i].annotatedUser);
sheetData4.getRange(row,3).setValue(chromebooks[i].annotatedLocation);
sheetData4.getRange(row,4).setValue(chromebooks[i].annotatedAssetId);
sheetData4.getRange(row,5).setValue(chromebooks[i].serialNumber);
sheetData4.getRange(row,6).setValue(chromebooks[i].lastEnrollmentTime);
sheetData4.getRange(row,7).setValue(chromebooks[i].deviceId);
sheetData4.getRange(row,8).setValue(chromebooks[i].bootMode);
sheetData4.getRange(row,9).setValue(chromebooks[i].recentUsers);
sheetData4.getRange(row,10).setValue(chromebooks[i].macAddress);
sheetData4.getRange(row,11).setValue(chromebooks[i].lastSync);
sheetData4.getRange(row,12).setValue(chromebooks[i].osVersion);
sheetData4.getRange(row,13).setValue(chromebooks[i].platformVersion);
sheetData4.getRange(row,14).setValue(chromebooks[i].activeTimeRanges);
sheetData4.getRange(row,15).setValue(chromebooks[i].model);
sheetData4.getRange(row,16).setValue(chromebooks[i].etag);
sheetData4.getRange(row,17).setValue(chromebooks[i].firmwareVersion);
sheetData4.getRange(row,18).setValue(chromebooks[i].status);
sheetData4.getRange(row,19).setValue(chromebooks[i].ethernetMacAddress);
sheetData4.getRange(row,20).setValue(chromebooks[i].notes);
sheetData4.getRange(row,21).setValue(chromebooks[i].systemRamTotal /
(1024*1024) /1024); // "/ (1024*1024)" converts bytes to Mb "/1024"
then converts back to Gb
sheetData4.getRange(row,22).setValue(chromebooks[i].cpuStatusReports);
}
row++ Logger.log(row) } } }
The results in the log file....
[{cpuUtilizationPercentageInfo=[63],
cpuTemperatureInfo=[{temperature=24, label=soc_dts0 },
{temperature=24, label=soc_dts1 }],
reportTime=2019-03-10T18:11:49.480Z}]
How do i reference cpuUtilizationPercentageInfo, cpuTemperatureInfo from cpuStatusReports?
Thankyou
In the loop add
var status = chromebooks[i].cpuStatusReports;
var cpuUtilizationPercentageInfo = status[0].cpuUtilizationPercentageInfo[0];
var cpuTemperatureInfo = status[0].cpuTemperatureInfo[0].temperature;
var label = status[0].cpuTemperatureInfo[0].label;
Check logger.log() to see if you get the desired results.
did you tried:
.setValue(chromebooks[i].cpuStatusReports.toString());
just turn every thing into string and you should have no problem on setValue() I guess.
So i have a script the gets some data from a server.
I want my script to publish the data to a sheet name "market items".
I got this working if I'm running the script directly from the sheet by using =getMarketItemsTrigger(1).
It posts all 11,669 items to my sheet.
The problem with this is that it refreshes every time the sheet is reloaded; I need it to only run once a month.
I've been trying to create a script which needs no reference in the given sheet but posts directly to a pre-named sheet but I can't figure out how I can get the data into the sheet
this is the script file i'm using
var version = '9a'
function getMarketItemsTrigger(refresh)
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Market Items");
Logger.log(sheet.getMaxColumns());
Logger.log(sheet.getMaxRows());
sheet.clear();
if(sheet.getMaxColumns()>2){
Logger.log('deleting colums');
sheet.deleteColumns(2, sheet.getMaxColumns()-2);
}
if(sheet.getMaxRows()>2){
Logger.log('deleting rows');
sheet.deleteRows(2,sheet.getMaxRows()-1);
}
var marketItemsEndpoint = 'https://crest-tq.eveonline.com/market/types/';
var marketItemsResponse = JSON.parse(fetchUrl(marketItemsEndpoint));
var totalPages = marketItemsResponse['pageCount'];
var itemList = [];
var headers = ['Item Name', 'ID'];
itemList.push(headers);
for (var currentPage = 1; currentPage <= totalPages; currentPage++)
{
Logger.log('Processing page ' + currentPage);
var marketItems = marketItemsResponse['items'];
for (var itemReference in marketItems)
{
var item = marketItems[itemReference];
itemList.push([item['type']['name'], item['id']]);
}
if (currentPage < totalPages)
{
var nextEndpoint = marketItemsResponse['next']['href'];
marketItemsResponse = JSON.parse(fetchUrl(nextEndpoint));
}
}
//sheet.insertRows(1,itemList.length+1);
// var range = sheet.getRange(1, 1,itemList.length+1,3);
// for(var i = 1;i<itemList.length;i++){
// range.getCell(i, 1).setValue([itemList]);
// range.getCell(1, i).setValue(itemList.);
// }
// Logger.log("don");
//sheet.getRange(1, 1, 1, itemList.length).setValues(itemList);
// sheet.getRange(itemList.length+1, 2).setValues(itemList);
// sheet.getDataRange().setValues([itemList]);
// sheet.appendRow(itemList);
// sheet.getRange(12+totalPages, 1, itemList.length, 1).setValues(itemList);
return itemList;
}
/**
* Private helper method that wraps the UrlFetchApp in a semaphore
* to prevent service overload.
*
* #param {url} url The URL to contact
* #param {options} options The fetch options to utilize in the request
*/
function fetchUrl(url)
{
if (gcsGetLock())
{
// Make the service call
headers = {"User-Agent": "Google Crest Script version " + version + " (/u/nuadi #Reddit.com)"}
params = {"headers": headers}
httpResponse = UrlFetchApp.fetch(url, params);
}
return httpResponse;
}
/**
* Custom implementation of a semaphore after LockService failed to support GCS properly.
* Hopefully this works a bit longer...
*
* This function searches through N semaphores, until it finds one that is not defined.
* Once it finds one, that n-th semaphore is set to TRUE and the function returns.
* If no semaphore is open, the function sleeps 0.1 seconds before trying again.
*/
function gcsGetLock()
{
var NLocks = 150;
var lock = false;
while (!lock)
{
for (var nLock = 0; nLock < NLocks; nLock++)
{
if (CacheService.getDocumentCache().get('GCSLock' + nLock) == null)
{
CacheService.getDocumentCache().put('GCSLock' + nLock, true, 1)
lock = true;
break;
}
}
}
return lock;
}
/**
* Private helper function that will check for a new version of GCS.
*/
function versionCheck()
{
var versionEndpoint = 'https://raw.githubusercontent.com/nuadi/googlecrestscript/master/version';
var newVersion = fetchUrl(versionEndpoint);
if (newVersion != null)
{
newVersion = newVersion.getContentText().trim();
Logger.log('Current version from Github: ' + newVersion);
var message = 'You are using the latest version of GCS. Fly safe. o7';
var title = 'No updates found';
if (newVersion > version)
{
message = 'A new version of GCS is available on GitHub.';
title = 'GCS version ' + newVersion + ' available!';
}
SpreadsheetApp.getActiveSpreadsheet().toast(message, title, 120);
}
}
All the code in the function getMarketItemsTrigger that's commented out is what I have tyred without luck .
The short version of this question is how can i post the values in itemList to column a and b in sheet market items
You can write the array itemList to the sheet by adding:
//your code
ss.getSheetByName('name_of_sheet_here')
.getRange(1, 1, itemList.length, itemList[0].length)
.setValues(itemList)
//more code (if needed)
} //end of code
-->> change sheet name and range to suit.
There are two ways to do this. If you did want it to run as a custom function those have access to the script property service. You could save a time stamp in the script properties and check it every time the custom function runs.
https://developers.google.com/apps-script/reference/properties/
https://developers.google.com/apps-script/guides/sheets/functions#using_apps_script_services
The second is to create a time trigger to run the code as a cron job every month.
https://developers.google.com/apps-script/guides/triggers/installable#time-driven_triggers
https://developers.google.com/apps-script/guides/triggers/installable#managing_triggers_manually