Google Apps Script to remove hangouts links from calendar events - google-apps-script

I have successfully accessed a Google calendar event and can change the color, but I'm stuck when it comes to removing the hangouts link.
I'm attempting to use code to automatically remove the hangouts links when I am the meeting originator and have not changed the hangout name, but I'm not having any success in actually changing the link.
Any help greatly appreciated.
function removehangout() {
var calendarId = 'primary';
//var calendars = CalendarApp.getOwnedCalendarsByName('Mirage ELDRIDGE');
var now = new Date();
// Determines how many events are happening in the next 24 hours x 1 days.
var now = new Date();
var endr = new Date(now.getTime() + (1 * 24 * 60 * 60 * 1000));
var events2 = CalendarApp.getDefaultCalendar().getEvents(now, endr);
Logger.log('Number of events: ' + events2.length);
var events = Calendar.Events.list(calendarId, {
timeMin: now.toISOString(),
singleEvents: true,
orderBy: 'startTime',
maxResults: 5
});
if (events.items && events.items.length > 0) {
for (var i = 0; i < events.items.length; i++) {
var event1 = events.items[i];
var d = event1.description;
var ttitle = event1.summary;
var whoby = event1.creator.email;
Logger.log(ttitle + ' by: ' + whoby);
if(whoby.indexOf('mirage.eldridge') != -1){
Logger.log(ttitle + '--> was by mirage');
var hangoutname = event1.hangoutLink;
Logger.log(ttitle + '--> hangout link name --> ' + hangoutname);
if (hangoutname != null) {
if (hangoutname.indexOf('mirage-eldridge') != -1){
//delete this link here
Logger.log(ttitle + '--> remove hangout');
//event.setHangoutLink(null);
//var idno = event.iCalUID
//CalendarApp.getEventSeriesById(idno)
event1.HangoutLink = null;
Logger.log(ttitle + '... ' + event1.hangoutLink);
Logger.log(event1.iCalUID);
//event.setcolorId('11');
var event2 = Calendar.Events.get(calendarId, event1.id)
event2.colorId = 9;
event2.hangoutLink = 'fred';
//Calendar.Events.patch(event2,calendarId,event1.id);
Calendar.Events.update(event2,calendarId,event1.id);
}
} else {
Logger.log(ttitle + ' -- do not remove ' + hangoutname);
}
}
if (!d)
d = '';
//var foundlinkyes = d.indexOf('HangoutLink');
//var actuallink = event.hangoutLink;
//var hasrlink = 'True';
//if (!actuallink) {
//Logger.log(ttitle + ' no link found');
//hasrlink = "False";
//}
//Logger.log('desc: ' + ttitle + '-- foundyes: ' + foundlinkyes);
//if (foundlinkyes == -1 && hasrlink == 'True'){
//if (event.hangoutLink && (d.indexOf('Hangout: ')== -1)){
//Logger.log (event.summary + ' - ' + event.hangoutLink + ' - ' + event.description);
//Logger.log(ttitle + ' added this ' + event.hangoutLink);
//event.description = 'HangoutLink: ' + event.hangoutLink + '\n\n' + d;
//Calendar.Events.update(event, calendarId, event.id);
//foundlinkyes = 0;
//hasrlink = 'True';
//}
//}
}
} else {
Logger.log('No events found.');
}
}

Related

GAS - Script execution time too long / Workaround?

I have a script that takes more than 5 minutes to execute. So it will be aborted after 5 minutes with the information that the execution time is too long.
Now I am looking for a solution to handle this. In the following example I would like to interrupt when var = i has reached a value of 300 and then continue with i = 301. Is this an option for a workaround? If so, how has the code to be adapted?
var xy = 1100;
for (var = i; i<= xy; i++){
{
do_some_stuff();
}
}
In practice my code is the following....and the loop is starting with for(var i = 3; i <= lastrow +1; i++) lastrow has a value of 1500.
function Create_geodata()
{
var Geodata = getSheetById(1702838837);
var Geojson_Data = getSheetById(1515926044);
var Control_Panel = getSheetById(1102907697);
Geodata.getRange('I4').setValue('Yes');
var Hyperlink_Geodata = Control_Panel.getRange('O18').getValue();
var document_missing_ID = Control_Panel.getRange('O24').getValue();
var Umap_Hyperlink = Control_Panel.getRange('L20').getValue();
var umap_zoom = Control_Panel.getRange('N22').getValue();
var Own_ID_Sort_Setting = Control_Panel.getRange('O30').getValue();
var Own_ID_Sort = Control_Panel.getRange('M32').getValue();
var Threshold_Altitude = Control_Panel.getRange('N28').getValue();
var Automatic_Altitude_Removal = Control_Panel.getRange('O26').getValue();
var Cat_A = Control_Panel.getRange('C36').getValue();
var Cat_B = Control_Panel.getRange('C38').getValue();
var Cat_C = Control_Panel.getRange('C40').getValue();
RESET_Geodata(); //Clear data before proceed
if (Own_ID_Sort_Setting)
{standard_sort_column = Own_ID_Sort}
else
{standard_sort_column = "name"}
var data = Geojson_Data.getDataRange().getValues();
var col1 = data[0].indexOf(standard_sort_column) + 1;
var col2 = data[0].indexOf('coordinates') + 1;
var col3 = data[0].indexOf('name') + 1;
var col4 = data[0].indexOf('description') + 1;
var col1_Char = columnToLetter(col1); //last row of column where sort-criteria is located
var col2_Char = columnToLetter(col2);
var col3_Char = columnToLetter(col3);
var col4_Char = columnToLetter(col4);
var lastrow_col1 = Geojson_Data.getRange(col1_Char + ':' + col1_Char).getValues();
lastrow_col1 = lastrow_col1.filter(String).length;
var lastrow = Geojson_Data.getLastRow();//last row of complete sheet
var lc = Geojson_Data.getLastColumn(); //last column
var lc_Char = columnToLetter(lc);
var dc = 0;
Geojson_Data.getRange('N1').setValue(col1);
if (!document_missing_ID)
{
for(var t = 2; t <= lastrow; t++)
{
if (Geojson_Data.getRange(t,col1).getValue() == "")
{
Geojson_Data.deleteRow(t);
}
}
}
else
{
for(var t = 2; t <= lastrow; t++)
{
if (Geojson_Data.getRange(t,col1).getValue() == "")
{
dc++;
var formattedNumber = ("000" + dc).slice(-4);
Geojson_Data.getRange(t,col1).setValue('ZZ_' + formattedNumber);
}
}
}
Geojson_Data.getRange('A2:' + lc_Char + lastrow).sort(col1);
Geojson_Data.getRange(col1_Char + 2 + ':' + col1_Char + lastrow).copyTo(Geodata.getRange('A3:A' + lastrow),{contentsOnly: true});
Geojson_Data.getRange(col2_Char + 2 + ':' + col2_Char + lastrow).copyTo(Geodata.getRange('F3:F' + lastrow),{contentsOnly: true});
Geojson_Data.getRange(col3_Char + 2 + ':' + col3_Char + lastrow).copyTo(Geodata.getRange('B3:B' + lastrow),{contentsOnly: true});
Geojson_Data.getRange(col4_Char + 2 + ':' + col4_Char + lastrow).copyTo(Geodata.getRange('D3:D' + lastrow),{contentsOnly: true});
var geodata_sorted = '';
var route_length = 0;
for(var i = 3; i <= lastrow +1; i++)
{
var pr = 0;
var fl = false;
var distance_neighbour_points = 0;
var Ar = Geodata.getRange('F' + i).getValue();
Ar = Ar.split(',');
var Ar_Anz = Ar.length - 1;
for(var b = 0; b <= Ar_Anz; b=b+2)
{
if ((Ar_Anz - b) != 0)
{
var E_Lat = Ar[b];
var E_Lon = Ar[b + 1];
if (fl)
{
var A_Lat = Ar[b - 2];
var A_Lon = Ar[b - 1];
distance_neighbour_points = distVincenty(A_Lat, A_Lon, E_Lat, E_Lon);
if (Automatic_Altitude_Removal && (distance_neighbour_points > Threshold_Altitude))
{
b++;
E_Lat = Ar[b];
E_Lon = Ar[b + 1];
A_Lat = Ar[b - 3];
A_Lon = Ar[b - 2];
}
route_length = route_length + distVincenty(A_Lat, A_Lon, E_Lat, E_Lon);
}
pr++;
fl = true;
}
geodata_sorted = geodata_sorted + E_Lat + ',' + E_Lon;
if ((Ar_Anz - b) < 2)
{
}
else
{
geodata_sorted = geodata_sorted + ',';
}
if ((Ar_Anz - b) < 2)
{
pr = parseInt(pr / 2) * 2 + 1;
var Ay = geodata_sorted.split(',');
var Geo_Mitte_Lon = Ay[pr - 1];
var Geo_Mitte_Lat = Ay[pr];
var googlemaps = 'https://maps.google.com/?q=' + Geo_Mitte_Lat + ',' + Geo_Mitte_Lon;
var umap = 'https://umap.openstreetmap.fr/de' + '/map/' + Umap_Hyperlink + '#' + umap_zoom + '/' + Geo_Mitte_Lat + '/' + Geo_Mitte_Lon;
Geodata.getRange(i, 3).setValue(route_length / 1000);
Geodata.getRange(i, 6).setValue(geodata_sorted);
Geodata.getRange(i, 7).setValue(googlemaps);
Geodata.getRange(i, 8).setValue(umap);
//Verlinkung
if (Hyperlink_Geodata)
{
var displayName1 = Geodata.getRange(i,1).getValue();
var displayName2 = Geodata.getRange(i,2).getValue();
Geodata.getRange(i,1).setFormula('=HYPERLINK(\"' + googlemaps + '\";\"' + displayName1 + '\")');
Geodata.getRange(i,2).setFormula('=HYPERLINK(\"' + umap + '\";\"' + displayName2 + '\")');
}
geodata_sorted = '';
route_length = 0;
}
}
//Set categories Cat_A,B,C...
var description_content = Geodata.getRange(i,4).getValue();
var regExpA = new RegExp('/*' + Cat_A, 'gi');
var regExpB = new RegExp('/*' + Cat_B, 'gi');
var regExpC = new RegExp('/*' + Cat_C, 'gi');
var compareA = regExpA(description_content);
var compareB = regExpB(description_content);
var compareC = regExpC(description_content);
if (compareC == Cat_C) Geodata.getRange(i,5).setValue(Cat_C);
if (compareB == Cat_B) Geodata.getRange(i,5).setValue(Cat_B);
if (compareA == Cat_A) Geodata.getRange(i,5).setValue(Cat_A);
}
SpreadsheetApp.getActiveSpreadsheet().setActiveSheet(Geodata);
Geodata.getRange('I4').setValue('No');
}

"Lock wait timeout exceeded" when sending data from Google Sheets to MySQL

I wrote an Apps Script macro to send data from a Google spreadsheet to a MySQL table. In a first time, in delete some rows in the table and then I add rows in this table. I sometimes get a "Lock wait timeout exceeded; try restarting transaction" error. Sometimes it runs after 100 seconds, sometimes 4 minutes.
I don't understand what is wrong with this code.
//classeur.insertSheet("feuillebis")
//feuillebis=classeur.getSheets()[1]
//var feuillebis=classeur.getSheetByName('feuillebis')
var classeur = SpreadsheetApp.getActiveSpreadsheet() ;
var feuille = classeur.getActiveSheet();
var host = "107.167.186.180";
var databaseName = "eatology";
var userName = "root";
var password = "eatology";
var port = 3306;
var tableName = "weekly_order";
var url = 'jdbc:mysql://' + host + ':' + port + '/' + databaseName;
var nbrow = feuille.getMaxRows()
function Send_Weekly_Order_To_Data_Base() {
///here are all the connection parameters
var classeur = SpreadsheetApp.getActiveSpreadsheet();
var feuille = classeur.getActiveSheet();
var nbrow = feuille.getMaxRows();
var host = "107.167.186.180";
var databaseName = "eatology";
var userName = "root";
var password = "eatology";
var port = 3306;
var tableName = "weekly_order";
var url = 'jdbc:mysql://' + host + ':' + port + '/' + databaseName;
var conn = Jdbc.getConnection(url, userName, password);
conn.setAutoCommit(false);
///get the weekly_order as an array from the sql
var rowcount = 0;
var stmt2 = conn.createStatement();
var results = stmt2.executeQuery("SELECT * FROM eatology.weekly_order");
while (results.next()) {
if (results.getInt(1) > rowcount){
rowcount = results.getInt(1)
}
}
conn.commit();
results.close();
stmt2.close();
///delete the rows from the current week where we are running the macro
var timezone1 = classeur.getSpreadsheetTimeZone();
var date1 = Utilities.formatDate(feuille.getRange(2, 2).getValue(), timezone1, "yyyy-MM-dd");
var date2 = Utilities.formatDate(feuille.getRange(2, 3).getValue(), timezone1, "yyyy-MM-dd");
var date3 = Utilities.formatDate(feuille.getRange(2, 4).getValue(), timezone1, "yyyy-MM-dd");
var date4 = Utilities.formatDate(feuille.getRange(2, 5).getValue(), timezone1, "yyyy-MM-dd");
var date5 = Utilities.formatDate(feuille.getRange(2, 6).getValue(), timezone1, "yyyy-MM-dd");
var date6 = Utilities.formatDate(feuille.getRange(2, 7).getValue(), timezone1, "yyyy-MM-dd");
///clear the table weekly-order in the database
var stmt1 = conn.createStatement();
var result = stmt1.executeUpdate("DELETE FROM eatology.weekly_order where `Date` = " + "'" + date1 + "'" +" or `Date` = " + "'" + date2 + "'" +" or `Date` = " + "'" + date3 + "'" +" or `Date` = "+ "'" + date4 + "'" +" or `Date` = " + "'" + date5 + "'" +" or `Date` = "+ "'" + date6 + "'" );
//var result = stmt1.executeUpdate("DELETE FROM eatology.weekly_order where `Date` = " + "'" + date1 +"'");
conn.commit();
stmt1.close();
conn.close();
rowcount = rowcount + 1;
var conn = Jdbc.getConnection(url, userName, password);
conn.setAutoCommit(false);
var stmt = conn.prepareStatement('INSERT INTO eatology.weekly_order '
+ '(`Uid`, `Date`, `MP`, `Cname`, `Pname`, `Breakfast`, `Snack1`, `Lunch`, `Snack2`, `Dinner`) values (?,?,?,?,?,?,?,?,?,?)');
var program_name_line = 0;
var array = feuille.getRange(1, 1, nbrow, 7).getValues();
for (var j = 1; j < 7; j = j + 1) {
var inside = 0;
var i = 1;
while (array[i][0] != "Total" && i < 1000) {
i = i + 1
var color = feuille.getRange(i + 1, j + 1).getBackgrounds()
var fi1 = array[i][0].toString();
var fij = array[i][j].toString();
var empty = (fij == "");
var already = 0;
var test11111 = (color != "#5d31ce");
var cas1 = ((empty == false) && (fi1 != "Total") && (inside == 0));
var cas2 = (color == "#5d31ce" && inside == 1);
var cas3 = (empty == false);
if ((fi1 != "Total") && (inside == 0) && color != "#5d31ce") {
program_name_line = i;
inside = 1;
if (empty == false) {
var Uid = rowcount;
var Date1 = (Utilities.formatDate(array[1][j], timezone1, "yyyy-MM-dd"));
var MP = (array[program_name_line][0]);
var place = ((fij).indexOf("-"));
var length = (fij.length);
var Pname = ((fij).substring(place + 1, length));
var Cname = ((fij).substring(0, place));
var list = (meal(MP, Pname));
var Breakfast = list[0];
var Snack1 = list[1];
var Lunch = list[2];
var Snack2 = list[3];
var Dinner = list[4];
if (MP == "TM") {
var Breakfast = 1;
var Snack1 = 1;
var Lunch = 1;
var Snack2 = 1;
var Dinner = 1;
}
rowcount = rowcount + 1;
stmt.setInt(1, Uid);
stmt.setString(2, Date1);
stmt.setString(3, MP);
stmt.setString(4, Cname);
stmt.setString(5, Pname);
stmt.setInt(6, Breakfast);
stmt.setInt(7, Snack1);
stmt.setInt(8, Lunch);
stmt.setInt(9, Snack2);
stmt.setInt(10, Dinner);
stmt.addBatch();
}
}
else if (color == "#5d31ce" && inside == 1) {
inside = 0;
}
else if (empty == false && color != "#5d31ce") {
var Uid = rowcount ;
var Date1 = (Utilities.formatDate(array[1][j], timezone1, "yyyy-MM-dd"));
var MP = (array[program_name_line][0].toString());
var place = ((fij).indexOf("-"));
var length = (fij.length);
var Pname = ((fij).substring(place + 1, length));
var Cname = ((fij).substring(0, place));
var list = (meal(MP, Pname));
var Breakfast = (list[0]);
var Snack1 = (list[1]);
var Lunch = (list[2]);
var Snack2 = (list[3]);
var Dinner = (list[4]);
if (MP == "TM") {
var Breakfast = 1;
var Snack1 = 1;
var Lunch = 1;
var Snack2 = 1;
var Dinner = 1;
}
rowcount = rowcount+1;
stmt.setInt(1, Uid);
stmt.setString(2, Date1);
stmt.setString(3, MP);
stmt.setString(4, Cname);
stmt.setString(5, Pname);
stmt.setInt(6, Breakfast);
stmt.setInt(7, Snack1);
stmt.setInt(8, Lunch);
stmt.setInt(9, Snack2);
stmt.setInt(10, Dinner);
stmt.addBatch();
}
}
}
stmt.executeBatch();
conn.commit();
stmt.close();
conn.close();
}
function meal(MP, Pname){
var result= [0, 0, 0, 0, 0]
//in order to know if we have two snacks or only one because if the programm has more than 1200 cal, there are two snacks, otherwise, only one snack
var two_snacks = 1
if (MP.indexOf("1200") > -1) {
two_snacks = 0
}
//if the program type is '3'
if (Pname.indexOf("3") > -1) {
result[0] = 1;
result[1] = 1;
result[2] = 1;
result[4] = 1;
if (two_snacks == 1) {
result[3] = 1;
}
}
//if the program type is '2'
if (Pname.indexOf("2") > -1 && Pname.indexOf("S") == -1) {
result[0] = 1;
result[1] = 1;
result[2] = 1;
if (two_snacks == 1) {
result[3] = 1;
}
}
//if there is the B letter
if (Pname.indexOf("B") > -1) {
result[0] = 1;
}
//if there is the L letter
if (Pname.indexOf("L") > -1) {
result[2] = 1;
}
//if there is the D letter
if (Pname.indexOf("D") > -1) {
result[4] = 1;
}
//if there is the 2S letter
if (Pname.indexOf("2S") > -1) {
result[1] = 1;
result[3] = 1;
}
//if there is the 1S letter
if (Pname.indexOf("1S") > -1) {
result[1] = 1;
result[1] = 1;
}
return result
}

HTML5 Input datetime-local default value of today and current time

Is there anyway that I can make a default value of HTML5 input type='datetime-local' to today's date and this current time.
Thanks before
You can make it shorter:
<input type="datetime-local" id="cal">
window.addEventListener('load', () => {
var now = new Date();
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
/* remove second/millisecond if needed - credit ref. https://stackoverflow.com/questions/24468518/html5-input-datetime-local-default-value-of-today-and-current-time#comment112871765_60884408 */
now.setMilliseconds(null)
now.setSeconds(null)
document.getElementById('cal').value = now.toISOString().slice(0, -1);
});
It's possible. By using a JQuery function, you can have a really complete solution.
Here is an example.
JSFiddle http://jsfiddle.net/v8MNx/1/
HTML
<form action="demo.html" id="myForm">
<p>
<label>Date:</label>
<input type="datetime" name="anniversaire" id="anniversaire"/>
</p>
<input type="submit" value="Submit"/>
</form>
JQuery:
//Function found here: https://gist.github.com/ryanburnette/8803238
$.fn.setNow = function (onlyBlank) {
var now = new Date($.now())
, year
, month
, date
, hours
, minutes
, seconds
, formattedDateTime
;
year = now.getFullYear();
month = now.getMonth().toString().length === 1 ? '0' + (now.getMonth() + 1).toString() : now.getMonth() + 1;
date = now.getDate().toString().length === 1 ? '0' + (now.getDate()).toString() : now.getDate();
hours = now.getHours().toString().length === 1 ? '0' + now.getHours().toString() : now.getHours();
minutes = now.getMinutes().toString().length === 1 ? '0' + now.getMinutes().toString() : now.getMinutes();
seconds = now.getSeconds().toString().length === 1 ? '0' + now.getSeconds().toString() : now.getSeconds();
formattedDateTime = year + '-' + month + '-' + date + 'T' + hours + ':' + minutes + ':' + seconds;
if ( onlyBlank === true && $(this).val() ) {
return this;
}
$(this).val(formattedDateTime);
return this;
}
$(function () {
// Handler for .ready() called.
$('input[type="datetime"]').setNow();
});
The accepted answer seems pretty complicated to me... here a shorter solution that doesn't need jQuery
JSFiddle: https://jsfiddle.net/rzaceg8v/
window.addEventListener("load", function() {
var now = new Date();
var utcString = now.toISOString().substring(0,19);
var year = now.getFullYear();
var month = now.getMonth() + 1;
var day = now.getDate();
var hour = now.getHours();
var minute = now.getMinutes();
var second = now.getSeconds();
var localDatetime = year + "-" +
(month < 10 ? "0" + month.toString() : month) + "-" +
(day < 10 ? "0" + day.toString() : day) + "T" +
(hour < 10 ? "0" + hour.toString() : hour) + ":" +
(minute < 10 ? "0" + minute.toString() : minute) +
utcString.substring(16,19);
var datetimeField = document.getElementById("myDatetimeField");
datetimeField.value = localDatetime;
});
<input type="datetime-local" id="myDatetimeField"/>
The methods above worked but were too verbose for me.
Here's my version:
window.addEventListener("load", function() {
var now = new Date();
var offset = now.getTimezoneOffset() * 60000;
var adjustedDate = new Date(now.getTime() - offset);
var formattedDate = adjustedDate.toISOString().substring(0,16); // For minute precision
var datetimeField = document.getElementById("myDatetimeField");
datetimeField.value = formattedDate;
});
This worked perfectly!
One note, I tried this the only month it would break, October. It would give me a '010', instead of 10.
month = (now.getMonth() +1 ).toString().length === 1 ? '0' + (now.getMonth() + 1).toString() : now.getMonth() + 1;
Big line works for me, if it doesn't for you you can introduce whitespaces and line breaks in the expressions.
function setDatetimeInput(element, t = new Date()){
function p(number){return number.toString().padStart(2, '0');}//number to 2 digit, 0 padded string
element.value = `${t.getFullYear()}-${p(t.getMonth()+1)}-${p(t.getDate())}T${p(t.getHours())}:${p(t.getMinutes())}`;
}
here's a simple way:
<input type="datetime-local" id="cal">
const currentDateTime = () => {
var tzoffset = new Date().getTimezoneOffset() * 60000; //offset in milliseconds
var localISOString = new Date(Date.now() - tzoffset)
.toISOString()
.slice(0, -1);
// convert to YYYY-MM-DDTHH:MM
const datetimeInputString = localISOString.substring(
0,
((localISOString.indexOf("T") | 0) + 6) | 0
);
console.log(datetimeInputString);
return datetimeInputString;
};
document.getElementById('cal').value = currentDateTime();

How to set first line of paragraph HEADING2 and rest normal text

I'm using Google Apps Script to iterate through my contacts and print name, address, email and phone numbers to a document.
I want the name in style "Heading 2" and the rest in style "Normal text".
How can I do this?
Here's what I've got so far but it makes the whole paragraph Heading 2, instead of just the name.
var myContacts = ContactsApp.findContactGroup('Some group').getContacts();
for (i=0; i < myContacts.length; i++)
{
var fullName = myContacts[i].getFullName();
if (fullName == '')
fullName = 'Anonymous';
var contactPara = doc.appendParagraph(fullName);
contactPara.setHeading(DocumentApp.ParagraphHeading.HEADING2);
var homeAddresses = myContacts[i].getAddresses(ContactsApp.Field.HOME_ADDRESS);
var homeAddress = '';
if (homeAddresses.length > 0)
contactPara.appendText('\n' + homeAddresses[0].getAddress());
contactPara.appendText('\n' + 'Email: ' + myContacts[i].getPrimaryEmail());
var mobilePhones = myContacts[i].getPhones(ContactsApp.Field.MOBILE_PHONE);
if (mobilePhones.length > 0)
contactPara.appendText('\n' + 'Mobile phone: ' + mobilePhones[0].getPhoneNumber());
var homePhones = myContacts[i].getPhones(ContactsApp.Field.HOME_PHONE);
if (homePhones.length > 0)
contactPara.appendText('\n' + 'Home phone: ' + homePhones[0].getPhoneNumber());
var workPhones = myContacts[i].getPhones(ContactsApp.Field.WORK_PHONE);
if (workPhones.length > 0)
contactPara.appendText('\n' + 'Work phone: ' + workPhones[0].getPhoneNumber());
}
Alternatively, if there's a better way to do what I want them please suggest it.
You initially set the style throughout the paragraph, and then add back the text.
You can create 2 section:
for the fullName
var headPara = doc.appendParagraph(fullName);
headPara.setHeading(DocumentApp.ParagraphHeading.HEADING2);
and new paragraph with normal style for content
var contactPara = doc.appendParagraph(' ').setHeading(DocumentApp.ParagraphHeading.NORMAL);
Result
var myContacts = ContactsApp.getContacts();
for (i=0; i < myContacts.length; i++)
{
var fullName = myContacts[i].getFullName();
if (fullName == '')
fullName = 'Anonymous';
var headPara = doc.appendParagraph(fullName);
headPara.setHeading(DocumentApp.ParagraphHeading.HEADING2);
var contactPara = doc.appendParagraph(' ').setHeading(DocumentApp.ParagraphHeading.NORMAL);
var homeAddresses = myContacts[i].getAddresses(ContactsApp.Field.HOME_ADDRESS);
var homeAddress = '';
if (homeAddresses.length > 0)
contactPara.appendText('\n' + homeAddresses[0].getAddress());
contactPara.appendText('\n' + 'Email: ' + myContacts[i].getPrimaryEmail());
var mobilePhones = myContacts[i].getPhones(ContactsApp.Field.MOBILE_PHONE);
if (mobilePhones.length > 0)
contactPara.appendText('\n' + 'Mobile phone: ' + mobilePhones[0].getPhoneNumber());
var homePhones = myContacts[i].getPhones(ContactsApp.Field.HOME_PHONE);
if (homePhones.length > 0)
contactPara.appendText('\n' + 'Home phone: ' + homePhones[0].getPhoneNumber());
var workPhones = myContacts[i].getPhones(ContactsApp.Field.WORK_PHONE);
if (workPhones.length > 0)
contactPara.appendText('\n' + 'Work phone: ' + workPhones[0].getPhoneNumber());
}

How to export (dump) WebSQL data

I'm working on a Chrome Extension that uses WebSQL to store historical data.
Being WebSQL, the DB is stored on the client.
I'd like to add an option to export/import such data so that the user can share/use this data with other users, or with other PCs.
These are my first steps on a client-only database, so I wonder how to do this.
I was thinking to convert the DB to a huge json string that the user can copy/paste but doesn't look very user-friendly.
Is there any better solution?
I got a single table dump solution working on a HTML5 database client I wrote a few days ago.
Check out http://html5db.desalasworks.com/script.js and scroll down to SqlClient.exportTable, this has an example that needs to be expanded to cover the whole database.
The steps are:
Step 1: Create the schema:
SELECT sql FROM sqlite_master
Step 2: Get a list of tables:
SELECT tbl_name from sqlite_master WHERE type = 'table'
Step 3: Loop through each of them and create an INSERT script with the results
transaction.executeSql("SELECT * FROM " + _tbl_name + ";", [],
function(transaction, results) {
if (results.rows) {
for (var i = 0; i < results.rows.length; i++) {
var row = results.rows.item(i);
var _fields = [];
var _values = [];
for (col in row) {
_fields.push(col);
_values.push('"' + row[col] + '"');
}
_exportSql += ";\nINSERT INTO " + _tbl_name + "(" + _fields.join(",") + ") VALUES (" + _values.join(",") + ")";
}
}
}
);
Hope this is useful.
UPDATE JAN 2016 - WHOLE DB EXPORT
I've got a JS websqldump library that you can download from github as well.
This one will export the whole database. Check out the code on:
https://github.com/sdesalas/websqldump
Usage as follows
websqldump.export({
database: 'NorthwindLite',
success: function(sql) {alert(sql);}
});
Not the most elegant way, yet most convenient.
Just paste the script in chrome debugger tools then call c(), and you should get the file.
var looongSQL = "";
var x = function (options) {
if (options.n < options.sqlTables.length) {
onTheMove.openLocalDatabase().transaction(
function (tx) {
var sqlStatement = "SELECT * FROM " + options.sqlTables[options.n];
tx.executeSql(sqlStatement, [],
function (tx, rslt) {
if (rslt.rows) {
for (var m = 0; m < rslt.rows.length; m++) {
var dataRow = rslt.rows.item(m);
var _fields = [];
var _values = [];
for (col in dataRow) {
_fields.push(col);
_values.push('"' + dataRow[col] + '"');
}
looongSQL += "INSERT INTO " + options.sqlTables[options.n] + "(" + _fields.join(",") + ") VALUES (" + _values.join(",") + ");\n";
}
}
options.n++;
x(options);
}
);
});
}else
{
document.location = 'data:Application/octet-stream,' +
encodeURIComponent(looongSQL);
}
};
var c = function () {
onTheMove.openLocalDatabase().transaction(
function (transaction) {
transaction.executeSql("SELECT sql FROM sqlite_master;", [],
function (transaction, results) {
var sqlStatements = [];
if (results.rows) {
for (var i = 0; i < results.rows.length; i++) {
console.log(results.rows.item(i));
var row = results.rows.item(i);
if (row.sql != null && row.sql.indexOf("CREATE TABLE ") != -1 && row.sql.indexOf("__") == -1) {
var tableName = row.sql.replace("CREATE TABLE ", "").split(/ |\(/)[0];
sqlStatements.push('DROP TABLE IF EXISTS ' + tableName);
}if(row.sql != null && row.sql.indexOf("__") == -1){
sqlStatements.push(row.sql);}
}
}
for (var j = 0; j < sqlStatements.length; j++) {
if (sqlStatements[j] != null) {
looongSQL += sqlStatements[j] + ';\r\n';
}
}
transaction.executeSql("SELECT tbl_name from sqlite_master WHERE type = 'table'", [],
function (transaction, res) {
var sqlTables = [];
for (var k = 0; k < res.rows.length; k++) {
if (res.rows.item(k).tbl_name.indexOf("__") == -1) {
sqlTables.push(res.rows.item(k).tbl_name);
}
}
x({
sqlTables: sqlTables,
n: 0
});
});
}
);
});
};
Another version that exports it as JSON
var looongSQL = "[\n";
var stringidiedLocalStorage = JSON.stringify(JSON.stringify(localStorage));
looongSQL += "/* 1 */ " + stringidiedLocalStorage + ",\n";
var x = function (options) {
if (options.n < options.sqlTables.length) {
onTheMove.openLocalDatabase().transaction(
function (tx) {
var sqlStatement = "SELECT * FROM " + options.sqlTables[options.n];
tx.executeSql(sqlStatement, [],
function (tx, rslt) {
if (rslt.rows && rslt.rows.length > 0) {
var _fields = [];
for (var col in rslt.rows.item(0)) {
_fields.push(col);
}
var insertTableSQL = "\"INSERT INTO " + options.sqlTables[options.n] + "(" + _fields.join(",") + ") ";
looongSQL += "/* " + options.count + " */ " + insertTableSQL;
for (var m = 0; m < rslt.rows.length; m++) {
var dataRow = rslt.rows.item(m);
var _values = [];
for (var col in dataRow) {
_values.push('\'' + dataRow[col] + '\'');
}
looongSQL += "SELECT " + _values.join(",");
if (m < rslt.rows.length - 1 && (m % 499 != 0 || m == 0)) {
looongSQL += " UNION ALL ";
}
if (m % 499 == 0 && m != 0) {
options.count++;
looongSQL += "\",\r\n/* " + options.count + " */ " + insertTableSQL;
}
}
looongSQL += "\",\r\n";
options.count++;
}
options.n++;
x(options);
}
);
});
} else {
looongSQL += ']';
document.location = 'data:Application/octet-stream,' +
encodeURIComponent(looongSQL);
}
};
var c = function () {
onTheMove.openLocalDatabase().transaction(
function (transaction) {
transaction.executeSql("SELECT sql FROM sqlite_master;", [],
function (transaction, results) {
var sqlStatements = [];
var count = 2;
if (results.rows) {
for (var i = 0; i < results.rows.length; i++) {
console.log(results.rows.item(i));
var row = results.rows.item(i);
if (row.sql != null && row.sql.indexOf("CREATE ") != -1) {
var objectType = row.sql.replace("CREATE ", "").split(/ |\(/)[0];
if (row.sql.indexOf("CREATE " + objectType + " ") != -1 && row.sql.indexOf("__") == -1) {
var objectName = row.sql.replace("CREATE " + objectType + " ", "").split(/ |\(/)[0];
sqlStatements.push('/* ' + count + ' */ "DROP ' + objectType + ' IF EXISTS ' + objectName + '"');
count++;
}
if (row.sql != null && row.sql.indexOf("__") == -1) {
sqlStatements.push('/* ' + count + ' */ "' + row.sql.replace(/(\r\n|\n|\r)/gm, " ") + '"');
count++;
}
}
}
}
for (var j = 0; j < sqlStatements.length; j++) {
if (sqlStatements[j] != null) {
looongSQL += sqlStatements[j] + ',\r\n';
}
}
transaction.executeSql("SELECT tbl_name from sqlite_master WHERE type = 'table'", [],
function (transaction, res) {
var sqlTables = [];
for (var k = 0; k < res.rows.length; k++) {
if (res.rows.item(k).tbl_name.indexOf("__") == -1) {
sqlTables.push(res.rows.item(k).tbl_name);
}
}
x({
sqlTables: sqlTables,
n: 0,
count: count
});
});
}
);
});
};