Related
In Google Apps Script, I'm using some code I adapted from a project I found. It calls an API endpoint and lays out the data in a spreadsheet. I was able to get it to loop through multiple API calls in order to pull data from multiple documents. However, the code breaks if it finds a document with no data. In this case, I want it to just skip that iteration and start again at the next cardIds.forEach iteration.
Here's a link to a sample sheet.
I tried:
if (response == "") {
return;
}
But no dice. Here's the full code (also it's very inefficient. I have params on their twice because I'm not sure how to consolidate them with all the functions inside other functions..)
const DATA_SHEET = "Data";
const USERNAME_CELL = "B1";
const API_TOKEN_CELL = "B2";
const CARD_ID_COL = "Cards!B:B"
const DATA_RANGE = "A4:C"
var getNextPage = function(response) {
var url = response.getAllHeaders().Link;
if (!url) {
return "";
}
return /<([^>]+)/.exec(url)[1];
};
var getIt = function(path, username, apiToken) {
var params = {
"method": "GET",
"muteHttpExceptions": true,
"headers": {
"Content-Type": "application/json",
"Authorization": "Basic " + Utilities.base64Encode(username + ":" + apiToken),
"x-guru-application": "spreadsheet",
"X-Amzn-Trace-Id": "GApp=spreadsheet"
}
};
var response = UrlFetchApp.fetch(path, params);
var data = JSON.parse(response.getContentText());
// check if there's another page of results.
var nextPage = getNextPage(response);
if (nextPage) {
data.nextPage = nextPage;
};
return data;
};
var getItAll = function(url, username, apiToken, callback) {
var data = [];
while (url) {
var page = getIt(url, username, apiToken);
var startIndex = data.length;
page.forEach(function(a) {
data.push(a);
});
// get the url of the next page of results.
url = page.nextPage;
if (callback) {
// the second parameter is whether we're done or not.
// if there's a url for the next page that means we're not done yet.
callback(data, startIndex, page.length, url ? false : true);
}
}
return data;
};
function eachCard() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(DATA_SHEET);
sheet.getRange(DATA_RANGE).clearContent();
var username = sheet.getRange(USERNAME_CELL).getValue();
var apiToken = sheet.getRange(API_TOKEN_CELL).getValue();
var cardIds = sheet.getRange(CARD_ID_COL).getValues().flat().filter(r=>r!="");
var params = {
"method": "GET",
"muteHttpExceptions": true,
"headers": {
"Content-Type": "application/json",
"Authorization": "Basic " + Utilities.base64Encode(username + ":" + apiToken),
"x-guru-application": "spreadsheet",
"X-Amzn-Trace-Id": "GApp=spreadsheet"
}
};
cardIds.forEach(function (cardId) {
var fullUrl = "https://api.getguru.com/api/v1/cards/"+cardId+"/comments"
var cardComments = getItAll(fullUrl, username, apiToken);
var fullUrl = "https://api.getguru.com/api/v1/cards/"+cardId+"/extended"
var response = UrlFetchApp.fetch(fullUrl, params);
var cardData = JSON.parse(response.getContentText());
var sheetLastRow = sheet.getLastRow();
var range = sheet.getRange("A" + sheetLastRow);
if (range.getValue() !== "") {
var lastRow = sheetLastRow+1;
} else {
var lastRow = range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow()+1;
}
cardComments.forEach(function(comment, commentIndex) {
sheet.getRange(lastRow + commentIndex, 1).setValue(comment.dateCreated);
sheet.getRange(lastRow + commentIndex, 1 + 1).setValue(comment.content);
sheet.getRange(lastRow + commentIndex, 1 + 2).setValue(cardData.preferredPhrase);
});
});
}
EDIT: I have added the response from OMDB
{Response: "False", Error: "Invalid API key!"}
Error: "Invalid API key!"
Response: "False"
I am new to web development and I am trying to build a chrome extension that displays imdb scores on netflix. I am using the OMDB API to do this. At first I got the following error:
"Mixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ''. This request has been blocked; the content must be served over HTTPS.",
however I just changed the "http" in the url to "https" and it went away. However, now I am getting a 401 error, which I think means my access is being denied.
This is a picture of the full error
Here is the code for the extension
Manifest file:
{
"manifest_version": 2,
"name": "1_ratings_netflix",
"version": "0.1",
"description": "Display imdb ratings on netflix",
"content_scripts": [
{
"matches": [
"https://www.netflix.com/*", "https://www.omdbapi.com/*"
],
"js": ["content.js"]
}
],
"icons": { "16": "icon16.png", "48":"icon48.png"},
"permissions": [
"https://www.netflix.com/*", "https://www.omdbapi.com/*"
]
}
Content File:
function fetchMovieNameYear() {
var synopsis = document.querySelectorAll('.jawBone .jawbone-title-link');
if (synopsis === null) {
return;
}
var logoElement = document.querySelectorAll('.jawBone .jawbone-title-link .title');
if (logoElement.length === 0)
return;
logoElement = logoElement[logoElement.length - 1];
var title = logoElement.textContent;
if (title === "")
title = logoElement.querySelector(".logo").getAttribute("alt");
var titleElement = document.querySelectorAll('.jawBone .jawbone-title-link .title .text').textContent;
var yearElement = document.querySelectorAll('.jawBone .jawbone-overview-info .meta .year');
if (yearElement.length === 0)
return;
var year = yearElement[yearElement.length - 1].textContent;
var divId = getDivId(title, year);
var divEl = document.getElementById(divId);
if (divEl && (divEl.offsetWidth || divEl.offsetHeight || divEl.getClientRects().length)) {
return;
}
var existingImdbRating = window.sessionStorage.getItem(title + ":" + year);
if ((existingImdbRating !== "undefined") && (existingImdbRating !== null)) {
addIMDBRating(existingImdbRating, title, year);
} else {
makeRequestAndAddRating(title, year)
}
};
function addIMDBRating(imdbMetaData, name, year) {
var divId = getDivId(name, year);
var divEl = document.getElementById(divId);
if (divEl && (divEl.offsetWidth || divEl.offsetHeight || divEl.getClientRects().length)) {
return;
}
var synopsises = document.querySelectorAll('.jawBone .synopsis');
if (synopsises.length) {
var synopsis = synopsises[synopsises.length - 1];
var div = document.createElement('div');
var imdbRatingPresent = imdbMetaData && (imdbMetaData !== 'undefined') && (imdbMetaData !== "N/A");
var imdbVoteCount = null;
var imdbRating = null;
var imdbId = null;
if (imdbRatingPresent) {
var imdbMetaDataArr = imdbMetaData.split(":");
imdbRating = imdbMetaDataArr[0];
imdbVoteCount = imdbMetaDataArr[1];
imdbId = imdbMetaDataArr[2];
}
var imdbHtml = 'IMDb rating : ' + (imdbRatingPresent ? imdbRating : "N/A") + (imdbVoteCount ? ", Vote Count : " + imdbVoteCount : "");
if (imdbId !== null) {
imdbHtml = "<a target='_blank' href='https://www.imdb.com/title/" + imdbId + "'>" + imdbHtml + "</a>";
}
div.innerHTML = imdbHtml;
div.className = 'imdbRating';
div.id = divId;
synopsis.parentNode.insertBefore(div, synopsis);
}
}
function getDivId(name, year) {
name = name.replace(/[^a-z0-9\s]/gi, '');
name = name.replace(/ /g, '');
return "aaa" + name + "_" + year;
}
function makeRequestAndAddRating(name, year) {
var url = "https://www.omdbapi.com/?i=tt3896198&apikey=**{API_KEY}**" + encodeURI(name)
+ "&y=" + year + "tomatoes=true";
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function () {
if (xhr.status === 200) {
var apiResponse = JSON.parse(xhr.responseText);
var imdbRating = apiResponse["imdbRating"];
var imdbVoteCount = apiResponse["imdbVotes"];
var imdbId = apiResponse["imdbID"];
var imdbMetaData = imdbRating + ":" + imdbVoteCount + ":" + imdbId;
window.sessionStorage.setItem(name + ":" + year, imdbMetaData);
window.sessionStorage.setItem("metaScore:" + name + ":" + year, metaScore)
window.sessionStorage.setItem("rotten:" + name + ":" + year, rottenRating);
addIMDBRating(imdbMetaData, name, year);
addRottenRating(rottenRating, name, year);
addMetaScore(metaScore, name, year);
}
};
xhr.send();
}
if (window.sessionStorage !== "undefined") {
var target = document.body;
// create an observer instance
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
window.setTimeout(fetchMovieNameYear, 5);
});
});
// configuration of the observer:
var config = {
attributes: true,
childList: true,
characterData: true
};
observer.observe(target, config);
}
It would be helpful for you to post the request and response for OMDB (you can find them in the "Network" tab in dev tools).
One thing that triggers CORS (cross-origin requests) errors is specifying a content type other than application/x-www-form-urlencoded, multipart/form-data or text/plain. If I recall correctly, the OMDB API will return a JSON response even without specifying the content type of the request, so you should try removing the line:
xhr.setRequestHeader('Content-Type', 'application/json');
More on "Simple Requests" which do not trigger CORS: https://javascript.info/fetch-crossorigin#simple-requests
You also need to get an API key (https://www.omdbapi.com/apikey.aspx) and replace
**{API_KEY}** in your code with the key. You also need to add the t key to your querystring or the title will be appended to your API key.
var url = "https://www.omdbapi.com/?i=tt3896198&apikey=**{API_KEY}**" + "&t="
+ encodeURI(name) + "&y=" + year + "tomatoes=true";
I am trying to send data from a javascript function that generates a random string upon the page loading to a Django view. I don't know how to structure the script tag to send the data after the page has loaded and the views.py to receive the data. I am new to javascript and don't quite know how to go about this. I appreciate any help provided.
index.html
<script>
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
console.log(makeid(9));
</script>
You can use ajax to send data to Django view like following code.
javascript:
function makeid(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
$.ajax({
type: "GET",
url: '/my_def_in_view',
data: {
"result": result,
},
dataType: "json",
success: function (data) {
// any process in data
alert("successfull")
},
failure: function () {
alert("failure");
}
});
}
urls.py:
urlpatterns = [
url(r'^my_def_in_view$', views.my_def_in_view, name='my_def_in_view'),
...
]
views.py:
def my_def_in_view(request):
result = request.GET.get('result', None)
# Any process that you want
data = {
# Data that you want to send to javascript function
}
return JsonResponse(data)
If it was successfull it goes back to "success" part.
you can do that in two ways:
Tradicional with ajax
Websockets: With django channels
If you want to send a bit of information, an ajax request is enough, you have to set and address and a view to receive the POST or GET ajax request.
I recommend to you use pure JS, not jquery
For example, this is a call to refresh a captcha image....
/*Agregar boton refresh al lado del campo input*/
let captcha_field =
document.getElementById('captcha-field-registro_1').parentNode;
let refresh_button=document.createElement('BUTTON');
refresh_button.addEventListener('click',refresh_captcha)
refresh_button.innerHTML = "Refrescar Captcha"; // Insert text
captcha_field.appendChild(refresh_button);
let url_captcha= location.protocol + "//" +
window.location.hostname + ":" +
location.port + "/captcha/refresh/";
let id_captcha_0="captcha-field-registro_0"
function refresh_captcha(){
let xhr = new XMLHttpRequest();
xhr.open('GET', url_captcha, true);
xhr.onload = function recv_captcha_load(event){
console.log("event received", event,
"state",xhr.readyState);
let data_txt = xhr.responseText;
let data_json = JSON.parse(data_txt);
console.log("Data json", data_json);
if (xhr.readyState==4){
if (xhr.status==200){
console.log("LOAD Se ha recibido esta informaciĆ³n", event);
let captcha_img=document.getElementsByClassName('captcha')[0];
console.log("Catpcha img dom", captcha_img);
captcha_img.setAttribute('src', data_json['image_url'])
document.getElementById(id_captcha_0).value=data_json['key']
}
else{
console.log("Error al recibir")
}
}
};
var csrftoken = getCookie('csrftoken');
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader("X-CSRFToken", csrftoken);
xhr.send();
}
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
let cookie = cookies[i].trim();
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
I'm having a few problems with this, so I'll try to keep it simple. What's happening in the first script is a new Google doc file gets made from a copy of a "master" doc I've defined, which gets its data populated from Form submissions, and that new copy is ultimately moved to a Folder on my Drive. The second script is supposed to send that copied file to the Google Cloud Print. The first script works perfect; I have it triggered on a form submit. The second script works by itself, but only when I explicitly define the master doc ID in the "content" section. Because with each Form submission a new doc gets made, I was having trouble integrating the new doc's ID with the second script. Right now, I tried pulling from the var file, but that's not working. I might have a syntax issue.
My other problem is I need to merge my second script with the first, in a way that gets triggered on the same Form Submit and probably execute after the PDF creation and Email send, but before it gets moved to the folder.
Any help or advice would be greatly appreciated.
And I've removed some of my IDs and sensitive information where you only see double quotes.
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var email_address = "";
var job_name = e.values[1];
var ship_to = e.values[11];
var address = e.values[12];
var order_count = e.values[7];
var program = e.values[2];
var workspace = e.values[3];
var offer = e.values[4];
var sort_1 = e.values[5];
var sort_2 = e.values[6];
var image_services = e.values[9];
var print_services = e.values[10];
var priority = e.values[13];
var notes = e.values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(file, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": file,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
**
Update 8/14 with Sandy Good's suggestion:
**
I've attempted to do what you suggested, but now it's not creating the doc or sending to the cloud print. Any thoughts?
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
function createNewDoc(values) {
var email_address = "";
var job_name = e.values[1];
var ship_to = e.values[11];
var address = e.values[12];
var order_count = e.values[7];
var program = e.values[2];
var workspace = e.values[3];
var offer = e.values[4];
var sort_1 = e.values[5];
var sort_2 = e.values[6];
var image_services = e.values[9];
var print_services = e.values[10];
var priority = e.values[13];
var notes = e.values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(file, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": file,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
// When Form Gets submitted
function onFormSubmit(e) {
//Get information from form and set as variables
var values = e.values;
createNewDoc(values);
printGoogleDocument(file, docName);
}
Not sure if that is what you are after, but the easiest way to execute functions consecutively is to pass a callback function as an argument to your function.
Here's the list of simple functions assigned to variables.
var addFive = function(number, callback){
number += 5;
if (callback) {
return callback(number);
}
return number;
}
var multiplyByFive = function(number, callback){
number *= 5;
if (callback) {
return callback(number);
}
return number;
}
var subtractFive = function(number, callback){
number -= 5;
if (callback) {
return callback(number);
}
return number;
}
You can then just chain call them like this.
function test() {
var result = addFive(7, function(number) {
return multiplyByFive(number, function(number){
return subtractFive(number);
});
});
Logger.log(result); //logs (7 + 5) * 5 - 5 = 55
}
Of course, if your functions only perform operations like creating files and don't return values, feel free to omit the 'return' statement.
I have more questions in regards to this project, but I think this specific question has been answered, so here's the final code for future reference.
// Work Order
// Get template from Google Docs and name it
var docTemplate = ""; // *** replace with your template ID ***
var docName = "Work Order";
function addDates() {
var date = new Date(); // your form date
var holiday = ["09/04/2017", "10/09/2017", "11/23/2017", "12/24/2017", "12/25/2017", "01/01/2018"]; //Define holiday dates in MM/dd/yyyy
var days = 5; //No of days you want to add
date.setDate(date.getDate());
var counter = 0;
if (days > 0) {
while (counter < days) {
date.setDate(date.getDate() + 1);
var check = date.getDay();
var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy"));
if (check != 0 && check != 6 && holidayCheck == -1) {
counter++;
}
}
}
Logger.log(date) //for this example will give 08/16/2017
return date;
}
function createNewDoc(values) {
//Get information from form and set as variables
var email_address = "";
var job_name = values[1];
var ship_to = values[11];
var address = values[12];
var order_count = values[7];
var program = values[2];
var workspace = values[3];
var offer = values[4];
var sort_1 = values[5];
var sort_2 = values[6];
var image_services = values[9];
var print_services = values[10];
var priority = values[13];
var notes = values[14];
var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy");
var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy");
// Get document template, copy it as a new temp doc, and save the Doc's id
var copyId = DriveApp.getFileById(docTemplate)
.makeCopy(docName + ' for ' + job_name)
.getId();
// Open the temporary document
var copyDoc = DocumentApp.openById(copyId);
// Get the document's body section
var copyBody = copyDoc.getActiveSection();
// Replace place holder keys,in our google doc template
copyBody.replaceText('keyJobName', job_name);
copyBody.replaceText('keyShipTo', ship_to);
copyBody.replaceText('keyAddress', address);
copyBody.replaceText('keyOrderCount', order_count);
copyBody.replaceText('keyProgram', program);
copyBody.replaceText('keyWorkspace', workspace);
copyBody.replaceText('keyOffer', offer);
copyBody.replaceText('keySort1', sort_1);
copyBody.replaceText('keySort2', sort_2);
copyBody.replaceText('keyImageServices', image_services);
copyBody.replaceText('keyPrintServices', print_services);
copyBody.replaceText('keyPriority', priority);
copyBody.replaceText('keyNotes', notes);
copyBody.replaceText('keyDate', formattedDate);
copyBody.replaceText('keyDue', expirationDate);
// Save and close the temporary document
copyDoc.saveAndClose();
// Convert temporary document to PDF by using the getAs blob conversion
var pdf = DriveApp.getFileById(copyId).getAs("application/pdf");
// Attach PDF and send the email
var subject = "New Job Submission";
var body = "Here is the work order for " + job_name + "";
MailApp.sendEmail(email_address, subject, body, {
htmlBody: body,
attachments: pdf
});
// Move file to folder
var file = DriveApp.getFileById(copyId);
DriveApp.getFolderById("").addFile(file);
file.getParents().next().removeFile(file);
}
function printGoogleDocument(file, docName) {
// For notes on ticket options see https://developers.google.com/cloud-print/docs/cdd?hl=en
var ticket = {
version: "1.0",
print: {
color: {
type: "STANDARD_COLOR"
},
duplex: {
type: "NO_DUPLEX"
},
}
};
var payload = {
"printerid": "",
"content": file,
"title": docName,
"contentType": "google.kix", // allows you to print google docs
"ticket": JSON.stringify(ticket),
};
var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', {
method: "POST",
payload: payload,
headers: {
Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken()
},
"muteHttpExceptions": true
});
// If successful, should show a job here: https://www.google.com/cloudprint/#jobs
response = JSON.parse(response);
if (response.success) {
Logger.log("%s", response.message);
} else {
Logger.log("Error Code: %s %s", response.errorCode, response.message);
}
return response;
}
// When Form Gets submitted
function onFormSubmit(e) {
var values = e.values;
createNewDoc(values);
printGoogleDocument(file, docName);
}
I am developing android app using phonegap 1.5.0
App stores data in local database and synchronizes using web services.
I am using one button click to call synchronize data JavaScript function.
What I have found is:
This synch button's on click event fires twice.
Single record is getting uploaded twice and the uploaded time is same in the server database.
How to avoid this?
Thanks
EDIT:
Hey everyone, sorry for the delay in reply; was bit busy with some priority work.
Calling SyncData() function on click of button.
Here is the code:
document.addEventListener("DOMContentLoaded", onDeviceReady, false);
var db;
var maxrecords = 0;
var recordsprocessed = 0;
var urlstart = "http://www.mywebsite.com/";
function onDeviceReady() {
db = window.openDatabase("LocalDB", "1.0", "PhoneGap Demo", 50 * 1024 * 1024);
}
function SyncData() {
maxrecords = 0;
recordsprocessed = 0;
db.transaction(queryDB, errorCB, successCB);
}
function queryDB(tx) {
var entriestoupload = 0;
var profimagetoupload = 0;
//check how many entries are to be synchronized
tx.executeSql('SELECT count(*) as cnt FROM tblEntries WHERE IsUploaded=0', [], function(tx, results) {
entriestoupload = parseInt(results.rows.item(0)['cnt']);
//check how many profile images are to be uploaded
tx.executeSql('SELECT count(*) as cnt FROM tblEntries WHERE IsProfileImageUploaded=0', [], function(tx, results) {
profimagetoupload = parseInt(results.rows.item(0)['cnt']);
//synch proceeds if there is any record which is not sychronised
if (entriestoupload > 0 || profimagetoupload > 0) {
var dataMsg = '';
var porofimgMsg = '';
if (entriestoupload > 0) dataMsg = entriestoupload + ' entry, ';
if (profimagetoupload > 0) porofimgMsg = profimagetoupload + ' profile image ';
// give user exact info about what will be synchronized
if (confirm(dataMsg + porofimgMsg + ' are not synchronized.\n Do you want to start synchronisation? \n Please wait till synch successfull message appears.')) {
//start synchronisation
tx.executeSql('SELECT * FROM tblEntries ORDER BY DateOfRegistration DESC', [], uploadData, errorCB);
}
} else {
alert('All records are already Synchronized.');
}
}, errorCB);
}, errorCB);
}
function uploadData(tx, results) {
var len = results.rows.length;
maxrecords = len;
var Synched = 0;
if (len > 0) {
for (var i = 0; i < len; i++) {
var row = results.rows.item(i);
var LocalId = row['LocalId'];
var DateOfRegistration = getDateTimeformatMySql(String(row['DateOfRegistration']));
var DateOption = getDateTimeformatMySql(String(row['DateOption']));
var VolunteerId = row['VolunteerId'];
var IsUploaded = row['IsUploaded'];
var LiveId = row['LiveId'];
var ProfileImagePath = row['ProfileImagePath'];
var IsProfileImageUploaded = parseInt(row['IsProfileImageUploaded']);
var params = null;
var weburl = null;
if (IsUploaded == 0) {
//set parameters for web service
params = "LocalId=" + LocalId + "&OrganizationName=" + row['OrganizationName'] + "&FirstName=" + row['FirstName'] + "&LastName=" + row['LastName'] + "&EmailAddress=" + row['EmailAddress'] + "&MobileNumber=" + row['MobileNumber'] + "&Country=" + row['Country'] + "&State=" + row['State'] + "&City=" + row['City'] + "&Lattitude=" + row['Lattitude'] + "&Longitude=" + row['Longitude'] + "&Website=" + row['Website'] + "&DateOption=" + DateOption + "&TimeOption=" + row['TimeOption'] + "&NumberOption=" + row['NumberOption'] + +"&RadioOption=" + row['RadioOption'] + "&Details=" + row['Details'] + "&CheckBoxoption=" + row['CheckBoxoption'] + "&DropDownOption=" + row['DropDownOption'] + "&DateOfRegistration=" + DateOfRegistration + "&VolunteerId=" + VolunteerId;
//web service url
weburl = urlstart + "mywebserviceurl";
try {
$.ajax({
async: false,
type: "POST",
url: weburl,
data: params,
dataType: "json",
success: function(data, textStatus, jqXHR) {
if (data.Success == "0") {
alert('web services error:\n' + data.Message);
}
if (data.Success == "1") {
try {
LiveId = parseInt(String(data.LiveId));
IsUploaded = 1;
//Update local database to set IsUploaded and LiveId
tx.executeSql("UPDATE tblEntries SET LiveId= " + LiveId + " ,IsUploaded=1 WHERE LocalId= " + LocalId, [], function(tx, results) {
Synched = Synched + 1; /*alert(LiveId);*/
}, errorCB);
//check if profile image exists or not
if (ProfileImagePath != undefined) {
uploadImage(LiveId, LocalId, ProfileImagePath, '1', '');
}
} catch (e) {
}
}
},
error: function() {
alert("There was an error loading the feed");
}
});
} catch (e) {
}
} else {
//check if data is uploaded and image is not uploaded
if (IsProfileImageUploaded == 0 && ProfileImagePath != undefined) {
uploadImage(LiveId, ShopId, ProfileImagePath, '1', '');
}
}
}
}
} // end of querySucess function
//function to upload image
function uploadImage(LiveId, LocalId, ImagePath, UploadType, CreationDate) {
try {
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = ImagePath;
options.mimeType = "image/jpg";
var params = new Object();
params.LiveId = LiveId;
params.LocalId = LocalId;
params.UploadType = UploadType;
params.CreationDate = CreationDate;
options.params = params;
options.chunkedMode = false;
var ft = new FileTransfer();
var url = urlstart + "mywebservice_url_to_uploadimage";
ft.upload(ImagePath, url, win, fail, options, false);
} catch (e) {
console.error("Survey App Err :" + e.message);
}
}
function win(r) {
var jsonresponse = r.response.substring(r.response.indexOf('{'), r.response.indexOf('}') + 1);
var obj = $.parseJSON(jsonresponse);
if (obj.Success == "1") {
var LocalId = parseInt(obj.LocalId);
var UploadType = parseInt(obj.UploadType);
if (UploadType == 1) {
db.transaction(function(tx) {
tx.executeSql("UPDATE tblEntries SET IsProfileImageUploaded=1 WHERE LocalId=?", [LocalId], function(tx, results) {
}, errorCB);
}, errorCB, successCB);
}
}
}
function fail(error) {
alert("There was an error uploading image");
}
Only solution i found for this is to use tap instead of click and it will solve the problem.