How to append one Google Doc to another using APIv1 - google-docs-api

I'm writing a merging program. Instead of creating one document per input row, I want the merged (template with input values replaced) output from each input row added to a single document.
And the template is not just text. It's another Google doc with a standalone table.
I started with the mail merge example and it works fine but produces a separate doc for each input row. I've written a helper function that I call for each output doc, with "dest_doc" set to my summary doc.
Sadly, this does not work since the API seems only to permit unstyled text insertion, not contents-from-a-Doc.
It works fine when using 'hello world ' -- this is properly replicated in the output file. But when I replace it with body or body['contents'] it fails.
Is there any way of doing this? I'd balk at writing a contents-tree-to-UpdateRequest translator.
def append_contents(dest_doc, source_doc):
"""Copy the contents of the source doc to the end of the destination doc
"""
document = DOCS.documents().get(documentId=source_doc).execute()
body = document.get('body')
requests = [
{
'insertText': {
'endOfSegmentLocation': {
'segmentId': '',
},
'text': 'hello world '
}
},
]
DOCS.documents().batchUpdate(documentId=dest_doc, body={'requests': requests}).execute()
return
Thanks for your time.

Unfortunately you can't use the insertText request to append a complex object (as the Body of another Document) to your Document. This request only accepts text.
I'm afraid that the only solution here would be to parse the elements of your documents and create a request translator for each one of their types.
Even in Apps Script as you can see in this example, the merge is done element per element according to its type (Text, Table, Image, Paragraph, etc.).
However, if this feature is really important to you, you should definitely submit a feature request here

Related

How can I use a Lua module in MediaWiki to display graphs

I currently have a Lua module that does some manipulation on data it is passed then I would like it to display a graph on an article.
I am having trouble getting the graph displaying properly however I have tried a couple of approaches thus far:
Output in the form of {{Graph:Chart|variablesHere}} using the graph template as is recommended on the extension page, which works fine usually. The problem with this approach is that (I assume) because it comes from a module the text isn't actually processed by MediaWiki and therefore display plaintext.
Using require('Module:Graph') and and printing the output to the page, however it does not correctly make a graph either as it isn't properly formatted and I haven't been able to understand how to convert it like Template:Graph:Chart does
Just looking for any suggestions on where to go from here.
Use frame:preprocess(string_containing_templates) to expand a string that contains templates such as Template:Graph:Chart.
If you want to avoid preprocessing, you could call the chart function of Module:Graph, but it is complicated to get the same result as expanding Template:Graph:Chart because you have to translate the contents of Template:Chart:Graph to Lua. To generate the same content as frame:preprocess("{{Graph:Chart|width=100|height=100|x=1|y=1}}"), you would do:
frame:extensionTag("templatestyles", nil, { src = "Graph:Chart/styles.css" })
.. frame:extensionTag (
"graph",
require("Module:Graph").chart { args = { width = '100', height = '100', x = '1', y = '1' } }
)
Here frame must be a frame object. Not very pretty, and if any changes are made to the template, they won't be reflected in your module code. So it is probably best to just preprocess the template.

Access all fields in Zapier Code Step

Is it possible to access all the fields from a previous step as a collection like json rather than having to explicitly setting each one in the input data?
Hope the screenshot illustrates the idea:
https://www.screencast.com/t/TTSmUqz2auq
The idea is I have a step that lookup responses in a google form and I wish to parse the result to display all the Questions and Answer into an email.
Hope this is possible
Thanks
David here, from the Zapier Platform team. Unfortunately, what I believe you're describing right now isn't possible. Usually this works fine since users only map a few values. The worst case is when you want every value, which it sounds like you're facing. It would be cool to map all of them. I can pass that along to the team! In the meantime, you'll have to click everything you're going use in the code step.
If you really don't want to create a bunch of variables, but you could map them all into a single input and separate them with a separator like |, which (as long as it doesn't show up in the data), it's easy to split in the code step.
Hope that helps!
The simplest solution would be to create an additional field in the output object that is a JSON string of the output. In a Python code step, it would look like
import json
output = {'id': 123, 'hello': 'world'}
output['allfields'] = json.dumps(output)
or for returning a list
import json
output = [{'id': 123, 'hello': 'world'},{'id': 456, 'bye': 'world'}]
for x in output:
x['allfields'] = json.dumps(output[output.index(x)])
Now you have the individual value to use in steps as well as ALL the values to use in a code step (simply convert them from JSON). The same strategy holds for Javascript as well (I simply work in Python).
Zapier Result
Fields are accessible in an object called input_data by default. So a very simplistic way of grabbing a value (in Python) would be like:
my_variable = input_data['actual_field_name_from_previous_step']
This differs from explicitly naming the the field with Input Data (optional). Which as you know, is accessed like so:
my_variable = input['your_label_for_field_from_previous_step']
Here's the process description in Zapier docs.
Hope this helps.

Ruby REXML: Get Value Of An XML Element

I am trying to put the values of some xml elements into an array using rexml. Here is an example of what I am doing:
doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
puts element.text
}
However, that outputs:
[<title> ... </>, <title> ... </>]
How can I get it to output an array containing "This is one title" and "This is another title"?
Moving my comment to an answer, per request:
While puts may convert its argument its argument to a string anyway, you can have the XPath return the text node in the first place:
XPath.each(doc, "*/title/text()") {...
Are you sure about that? Here's a complete program:
#!/usr/bin/ruby
require 'rexml/document'
include REXML
doc = Document.new("<data><title>This is one title</title><title>This is another title</title></data>")
XPath.each( doc, "*/title") { |element|
puts element.text
}
Output:
This is one title
This is another title
Edit: It sounds like the OP has moved on, but I think there should be some clarification added here for future visitors. I upvoted #LarsH's good answer, but it should be noted that, given the OP's specific input, element.text should produce exactly the same output as would result from selecting the text() nodes in the first place. From the docs:
text( path = nil )
A convenience method which returns the String value
of the first child text element, if one exists, and nil otherwise.
The sample input given in the original question shows <title> elements containing only one text node in each case. Therefore, these two methods are the same (in this case).
However, pay attention to this important note:
Note that an element may have multiple Text elements, perhaps
separated by other children. Be aware that this method only returns
the first Text node.
You can get all of an element's child text nodes using texts() (plural).
What I suspect a lot of people are really looking for is an equivalent of the DOM's textContent (or its illegitimate cousin innerText). Here's how you might do that in Ruby:
XPath.each(doc, "*/title") { |el|
puts XPath.match(el,'.//text()').join
}
This joins all of the text descendants of each element into a single string.
The short answer is that there's no short answer. Which one of these you want, if any, is highly context-specific. The only requirement in the original question is to "put the values of some xml elements into an array", which isn't really much of a specification.

How can I populate a jQuery template (tmpl) using HTML5 Local Storage data

I am trying to build a simple jQuery UI template and populate it with data stored in the localStorage.
I need to set the local storage with a list of guests and have the user edit the list. When clicking update, the changes are sent back to the server.
<ul id="guests">
<li>
Name: ${name} <br />
Phone: ${phone} <br />
Email: ${email}
</li>
</ul>
I am really new at this and have no idea what to do. I am just interested in setting the local storage when the page loads and populating the template.
Can someone please provide a short tutorial?
I thought this is a simple question... Can someone please let me know in case it is not possible at all? Thanks!
you say you want to save the data to localStorage, but also that you want to send modified data to the server.
I would suggest that you divide this problem up into (Part 1) learning how to save locally to localStorage and rendering that content with templating and then (Part 2) learning how to store on a server. I can help you with Part 1, since quite frankly I'm still learning about Part 2 myself.
Okay so, two subtasks:
using localStorage to persist data
using jQuery templates to render data
Using localStorage
You haven't specified where your data is coming from, so I'll assume you have some JSON. For simplicity I'll just use this data:
(You might be wondering why I added content that isn't plain ASCII -- it's just a habit of mine, I believe in testing with realistic text from the get-go. When we finally render this data, it should look right in your browser.)
var philosophers = [
{
"phone": "1-800-123-1937",
"name": "H\u00e9l\u00e8ne Cixous",
"email": "helene#stanford.edu"
},
{
"phone": "1-800-000-0000",
"name": "\u041c\u0438\u0445\u0430\u0438\u0301\u043b \u0411\u0430\u043a\u0443\u0301\u043d\u0438\u043d",
"email": "mikhail#ispitondns.com"
},
{
"phone": "1-800-770-0830",
"name": "Jayar\u0101\u015bi Bha\u1e6d\u1e6da",
"email": "jay#ancientindia.edu"
}
]
So we need to get this into localStorage, just to have some data to start with.
The trick about localStorage is that you can't just directly store JSON objects. You can only store strings. There are some libraries out there designed to improve on this situation, but we'll just convert our objects ourselves. To do that we'll use JSON:
localStorage.philosophers = JSON.stringify(philosophers)
Unsurprisingly, JSON.stringify turns JSON objects into a string, and that can be set directly as an "attribute" of localStorage.
(If you're using an old browser, then you might not have the native JSON object -- there's a library you can include for that too.)
Okay, so now we have some contact data stashed in localStorage with the label of philosophers. (Hey, you never know when you might need to call a philosopher!)
To get that data back out and into a Javascript object we can do something with, we use another JSON method, JSON.parse.
philosophers = JSON.parse(localStorage.philosophers)
This is all pretty artificial, since we've got the philosophers data in the first place, then we stringify it, and then we store it, and then we take it right back out, and then we parse it, and then we're back where we started. But in reality such data will come from some other source -- perhaps an external file or a web service or whatever.
Using templates to render objects
Since you used what looks like jQuery template syntax in your template, I'm going to assume that's the library you're using. The jQuery docs show us how we can render a variable containing some objects (like what we have in our philosophers variable) with a template, here's the key bit of those docs:
// Convert the markup string into a named template
$.template( "summaryTemplate", "<li>${Name}</li>" );
function renderList() {
// Render the movies data using the named template: "summaryTemplate"
$.tmpl( "summaryTemplate", movies ).appendTo( "#moviesList" );
}
Here's one way you can get your template to work (there are other, arguably cleaner methods, but jQuery templates are a topic unto themselves):
var myTemplate = "<li>Name: ${name}<br/>Phone: ${phone}<br/>Email: ${email}</li>";
$.template("contactLi", myTemplate);
That creates a template and stores it in a variable named contentLi. (Note that $.template wants that given variable name given as a string, which strikes me as weird. I find the way jQuery templates names and defines these methods confusing, which is one of the reasons I prefer Mustache for templating. Shrug.)
Also, note that we don't have the ul included in the template, because that's not going to be repeated for each rendered object. Rather, we're going to add the ul as a hook in the markup, and render the assembled template repeatedly as a child of that. Which just takes a single line with jQuery templates, rather nice:
$.tmpl( "contactLi", philosophers ).appendTo( "#guests" );
So there you go, a rendered list.
I know this doesn't answer your whole question but there's a lot here to start with.
Here's an example you can try out, it ends up rendering something like:
Name: Hélène Cixous
Phone: 1-800-123-1937
Email: helene#stanford.edu
Name: Михаи́л Баку́нин
Phone: 1-800-000-0000
Email: mikhail#ispitondns.com
Name: Jayarāśi Bhaṭṭa
Phone: 1-800-770-0830
Email: jay#ancientindia.edu
(Hehe, boy, SO's syntax highlighting doesn't handle that Unicode text very well!)
try AmplifyJS -- can extract your data as json the same way you would as $.getJSON

Is there a way to automatically grab all the elements on the page using Selenium?

When creating tests for .Net applications, I can use the White library to find all elements of a given type. I can then write these elements to an Xml file, so they can be referenced and used for GUI tests. This is much faster than manually recording each individual element's info, so I would like to do the same for web applications using Selenium. I haven't been able to find any info on this yet.
I would like to be able to search for every element of a given type and save its information (location/XPath, value, and label) so I can write it to a text file later.
Here is the ideal workflow I'm trying to get to:
navigate_to_page(http://loginscreen.com)
log_in
open_account
button_elements = grab_elements_of_type(button) # this will return an array of XPaths and Names/IDs/whatever - some way of identifying each grabbed element
That code can run once, and I can then re-run it should any elements get changed, added, or removed.
I can then have another custom function iterate through the array, saving the info in a format I can use later easily; in this case, a Ruby class containing a list of constants:
LOGIN_BUTTON = "//div[1]/loginbutton"
EXIT_BUTTON = "//div[2]/exitbutton"
I can then write tests that look like this:
log_in # this will use the info that was automatically grabbed beforehand
current_screen.should == "Profile page"
Right now, every time I want to interact with a new element, I have to manually go to the page, select it, open it with XPather, and copy the XPath to whatever file I want my code to look at. This takes up a lot of time that could otherwise be spent writing code.
Ultimately what you're looking for is extracting the information you've recorded in your test into a reusable component.
Record your tests in Firefox using the Selenium IDE plugin.
Export your recorded test into a .cs file (assuming .NET as you mentioned White, but Ruby export options are also available)
Extract the XPath / CSS Ids and encapsulate them into a reusable classes and use the PageObject pattern to represent each page.
Using the above technique, you only need to update your PageObject with updated locators instead of re-recording your tests.
Update:
You want to automate the record portion? Sounds awkward. Maybe you want to extract all the hyperlinks off a particular page and perform the same action on them?
You should use Selenium's object model to script against the DOM.
[Test]
public void GetAllHyperLinks()
{
IWebDriver driver = new FireFoxDriver();
driver.Navigate().GoToUrl("http://youwebsite");
ReadOnlyCollection<IWebElement> query
= driver.FindElements( By.XPath("//yourxpath") );
// iterate through collection and access whatever you want
// save it to a file, update a database, etc...
}
Update 2:
Ok, so I understand your concerns now. You're looking to get the locators out of a web page for future reference. The challenge is in constructing the locator!
There are going to be some challenges with constructing your locators, especially if there are more than one instance, but you should be able to get far enough using CSS based locators which Selenium supports.
For example, you could find all hyperlinks using an xpath "//a", and then use Selenium to construct a CSS locator. You may have to customize the locator to suit your needs, but an example locator might be using the css class and text value of the hyperlink.
//a[contains(#class,'adminLink')][.='Edit']
// selenium 2.0 syntax
[Test]
public void GetAllHyperLinks()
{
IWebDriver driver = new FireFoxDriver();
driver.Navigate().GoToUrl("http://youwebsite");
ReadOnlyCollection<IWebElement> query
= driver.FindElements( By.XPath("//a") );
foreach(IWebElement hyperLink in query)
{
string locatorFormat = "//a[contains(#class,'{0}')][.='{1}']";
string locator = String.Format(locatorFormat,
hyperlink.GetAttribute("class"),
hyperlink.Value);
// spit out the locator for reference.
}
}
You're still going to need to associate the Locator to your code file, but this should at least get you started by extracting the locators for future use.
Here's an example of crawling links using Selenium 1.0 http://devio.wordpress.com/2008/10/24/crawling-all-links-with-selenium-and-nunit/
Selenium runs on browser side, even if you can grab all the elements, there is no way to save it in a file. As I know , Selenium is not design for that kinds of work.
You need to get the entire source of the page? if so, try the GetHtmlSource method
http://release.seleniumhq.org/selenium-remote-control/0.9.0/doc/dotnet/html/Selenium.DefaultSelenium.GetHtmlSource.html

Resources