notify-send only if not already - linux

I'm running linux mint 12 (package base is Ubuntu Oneiric). I essentially want to have a script run every minute or so which does some stuff, and will give me true or false. If true I want a pop-up notification. I'm considering notify-send as this appears to do what I want to do, in a nice unobtrusive way. There are a couple of problems I've encountered though.
I don't want the notifications to stack up. If it returns true and I do not attend to it, it will return true the next time and current this causes the notifications to stack up. Is there any way to check if the notification has already been issued, and thus not send another one (perhaps send the notification again after 10 minutes in case I didn't notice it the first time). The job is currently set up as a cronjob, but I can think of a 'hacky' way of getting this functionality if I was to have the script running constantly and using sleep, but I'd rather avoid that root.
Additionally, how can I make it so that when I click the notification it will launch an application/script of my choosing? This appears to be possible as Dropbox etc issue notifications that behave in this manor, but I'm not sure if that is done through notify-send or not.
Anything to point me in the right direction would be great. Thanks.

From a quick perusal of the libnotify API, it does not appear that the daemon returns anything to the client identifying an outstanding notification. In other words, it's a "fire and forget" API -- once you've sent the request to display a popup you have no way to determine if the popup is still there. I'm afraid you're out of luck, at least with notify-send.

One simple trick is to use the -t option such that the notification expires at the next check. So, for example, if you check via crontab every 10 minutes then you would use
notify-send -t 600000 "You need to update your caffeine level".
This would remove the old notification at the exact time the new one is being issued.

Related

Windows 10 Event Viewer ID description problem

I've looked at so many articles in the past year without finding an answer, I'm starting to go crazy...
I do a lot of application support and use the Event Viewer on a regular basis. On any machine but mine, when I look at an event with Event ID 0, the "data" part of that entry is shown in the General tab of the viewer. This is the default behavior that I like. On my laptop, however, for about a year now, Event ID 0 shows as "The operation completed successfully." I no longer see the "data" part of the event in the General section of the window.
Example of the annoying message
The only thing I can think of, is that I added a custom description (or definition) for Event ID 0. But frankly, I don't know how I did it, if that is the case. I want to go back to seeing the "data" in there, rather than this useless message.
Does anyone know how to fix this?
While not a "fix" to the problem, I have what may be a workaround for you.
First, I can confirm that I have experienced it also--and it's been on MORE than one computer. But it has been limited to only some apps ("sources", in event viewer parlance). So I am assuming it's THEIR doing rather than ours. Your situation may be different.
But second, and until you may find a better solution, I will note also that there may well BE a useful message for you to see. If you click on the Details tab above that message, the "friendly view" of the details will readily show what the "real" message is that underlies that log entry.
See this screenshot showing a Postgres startup message that was hidden under such an "operation completed successfully" log entry.
I have seen it and other apps/sources work this way for such startup status messages, failures, errors, and more.
Like you, I lament that we should have to know to do that. It feels to me like the folks creating the code that create the event log entry are making some choice that leads to this behavior. At least now I know that I can SEE the info they are trying to share, albeit via what seems a poor choice.

How to set Google home device in “listen mode” with node red

Is there a way to make a node where you can "make" a conversation with google home mini device?
You already can send TTS and it will anounce whatever you type, but is there a way to wait for a response from the end user and receive (his response) STT back into node red?
The end goal is to let Google home mini ask you for input and based on the response you can activate a flow within Node red. But for that you need to activate your speaker into some kind of "listen mode", like you do when saying "hey google"
That depends on what you want the flow to do
If it can be triggered by trying to control a "device" e.g. " hey Google, turn on kitchen light" then there are 3 or 4 nodes/services that will do that. e.g. node-red-contrib-googlehome (full disclosure I wrote and run this one)
There are also some nodes to help with none smart home actions e.g. node-red-contrib-gactions-fulfillment
But you will have to trigger it, you cannot have the device initiate the interaction iirc
Workaround:
When triggered, cast "Are you ok?" and store a flag saying what triggered it and when.
Expect user to say either "OK Google, I'm fine" or "OK Google, I'm not feeling okay"
This triggers actions that look at the flag, and if its not too long ago since it was set, do the appropriate thing.
You could add a timeout to ask again if no reply was given, or to raise an alarm if no response after a number of retries, but that might be prone to false alarms.
This doesn't open google home to listens, it just expect the user to make an ordinary command to google home, that doesn't know that something was casted to it seconds ago.

How can I prevent user from doing anything else while Userform is displayed?

Like the title says, I have an Excel file with a macro running on load and I'd like to make it so the user can't use the computer while the macro is running.
It's a simple form for data input. However, most of the time users, just ignore it and let it run in the background while they work on other things.
Is it possible to make it so that while the Userform is being displayed, they can't do anything else on the computer forcing them to input the data?
I've tried everything from alerts to make them unable to close the form if they do not input data, but so far, nothing worked.
You can't do that. Your form is living in the EXCEL.EXE process space, and there is no way to tell Windows that EXCEL.EXE is all it's going to be doing until EXCEL.EXE says so.
This isn't a VBA limitation - you can't have a process that hijacks all message loops in every other processes on a machine, that's a recipe for disaster. I don't expect the OS to let you do that in any way, shape, or form.
Inline with the above, its best practice not to irritate your users. However, if its an application on a machine with a sole function, i.e a visitor log then you could make the form a topmost form.
see for instance https://www.mrexcel.com/forum/excel-questions/386643-userform-always-top.html for an example, and https://www.jkp-ads.com/articles/apideclarations.asp for declarations of the windows API functions
Another approach is to set a timer and alert your user with a sound...

Why am I getting a DDE error when opening a file in Explorer that associated with our application?

Our legacy MDI desktop application uses the /dde switch in the association. When opening a file associated with it, and the application has not yet started up, Explorer pops up the following error:
There was a problem sending the command to the program.
The registry looks something like this:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document]
#="App File"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\DefaultIcon]
#="d:\\Program Files (x86)\\MyApp\\version\\app.exe,1"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\open]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\open\command]
#="\"C:\\Program Files\\App\\app.exe\" /dde"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\open\ddeexec]
#="[open(\"%1\")]"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\print]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\print\command]
#="C:\\Program Files\\App\\app.exe /dde"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\print\ddeexec]
#="[print(\"%1\")]"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\printto]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\printto\command]
#="C:\\Program Files\\App\\app.exe /dde"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\App.Document\shell\printto\ddeexec]
#="[printto(\"%1\",\"%2\",\"%3\",\"%4\")]"
Just to be clear, I just took these entries from the registry. I'm not well versed in what they do, but I can hazard a guess that they link the verbs to actions by way of the DDE interface.
Note that if the application has already started up, the document opens up fine in that instance. This is only an issue if the application hasn't started up and must execute a new instance of the application.
So, what is happening is that the associated file is opened through Explorer by double clicking on it, and the associated application is executed. Explorer would then pop up that message and our application would do nothing. Double clicking on the file a second time would then open the document.
We've had this issue previously, but we just decided to ignore it for a few years as no one really knew what it was and we had other priorities at the time. Our workaround was to tell the user to change the /dde to "%1". Yeah, lame, but it worked well enough. One issue with doing that though, was that it would execute a new instance of the application, regardless if the application was already running or not.
Anyways, this issue is now starting to become an actual problem and needs to be fixed. One of our developers is saying that the DDE system is antiquated and we should try writing a COM component that will redirect to our application like Visual Studio does as debugging this issue could take a while. I've not verified that yet, nor researched how much effort that would be. However, either may be resource intensive, either on the debugging or the research side, so I'm trying to do some preliminary research to see what I can dig up and determine which is the better approach.
Stepping in the code, I was able to determine that it gets to a ::SetWindowPlacement() call and stepping over that will cause the error message box to pop up (if Explorer hasn't timed out first). As it is a WINAPI, I cannot step into that function to see what it is doing.
The application is written mostly in VC/VC++ using MFC/API and other libraries.
So my question is, does anyone know why this is happening and how it can be fixed?
Edit
Some additional information:
I was able to intercept all of the SendMessage()/PostMessage()/DispatchMessage() function calls non-destructively, which will log all of the messages. This was achieved by using MS Detours 3.0.
What I am seeing is that there are 4 SendMessage calls with a WM_COPYDATA message which appears to be coming out of shell32.dll. However, it doesn't appear to be the messages that are at fault though.
Putting a __debugbreak() when it detects the WM_COPYDATA message results in no error until a few steps beyond. How far depends on if I step or if I put a breakpoint and run the code to somewhere beyond where I thought I was getting the error. Using DebugBreak() seems to slow down the debugger to the point where I can't step without the error showing up.
What I can't understand is that there doesn't appear to be any rhyme or reason as to what is triggering the error message to pop up. I doesn't appear to be a timeout as the timeout appears to be long until I start stepping in the code, and sometimes no messages are being Sent/Posted by the code. So there's no WM_DDE_ACK (or any message for that matter) being sent back to the Explorer window that has initiated this. This is very frustrating.
To further complicate things, if I use the intrinsic __debugbreak() call and I have a breakpoint somewhere else in the code, it sometimes can stop at that breakpoint rather than stopping at the __debugbreak(). And sometimes, when I run the code immediately when I get control of the debugger, it will sometimes result in a second break, as if it hit another __debugbreak(). What's that all about? Inconsistent debugging is certainly making this issue even harder to track down. >:(
This DDE stuff is still the in use for MDI interfaces. So if one EXE opens different files.
If you can launch you application multiple times and this is OK, for the customer, switching the entries in the registry to the normal place holders from the SDI is OK too.
Usually this message is shown from the explorer, if the EXE doesn't get ready in a specific time to accept the DDE commands.
So the main question for you is: What is changed or so slow in the application that the DDE messages are not retrieved.
On case would be if it takes a real long time until the message loop starts. A running message loop for the main window is required for DDE support.
SetWindowPos istself will not be the problem, but it might cause hundreds of messages (WM_SIZE, ...) to be fired to your application, and every handler in your application here might be the problem.
Just place a little timer inside the application in front of the SetWindowPos and check how long it takes to return...
Check how long the app takes, until InitInstance is exited with TRUE. After InitInstance exits CWinApp::Run starts and the message loop starts.
I've run into the same problem.
My solution was to add the ../ddeexec/* section in the registry on application startup and then remove them on application exit.
Not a very nice solution but it is easy to do, and it works.

problems testing sharepoint with selenium (timeouts, repeating auth and missed links)

I have some serious problems testing a sharepoint site with selenium/bromine. As I did't find an answer via various searches I hope someone here can point me in the right direction.
I am constantly getting timeouts opening the main page, but the server is definetly fast enough to answer the request and at 90% idle. Nevertheless I just get logs like these:
open http://username:passwd#10.13.110.54/default.aspx | Timed out after 90000ms
Test terminated The selenium server did not return OK
The auth popup is popping up at irregular intervals (every 5 to 10 clicks) although every open command uses the http://username:passwd#10.13.110.54/ as prefix
Clicking on elements is sometimes not registered, the logs show a successful
isElementPresent link=myLink
click link=myLink
but the browser doesn't react. These are mainly in-page links which open a new folder or an editing box.
I'm not sure whether I should have posted the in three separate questions, but I didn't want to spam.
Hope someone can help me, as I have these problems now for nearly 3 weeks.
Thanks in advance
Thomas
For your question number 2: Okay, this is a really late reply. I stumbled on this page looking for the answer myself. Given that I have solved it in the meantime, I figured I'd post my answer for other people stumbling onto this page.
General solution:
You need to create or use a profile that will let firefox automatically forward your credentials to the sharepoint website. You can create the profile manually and call it each time, see https://applicationtestingtips.wordpress.com/2009/12/21/seleniumrc-handle-windows-authentication-firefox/ for instructions.
Programmer solution: (works in python, should work similarly in Java)
Or you can create a new profile on the fly each time. I did that based on the information in the previously mentioned website. I use python for calling selenium, but this should be rather similar in whatever language you use to call selenium:
sharepointHosts = 'sharepoint1.mycompany.com,sharepoint2.mycompany.com' #have all your sharepoint hosts here in a comma-separated list
ffProfile.set_preference('network.automatic-ntlm-auth.trusted-uris', sharepointHosts)
ffProfile.set_preference('network.negotiate-auth.delegation-uris', sharepointHosts)
ffProfile.set_preference('network.negotiate-auth.trusted-uris', sharepointHosts)
driver = webdriver.Firefox(firefox_profile=ffProfile)

Resources