It is currently October 15th, 2021, 10:52 pm

Sooo, let's talk about updating section variables on WebParser child measures

Help with creating, editing & fixing problems with skins
User avatar
Jeff
Posts: 232
Joined: September 3rd, 2018, 11:18 am

Sooo, let's talk about updating section variables on WebParser child measures

Post by Jeff »

Fun topic, right?

Code: Select all

<html>
    <body>
        <table>
            <tbody>
        <tr id="entry1">
            <td class="entry-title-english">null</td>
            <td class="entry-title-japanese">はたらく魔王さま! 2</td>
        </tr>
    
        <tr id="entry2">
            <td class="entry-title-english">null</td>
            <td class="entry-title-japanese">痛いのは嫌なので防御力に極振りしたいと思います。II</td>
        </tr>
    
 <!-- The list goes on -->
    
        <tr id="entry362">
            <td class="entry-title-english">null</td>
            <td class="entry-title-japanese">映画スター☆トゥインクルプリキュア 星のうたに想いをこめて</td>
        </tr>
    
        <tr id="lastEntry363">
            <td class="entry-title-english">Future Folktales</td>
            <td class="entry-title-japanese">アサティール 未来の昔ばなし</td>
        </tr>
            </tbody>
        </table>
    </body>
</html>
This is the file I'm trying to parse right now, it's just a HTML table from entry1 to lastentry363 (the last entry in the list has last prefixed to itself)

Code: Select all

[Parser]
Measure=WebParser
URL=file://#CURRENTPATH#animes.txt
RegExp=(?sUi)<tbody>(.*)<\/tbody>
FinishAction=[!UpdateMeasure LastEntry]
UpdateDivider=-1

[LastEntry]
Measure=WebParser
URL=[Parser]
RegExp=(?sUi)id="lastEntry(\d*)".*
StringIndex=1
StringIndex2=1
UpdateDivider=-1
OnChangeAction=[!UpdateMeasure RandomNumber]

[RandomNumber]
Measure=Calc
Formula=Floor((Random / 1000) * [LastEntry])
LowBound=1
HighBound=1000
DynamicVariables=1
UpdateDivider=-1

[PickedEntry]
Measure=WebParser
URL=[Parser]
RegExp=(?sUi).*entry[RandomNumber:].*"entry-title-english">((.*)<.*"entry-title-japanese">(.*)<
StringIndex=1
StringIndex2=1
UpdateDivider=-1
DynamicVariables=1
This is my Rainmeter code

[Parser] is the parent measure and gets everything inside tbody, [LastEntry] is a child measure and gets the numbesr from id=lastentryXXX
The reason why [Parser] has FinishAction=[!UpdateMeasure LastEntry] is because after the parent measure finishes, for some reason WebParser measures that have UpdateDivider=-1 do update the string value, but not the number value, so I'm doing that to update the number value (also doing it because HighBound=[LastEntry] dosen't work because of the same reason)
So far so good, [Parser] gets the list, [LastEntry] gets the number, [RandomNumber] gets a random number between 1 and the list count, the problem is here, [PickedEntry] is a child measure who's parent has finished before [RandomNumber] could, FinishAction is only executed after the parent measure is done and dosen't work on child measures, Disabled=1, Paused=1, !EnableMeasure, !UnPauseMeasure, !UpdateMeasure, !CommandMeasure X "Update", none of this works.

Question is, how do I update a child measure ([PickedEntry]) who's necesary number is obtained after a parent ([Parser]) and child measure ([LastEntry]) are executed sequentially?
A simple yes or no, pointing out the single line that's wrong or missing options which are wrong is appreciated
User avatar
Brian
Developer
Posts: 2272
Joined: November 24th, 2011, 1:42 am
Location: Utah

Re: Sooo, let's talk about updating section variables on WebParser child measures

Post by Brian »

This isn't going to work like you think it would. Child Webparser measures are updated solely by the parent measure, not on their own. So using the results from one child measure, and processing it through another measure to then use in a second child measure (from the same parent) won't work.

You are basically going to have to parse the file twice to get what you want...or use another method (like lua).

Here is the double parsing method:

Code: Select all

[Parser]
Measure=WebParser
URL=file://#CURRENTPATH#animes.txt
RegExp=(?sUi)<tbody>(.*)<\/tbody>
FinishAction=[!UpdateMeasure RandomNumber]
UpdateDivider=-1

[LastEntry]
Measure=WebParser
URL=[Parser]
RegExp=(?sUi)id="lastEntry(\d*)".*
StringIndex=1
StringIndex2=1
UpdateDivider=-1

[RandomNumber]
Measure=Calc
Formula=Floor((Random / 1000) * [LastEntry])
LowBound=1
HighBound=1000
DynamicVariables=1
UpdateDivider=-1
OnChangeAction=[!EnableMeasure Parser2][!UpdateMeasure Parser2]

[Parser2]
Measure=WebParser
URL=file://#CURRENTPATH#animes.txt
RegExp=(?sUi)<tbody>(.*)<\/tbody>
UpdateDivider=-1
Disabled=1
FinishAction=[!DisableMeasure Parser2]

[PickedEntry]
Measure=WebParser
URL=[Parser2]
RegExp=(?sUi).*entry[RandomNumber:].*"entry-title-english">(.*)<.*"entry-title-japanese">(.*)<
StringIndex=1
StringIndex2=1
UpdateDivider=-1
DynamicVariables=1
Note, since child Webparser measures are solely updated by its parent, there is no need to "update" the child measure.

Also, there was a an extra ( in the original [PickedEntry] RegExp.



Lua is much more flexible in cases like this.

Skin:

Code: Select all

[Parser]
Measure=WebParser
URL=file://#CURRENTPATH#animes.txt
RegExp=(?sUi)<tbody>(.*)<\/tbody>
FinishAction=[!EnableMeasure Script][!UpdateMeasure Script]
UpdateDivider=-1

[Script]
Measure=Script
ScriptFile=#CURRENTPATH#animes.lua
UpdateDivider=-1
Disabled=1
animes.lua

Code: Select all

function Initialize()
	math.randomseed(os.time())
	parser = SKIN:GetMeasure('Parser')
end

function Update()
	local filedump = parser:GetStringValue()
	local _, _, lastEntry = string.find(filedump, 'lastEntry(%d+)')
	local randomNum = math.random(1, tonumber(lastEntry))
	local _, _, english, japanese = string.find(filedump, 'entry'..randomNum..'".-english">(.-)<.-japanese">(.-)<')
	--print (english, japanese)
	return japanese
end
The string value of [Script] will be the japanese version of a random entry.

The lua is just an example and is not tested on "real" data. Also, there might be an error if the random number generated is the last entry, since the pattern matches a lowercase "entry" (while the .txt file had a uppercase "lastEntry"). I will leave that issue for you. :D


Hopefully that helps.

-Brian
User avatar
Yincognito
Rainmeter Sage
Posts: 4063
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Sooo, let's talk about updating section variables on WebParser child measures

Post by Yincognito »

Alternatively to what Brian said, and without the need for double parsing or Lua, I believe (can't test it now since I'm on mobile) this could easily be solved by converting your picker measure to a String type, with its value being the WebParser parent (since you already capture everything there), then apply a regex substitution to "extract" the said entry using a relatively similar regex when updating the String measure from the FinishAction of the WebParser parent.

It's possible that you'd need to adjust the substitution to account for empty capture values (though I don't think it would be necessary in this case), but other than that, the approach is pretty straightforward.

P.S. Since your current picker grabs 2 captures (for both English and Japanese), you'd need to properly duplicate and adjust the converted String equivalent to do the same, but then, it would be similar if using WebParser children, so no significant change there.