It is currently September 29th, 2024, 7:21 pm

Reading commands

General topics related to Rainmeter.
User avatar
jsmorley
Developer
Posts: 22793
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Reading commands

Post by jsmorley »

Randy21590 wrote: I haven't learned about those methods yet but I'm here to learn. Looks like I have a lot of work to do.
Those are the magic words. Let me see if I can cobble something together that can get you well started.
Randy21590
Posts: 10
Joined: August 17th, 2013, 5:38 pm

Re: Reading commands

Post by Randy21590 »

sa3er wrote:Amazing idea but yes this can be easily done using Rules in Microsoft Outlook.

As for that matter:
Step 1 - Right click on outlook icon in systray and choose Hide When Minimized.
Step 2 - How to start Outlook in a minimized state
Oh, thanks for that!
jsmorley wrote:These are the "Rainmeter" forums. Where is the fun in that? ;-)
I know right! I just started reading about bangs.
jsmorley wrote: Those are the magic words. Let me see if I can cobble something together that can get you well started.
Thanks! I actually still want to get started on this.
User avatar
moshi
Posts: 1740
Joined: November 13th, 2012, 9:53 pm

Re: Reading commands

Post by moshi »

jsmorley wrote:.The issue I have with it is that to make it not just execute the command over and over again, until such time as you "read" the message in GMail itself, and thus remove it from the "unread" list you will get, is going to be reasonably complicated. There is probably some way using the <modified> tag and storing it in an external text file you read and compare before acting, but parsing and properly dealing with date strings in Lua is not trivial, and really, Moshi is right that there may be better tools for this kind of thing.
use the latest executed item as part of the RegExp in the main measure, now that it is dynamic.
User avatar
jsmorley
Developer
Posts: 22793
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Reading commands

Post by jsmorley »

Ah, there is an <id> tag that is perfect for this without having to deal with dates.
User avatar
jsmorley
Developer
Posts: 22793
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Reading commands

Post by jsmorley »

moshi wrote: use the latest executed item as part of the RegExp in the main measure, now that it is dynamic.
Yeah, but sorry, I'm not going to create 50 or more measures to avoid Lua. Especially now that we support Unicode.
User avatar
moshi
Posts: 1740
Joined: November 13th, 2012, 9:53 pm

Re: Reading commands

Post by moshi »

no, i'm talking about the single main measure. something like:

Code: Select all

RegExp="^(.*)[#LastExecutedItem#|$]"
might be

Code: Select all

RegExp="^(.*?)[#LastExecutedItem#|$]"
as well, i can't test right now, and lazy/greedy matches seem to work the opposite way in Rainmeter as in other regular expression systems.


and it would need only two measures without Lua. one that subtitutes the mail with a bang. and the same measure again to substitute all possible matches with the same number for an IfEqualAction. ;)

i think a good strategy would be to use the subject of the mail as a password. this would not only make it easier to parse, but also add a little layer of security, as faking the sender address is just too easy.
User avatar
moshi
Posts: 1740
Joined: November 13th, 2012, 9:53 pm

Re: Reading commands

Post by moshi »

actually a third measure would be needed without Lua to determine the variable.
User avatar
jsmorley
Developer
Posts: 22793
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Reading commands

Post by jsmorley »

It really wasn't all that hard:

This ABSOLUTELY requires the latest Rainmeter 3.0 beta from http://rainmeter.net.
GMailTrigger_1.0.rmskin
READ THIS FIRST

Skin:

Code: Select all

[Rainmeter]
Update=1000

[Variables]
SecondsBetweenCheck=120
GMailID=YOURGMAILID
GMailPassword=YOURPASSWORD
TriggerAuthor=YOURFULLGMAILADDRESS
TriggerText=ShutdownPC
TriggerBang=["shutdown.exe" -t 0 -s -f]
TriggerLast=

[MeasureTriggerMail]
Measure=Plugin
Plugin=WebParser
URL=https://#GMailID#:#GMailPassword#@gmail.google.com/gmail/feed/atom
RegExp=(?siU)^(.*)$
UpdateRate=#SecondsBetweenCheck#
DecodeCharacterReference=1
FinishAction=[!CommandMeasure MeasureScript "GMailTrigger()"]

[MeasureScript]
Measure=Script
ScriptFile=#CURRENTPATH#GMailTrigger.lua
UpdateDivider=-1

[MeterDummy]
Meter=String
You need to set the variables:

GMailID= This will be your GMail login ID
GMailPassword= This will be your GMail login password
TriggerAuthor= Your full GMail address, like johndoe@gmail.com. This is in effect the "from" address to test for.
TriggerText= The text at the beginning of the BODY of the email to use as the "trigger" phrase
TriggerBang= The bang you want to send to Rainmeter if a new email is found from YOU with the trigger text at the beginning of the body.

That's all you need to do. Now for some explanation...

GMailTrigger.lua:

Code: Select all

function Initialize()

	allMail = SKIN:GetMeasure('MeasureTriggerMail')

	entryPattern = '.-<entry>(.-)</entry>'
	titlePattern = '.-<entry>.-<title>(.-)</title>'
	summaryPattern = '.-<entry>.-<summary>(.-)</summary>'
	modifiedPattern = '.-<entry>.-<modified>(.-)</modified>'
	idPattern = '.-<entry>.-<id>(.-)</id>'
	authorPattern = '.-<entry>.-<author>.-<email>(.-)</email>'
	
	triggerAuthor = SKIN:GetVariable('TriggerAuthor')
	triggerText = SKIN:GetVariable('TriggerText')
	triggerBang = SKIN:GetVariable('TriggerBang')

end

function GMailTrigger()

	local rawMail = allMail:GetStringValue()
	
	Titles = {}
	Summaries = {}
	ModDates = {}
	IDs = {}
	Authors = {}
	
	startPos = 0
	
	rawMailCounted, numberOfItems = rawMail:gsub('<entry>', "")
	
	for i = 1, numberOfItems do

		entryStart, entryEnd = rawMail:find(entryPattern, startPos)
		entry = rawMail:sub(entryStart, entryEnd)
		
		Titles[i] = entry:match(titlePattern)
		Summaries[i] = entry:match(summaryPattern)
		ModDates[i] = entry:match(modifiedPattern)
		IDs[i] = entry:match(idPattern)
		Authors[i] = entry:match(authorPattern)
	
		startPos = entryEnd + 1
		
	end
	
	triggerLast = SKIN:GetVariable('TriggerLast')
	CheckTrigger()
	
end

function CheckTrigger()	

	for i = 1, numberOfItems do
		if Authors[i]:match(triggerAuthor) and Summaries[i]:match('^'..triggerText) then
			if IDs[i] ~= triggerLast then
				SKIN:Bang('!WriteKeyValue', 'Variables', 'TriggerLast', IDs[i])
				SKIN:Bang(triggerBang)
				return
			end
		end
	end
	
end
So what this does is:

Initialize() - Does this once when the skin is loaded or refreshed.
1) Get a handle to the WebParser measure in the skin
2) Set up some regular expression (really Lua "matching") patterns to find mail entries and the components of the entry.
3) Get the variables for your full email address (author), the trigger text, and the trigger bang from the skin.

GMailTrigger() - Does this every time your mail feed is read by WebParser.
1) Get the raw string value of the WebParser measure into rawMail.
2) Set up some Lua tables to hold the values we parse.
3) Count the number of entries in the feed.
4) Loop through the number of entries, populating our Lua tables with the titles, summaries, (the body bit from the email) the modified dates, (we don't actually use this, but I thought we might at some point if you extend this) the "id" tags, (uniquely identifies an email, critical to this whole thing) and the authors (your email address)
5) Gets the last "ID" that was saved to the variable TriggerLast in the skin
6) Calls the function CheckTrigger()

CheckTrigger()
Loops through the number of entries:
1) Checks to see if both the author is you, and the trigger text is found at the beginning of the first line of the email summary.
If those conditions are true, then
1) Checks to see if the email "id" matches the one already in the skin in the variable TriggerLast.
If it does not then
1) Writes the "id" tag for this message to the skin in the variable TriggerLast
2) Executes the desired bang to the skin
3) exits out of the loop with "return", so we don't continue checking (this assumes that the bang is going to be other than a shutdown of course, since in that case it won't matter, we will be gone.)


So in this case, if I send myself an email with "ShutdownPC" or "ShutdownPC you fool!" as the beginning of the first line of the body of an email, my PC will shutdown.

Let me know if you have any questions.

Cautions:

EVERYTHING in Lua is case sensitive. Be sure you use the correct case for all variables, and that when you do the "trigger" mail, you use the same case. The Lua could easily be modified to allow for any case in the variables and emails, but I think it best to stay with strict formatting.

If you "read" or "delete" the email message with the trigger, be sure you read or delete ALL "undread" copies of it from your inbox, or some older one will now trigger the action. To keep it simple, this whole thing is not based on "date", but rather "is the most recent trigger message the one I last acted upon?".

I personally would suggest that the "trigger" be a tad more obscure than just "shutdown" or anything else that has any possibility of inadvertently being at the beginning of a message from you to you.

P.S. Nothing says a skin like this has to be about shutting down your PC. It could be set up so that an email you send yourself could launch TeamViewer, or start a backup, or just about anything else you can get at with a command line or batch file in Windows. In addition, it could pretty easily be modified to support multiple "triggers" and branch, so that for example sending "start tv" would start TeamViewer, and "stop tv" would kill the TeamViewer process.
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 22793
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Reading commands

Post by jsmorley »

Edit: fixed a small bug in the .rmskin in the post above.
Randy21590
Posts: 10
Joined: August 17th, 2013, 5:38 pm

Re: Reading commands

Post by Randy21590 »

Wow! Thank you so much jsmorley! You've outdone yourself I'll say. I'll be sure to play around with your code when I have the time. That's awesome. Thanks again.