Is it possible to support different locales, not making use of Google Web Translation Tool?
Web translation does not seems to be working with Google Sites, once generated code (javascript) is considered invalid by the Google Sites page editor (Edit HTML). Head based meta tags are also not supported.
Make a new site for each locale and synchronize their page structures. You could also create machine translated versions using this script (although they would need fixing by a native speaker):
function localizepagestolocalizedsites() {
var fromblog = SitesApp.getPageByUrl("https://sites.google.com/a/yourdomain.com/english/home");
var toblog = SitesApp.getPageByUrl("https://sites.google.com/a/yourdomain.com/japanese/home");
var nextbloc = 0;
while (true) {
var pages = fromblog.getAllDescendants({"start":nextbloc,"max":100});
if (pages.length > 0){
Logger.log("starting at.."+nextbloc+" there are .."+pages.length+" pages starting with.."+pages[0].getTitle());
var i = nextbloc;
for (var x in pages) {
var localizedTitle = LanguageApp.translate(pages[x].getTitle(), "en", "ja");
var localizedBody = LanguageApp.translate(pages[x].getHtmlContent(), "en", "ja");
toblog.createWebPage(localizedTitle, pages[x].getName(), localizedBody);
i = i + 1;
}
} else {
break;
}
nextbloc = nextbloc + 100;
}
}
Related
I have found an extremely good google script for a google form that allows me to retrieve the answers of a google form in a spreadsheet along with the "getEditResponseUrl()" that will help me build a database that can be modified through the google form.
However, I am struggling in getting the url of an "upload file question". The question where the user is supposed to upload a file is the fourth one "facture".
The answer I get in my spreadsheet is only "[Ljava.lang.Object;#508c8b8b" but not the file.
Any idea how to make this work so that I get the url of the file that was uploaded by the user ?
Thank you and Kind regards
var ss = SpreadsheetApp.openById("spreadsheeturl"); // to be customised
var responseSheet = "Database"; // to be customised
function submitFormFunc(e) {
var items = e.response.getItemResponses();
var responses={};
for(var i = 0; i< items.length; i++) {
responses[items[i].getItem().getTitle()]=items[i].getResponse();
}
var responseRow = [];
responseRow.push(e.response.getTimestamp().toString());
responseRow.push(e.response.getId());
responseRow.push(responses["Challenge"]); // to be customised
responseRow.push(responses["Client"]);
responseRow.push(responses["Date"]);
responseRow.push(responses["Facture"]);
// to be customised
// add as many as needed
responseRow.push(FormApp.getActiveForm().getResponse(e.response.getId()).getEditResponseUrl());
var isNewItem = alreadyExist(ss,e.response.getId());
if(isNewItem<0){
ss.getSheetByName(responseSheet).appendRow(responseRow);
}
else{
ss.getSheetByName(responseSheet).getRange(isNewItem+2, 1, 1, 6).setValues([responseRow]);
}
}
function alreadyExist(ss,id){
var ids = ss.getSheetByName(responseSheet).getRange("B2:B").getValues();
for(var i=0; i< ids.length; i++){
if(ids[i][0]===id){
return(i);
}
}
return(-1);
}
Here's a snippet from the Form Notifications add-on that converts the uploaded file ids into Google Drive URLs and concatenates the result in case of multiple uploads.
var urls = answer.toString().split(",").map(function(f) {
return "https://drive.google.com/open?id=" + f;
}).join(", ");
I want to get speaker notes from Google Slides by API, but I could not find any fields for speaker notes.
For reference: Method: presentations.pages.get
What would be a good way to do this?
Support for speaker notes is now available in the Slides API v1. Documentation is here: https://developers.google.com/slides/how-tos/notes
In the absence of the API, I wouldn't suggest this is a good way of doing it. In fact it is horrible. But here it is. If you absolutely had to do it. It is likely a bit flakey too.
Steps are:
Export the presentation, via the Drive API, as a PowerPoint .pptx file
Unpack the file - it is a zip file containing a directory structure with XML files in.
Identify the speaker notes files and process them as per your requirement (e.g. extract all text, or work on the XML etc).
Ugly right? Here's an example in Apps Script:
Enable Drive API in Advanced Services within your script (Resources > Advanced Google Services).
function example() {
// Print out the speaker notes
Logger.log(getNotes('123abc......asd'));
}
// Returns an array of strings, one string per slide
// representing the speaker notes.
function getNotes(presentationId) {
//DriveApp.createFile();
var notesRegex = /ppt\/notesSlides\/notesSlide\d+\.xml/;
var url = 'https://www.googleapis.com/drive/v2/files/' + presentationId +
'/export?mimeType=application%2Fvnd.openxmlformats-officedocument.presentationml.presentation';
var options = {
headers: {
Authorization : 'Bearer ' + ScriptApp.getOAuthToken()
}
};
var response = UrlFetchApp.fetch(url, options);
var zipBlob = Utilities.newBlob(response.getContent(), 'application/zip');
var data = Utilities.unzip(zipBlob);
var notes = [];
for (var i = 0; i < data.length; i++) {
if (notesRegex.test(data[i].getName())) {
// Example simply extracts text from speaker notes
// You could do something more complex.
notes.push(extractTextFromXml(data[i].getDataAsString()));
}
}
return notes;
}
function extractTextFromXml(xml) {
var doc = XmlService.parse(xml);
var root = doc.getRootElement();
var ns = root.getNamespace('a');
var text = [];
function walkNode(node) {
if (node.getText()) {
text.push(node.getText());
}
var children = node.getChildren();
if (children.length) {
children.forEach(function(child) {
walkNode(child);
});
}
}
walkNode(root);
return text.join('\n');
}
I'm converting a generated doc to a pdf and to png's, see the code below. But for some reason there is something wrong with the fonts. On my local develop machine everything is right, but when deployed on the production servers the fonts in the PNG's are missing. I've checked but they are installed on the servers. Can someone help me with this?
var dstDoc = doc.Clone();
var newInvoice = new InvoicePdf(factuur);
var ds = newInvoice.ToDataSet();
dstDoc.BuiltInDocumentProperties.Title = newInvoice.InvoiceID;
dstDoc.BuiltInDocumentProperties.Subject = newInvoice.SendDate;
dstDoc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();
dstDoc.MailMerge.ExecuteWithRegions(ds);
var filePath = Path.Combine(folderInvoices, newInvoice.SendDateOrginal.Year.ToString(CultureInfo.InvariantCulture));
Directory.CreateDirectory(filePath);
var fileName = string.Format("{0} - {1}", newInvoice.InvoiceID, newInvoice.DebtorCompany.ToString(true));
filePath = Path.Combine(filePath, fileName);
filePaths.Add(filePath + ".pdf");
dstDoc.Save(filePath + ".pdf", SaveFormat.Pdf);
var options = new ImageSaveOptions(SaveFormat.Png) { PageCount = 1, Resolution = 120, UseAntiAliasing = true, PrettyFormat = true, UseHighQualityRendering = true };
for (var i = 0; i < dstDoc.PageCount; i++)
{
options.PageIndex = i;
dstDoc.Save(string.Format("{0}_{1}.png", filePath, i), options);
}
If it is a shared server, then most probably it is a security issue. Aspose.Words for .NET DLL needs access to the Windows registry, to find the fonts folder. Refer to http://www.aspose.com/docs/display/wordsnet/Considerations+When+Running+on+a+Shared+Server+Environment for more details.
A workaround is also possible to specify the path of folder, which has all the required fonts. Please see http://www.aspose.com/docs/display/wordsnet/How+to++Specify+True+Type+Fonts+Location for sample code.
I work with Aspose as Developer evangelist.
I'm need a way to save the current page (including, images, CSS, etc.) from an add-on.
Of course I found the saveDocument() function in the SDK but I was not able to make it work.
from add-on script, I do not have access to actual DOM content
from content script, I do not have access to SDK function 'saveDocument()'
I miss something, I would be very happy if someone could help me.
Best regards,
Fred
here's one way to access the DOM document from addon script.
var winutil = require('sdk/window/utils');
function findDocument(predicate){
// searching in focused window only
// you can also get all windows with winutil.windows('navigator:browser')
var win = winutil.getMostRecentBrowserWindow();
var gBrowser = win.gBrowser;
// traverse tabs of focused window
for (var i=0, l=gBrowser.browsers.length; i<l; i++)
{
var br = gBrowser.getBrowserAtIndex(i);
var doc = br.contentDocument;
if (predicate(doc))
return doc;
}
}
// and this is probably how you would save (not tested)
var {Cc, Ci} = require('chrome');
var wbp = Cc["#mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(Ci.nsIWebBrowserPersist);
var doc = findDocument(/* whatever */);
if (doc)
wbp.saveDocument(doc, /* figure out other args */);
I m trying to use get and list method with google plus comment. In official site it said (All API calls require either an OAuth 2.0 token or an API key. ) and I have tried send GET request without the step of OAuth it works it returns json format data. My question is OAuth must require before using google+ API?
It depends on exactly what data you're trying to get.
https://developers.google.com/+/api/oauth documents the benefits of using OAuth, but in general, if you want to get private profile data, or if you wish to use the /me/ URL shortcut, you will need to use OAuth and may, if you wish, use an App Key in addition. If all you're interested in is public data, you can use the App Key.
The short answer to whether you can do it is that you can get comments from Google+ without OAuth.
As for the how would you do this, I'm not sure which language you're doing this in but the following code shows how this is done in JavaScript.
The API calls used here can be experimented with in the API explorer:
Listing Activities
Listing Comments
A demo of this code is here.
You will need an API key (the simple key) for a project with the Google+ APIs from the Google APIs console. When you set up the project, you will only need to enable the Google+ API from the services section.
First, grab the activities using the public data API:
// Gets the activities for a profile
function getActivities(profileID){
var activities = null;
var URL = "https://www.googleapis.com/plus/v1/people/" + profileID + "/activities/public?alt=json&key=" + key;
var request = new XMLHttpRequest();
request.open('GET', URL, false);
request.send(); // because of "false" above, will block until the request is done
// and status is available. Not recommended, however it works for simple cases.
if (request.status === 200) {
if (debug) console.log("retrieved activities \n\n");
var activities = jQuery.parseJSON(request.responseText).items;
console.log("Discovered " + activities.length + " activities");
}else{
handleRequestIssue(request);
}
return activities;
}
The following code loops through the activities
for (var i=0; i < activities.length; i++) {
console.log("trying to do something with an activity: " + i);
var activity = activities[i];
console.log(activity.id);
}
Next, you can use the activity IDs to retrieve the comments per activity:
function getCommentsForActivity(activityID){
var comments = "";
var URL = "https://www.googleapis.com/plus/v1/activities/" + activityID + "/comments?alt=json&key=" + key;
var request = new XMLHttpRequest();
request.open('GET', URL, false);
request.send(); // because of "false" above, will block until the request is done
// and status is available. Not recommended, however it works for simple cases.
if (request.status === 200) {
if (debug) console.log(request.responseText);
var comments = jQuery.parseJSON(request.responseText).items;
if (debug){
for (comment in comments){
console.log(comment);
}
}
}else{
handleRequestIssue(request);
}
return comments;
}
function manualTrigger(){
var activities = getActivities("109716647623830091721");
}
The following code brings it all together and retrieves activities and comments for a specific post:
$(document).ready(function () {
var renderMe = "";
var activities = getActivities("109716647623830091721");
console.log("activities retrieved: " + activities.length);
for (var i=0; i < activities.length; i++) {
console.log("trying to do something with an activity: " + i);
var activity = activities[i];
renderMe += "<br/><div class=\"article\"><p>" + activity.title + "</p>";
console.log(activity.id);
// get comments
var comments = getCommentsForActivity(activity.id);
for (var j=0; j<comments.length; j++){
renderMe += "<br/><div class=\"comment\">" + comments[j].object.content + "</div>";
}
renderMe += "</div>";
}
console.log("I'm done");
document.getElementById("ac").innerHTML = renderMe;
});