Retrieve Google Calendar events using API v3 in javascript - javascript

last year I was using the code found here http://gdata-javascript-client.googlecode.com/svn/trunk/samples/calendar/simple_sample/simple_sample.html to retrieve all events from "now" of a public Google Calendar and then display the results in a webpage.
I modified that code to match my needs (see the code below).
Now, with API v3, the code doesn't work anymore and I'm not able to understand which lines of the code are deprecated and how to update them.
Could please someone help me with this code?
Thank you so much :-)
<body>
<script type="text/javascript" src="http://www.google.com/jsapi?key=YOUR_KEY_HERE"></script>
<script type="text/javascript">
/* Loads the Google data JavaScript client library */
google.load("gdata", "2.x");
function init() {
// init the Google data JS client library with an error handler
google.gdata.client.init(handleGDError);
// load the code.google.com calendar
loadMyCalendar();
}
/**
* Loads the Google Event Calendar
*/
function loadMyCalendar() {
loadCalendarByAddress('MY_ADDRESS#gmail.com'); /* address here
}
/**
* Adds a leading zero to a single-digit number. Used for displaying dates.
*/
function padNumber(num) {
if (num <= 9) {
return "0" + num;
}
return num;
}
/**
* Determines the full calendarUrl based upon the calendarAddress
* argument and calls loadCalendar with the calendarUrl value.
*
* #param {string} calendarAddress is the email-style address for the calendar
*/
function loadCalendarByAddress(calendarAddress) {
var calendarUrl = 'https://www.google.com/calendar/feeds/' +
calendarAddress +
'/public/full';
loadCalendar(calendarUrl);
}
function loadCalendar(calendarUrl) {
var service = new
google.gdata.calendar.CalendarService('gdata-js-client-samples-simple');
var query = new google.gdata.calendar.CalendarEventQuery(calendarUrl);
query.setOrderBy('starttime');
query.setSortOrder('ascending');
query.setFutureEvents(true);
query.setSingleEvents(true);
query.setMaxResults(100);
service.getEventsFeed(query, listEvents, handleGDError);
}
/**
* Callback function for the Google data JS client library to call when an error
* occurs during the retrieval of the feed. Details available depend partly
* on the web browser, but this shows a few basic examples. In the case of
* a privileged environment using ClientLogin authentication, there may also
* be an e.type attribute in some cases.
*
* #param {Error} e is an instance of an Error
*/
function handleGDError(e) {
document.getElementById('jsSourceFinal').setAttribute('style',
'display:none');
if (e instanceof Error) {
/* alert with the error line number, file and message */
alert('Error at line ' + e.lineNumber +
' in ' + e.fileName + '\n' +
'Message: ' + e.message);
/* if available, output HTTP error code and status text */
if (e.cause) {
var status = e.cause.status;
var statusText = e.cause.statusText;
alert('Root cause: HTTP error ' + status + ' with status text of: ' +
statusText);
}
} else {
alert(e.toString());
}
}
/**
* Callback function for the Google data JS client library to call with a feed
* of events retrieved.
*
* Creates an unordered list of events in a human-readable form. This list of
* events is added into a div called 'events'. The title for the calendar is
* placed in a div called 'calendarTitle'
*
* #param {json} feedRoot is the root of the feed, containing all entries
*/
function listEvents(feedRoot) {
var entries = feedRoot.feed.getEntries();
var eventDiv = document.getElementById('events');
if (eventDiv.childNodes.length > 0) {
eventDiv.removeChild(eventDiv.childNodes[0]);
}
var ul = document.createElement('ul');
/* set the calendarTitle div with the name of the calendar */
/*document.getElementById('calendarTitle').innerHTML =
"Calendar: " + feedRoot.feed.title.$t + "<br/><br/>";*/
/* loop through each event in the feed */
var len = entries.length;
for (var i = 0; i < len; i++) {
var entry = entries[i];
/* contenuto e titolo sono invertiti */
var cont = entry.getTitle().getText();
var title = entry.getContent().getText(); /* get description notes */
/* only events containing WORD_1 &/or WORD_2 & not containing '?' */
if(cont.indexOf('?') == -1 && (cont.indexOf('WORD_1') > -1 || cont.indexOf('WORD_2') > -1)){
var whereIs = entry.getLocations()[0].getValueString();
var startDateTime = null;
var startJSDate = null;
var times = entry.getTimes();
if (times.length > 0) {
startDateTime = times[0].getStartTime();
startJSDate = startDateTime.getDate();
}
var entryLinkHref = null;
if (entry.getHtmlLink() != null) {
entryLinkHref = entry.getHtmlLink().getHref();
}
var day = padNumber(startJSDate.getDate());
var month = padNumber(startJSDate.getMonth() + 1);
var dateString = day + "/" + month + "/" + startJSDate.getFullYear();
if (title.indexOf(' - ') > -1) {
cont = title.substring(0, title.indexOf(' - ')+3) + cont + " # " + whereIs;
title = title.substring(title.indexOf(' - ')+3);
} else cont = "h_:_ - " + cont + " # " + whereIs;
var li = document.createElement('li');
/* if we have a link to the event, create an 'a' element */
if (entryLinkHref != null) {
entryLink = document.createElement('a');
entryLink.setAttribute('href', entryLinkHref);
li.appendChild(document.createTextNode(dateString + ' - '));
entryLink.appendChild(document.createTextNode(title));
li.appendChild(entryLink);
} else {
li.appendChild(document.createTextNode(dateString + ' - ' + title));
}
var p = document.createElement("p");
var lo = document.createElement('lo');
lo.appendChild(document.createTextNode(cont));
li.style.fontSize = "25px";
lo.style.fontSize = "15px";
/* append the list item onto the unordered list */
ul.appendChild(li);
ul.appendChild(lo);
ul.appendChild(p);
}
eventDiv.appendChild(ul);
}
}
google.setOnLoadCallback(init);
</script>
<p id="events">LOADING CALENDAR . . . . . . . . . .</p>
</body>

SOLVED :-) here's the javascript code to access and show upcoming events of PUBLIC google Calendars, with Google Calendar API v3.
<html>
<head>
</head>
<body bgcolor="black" text="white" link="#00ffff" vlink="green" alink="yellow">
<script>
var clientId = 'YOUR_CLIENT_ID HERE'; //choose web app client Id, redirect URI and Javascript origin set to http://localhost
var apiKey = 'YOUR_APIKEY_HERE'; //choose public apiKey, any IP allowed (leave blank the allowed IP boxes in Google Dev Console)
var userEmail = "YOUR_ADDRESS#gmail.com"; //your calendar Id
var userTimeZone = "YOUR_TIME_ZONE_HERE"; //example "Rome" "Los_Angeles" ecc...
var maxRows = 10; //events to shown
var calName = "YOUR CALENDAR NAME"; //name of calendar (write what you want, doesn't matter)
var scopes = 'https://www.googleapis.com/auth/calendar';
//--------------------- Add a 0 to numbers
function padNum(num) {
if (num <= 9) {
return "0" + num;
}
return num;
}
//--------------------- end
//--------------------- From 24h to Am/Pm
function AmPm(num) {
if (num <= 12) { return "am " + num; }
return "pm " + padNum(num - 12);
}
//--------------------- end
//--------------------- num Month to String
function monthString(num) {
if (num === "01") { return "JAN"; }
else if (num === "02") { return "FEB"; }
else if (num === "03") { return "MAR"; }
else if (num === "04") { return "APR"; }
else if (num === "05") { return "MAJ"; }
else if (num === "06") { return "JUN"; }
else if (num === "07") { return "JUL"; }
else if (num === "08") { return "AUG"; }
else if (num === "09") { return "SEP"; }
else if (num === "10") { return "OCT"; }
else if (num === "11") { return "NOV"; }
else if (num === "12") { return "DEC"; }
}
//--------------------- end
//--------------------- from num to day of week
function dayString(num){
if (num == "1") { return "mon" }
else if (num == "2") { return "tue" }
else if (num == "3") { return "wed" }
else if (num == "4") { return "thu" }
else if (num == "5") { return "fri" }
else if (num == "6") { return "sat" }
else if (num == "0") { return "sun" }
}
//--------------------- end
//--------------------- client CALL
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
checkAuth();
}
//--------------------- end
//--------------------- check Auth
function checkAuth() {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
//--------------------- end
//--------------------- handle result and make CALL
function handleAuthResult(authResult) {
if (authResult) {
makeApiCall();
}
}
//--------------------- end
//--------------------- API CALL itself
function makeApiCall() {
var today = new Date(); //today date
gapi.client.load('calendar', 'v3', function () {
var request = gapi.client.calendar.events.list({
'calendarId' : userEmail,
'timeZone' : userTimeZone,
'singleEvents': true,
'timeMin': today.toISOString(), //gathers only events not happened yet
'maxResults': maxRows,
'orderBy': 'startTime'});
request.execute(function (resp) {
for (var i = 0; i < resp.items.length; i++) {
var li = document.createElement('li');
var item = resp.items[i];
var classes = [];
var allDay = item.start.date? true : false;
var startDT = allDay ? item.start.date : item.start.dateTime;
var dateTime = startDT.split("T"); //split date from time
var date = dateTime[0].split("-"); //split yyyy mm dd
var startYear = date[0];
var startMonth = monthString(date[1]);
var startDay = date[2];
var startDateISO = new Date(startMonth + " " + startDay + ", " + startYear + " 00:00:00");
var startDayWeek = dayString(startDateISO.getDay());
if( allDay == true){ //change this to match your needs
var str = [
'<font size="4" face="courier">',
startDayWeek, ' ',
startMonth, ' ',
startDay, ' ',
startYear, '</font><font size="5" face="courier"> # ', item.summary , '</font><br><br>'
];
}
else{
var time = dateTime[1].split(":"); //split hh ss etc...
var startHour = AmPm(time[0]);
var startMin = time[1];
var str = [ //change this to match your needs
'<font size="4" face="courier">',
startDayWeek, ' ',
startMonth, ' ',
startDay, ' ',
startYear, ' - ',
startHour, ':', startMin, '</font><font size="5" face="courier"> # ', item.summary , '</font><br><br>'
];
}
li.innerHTML = str.join('');
li.setAttribute('class', classes.join(' '));
document.getElementById('events').appendChild(li);
}
document.getElementById('updated').innerHTML = "updated " + today;
document.getElementById('calendar').innerHTML = calName;
});
});
}
//--------------------- end
</script>
<script src='https://apis.google.com/js/client.js?onload=handleClientLoad'></script>
<div id='content'>
<h1 id='calendar' style="color:grey">LOADING . . . .</h1>
<ul id='events'></ul>
</div>
<p id='updated' style="font-size:12; color:grey">updating . . . . .</p>
</body>
</html>

Here's a simplified, annotated, and updated script based on Max's original that makes use of Moment.js and JQuery. Read the full blog post here for details (including how to get your API key), or just replace YOUR_CALENDAR_ID and YOUR_API_KEY in the script below:
<script>
/* This solution makes use of "simple access" to google, providing only an API Key.
* This way we can only get access to public calendars. To access a private calendar,
* we would need to use OAuth 2.0 access.
*
* "Simple" vs. "Authorized" access: https://developers.google.com/api-client-library/javascript/features/authentication
* Examples of "simple" vs OAuth 2.0 access: https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests
*
* We will make use of "Option 1: Load the API discovery document, then assemble the request."
* as described in https://developers.google.com/api-client-library/javascript/start/start-js
*/
function printCalendar() {
// The "Calendar ID" from your calendar settings page, "Calendar Integration" secion:
var calendarId = 'YOUR_CALENDAR_ID#group.calendar.google.com';
// 1. Create a project using google's wizzard: https://console.developers.google.com/start/api?id=calendar
// 2. Create credentials:
// a) Go to https://console.cloud.google.com/apis/credentials
// b) Create Credentials / API key
// c) Since your key will be called from any of your users' browsers, set "Application restrictions" to "None",
// leave "Website restrictions" blank; you may optionally set "API restrictions" to "Google Calendar API"
var apiKey = 'YOUR_API_KEY';
// You can get a list of time zones from here: http://www.timezoneconverter.com/cgi-bin/zonehelp
var userTimeZone = "Europe/Budapest";
// Initializes the client with the API key and the Translate API.
gapi.client.init({
'apiKey': apiKey,
// Discovery docs docs: https://developers.google.com/api-client-library/javascript/features/discovery
'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'],
}).then(function () {
// Use Google's "apis-explorer" for research: https://developers.google.com/apis-explorer/#s/calendar/v3/
// Events: list API docs: https://developers.google.com/calendar/v3/reference/events/list
return gapi.client.calendar.events.list({
'calendarId': calendarId,
'timeZone': userTimeZone,
'singleEvents': true,
'timeMin': (new Date()).toISOString(), //gathers only events not happened yet
'maxResults': 20,
'orderBy': 'startTime'
});
}).then(function (response) {
if (response.result.items) {
var calendarRows = ['<table class="wellness-calendar"><tbody>'];
response.result.items.forEach(function(entry) {
var startsAt = moment(entry.start.dateTime).format("L") + ' ' + moment(entry.start.dateTime).format("LT");
var endsAt = moment(entry.end.dateTime).format("LT");
calendarRows.push(`<tr><td>${startsAt} - ${endsAt}</td><td>${entry.summary}</td></tr>`);
});
calendarRows.push('</tbody></table>');
$('#wellness-calendar').html(calendarRows.join(""));
}
}, function (reason) {
console.log('Error: ' + reason.result.error.message);
});
};
// Loads the JavaScript client library and invokes `start` afterwards.
gapi.load('client', printCalendar);
</script>
You will also need to include Moment.JS and the Google JS API somewhere in your page:
<script src="https://cdn.jsdelivr.net/npm/moment#2/moment.min.js"></script>
<script src="https://apis.google.com/js/api.js"></script>

Related

count total number of word in pdf book using node js? [duplicate]

I wonder if is possible to get the text inside of a PDF file by using only Javascript?
If yes, can anyone show me how?
I know there are some server-side java, c#, etc libraries but I would prefer not using a server.
thanks
Because pdf.js has been developing over the years, I would like to give a new answer. That is, it can be done locally without involving any server or external service. The new pdf.js has a function: page.getTextContent(). You can get the text content from that. I've done it successfully with the following code.
What you get in each step is a promise. You need to code this way: .then( function(){...}) to proceed to the next step.
PDFJS.getDocument( data ).then( function(pdf) {
pdf.getPage(i).then( function(page){
page.getTextContent().then( function(textContent){
What you finally get is an string array textContent.bidiTexts[]. You concatenate them to get the text of 1 page. Text blocks' coordinates are used to judge whether newline or space need to be inserted. (This may not be totally robust, but from my test it seems ok.)
The input parameter data needs to be either a URL or ArrayBuffer type data. I used the ReadAsArrayBuffer(file) function in FileReader API to get the data.
Note: According to some other user, the library has updated and caused the code to break. According to the comment by async5 below, you need to replace textContent.bidiTexts with textContent.items.
function Pdf2TextClass(){
var self = this;
this.complete = 0;
/**
*
* #param data ArrayBuffer of the pdf file content
* #param callbackPageDone To inform the progress each time
* when a page is finished. The callback function's input parameters are:
* 1) number of pages done;
* 2) total number of pages in file.
* #param callbackAllDone The input parameter of callback function is
* the result of extracted text from pdf file.
*
*/
this.pdfToText = function(data, callbackPageDone, callbackAllDone){
console.assert( data instanceof ArrayBuffer || typeof data == 'string' );
PDFJS.getDocument( data ).then( function(pdf) {
var div = document.getElementById('viewer');
var total = pdf.numPages;
callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++){
pdf.getPage(i).then( function(page){
var n = page.pageNumber;
page.getTextContent().then( function(textContent){
if( null != textContent.bidiTexts ){
var page_text = "";
var last_block = null;
for( var k = 0; k < textContent.bidiTexts.length; k++ ){
var block = textContent.bidiTexts[k];
if( last_block != null && last_block.str[last_block.str.length-1] != ' '){
if( block.x < last_block.x )
page_text += "\r\n";
else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null ))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++ self.complete;
callbackPageDone( self.complete, total );
if (self.complete == total){
window.setTimeout(function(){
var full_text = "";
var num_pages = Object.keys(layers).length;
for( var j = 1; j <= num_pages; j++)
full_text += layers[j] ;
callbackAllDone(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
I couldn't get gm2008's example to work (the internal data structure on pdf.js has changed apparently), so I wrote my own fully promise-based solution that doesn't use any DOM elements, queryselectors or canvas, using the updated pdf.js from the example at mozilla
It eats a file path for the upload since i'm using it with node-webkit.
You need to make sure you have the cmaps downloaded and pointed somewhere and you nee pdf.js and pdf.worker.js to get this working.
/**
* Extract text from PDFs with PDF.js
* Uses the demo pdf.js from https://mozilla.github.io/pdf.js/getting_started/
*/
this.pdfToText = function(data) {
PDFJS.workerSrc = 'js/vendor/pdf.worker.js';
PDFJS.cMapUrl = 'js/vendor/pdfjs/cmaps/';
PDFJS.cMapPacked = true;
return PDFJS.getDocument(data).then(function(pdf) {
var pages = [];
for (var i = 0; i < pdf.numPages; i++) {
pages.push(i);
}
return Promise.all(pages.map(function(pageNumber) {
return pdf.getPage(pageNumber + 1).then(function(page) {
return page.getTextContent().then(function(textContent) {
return textContent.items.map(function(item) {
return item.str;
}).join(' ');
});
});
})).then(function(pages) {
return pages.join("\r\n");
});
});
}
usage:
self.pdfToText(files[0].path).then(function(result) {
console.log("PDF done!", result);
})
Just leaving here a full working sample.
<html>
<head>
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>
</head>
<body>
<input id="pdffile" name="pdffile" type="file" />
<button id="btn" onclick="convert()">Process</button>
<div id="result"></div>
</body>
</html>
<script>
function convert() {
var fr=new FileReader();
var pdff = new Pdf2TextClass();
fr.onload=function(){
pdff.pdfToText(fr.result, null, (text) => { document.getElementById('result').innerText += text; });
}
fr.readAsDataURL(document.getElementById('pdffile').files[0])
}
function Pdf2TextClass() {
var self = this;
this.complete = 0;
this.pdfToText = function (data, callbackPageDone, callbackAllDone) {
console.assert(data instanceof ArrayBuffer || typeof data == 'string');
var loadingTask = pdfjsLib.getDocument(data);
loadingTask.promise.then(function (pdf) {
var total = pdf._pdfInfo.numPages;
//callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++) {
pdf.getPage(i).then(function (page) {
var n = page.pageNumber;
page.getTextContent().then(function (textContent) {
//console.log(textContent.items[0]);0
if (null != textContent.items) {
var page_text = "";
var last_block = null;
for (var k = 0; k < textContent.items.length; k++) {
var block = textContent.items[k];
if (last_block != null && last_block.str[last_block.str.length - 1] != ' ') {
if (block.x < last_block.x)
page_text += "\r\n";
else if (last_block.y != block.y && (last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++self.complete;
//callbackPageDone( self.complete, total );
if (self.complete == total) {
window.setTimeout(function () {
var full_text = "";
var num_pages = Object.keys(layers).length;
for (var j = 1; j <= num_pages; j++)
full_text += layers[j];
callbackAllDone(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
</script>
Here's some JavaScript code that does what you want using Pdf.js from http://hublog.hubmed.org/archives/001948.html:
var input = document.getElementById("input");
var processor = document.getElementById("processor");
var output = document.getElementById("output");
// listen for messages from the processor
window.addEventListener("message", function(event){
if (event.source != processor.contentWindow) return;
switch (event.data){
// "ready" = the processor is ready, so fetch the PDF file
case "ready":
var xhr = new XMLHttpRequest;
xhr.open('GET', input.getAttribute("src"), true);
xhr.responseType = "arraybuffer";
xhr.onload = function(event) {
processor.contentWindow.postMessage(this.response, "*");
};
xhr.send();
break;
// anything else = the processor has returned the text of the PDF
default:
output.textContent = event.data.replace(/\s+/g, " ");
break;
}
}, true);
...and here's an example:
http://git.macropus.org/2011/11/pdftotext/example/
Note: This code assumes you're using nodejs. That means you're parsing a local file instead of one from a web page since the original question doesn't explicitly ask about parsing pdfs on a web page.
#gm2008's answer was a great starting point (please read it and its comments for more info), but needed some updates (08/19) and had some unused code. I also like examples that are more full. There's more refactoring and tweaking that could be done (e.g. with await), but for now it's as close to that original answer as it could be.
As before, this uses Mozilla's PDFjs library. The npmjs package is at https://www.npmjs.com/package/pdfjs-dist.
In my experience, this doesn't do well in finding where to put spaces, but that's a problem for another time.
[Edit: I believe the update to the use of .transform has restored the whitespace as it originally behaved.]
// This file is called myPDFfileToText.js and is in the root folder
let PDFJS = require('pdfjs-dist');
let pathToPDF = 'path/to/myPDFfileToText.pdf';
let toText = Pdf2TextObj();
let onPageDone = function() {}; // don't want to do anything between pages
let onFinish = function(fullText) { console.log(fullText) };
toText.pdfToText(pathToPDF, onPageDone, onFinish);
function Pdf2TextObj() {
let self = this;
this.complete = 0;
/**
*
* #param path Path to the pdf file.
* #param callbackPageDone To inform the progress each time
* when a page is finished. The callback function's input parameters are:
* 1) number of pages done.
* 2) total number of pages in file.
* 3) the `page` object itself or null.
* #param callbackAllDone Called after all text has been collected. Input parameters:
* 1) full text of parsed pdf.
*
*/
this.pdfToText = function(path, callbackPageDone, callbackAllDone) {
// console.assert(typeof path == 'string');
PDFJS.getDocument(path).promise.then(function(pdf) {
let total = pdf.numPages;
callbackPageDone(0, total, null);
let pages = {};
// For some (pdf?) reason these don't all come in consecutive
// order. That's why they're stored as an object and then
// processed one final time at the end.
for (let pagei = 1; pagei <= total; pagei++) {
pdf.getPage(pagei).then(function(page) {
let pageNumber = page.pageNumber;
page.getTextContent().then(function(textContent) {
if (null != textContent.items) {
let page_text = "";
let last_item = null;
for (let itemsi = 0; itemsi < textContent.items.length; itemsi++) {
let item = textContent.items[itemsi];
// I think to add whitespace properly would be more complex and
// would require two loops.
if (last_item != null && last_item.str[last_item.str.length - 1] != ' ') {
let itemX = item.transform[5]
let lastItemX = last_item.transform[5]
let itemY = item.transform[4]
let lastItemY = last_item.transform[4]
if (itemX < lastItemX)
page_text += "\r\n";
else if (itemY != lastItemY && (last_item.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null))
page_text += ' ';
} // ends if may need to add whitespace
page_text += item.str;
last_item = item;
} // ends for every item of text
textContent != null && console.log("page " + pageNumber + " finished.") // " content: \n" + page_text);
pages[pageNumber] = page_text + "\n\n";
} // ends if has items
++self.complete;
callbackPageDone(self.complete, total, page);
// If all done, put pages in order and combine all
// text, then pass that to the callback
if (self.complete == total) {
// Using `setTimeout()` isn't a stable way of making sure
// the process has finished. Watch out for missed pages.
// A future version might do this with promises.
setTimeout(function() {
let full_text = "";
let num_pages = Object.keys(pages).length;
for (let pageNum = 1; pageNum <= num_pages; pageNum++)
full_text += pages[pageNum];
callbackAllDone(full_text);
}, 1000);
}
}); // ends page.getTextContent().then
}); // ends page.then
} // ends for every page
});
}; // Ends pdfToText()
return self;
}; // Ends object factory
Run in the terminal:
node myPDFfileToText.js
Updated 02/2021
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>
<script>
function Pdf2TextClass(){
var self = this;
this.complete = 0;
this.pdfToText = function(data, callbackPageDone, callbackAllDone){
console.assert( data instanceof ArrayBuffer || typeof data == 'string' );
var loadingTask = pdfjsLib.getDocument(data);
loadingTask.promise.then(function(pdf) {
var total = pdf._pdfInfo.numPages;
//callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++){
pdf.getPage(i).then( function(page){
var n = page.pageNumber;
page.getTextContent().then( function(textContent){
//console.log(textContent.items[0]);0
if( null != textContent.items ){
var page_text = "";
var last_block = null;
for( var k = 0; k < textContent.items.length; k++ ){
var block = textContent.items[k];
if( last_block != null && last_block.str[last_block.str.length-1] != ' '){
if( block.x < last_block.x )
page_text += "\r\n";
else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null ))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++ self.complete;
//callbackPageDone( self.complete, total );
if (self.complete == total){
window.setTimeout(function(){
var full_text = "";
var num_pages = Object.keys(layers).length;
for( var j = 1; j <= num_pages; j++)
full_text += layers[j] ;
console.log(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
var pdff = new Pdf2TextClass();
pdff.pdfToText('PDF_URL');
</script>
For all the people who actually want to use it on a node server:
/**
* Created by velten on 25.04.16.
*/
"use strict";
let pdfUrl = "http://example.com/example.pdf";
let request = require('request');
var pdfParser = require('pdf2json');
let pdfPipe = request({url: pdfUrl, encoding:null}).pipe(pdfParser);
pdfPipe.on("pdfParser_dataError", err => console.error(err) );
pdfPipe.on("pdfParser_dataReady", pdf => {
//optionally:
//let pdf = pdfParser.getMergedTextBlocksIfNeeded();
let count1 = 0;
//get text on a particular page
for (let page of pdf.formImage.Pages) {
count1 += page.Texts.length;
}
console.log(count1);
pdfParser.destroy();
});
It is possible but:
you would have to use the server anyway, there's no way you can get content of a file on user computer without transferring it to server and back
I don't thing anyone has written such library yet
So if you have some free time you can learn pdf format and write such a library yourself, or you can just use server side library of course.

Delay for messages in node-telegram-bot-api

I am working on a telegram bot with the node-telegram-bot-api library. I made 2 buttons using keyboard. But when you click on them a lot, the bot will spam and sooner or later it will freeze. Is it possible to somehow put a delay for the user on messages.
if (text === '/start') {
return bot.sendMessage(chatId, 'hello', keyboardMain);
}
export const keyboardMain = {
reply_markup: JSON.stringify({
keyboard: [
[{
text: '/start',
},
],
resize_keyboard: true
})
};
You can create a user throttler using Javascript Map
/*
* #param {number} waitTime Seconds to wait
*/
function throttler(waitTime) {
const users = new Map()
return (chatId) => {
const now = parseInt(Date.now()/1000)
const hitTime = users.get(chatId)
if (hitTime) {
const diff = now - hitTime
if (diff < waitTime) {
return false
}
users.set(chatId, now)
return true
}
users.set(chatId, now)
return true
}
}
How to use:
You'll get the user's chatId from telegram api. You can use that id as an identifier and stop the user for given specific time.
For instance I'm gonna stop the user for 10seconds once the user requests.
// global 10 second throttler
const throttle = throttler(10) // 10 seconds
// in your code
const allowReply = throttle(chatId) // chatId obtained from telegram
if (allowReply) {
// reply to user
} else {
// dont reply
}
I tried using this code, put the function code in my function file, connected everything to the required file, and I don’t understand what to do next and where to insert the last code and what to do with it. I'm new to JavaScript and just learning.
import {
bot
} from '../token.js';
import {
throttler
} from '../functions/functions.js';
import {
keyboardMain
} from '../keyboards/keyboardsMain.js';
export function commands() {
bot.on('message', msg => {
const text = msg.text;
const chatId = msg.chat.id;
const throttle = throttler(10);
if (text === '/start') {
const allowReply = throttle(chatId) // chatId obtained from telegram
if (allowReply) {
return bot.sendMessage(chatId, 'hello', keyboardMain);
} else {
// dont reply
}
}
return bot.sendMessage(chatId, 'error');
});
}
Get the time when he pressed the button
Get the time of the next click
Take away the difference and set the condition (if, for example, more than 3 seconds have passed between clicks, then the user will not be frozen).
var token = ""; // FILL IN YOUR OWN TOKEN
var telegramUrl = "https://api.telegram.org/bot" + token;
var webAppUrl = ""; // FILLINYOUR GOOGLEWEBAPPADDRESS
var ssId = ""; // FILL IN THE ID OF YOUR SPREADSHEET
function getMe() {
var url = telegramUrl + "/getMe";
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function setWebhook() {
var url = telegramUrl + "/setWebhook?url=" + webAppUrl;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function sendText(id,text) {
var url = telegramUrl + "/sendMessage?chat_id=" + id + "&text=" + text;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function doGet(e) {
return HtmlService.createHtmlOutput("Hi there");
}
function doPost(e){
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var id = data.message.chat.id;
var msgbegan = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A7").getValue();
var msginfo = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A9").getValue();
var answer = "%0A" + msgbegan + "%0A" ;
///////////////////////
/*
* #param {number} waitTime Seconds to wait
*/
function throttler(waitTime) {
const users = new Map()
return (chatId) => {
const now = parseInt(Date.now()/1000)
const hitTime = users.get(chatId)
if (hitTime) {
const diff = now - hitTime
if (diff < waitTime) {
return false
}
users.set(chatId, now)
return true
}
users.set(chatId, now)
return true
}
}
// global 10 second throttler
const throttle = throttler(500) // 10 seconds
// in your code
const allowReply = throttle(chatId) // chatId obtained from telegram
if (allowReply) {
// reply to user
} else {
// dont reply
}
///////////////////////////////////////
if(text == "/start"){
sendText(id, answer);
} else if (text == "/info"){
sendText(id, msginfo);
}else{
if (text.length == 10){
var found = false;
var total_rows = SpreadsheetApp.openById(ssId).getSheets()[0].getMaxRows();
for(i=1; i<=total_rows; i++){
var loop_id = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(i,2).getValue();
if(text == loop_id){
found = true;
found_at = i; // employee row
break;
}
}
if(found){
sendText(id, work_message);
}else{
var msgerrror = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A6").getValue();
var not_found = "%0A" + msgerrror+ "%0A" ;
sendText(id, not_found);
}
} else {
sendText(id, "eroor");
}
}
/////////////
var emp_name = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,1).getValue();
var emp_work = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,3).getValue();
var homeloc = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,4).getValue();
var emp_location = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,8).getValue();
var emp_data = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,5).getValue();
var emp_day = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,6).getValue();
var emp_clock = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,7).getValue();
var emp_location = SpreadsheetApp.openById(ssId).getSheets()[0].getRange(found_at,8).getValue();
var welcome = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A2").getValue();
var msgemp = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A3").getValue();
var msgloc = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A4").getValue();
var msgbay = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A5").getValue();
var msghome = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A8").getValue();
var msmobil = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A11").getValue();
var mstoday = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A13").getValue();
var msdata = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A14").getValue();
var msclock = SpreadsheetApp.openById(ssId).getSheets()[1].getRange("A15").getValue();
var work_message = welcome + emp_name +
"%0A" + msgemp + emp_work +
"%0A" + mstoday + emp_day +
"%0A" + msdata + emp_data +
"%0A" + msclock + emp_clock +
"%0A" + msghome + homeloc +
"%0A" + msgloc+ emp_location +
"%0A" + msgbay +
"%0A" + msmobil ;
}
Excuse me . I am a beginner
Is this the correct way

Using JavaScript only, how can I query a google sheet and assign the value of a single cell as a JavaScript variable?

I am wanting to drive a web page using data from a few google sheets.
I’ve figure out how to query my sheet, but the data displays as a datatable and that’s not what I’m looking for. I’d like to be able to take the query cell value and insert it into HTML code. I will also use the value in another query in order to retrieve other information from a different google sheet.
I have two live pages:
http://www.bandstand.ca/widget
This page is a starter skeleton version of my project. I have “Day 5” statically coded and formatted for now but want to replace it with query data as per:
http://www.bandstand.ca/widget/sas.html
I had tried using getValue(0,0) but must not have had something set right. I am totally new to using queries and have not been able to figure out if JavaScript can do anything with the content of the response. I tried hiding the div element that the query fills and just parsing content of the data table, but again, couldn’t figure out a workable solution. I’ve tried searching through the api documentation but I’m not finding anything that looks right either. Surely there’s a way to extract the data and use it within other html. I don’t particularly care if the code is clean (as I’m sure you can tell, I’ve hacked apart other peoples’ code to get the sas.html file down to where it’s at.) I just want something that works.
I’m a teacher and thought this would be an easy little project to build an in-class announcement page that I could have displayed all the time in my room and have it cycle through my schedule of classes via my easily updated google sheets. So far, not so easy! If anyone can help tweak my code to get what I’m asking, I’d sure be grateful!
You can try something like this:
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth() + 2;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql) {
var gq = 'SELECT '+ gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg;
return url;
}
function Request(url, responseFunction) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")"));
var responseJSON = JSON.parse(response);
responseFunction(responseJSON);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML = value;
})
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var currentDate = GetCurrentDate();
var gql = "C WHERE A = DATE " + currentDate;
var url = CreateUrl(gsKey, gql);
var previewElement = document.getElementById('preview');
preview(previewElement, url);
<html>
<head>
<title>Student Announcement System</title>
</head>
<body>
<div id="preview">initial value</div>
</body>
</html>
Here is link to jsbin snippet. (Inline stackoverflow snippet might not work because of CORS and Access-Control-Allow-Origin.)
EDIT after Greg Duguid's comment:
There are three problems with your code:
Your scripts are not working at all. Try to run following snippet:
<script>
document.write("Text 1")
</script>
<script language = "text/javascript">
document.write("Text 2")
</script>
<script type = "text/javascript">
document.write("Text 3")
</script>
When you run it you should get something like Text 1 Text 3 and that is because <script language = "text/javascript"> is wrong and won't work, language parameter is deprecated and you should use type instead. Also in HTML5 you can omit type parameter so it is best to use syntax like this <script>document.write("Text")</script>.
There is syntax error in function preview: last bracket ( should be ).
// OLD CODE
/*
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
//elm.innerHTML = value;
DayNumber = value;
}
( // ERROR IS IN THIS LINE
}
*/
// NEW CODE
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
//elm.innerHTML = value;
DayNumber = value;
}
) // error WAS in this line
}
Code in line:
<font size="+6" color="#FFFF00">Day <script>document.write(DayNumber);</script></font>
When you call function document.write(DayNumber) variable DayNumber is equal to "" because function preview is still not executed at that moment. Reason for this is that execution of function preview takes time. (Because you are retrieving data from sheet document, usually when you retrieve data from server or something similar that takes time.) Execution of code in javascript is asynchronous which means that javscript doesn't wait for function to finish with execution and goes on. Look at this example:
function getData() {
// some function that takes time to get data from server, ducument, or something else
return data;
}
var data = getData();
document.write(data);
In first line function getData() is called, but data will be set to undefined because program will not wait for function getData() to return its value. So function document.write(data) will not preview anything.
(Also it is not good practice to use script tag inside another tag. So you should avoid putting script tag inside font tag like this: <font size="+6" color="#FFFF00">Day <script>document.write(DayNumber);</script></font>.)
Solution for this problem is that you add id to you font tag and than change text in font tag in javascript inside function preview:
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth();
var day = currentTime.getDate() + 1;
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql) {
var gq = 'SELECT '+ gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg;
return url;
}
function Request(url, responseFunction) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")"));
var responseJSON = JSON.parse(response);
responseFunction(responseJSON);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML += " " + value;
}
)
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var currentDate = GetCurrentDate();
var gql = "C WHERE A = DATE " + currentDate;
var url = CreateUrl(gsKey, gql);
var previewElement = document.getElementById('preview');
preview(previewElement, url);
<html>
<title>Student Announcement System</title>
<body>
<font size="+6" color="#FFFF00" id="preview">Day</font>
</body>
</html>
This last code should be solution to your problem. Also here is link to jsbin snippet (because stackoverflow snippet might not work when you run it).
EDIT after second Greg Duguid's comment:
Sorry it took little longer to answer. Problem is in line:
var previewElement = document.getElementById('preview');
When this line is executed previewElement is not found and it is set to undefined. This is because javascript code in script tag (<script>...</script>) is before body tag (<body>...</body>) so code is executed before elements in body are defined. So when your page is run, first javascript code is executed and then element <font id="preview">Day</font> is defined. There is simple solution for this: You need to put your script tag at the end of body like this:
<html>
<head>
<style type="text/css">
<!--
body {
background-color: #003c66;
}
-->
</style>
<title>Student Announcement System</title>
</head>
<body>
<font size="+6" color="#FFFF00" id="preview">Day</font>
<script>
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth()+1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql, sheet) {
var gq = 'SELECT '+ gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg + '&gid=' + sheet;
return url;
}
function Request(url, responseFunction) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = this.responseText.substring(this.responseText.IndexOf("(")+1, this.responseText.lastIndexOf(")"));
var responseJSON = JSON.parse(response);
responseFunction(responseJSON);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function preview(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML += " " + value;
}
)
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var gsSheet='349215948';
var currentDate = GetCurrentDate();
var gql = "C WHERE A = DATE " + currentDate;
var url = CreateUrl(gsKey, gql, gsSheet);
var previewElement = document.getElementById('preview');
preview(previewElement, url);
</script>
</body>
</html>
And again here is jsbin snippet which should work.
EDIT after this Greg Duguid's comment:
The problem is in your query:
var PERIODgql = "C WHERE A = " + value + " AND B = " + CurrentPeriod;
CurrentPeriod is string so you need to add single quotes around it like this:
var PERIODgql = "C WHERE A = " + value + " AND B = '" + CurrentPeriod + "'";
When it is created, PERIODgql will be something like:
"C WHERE A = 1 AND B = 'P5'"
These queries are similar to SQL queries (which are used to get data form SQL database), you can read more about this here.
Also i noticed your function FindCurrentPeriod:
function FindCurrentPeriod() {
var CurrentPeriod;
var CurrentDate = new Date();
//////////////////////////////
//FOR TESTING VARIOUS TIMES
CurrentDate.setHours(14);
CurrentDate.setMinutes(0);
//////////////////////////////
var CurrentHour = CurrentDate.getHours();
var CurrentMinute = CurrentDate.getMinutes();
if (CurrentHour < 8) {
CurrentPeriod = "Before School";
}
if (CurrentHour == 8) {
if (CurrentMinute < 40) {
CurrentPeriod = "Before School";
} else {
CurrentPeriod = "P1";
}
}
if (CurrentHour == 9) {
if (CurrentMinute < 40) {
CurrentPeriod = "P1";
} else {
if (CurrentMinute < 45) {
CurrentPeriod = "B12";
} else {
CurrentPeriod = "P2";
}
}
}
if (CurrentHour == 10) {
if (CurrentMinute < 37) {
CurrentPeriod = "P2";
} else {
if (CurrentMinute < 47) {
CurrentPeriod = "B23";
} else {
CurrentPeriod = "P3";
}
}
}
if (CurrentHour == 11) {
if (CurrentMinute < 39) {
CurrentPeriod = "P3";
} else {
if (CurrentMinute < 44) {
CurrentPeriod = "B34";
} else {
CurrentPeriod = "P4";
}
}
}
if (CurrentHour == 12) {
if (CurrentMinute < 36) {
CurrentPeriod = "P4";
} else {
CurrentPeriod = "Lunch";
}
}
if (CurrentHour == 13) {
if (CurrentMinute < 13) {
CurrentPeriod = "Lunch";
} else {
CurrentPeriod = "P5";
}
}
if (CurrentHour == 14) {
if (CurrentMinute < 5) {
CurrentPeriod = "P5";
} else {
if (CurrentMinute < 10) {
CurrentPeriod = "B56";
} else {
CurrentPeriod = "P6";
}
}
}
if (CurrentHour == 15) {
if (CurrentMinute < 2) {
CurrentPeriod = "P6";
} else {
CurrentPeriod = "After School";
}
} else {
CurrentPeriod = "After School";
}
return CurrentPeriod;
}
While this is working, it is not really easy to read and there is some repeating conditions so if need to change your code later, that will be harder to do. So I would suggest using a function to help you compare time (in hours and minutes). You can add just short function like this:
function time(hours, minutes) {
return hours*60 + minutes;
}
Now you can compare times 10:50 and 11:25 like this:
if (time(10,50) < time(11,25)) {
//part when you do what you want if condition is ture
}
So you can write your function FindCurrentPeriod like this:
function FindCurrentPeriod() {
var CurrentPeriod;
var CurrentDate = new Date();
//////////////////////////////
//FOR TESTING VARIOUS TIMES
CurrentDate.setHours(14);
CurrentDate.setMinutes(0);
//////////////////////////////
var CurrentHour = CurrentDate.getHours();
var CurrentMinute = CurrentDate.getMinutes();
var cirrentTime = time(CurrentHour, CurrentMinute);
if (cirrentTime < time(8, 40)) {
CurrentPeriod = "Before School";
}
else if (cirrentTime < time(9, 40)) {
CurrentPeriod = "P1";
}
else if (cirrentTime < time(9, 45)) {
CurrentPeriod = "B12";
}
else if (cirrentTime < time(10, 37)) {
CurrentPeriod = "P2";
}
else if (cirrentTime < time(10, 47)) {
CurrentPeriod = "B23";
}
else if (cirrentTime < time(11, 39)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(11, 44)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(12, 36)) {
CurrentPeriod = "P4";
}
else if (cirrentTime < time(13, 13)) {
CurrentPeriod = "Lunch";
}
else if (cirrentTime < time(14, 5)) {
CurrentPeriod = "P5";
}
else if (cirrentTime < time(14, 10)) {
CurrentPeriod = "B56";
}
else if (cirrentTime < time(15, 2)) {
CurrentPeriod = "P6";
}
else {
CurrentPeriod = "After School";
}
return CurrentPeriod;
}
This is shorter and also easier to read and change if needed.
Here is whole code in stackoverflow snippet (again I'll add jsbin snippet below, because inline stackoverflow snippet might not work because of CORS rules):
function preview2(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML = value;
})
}
function GetCurrentDate() {
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var currentDate = "'" + year + "-" + month + "-" + day + "'";
return currentDate;
}
function CreateUrl(key, gql, sheet) {
var gq = 'SELECT ' + gql;
var encodedgg = encodeURIComponent(gq);
var url = 'https://docs.google.com/spreadsheets/d/' + key + '/gviz/tq?tq=' + encodedgg + '&gid=' + sheet;
return url;
}
function time(hours, minutes) {
return hours*60 + minutes;
}
function FindCurrentPeriod() {
var CurrentPeriod;
var CurrentDate = new Date();
//////////////////////////////
//FOR TESTING VARIOUS TIMES
CurrentDate.setHours(14);
CurrentDate.setMinutes(0);
//////////////////////////////
var CurrentHour = CurrentDate.getHours();
var CurrentMinute = CurrentDate.getMinutes();
var cirrentTime = time(CurrentHour, CurrentMinute);
if (cirrentTime < time(8, 40)) {
CurrentPeriod = "Before School";
}
else if (cirrentTime < time(9, 40)) {
CurrentPeriod = "P1";
}
else if (cirrentTime < time(9, 45)) {
CurrentPeriod = "B12";
}
else if (cirrentTime < time(10, 37)) {
CurrentPeriod = "P2";
}
else if (cirrentTime < time(10, 47)) {
CurrentPeriod = "B23";
}
else if (cirrentTime < time(11, 39)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(11, 44)) {
CurrentPeriod = "P3";
}
else if (cirrentTime < time(12, 36)) {
CurrentPeriod = "P4";
}
else if (cirrentTime < time(13, 13)) {
CurrentPeriod = "Lunch";
}
else if (cirrentTime < time(14, 5)) {
CurrentPeriod = "P5";
}
else if (cirrentTime < time(14, 10)) {
CurrentPeriod = "B56";
}
else if (cirrentTime < time(15, 2)) {
CurrentPeriod = "P6";
}
else {
CurrentPeriod = "After School";
}
return CurrentPeriod;
}
function preview1(elm, url) {
fetch(url)
.then(data => data.text())
.then(function(response) {
var responseText = response.substring(response.indexOf("(") + 1, response.lastIndexOf(")"));
var response = JSON.parse(responseText);
var value = response['table']['rows'][0]['c'][0]['v'];
elm.innerHTML += " " + value;
var CurrentPeriod = FindCurrentPeriod();
var PERIODgsSheet = '618896702';
var PERIODgql = "C WHERE A = " + value + " AND B = '" + CurrentPeriod + "'";
var PeriodURL = CreateUrl(gsKey, PERIODgql, PERIODgsSheet);
var periodElement = document.getElementById('period1');
preview2(periodElement, PeriodURL);
})
}
var gsKey = '1-dNm_AKv3Iiy-ggLjGJKHPwUqs379QJh0e4SzbEPcJQ';
var DAYgsSheet = '349215948';
var currentDate = GetCurrentDate();
var DAYgql = "C WHERE A = DATE " + currentDate;
var DayURL = CreateUrl(gsKey, DAYgql, DAYgsSheet);
var previewElement = document.getElementById('preview');
preview1(previewElement, DayURL);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="refresh" content="600" />
<title>Student Announcement System</title>
<style type="text/css">
<!--
body {
background-color: #003c66;
}
-->
</style>
<!-- CSS Code -->
<style type="text/css" scoped>
.GeneratedMarquee {
font-family:'Arial Black', sans-serif;
font-size:8em;
font-weight:bold;
line-height:2em;
text-align:left;
color:#ffff00;
background-color:#003c66;
padding:40pt;
}
</style>
</head>
<body>
<table width=100%>
<tr>
<td width=240px>
<iframe scrolling="no" frameborder="no" clocktype="html5" style="overflow:hidden;border:0;margin:0;padding:0;width:240px;height:80px;"src="https://www.clocklink.com/html5embed.php?clock=004&timezone=MST&color=white&size=240&Title=&Message=&Target=&From=2018,1,1,0,0,0&Color=white"></iframe>
</td>
<td nowrap>
<center>
<font size="80px" color="#FFFF00" id="preview">DAY </font>
</center>
</td>
<td width=100%>
<a class="weatherwidget-io" href="https://forecast7.com/en/53d54n113d49/edmonton/" data-label_1="EDMONTON" data-font="Helvetica" data-icons="Climacons Animated" data-days="7" data-theme="original" data-basecolor="#003c66" ></a>
<script>
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src='https://weatherwidget.io/js/widget.min.js';fjs.parentNode.insertBefore(js,fjs);}}(document,'script','weatherwidget-io-js');
</script>
</td>
</tr>
</table>
<font color="FFFFFF", size="+6">
<script language=javascript>
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
var today = new Date();
document.write(today.toLocaleDateString("en-US", options)); // Saturday, September 17, 2016
formattedDate = today.toLocaleDateString("en-US", options);
</script>
</font>
<br><font size="80px" color="#FFFF00" id="period1">Class:</font>
<script src="sas.js"></script>
</body>
</html>
Here is jsbin snippet.

How to set a cookie that prevents further javascript alerts?

I have this code for detecting android:
var mobile = (/android/i.test(navigator.userAgent.toLowerCase()));
if (mobile){
alert("Message to android users");
}
...but how do I get that script to also set a cookie so the android user doesn't continue getting the alert (either on reloading the page, returning later to the page, or navigating to other pages which have the alert)?
I also have this, which uses a cookie to avoid a user viewing a "welcome page" they've already seen:
var RedirectURL = "http://www.example.com/real-home-page.html";
var DaysToLive = "365";
var CookieName = "FirstVisit";
function Action() {
location.href = RedirectURL;
}
DaysToLive = parseInt(DaysToLive);
var Value = 'bypass page next time';
function GetCookie() {
var cookiecontent = '';
if(document.cookie.length > 0) {
var cookiename = CookieName + '=';
var cookiebegin = document.cookie.indexOf(cookiename);
var cookieend = 0;
if(cookiebegin > -1) {
cookiebegin += cookiename.length;
cookieend = document.cookie.indexOf(";",cookiebegin);
if(cookieend < cookiebegin) { cookieend = document.cookie.length; }
cookiecontent = document.cookie.substring(cookiebegin,cookieend);
}
}
if(cookiecontent.length > 0) { return true; }
return false;
}
function SetCookie() {
var exp = '';
if(DaysToLive > 0) {
var now = new Date();
then = now.getTime() + (DaysToLive * 24 * 60 * 60 * 1000);
now.setTime(then);
exp = '; expires=' + now.toGMTString();
}
document.cookie = CookieName + '=' + Value + exp;
return true;
}
if(GetCookie() == true) { Action(); }
SetCookie();
Can the second script be adapted and combined into the first to do something like:
function Action() {
don't-open-that-alert-again;
I've googled and found some js cookie scripts, but all over 100K. Prefer something as succinct as the above.

Refreshing KML data in Google Maps V3

I have a map that I have ported from V2 to V3 and I am trying to update the code to refresh the KML data at a set time. In this case every 30 secs. It is just suppose to update the data on the map and show the countdown for when the next update happens.
Here is a working version of how it is suppose to work in V2.
V2 EXAMPLE
Here is the relevant code in the V3 script I have updated but it is not working. I am not getting any errors so I am not sure what I am doing wrong. This is working on V2 but I can't get it to work with V3. What am I missing and overlooking?
//This calls genkml.php on every refresh cycle to generate a new kml file
function UpdateKML() {
//document.getElementById('TheDiv').innerHTML = '0';
var xmlhttp=false;
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
xmlhttp=false;
}
}
if (!xmlhttp && window.createRequest) {
try {
xmlhttp = window.createRequest();
} catch (e) {
xmlhttp=false;
}
}
xmlhttp.open("GET", "genkml.php?force=" + force + "&ofd=" + KMLdate + "&nsd=" + NSdate + "&dbg=" + dbg + "&rand="+(new Date()).valueOf(),true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
var resp = xmlhttp.responseText;
//if (resp === undefined) resp = ''; // If we get a bad response, just set resp to nothing
if (dbg == 'y') { // Check if we want debug info
var tmpresp = resp;
if (tmpresp === undefined) tmpresp = ' ';
if (document.getElementById('div1') == null) { // Check if debug div exists, if not add it to end of body
var divTag = document.createElement("div");
divTag.id = "div1";
divTag.innerHTML = 'Response Status: ' + xmlhttp.status + '<br />' + tmpresp;
document.body.appendChild(divTag);
} else { // Otherwise just update the info
document.getElementById('div1').innerHTML = 'Response Status: ' + xmlhttp.status + '<br />' + tmpresp;
}
} else { // Else check if debug div exists and remove it (will take an update to remove
if (document.getElementById('div1') != null) document.body.removeChild(document.getElementById("div1"));
}
if (resp !== undefined) { // Make sure we got data
KMLdate = resp.split("|")[0].split("~")[0];
NSdate = resp.split("|")[0].split("~")[1];
updateHTML(resp); // This calls the updateHTML function if there is info returned
}
}
}
xmlhttp.send(null);
// add back overlays
nyLayer = new google.maps.KmlLayer(null);
nyLayer.setMap(null); // Remove overlays
var nyLayer = new google.maps.KmlLayer(URLToKML + "?rand="+(new Date()).valueOf(),
{
suppressInfoWindows: false,
map: map,
preserveViewport: true,
zIndex: 999
});
// Time overlayed on map - could be in updateHTML() to just show when .kml read last
var time = CurrentTime ("B", "12a", true, TZOffset)
document.getElementById('currenttime').innerHTML = time;
}
function CurrentTime (type, hours, secs, ofs) {
/*
type (char) hours (char) secs (bool) ofs (num)
"U"-UTC "24"=24 hr time true=hh:mm:ss 0=hours from UTC
"B"-User's Browser "12"=12 hr time false=hh:mm
"S"-Web Site "12a"=am/pm
*/
if (type == null){ type = "B"; } // These are the defaults
if (hours == null){ hours = "12a"; }
if (secs == null){ secs = true; }
if (ofs == null){ ofs = 0; }
var currentHour = 0;
var currentMinute = 0;
var currentSecond = 0;
var time = 0;
var currentDate = new Date();
if (type == "U") {
currentHour = currentDate.getUTCHours(); // UTC
} else if (type == "B") {
currentHour = currentDate.getHours(); // Viewer's time
} else {
currentHour = currentDate.getUTCHours() + ofs; // your local time
if(currentHour < 0) { currentHour = currentHour + 24;}
}
currentMinute = currentDate.getMinutes();
currentMinute = (currentMinute < 10 ? "0" : "") + currentMinute;
if (hours == "24") {
if(currentHour == 24) { currentHour = 0 }; // use if wanting 24 hour time
currentHour = (currentHour < 10 ? "0" : "") + currentHour;
} else if (hours == "12") {
if(currentHour == 0) currentHour = 12;
currentHour = (currentHour < 10 ? "0" : "") + currentHour;
} else {
if(currentHour == 0) currentHour = 12; // else no leading zero for am/pm
}
time = currentHour + ":" + currentMinute;
if (secs) {
currentSecond = currentDate.getSeconds();
currentSecond = (currentSecond < 10 ? "0" : "") + currentSecond;
time = time + ":" + currentSecond;
}
if (hours == "12a") {
time = time + " " + (currentHour > 12 ? "PM" : "AM");
}
return time;
}
//This function is only used if you leave the debug checkbox below
// You can remove this function and the checkbox and set the debug
// mode using the dbg=y query parameter
function debug(obj){
if (obj.checked) {
dbg='y';
} else {
dbg='n';
if (document.getElementById('div1') != null) document.body.removeChild(document.getElementById("div1"));
//document.getElementById('TheDiv').innerHTML = '';
}
}
//This function is only used if you leave the Force Update checkbox below
// You can remove this function and the checkbox and set the force
// mode using the force=y query parameter
function forceupdate(obj){
if (obj.checked) {
force='y';
} else {
force='n';
}
}
//This function parses out the query parameter value
function gup( name ){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
Here is a link to the full .js map code for V3 if anyone needs to see it.
V3 NSGAMP CODE
V3 FULL PAGE
EDIT: I think it has to do with this snippet of code that is suppose to remove then add the updated KML data to the map.
This was in V2 which is depreciated now.
// add back overlays
map.removeOverlay(geoXml); //Remove overlays
geoXml = new GGeoXml(URLToKML + "?rand="+(new Date()).valueOf() ); //rand is used to trick google maps into thinking this is a new KML (don't use cache version)
map.addOverlay(geoXml); //Add the new data from the newly generated KML
Code I updated for V3 replacing the above depreciated V2 snippet which was found by searching. Not sure if this is correct but it was all I could find.
// add back overlays
nyLayer = new google.maps.KmlLayer(null);
nyLayer.setMap(null); // Remove overlays
function refresh(layer) {
var nyLayer = new google.maps.KmlLayer(URLToKML + "?rand="+(new Date()).valueOf(),
{
suppressInfoWindows: false,
map: map,
preserveViewport: true,
zIndex: 999
});
}
I got it sorted and working and I knew it was a simple edit but I was having a really difficult time finding a solution. If anyone else this could help this is what I did.
Changed this in the V2 version.
updateHTML(resp); //This calls the updateHTML function if there is info returned
}
}
}
xmlhttp.send(null);
// add back overlays
map.removeOverlay(geoXml); //Remove overlays
geoXml = new GGeoXml(URLToKML + "?rand="+(new Date()).valueOf() ); //rand is used to trick google maps into thinking this is a new KML (don't use cache version)
map.addOverlay(geoXml); //Add the new data from the newly generated KML
To this in the V3 version.
updateHTML(resp); // This calls the updateHTML function if there is info returned
}
//remove layer
window.nyLayer.setMap(null);
//change its url so that we would force the google to refetch data
window.nyLayer.url = URLToKML + "?rand="+(new Date()).valueOf();
//and re-add layer
window.nyLayer.setMap(window.map);
}
}
xmlhttp.send(null);
The map.removeOverlay and map.addOverlay is depreciated in V3 so it took me while to find the replacement.
Or you can simplify it even further and use:
window.nyLayer.url = URLToKML + '&ver=' + Date.now();

Categories

Resources