Page 2 of 3
Re: Need to parse text using chunks and tokens (??)
Posted: Wed Aug 20, 2014 2:17 pm
by karmacomposer
jacque wrote:What you want is the split command, which is all set up to deal this type of thing. It separates the data by items and puts the whole thing into an array.
Code: Select all
put urlDecode(pData) into pData
split pData by "&" and "="
There is a PayPal script for LiveCode on my site here
http://hyperactivesw.com/cgipaypal/index.html
In particular, take a look at the checkOrderData function, which parses the incoming data.
Thank you, but those seem to be cgi scripts or server-side scripts. I was hoping to do this as a stand-alone PC application. Is there any way to do what you suggest without using CGI?
Also, when you say the above two lines separate fields and put them into an array, how do you then access the array? What is the variable name? pData?
Would it be something like:
Code: Select all
If s[pData] = "String" then
Do something with s
else
Do something else with s
End if
Is that the correct structure?
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Wed Aug 20, 2014 2:30 pm
by Thierry
Mike,
put pData["payment_gross"]
should be according to your previous set of data: 51.80
Does that make sense?
Thierry
Re: Need to parse text using chunks and tokens (??)
Posted: Wed Aug 20, 2014 3:30 pm
by karmacomposer
Yes it does.
Now, I noticed that every end of record ends in VERIFIED. There are hundreds of orders in the database and I need to separate each one so that I can extract what I need from each order to the last one at the moment the program is run.
Essentially, I need something like:
Figure out how many total lines of text there are
Then, use a For/Next loop
For i=1 to [total number of lines]+1
--First line of every order is the order number = need to store that number in orderID(i)
if s="20/8/2014" then put that into date(i) --and turn it into American date of 8/20/2014
if s="tax" than put that into an tax(i)
if s="mc_total" then put that into mctotal(i)
if s="product" then put that into product(i)
next i
Somehow read the last VERIFIED to know that is the last order currently in the database. I then need to somehow write down that last order number - orderID(i) so that the next time the client uses the program, it starts from the last orderID(i)+1
Something like that.
How do I do this in LiveCode? How do IU detect when I am done with all orders?
I need to grab the date of each order, what product was ordered and the sales tax for each order and put them into an array.
I then need to figure out what product was ordered and replace it with a monetary value (if product(i)="Gold Long Sleeve Polo Shirt" then payout(i)="2.00"
In the end, I need to show the sum of all payouts (product value) and the total sales tax.
I need to do this in some kind of a way to show it either in 14 or 30 day increments and I then need to write a cookie or text file with a value so that we don't start from the beginning (to show what is owed after 2 weeks or a month, whatever the period is).
That is everything I need to accomplish with this data.
Once I know how to get everything into arrays and then do something with that data, most of this I can figure out on my own with minimal help.
The data period will be my next stumbling block.
Thank you again for your help.
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Wed Aug 20, 2014 3:50 pm
by Thierry
karmacomposer wrote:Yes it does.
Figure out how many total lines of text there are
Then, use a For/Next loop
For i=1 to [total number of lines]+1
You might find this interesting:
repeat for each key aKey in yourArray
put "Key: " & aKey & " Value: " & yourArray[ aKey] &cr after fld 1
end repeat
Thierry
Re: Need to parse text using chunks and tokens (??)
Posted: Wed Aug 20, 2014 9:57 pm
by karmacomposer
Thierry wrote:karmacomposer wrote:Yes it does.
Figure out how many total lines of text there are
Then, use a For/Next loop
For i=1 to [total number of lines]+1
You might find this interesting:
repeat for each key aKey in yourarray
put aKey .... yourarray[ aKey] &cr after fld ...
end repeat
(pseudo-code)
Thierry
I appreciate the help. I looked into the repeat/end repeat loop and I understand it, but the part I am not sure about, I have questions about (in parenthesis):
put aKey (what is the ... for) yourarray(aKey) &cr after fld ... (what do you mean by fld ...)? Is that the field in the database? In the LiveCode app?
Thanks for clarifying.
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Thu Aug 21, 2014 12:22 am
by karmacomposer
Is the following code in --create array correct?
Code: Select all
put tData into s -- fld 1 contains your data
put urldecode(s) into s
replace "&" with return in s
put s into field "fldData"
--create array
repeat for each line thisLine in s
put thisLine into tArray[thisLine]
end repeat
I am hoping that this code stores each line of the MySQL data (stored in s) into the array tArray[thisLine]
Does this repeat/end repeat actually end or does it loop forever?
If this array is correct, how do I single out a particular piece of data from it?
Say I want to find the following line "tax=5.60" In the array. How would I find just the "tax=" part of it and then put the value next to the = sign "5.60" into a new array?
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Thu Aug 21, 2014 8:53 am
by Thierry
karmacomposer wrote:
put aKey (what is the ... for) yourarray(aKey) &cr after fld ... (what do you mean by fld ...)?
Thanks for clarifying.
Mike,
Sorry, apparently my pseudo-code was not helpful
I did re-edit my previous post with a working 3 lines of code
Best,
Thierry
Re: Need to parse text using chunks and tokens (??)
Posted: Thu Aug 21, 2014 9:05 am
by Thierry
Hi,
From all your questions, it seems you are not familiar with arrays.
I humbly suggest that you read runrev docs and lessons about arrays;
you'll win a lot of times doing this first.
For your specific problem with the paypal datas, you don't *have* to use arrays;
you can put everything in a field with each line being something like:
mc_gross=42
tax=99
..=..
.=.
to read this field, i.e:
put line 1 of fld "myfield" into tmp # line 1: mc_gross=42
set the itemdelimiter to "="
put item 1 of tmp # --> mc_gross
put item 2 of tmp # --> 42
Arrays are very practical for this kind of problems, but are not mandatory.
Choose what suits you best and be happy.
Thierry
Re: Need to parse text using chunks and tokens (??)
Posted: Fri Aug 22, 2014 2:54 am
by jacque
karmacomposer wrote:jacque wrote:
Thank you, but those seem to be cgi scripts or server-side scripts. I was hoping to do this as a stand-alone PC application. Is there any way to do what you suggest without using CGI?
The function on the web page doesn't particularly depend on CGI, I mostly mentioned it because the function does something very similar to what you asked about. The built-in split command creates the array and separates the parts. The label of each item becomes the key, and its value becomes the element. You can make the array in a single line of code, but since Paypal urlEncodes the data, unwind that first:
Code: Select all
put urlDecode(s) into s
split s by "&" and "="
Now you have an array with the keys as the labels and the values as elements. Then you can extract those to do whatever you want. For example, get the price or the purchaser:
Code: Select all
put s["mc_gross"] into tPrice
put s["first_name"] && s["last_name"] into tName -- full name
put s["item_name"] into tThingBought
I've been too busy to get to the forum lately so maybe you've already solved this, but I thought I'd respond just in case.
Re: Need to parse text using chunks and tokens (??)
Posted: Fri Aug 22, 2014 3:16 pm
by karmacomposer
jacque wrote:karmacomposer wrote:jacque wrote:
Thank you, but those seem to be cgi scripts or server-side scripts. I was hoping to do this as a stand-alone PC application. Is there any way to do what you suggest without using CGI?
The function on the web page doesn't particularly depend on CGI, I mostly mentioned it because the function does something very similar to what you asked about. The built-in split command creates the array and separates the parts. The label of each item becomes the key, and its value becomes the element. You can make the array in a single line of code, but since Paypal urlEncodes the data, unwind that first:
Code: Select all
put urlDecode(s) into s
split s by "&" and "="
Now you have an array with the keys as the labels and the values as elements. Then you can extract those to do whatever you want. For example, get the price or the purchaser:
Code: Select all
put s["mc_gross"] into tPrice
put s["first_name"] && s["last_name"] into tName -- full name
put s["item_name"] into tThingBought
I've been too busy to get to the forum lately so maybe you've already solved this, but I thought I'd respond just in case.
Thank you BOTH for your help. This makes the most sense to me and I now can get the LAST ORDER information into an array.
Yes, I did read ALL the LiveCode docs on arrays and repeat and I still cannot get it right. I am used to a little different kind of programming, so LiveCode is worded easier, yet it takes time and effort to get it right.
How can I get ALL the data into the fields?
I know there are currently 248 total orders. The last order currently displays in the field "fldData" (textbox with table turned on) using the suggested code above.
I am pretty sure I use a repeat loop to get all the data into and out from the array. The question is, how do I get all the data from the database into the array using repeat from 1 to xxx where xxx changes all the time? Do I use the forever repeat? Do I read the data and figure out the last order number (in this case 248). The very first piece of data in each record is the record #. There does not seem to be a label for it, so how do I know how to capture it in an array variable?
What is ?? in this case?
I then assume once I know the last ?? I can do a repeat from 1 to ??, correct?
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Fri Aug 22, 2014 3:30 pm
by karmacomposer
I am happy to say the following worked:
Code: Select all
put s["num_cart_items"] into tNumItems
-- last item is shipping - get rid of it
repeat with tVarNum = 1 to tNumItems
put s["item_name" & tVarNum] into tThingBought
put tThingBought into line tVarNum of field "fldData"
end repeat
However, the last line of num_cart_items is always "shipping" instead of the actual items bought.
I figured it out -
That puts the correct amount of items bought in the current order.
I also figured out how to display the payout in a separate field.
Now I need to add them all up. I've tried several ways with no luck.
Code: Select all
repeat with tVarNum = 1 to tNumItems
put tTotalPayout +line tNumItems of field "fldSub" into tTotalPayout
end repeat
put tTotalPayout into field "fldPayoutAmount"
does not work. I also tried just using the array amounts:
Code: Select all
put s["num_cart_items"] into tNumItems
-- last item is shipping - get rid of it
put tNumItems - 1 into tNumItems
repeat with tVarNum = 1 to tNumItems
put s["item_name" & tVarNum] into tThingBought
put tThingBought into line tVarNum of field "fldData"
if tThingBought = "Gold Short Sleeve Polo Shirt Size Kids 8" then
put "1.80" into tPayoutAmt[tVarNum]
end if
if tThingBought = "Royal Blue Short Sleeve Polo Shirt Size Kids 7" then
put "1.80" into tPayoutAmt[tVarNum]
end if
if tThingBought = "Royal Blue School Spirit Shirt Size Kids Medium" then
put "4.00" into tPayoutAmt[tVarNum]
end if
if tThingBought = "Gold School Spirit Shirt Size Kids Medium" then
put "4.00" into tPayoutAmt[tVarNum]
end if
put tPayoutAmt[tVarNum] into line tVarNum of field "fldSub"
end repeat
put tSalesTax into field "fldSalesTaxtoDate"
repeat with tVarNum = 1 to tNumItems
put tTotalPayout + tPayoutAmt[tVarNum] into tTotalPayout"
end repeat
put tTotalPayout into field "fldPayoutAmount"
That did not work either.
Any suggestions? I'll keep looking for the right way to do this.
Either way - nice to see something working for once. (lol).
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Fri Aug 22, 2014 5:05 pm
by karmacomposer
OK. I figured out EVERYTHING for one order.
My only stumbling block now is the total number of orders.
I KNOW the 1st piece of data for every order is a number. That is the OrderID. However, there is no field name, so how do I use it in an array?
The last order is the total number of orders. The first one is "1" and the current last is "249", but that one will change with each new order.
How do I capture that last number to use it in the overall repeat/end repeat?
Help with this gets me about 85% done.
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Fri Aug 22, 2014 8:07 pm
by jacque
It would help to see some representative data, even if you have to fake some of the content for privacy reasons.
If it is what I'm thinking, every order is on its own line. Is that right? In other words, the content of the entire shopping cart for a single order is sent as a single line of url encoded data, followed by a line ending. If so, then the number of lines is the number of orders.
You don't need to count the number of orders though, you can just loop through all the lines. I'm a little confused about how the data is coming in, so this may not be right, but something like this may work:
Code: Select all
repeat for each line L in tAllData -- tAllData is all 248 orders, one per line
processData L -- "L" will contain the data block for one order; i.e., one Paypal line
end repeat
And then you have a "processData" handler that does the actual array manipulation:
Code: Select all
on processData pData -- pData is one order
put urlEncode(pData) into pData
split pData by "&" and "="
repeat for each key k in pData -- loop through each key
if pData["order_id"] contains "shipping" then next repeat -- ignore this one
-- do the rest of the processing here, and fill the fields
end repeat
end processData
I'm pretty sure that last repeat loop is wrong because I'm not clear on what you need to look for when you want to ignore a line, but maybe this will put you on the right track. Bascially the idea is not to count, but to look for a specific value that indicates you don't want to process that line, or that part of the order.
You can't assume that the keys of the array will be in order, and in fact they almost never are. That means that the "last" key may not really be the one that's shipping, it could be the first thing purchased. That's why you need to look for a value rather than a sequential order when deciding which things to ignore.
Re: Need to parse text using chunks and tokens (??)
Posted: Mon Aug 25, 2014 3:55 pm
by karmacomposer
The following code gives me an error in command at:
on processData pData -- pData is one order.
The code is attached to a button:
Code: Select all
on mouseUp
-- check the global connection ID to make sure we have a database connection
global gConnectionID
if gConnectionID is not a number then
answer error "Please connect to the database first."
exit to top
end if
put "" into field "fldData"
put "" into field "fldSub"
global Totals
-- construct the SQL (this selects all the data from the specified table)
put "gccas38_paypal" into tTableName -- set this to the name of a table in your database
put "SELECT * FROM " & tTableName into tSQL
-- query the database
put revDataFromQuery(tab, cr, gConnectionID, tSQL) into tData
-- check the result and display the data or an error message
if item 1 of tData = "revdberr" then
answer error "There was a problem querying the database:" & cr & tData
else
--Old Code
--put urlDecode(s) into tData
--split tData by "&" and "="
--Zero stuff out
put "0.00" into Totals
put "0" into tTotalNumItems
put 1 into lineCount
--Main Loop
repeat for each line L in tData -- tData is all 248 orders, one per line
processData L -- "L" will contain the data block for one order; i.e., one Paypal line
end repeat
--Function to process data
on processData pData -- pData is one order
put urlEncode(pData) into pData
split pData by "&" and "="
repeat for each key k in pData -- loop through each key
if pData["order_id"] contains "PENDING" then next repeat -- ignore this one
-- Process Data
put pData["mc_gross"] into tPrice
put pData["first_name"] && s["last_name"] into tName -- full name
put pData["tax"] into tSalesTax
put pData["payment_date"] into tSaleDate
put pData["num_cart_items"] into tNumItems
-- last item is shipping - get rid of it
put tNumItems - 1 into tNumItems
repeat with tVarNum = 1 to tNumItems
put pData["item_name" & tVarNum] into tThingBought
put tThingBought into line lineCount of field "fldData"
put pData["quantity" & tVarNum] into tTotalNumItems
if tThingBought = "Gold Short Sleeve Polo Shirt Size Kids 8" then
put "1.80" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
if tThingBought = "Maroon Short Sleeve Polo Shirt Size Kids 12" then
put "1.80" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
if tThingBought = "Heather Gray Polo Shirt Short Sleeve Size Kids 14" then
put "1.80" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
if tThingBought = "Royal Blue Short Sleeve Polo Shirt Size Kids 7" then
put "1.80" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
if tThingBought = "Royal Blue School Spirit Shirt Size Kids Medium" then
put "4.00" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
if tThingBought = "Gold School Spirit Shirt Size Kids Medium" then
put "4.00" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
put tPayoutAmt[tVarNum] into line lineCount of field "fldSub"
put tTotalNumItems into line lineCount of field "fldQuantity"
add tPayoutAmt[tVarNum] to field "fldPayoutAmount"
end repeat
add tSalesTax to field "fldSalesTaxToDate"
add 1 to lineCount
--put tSaleDate into field "fldOrderDate"
--put tThingBought into line 1 of field "fldData"
--put tSaleDate into line 2 of field "fldData"
--put tSalesTax into line 3 of field "fldData"
end repeat
end processData
end if
end mouseUp
If the paypal order was not completed or shows pending, failed or whatever paypal deems as NOT going through needs to be ignored.
I'm not sure if L and pData have to somehow be referenced?
On the line where I try to filter what was bought:
if tThingBought = "Gold Short Sleeve Polo Shirt Size Kids 8" then
put "1.80" * tTotalNumItems into tPayoutAmt[tVarNum]
end if
It's a substitution table - there will be tons of these (4 product types with 4 color choices and up to 10 size choices per item). I put the payout
amount in a separate multi-line field. I need to list each item bought, its quantity, its payout and a total tally of all payouts in one value and all
sales tax in one value.
Here is a sample of paypal code:
Code: Select all
cmd=_notify-validate&mc_gross=104.23&protection_eligibility=Eligible&address_status=confirmed&item_number1=&tax=6.23&item_number2=&payer_id=privateID&item_number3=&address_street=PrivateAddr&item_number4=&payment_date=14%3A26%3A57+Jul+29%2C+2014+PDT&payment_status=Completed&charset=windows-1252&address_zip=Zippy&mc_shipping=0.00&mc_handling=0.00&first_name=Fname&mc_fee=3.32&address_country_code=US&address_name=Nope¬ify_version=3.8&custom=71_LongNum&payer_status=unverified&business=clientEmail&address_country=United+States&num_cart_items=4&mc_handling1=0.00&mc_handling2=0.00&mc_handling3=0.00&address_city=City&mc_handling4=0.00&verify_sign=PrivateNum&payer_email=Privateemail&mc_shipping1=0.00&mc_shipping2=0.00&mc_shipping3=0.00&mc_shipping4=0.00&txn_id=TaxID&payment_type=instant&last_name=Nope&address_state=FL&item_name1=Royal+Blue+Long+Sleeve+Polo+Shirt+Size+Kids+XL&receiver_email=ClientEmail&item_name2=Royal+Blue+Short+Sleeve+Polo+Shirt+Size+Kids+20&payment_fee=3.32&item_name3=Gold+Short+Sleeve+Polo+Shirt+Size+Kids+20&item_name4=shipping&quantity1=1&quantity2=3&receiver_id=Private&quantity3=1&txn_type=cart&quantity4=1&mc_gross_1=21.00&mc_currency=USD&mc_gross_2=51.00&mc_gross_3=17.00&residence_country=US&mc_gross_4=9.00&transaction_subject=PrivateNum&payment_gross=104.23&ipn_track_id=Nope-a-HTTP/1.1 200 OK
Server: Apache
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=14400
Strict-Transport-Security: max-age=14400
; charset=UTF-8
DC: slc-b-origin-www-2.paypal.com
Date: Tue, 29 Jul 2014 21:27:03 GMT
Content-Length: 8
Connection: close
Set-Cookie: cwrClyrK4LoCV1fydGbAxiNL6iG=a49RcAaudnrdjiRcaJbzGODaIVimNR9dnjLZlo3cWbbF6RWsokQil0hyVakCYLr_gWuYe0j4HRTkE6uHAfLvC8R2HOuy_03VDG3Qloi_PZj0_23Qr_CreJ9VVJI3lirv76p-uiXBxgO7DT7plGCrCx2xu4TIS01uwP46BbefeksTUKYuzfhFYg5qy79RabuWuSRxARTW3pimRGR1Z1C9fpuNC7XKmDEzjikvuaoJUp1zGnRC62YfzgfM7AOU7qy59AmFoOSTfMIRRR6j92vSKvirqzNn5BErwfVUa9jcthmw_Hwqwy-SAvB0l72X5ppHzYC-uPxySF-bSn6cI2bYxWV1X9MNPQGHXGStYTXNleD09UPJhGjlf6ubpm6RQ98SyC-Ec2UV3pVohMv-TzPPSFOkupWQaeVnczw1dm; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: cookie_check=yes; expires=Fri, 26-Jul-2024 21:27:03 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: navlns=0.0; expires=Thu, 28-Jul-2016 21:27:03 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: Apache=10.74.8.137.1406669223448719; path=/; expires=Thu, 21-Jul-44 21:27:03 GMT
Set-Cookie: X-PP-SILOVER=name%3DLIVE6.WEB.1%26silo_version%3D880%26app%3Dslingshot%26TIME%3D2802964563; domain=.paypal.com; path=/; Secure; HttpOnly
Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT
Set-Cookie: Apache=10.74.8.53.1406669223439437; path=/; expires=Thu, 21-Jul-44 21:27:03 GMT
Set-Cookie: AKDC=slc-b-origin-www-2.paypal.com; expires=Tue, 29-Jul-2014 21:57:03 GMT; path=/; secure
VERIFIED
Everything from Server: Apache and below can be ignored. I changed private info to nonsense text.
Can you help me as to why the code gives me an error on compile?
Thank you.
Mike
Re: Need to parse text using chunks and tokens (??)
Posted: Mon Aug 25, 2014 6:54 pm
by jacque
You can't embed one handler inside another. The function is inside the mouseUp handler. Instead, it should look like this:
on mouseUp
-- all the mouseup stuff
end mouseUp
function processData pData
-- all the processing stuff
end processData