2

I'm writing an AI personal assistant. One part of the software is a monitor daemon. A small process that monitor's user's active windows. I'm using python( with libwnck and psutils for obtaining info on active windows). One thing I'd like my monitor to do is to keep track of music that the listener often listen's to.

Is there anyway I could 'monitor' opening and closing of files? psutils.Process has a function that returns a list of open files, but I need some way to notify it to check for it. Currently it only checks process data when window switches, or a window is opened or closed.

  • 1
    Have you looked at lsof? You can give this command a pid and see what files it has open currently. – datUser Jun 3 '15 at 13:54
  • I already have psutil for that. I just need some method of knowing if a file was closed or opened. I could then ask psutil to get a list of files 'X' process is using. – turtleDev Jun 3 '15 at 17:42
4

You can monitor the opening/closing of files using the inotify subsystem. pyinotify is one interface to this subsystem.

Note that if you have a lot of events going to inotify, some can be dropped, but it works for most cases (especially your case in which user interaction will drive the opening/closing of files).

pyinotify is available via easy_install/pip and at https://github.com/seb-m/pyinotify/wiki

MWE (based on http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/):

#!/usr/bin/env python
import pyinotify

class MyEventHandler(pyinotify.ProcessEvent):
    def process_IN_CLOSE_NOWRITE(self, event):
        print "File closed:", event.pathname

    def process_IN_OPEN(self, event):
        print "File opened::", event.pathname

def main():
    # Watch manager (stores watches, you can add multiple dirs)
    wm = pyinotify.WatchManager()
    # User's music is in /tmp/music, watch recursively
    wm.add_watch('/tmp/music', pyinotify.ALL_EVENTS, rec=True)

    # Previously defined event handler class
    eh = MyEventHandler()

    # Register the event handler with the notifier and listen for events
    notifier = pyinotify.Notifier(wm, eh)
    notifier.loop()

if __name__ == '__main__':
    main()

This is quite low-level information - you might be surprised how often your program uses these low-level open/close events. You can always filter and coalesce events (for example, assume events received for the same file in a certain time period correspond to the same access).

  • Another question. My program uses gobject.mainloop. If I run this, I'll have to run it in a seprate thread, and use some form of Interprocess communication to make it work. Also. Let's say I don't know where the music files are. How do I make it work then? – turtleDev Jun 3 '15 at 18:05
  • @turtleDev If you don't know where the files are, this can get messy since you definitely don't want to listen to /. Is it possible to assume $HOME? Or maybe you can look at directories opened by the music player process... I also think the lsof/psutil stuff that was discussed previously could work if you poll every N seconds, where N is much shorter than most songs. – zje Jun 3 '15 at 18:14
  • Yes. I'm considering it. But it would add to overhead. I'm already doing stuff that actively scans stuff, which will eventually lead to high overhead. One method I have in mind is to use find / | grep media format and then store paths where media files were found, and monitor those. But aren't there any straightforward ways of doing this? – turtleDev Jun 3 '15 at 18:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.