Exemplo n.º 1
0
class TogglApi:
    def __init__(self):
        self.config = load_config()
        api_token = self.config['toggl']['token']
        self.toggl = Toggl()
        self.toggl.setAPIKey(api_token)

    def preset_projects(self):
        return self.config['toggl']['preset_projects']

    def current_timer(self):
        timer = self.toggl.currentRunningTimeEntry()['data']
        if timer:
            if 'pid' in timer:
                project = self.get_project_name(timer['pid'])
            else:
                project = ['Kein Projekt', (244, 244, 6)]

            timer_dic = {
                'name': timer.get('description', ""),
                'id': timer['id'],
                'start_time':
                datetime.fromtimestamp(int(timer['duration']) * -1),
                'project_name': project[0],
                'project_color': project[1]
            }
            # start = datetime.strptime(timer['start'],"%Y-%m-%dT%H:%M:%S+00:00")
            return timer_dic
        else:
            return {
                'name': "",
                'id': "1234",
                'start_time': datetime.fromtimestamp(1542385078),
                'project_name': "Kein Projekt",
                'project_color': (30, 0, 0)
            }

    def get_project_name(self, pid):
        project = self.toggl.getProject(pid)['data']
        name = project['name']
        try:
            color = self.hex_to_rgb(project['hex_color'])
            color = (int(color[0] / 2), int(color[1] / 2), int(color[2] / 2))
        except ():
            color = (200, 200, 200)
        return name, color

    def start_timer(self, project_name, description):
        print(self.config['toggl']['project_ids'][project_name])
        self.toggl.startTimeEntry(
            description, self.config['toggl']['project_ids'][project_name])

    def stop_timer(self):
        current_timer_id = self.current_timer()['id']
        if current_timer_id:
            self.toggl.stopTimeEntry(current_timer_id)
            return True
        return False

    @staticmethod
    def hex_to_rgb(hex_str):
        hex = hex_str[1:]  # remove pound sign
        # https://stackoverflow.com/questions/29643352/converting-hex-to-rgb-value-in-python
        return tuple(int(hex[i:i + 2], 16) for i in (0, 2, 4))
Exemplo n.º 2
0
class TogglDelegate(ZeiDelegate):
    def __init__(self, periph, config):
        self.config = config
        self.toggl = Toggl()
        self.toggl.setAPIKey(self.config["toggl"]["settings"]["token"])
        self._populateProjects()
        self._populateMappings(self.config["mappings"])
        super().__init__(periph)

    def handleNotification(self, cHandle, data):
        if cHandle == 38:  # Side Change Notification
            side = struct.unpack("B", data)[0]
            self._trackProjectByMapping(
                self.mappings[side] if side in self.mappings else self.mappings[0]
            )
        else:
            _log.info("Notification from hndl: %s - %r", cHandle, data)

    def _trackProjectByMapping(self, mapping: Mapping):
        self._trackProject(
            description=mapping.description, pid=mapping.id, tags=mapping.tags
        )

    def _trackProject(self, description: str, pid: int, tags: list):
        current = self.toggl.currentRunningTimeEntry()["data"]

        if current is not None:
            if (
                datetime.now(timezone.utc) - dateutil.parser.isoparse(current["start"])
            ).total_seconds() < 20:
                # Delete entry if not older than 20s
                _log.info("Abort currently running entry")
                self.toggl.deleteTimeEntry(current["id"])
            else:
                _log.info("Stopping currently running entry")
                self.toggl.stopTimeEntry(current["id"])

        if pid not in self.projects:
            _log.info("Project not found, aborting")
            return

        _log.info(
            "Now tracking project %s: %s (%s)",
            self.projects[pid]["name"],
            description,
            ", ".join(tags if tags else []),
        )

        notification.notify(
            title="Toggl",
            message=f"Now tracking project {self.projects[pid]['name']} {description} ({', '.join(tags) if tags else ''})",
            app_name="Toggl",
            app_icon=join(dirname(realpath(__file__)), "icons/toggl.png"),
            timeout=5,
        )
        if pid == 0:
            return

        self.toggl.startTimeEntry(description, pid=pid, tags=tags)

    def _populateMappings(self, mappings: dict):
        self.mappings = {0: Mapping(0, 0)}
        for i in mappings:
            self.mappings[int(i)] = Mapping(int(i), int(mappings[i]["id"]))
            if "description" in mappings[i]:
                self.mappings[int(i)].description = mappings[i]["description"]
            if "tags" in mappings[i]:
                self.mappings[int(i)].tags = mappings[i]["tags"]

    def _populateProjects(self):
        self.projects = {}
        proj = self.toggl.getWorkspaceProjects(
            self.config["toggl"]["settings"]["workspace_id"]
        )
        NoneProj = {
            "id": 0,
            "wid": int(self.config["toggl"]["settings"]["workspace_id"]),
            "name": "None",
            "billable": False,
            "is_private": True,
            "active": True,
            "template": False,
            "at": "2020-06-09T04:02:38+00:00",
            "created_at": "2019-12-09T16:36:28+00:00",
            "color": "9",
            "auto_estimates": False,
            "actual_hours": 0,
            "hex_color": "#990099",
        }

        self.projects[0] = NoneProj
        for i in proj:
            self.projects[i["id"]] = i
Exemplo n.º 3
0
#!/usr/bin/env python
#
# LaunchBar Action Script
#
from toggl.TogglPy import Toggl
from requests import HTTPError
import datetime

# %%
toggl = Toggl()
# fill your own E-Mail and Password.
toggl.setAuthCredentials('<EMAIL>', '<PASSWORD>')

# %%
try:
    currentTimer = toggl.currentRunningTimeEntry()
    if currentTimer['data'] is None:
        print('No Time Entry Runnig Now.')
    else:
        stoppedEntry = toggl.stopTimeEntry(currentTimer['data']['id'])['data']
        duration_str = str(datetime.timedelta(0, stoppedEntry['duration']))
        print('Stopped: {}, Have Run {}.'.format(stoppedEntry['description'],
                                                 duration_str))
except HTTPError as e:
    print(e)
Exemplo n.º 4
0
def print_post():
    write_log("Received: " + str(dict(request.args)))
    if "action" not in request.args or len(
            request.args["action"]) == 0 or request.args["action"] not in [
                "start", "stop"
            ]:
        err_msg = "ERR: Action not provided or is not 'start' or 'stop'",
        write_log(err_msg)
        return err_msg, 200  # 400
    if "toggl_api_token" not in request.args or len(
            request.args["toggl_api_token"]) == 0:
        err_msg = "ERR: Toggl API token not provided"
        write_log(err_msg)
        return err_msg, 200  # 400
    action = request.args["action"]
    api_token = request.args["toggl_api_token"]
    toggl = Toggl()
    toggl.setAPIKey(api_token)
    if action == "stop":
        currentTimer = toggl.currentRunningTimeEntry()
        response = toggl.stopTimeEntry(currentTimer['data']['id'])
        write_log("Received from toggl:" + str(response))
        return response, 200

    if "desc" not in request.args or len(request.args["desc"]) == 0:
        err_msg = "ERR: Description not provided"
        write_log(err_msg)
        return err_msg, 200  # 400
    if "project" not in request.args or len(request.args["project"]) == 0:
        err_msg = "ERR: Project not provided"
        write_log(err_msg)
        return err_msg, 200  # 400
    desc = request.args["desc"]
    project_name = request.args["project"]

    write_log("Sending request for workspaces")
    workspaces = toggl.request("https://api.track.toggl.com/api/v8/workspaces")
    all_projects = []
    for w in workspaces:
        workspace_id = w["id"]
        resp = toggl.request(
            f"https://api.track.toggl.com/api/v8/workspaces/{workspace_id}/projects"
        )
        # Resp can be none if a workspace has no projects
        if resp:
            all_projects += resp
    all_project_names = [p["name"] for p in all_projects]
    if project_name not in all_project_names:
        err_msg = f"ERR: Project with name `{project_name}` not found."
        write_log(err_msg)
        return err_msg, 200  # 404
    project_id = -1
    for p in all_projects:
        if p["name"] == project_name:
            project_id = p["id"]
    if project_id == -1:
        err_msg = f"ERR: No project ID can be found for project with name `{project_name}`."
        write_log(err_msg)
        return err_msg, 200  # 404
    write_log(f"Performing action {action} on entry.")
    response = toggl.startTimeEntry(desc, project_id)
    write_log("Received from toggl:" + str(response))
    return response, 200