Getting around 100 maxresult with AdminDirectory.Chromeosdevices.list - google-apps-script

I am writing a Google App Script that pulls Chromebook device information from gSuite. I need to export it as a CSV to ingest it into a database. I ran into an issue, however. The API 'AdminDirectory.Chromeosdevices.list' is limited to 100 maxResults. I have over 30,000 results.
Here is my test code.
function updateDeviceList() {
var page, pageToken, row, dateTime;
dateTime = getDateTime();
deleteAllRows();
do {
page = AdminDirectory.Chromeosdevices.list("my_customer",
{
domain: 'redclayschools.com',
maxResults: 115,
orderBy: 'annotatedUser',
pageToken: pageToken,
projection: 'full',
query: 'id:*'
});
for (i in page.chromeosdevices) {
row = getLastRow();
writeToCell(row, 1, page.chromeosdevices[i].orgUnitPath);
writeToCell(row, 2, page.chromeosdevices[i].annotatedUser);
writeToCell(row, 3, page.chromeosdevices[i].annotatedLocation);
writeToCell(row, 4, page.chromeosdevices[i].annotatedAssetId);
writeToCell(row, 5, page.chromeosdevices[i].serialNumber);
writeToCell(row, 6, page.chromeosdevices[i].lastEnrollmentTime);
writeToCell(row, 7, page.chromeosdevices[i].deviceId);
writeToCell(row, 8, page.chromeosdevices[i].bootMode);
writeToCell(row, 9, page.chromeosdevices[i].recentUsers);
writeToCell(row, 10, page.chromeosdevices[i].macAddress);
writeToCell(row, 11, page.chromeosdevices[i].lastSync);
writeToCell(row, 12, page.chromeosdevices[i].osVersion);
writeToCell(row, 13, page.chromeosdevices[i].platformVersion);
writeToCell(row, 14, page.chromeosdevices[i].activeTimeRanges);
writeToCell(row, 15, page.chromeosdevices[i].model);
writeToCell(row, 16, page.chromeosdevices[i].etag);
writeToCell(row, 17, page.chromeosdevices[i].firmwareVersion);
writeToCell(row, 18, page.chromeosdevices[i].status);
writeToCell(row, 19, page.chromeosdevices[i].ethernetMacAddress);
writeToCell(row, 20, page.chromeosdevices[i].notes);
writeToCell(row, 21, dateTime);
}
} while (pageToken){
}
}
And my helper functions (this shouldn't matter):
function writeToCell(row, column, text) {
sheet.getRange(row, column).setValue(text);
}
Is there a better function to use (I can't seem to find anything), or a way around the 100 maxResult limit? I know the approach with writing directly to the row isn't efficient, this is only test code.
Thanks!

Yes, based from this documentation, the API returns a default and a maximum of 100 entries per page for Chrome and mobile devices. Suggested action is to retry using exponential back-off. You need to slow down the rate at which you are sending the requests.

Related

Angualrjs <select> ng-model adds strange string

In my angular js application I have used as follows
<select id='baseline' class="form-control" ng-model='vm.modal.baseline'>
<option ng-repeat='base in vm.baseline' ng-value='base'>{{base}}</option>
</select>
Then in my controller
vm.baseline = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
vm.modal = {baseline: '3'};
but select is not defaulting to 3 instead it adds
<option value="? string:3 ?"></option>
What should I do to set the default value as 3? Thank you.
There is a problem with your controller AS syntax, it is working correctly with $scope see the eg with your code.
https://jsfiddle.net/6r5Lnasb/
<div ng-app ng-controller="LoginController">
<select id='baseline' class="form-control" ng-model='modal.baseline'>
<option ng-repeat='base in baseline' ng-value='base'>{{base}}</option>
</select>
</div>
function LoginController($scope) {
$scope.baseline = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$scope.modal = {baseline: '3'};
}
It doesn't work because ng-model value is a string and option value is number.
Change vm.modal = {baseline: 3}; or convert baseline to array of strings vm.baseline = ['1', '2', '3' ...];
Try replacing these two lines
vm.baseline = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
vm.modal = {baseline: '3'};
with below lines
vm = {
baseline: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
modal: {
baseline: '3'
}
}
As the variable vm is not defined/declared something like var vm; or var vm = {}; or var vm = null assigning an array value or any value to a property of an undefined variable will throw an error hence it was not working.
if you have seen your browser console you might have got some similar looking error: TypeError: Cannot set property 'baseline' of undefined

How to fetch archived history from Chrome API

I would like to list archived (90+ days) history URLs from Google Chrome using Chrome API.
I realised that it's probably impossible because the results have not been returned:
let urlAmount = 0;
chrome.history.search(
{
"text": "",
"startTime": new Date(2018, 5, 14, 11, 0, 0).getTime(),
"endTime": new Date(2018, 6, 14, 11, 0, 0).getTime()
},
function(historyItems)
{
for (var i = 0; i < historyItems.length; i++)
{
urlAmount++;
}
});
As you can see I'm checking (2018.05.14 - 2018.06.14) time interval (it's more that 90 days ago from now).
urlAmount is 0 but for example (2019.01.14 - 2019.01.20) it's 100 (default max value is 100).
Is it possible to fetch such archived history this way?
If not what about Selenium automation approach?
The urlAmount variable is incremented inside a callback. So you should move its initialization to the callback function(historyItems), right before the for loop.
The default value for maxResults is 100 if you don't use it, but you can set to it a higher value.

what is the best way to zip multiple lists in ImmutableJS

Assume i have a List of Lists. e.g:
const l : List<List<number>> = fromJS([[0,1,2,3],[4,5,6,7],[8,9,10,11]])
what is the best way (without using toJS()) to zip "l" so i'll get:
[[0,4,8],[1,5,9],[2,6,10],[3,7,11]]
I believe you want to use List#zip.
const l = Immutable.fromJS([
[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]
]);
const zipped = l.get(0).zip(...l.rest());
console.log(zipped);
// [ [0,4,8], [1,5,9], [2,6,10], [3,7,11] ];
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.9/immutable.js"></script>
Note that this returns a list of Arrays. It's easy enough to turn them into Lists though:
const zippedLists = zipped.map(List);
You might also be interested in List#zipAll if you're zipping lists of different sizes.

Selective rearrangement of columns in XMLListCollection not working

I am trying to selectively rearrange columns in my XMLListCollection but for some reasons it is not working.
As an example, say my array is - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. I am trying to shift 9th column to 2nd column. So my output shall be like this [1, 9, 2, 3, 4, 5, 6, 7, 8, 10].
I have tried the below code to achieve my result.
model.columns = new XMLListCollection(event.payload.Columns.Column);
// Selective re-arrangment
// Storing 9 col in backup variable
Var backUp:XMLListCollection = model.columns[9];
// Removing item from column 9
model.columns.removeItemAt(9);
// Inserting backup variable at desired index
model.columns.addItemAt(backUp,2)
// Code for rendering each column
for each( var col:XML in model.columns){
if(col.#visible == "Y"){
var dataGridColumn:FlexDataGridColumn = new FlexDataGridColumn();
dataGridColumn.headerText = col.#display_nm;
dataGridColumn.dataField = '#'+col.#variable;
view.adjustmentModuleColumns.addColumn( dataGridColumn);
view.adjustmentsDataGrid.reDraw();
}
}
For some reasons above code is not working as expected. Please suggest.

How to get only unique values of a 2d array

I need to get the following 2d array from:
[[Option 10, 2.0], [Option 10, 2.0], [Option 9, 1.0], [Option 7, 1.0]]
to
[[Option 10, 2.0], [Option 9, 1.0], [Option 7, 1.0]]
I found this post (Splitting a 2D array using some() , by date, avoiding duplicates. Just want 1 unique email, not row. Where am i wrong here?) that has a very efficient way of getting unique values, but I cannot figure out how to apply it to my situation.
Your use case is simpler than the one you refer to.
try this for example :
function myFunction() {
var source = [['Option 10', 2], ['Option 10', 2], ['Option 9', 1], ['Option 7', 1]];
var dest = [];
dest.push(source[0]);
for(var n = 1 ; n< source.length ; n++){
if(dest.join().indexOf(source[n].join()) == -1){dest.push(source[n])};
}
Logger.log(dest);
}
Because 'unique' is not always simple to describe, I often use a pattern which is is, in effect, a variation of Serge's correct answer using ES5 array map/filter functions.
An edited version:
function hash(arr) {
// in this case the hash method is the same as Serge's Array.join() method,
but could be customised to suit whatever condition you need to generate
bespoke comparators such as where `1 + 3` should match `2 + 2`, or where
particular columns in the array can be omitted
return arr.join();
}
function myFunction() {
var source = [['Option 10', 2], ['Option 10', 2], ['Option 9', 1], ['Option 7', 1]];
var hash = source.map(
function (row) {
return hash(row);
}
);
source = source.filter(
function (filterRow, i) {
return hash.slice(0, i).indexOf(hash(filterRow)) < 0;
}
);
Logger.log(source);
}
I only include this as there are times when your comparison may need to flex a little. In your example this isn't important which is why Serge's is correct, but I share to show a potential expansion food for thought for when unique needs to be 'tweaked'