-
Notifications
You must be signed in to change notification settings - Fork 9
/
presentation.js
141 lines (126 loc) · 4.9 KB
/
presentation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
* Connector to Redmine from Google Apps Scripts platform.
*
* Copyright (c) 2011,2012 Emergya
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Author: Alejandro Leiva <[email protected]>
*
*/
// Presentation functions
// Returns true if the cell where cellData was read from is empty.
// Arguments:
// - cellData: string
function isCellEmpty(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
// Returns true if the character char is alphabetical, false otherwise.
function isAlnum(char) {
return char >= 'A' && char <= 'Z' ||
char >= 'a' && char <= 'z' ||
isDigit(char);
}
// Returns true if the character char is a digit, false otherwise.
function isDigit(char) {
return char >= '0' && char <= '9';
}
// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words or underscores. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
// - header: string to normalize
// - underscore: boolean to choose between using mixed case to separate words or underscores
// Examples:
// "First Name" -> "firstName"
// "Market Cap (millions) -> "marketCapMillions
// "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeString(header, underscore) {
var key = "";
var upperCase = false;
for (var i = 0; i < header.length; ++i) {
var letter = header[i];
if (letter == " " && key.length > 0) {
upperCase = true;
continue;
}
if (!isAlnum(letter)) {
continue;
}
if (key.length == 0 && isDigit(letter)) {
continue; // first character must be a letter
}
if (upperCase) {
upperCase = false;
if(underscore)
key +="_"+letter.toLowerCase();
else
key += letter.toUpperCase();
} else {
key += letter.toLowerCase();
}
}
return key;
}
// Returns an Array of normalized Strings.
// Empty Strings are returned for all Strings that could not be successfully normalized.
// Arguments:
// - headers: Array of Strings to normalize
// - underscore: boolean to choose between using mixed case to separate words or underscores
function normalizeStrings(headers, underscore) {
var keys = [];
for (var i = 0; i < headers.length; ++i) {
keys.push(normalizeString(headers[i], underscore));
}
return keys;
}
// setRowsData fills in one row of data per object defined in the objects Array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
// - sheet: the Sheet Object where the data will be written
// - objects: an Array of Objects, each of which contains data for a row
// - optHeadersRange: a Range of cells where the column headers are defined. This
// defaults to the entire first row in sheet.
// - optFirstDataRowIndex: index of the first row where data should be written. This
// defaults to the row immediately below the headers.
function setRowsData(sheet, objects, optHeadersRange, optFirstDataRowIndex) {
var headersRange = optHeadersRange || sheet.getRange(1, 1, 1, sheet.getMaxColumns());
var firstDataRowIndex = optFirstDataRowIndex || headersRange.getRowIndex() + 1;
var headers = normalizeStrings(headersRange.getValues()[0], true);
var data = [];
for (var i = 0; i < objects.length; ++i) {
var values = [];
var project = objects[i];
for (j = 0; j < project.length; ++j) {
for(k = 0; k < headers.length; ++k) {
var header = headers[k];
//We only push the value if the current project element is the current needed field
if(project[j][header] != undefined){
values.push(header.length > 0 && project[j][header] ? project[j][header].text : "");
}
}
}
data.push(values);
}
var destinationRange = sheet.getRange(firstDataRowIndex, headersRange.getColumnIndex(),
objects.length, headers.length);
destinationRange.setValues(data);
}
function populateProjectsSS() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var projectsSheet = ss.getSheetByName('ProjectsData') || ss.insertSheet('ProjectsData', ss.getSheets().length);
projectsSheet.clear();
var columnNames = ["Id", "Project Name", "Description", "Created On", "Updated On"];
var headersRange = projectsSheet.getRange(1, 1, 1, columnNames.length);
headersRange.setValues([columnNames]);
var data = (new Redmine()).getProjects();
setRowsData(projectsSheet, data);
}