It is currently March 28th, 2024, 10:09 pm

Help with webparser and JSON

Get help with creating, editing & fixing problems with skins
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Help with webparser and JSON

Post by balala »

50l3r wrote: March 7th, 2019, 1:45 pm I think it's because sometimes user ids do not exist. That JSON only returns the connected users apparently :(
Sorry, but this is not correct. I didn't work online, but with the posted json file, which does have the 159985870458322944 ID user, so it should have to work. But it doesn't. Will take a look immediately...
50l3r
Posts: 24
Joined: August 19th, 2015, 6:11 pm

Re: Help with webparser and JSON

Post by 50l3r »

balala wrote: March 7th, 2019, 1:50 pm Sorry, but this is not correct. I didn't work online, but with the posted json file, which does have the 159985870458322944 ID user, so it should have to work. But it doesn't. Will take a look immediately...
This url "https://discordapp.com/api/servers/260710162891800576/widget.json" contains info about discord server and users online.

My purpose its check if user is online or not, and display and avatar with status like:

Image

Thats the minimal code:

Code: Select all

[Rainmeter]
AccurateText=1
Update=1000
DynamicWindowSize=1

[Metadata]
Name=Discord User Status
Author=50l3r
Information=View discord user avatar and status
Version=1.0

[Variables]
UserID=159985870458322944
ServerID=260710162891800576
StatusOnline=67,181,129,255
Statusidle=250,166,26,255
Statusdnd=240,71,71,255

[MeasureDiscord]
Measure=Plugin
Plugin=WebParser.dll
URL=https://discordapp.com/api/servers/#ServerID#/widget.json
RegExp=(?siU)\{"username": "(.*)", "status": "(.*)", "avatar_url": "(.*)", "avatar": "(.*)", "id": "#UserID#"}
UpdateRate=30

[MeasureUserName]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1

[MeasureDiscordStatus]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=2
DecodeCharacterReference=1
Substitute="\u2713":"✓"
IfMatch=online
IfMatchAction=[!SetOption MeterDiscordStatus ImageTint #StatusOnline#]
IfMatch2=idle
IfMatchAction2=[!SetOption MeterDiscordStatus ImageTint #Statusidle#]
IfMatch3=dnd
IfMatchAction3=[!SetOption MeterDiscordStatus ImageTint #Statusdnd#]
IfMatch4=online|idle|dnd
IfNotMatchAction4=[!SetOption MeterDiscordStatus ImageTint 0,0,0,1]
IfMatchMode=1	


[MeasureAvatarURL]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=3
Download=1


[Avatar1]
Meter=Image
MeasureName=MeasureAvatarURL
ImageName=%1
x=0
y=0
w=75
h=75
MaskImageName=#@#images\Masks\Mask
Group=Avatar

[MeterDiscordStatus]
Meter=Image
ImageName=#@#images\status\status.PNG
ImageTint=0,0,0,1
x=0
y=0
w=75
h=75

[MeasureDiscriminator]
Measure=WebParser
Url=[MeasureDiscord]
StringIndex=4
But the value isnt correct.Thats not the user:

Image


The name of the user id 159985870458322944 is "MEE6"
User avatar
balala
Rainmeter Sage
Posts: 16110
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Help with webparser and JSON

Post by balala »

The strings under the {}, vary, which makes the read very difficult. Unfortunately I can't figure out a good RegExp. Still trying, but can't succeed yet...
User avatar
FreeRaider
Posts: 826
Joined: November 20th, 2012, 11:58 pm

Re: Help with webparser and JSON

Post by FreeRaider »

Can you post the images MaskImageName=#@#images\Masks\Mask and ImageName=#@#images\status\status.PNG?

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

Re: Help with webparser and JSON

Post by Yincognito »

You have to take things one at a time, not all at once. The source has, for example, curly brackets inside curly brackets, and your RegExp doesn't seem to like that. What you have to do is take all the data from a particular user, and then break it in pieces and get the elements with very simple regexes (bear in mind that I used the username and id as left and right "anchors" in the WebParser parent measure, so they have to be at the start and end of a {} user data for this to work):

Code: Select all

[Rainmeter]
AccurateText=1
Update=1000
DynamicWindowSize=1

[Metadata]
Name=Discord User Status
Author=50l3r
Information=View discord user avatar and status
Version=1.0

[Variables]
UserID=159985870458322944
ServerID=260710162891800576
StatusOnline=67,181,129,255
Statusidle=250,166,26,255
Statusdnd=240,71,71,255

[MeasureDiscord]
Measure=Plugin
Plugin=WebParser.dll
URL=https://discordapp.com/api/servers/#ServerID#/widget.json
RegExp='(?siU)(?(?=\{.*"id": "#UserID#"\}).*?(\{"username".*"id": "#UserID#"\}))'
UpdateRate=30
DynamicVariables=1

[MeasureUserName]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"username": "(.*)".*'
StringIndex2=1

[MeasureDiscordStatus]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"status": "(.*)".*'
StringIndex2=1
DecodeCharacterReference=1
Substitute="\u2713":"✓"
IfMatch=online
IfMatchAction=[!SetOption MeterDiscordStatus ImageTint #StatusOnline#]
IfMatch2=idle
IfMatchAction2=[!SetOption MeterDiscordStatus ImageTint #Statusidle#]
IfMatch3=dnd
IfMatchAction3=[!SetOption MeterDiscordStatus ImageTint #Statusdnd#]
IfMatch4=online|idle|dnd
IfNotMatchAction4=[!SetOption MeterDiscordStatus ImageTint 0,0,0,1]
IfMatchMode=1	

[MeasureAvatarURL]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"avatar_url": "(.*)".*'
StringIndex2=1
Download=1

[MeasureAvatar]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"avatar": "(.*)".*'
StringIndex2=1

[MeasureDiscriminator]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"discriminator": "(.*)".*'
StringIndex2=1

[MeasureID]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"id": "(.*)".*'
StringIndex2=1

[Avatar1]
Meter=Image
MeasureName=MeasureAvatarURL
ImageName=%1
x=0
y=0
w=75
h=75
MaskImageName=#@#images\Masks\Mask
Group=Avatar

[MeterDiscordStatus]
Meter=Image
ImageName=#@#images\status\status.PNG
ImageTint=0,0,0,1
x=0
y=0
w=75
h=75
And screenshot:
discord demo.jpg
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
FreeRaider
Posts: 826
Joined: November 20th, 2012, 11:58 pm

Re: Help with webparser and JSON

Post by FreeRaider »

A code based on lua script working but in

[BETA VERSION]


code skin

Code: Select all

[Rainmeter]
AccurateText=1
Update=1000
DynamicWindowSize=1

[Variables]
UserID=266253963542790145
ServerID=260710162891800576
StatusOnline=67,181,129,255
Statusidle=250,166,26,255
Statusdnd=240,71,71,255
Update=900

[MeasureSite]
Measure=WebParser
UpdateRate=#Update#
URL=https://discordapp.com/api/servers/#ServerID#/widget.json
RegExp=(?siU)^(.*)$
FinishAction=[!UpdateMeasure MeasureScript][!EnableMeasure MeasureAvatarURL][!CommandMeasure MeasureAvatarURL "Update"]

[MeasureScript]
Measure=Script
ScriptFile=json.lua
UpdateDivider=-1
IDtoMatch=#UserID#

[MeasureAvatarURL]
Measure=WebParser
URL=""
StringIndex=1
Download=1
Disabled=1

[Avatar1]
Meter=Image
MeasureName=MeasureAvatarURL
ImageName=%1
x=0
y=0
w=75
h=75
; MaskImageName=#@#images\Masks\Mask
; Group=Avatar

[MeterDiscordStatus]
Meter=Image
; ImageName=#@#images\status\status.PNG
ImageTint=0,0,0,1
x=0
y=0
w=75
h=75
json.lua

Code: Select all

function Initialize()

   measureSite = SKIN:GetMeasure('MeasureSite')
   iduser = SELF:GetOption('IDtoMatch') or nil
   namesPattern = '{.-"username"(.-).-}'
   namesrow = {}
    
   
end

function Update()



   allData = measureSite:GetStringValue()
   if allData == '' then return end

   dummyString, namesCount = string.gsub(allData, 'username', '')
   
  
			for i = 1, namesCount do
					namesrow[i] = {}
			end
  
  
  startPos = 0
   
	for i = 1, namesCount do
         
         currentnamesStart, currentnamesEnd = string.find(allData, namesPattern, startPos)
         currentnames = string.sub(allData, currentnamesStart, currentnamesEnd)
        
		startPos = tonumber(currentnamesEnd) + 1
		
         namesrow[i]['username'] = string.match(currentnames,  '"username": "(.-)"')
		 namesrow[i]['status'] = string.match(currentnames,  '"status": "(.-)"')
		 namesrow[i]['avatar_url'] = string.match(currentnames,  '"avatar_url": "(.-)"')
		 namesrow[i]['avatar'] = string.match(currentnames,  '"avatar": "(.-)"')
		 namesrow[i]['id'] = string.match(currentnames,  '"id": "(.-)"')

	 if namesrow[i]['id'] == iduser then
			SKIN:Bang('!SetOption', 'MeasureAvatarURL', 'URL', namesrow[i]['avatar_url'])
						
			-- if namesrow[i]['status'] == "online" or "idle" or "dnd" then
					-- SKIN:Bang('!SetOption', 'MeterDiscordStatus', 'ImageTint', '0,0,0,1')
			-- end
			
			if namesrow[i]['status'] == "online" then
					SKIN:Bang('!SetOption', 'MeterDiscordStatus', 'ImageTint', '#StatusOnline#')
			end
			if namesrow[i]['status'] == "idle" then
					SKIN:Bang('!SetOption', 'MeterDiscordStatus', 'ImageTint', '#Statusidle#')
			end
			if namesrow[i]['status'] == "dnd" then
					SKIN:Bang('!SetOption', 'MeterDiscordStatus', 'ImageTint', '#Statusdnd#')
			end
	 end
	end
  return namesCount
end

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

Re: Help with webparser and JSON

Post by Yincognito »

FreeRaider wrote: March 8th, 2019, 1:38 pmA code based on lua script working...
This might be a better approach, as it only looks for "username", although using Lua for something that can be also done in a skin code itself is not my cup of tea, LOL. I'm not familiar with Lua patterns, so I'll ask, since you probably know better than me: is the pattern valid for user data like {"username": "Anchovy", "status": "online", "game": {"name": "Warframe"}, "avatar_url": "https://cdn.discordapp.com/avatars/177117512763179008/25ad7b84318368aa9abadaca34cb3bc7.jpg", "avatar": "25ad7b84318368aa9abadaca34cb3bc7", "discriminator": "8047", "id": "177117512763179008"}? What I mean, it doesn't stop at the first } (i.e. the one after "Warframe"), right? For me, that was the main reason to include the "id": "#UserID#"\} as the right anchor, to be sure that it takes the second } as the end of the user data, not the first. Just asking, maybe I learn a thing or two about these Lua patterns too. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
FreeRaider
Posts: 826
Joined: November 20th, 2012, 11:58 pm

Re: Help with webparser and JSON

Post by FreeRaider »

Yincognito wrote: March 8th, 2019, 3:47 pm

This might be a better approach, as it only looks for "username", although using Lua for something that can be also done in a skin code itself is not my cup of tea, LOL. I'm not familiar with Lua patterns, so I'll ask, since you probably know better than me: is the pattern valid for user data like {"username": "Anchovy", "status": "online", "game": {"name": "Warframe"}, "avatar_url": "https://cdn.discordapp.com/avatars/177117512763179008/25ad7b84318368aa9abadaca34cb3bc7.jpg", "avatar": "25ad7b84318368aa9abadaca34cb3bc7", "discriminator": "8047", "id": "177117512763179008"}? What I mean, it doesn't stop at the first } (i.e. the one after "Warframe"), right? For me, that was the main reason to include the "id": "#UserID#"\} as the right anchor, to be sure that it takes the second } as the end of the user data, not the first. Just asking, maybe I learn a thing or two about these Lua patterns too. ;-)
I understand what you mean. I think I've fixed the pattern. Now it should capture all the information, even if there is another brace before ID.


In the lua script you can replace the previous namesPattern the following
namesPattern = '{("username".-id.-)}'
discord.png
You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Rainmeter Sage
Posts: 7029
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Help with webparser and JSON

Post by Yincognito »

FreeRaider wrote: March 8th, 2019, 7:00 pmIn the lua script you can replace the previous namesPattern the following
namesPattern = '{("username".-id.-)}'
I didn't test your previous pattern though - just by the look of it I guessed that it will have problems with a second bracket. In the end, the issue is probably corrected. Good job!
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
50l3r
Posts: 24
Joined: August 19th, 2015, 6:11 pm

Re: Help with webparser and JSON

Post by 50l3r »

Yincognito wrote: March 8th, 2019, 3:27 am You have to take things one at a time, not all at once. The source has, for example, curly brackets inside curly brackets, and your RegExp doesn't seem to like that. What you have to do is take all the data from a particular user, and then break it in pieces and get the elements with very simple regexes (bear in mind that I used the username and id as left and right "anchors" in the WebParser parent measure, so they have to be at the start and end of a {} user data for this to work):

Code: Select all

[Rainmeter]
AccurateText=1
Update=1000
DynamicWindowSize=1

[Metadata]
Name=Discord User Status
Author=50l3r
Information=View discord user avatar and status
Version=1.0

[Variables]
UserID=159985870458322944
ServerID=260710162891800576
StatusOnline=67,181,129,255
Statusidle=250,166,26,255
Statusdnd=240,71,71,255

[MeasureDiscord]
Measure=Plugin
Plugin=WebParser.dll
URL=https://discordapp.com/api/servers/#ServerID#/widget.json
RegExp='(?siU)(?(?=\{.*"id": "#UserID#"\}).*?(\{"username".*"id": "#UserID#"\}))'
UpdateRate=30
DynamicVariables=1

[MeasureUserName]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"username": "(.*)".*'
StringIndex2=1

[MeasureDiscordStatus]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"status": "(.*)".*'
StringIndex2=1
DecodeCharacterReference=1
Substitute="\u2713":"✓"
IfMatch=online
IfMatchAction=[!SetOption MeterDiscordStatus ImageTint #StatusOnline#]
IfMatch2=idle
IfMatchAction2=[!SetOption MeterDiscordStatus ImageTint #Statusidle#]
IfMatch3=dnd
IfMatchAction3=[!SetOption MeterDiscordStatus ImageTint #Statusdnd#]
IfMatch4=online|idle|dnd
IfNotMatchAction4=[!SetOption MeterDiscordStatus ImageTint 0,0,0,1]
IfMatchMode=1	

[MeasureAvatarURL]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"avatar_url": "(.*)".*'
StringIndex2=1
Download=1

[MeasureAvatar]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"avatar": "(.*)".*'
StringIndex2=1

[MeasureDiscriminator]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"discriminator": "(.*)".*'
StringIndex2=1

[MeasureID]
Measure=WebParser
URL=[MeasureDiscord]
StringIndex=1
RegExp='(?siU).*"id": "(.*)".*'
StringIndex2=1

[Avatar1]
Meter=Image
MeasureName=MeasureAvatarURL
ImageName=%1
x=0
y=0
w=75
h=75
MaskImageName=#@#images\Masks\Mask
Group=Avatar

[MeterDiscordStatus]
Meter=Image
ImageName=#@#images\status\status.PNG
ImageTint=0,0,0,1
x=0
y=0
w=75
h=75
And screenshot:

discord demo.jpg
Sorry for delay in response. With this regexp it works.

Now, i have to find out how can i get the user status when he`s not online or afk. The user not appear in json when he's offline.

Maybe a static avatar image

Much thanks for your help :)