It is currently April 24th, 2024, 5:03 pm

Question on RSS elements

Get help with creating, editing & fixing problems with skins
User avatar
Yincognito
Rainmeter Sage
Posts: 7156
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Question on RSS elements

Post by Yincognito »

This is slightly off-topic as it doesn't have much to do with skins in particular, but in the end will help me build the skin appropriately, so: do you know any smart way to choose between various "description" elements from a RSS feed? I've looked at the official docs (e.g. RSS Board, W3 Validator, Wikipedia, etc.), but I still have no idea on what basis to choose the appropriate description element/tag to display in a feed skin.

For example, RSS has:
- <description>
- <media:description>
- <media:text>
all of which can contain the "right" description for a certain feed item.

A site like CNN.com will have its description data in the usual <description> tag (this is the preferable and most used scenario):

Code: Select all

  <item>
    <title><![CDATA[Trump predicts 'very good chance' of China trade deal ]]></title>
    <description><![CDATA[President Donald Trump expressed optimism on a trade deal with China, after meeting with Chinese Vice Premier Liu He in the Oval Office on Friday afternoon. ]]></description>
    <link>https://www.cnn.com/2019/02/22/politics/trump-china-trade-talks/index.html</link>
    <guid isPermaLink="true">https://www.cnn.com/2019/02/22/politics/trump-china-trade-talks/index.html</guid>
    <pubDate>Sat, 23 Feb 2019 07:05:12 GMT</pubDate>
    <media:group><media:content medium="image" url="https://cdn.cnn.com/cnnnext/dam/assets/190222152628-02-donald-trump-liu-he-super-169.jpg" height="619" width="1100" /><media:content medium="image" url="https://cdn.cnn.com/cnnnext/dam/assets/190222152628-02-donald-trump-liu-he-large-11.jpg" height="300" width="300" /><media:content medium="image" url="https://cdn.cnn.com/cnnnext/dam/assets/190222152628-02-donald-trump-liu-he-vertical-large-gallery.jpg" height="552" width="414" /><media:content medium="image" url="https://cdn.cnn.com/cnnnext/dam/assets/190222152628-02-donald-trump-liu-he-video-synd-2.jpg" height="480" width="640" /><media:content medium="image" url="https://cdn.cnn.com/cnnnext/dam/assets/190222152628-02-donald-trump-liu-he-live-video.jpg" height="324" width="576" /><media:content medium="image" url="https://cdn.cnn.com/cnnnext/dam/assets/190222152628-02-donald-trump-liu-he-t1-main.jpg" height="250" width="250" /></media:group>
  </item>
but a site like Marca.com has its "true" item description content in <media:description>, with almost nothing in the <description> tag:

Code: Select all

  <item>
    <title><![CDATA[Hazard deal goes cold thanks to FIFA... And Real Madrid]]></title>
    <description><![CDATA[&nbsp;<a href="https://www.marca.com/en/football/real-madrid/2019/02/23/5c7079d7e2704ee9b38b45a2.html"> Leer </a><img src="http://secure-uk.imrworldwide.com/cgi-bin/m?cid=es-widgetueditorial&amp;cg=rss-marca&amp;ci=es-widgetueditorial&amp;si=https://e00-marca.uecdn.es/rss/en/index.xml" alt=""/>]]></description>
    <dc:creator><![CDATA[marca.com]]></dc:creator>
    <link>https://www.marca.com/en/football/real-madrid/2019/02/23/5c7079d7e2704ee9b38b45a2.html</link>
    <media:description type="html"><![CDATA[A potential transfer to take &lt;strong&gt;Eden Hazard to Real Madrid&lt;/strong&gt; looks less likely than ever at present, with a number of factors completely changing the complex of the sit]]></media:description>
    <media:title type="html"><![CDATA[REAL MADRID|Unsure after form of Vinicius and Rodrygo's arrival]]></media:title>
    <media:content url="https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/02/23/15508796541256.jpg" medium="image" width="650" height="366" />
    <media:thumbnail url="https://e00-marca.uecdn.es/assets/multimedia/imagenes/2019/02/23/15508796541256_150x0.jpg" width="150" height="84" />
    <guid>https://www.marca.com/en/football/real-madrid/2019/02/23/5c7079d7e2704ee9b38b45a2.html</guid>
    <pubDate>Sat, 23 Feb 2019 01:11:14 +0100</pubDate>
  </item>
and I've seen full descriptions in <media:text> tags as well... Of course, Atom feeds also have <summary>, <content> or even <subtitle> that you can look into, but at least they are sort of "mutually exclusive" in a way, so the picking process is simpler.

Do you have any idea how to choose the "right" tag to look into? How do YOU do it, in your feed skin? Is it something like "if <media:description> tag exists (or it has attributes), then this is where you should look for", or is it something like "just check all the related tags and choose the one with the most content (or something like that)"? How the heck do other RSS parsers pick the correct content in this? Or do they have to perform multiple checks and "guess" things as well? :???:
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5406
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Question on RSS elements

Post by eclectic-tech »

You seem to be asking if there is a way to read any RSS automatically selecting the correct information. Sadly, there is no universal reader due to the informal formatting of different feed, and different tags based on the feed type. So you could get into IfConditions and IfMatch actions, but I do not believe you will be able to make it flexible enough to work with any feed an end user tries to access.

Besides the different tags, for ME, the order of the information is also not standardized; the information can be in any order the RSS creator wants to place it.

I have devised a solution for the capture tags and random order that you may find useful, once you start seeing the wide range of RSS formatting.

I start with a basic template (included below) and create a variable that captures each story "section". This will be different for every feed.

Code: Select all

; URL for parsing
URL=https://forum.rainmeter.net/feed.php

; This variable holds regular expression syntax for parsing 1 ATOM entry section. The variable will be used repeatedly to parse all entries
storysect=(?(?=.*<entry>).*<entry>.*<name>(.*)</name>.*<link.*"(.*)".*<title.*>(.*)</title>)
;							   1 author		      2 link		   3 title			
; The order of storysect can be different from site to site. 
Then I create a variable set to the maximum number of captures in #storysect# and a multiplier variables that let me use preset child measures to capture the desired information without needing to code each unique feed.

Code: Select all

; Create variables for use as StringIndex locators
; This automatically sets the index on all child measures
; Captures is the total number of captures in #storysect#
Captures=3
; Location of info in relation to #Captures#
; The last item captured is always zero with declining values for each capture until the first capture in #storysect#
TitleIndex=0
LinkIndex=-1
AuthorIndex=-2
Rather than writing 40 unique child measures to capture 10 stories with 4 items, I simply modify a few variables to be able to parse any feed.

Here is a template RSS reader I used to create multiple readers for illustra. All I need to change is the URL, the #storysect# variable, and the capture multipliers.

Code: Select all

; Lines starting ; (semicolons) are commented out.
; That is, they do not affect the code and are here for demonstration purposes only.
; ----------------------------------

[Rainmeter]
; This section contains general settings that can be used to change how Rainmeter behaves.
Update=1000
AccurateText=1
DynamicWindowSize=1
Group=#RootConfig#

SkinWidth=(198*#Scale#)
SkinHeight=((42*#Scale#)+(#ItemLines#*22)*#Scale#)

MiddleMouseUpAction=[!ToggleConfig "#RootConfig#\Options" "Options.ini"]

ContextTitle="Show 5 Items"
ContextAction=[!WriteKeyValue Variables ItemLines 5][!Refresh]
ContextTitle2="Show 10 Items"
ContextAction2=[!WriteKeyValue Variables ItemLines 10][!Refresh]

; ----------------------------------

[Metadata]
; Contains basic information of the skin.
Author=Eclectic Tech Website: http://eclectic-tech.deviantart.com/
Name=RSS Reader Template
Information=RSS Reader for almost any forum. Use this as a starting point. Read comments to set up a new RSS feed.
License=Creative Commons BY-NC-SA 4.0
Version=1.2019.01.25

; ----------------------------------

[Variables]
; Include allow the addition of an external file with code that can be used in multiple skins
@includeVariables=#@#Variables.inc

; Variables declared here can be used later on between two # characters (e.g. #MyVariable#).
; They will overwrite any identical variables from the @includeVariables file

; Sets the skin height based on the number of items 
ItemLines=5

; Title & URL for main site
FeedName="Rainmeter Forum"
mainURL=https://forum.rainmeter.net/

; URL for parsing
URL=https://forum.rainmeter.net/feed.php

; This variable holds regular expression syntax for parsing 1 ATOM entry section. The variable will be used repeatedly to parse all entries
storysect=(?(?=.*<entry>).*<entry>.*<name>(.*)</name>.*<link.*"(.*)".*<title.*>(.*)</title>)
;						   1 author			   2 link		3 title			
; The order of storysect can be different from site to site. 

; Add Debug=2 to [RSS] measure. Save and refresh the skin. Open the 'webparserdump.txt' file it creates in the folder. 
; Look for the order of <entry>, <link>, <name>, and <title> as they are arranged, set storysect above to match that order

; Remember to delete Debug=2 from [RSS]!

; Create variables for use as StringIndex locators
; This automatically sets the index on all child measures
; Captures is the total number of captures in #storysect#
Captures=3
; Location of info in relation to #Captures#
; The last item captured is always zero with declining values for each capture until the first capture in #storysect#
TitleIndex=0
LinkIndex=-1
AuthorIndex=-2

; Special substitutions to clean up Rainmeter titles
RainSubstitute="":"Just a moment..."," Rainmeter Skins":""," Your Creations":":"," Discussion":""," Software & Customization":""," & Feature Suggestions":"","^\s+":"","<!\[CDATA\[":"","\]\]>":"","!\[CDATA\[":"","\]\]":""
; ----------------------------------
; MEASURES return some kind of value

; ----------------------------------
;  WEBPARSER MEASURES

[RSS]
Measure=WebParser
Url=#URL#
; Parse multiple sections the neat way using a variable in the RegExp that defines the repeated captures
RegExp=(?siU)#storysect##storysect##storysect##storysect##storysect##storysect##storysect##storysect##storysect##storysect#
; Used to see the actual data of Url and define #storysect# above
; Debug=2
; This measure is the parent. It captures all of the strings defined by RegExp to be used by StringIndex numbers in the child measures
; The default UpdateRate for Webparser is 600 milliseconds (10 minutes if skin Update=1000)
FinishAction=[!CommandMeasure MeasureCountDown "Reset"]

[RSS1]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*1+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
; This child measure seperates the Title found by the RegExp in [RSS] for the first captured storysect

[RSS1link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*1+#LinkIndex#)
; This child measure separates the Link found by RegExp in [RSS] for the first captured storysect

[RSS1author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*1+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
; This child measure separates the Author found by RegExp in [RSS] for the first captured storysect

[RSS2]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*2+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the second captured storysect

[RSS2link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*2+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the second captured storysect

[RSS2author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*2+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the second captured storysect

[RSS3]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*3+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the third captured storysect

[RSS3link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*3+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the third captured storysect

[RSS3author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*3+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the third captured storysect

[RSS4]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*4+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the fourth captured storysect

[RSS4link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*4+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the fourth captured storysect

[RSS4author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*4+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the fourth captured storysect

[RSS5]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*5+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the fifth captured storysect

[RSS5link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*5+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the fifth captured storysect

[RSS5author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*5+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the fifth captured storysect

[RSS6]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*6+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the sixth captured storysect

[RSS6link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*6+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the sixth captured storysect

[RSS6author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*6+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the sixth captured storysect

[RSS7]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*7+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the seventh captured storysect

[RSS7link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*7+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the seventh captured storysect

[RSS7author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*7+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the seventh captured storysect

[RSS8]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*8+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the eighth captured storysect

[RSS8link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*8+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the eighth captured storysect

[RSS8author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*8+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the eighth captured storysect

[RSS9]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*9+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the ninth captured storysect

[RSS9link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*9+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the ninth captured storysect

[RSS9author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*9+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the ninth captured storysect

[RSS10]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*10+#TitleIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure seperates the Title found by the RegExp in [RSS] for the tenth captured storysect

[RSS10link]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*10+#LinkIndex#)
DynamicVariables=1
; This child measure separates the Link found by RegExp in [RSS] for the tenth captured storysect

[RSS10author]
Measure=WebParser
Url=[RSS]
StringIndex=(#Captures#*10+#AuthorIndex#)
DecodeCharacterReference=1
RegExpSubstitute=1
Substitute=#RainSubstitute#
DynamicVariables=1
; This child measure separates the Author found by RegExp in [RSS] for the tenth captured storysect

[MeasureItemLines]
Measure=Calc
Formula=1
IfCondition=(#ItemLines#=5)
IfTrueAction=[!HideMeter MeterBar5][!ShowMeter MeterCountDownBack5][!ShowMeter MeterCountDown5]#U#
IfFalseAction=[!ShowMeter MeterBar5][!HideMeter MeterCountDownBack5][!HideMeter MeterCountDown5]#U#

[MeasureCountDown]
Measure=Loop
StartValue=0
; Endvalue is the UpdateRate for the [RSS] webparser measure
EndValue=600
Increment=1

; Include allow the addition of an external file with code that can be used in multiple skins
@includesystemColors=#@#includes\SysColors.inc

; ----------------------------------
; STYLES are used to "centralize" options

[styleTitle]
StringAlign=CENTER
InlineSetting=Face | #fontName#
InlineSetting2=Size | 10
InlineSetting3=Weight | 900
InlineSetting4=Color | #textColor#
InlineSetting5=Case | UPPER
StringEffect=SHADOW
FontEffectColor=#AccentColor#,50
AntiAlias=1
ClipString=2
ClipStringW=180
DynamicVariables=1
; Scale Center 
TransformationMatrix=#Scale#;0;0;#Scale#;((1-#Scale#)*([#CURRENTSECTION#:X]+[#CURRENTSECTION#:W]/2));((1-#Scale#)*([#CURRENTSECTION#:Y]))
ToolTipWidth=(150*#Scale#)

[styleLeftText]
StringAlign=LEFT
; Meters using styleLeftText will be left-aligned.
InlineSetting=Face | #fontName#
InlineSetting2=Size | #textSize#
InlineSetting3=Weight | 900
InlineSetting4=Color | #textColor#
StringEffect=SHADOW
FontEffectColor=#AccentColor#,20
AntiAlias=1
ClipString=2
ClipStringW=170
DynamicVariables=1
; Scale Left 
TransformationMatrix=#Scale#;0;0;#Scale#;((1-#Scale#)*([#CURRENTSECTION#:X]));((1-#Scale#)*([#CURRENTSECTION#:Y]))
ToolTipWidth=(150*#Scale#)

[styleRightText]
StringAlign=Right
; Meters using styleRightText will be right-aligned.
InlineSetting=Face | #fontName#
InlineSetting2=Size | #textSize#
InlineSetting3=Weight | 900
InlineSetting4=Color | #textColor#
StringEffect=SHADOW
FontEffectColor=#AccentColor#,20
AntiAlias=1
ClipString=1
DynamicVariables=1
; Scale Right
TransformationMatrix=#Scale#;0;0;#Scale#;((1-#Scale#)*([#CURRENTSECTION#:X]+[#CURRENTSECTION#:W]));((1-#Scale#)*([#CURRENTSECTION#:Y]-[#CURRENTSECTION#:H]/32))
ToolTipWidth=(150*#Scale#)

[styleSeperator]
SolidColor=#colorBar#
DynamicVariables=1
X=(9*#Scale#)
Y=-1R
W=(180*#Scale#)
H=(1*#Scale#)

[styleBar]
BarColor=#colorBar#
BarOrientation=HORIZONTAL
SolidColor=#MenuTextColor#
DynamicVariables=1
X=(9*#Scale#)
Y=-1R
W=(180*#Scale#)
H=(1*#Scale#)

; ----------------------------------
; METERS display images, text, bars, etc.

[MeterBackground]
Meter=Shape
DynamicVariables=1
X=5
Y=5
Shape=Rectangle 0,0,190,(36+(#ItemLines#*22)),2 | Fill Color #fillColor# | StrokeWidth (1*#Scale#) | Stroke Color [#darkColor] | Scale #Scale#,#Scale#,0,0

[MeterBackgroundTop]
Meter=Shape
DynamicVariables=1
X=(5*#Scale#)
Y=(5*#Scale#)
Shape=Rectangle 3,3,184,25,2 | Fill Color #headerColor# | StrokeWidth 0 | Stroke Color [#darkColor] | Scale #Scale#,#Scale#,0,0

[meterTitle]
Meter=String
MeterStyle=styleTitle
; Using MeterStyle=styleTitle will basically "copy" the
; contents of the [styleTitle] section here during runtime.
X=((198*#Scale#)/2)
Y=(12*#Scale#)
W=190
H=18
Text=#FeedName#
; Even though the text is set to Options, Rainmeter will display
; it as OPTIONS, because styleTitle contains StringCase=Upper.
LeftMouseUpAction=["#mainURL#"]
Tooltiptext="Left-click to open #FeedName#"

[meterLabel1]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS1
X=(9*#Scale#)
Y=(38*#Scale#)
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS1link]"]
TooltipText="[RSS1]#CRLF#Author: [RSS1author]"

[meterBar1]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel1:Y]+([MeterLabel1:H]*#Scale#)-1)

[meterLabel2]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS2
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS2link]"]
TooltipText="[RSS2]#CRLF#Author: [RSS2author]"
Hidden=(#ItemLines#<2)?

[meterBar2]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel2:Y]+[MeterLabel2:H]*#Scale#-1)
Hidden=(#ItemLines#<2)?

[meterLabel3]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS3
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS3link]"]
TooltipText="[RSS3]#CRLF#Author: [RSS3author]"
Hidden=(#ItemLines#<3)?

[meterBar3]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel3:Y]+[MeterLabel3:H]*#Scale#-1)
Hidden=(#ItemLines#<3)?

[meterLabel4]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS4
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS4link]"]
TooltipText="[RSS4]#CRLF#Author: [RSS4author]"
Hidden=(#ItemLines#<4)?

[meterBar4]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel4:Y]+[MeterLabel4:H]*#Scale#-1)
Hidden=(#ItemLines#<4)?

[meterLabel5]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS5
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS5link]"]
TooltipText="[RSS5]#CRLF#Author: [RSS5author]"
Hidden=(#ItemLines#<5)?

[meterBar5]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel5:Y]+[MeterLabel5:H]*#Scale#-1)
Hidden=(#ItemLines#<5)?

[meterCountDownBack5]
Meter=IMAGE
MeterStyle=styleSeperator
Y=([MeterLabel5:Y]+[MeterLabel5:H]*#Scale#-1)
SolidColor=#MenuTextColor#
Hidden=1

[meterCountDown5]
Meter=IMAGE
MeterStyle=styleSeperator
Y=r
W=((181*#Scale#)-((181*#Scale#)*[MeasureCountdown:]/600))
Hidden=1

[meterLabel6]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS6
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS6link]"]
TooltipText="[RSS6]#CRLF#Author: [RSS6author]"
Hidden=(#ItemLines#<6)?

[meterBar6]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel6:Y]+[MeterLabel6:H]*#Scale#-1)
Hidden=(#ItemLines#<6)?

[meterLabel7]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS7
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS7link]"]
TooltipText="[RSS7]#CRLF#Author: [RSS7author]"
Hidden=(#ItemLines#<7)?

[meterBar7]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel7:Y]+[MeterLabel7:H]*#Scale#-1)
Hidden=(#ItemLines#<7)?

[meterLabel8]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS8
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS8link]"]
TooltipText="[RSS8]#CRLF#Author: [RSS8author]"
Hidden=(#ItemLines#<8)?

[meterBar8]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel8:Y]+[MeterLabel8:H]*#Scale#-1)
Hidden=(#ItemLines#<8)?

[meterLabel9]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS9
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS9link]"]
TooltipText="[RSS9]#CRLF#Author: [RSS9author]"
Hidden=(#ItemLines#<9)?

[meterBar9]
Meter=Image
MeterStyle=styleSeperator
Y=([MeterLabel9:Y]+[MeterLabel9:H]*#Scale#-1)
Hidden=(#ItemLines#<9)?

[meterLabel10]
Meter=String
MeterStyle=styleLeftText
MeasureName=RSS10
X=(9*#Scale#)
Y=(8*#Scale#)R
W=181
H=14
SolidColor=0,0,0,1
LeftMouseUpAction=["[RSS10link]"]
TooltipText="[RSS10]#CRLF#Author: [RSS10author]"
Hidden=(#ItemLines#<10)?

[meterCountDownBack]
Meter=IMAGE
MeterStyle=styleSeperator
Y=([MeterLabel10:Y]+[MeterLabel10:H]*#Scale#-1)
SolidColor=#MenuTextColor#
Hidden=(#ItemLines#<10)?

[meterCountDown]
Meter=IMAGE
MeterStyle=styleSeperator
Y=r
W=((181*#Scale#)-((181*#Scale#)*[MeasureCountdown:]/600))

Here is the @include file; '@Resources\Variables.inc' you would need to view the Template
Or just download illustra to see the readers.

Code: Select all

[Variables]
; =========================================
; GMail may require you to enable "Allow less secure apps" on your account
; You must set these 2 variables before the GMail skin will work
; Set GMailUser to your GMail address without the "@gmail.com"
GMailUser={GMailUsername}
;Not Setup
; Set GMailPassword to your GMail password
GMailPassword={GMailPassword}

; To set additional GMail Accounts, add an increasing number to the above variables
; Increase #ItemLines# variable in GMail.ini to the number of accounts
; Set GMailUser2 to your GMail address without the "@gmail.com"
GMailUser2={GMailUsername2}
; Set GMailPassword2 to your GMail password
GMailPassword2={GMailPassword2}

; =========================================
; Set the PlayerInterface variable below to one of the following players
; AIMP: PlayerInterface=AIMP
; Fully supported. Tested with AIMP 2.61.

; foobar2000: PlayerInterface=CAD
; Fully supported. The foo_cad plugin (download) needs to be installed.

; iTunes: PlayerInterface=iTunes
; Fully supported. Tested with iTunes 10.2.

; J. River Media Center and Media Jukebox: PlayerInterface=CAD
; Fully supported through the CAD interface with Media Center 19 and later. 
; More information here.

; MediaMonkey: PlayerInterface=MediaMonkey
; Fully supported. Tested with MediaMonkey 3.2.5.

; MusicBee: PlayerInterface=CAD
; Fully supported. MusicBee 1.2 (or higher) is required.

; Winamp: PlayerInterface=Winamp
; Fully supported.

; WMP: PlayerInterface=WMP

PlayerInterface=Winamp

; =========================================
; User Colors {You can change these but the Options skin will overwrite when used}
BGAlpha=180
lightColor=220,220,220
darkColor=30,30,30
textColor=[#lightColor]
; [*#Win8Color] or [#AeroColor]
fillColor=[#darkColor],#BGAlpha#
headerColor=[#darkColor],#BGAlpha#
; Separator/Bar Color
colorBar=235,170,0,255
; default bar color: 235,170,0,255

; =========================================
; World Time Locations
;
; You have to set locations here.
; There has been a change on the website, so this becomes a little more difficult.
; Go to https://time.yandex.com/
; Add a city you like.
; Move mouse over that city. Click the gear icon.
; Click "Informer".
; Look at the displayed code. Copy the number after "geoid=" for each city, one at a time, and replace the number code after each 'Location#=' below.
; Save this file. Refresh or Unload/Load the skin

Location1=200
;Los Angeles

Location2=202
;New York

Location3=10393
;London

Location4=213
;Moscow

Location5=10619
;Singapore

Location6=21265
;Melbourne

; =========================================
; Font
fontName=Trebuchet MS
textSize=8

; =========================================
; SysColors Variables { ** DO NOT EDIT ** }
AccentColor=[&mAccent]
MenuTextColor=[&mMenuText]
Win8Color=[&mWin8]
AeroColor=[&mAero]
HighlightColor=[&mHighlight]
MenuColor=[&mMenu]
; Common Skin Variables { ** DO NOT EDIT ** }
U=[!UpdateMeter *][!Redraw]
; Scale values 1~3
Scale=1.25

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

Re: Question on RSS elements

Post by Yincognito »

eclectic-tech wrote: March 2nd, 2019, 4:03 pmYou seem to be asking if there is a way to read any RSS automatically selecting the correct information.Sadly, there is no universal reader due to the informal formatting of different feed, and different tags based on the feed type.
Yes, indeed - you seem to be correct on this one, sadly.
eclectic-tech wrote: March 2nd, 2019, 4:03 pmSo you could get into IfConditions and IfMatch actions, but I do not believe you will be able to make it flexible enough to work with any feed an end user tries to access. Besides the different tags, for ME, the order of the information is also not standardized; the information can be in any order the RSS creator wants to place it.
This is where we disagree: while the RSS/Atom source info is indeed not in a standard order, you can make a skin flexible enough to work with any feed whatsoever, irrespective of order and the content (or better said, where is the content) of the tags - and this is exactly what my skin will do eventually. The reason why I asked the above was not because I couldn't get the info in a regex, but because when performing a custom renaming of the tags to standardize any feed (RSS, Atom, etc.), I wanted to avoid duplicate custom tags (since it was complicated to eliminate them using regexes, especially when they are mixed up - i.e. not consecutive - and you work with an "aggregator" string).

It's a longer story (that I discussed with jsmorley as well), but the bottom line is I "aggregate" and "standardize" feeds the way Yahoo Query Language used to do, in order to avoid hundreds of measures to get the info on each item, and then get the info on a single item by manipulating two indexes: the feed index and the item index. Whenever I need to "move" to a different feed or item, I just change the indexes appropriately and update the "getter" measure (not a WebParser measure, by the way).

The issue I had was that because of the way I renamed the tags, I ended up with duplicates for stuff like <description> and <media:description>, or <logo> and <icon>, because they were assigned the same "item element" ID (e.g. <3> for description elements or <6> for logo elements). However, after I asked the question, I workarounded the issue by simply setting my IDs to <0s> and <1s>, or <0o> and <1o>, where the number is the occurence of the element (for example, 0 for <description> and 1 for <media:description>) and the letter is the element ID (e.g. s=summary, o=logo - I used Atom style naming overall). These custom tags are invalid as per XML Naming Rules, since they start with a number, so I have no problem identifying the "boundaries" of an element in the XML, and setting a regex to either ignore or notice them is easy as well. And, of course, this also reduces the length of the text in the "aggregator", since the tags consume a maximum of 5 characters for something like </0f> (the end of a feed).
eclectic-tech wrote: March 2nd, 2019, 4:03 pmI have devised a solution for the capture tags and random order that you may find useful, once you start seeing the wide range of RSS formatting.
I don't fully grasp how your indexes change and are used to identify stuff, but I guess it's just a different form of what I designed as well (without even knowing of your method). The difference is that you work with RegExp within a WebParser measure, and I work with a RegExp Substitute within a String measure, and, of course, the fact that I used automatically (i.e. without editing the variables file) modifiable indexes for both the feed and the item. After that, well, I will either choose a single tag from the <number, letter> system, or, in case of descriptions, just concatenate them, but not with a regex, but when displaying things at runtime (e.g. [Description][MediaDescription] or something like that).
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5406
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Question on RSS elements

Post by eclectic-tech »

I have no desire to create a reader that works with everything, but I hope you succeed in this.

My suggestion is not as ambitious as yours. Mine creates a StringIndex multiplier that lets me create sets of universal measures for the info I want (Title, Author, Link, Image, etc.) and set the StringIndex to a simple formula using the multiplier: StrigIndex=(#Captures#*1+#TitleIndex#).

This lets me use one RSS reader skin, to access multiple feeds, by putting a few variables in an @include file that set the URL, Captures, and Item Order. I used this in my Win10 RSS readers.

It simplified it enough for me. Everyone has their own way to approach how things are done... mine is usually not normal ;-)

Good luck with your project.
User avatar
Yincognito
Rainmeter Sage
Posts: 7156
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Question on RSS elements

Post by Yincognito »

eclectic-tech wrote: March 2nd, 2019, 5:57 pm I have no desire to create a reader that works with everything, but I hope you succeed in this.

My suggestion is not as ambitious as yours. Mine creates a StringIndex multiplier that lets me create sets of universal measures for the info I want (Title, Author, Link, Image, etc.) and set the StringIndex to a simple formula using the multiplier: StrigIndex=(#Captures#*1+#TitleIndex#).

This lets me use one RSS reader skin by putting a few variables in an @include file that set the URL, Captures, and Item Order. I used this in my Win10 RSS readers.

It simplified it enough for me. Everyone has their own way to approach how things are done... mine is usually not normal ;-)

Good luck with your project.
Actually, mine is not normal, since I'm always looking for the final/perfect solution. :D Others set up things for their specific needs and keep it simple in terms of implementation, but I like more to keep it simple in terms of usage for any regular user: set the feed sites separated by comma in the settings skin, and the rest is taken care of by the Feeds skin, without any edit of the variables involved from the user part. All this with just a single set of (title, description, link, updated) measures.

It's nice to see that you too thought about using indexes to get elements out of the parser. I think I finally understood your formula: you go from Title to Title and use its position as a reference for the next set of item tags. That's ingenious - it would have been a good idea for my case as well, had I not been using my custom tags already. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth