コード例 #1
0
 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)
コード例 #2
0
def toggl_delete_entries_for_ids(ids, token=None):
    toggl = Toggl()
    if token is None:
        token = os.getenv("TOGGL_API_TOKEN")
    toggl.setAPIKey(token)

    for id_ in ids:
        endpoint = Endpoints.TIME_ENTRIES + f"/{id_}"
        toggl_http_request(toggl, endpoint, "DELETE")
コード例 #3
0
class Toggl2GSuiteTest(unittest.TestCase):
    def setUp(self):
        self.api_key = os.environ["TOGGL_API_KEY"]
        self.toggl = Toggl()
        self.toggl.setAPIKey(self.api_key)

    # see https://stackoverflow.com/questions/19153462/get-excel-style-column-names-from-column-number
    LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    @staticmethod
    def excel_style(row, col):
        """ Convert given row and column number to an Excel-style cell name. """
        result = []
        while col:
            col, rem = divmod(col - 1, 26)
            result[:0] = Toggl2GSuiteTest.LETTERS[rem]
        return "".join(result) + str(row)

    def test_toggl2gsuite(self):
        # have to do this year by year
        data = {
            "workspace_id": os.environ["WORKSPACE_ID"],
        }
        y = self.toggl.getDetailedReport(data)

        credentials = ServiceAccountCredentials.from_json_keyfile_name(
            os.environ["KEYFILE"], ["https://spreadsheets.google.com/feeds"]
        )

        client = gspread.authorize(credentials)
        sheet = client.open_by_url(os.environ["SHEET_URL"])
        worksheet = sheet.get_worksheet(0)

        wrote_header = False
        columns_to_write = [
            "user",
            "updated",
            "start",
            "end",
            "client",
            "project",
            "description",
            "is_billable",
            "billable",
        ]
        cell_row = 0
        for row_idx, rec in enumerate(y["data"]):
            if wrote_header == False:
                for col_idx, header in enumerate(columns_to_write):
                    worksheet.update_acell(
                        Toggl2GSuiteTest.excel_style(row_idx + 1, col_idx + 1), header
                    )
                wrote_header = True
            for col_idx, header in enumerate(columns_to_write):
                worksheet.update_acell(
                    Toggl2GSuiteTest.excel_style(row_idx + 2, col_idx + 1), rec[header]
                )
コード例 #4
0
def main():

    # Read config file
    config = read_config_file()
    api_key = config.get('general', 'api_key').strip()

    api = Toggl()
    api.setAPIKey(api_key)
    projects = download_projects(api)
    dump_projects_as_csv(projects, sys.stdout)
コード例 #5
0
    def setUp(self):
        self.api_key = os.environ['TOGGL_API_KEY']
        if self.api_key is None:
            raise Exception("Unable to execute api tests without an api key")

        self.workspace_id = os.environ['WORKSPACE_ID']
        if self.workspace_id is None:
            raise Exception(
                "Unable to execute api tests without a workspace key to query")

        self.toggl = Toggl()
        self.toggl.setAPIKey(self.api_key)
コード例 #6
0
 def main(self):
     API_TOKEN = certification.load_json()
     if not API_TOKEN:
         print('[WARN]:Please set the API token in config.json')
     toggl = Toggl()
     toggl.setAPIKey(API_TOKEN)
     args = argument.get_argument()
     if args.function.lower() == 'start':
         workspace_id = self.get_workspace_id(toggl)
         self.get_project(toggl, workspace_id)
         self.start(toggl)
     elif args.function.lower() == 'stop':
         self.stop(toggl)
コード例 #7
0
ファイル: toggl_me.py プロジェクト: tvdsluijs/toggl_processer
    def get_data(self):
        toggl = Toggl()
        toggl.setAPIKey(self.config['api'])

        data = {
            'workspace_id': workspace_id,
            'user_agent': user_agent,
            'since': self.last_month_first,
            'until': self.last_month_last
        }
        self.response = toggl.request(
            "https://toggl.com/reports/api/v2/details", parameters=data)
        self.save_raw_data()
コード例 #8
0
def team_weekly_report(destination, since, until, api_key, workspace):
    logger.info(
        "Downloading the team weekly report from {} until {} into {}".format(
            since, until, destination))
    toggl = Toggl()
    toggl.setAPIKey(api_key)

    data = {
        'workspace_id':
        workspace,  # see the next example for getting a workspace id
        'since': since,
        'until': until
    }
    try:
        result = toggl.getSummaryReport(data)
    except Exception as e:
        logger.error("Unable to download the team weekly data {}".format(e))
        return

    # Calculate hours and minutes
    total_ms = result['total_grand']
    if total_ms:
        hours, minutes = divmod(total_ms / 1000 / 60, 60)
        time_str = "Total team hours: {:.0f}h {:.0f}m".format(hours, minutes)
    else:
        time_str = "Total team hours: No hours recorded"

    # Find all project worked on
    items_worked_on = [
        item["title"]["time_entry"] for project in result["data"]
        for item in project["items"]
    ]
    if len(items_worked_on) == 0:
        items_worked_on = ["No tasks worked on for this time period"]

    # Calculate the pretty data for the start of the week
    date = datetime.strptime(since, "%Y-%m-%d")
    formatted_week = date.strftime("%B %d")
    formatted_items = "- " + "\n- ".join(items_worked_on)
    formatted_team_report = team_report_template.format(
        formatted_week, formatted_items, time_str)

    logger.info("Created team report:")
    logger.info(formatted_team_report)

    logger.info("Adding to team log file %s", destination)

    with open(destination, "a") as report:
        report.write(formatted_team_report)

    logger.info("Done team report")
コード例 #9
0
ファイル: toggl_get_entries.py プロジェクト: Pand9/easyaccess
def toggl_get_entries_raw(date: datetime.date, token=None):
    toggl = Toggl()
    if token is None:
        token = os.getenv("TOGGL_API_TOKEN")
    toggl.setAPIKey(token)

    start_date = datetime.datetime.combine(date, datetime.time()).astimezone()
    params = {"start_date": start_date.isoformat()}
    params["end_date"] = (start_date + datetime.timedelta(days=1) +
                          datetime.timedelta(minutes=-1)).isoformat()

    print(date)
    time.sleep(2)
    togglentries = toggl.request(Endpoints.TIME_ENTRIES, params)
    return togglentries
コード例 #10
0
ファイル: __init__.py プロジェクト: kquinsland/ha-toggl
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up Toggl from a config entry."""
    hass.data[DOMAIN]["toggl"] = Toggl()
    for component in PLATFORMS:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, component))
    return True
コード例 #11
0
class TogglPyTests(unittest.TestCase):
    def setUp(self):
        self.api_key = os.environ["TOGGL_API_KEY"]
        if self.api_key is None:
            raise Exception("Unable to execute api tests without an api key")

        self.workspace_id = os.environ["WORKSPACE_ID"]
        if self.workspace_id is None:
            raise Exception(
                "Unable to execute api tests without a workspace key to query"
            )

        self.toggl = Toggl()
        self.toggl.setAPIKey(self.api_key)

    def test_connect(self):
        response = self.toggl.request("https://api.track.toggl.com/api/v8/clients")
コード例 #12
0
ファイル: toggl2gsuite.py プロジェクト: matthewdowney/TogglPy
class Toggl2GSuiteTest(unittest.TestCase):
    def setUp(self):
        self.api_key = os.environ['TOGGL_API_KEY']
        self.toggl = Toggl()
        self.toggl.setAPIKey(self.api_key)

    # see https://stackoverflow.com/questions/19153462/get-excel-style-column-names-from-column-number
    LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

    @staticmethod
    def excel_style(row, col):
        """ Convert given row and column number to an Excel-style cell name. """
        result = []
        while col:
            col, rem = divmod(col - 1, 26)
            result[:0] = Toggl2GSuiteTest.LETTERS[rem]
        return ''.join(result) + str(row)

    def test_toggl2gsuite(self):
        # have to do this year by year
        data = {
            'workspace_id': os.environ['WORKSPACE_ID'],
        }
        y = self.toggl.getDetailedReport(data)


        credentials = ServiceAccountCredentials.from_json_keyfile_name(
            os.environ['KEYFILE'],
            ['https://spreadsheets.google.com/feeds'])

        client = gspread.authorize(credentials)
        sheet = client.open_by_url(os.environ['SHEET_URL'])
        worksheet = sheet.get_worksheet(0)

        wrote_header = False
        columns_to_write = ['user', 'updated', 'start', 'end', 'client', 'project', 'description', 'is_billable',
                            'billable']
        cell_row = 0
        for row_idx, rec in enumerate(y['data']):
            if wrote_header == False:
                for col_idx, header in enumerate(columns_to_write):
                    worksheet.update_acell(Toggl2GSuiteTest.excel_style(row_idx + 1, col_idx + 1), header)
                wrote_header = True
            for col_idx, header in enumerate(columns_to_write):
                worksheet.update_acell(Toggl2GSuiteTest.excel_style(row_idx + 2, col_idx + 1), rec[header])
コード例 #13
0
def toggl_get_tasks(token=None) -> List[TglTask]:
    toggl = Toggl()
    if token is None:
        token = os.getenv("TOGGL_API_TOKEN")
    toggl.setAPIKey(token)

    workspaces = []
    for e in _retry(lambda: toggl.getWorkspaces()):
        workspaces.append((e["id"], e["name"]))

    projects = []
    for wid, wname in workspaces:
        for e in _retry(lambda: toggl.request(Endpoints.WORKSPACES +
                                              f"/{wid}/projects")) or []:
            projects.append((e["id"], e["name"]))

    ptasks = []
    for pid, pname in projects:
        for e in _retry(lambda: toggl.getProjectTasks(pid)) or [{
                "id": 0,
                "name": ""
        }]:
            ptasks.append(TglTask(pid, pname, e["id"], e["name"]))

    return ptasks
コード例 #14
0
def get_entries(start, end, from_workspace_id, from_user_id):
    toggl = Toggl()

    toggl.setAPIKey(os.getenv('TOGGL_APIKEY'))
    response = toggl.request(
        f'https://toggl.com/reports/api/v2/details?workspace_id={from_workspace_id}&since={start}&until={end}&user_agent={user_agent}&uid={from_user_id}&include_time_entry_ids=true&user_ids={from_user_id}'
    )
    if response['total_count'] > response['per_page']:
        raise Exception('Paging not supported, results exceed the page')
    for k, v in response.items():
        if k != 'data':
            print(k, v)

    entries = []

    for time_entry in response['data']:
        print(time_entry)
        entries.append(time_entry)
    return entries
コード例 #15
0
ファイル: tests.py プロジェクト: matthewdowney/TogglPy
    def setUp(self):
        self.api_key      = os.environ['TOGGL_API_KEY']
        if self.api_key is None:
            raise Exception("Unable to execute api tests without an api key")

        self.workspace_id = os.environ['WORKSPACE_ID']
        if self.workspace_id is None:
            raise Exception("Unable to execute api tests without a workspace key to query")

        self.toggl        = Toggl()
        self.toggl.setAPIKey(self.api_key)
コード例 #16
0
ファイル: classes.py プロジェクト: heyjva/Strava2Toggl
class Toggls():

    def __init__(self, key):
        self.toggl = Toggl()
        self.toggl.setAPIKey(key)

    def get_Workspaces(self):
        return self.toggl.getWorkspaces()

    def getprojectsinworkspace(self, id):
        urls = "https://www.toggl.com/api/v8/workspaces/" + str(id) + "/projects"
        return self.toggl.request(urls)

    def get_workspace(self, name):
        return self.toggl.getWorkspace(name)

    def make_time_entry(self, pid, workout):
        start = workout[1][6:10] + "-" + workout[1][:2] + "-" + workout[1][3:5] + "T" + workout[1][12:] + ".000Z"
        time = float(workout[2][0])*60*60 + float(workout[2][2:4])*60 + float(workout[2][5:7])
        url = 'https://www.toggl.com/api/v8/time_entries'
        data = {
            "time_entry":
                {
                    "description":"Workout",
                    "tags":[""],
                    "duration": time,
                    "start": start,
                    "pid": pid,
                    "created_with":"api"
                }
        }
        return self.toggl.postRequest(url, parameters=data)
コード例 #17
0
    def _loadActiviy(self):
        toggl = Toggl()
        toggl.setAPIKey(self._token)
        self._report_date = self._daily_date - timedelta(1)
        self.friday_text = ''

        if self._report_date.isoweekday() is 6 or self._report_date.isoweekday() is 7:
            self._report_date = self._daily_date - timedelta(3 if self._daily_date.isoweekday() is 1 else 2)
            self.friday_text = " (Friday)"

        self.report_day = '{0:%Y-%m-%d}'.format(self._report_date)

        me_info = toggl.request(toggl_urls.me)
        self._username = me_info['data']['fullname']

        summary_url = toggl_urls.summary + "?workspace_id={}&since={}&until={}&user_agent=api_test".format(
            self._workspace_id, self.report_day, self.report_day)
        response = toggl.request(summary_url)

        activity = {}
        default_project = conf_manager.get_default_project()

        for data in response['data']:
            project_name = default_project if None == data['title']['project'] else data['title']['project']
            activity[project_name] = []
            for item in data['items']:
                hours = self.millis_to_hours(item['time'])
                self._total_hours += hours
                activity[project_name].append(Task(item['title']['time_entry'], project_name, hours).serialize())

        self._activity = activity
        return activity
コード例 #18
0
def _get_toggl_client(api_key):
    client = Toggl()
    client.setAPIKey(api_key)

    try:
        client.getWorkspaces()
    except HTTPError:
        raise click.BadParameter('Invalid api key or connection problem')
    return client
コード例 #19
0
def user_weekly_report(directory, since, until, api_key, users, workspace):
    """
    Downloads each users weekly reports as a summary and details pdf into their own directories.
    :param workspace:
    :param api_key: The toggl api key to use.
    :param users: The dictionary are users with the key as the user id and the values as the full name.
    :param directory: The root destination directory. Each user will have a sub-directory created for their reports
    :param since: The start date in the form yyyy-MM-dd
    :param until: the end data in the form yyyy-MM-dd. Files will be prepended with this date string.
    :return: None
    """
    logging.info(
        "Downloading user weekly reports from {} until {} into {}".format(
            since, until, directory))
    toggl = Toggl()
    toggl.setAPIKey(api_key)

    for uid, name in users.items():
        logger.info("Downloading reports for {}".format(name))
        name = users[uid]
        data = {
            'workspace_id':
            workspace,  # see the next example for getting a workspace id
            'since': since,
            'until': until,
            'user_ids': uid
        }

        folder = path.join(directory, name)

        if not path.exists(folder):
            logger.info("Creating the folder {}".format(folder))
            makedirs(folder)

        details = path.join(folder, until + "-details.pdf")
        summary = path.join(folder, until + "-summary.pdf")

        try:
            toggl.getDetailedReportPDF(data, details)
            logger.info("Downloaded {}".format(details))
            toggl.getSummaryReportPDF(data, summary)
            logger.info("Downloaded {}".format(summary))
        except Exception as e:
            logging.error(e)
コード例 #20
0
ファイル: toggl_add_entries.py プロジェクト: Pand9/easyaccess
def toggl_add_entries(entries: List[TglStandardEntry],
                      tasks: List[TglTask],
                      token=None):
    toggl = Toggl()
    if token is None:
        token = os.getenv("TOGGL_API_TOKEN")
    toggl.setAPIKey(token)

    taskmap = {}
    for t in tasks:
        k = t.project_name, t.task_name
        v = t.project_id, t.task_id
        taskmap[k] = v

    togglentries = []
    for i, entry in enumerate(entries, start=1):
        try:
            try:
                pid, tid = taskmap[(entry.project, entry.task)]
            except KeyError:
                raise ConvertingError(
                    f"{entry.project}, {entry.task} not found")
            togglentry = {
                "description": entry.description,
                "pid": pid,
                "tid": tid if tid else None,
                "start": entry.start.astimezone().isoformat(),
                "duration": entry.duration.seconds,
                "created_with": "easytrack",
            }
            togglentries.append(togglentry)
        except ConvertingError as e:
            e.i = i
            e.line = e
            raise

    for i, togglentry in enumerate(togglentries, start=1):
        try:
            try:
                print(i, '/', len(togglentries))
                time.sleep(2)
                resp = toggl.postRequest(Endpoints.TIME_ENTRIES,
                                         {"time_entry": togglentry})
            except urllib.error.HTTPError as e:
                raise TogglError(body=e.fp.read().decode(), underlying=e)
            resp = toggl.decodeJSON(resp)
            if resp.get("data") is None:
                raise ConvertingError(f"data not found in resp {resp}")
        except ConvertingError as e:
            e.i = i
            e.line = e
            raise
コード例 #21
0
def get_projects():
    """Since the current project function in PyToggl doesn't work, I made my own
    hacky version. Gets all projects assigned to a client and returns it as a
    list"""

    toggl = Toggl()

    toggl.setAPIKey(TOGGL_TOKEN)

    clients = toggl.getClients()

    toggl_projects = []

    for client in clients:
        projects = toggl.getClientProjects(client["id"])
        if projects != None:
            for project in projects:
                toggl_projects.append(project)

    return toggl_projects
コード例 #22
0
def save_entries(entries, workspace_id, user_id, project_id, hourdiff_to_utc):
    toggl = Toggl()

    toggl.setAPIKey(os.getenv('TOGGL_APIKEY'))
    for entry in entries:
        start = entry['start']
        start_date = datetime.datetime.strptime(start, '%Y-%m-%dT%H:%M:%S%z')
        y = start_date.year
        m = start_date.month
        d = start_date.day
        h = start_date.hour
        desc = entry['description']
        print(entry['dur'])
        toggl.createTimeEntry(round(entry['dur'] / 3600000.0, 1),
                              description=desc,
                              projectid=project_id,
                              year=y,
                              month=m,
                              day=d,
                              hour=h,
                              hourdiff=hourdiff_to_utc)
コード例 #23
0
 def __init__(self):
     self.config = load_config()
     api_token = self.config['toggl']['token']
     self.toggl = Toggl()
     self.toggl.setAPIKey(api_token)
コード例 #24
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))
コード例 #25
0
ファイル: toggl2gsuite.py プロジェクト: matthewdowney/TogglPy
 def setUp(self):
     self.api_key = os.environ['TOGGL_API_KEY']
     self.toggl = Toggl()
     self.toggl.setAPIKey(self.api_key)
コード例 #26
0
ファイル: add_day.py プロジェクト: martbern/gcal-to-toggl
import sys

# Integration imports
from credentials import TOGGL_TOKEN, AIRTABLE_API_KEY
from toggl.TogglPy import Toggl
from airtable import Airtable
from airtable_integrations import *
import gcal

#Utilities
import re
from pprint import pprint
from task_dicts import event_exclude
import urllib

toggl = Toggl()

toggl.setAPIKey(TOGGL_TOKEN)

offset = int(sys.argv[1])

#Generate today-string
index = dt.today() + datetime.timedelta(offset)
index_midnight = index.replace(hour=0, minute=1)
index_formatted = index_midnight.isoformat() + 'Z'
index_str = dt.strftime(index, '%Y-%m-%d')

day_after_index = index + datetime.timedelta(1)
day_after_index_midnight = day_after_index.replace(hour=0, minute=1)
day_after_index_formatted = day_after_index_midnight.isoformat() + 'Z'
コード例 #27
0
 def __init__(self, api_key):
     # create a Toggl object and set our API key
     self.toggl = Toggl()
     self.toggl.setAPIKey(api_key)
コード例 #28
0
class TogglTimesheets:
    def __init__(self, api_key):
        # create a Toggl object and set our API key
        self.toggl = Toggl()
        self.toggl.setAPIKey(api_key)

    def _get_raw_timelogs(self, start_date=None, end_date=None):
        # Add filters
        params = {}
        if start_date:
            params["start_date"] = start_date
        if end_date:
            params["end_date"] = end_date

        # Make request and return
        return self.toggl.request(Endpoints.TIME_ENTRIES, parameters=params)

    def _get_raw_timelogs_last_n_days(self, n_days):
        last_n_days = datetime.utcnow() - timedelta(days=n_days)
        last_n_days_str = last_n_days.replace(microsecond=0,
                                              tzinfo=timezone.utc).isoformat()
        return self._get_raw_timelogs(start_date=last_n_days_str)

    @staticmethod
    def _parse_timelog(raw):
        """
        {
            'start': '2019-05-11T12:19:39+00:00',
            'stop': '2019-05-11T12:40:27+00:00',
            'description': 'Trying to deploy mongodb',
            'tags': ['BB-1212'],
            'duronly': False,
        }
        """
        if raw.get('duronly', False):
            raise ("Error, timelog with duronly = true")

        tags = raw.get('tags', [])
        ticket = None
        dd = False
        ff = False
        for tag in tags:
            if ISSUE_REGEX.match(tag):
                ticket = tag
            elif tag == 'DD':
                dd = True
            elif tag == 'FF':
                ff = True
        if not ticket and 'description' in raw:
            possible = ISSUE_REGEX.findall(raw['description'])
            if possible:
                # TODO Dividing to multiple tickets
                ticket = possible[0]
                raw['description'] = raw['description'].strip(ticket).strip()

        if 'description' not in raw:
            # Shouldn't exist, but alas
            raw['description'] = 'NO DESCRIPTION'

        start = datetime.strptime(raw['start'], DATETIME_FORMAT)
        end = datetime.strptime(raw['stop'], DATETIME_FORMAT)

        return Timelog(ticket=ticket,
                       date=start,
                       time=end - start,
                       description=raw['description'],
                       ff_time=ff,
                       dd_time=dd)

    def get_timelogs_last_n_days(self, n_days=1):
        raw_logs = self._get_raw_timelogs_last_n_days(n_days)

        result = {
            'complete': list(),
            'incomplete': list(),
        }
        for item in raw_logs:
            if 'stop' not in item:
                # Ignore currently running
                continue
            timelog = self._parse_timelog(item)
            if timelog.ticket:
                result['complete'].append(timelog)
            else:
                result['incomplete'].append(timelog)

        return result

    def get_timelogs(self, start_date, end_date):
        start_date_str = start_date.replace(microsecond=0,
                                            tzinfo=timezone.utc).isoformat()
        end_date_str = end_date.replace(microsecond=0,
                                        tzinfo=timezone.utc).isoformat()

        raw_logs = self._get_raw_timelogs(start_date=start_date_str,
                                          end_date=end_date_str)

        result = {
            'complete': list(),
            'incomplete': list(),
        }
        for item in raw_logs:
            if 'stop' not in item:
                # Ignore currently running
                continue
            timelog = self._parse_timelog(item)
            if timelog.ticket:
                result['complete'].append(timelog)
            else:
                result['incomplete'].append(timelog)

        return result
コード例 #29
0
ファイル: tests.py プロジェクト: matthewdowney/TogglPy
class TogglPyTests(unittest.TestCase):

    def setUp(self):
        self.api_key      = os.environ['TOGGL_API_KEY']
        if self.api_key is None:
            raise Exception("Unable to execute api tests without an api key")

        self.workspace_id = os.environ['WORKSPACE_ID']
        if self.workspace_id is None:
            raise Exception("Unable to execute api tests without a workspace key to query")

        self.toggl        = Toggl()
        self.toggl.setAPIKey(self.api_key)

    def test_connect(self):
        response = self.toggl.request("https://www.toggl.com/api/v8/clients")
        self.assertTrue(response is not None)

    def test_putTimeEntry(self):
        request_args = {
            'workspace_id': self.workspace_id,
        }
        entries = self.toggl.getDetailedReport(request_args)
        #for this tests I'm tagging my Pomodoro Entries
        missing_projects = [r for r in entries['data'] if r['project'] is None and 'Pomodoro' in r['description'] ]
        me = missing_projects[0]
        me_id = me['id'] #remember for later

        #I've tagged my pomodoro entries as Self/Self
        cp = self.toggl.getClientProject("Self", "Self")
        project_id = cp['data']['id']
        me['pid'] = project_id

        #his is the new stuff
        response = self.toggl.putTimeEntry({"id": me_id, "pid":project_id})
        self.assertTrue(response is not None)
        self.assertTrue('data' in response)
        self.assertTrue(response['data']['pid'] == project_id)


    def test_getDetailedReportCSV(self):
        data = {
            'workspace_id': self.workspace_id,
        }
        csvfile = 'data.csv'
        self.toggl.getDetailedReportCSV(data, csvfile)
        self.assertTrue(os.path.isfile(csvfile))
        os.remove(csvfile)

        data = self.toggl.getDetailedReportCSV(data)
        self.assertTrue(data is not None)


    def test_getDetailedReport(self):
        data = {
            'workspace_id': self.workspace_id,
        }
        d = self.toggl.getDetailedReport(data)
        self.assertTrue(d is not None)
        self.assertTrue(len(d.keys()) > 0 )
        fields = ['total_count', 'total_currencies', 'total_billable', 'data']
        for f in fields:
            self.assertTrue(f in d.keys())
        data = d['data']
        self.assertTrue(len(data)>0)
        dr = data[0]
        self.assertTrue('client' in dr)
        self.assertTrue('start' in dr)
        self.assertTrue('end' in dr)
        self.assertTrue('task' in dr)
        self.assertTrue('user' in dr)
        self.assertTrue('project' in dr)
コード例 #30
0
ファイル: toggl.py プロジェクト: mari8i/TimeTrackerDice
def _get_toggl(user: User) -> Toggl:
    toggl = Toggl()
    toggl.setAPIKey(user.togglcredentials.api_key)
    return toggl
コード例 #31
0
#get total amount of productivity in last 7 days

from toggl.TogglPy import Toggl
toggl = Toggl()

toggl.setAPIKey('53a2d3c3856e1ef39982074936cd0c51')

response = toggl.request("https://toggl.com/reports/api/v2/weekly")

print(response)
コード例 #32
0
class TogglPyTests(unittest.TestCase):
    def setUp(self):
        self.api_key = os.environ['TOGGL_API_KEY']
        if self.api_key is None:
            raise Exception("Unable to execute api tests without an api key")

        self.workspace_id = os.environ['WORKSPACE_ID']
        if self.workspace_id is None:
            raise Exception(
                "Unable to execute api tests without a workspace key to query")

        self.toggl = Toggl()
        self.toggl.setAPIKey(self.api_key)

    def test_connect(self):
        response = self.toggl.request(
            "https://api.track.toggl.com/api/v8/clients")
        self.assertTrue(response is not None)

    def test_putTimeEntry(self):
        request_args = {
            'workspace_id': self.workspace_id,
        }
        entries = self.toggl.getDetailedReport(request_args)
        #for this tests I'm tagging my Pomodoro Entries
        missing_projects = [
            r for r in entries['data']
            if r['project'] is None and 'Pomodoro' in r['description']
        ]
        me = missing_projects[0]
        me_id = me['id']  #remember for later

        #I've tagged my pomodoro entries as Self/Self
        cp = self.toggl.getClientProject("Self", "Self")
        project_id = cp['data']['id']
        me['pid'] = project_id

        #his is the new stuff
        response = self.toggl.putTimeEntry({"id": me_id, "pid": project_id})
        self.assertTrue(response is not None)
        self.assertTrue('data' in response)
        self.assertTrue(response['data']['pid'] == project_id)

    def test_getDetailedReportCSV(self):
        data = {
            'workspace_id': self.workspace_id,
        }
        csvfile = 'data.csv'
        self.toggl.getDetailedReportCSV(data, csvfile)
        self.assertTrue(os.path.isfile(csvfile))
        os.remove(csvfile)

        data = self.toggl.getDetailedReportCSV(data)
        self.assertTrue(data is not None)

    def test_getDetailedReport(self):
        data = {
            'workspace_id': self.workspace_id,
        }
        d = self.toggl.getDetailedReport(data)
        self.assertTrue(d is not None)
        self.assertTrue(len(d.keys()) > 0)
        fields = ['total_count', 'total_currencies', 'total_billable', 'data']
        for f in fields:
            self.assertTrue(f in d.keys())
        data = d['data']
        self.assertTrue(len(data) > 0)
        dr = data[0]
        self.assertTrue('client' in dr)
        self.assertTrue('start' in dr)
        self.assertTrue('end' in dr)
        self.assertTrue('task' in dr)
        self.assertTrue('user' in dr)
        self.assertTrue('project' in dr)
コード例 #33
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)
コード例 #34
0
class TogglTimesheets:
    def __init__(self, api_key):
        # create a Toggl object and set our API key
        self.toggl = Toggl()
        self.toggl.setAPIKey(api_key)

    def _get_raw_timelogs(self, start_date=None, end_date=None):
        # Add filters
        params = {}
        if start_date:
            params["start_date"] = start_date
        if end_date:
            params["start_date"] = end_date

        # Make request and return
        return self.toggl.request(Endpoints.TIME_ENTRIES, parameters=params)

    def _get_raw_timelogs_last_n_days(self, n_days):
        last_n_days = datetime.utcnow() - timedelta(days=n_days)
        last_n_days_str = last_n_days.replace(microsecond=0,
                                              tzinfo=timezone.utc).isoformat()
        return self._get_raw_timelogs(start_date=last_n_days_str)

    @staticmethod
    def _parse_timelog(raw):
        """
        {
            'start': '2019-05-11T12:19:39+00:00',
            'stop': '2019-05-11T12:40:27+00:00',
            'description': 'Trying to deploy mongodb',
            'tags': ['BB-1212'],
            'duronly': False,
        }
        """
        if raw.get('duronly', False):
            print(raw)
            raise ("Error, timelog with duronly = true")

        tags = raw['tags']
        ticket = None
        dd = False
        ff = False
        for tag in tags:
            if re.match(ISSUE_REGEX, tag):
                ticket = tag
            elif tag == 'DD':
                dd = True
            elif tag == 'FF':
                ff = True

        start = datetime.strptime(raw['start'], DATETIME_FORMAT)
        end = datetime.strptime(raw['stop'], DATETIME_FORMAT)

        return TIMELOG(ticket=ticket,
                       date=start,
                       time=end - start,
                       description=raw['description'],
                       ff_time=ff,
                       dd_time=dd)

    def get_timelogs_last_n_days(self, n_days=1):
        raw_logs = self._get_raw_timelogs_last_n_days(n_days)

        result = {
            'complete': list(),
            'incomplete': list(),
        }
        for item in raw_logs:
            timelog = self._parse_timelog(item)
            if timelog.ticket:
                result['complete'].append(timelog)
            else:
                result['incomplete'].append(timelog)

        return result