Coder Social home page Coder Social logo

eerovil / tracklater Goto Github PK

View Code? Open in Web Editor NEW
122.0 8.0 4.0 323 KB

TrackLater helps you track time after-the-fact by combining clues and showing your day on a simple timeline view.

License: MIT License

Python 70.66% JavaScript 23.94% HTML 4.35% Dockerfile 1.06%
time-tracker toggl slack thyme git taiga jira linux opensource python

tracklater's Introduction

TrackLater

Screenshot has green/red colors for my current two projects/clients. Commits, thyme entries and slack messages are automatically colored.

Forgot to track your time for work? TrackLater helps you track time after-the-fact by combining clues and showing your day on a simple timeline view.

The initial version supports fetching clues from

Time entries can be exported to

  • Toggl
  • Clockify

Issues and projects/clients can be fetched from

  • Jira
  • Taiga
  • GitHub
  • Toggl (projects/clients)

Background

Everyone who uses time-tracking for their work knows that it can be a real pain, especially if you're a forgetful person like me. I pretty much never remember to start my timers, and when I do, I for sure will not remember to turn them off.

When working with multiple clients, it can be crucial (billing-wise) to track your time correctly and to be able to differentiate all tasks by client. For people that work 9-5 in-office for the same client and without need to track each task separately this app is probably overkill.

With this in mind, I built a basic app to use Thyme for passive time-tracking, and Toggl-api for exporting. I quickly found that my workflow was substantially improved by only having to think about time-tracking 1-2 times per week. I've now used this app for about a year, building a new timemodule every now and then.

TrackLater offers a basic set of features to help all time-trackers get their timesheets in order:

  • A timeline overview, which is usually missing from tracking software
  • Easily add time entries, with automatically detected projects and responsive UI
  • Get all your breadcrumbs, tracks, clues, footsteps in one place

Implementation notes

Every module separates their issues, time-entries and projects by group. This makes inter-module communication simple: e.g. commits made in the git repository for group x will be attributed to the corresponding Toggl project for group x.

Groups are arbitrary and decided by the user when creating their settings file. A good way to choose your amount of groups is to create a group for each client/work project.

While all modules are optional, an important backbone for TimeLater is thyme. UPDATE: I couldn't get thyme working on my new mac, so the new "backbone" will be ActivityWatch. The thyme module assumes an implementation where every day is stored in a file named YYYY-MM-DD.json. It's recommended to set up an automatic thyme tracking script for this.

I'm using a basic script to run thyme. It has evolved a bit after about a year of tracking: Sometimes thyme fails tracking and corrupts the whole file, so I definitely recommend using this script. https://gist.github.com/Eerovil/36d109d531659d24bfafea7111b12e90

To run thyme automatically every 20 seconds you can add this to your crontab. Windows users can probably use services (don't quote me on this).

* * * * * DISPLAY=:0 /home/eero/Documents/thyme/track-thyme-log.sh
* * * * * ( sleep 20; DISPLAY=:0 /home/eero/Documents/thyme/track-thyme-log.sh )
* * * * * ( sleep 40; DISPLAY=:0 /home/eero/Documents/thyme/track-thyme-log.sh )

Running

Install inside a virtualenv from PyPI. After first run & page load the example configuration should be created at ~/.config/tracklater.json (Windows and Mac configs found somewhere else, check here).

mkvirtualenv tracklater -p python3.7
pip install tracklater
tracklater

or

Clone the repository, install inside a virtualenv and run:

git clone [email protected]:Eerovil/TrackLater.git
cd TrackLater
mkvirtualenv tracklater -p python3.7 -a .
pip install .
tracklater

Additional example command to start the server. Must be run in the root directory.

FLASK_APP=tracklater python -m flask run

Usage

Select time entries from thyme and click export.

You can also double click on the timeline to create entries. Edit by selecting, dragging etc.

Contributing

Building and running the project is easy, as you can simply clone the repo and start making PRs.

If your workflow is not exactly like mine and you need additional functionality, please create an issue and we can start working on supporting your required modules.

Ideas for future support:

  • Jira time tracking
  • Maybe a Chrome page history parser?

Settings guide

Create a file called user_settings.py to the root folder (containing app.py)

To load test settings you can add from test_settings import * to the end of the file. This will use test data and no actual API calls will be made.

Each module has their own settings dict, containing a settings dict for each group. There is also a global key for non-group specific settings.

This example settings file contains two groups: group1 and group2.

In the example workers workflow, group1's issues are fetched from Jira while group2's issues are from Taiga.io, so you will find that the JIRA settings have no group2 key and TAIGA settings has no group1 key.

Time tracking (for billing) is done through Toggl. Also, both groups happen to have their own workspaces on slack, and obviously their own git repositories.


# edit to your liking and save as ~/.config/tracklater.json. Remove the comments

{
    "TESTING": false,
    "ENABLED_MODULES": [
        "activitywatch",
        "thyme",
        "gitmodule",
        "toggl",
        "clockify",
        "taiga",
        "jira",
        "slack"
    ],

    "UI_SETTINGS": {
        "toggl": {
            "global": "#E01A22"
        },
        "thyme": {
            "global": "#1aef65"
        },
        "gitmodule": {
            "global": "#F44D27"
        },
        "slack": {
            "global": "#4A154B"
        }
    },
    "TOGGL": {
        "global": {
            "API_KEY": "your-api-key"
        },
        "group1": {
            "NAME": "First Group",
            "PROJECTS": {
                "Development": "default",
                "Bug fixing": "bug"
            }
        },
        "group2": {
            "NAME": "Second Group",
            "PROJECTS": {
                "Development": "default",
                "Bug fixing": "default"
            }
        }
    },

    "CLOCKIFY": {
        "global": {
            "API_KEY": "",
            "WORKSPACE": "workspace-id" # This is optional. (Only one workspace is supported!)
        },
        "group1": {
            "NAME": "Red",
            "PROJECTS": {
                "Red": "default"
            }
        },
        "group2": {
            "NAME": "Blue",
            "PROJECTS": {
                "Blue": "default"
            }
        }
    },


    "GIT": {
        "global": {
            # Only commits made by users with EMAILS will be shown
            "EMAILS": ["[email protected]"]
        },
        "group1": {
            # Full path to the git repo
            "REPOS": ["/full/path/to/group1/repo"]
        },
        "group2": {
            "REPOS": ["/full/path/to/group2/repo"]
        }
    },

    "JIRA": {
        "group1": {
            # Each group must have these settings
            "CREDENTIALS": ["username", "password"],
            "URL": "https://group1.atlassian.net",
            "PROJECT_KEY": "DEV"
        }
    },

    "TAIGA": {
        "global": {
            "CREDENTIALS": ["username", "password"]
        },
        "group2": {
            # project_slug can be found in the URL
            "project_slug": "username-group2"
        }
    },

    "THYME": {
        "global": {
            # Directory containing the json files generated by thyme
            "DIR": "/full/path/to/thyme/dir"
        }
    },

    "ACTIVITYWATCH": {
        "global": {
            "EVENTS_URL": "http://host.docker.internal:5600/api/0/buckets/aw-watcher-window_Eeros-MacBook-Air.local/events",
            "IDLE": 900,
            "CUTOFF": 300
        },
    },

    "GITHUB": {
        "global": {
            "TOKEN": "token" # needs permissions specified here: https://developer.github.com/v4/guides/forming-calls/#authenticating-with-graphql
        },
        "group1": {
            "repo": ["owner", "repo1"]
        },
        "group2": {
            "repo": ["owner", "repo2"]
        }
    },

    "SLACK": {
        # Each group should contain a workspace to match all messager to a group
        "global": {
            # Global catch-all workspace for all groups
            "API_KEY": "legacy-slack-api-key-global",
            "USER_ID": "your-user-id"
        },
        "group2": {
            # Messages in this workspace will be matched to group2
            "API_KEY": "legacy-slack-api-key-group2",
            "USER_ID": "your-user-id"
        }
    }
}

tracklater's People

Contributors

eerovil 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

tracklater's Issues

Selecting and resizing entries is unresponsive sometimes

When selecting an entry and trying to resize, sometimes the entry gets unselected on the way and needs to be re-selected.

I think this is a (vis) timeline issue (actually now we use timeline-plus). I worked around it a bit by not allowing de-selecting at all regarding the selectedEntry variable. As such all other functionality should work well, but resizing can be a pain.

Full caching for all modules

All data could be cached, with a timeout of e.g. 1 hour.

This helps with UI development and UI responsiveness.

There needs to be a button to "force refresh".

Configuring settings when installed via setuptools

As of now you will need to configure tracklater in the virtualenv lib directory (e.g. /home/eerovil/.virtualenvs/tracklater/local/lib/python3.7/site-packages/tracklater/)

Figure out a way to do this. Doing all configuration inside the client would be a good way, I think.

Making it smart.

#37 addresses this for my case.

So, the whole point of this project was to make tracking easier, and, well. The base app doesn't really have many features to actually help your figure out what you were doing. I want to create a basic function to automatically generate time entries, and I think I've got something with the "generateTimeSnippet" function in this PR.

Rewrite the client

Currently there is a lot of bad code (too many side effects at least).

Let's fix the code or just rewrite in e.g. Vue.

The new client needs

  • separate asynchronous fetching for each module.
  • Allow changing any timeline data with instant update to the UI
  • First fetch cached data from the database and leave an async call waiting for latest real data

Smart async data fetching

After #14 is finished, the plan is as follows:

  • On initial client load, only entries from the database are fetched.
  • An async request is made (on load) which will update data to the latest version.
  • Some modules (like slack) can still use forced caching. E.g. slack doesn't ever need to fetch entries which have once been fetched.

CONTRIBUTING.md lacks information on default/expected workflow for contributing

I cloned the project to poke around. I am a C#/.NET developer so the typical python toolset/workflow is not fully familiar to me. Would it be possible to have CONTRIBUTING.md filled out with a "Getting Started" section on what steps are need to get a development instance running such as installing python, supported database engines, and running the app in development?

Thanks!

Testing

We need unit tests and integration tests.

I will be creating module-specific tests using data fixtures and mocked settings.

Tracking active window history

A helpful feature for this would be logging the active window. Sometimes, the time I have lost spans multiple tasks and knowing when the active window was for a specific project would help determine the division of time spent. Ideally this would be a hook, but polling every 1-5 minutes would be similarly useful.

Related SO article

If the ctypes approach is fast enough, this could be run on every mouse-click or tab as those are the common key presses for swapping windows. If the active window changes, the name is logged.

Emacs file access report tracking

Courtesy of reddit user /u/pvkooten, here is a snippet for an emacs script for file access tracking. This is easily parsed and grouped in TrackLater (given that I'm able to get an example file generated)

(defun log-file-visits ()
  (when (and buffer-file-name (not (eq last-command "xah-close-current-buffer")))
      (f-append-text (concat (int-to-string (float-time)) "," buffer-file-name "\n") 'utf-8 "/home/pascal/log-file-visits.txt")))

(add-hook 'find-file-hook 'log-find-visits)

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.