Giter Club home page Giter Club logo

ulogme's Introduction

ulogme

How productive were you today? How much code have you written? Where did your time go?

Keep track of your computer activity throughout the day: visualize your active window titles and the number of keystrokes in beautiful HTML timelines. Current features:

  • Records your active window title throughout the day
  • Records the frequency of key presses throughout the day
  • Record custom note annotations for particular times of day, or for day in general
  • Everything runs completely locally: none of your data is uploaded anywhere
  • Beautiful, customizable UI in HTML/CSS/JS (d3js).

The project currently only works on Ubuntu and OSX, and uses new fancy Promises feature of ECMAScript 6. This might not be implemented in all browsers. My Chrome has it, but for example my Firefox doesn't.

Demo

See a blog post (along with multiple screenshots) describing the project here.

Getting Started

To start recording

  1. Clone the repository to some folder: $ git clone https://github.com/karpathy/ulogme.git
  2. If you're on Ubuntu, make sure you have the dependencies: $ sudo apt-get install xdotool wmctrl. On Fedora, you may also need sudo yum install gnome-screensaver.
  3. cd inside and run $ ./ulogme.sh (note: this will ask you for sudo authentication which is required for showkey command). This will launch two scripts. One records the frequency of keystrokes and the other records active window titles. Both write their logs into log files in the logs/ directory. Every log file is very simply just the unix time stamp followed by data, one per line.
  4. For OSX only: there might be an additional step where you have to go to System Preferences > Security & Privacy > Accessibility, and make sure that Terminal (or iTerm2, or whatever you use to launch ulogme) is checked. If it wasn't checked previously and you just checked it, you may need to restart ulogme. If you don't do this step, you might find that window logging works but keypress logging doesn't.

The user interface

  1. Important. As a one-time setup, copy over the example settings file to your own copy: $ cp render/render_settings_example.js render/render_settings.js to create your own render_settings.js settings file. In this file modify everything to your own preferences. Follow the provided example to specify title mappings: A raw window title comes in, and we match it against regular expressions to determine what type of activity it is. For example, the code would convert "Google Chrome - some cool website" into just "Google Chrome". Follow the provided example and read the comments for all settings in the file.
  2. Once that's set up, start the web server viewer: $ python ulogme_serve.py, and go to to the provided address) for example http://localhost:8123) in your browser. Hit the refresh button on top right every time you'd like to refresh the results based on most recently recorded activity
  3. If your data isn't loading, try to explicitly run python export_events.py and then hit refresh. This should only be an issue the very first time you run ulogme.

User Interface

The user interface can switch between a single day view and an overview view by link on top. You have to hit the refresh button every time you'd like to pull in new data.

Single day page

  • You can enter a reminder "blog" on top if you'd like to summarize the day for yourself or enter other memos.
  • Click on any bar in the barcode view to enter a custom (short) note snippet for the time when the selected activity began. I use this to mark meetings, track my coffee/food intake, sleep time, or my total time spent running/swimming/gym or to leave notes for certain patterns of activity, etc. These could all later be correlated with various measures of productivity, in future.

Overview page

  • You can click the window titles to toggle them on and off from the visualization
  • Clicking on the vertical bars takes you to the full statistics for that day.

Known issues

  • One Ubuntu user reported broken view with no data. On further inspection we found that the logs were corrupt. One of the lines in a file in /logs was, instead of looking as {timestamp} {data} looked as @@@@@@@{timestamp} {data}, in other words an odd character was appended to the timestamp somehow. We manually erased these characters from the log file to fix the issue.
  • Legacy code note: if you used ulogme from before 28 July, you will have to run $ python legacy_split_events.py to convert your events files, once.
  • You may see "address already in use" if you try to run python ulogme_serve.py. Sometimes the system can get confused and takes a while to update what ports are being used. Use the optional argument to specify a different port, for example python ulogme_serve.py 8124 and then go to http://localhost:8124 instead, for example.
  • Overview page is blank. Are you sure your browser supports ECMAScript 6? Chrome should be fine, Firefox might not be, yet.

Contributing

The Ubuntu and OSX code base are a little separate on the data collection side. However, they each just record very simple log files in /logs. Once the log files are written, export_events.py takes the log files, does some simple processing and writes the results into .json files in /render. The Javascript/HTML/CSS UI codebase is all common and all lives in /render.

Ubuntu

ulogme has three main parts:

  1. Recording scripts keyfreq.sh and logactivewin.sh. You probably won't touch these.
  2. Webserver: ulogme_serve.py which wraps Python's SimpleHTTPServer and does some basic communication with the UI. For example, the UI can ask the server to write a note to a log file, or for a refresh.
  3. The UI. Majority of the codebase is here, reading the .json files in /render and creating the visualizations. There are several common .js files, and crucially the index.html and overview.html files. I expect that most people might be able to contribute here to add features/cleanup/bugfix.

OSX code

Things get a little ugly in OSX if you want to change anything with recording the log files because you have to recompile these portions any time you make any changes. It's ugly and it had to be done. However, if you're only interested in hacking with the UI, just change Javascript in render and no recompile is necessary, naturally.

Related projects

  • selfspy, Log everything you do on the computer, for statistics, future reference and all-around fun.
  • arbtt, automatic rule-based time tracker.

For more projects, this question on Personal Productivity Stack Exchange might be also worth a look.

License

MIT

ulogme's People

Contributors

binarybana avatar hexylena avatar jcjohnson avatar karpathy avatar pwcazenave avatar shazow avatar tobiasploetz avatar ypid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ulogme's Issues

Logging time spent inside a particular folder

Hi there,

Wonderful little tool you created there, Andrej. I have been using it for some time now and works like a charm.

I wanted to know whether there is a way to specify the folder or directory where I am coding in the render settings file. I am working on two different projects (in Python) and wanted to separate the time spent on the two out.

Thanks for your reply

Dhruv

Nothing else than "Locked Screen"

Hi,

I have just tried your stuff on my machine (Kubuntu 14.04 LTS) but while the total key frequencies update well in the bottom of the overview, the only window listed is "Locked Screen" with really small values (32 keys). On the single-day view there is also only this window with a small value (1m4s). Even if I re-execute manually the refreshing in the console and then refresh the interface, only the key frequencies change (by the way I did not need to sudo anything).

Additionally, locking my screen during a while and unlocking does not change the time spent, and executing manually the refresh in command line gives me this error:

a log file has changed, so will update render/events_1434085200.json
logs/notes_1434085200.txt probably does not exist, setting empty events list.
error was:
[Errno 2] No such file or directory: 'logs/notes_1434085200.txt'
wrote render/events_1434085200.json
wrote render/export_list.json

Any suggestion/fix?

Notes aren't properly escaped in Python, security concern

After posting this, I had a change of heart and wanted to email @karpathy instead and give him a bit of time, but found that I could not delete the issue (and title edit history is saved and visible), and rationalised that it seems obvious anyway and people probably already know if they looked at the code and understand Python string formatting.

To reproduce the bug under Linux, open ulogme's web UI, then click on an event, and try saving a note like "This is a test && echo 'hello world' > /home/user/test"

It doesn't save the whole note, and there's a new file under "/home/user/test" (if you could write to /home/user/) - proving an arbitrary execution security hole for anyone running ulogme with IP set to "" (the default), most default firewall setups, and untrusted devices on their LAN.

https://github.com/karpathy/ulogme/blob/master/ulogme_serve.py#L48

Merging #33 will go some way to remedying other issues like this that might exist. Or using an IP setting of "127.0.0.1" (instead of empty string or "0.0.0.0"), which means only localhost will be able to access the server (though I think this means that other users running on your system will still be able to execute commands as you).

This is how I fixed it in my own copy of ulogme. Replace line 48 in ulogme_serve.py with:

      writenote(note, note_time)

Add this after the current import statements:

import subprocess

Then add this function either just before or just after the class definition:

def writenote(note, time_=None):
  cmd = ["./note.sh"]
  if time_ is not None:
    cmd.append(str(time_))
  process = subprocess.Popen(cmd, stdin=subprocess.PIPE)
  process.communicate(input=note)
  process.wait()

I can't check whether that would work on OSX.

No keystrokes logged on OS X 10.9?

Hi Andrej,

Firstly, thanks for making this awesome tool. I read your blog post and am excited to try it out for myself. Unfortunately, though, I can't get it to log any keystrokes. The window title logging works fine and nothing reports any errors--it just always logs 0 keystrokes.

Steps to reproduce:
Clone the repo and cd into it
Create a suitable settings file as per your instructions
$ bash ulogme.sh
Verify that keyfreqraw.txt is written every few seconds, but that the keyfreq_* file records 0 keystrokes

OS:
OS X 10.9.4

I also tried installing pyobjc and running the python scripts directly by changing the DEV flag in run_ulogme_osx.sh, but to no avail. I added debug output to the EventSniffer.event_handler, and it appears this function just isn't being called.

I know in 10.9 one typically has to explicitly allow the app to "control this computer" in System Preferences > Security & Privacy > Accessibility in order to use NSEvent's
addGlobalMonitorForEventsMatchingMask:, but the menu doesn't present ulogme.app as an option, suggesting that maybe there's some missing step for the app to register its event tap...

If this is both a real issue (rather than me just missing something) and a pain to fix, I can probably contribute a native Cocoa app that would produce the needed functionality--just let me know.

osx rare errors

From time to time, I get rare errors on osx yosemite:

2015-02-19 10:48:42.054 ulogme_osx[785:6450] <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\xe9' in position 47: ordinal not in range(128)
2015-02-19 10:48:42.063 ulogme_osx[785:6450] (
    0   CoreFoundation                      0x00007fff92f2f66c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff9425f76e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff92f2f209 -[NSException raise] + 9
    3   _objc.so                            0x0000000104ad0626 PyObjCFFI_MakeClosure + 2197
    4   libffi.dylib                        0x00007fff8bfdfa07 ffi_closure_unix64_inner + 511
    5   libffi.dylib                        0x00007fff8bfdf0c6 ffi_closure_unix64 + 70
    6   CoreFoundation                      0x00007fff92e82b64 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    7   CoreFoundation                      0x00007fff92e827f3 __CFRunLoopDoTimer + 1059
    8   CoreFoundation                      0x00007fff92ef5dbd __CFRunLoopDoTimers + 301
    9   CoreFoundation                      0x00007fff92e3f288 __CFRunLoopRun + 2024
    10  CoreFoundation                      0x00007fff92e3e858 CFRunLoopRunSpecific + 296
    11  HIToolbox                           0x00007fff8ef9daef RunCurrentEventLoopInMode + 235
    12  HIToolbox                           0x00007fff8ef9d86a ReceiveNextEventCommon + 431
    13  HIToolbox                           0x00007fff8ef9d6ab _BlockUntilNextEventMatchingListInModeWithFilter + 71
    14  AppKit                              0x00007fff921c6f81 _DPSNextEvent + 964
    15  AppKit                              0x00007fff921c6730 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194
    16  AppKit                              0x00007fff921ba593 -[NSApplication run] + 594
    17  libffi.dylib                        0x00007fff8bfdef44 ffi_call_unix64 + 76
    18  ???                                 0x00007fd68c165440 0x0 + 140559450002496
)

Use of xinput under linux could remove sudo requirement

More of an FYI/feature request.

I don't know if xinput is available under OSX (judging by the issue reports, that's the primary user base), but under linux xinput allows you to capture key presses without requiring root.

$ xinput list
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=12   [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Video Bus                                 id=8    [slave  keyboard (3)]
    ↳ Sleep Button                              id=9    [slave  keyboard (3)]
    ↳ HP HD Webcam                              id=10   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳ HP Wireless hotkeys                       id=13   [slave  keyboard (3)]
    ↳ HP WMI hotkeys                            id=14   [slave  keyboard (3)]

$ xinput test 11 # AT Translated Set 2 keyboard, can move to other screens/windows.
key release 36 
key press   65 
key release 65 
key press   38 
key press   39 
key press   46 

export_events.py needed running before web interface would work?

I had an issue with getting the web interface to show any data (ajax requests for export_list.json was returning a 404 error). Hitting refresh on the page didn't change anything. Eventually I ran export_events.py, then tried web interface again, and my data finally showed.

(Also for what it's worth, underscore-min.map returning a 404 error)

logs/keyfreq_...txt

My key freq log file has timestamps, but each timestamp has a zero associated with it. When I load the webpage, there is no number next to total number of key strokes: The other log file looks reasonable.

➜ ulogme git:(master) cat logs/keyfreq_1417262400.txt
1417318604 0
1417318613 0
1417318622 0
1417318631 0
1417318640 0
....

Ulog

Hi from where i can fund the units of ulog parameters such as i want to know the units for Attitude

extract all times from all log files isn't working

Hello,

in file export_events.py on the line 54 the interpeter generates an exeption:

Traceback (most recent call last):
File "export_events.py", line 117, in
updateEvents()
File "export_events.py", line 54, in updateEvents
ts = [int(x[x.find('_')+1:x.find('.txt')]) for x in L]
ValueError: invalid literal for int() with base 10:

Incorrect comment in render_settings_examples.js

The comment goes like this:

// be very careful with ordering in the above because titles
// get matched from up to down (see mapwin()), so put the more specific
// window title rules on the bottom and more generic ones on top

Shouldn't the more specific rules go on top so that they get matched above the generic ones?

Starting ulogme at login

Hello,

I am not too sure where to put the instructions or the code for starting ulogme at run time. I think though it would be useful for others. I can contribute but need some guidance.

Cheers

overview not working

I have been using ulogme for 6 months (between Jan-Jun), and then I had a large gap without data (installed Ubuntu 16.04 and didnt setup commands to start ulogme at startup).. now I started logging again.. And in overview page "Key frequencies during each day" is blank and console log says (in Chrome):

Uncaught (in promise) TypeError: Cannot read property 't' of undefined
    at drawKeyEvents (http://localhost:8124/overview.html:218:32)
    at http://localhost:8124/overview.html:364:9

Console log (Firefox)

TypeError: es[0] is undefined

And that is the line causing the error:

        var d0 = new Date(es[0].t * 1000);

I'm guessing this is not promise compatability issue because both Chrome and Firefox were able to show overview page without problems 4-5 months ago.
How can I fix this problem? (I pulled the latest version - 416163e version)

__LOCKEDSCREEN didn't catch a thing (Yosemite). 'loginwindow' did

Tried ulogme for two days in MacOsX Yosemite. Most events were into "MISC", and even after customizing my render settings, I observed MISC was still big. Then discovered loginwindow event was captured instead of __LOCKEDSCREEN.

Not sure if it has something to do with any custom Mac config? In fact I usually put my Macbook to sleep while having lunch, and loginwindow was registered on that time... also the Mac was warm when returning from lunch, which makes me think that ulogme prevented it of going to sleep (this is not confirmed, though. I need more testing). Anyway, I got that loginwindow event and none of __LOCKEDSCREEN.

PS: congrats for the tool, I love it 😉

Python 3 support not present.

File "export_events.py", line 116, in
updateEvents()
File "export_events.py", line 53, in updateEvents
ts = [int(x[x.find('')+1:x.find('.txt')]) for x in L]
File "export_events.py", line 53, in
ts = [int(x[x.find('
')+1:x.find('.txt')]) for x in L]
ValueError: invalid literal for int() with base 10: ''

For python export_events.py.

I'm running Python3, fixed the issues caused by Python3 compatibility, this seems to be something other than Python 2/3 problem.

I'll update my pull request in order to accomodate all the changes needed for python3, but I cannot seem to work where both Python2 and Python3 coexist.

Sudo permissions required for showkey to read /dev/console

Thanks for the awesome set of scripts! I've been really enjoying this.

On my ubuntu systems (13.10) I have to sudo showkey in order for it to access /dev/console otherwise it gives the cryptic error:

Couldn't get a file descriptor referring to the console

Problem with xscreensaver

Hi,

When I run logactivewin.sh in Xfce I get the following error: no saver status on root window., and only __LOCKEDSCREEN is logged.

I assume it is a problem of when it checks the screensaver (I had to install xscreensaver in the first place, as it wouldn't work otherwise; and I don't see why this should be required).

I have seen here a similar problem related to the gnome-screensaver: #24

I am not familiar with the language, so I'm not of much help. Does anybody know what needs to be fixed?
I assume it would be here?

do
    islocked=true
    # Try to figure out which Desktop Manager is running and set the
    # screensaver commands accordingly.
    if [[ $GDMSESSION == 'xfce' ]]; then
        # Assume XFCE folks use xscreensaver (the default).
        screensaverstate=$(xscreensaver-command -time | cut -f2 -d: | cut -f2-3 -d' ')
        if [[ $screensaverstate =~ "screen non-blanked" ]]; then islocked=false; fi
    elif [[ $GDMSESSION == 'ubuntu' || $GDMSESSION == 'ubuntu-2d' || $GDMSESSION == 'gnome-shell' || $GDMSESSION == 'gnome-classic' || $GDMSESSION == 'gnome-fallback' || $GDMSESSION == 'cinnamon' ]]; then
        # Assume the GNOME/Ubuntu/cinnamon folks are using gnome-screensaver.
        screensaverstate=$(gnome-screensaver-command -q 2>&1 /dev/null)
        if [[ $screensaverstate =~ .*inactive.* ]]; then islocked=false; fi
    elif [[ $XDG_SESSION_DESKTOP == 'KDE' ]]; then
        islocked=$(qdbus org.kde.screensaver /ScreenSaver org.freedesktop.ScreenSaver.GetActive)
    else
        # If we can't find the screensaver, assume it's missing.
        islocked=false
    fi

    if [ $islocked = true ]; then
        curtitle="__LOCKEDSCREEN"
    else 
        id=$(xdotool getactivewindow)
        curtitle=$(wmctrl -lpG | while read -a a; do w=${a[0]}; if (($((16#${w:2}))==id)) ; then echo "${a[@]:8}"; break; fi; done)
    fi

    perform_write=false

Here is xscreensaver-command as possible reference: https://github.com/danfuzz/xscreensaver/blob/master/driver/xscreensaver-command.c

Thank you!

SyntaxError

Hi.
First of all, thanks for the amazing project, I love the spirit of data collection and great visualisation!

When I run ulogme.sh, I constantly get the following error:

SyntaxError: invalid syntax
logged key frequency: Wed Jun  1 17:19:36 BST 2016 0 release events detected into logs/keyfreq_.txt
  File "rewind7am.py", line 27
    print rewindTime(int(time.time()))
                   ^
SyntaxError: invalid syntax
[...]

Data is still recorded in the window_txt and keyfreq_.txt logs (In this format, e.g.: 1464797947 ulogme - File Manager -- I don't know if it is correct, with that date format.)

I also get these errors running the UI scripts (and they don't do anything):

$ python export_events.py
  File "export_events.py", line 26
    except Exception, e:
                    ^
SyntaxError: invalid syntax

$ python ulogme_serve.py
  File "ulogme_serve.py", line 72
    print 'Serving ulogme, see it on http://localhost:' + `PORT`
                                                      ^
SyntaxError: Missing parentheses in call to 'print'

I am on Manjaro 16.06 (Xfce) Linux.

Do you know what the problem could be and how (if) it can be solved?

Thanks!

Keystroke counting requires new permissions in Mac OSX

This line should be added at line 29 on the readme.md:

  1. As of Mac OS 10.14 there is an additional permission that needs to be granted to the shell script in order to count keystrokes. To do so, go to System Preferences > Security & Privacy > Input Monitoring, add ulogme/osx/dist/ulogme_osx and make sure it is checked off. Lock the settings, and restart the script and keystrokes should begin to get recorded.

Fedora 20

It also works on Fedora 20, but it needs the gnome-screensaver command, which can be installed with:

sudo yum install gnome-screensaver

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.