是否有时间跟踪窗口和应用程序使用情况的软件?

amb*_*mbi 13 time scripts window focus log

是否有软件可以记录我的活动时间并提供报告?基于焦点窗口和窗口标题。报告只会显示特定窗口所花费的时间及其标题,例如:

Application   Title                             Time
Firefox       Ask Ubuntu - Mozilla Firefox      5:58
Run Code Online (Sandbox Code Playgroud)

Jac*_*ijm 8


编辑:可以在此处找到带有排序报告的脚本版本


为它编写脚本总是很有趣!

下面的脚本将产生一个输出(报告),如:

------------------------------------------------------------
nautilus
0:00:05 (3%)
------------------------------------------------------------
   0:00:05 (3%)     .usagelogs
------------------------------------------------------------
firefox
0:01:10 (36%)
------------------------------------------------------------
   0:00:05 (3%)     The Asker or the Answerer? - Ask Ubuntu Meta - Mozilla Firefox
   0:00:15 (8%)     scripts - Is there software which time- tracks window & application usage? - Ask Ubuntu - Mozilla Firefox
   0:00:10 (5%)     Ask Ubuntu - Mozilla Firefox
   0:00:15 (8%)     Why is a one line non-understandable answer used as review audit? - Ask Ubuntu Meta - Mozilla Firefox
   0:00:20 (10%)    bash - How to detect the number of opened terminals by the user - Ask Ubuntu - Mozilla Firefox
   0:00:05 (3%)     BlueGriffon - Mozilla Firefox
------------------------------------------------------------
gedit
0:02:00 (62%)
------------------------------------------------------------
   0:02:00 (62%)    2016_06_04_10_33_29.txt (~/.usagelogs) - gedit

============================================================
started: 2016-06-04 10:33:29    updated: 2016-06-04 10:36:46
============================================================
Run Code Online (Sandbox Code Playgroud)


..每分钟更新一次。

笔记

  • 该报告可能会在“未知”类别下报告窗口。当windows有pid 0tkinterwindows,比如Idlewindows,一个PythonIDE)时就是这种情况。但是,它们的窗口标题和用法将被正确报告。

  • 带有密码输入的锁屏被报告为“nux 输入窗口”。

  • 百分比是四舍五入的百分比,这有时可能会导致应用程序的百分比与其窗口百分比的总和之间存在细微差异。

    一个例子:如果一个应用程序使用了两个窗口,每个窗口使用0,7%的总时间,两个窗口都会报告1%每个(0.7-->四舍五入1),而应用程序的使用报告1%1.4-->四舍五入到1

    不用说,这些差异在整个画面中完全无关紧要。

剧本

#!/usr/bin/env python3
import subprocess
import time
import os

# -- set update/round time (seconds)
period = 5
# -- 
# don change anything below
home = os.environ["HOME"]
logdir = home+"/.usagelogs"

def currtime(tformat=None):
    return time.strftime("%Y_%m_%d_%H_%M_%S") if tformat == "file"\
           else time.strftime("%Y-%m-%d %H:%M:%S")

try:
    os.mkdir(logdir)
except FileExistsError:
    pass

# path to your logfile
log = logdir+"/"+currtime("file")+".txt"; startt = currtime()

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

def time_format(s):
    # convert time format from seconds to h:m:s
    m, s = divmod(s, 60); h, m = divmod(m, 60)
    return "%d:%02d:%02d" % (h, m, s)

def summarize():
    with open(log, "wt" ) as report:
        totaltime = sum([it[2] for it in winlist])
        report.write("")
        for app in applist:
            wins = [r for r in winlist if r[0] == app]
            apptime = sum([it[2] for it in winlist if it[0] == app])
            appperc = round(100*apptime/totaltime)
            report.write(("-"*60)+"\n"+app+"\n"+time_format(apptime)+\
                         " ("+str(appperc)+"%)\n"+("-"*60)+"\n")
            for w in wins:
                wperc = str(round(100*w[2]/totaltime))
                report.write("   "+time_format(w[2])+" ("+\
                             wperc+"%)"+(6-len(wperc))*" "+w[1]+"\n")
        report.write("\n"+"="*60+"\nstarted: "+startt+"\t"+\
                     "updated: "+currtime()+"\n"+"="*60)

t = 0; applist = []; winlist = []
while True:
    time.sleep(period)
    frpid = get(["xdotool", "getactivewindow", "getwindowpid"])
    frname = get(["xdotool", "getactivewindow", "getwindowname"])
    app = get(["ps", "-p", frpid, "-o", "comm="]) if frpid != None else "Unknown"
    # fix a few names
    if "gnome-terminal" in app:
        app = "gnome-terminal"
    elif app == "soffice.bin":
        app = "libreoffice"
    # add app to list
    if not app in applist:
        applist.append(app)
    checklist = [item[1] for item in winlist]
    if not frname in checklist:
        winlist.append([app, frname, 1*period])
    else:
        winlist[checklist.index(frname)][
            2] = winlist[checklist.index(frname)][2]+1*period
    if t == 60/period:
        summarize()
        t = 0
    else:
        t += 1
Run Code Online (Sandbox Code Playgroud)

如何设置

  1. 脚本需要xdotool获取窗口的信息

    sudo apt-get install xdotool
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将脚本复制到一个空文件中,另存为 window_logs.py

  3. 测试运行脚本:通过命令(从终端)启动脚本:

    python3 /path/to/window_logs.py
    
    Run Code Online (Sandbox Code Playgroud)

    一分钟后,脚本创建一个日志文件,其中第一个结果为~/.usagelogs. 该文件带有创建日期和时间的时间戳。该文件每分钟更新一次。

    在文件底部,您可以看到最新编辑的开始时间和时间戳。通过这种方式,您始终可以看到文件的时间跨度。

    如果脚本重新启动,则会创建一个带有新 (start-) 时间戳的新文件。

  4. 如果一切正常,请添加到启动应用程序:Dash > 启动应用程序 > 添加。添加命令:

    /bin/bash -c "sleep 15 && python3 /path/to/window_logs.py"
    
    Run Code Online (Sandbox Code Playgroud)

更多笔记

  • ~/.uselogs默认是隐藏目录。按 (in nautilus) Ctrl+H使其可见。
  • 事实上,脚本在 5 秒内舍入窗口的活动性,假设少于 5 秒没有真正使用该窗口。如果您想更改该值,请将其设置在脚本开头的行中:

    # -- set update/round time (seconds)
    period = 5
    # -- 
    
    Run Code Online (Sandbox Code Playgroud)
  • 该脚本非常“缺乏果汁”。此外,由于每个窗口的时间更新是在脚本内部完成的,因此日志文件中的行数仅限于实际使用的窗口数。

    尽管如此,例如,我不会连续几周运行脚本,以防止积累太多行(= 窗口记录)来维护。