JSON body in text form - json

I need to do this, but replace the hard text with one that comes from another feature, otherwise it won't work, since karate assumes that everything is json, and I don't want it to assume that, my idea is to send it as text , just as you paste the code excerpt.
* text body =
"""
{ tags: '{"revision":"master"}', wurl: 'https://github.com/abc/repo', params: '{"a":"b"}', type: 'testflow' }
"""
* request body
im test
* def responseBody = callonce read('classpath:integration/helpers/steps/create_sign.feature')
* def bodyText = responseBody.resultado
* text body =
"""
#(bodyText)
"""
* request body
but it doesn't work

Related

How can you change all appearances of a text response in Karate DSL without having a placeholder?

I am wondering if it is possible to change all occurrences of a text in a Json response from a Karate DSL text without having a placeholder. For example , the fragment "https://thisisthepart.tochange" appears many times in the json response of karate dsl. I cannot do it with "set" because i do not know for which keys is going to appear that text.
"imageUrl": ["https://thisisthepart.tochange/idontwannachange/thispart"]
Thanks in advance
Yes, convert to a string, use the Java API String.replace() and re-convert:
* string response = response
* json response = response.replace('foo', 'bar')
Also refer: https://github.com/intuit/karate#type-conversion
EDIT: note that you can "re-build" JSON using a loop:
* def before = { a: 'hello', b: 'world' }
* def after = {}
* def fun = function(k, v){ after[k] = v + 'edit' }
* karate.forEach(before, fun)
* match after == { a: 'helloedit', b: 'worldedit' }

headers and footers in python-docx

I want to read header and footer text for a docx file in Python. I am using python-docx module.
I found this documentation - http://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html
But I do not think it has been implemented yet. I also see that there is a "feature-headers" branch in github for python-docx - https://github.com/danmilon/python-docx/tree/feature-headers
Seems like this feature never got into master branch. Anyone used this feature? Can you help me on how to use it?
Thank you very much.
There is a better solution to this problem :
Method Used to extract
using MS XML Word document
just zip the word document using zip module, It will give you access to xml format of word document, then you can use simple xml node extraction for text.
Following is the working code that extracts Header, Footer, Text Data from a docx file.
try:
from xml.etree.cElementTree import XML
except ImportError:
from xml.etree.ElementTree import XML
import zipfile
WORD_NAMESPACE = '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
PARA = WORD_NAMESPACE + 'p'
TEXT = WORD_NAMESPACE + 't'
def get_docx_text(path):
"""
Take the path of a docx file as argument, return the text in unicode.
"""
document = zipfile.ZipFile(path)
contentToRead = ["header2.xml", "document.xml", "footer2.xml"]
paragraphs = []
for xmlfile in contentToRead:
xml_content = document.read('word/{}'.format(xmlfile))
tree = XML(xml_content)
for paragraph in tree.getiterator(PARA):
texts = [node.text
for node in paragraph.getiterator(TEXT)
if node.text]
if texts:
textData = ''.join(texts)
if xmlfile == "footer2.xml":
extractedTxt = "Footer : " + textData
elif xmlfile == "header2.xml":
extractedTxt = "Header : " + textData
else:
extractedTxt = textData
paragraphs.append(extractedTxt)
document.close()
return '\n\n'.join(paragraphs)
print(get_docx_text("E:\\path_to.docx"))

Sending html in JSON, R

I have an html output in the form of a table and I want to send that with my JSON eventually via a POST for an api.
I have removed tags and troubleshot it but doesnt work. Is there a specific library that I can use in R to achieve this parsing?
I am using simple paste() to parse that html page and insert it into JSON's 'value'.
I first save my data.frame(list) as html then I try to parse it.
mydoc = bsdoc( title = 'xxx' )
mydoc= addFlexTable( mydoc, flextable = output_as_flex)
mydoc = addParagraph( mydoc, value = "<br>")
writeDoc(mydoc,file ="C://yyy.html")
tree=htmlTreeParse("C://yyy.html")
Here I follow the Confluence Rest Api's format to form this string for JSON. Data has to be passed(I am passing a variable in paste) as html where 'h_h'
data <- paste(sep='','{"type":"page","title":',
'"xxx",',
'"ancestors":[{"id":',123123,'}],"space":{"key":"','xxx','"},"body":{"storage":{"value":"',h_h,'","representation":"storage"}}}')
httr::set_config(config(ssl_verifypeer=FALSE))
URL <- "xxx/rest/api/content"
response = POST(URL, authenticate("xx", "xx"), body = data, verbose(),add_headers('Content-Type' = 'application/json;charset=utf-8','Cache-Control'='no-cache'))
response
http_status(response)
warn_for_status(response)
stop_for_status(response)
I want to upload that html table formed as output_as_flex to the api and eventually to the confluence page.
Thanks.

Parse HTML in Scala

Task: HTML - Parser in Scala. Im pretty new to scala.
So far: I have written a little Parser in Scala to parse a random html document.
import scala.xml.Elem
import scala.xml.Node
import scala.collection.mutable.Queue
import scala.xml.Text
import scala.xml.PrettyPrinter
object Reader {
def loadXML = {
val parserFactory = new org.ccil.cowan.tagsoup.jaxp.SAXFactoryImpl
val parser = parserFactory.newSAXParser()
val source = new org.xml.sax.InputSource("http://www.randomurl.com")
val adapter = new scala.xml.parsing.NoBindingFactoryAdapter
val feed = adapter.loadXML(source, parser)
feed
}
def proc(node: Node): String =
node match {
case <body>{ txt }</body> => "Partial content: " + txt
case _ => "grmpf"
}
def main(args: Array[String]): Unit = {
val content = Reader.loadXML
Console.println(content)
Console.println(proc(content))
}
}
The problem is that the "proc" does not work. Basically, I would like to get exactly the content of one node. Or is there another way to achieve that without matching?
Does the "feed" in the loadxml-function give me back the right format for parsing or is there a better way to achieve that? Feed gives me back the root node, right?
Thanks in advance
You're right: adapter.loadXML(source, parser) gives you the root node. The problem is that that root node probably isn't going to match the body case in in your proc method. Even if the root node were body, it still wouldn't match unless the element contained nothing but text.
You probably want something more like this:
def proc(node: Node): String = (node \\ "body").text
Where \\ is a selector method that's roughly equivalent to XPath's //—i.e., it returns all the descendants of node named body. If you know that body is a child (as opposed to a deeper descendant) of the root node, which is probably the case for HTML, you can use \ instead of \\.

Strange Base64 encode/decode problem

I'm using Grails 1.3.7. I have some code that uses the built-in base64Encode function and base64Decode function. It all works fine in simple test cases where I encode some binary data and then decode the resulting string and write it to a new file. In this case the files are identical.
But then I wrote a web service that took the base64 encoded data as a parameter in a POST call. Although the length of the base64 data is identical to the string I passed into the function, the contents of the base64 data are being modified. I spend DAYS debugging this and finally wrote a test controller that passed the data in base64 to post and also took the name of a local file with the correct base64 encoded data, as in:
data=AAA-base-64-data...&testFilename=/name/of/file/with/base64data
Within the test function I compared every byte in the incoming data parameter with the appropriate byte in the test file. I found that somehow every "+" character in the input data parameter had been replaced with a " " (space, ordinal ascii 32). Huh? What could have done that?
To be sure I was correct, I added a line that said:
data = data.replaceAll(' ', '+')
and sure enough the data decoded exactly right. I tried it with arbitrarily long binary files and it now works every time. But I can't figure out for the life of me what would be modifying the data parameter in the post to convert the ord(43) character to ord(32)? I know that the plus sign is one of the 2 somewhat platform dependent characters in the base64 spec, but given that I am doing the encoding and decoding on the same machine for now I am super puzzled what caused this. Sure I have a "fix" since I can make it work, but I am nervous about "fixes" that I don't understand.
The code is too big to post here, but I get the base64 encoding like so:
def inputFile = new File(inputFilename)
def rawData = inputFile.getBytes()
def encoded = rawData.encodeBase64().toString()
I then write that encoded string out to new a file so I can use it for testing later. If I load that file back in as so I get the same rawData:
def encodedFile = new File(encodedFilename)
String encoded = encodedFile.getText()
byte[] rawData = encoded.decodeBase64()
So all that is good. Now assume I take the "encoded" variable and add it to a param to a POST function like so:
String queryString = "data=$encoded"
String url = "http://localhost:8080/some_web_service"
def results = urlPost(url, queryString)
def urlPost(String urlString, String queryString) {
def url = new URL(urlString)
def connection = url.openConnection()
connection.setRequestMethod("POST")
connection.doOutput = true
def writer = new OutputStreamWriter(connection.outputStream)
writer.write(queryString)
writer.flush()
writer.close()
connection.connect()
return (connection.responseCode == 200) ? connection.content.text : "error $connection.responseCode, $connection.responseMessage"
}
on the web service side, in the controller I get the parameter like so:
String data = params?.data
println "incoming data parameter has length of ${data.size()}" //confirm right size
//unless I run the following line, the data does not decode to the same source
data = data.replaceAll(' ', '+')
//as long as I replace spaces with plus, this decodes correctly, why?
byte[] bytedata = data.decodeBase64()
Sorry for the long rant, but I'd really love to understand why I had to do the "replace space with plus sign" to get this to decode correctly. Is there some problem with the plus sign being used in a request parameter?
Whatever populates params expects the request to be a URL-encoded form (specifically, application/x-www-form-urlencoded, where "+" means space), but you didn't URL-encode it. I don't know what functions your language provides, but in pseudo code, queryString should be constructed from
concat(uri_escape("data"), "=", uri_escape(base64_encode(rawBytes)))
which simplifies to
concat("data=", uri_escape(base64_encode(rawBytes)))
The "+" characters will be replaced with "%2B".
You have to use a special base64encode which is also url-safe. The problem is that standard base64encode includes +, / and = characters which are replaced by the percent-encoded version.
http://en.wikipedia.org/wiki/Base64#URL_applications
I'm using the following code in php:
/**
* Custom base64 encoding. Replace unsafe url chars
*
* #param string $val
* #return string
*/
static function base64_url_encode($val) {
return strtr(base64_encode($val), '+/=', '-_,');
}
/**
* Custom base64 decode. Replace custom url safe values with normal
* base64 characters before decoding.
*
* #param string $val
* #return string
*/
static function base64_url_decode($val) {
return base64_decode(strtr($val, '-_,', '+/='));
}
Because it is a parameter to a POST you must URL encode the data.
See http://en.wikipedia.org/wiki/Percent-encoding
paraquote from the wikipedia link
The encoding used by default is based
on a very early version of the general
URI percent-encoding rules, with a
number of modifications such as
newline normalization and replacing
spaces with "+" instead of "%20"
another hidden pitfall everyday web developers like myself know little about