ColdFusion : String : Get Price From Inside 2 Points - parsing

I'm playing with the NOMICS API and get data in a string. But I'm having trouble getting just the Price:
This is part of the string from the METHOD=GET - which works fine..
"currency":"SHIB","platform_currency":"ETH","price":"0.000026199726","price_date":"2022-02-06T00:00:00Z","price_timestamp":"
I know that ,"price":" is the lead and then "," is the end...
But I can't seem to get just the 0.000026199726 from the middle- which is what I need.
<CFHTTP METHOD="Get"
URL="https://api.nomics.com/v1/currencies/ticker?key=#apikey#&ids=SHIB">
<cfset feedData = cfhttp.filecontent>
<cfset startpos = findNoCase(',"price":"', feedData)>
<cfset endpos = findNoCase('",', feedData)>
<cfset getdata = mid(feeddata,startpos,endpos-startpos)
<b>#getdata#</b> Errors as neg number.
The value of parameter 3 of the function Mid, which is now -191, must be a non-negative integer
This has to be an easy task. I must be using the wrong string function?
EDIT: Figured out - it was finding the "," but they are so many of them it found first one, which put things negative - so fix was to find the structure after. ","price_date" is after.
<cfset string = cfhttp.filecontent>
<cfset startpos = findNoCase('price":"', string)>
<cfset endpos = findNoCase('","price_date"', string)>
<cfset detdata = mid(string,startpos,endpos-startpos)>
<cfoutput>
start: #startpos#<br>
end: #endpos#<br>
data: #detdata#<br>
trimmed data: #trim(detdata)#<br>
trimmed data:
<br><b>#removechars(detdata,1,8)#</b><br><br>
</cfoutput>
I'll look at the JSON examples as well. Perhaps that will help with multiple pulls.
Excellent Folks : Thank you so much
<CFHTTP METHOD="Get"
URL="https://api.nomics.com/v1/currencies/ticker?key=#apikey#&ids=SHIB,BTC">
<cfset output = cfhttp.filecontent>
<cfoutput>
<cfset arrayOfStructs = deserializeJson(output)>
<cfloop array="#arrayOfStructs#" index="getpr">
<cfset Price = getpr.price />
<cfset TKID = getpr.id />
#tkid#: #price#<br>
</cfloop>
</cfoutput>
Spits out:
BTC: 43963.45841296
SHIB: 0.000033272664

Credit to Andrea/SOS
<CFHTTP METHOD="Get"
URL="https://api.nomics.com/v1/currencies/ticker?key=#apikey#&ids=SHIB,BTC">
<cfset output = cfhttp.filecontent>
<cfoutput>
<cfset arrayOfStructs = deserializeJson(output)>
<cfloop array="#arrayOfStructs#" index="getpr">
<cfset Price = getpr.price />
<cfset TKID = getpr.id />
#tkid#: #price#<br>
</cfloop>
</cfoutput>

Related

How parse the text between the element of xml file in python

I want to parse the xml file as following
<book attr='1'>
<page number='1'>
<text> sss </text>
<text> <b>bb<i>sss<b></i></b></text>
<text> <i><b>sss</b></i></text>
<text><a herf='a'> sss</a></text>
</page>
<page number='2'>
<text> sss2 </text>
<text> <b>bb<i>sss2</i><b></text>
<text> <i><b>sss2</b></i></text>
<text><a herf='a'> sss2</a></text>
</page>
.......
</book>
I want to extract all the text between the 'text' element. But there are 'b' 'i' 'a' elements et al., in between the 'text' element.
I have tried to use the following code.
tree = ET.parse('book.xml')
root = tree.getroot()
for p in root.findall('page'):
print(p.get('number'))
for t in p.findall('text'):
print(t.text)
But the result:
1
sss
None
None
None
2
sss2
None
None
None
Actually, I want to extract all the text between the and , and join to be sentence like the following:
1
bb sss
sss
sss
sss
2
bb sss2
sss2
sss2
sss2
But how to parse the subelement between the 'text' thanks!
For parsing XML you can use BeautifulSoup. The text between elements can be obtained with get_text() method:
data = '''<book attr='1'>
<page number='1'>
<text> sss </text>
<text> <b>bb<i>sss<b></i></b></text>
<text> <i><b>sss</b></i></text>
<text><a herf='a'> sss</a></text>
</page>
<page number='2'>
<text> sss2 </text>
<text> <b>bb<i>sss2</i><b></text>
<text> <i><b>sss2</b></i></text>
<text><a herf='a'> sss2</a></text>
</page>'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(data, 'lxml')
for page in soup.select('page[number]'):
print(page['number'])
for text in page.select('text'):
print(text.get_text(strip=True, separator=' '))
Prints:
1
sss
bb sss
sss
sss
2
sss2
bb sss2
sss2
sss2

Serve mp4 file through coldfusion and play with jwplayer

I have an web application in coldfusion which record videos and serve videos to user.
The video is working fine on android and desktop browsers but it is giving me error "Error loading media: File could not be played" in IOS.
Here is my JWPlayer code which is currently working.
jwplayer("element").setup({
file: "/video.cfm?token=4514_129_9B2F727D-5056-A85D-6EBE3E48FC2AB9C6",
image: "path/to/image",
width: 450,
height: 360,
type: "mp4",
logo: {
file: 'path/to/logo',
link: 'example.com',
hide : true
}
});
Here is my video.cfm to server mp4 after verification.
<cfset videoFile = 'path\to\file'>
<cfset fileInfo = GetFileInfo(videoFile)>
<cfset length = fileInfo.size>
<cfset start = 0>
<cfset end = fileInfo.size - 1>
<cfheader name="Content-type" value="video/mp4">
<cfheader name="Accept-Ranges" value="0-#length#">
<cfheader name="Content-Range" value="bytes #start#-#end#/#fileInfo.size#">
<cfheader name="Content-Length" value="#length#">
<cfcontent file="#videoFile#" type="video/mp4">
I have tried some solution by adding some header. But that doesn't work. Can anyone help me to sort out the problem.
I am able to resolve my problem. iOS uses a partial content header to run videos. Thanks to rickward for this lovely solution: Media Delivery to iPhones and iPads. I have made some little changes and it started working for me.
Here is the final video.cfm file.
<cfset videoPath = 'path\to\mp4\file'>
<cfif FileExists(videoPath)>
<cfset fileInfoVar = GetFileInfo(videoPath)>
<cfheader name="Last-Modified" value="#fileInfoVar.Lastmodified#">
<cfheader name="ETag" value="#hash(videoPath, 'MD5')#">
<cfheader name="Content-Location" value="http://example.com/video.cfm">
<cfif structKeyExists(GetHttpRequestData().headers, 'Range')>
<cfset rangeDownload(videoPath)>
<cfelse>
<cffile action="readbinary" file="#videoPath#" variable="theData">
<cfscript>
context = getPageContext();
context.setFlushOutput(false);
response = context.getResponse().getResponse();
response.setContentType("video/mp4");
response.setContentLength(arrayLen(theData));
out = response.getOutputStream();
out.write(theData);
out.flush();
out.close();
</cfscript>
</cfif>
</cfif>
<cffunction name="rangeDownload" returnType="void" output="yes">
<cfargument name="file" type="string" required="true" hint="path to file">
<cfset var l = {}>
<cfset l.request = GetHttpRequestData()>
<cffile action="readbinary" file="#ARGUMENTS.file#" variable="l.theData">
<cfset l.size = arrayLen(l.theData)>
<cfset l.length = l.size>
<cfset l.start = 0>
<cfset l.end = l.size - 1>
<!--- Now that we've gotten so far without errors we send the accept range header
/* At the moment we only support single ranges.
* Multiple ranges requires some more work to ensure it works correctly
* and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
*
* Multirange support annouces itself with:
* header('Accept-Ranges: bytes');
*
* Multirange content must be sent with multipart/byteranges mediatype,
* (mediatype = mimetype)
* as well as a boundry header to indicate the various chunks of data.
*/
--->
<cfheader name="Accept-Ranges" value="0-#l.length#">
<!---<cfheader name="Accept-Ranges" value="bytes"> --->
<!---
multipart/byteranges
http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2 --->
<cfif structKeyExists(l.request.headers, 'Range')>
<cfset l.c_start = l.start>
<cfset l.c_end = l.end>
<!--- Extract the range string --->
<cfset l.range = ListGetAt(l.request.headers.range, 2, '=')>
<!--- Make sure the client hasn't sent us a multibyte range --->
<cflog file="rangeDownload" text="#l.range#" />
<cfif l.range contains ','>
<!--- (?) Should this be issued here, or should the first
range be used? Or should the header be ignored and
we output the whole content?
--->
<cfheader statusCode = "416" statusText = "Requested Range Not Satisfiable">
<cfheader name="Content-Range" value="bytes #l.start#-#l.end#/#l.size#">
<!--- (?) Echo some info to the client? --->
<cfabort>
</cfif>
<!--- If the range starts with an '-' we start from the beginning
If not, we forward the file pointer
And make sure to get the end byte if specified --->
<cfif Left(l.range, 1) eq '-'>
<!--- The n-number of the last bytes is requested --->
<cfset l.c_start = l.size - Mid(l.range, 2, Len(l.range))>
<cfelse>
<cfset l.rangeArray = ListToArray(l.range, '-')>
<cfset l.c_start = l.rangeArray[1]>
<cfif ArrayLen(l.rangeArray) eq 2 and val(l.rangeArray[2]) gt 0>
<cfset l.c_end = l.rangeArray[2]>
<cfelse>
<cfset l.c_end = l.size>
</cfif>
</cfif>
<!---
/* Check the range and make sure it's treated according to the specs.
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
*/
// End bytes can not be larger than l.end. --->
<cfif l.c_end gt l.end>
<cfset l.c_end = l.end>
</cfif>
<!--- Validate the requested range and return an error if it's not correct. --->
<cfif l.c_start gt l.c_end || l.c_start gt (l.size - 1) || l.c_end gte l.size>
<cfheader statusCode = "416" statusText = "Requested Range Not Satisfiable">
<cfheader name="Content-Range" value="bytes #l.start#-#l.end#/#l.size#">
<!--- (?) Echo some info to the client? --->
<cfabort>
</cfif>
<cfset l.start = l.c_start>
<cfset l.end = l.c_end>
<cfset l.length = l.end - l.start + 1><!--- Calculate new content length --->
<cfscript>
context = getPageContext();
context.setFlushOutput(false);
response = context.getResponse().getResponse();
response.setContentType("video/mp4");
response.setContentLength(l.length);
</cfscript>
<cfheader statusCode = "206" statusText = "Partial Content">
</cfif>
<!--- Notify the client the byte range we'll be outputting --->
<cfheader name="Content-Range" value="bytes #l.start#-#l.end#/#l.size#">
<cfheader name="Content-Length" value="#l.length#">
<cfscript>
// Start buffered download
out = response.getOutputStream();
// write the portion requested
out.write(l.theData, javacast('int', l.start), javacast('int', l.length));
out.flush();
out.close();
</cfscript>
</cffunction>

Can't authenticate using Quickbooks web connector / CFML

I am attempting to implement a Quickbooks Web connector (QBWC) in Railo 4.x
<cfcomponent output="false">
<cffunction name = "authenticate" access="remote" returntype="string">
<cfargument name = "username" type="string" required="true">
<cfargument name = "password" type = "string" required="true">
<cfset var loc = {}>
<cfset loc.retVal= []>
<cfset loc.retVal[1] = "MYSESSIONTOKEN">
<cfset loc.retVal[2] = "NONE">
<cfset loc.retVal[3] = "">
<cfset loc.retVal[4] = "">
<cfreturn loc.retVal >
</cffunction>
<cffunction name = "clientVersion" access="remote" returnType ="string">
<cfargument name = "productVersion" type="string" required="true">
<cfset var loc = {}>
<cfset loc.retVal = "">
<cfreturn loc.retVal>
</cffunction>
</cfcomponent>
This is my QWC file:
<?xml version="1.0"?>
<QBWCXML>
<AppName>QuickCellarSVC</AppName>
<AppID></AppID>
<AppURL>http://localhost:8080/QuickCellar.cfc</AppURL>
<AppDescription>Quick Cellar railo component</AppDescription>
<AppSupport>http://localhost:8080/support.cfm</AppSupport>
<UserName>Joe</UserName>
<OwnerID>{57F3B9B1-86F1-4fcc-B1EE-566DE1813D20}</OwnerID>
<FileID>{90A44FB5-33D9-4815-AC85-BC87A7E7D1EB}</FileID>
<QBType>QBFS</QBType>
<Scheduler>
<RunEveryNMinutes>2</RunEveryNMinutes>
</Scheduler>
</QBWCXML>
The QBWC trace shows the problem :
Object reference not set to an instance of an object.
More info:
StackTrace = at QBWebConnector.WebService.do_authenticate(String& ticket, String& companyFileName)
Source = QBWebConnector
I was able to drill down a little more and discover that there is a casting problem in Railo maybe?
<?xml version="1.0" encoding="UTF-8"?>
-<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">-<soap:Body>-
Can't cast Complex Object Type Struct to StringUse Built-In-Function "serialize(Struct):String" to create a String from Struct
Now I know some of you are thinking "just serialize" the struct. Well, there is no such function in Railo (that I know of).
Any ideas are greatly appreciated.
The first issue I see is your "authenticate" method has return type of string, but you are returning an array. If you are trying to return a string you could use return serializeJSON(loc.retVal) instead of just retVal, which would return it as a JSON formatted string.

F# Set a property on ViewBag dynamic object (passing an image)

I tried to use the solution that Tomas Petricek wrote on this website but not for a string but for an image. Unfortunately, it doesn't work. This is my code:
Model:
let ChartModelCumulativePerformance =
let numMths = 60
let trackOfDates numMths = firstDate.AddMonths(numMths)
let trackHF = [for x in 0 .. 59 ->(trackOfDates x, HFReturns.[x])]
let trackBchk = [for x in 0 .. 59 ->(trackOfDates x, BchkReturns.[x])]
Chart.Line(trackHF,Name="Hedge Fund") |> ignore
Chart.Line(trackBchk,Name="Benchmark") |> ignore
let myChart = Chart.Combine(
[Chart.Line(trackHF,Name="Hedge Fund")
Chart.Line(trackBchk,Name="Benchmark")])
myChart.CopyAsBitmap()
member this.CreateCumulativePerformanceGraph() = ChartModelCumulativePerformance
Controller:
let dataChart = res.CreateCumulativePerformanceGraph()
let (?<-) (viewData:ViewDataDictionary) (name:string) (value: Image) = viewData.Add(name, value)
this.ViewData?chartCumulative <- dataChart
this.View("HFAnalysis") :> ActionResult
View
<img src =#ViewBag.chartCumulative height="80" width="80"/ alt="" />
or
<img src =#ViewData["chartCumulative"] height="80" width="80"/ alt="" />
Otherwise, do you know another methodologies? Thank in advance for your help
Ultimately you've got an HTML problem, not an F# problem here.
If you want to put image data directly into the src attribute of an img tag, you have to convert it to a base-64 string and then prefix it with the appropriate meta-data according to the Data URI standard.
I would convert your bitmap to a PNG (to shrink the file size) and then get a byte array for the image and pass it to Convert.ToBase64String. Ultimately you'll end up with something like this:
<img width="80" height="80" src="data:image/png;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7" />
Many thanks Joel !!!!
This is the code for those who would be interested:
Model:
let ChartModelCumulativePerformance =
//... code for building a Chart
let myChart = myChart.CopyAsBitmap()
let ms = new MemoryStream()
let tempVar = myChart.Save(ms,Imaging.ImageFormat.Png)
let imageData = ms.ToArray()
let imageBase64 = Convert.ToBase64String(imageData)
String.Format("data:image/png;base64,{0}", imageBase64)
Controller:
let dataChart = res.CreateCumulativePerformanceGraph()
let (?<-) (viewData:ViewDataDictionary) (name:string) (value: String) = viewData.Add(name, value)
this.ViewData?chartCumulative <- dataChart
this.View("HFAnalysis") :> ActionResult
View:

xml.parse return null google app script

I am trying parse the xml but result return null.
Here is the xml:
<feed>
<title type="text">neymar</title>
<subtitle type="text">Bing Image Search</subtitle>
<id>https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?Query='neymar'&$top=2</id>
<rights type="text"/>
<updated>2013-05-13T08:45:02Z</updated>
<link rel="next" href="https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?Query='neymar'&$skip=2&$top=2"/>
<entry>
<id>https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?Query='neymar'&$skip=0&$top=1</id>
<title type="text">ImageResult</title>
<updated>2013-05-13T08:45:02Z</updated>
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Guid">99cb00e9-c9bb-45ca-9776-1f51e30be398</d:ID>
<d:Title m:type="Edm.String">neymaer wallpaper neymar brazil wonder kid neymar wallpaper hd</d:Title>
<d:MediaUrl m:type="Edm.String">http://3.bp.blogspot.com/-uzJS8HW4j24/Tz3g6bNII_I/AAAAAAAAB1o/ExYxctnybUo/s1600/neymar-wallpaper-5.jpg</d:MediaUrl>
<d:SourceUrl m:type="Edm.String">http://insidefootballworld.blogspot.com/2012/02/neymar-wallpapers.html</d:SourceUrl>
<d:DisplayUrl m:type="Edm.String">insidefootballworld.blogspot.com/2012/02/neymar-wallpapers.html</d:DisplayUrl>
<d:Width m:type="Edm.Int32">1280</d:Width>
<d:Height m:type="Edm.Int32">800</d:Height>
<d:FileSize m:type="Edm.Int64">354173</d:FileSize>
<d:ContentType m:type="Edm.String">image/jpeg</d:ContentType>
<d:Thumbnail m:type="Bing.Thumbnail">
<d:MediaUrl m:type="Edm.String">http://ts3.mm.bing.net/th?id=H.5042206689331494&pid=15.1</d:MediaUrl>
<d:ContentType m:type="Edm.String">image/jpg</d:ContentType>
<d:Width m:type="Edm.Int32">300</d:Width>
<d:Height m:type="Edm.Int32">187</d:Height>
<d:FileSize m:type="Edm.Int64">12990</d:FileSize>
</d:Thumbnail>
</m:properties>
</content>
</entry>
<entry>
<id>https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?Query='neymar'&$skip=1&$top=1</id>
<title type="text">ImageResult</title>
<updated>2013-05-13T08:45:02Z</updated>
<content type="application/xml">
<m:properties>
<d:ID m:type="Edm.Guid">9a6b7476-643e-4844-a8da-a4b640a78339</d:ID>
<d:Title m:type="Edm.String">neymar jr 485x272 Neymar Show 2012 Hd</d:Title>
<d:MediaUrl m:type="Edm.String">http://www.sontransferler.com/wp-content/uploads/2012/07/neymar_jr.jpg</d:MediaUrl>
<d:SourceUrl m:type="Edm.String">http://www.sontransferler.com/neymar-show-2012-hd</d:SourceUrl>
<d:DisplayUrl m:type="Edm.String">www.sontransferler.com/neymar-show-2012-hd</d:DisplayUrl>
<d:Width m:type="Edm.Int32">1366</d:Width>
<d:Height m:type="Edm.Int32">768</d:Height>
<d:FileSize m:type="Edm.Int64">59707</d:FileSize>
<d:ContentType m:type="Edm.String">image/jpeg</d:ContentType>
<d:Thumbnail m:type="Bing.Thumbnail">
<d:MediaUrl m:type="Edm.String">http://ts1.mm.bing.net/th?id=H.4796985557255960&pid=15.1</d:MediaUrl>
<d:ContentType m:type="Edm.String">image/jpg</d:ContentType>
<d:Width m:type="Edm.Int32">300</d:Width>
<d:Height m:type="Edm.Int32">168</d:Height>
<d:FileSize m:type="Edm.Int64">4718</d:FileSize>
</d:Thumbnail>
</m:properties>
</content>
</entry>
</feed>
and here is the code:
var response = UrlFetchApp.fetch('https://api.datamarket.azure.com/Bing/Search/Image?Query=%27neymar%27&$top=2',options)
var resp = response.getContentText();
var ggg = Xml.parse(resp,false).getElement().getElement('entry').getElement('content').getElement('m:properties');
Logger.log(ggg);
How do I get element <d:MediaUrl m:type="Edm.String">?
update: but still not work
var response = UrlFetchApp.fetch('https://api.datamarket.azure.com/Bing/Search/Image?Query=%27neymar%27&$top=2',options)
var text = response.getContentText();
var eleCont = Xml.parse(text,true).getElement().getElement('entry').getElement('content');
var eleProp = eleCont.getElement('hxxp://schemas.microsoft.com/ado/2007/08/dataservices/metadata','properties')
var medUrl= eleProp.getElement('hxxp://schemas.microsoft.com/ado/2007/08/dataservices','MediaUrl').getText()
Logger.log(medUrl)
While the provider is using multiple namespaces (signified by m: and d: in front of element names), you can ignore them for retrieving the data you're interested in.
Once you've called getElement() to get the root of the XML doc, you can navigate through the rest using attribute names. (Stop after var feed = ... in the debugger, and explore feed, you'll find you have the entire XML document there
Try this:
var text = Xml.parse(resp,true);
var feed = text.getElement();
var urls = [];
for (var i in feed.entry) {
urls.push(feed.entry[0].content.properties.MediaUrl.Text);
}
Logger.log(urls);
This also works. Note that you have multiple entries in your response, and this example is going after the second of them:
var ggg = Xml.parse(resp,true)
.getElement()
.getElements('entry')[1]
.getElement('content')
.getElement('properties')
.getElement('MediaUrl')
.getText();
References
Namespaces in XML 1.0
XmlElement methods referencing namespace, such as getElement(namespaceName, localName)
Other relevant StackOverflow questions. xml element name with colon, lots about XML namespaces

Resources