Skip to content

Commit

Permalink
Add conda to project and add a setting to allow to set billable tag b…
Browse files Browse the repository at this point in the history
…ased on project property. And couple of renamings.
  • Loading branch information
kubantjan committed Sep 24, 2024
1 parent ac92274 commit 03c46b1
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 25 deletions.
44 changes: 24 additions & 20 deletions ClockifyAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def getTasksOnProject(self, workspace, projectName):
self._loadAdmin()

wsId = self.getWorkspaceID(workspace)
pId = self.getProjectID(projectName, workspace)
pId = self.get_project_id(projectName, workspace)

url = self.url + "/workspaces/%s/projects/%s/tasks" % (wsId, pId)
self.pTasks = self.multiGetRequest(url)
Expand Down Expand Up @@ -303,16 +303,16 @@ def getClientID(self, client, workspace, skipCliQuery=False):
raise RuntimeError("Client %s not found in workspace %s" % (client, workspace))
return clId

def getProjects(self, workspace, skipPrjQuery=False):
if self._syncProjects == True:
curUser = self._loadedUserEmail
def getProjects(self, workspace_name: str, skipPrjQuery=False):
if self._syncProjects:
cur_user = self._loadedUserEmail
self.projects = []

for user in self._APIusers:
self.logger.info("synchronizing clockify projects for user %s..." % user["email"])
self._loadUser(user["email"])

wsId = self.getWorkspaceID(workspace)
wsId = self.getWorkspaceID(workspace_name)
url = self.url + "/workspaces/%s/projects" % wsId
projects = self.multiGetRequest(url)
self.projects.extend(projects)
Expand All @@ -321,7 +321,7 @@ def getProjects(self, workspace, skipPrjQuery=False):
f = open("clockify_projects.json", "w")
f.write(json.dumps(self.projects, indent=2))
f.close()
self._loadUser(curUser)
self._loadUser(cur_user)
self._syncProjects = False

return self.projects
Expand Down Expand Up @@ -351,19 +351,23 @@ def getWorkspaceProjects(self, workspace, skipPrjQuery=False):

return self.projects

def getProjectID(self, project, workspace, skipPrjQuery=False):
pId = None
if skipPrjQuery:
def get_project(self, project_name: str, workspace_name: str, skip_prj_query=False):
if skip_prj_query:
projects = self.projects
else:
projects = self.getProjects(workspace, skipPrjQuery)
projects = self.getProjects(workspace_name, skip_prj_query)

project_candidates = []
for project in projects:
if project_name == project["name"]:
project_candidates.append(project)

if len(project_candidates) == 1:
return project_candidates[0]
raise ValueError(f"project {project_name} not found or multiple projects with same name found")

for p in projects:
if p["name"] == project:
pId = p["id"]
if pId == None:
raise RuntimeError("Project %s not found in workspace %s" % (project, workspace))
return pId
def get_project_id(self, project_name, workspace, skip_prj_query=False):
return self.get_project(project_name, workspace, skip_prj_query)["id"]

def getUsers(self, workspace):
if self._syncUsers == True:
Expand Down Expand Up @@ -669,7 +673,7 @@ def addEntry(self, start, description, projectName, userMail, workspace,
url = self.url + "/workspaces/%s/time-entries" % wsId

if projectName != None:
projectId = self.getProjectID(projectName, workspace, skipPrjQuery=self._syncProjects)
projectId = self.get_project_id(projectName, workspace, skip_prj_query=self._syncProjects)
if taskName != None:
pTasks = self.getTasksOnProject(workspace, projectName)
taskId = self.getTaskIdFromTasks(taskName, pTasks)
Expand Down Expand Up @@ -770,7 +774,7 @@ def getTimeEntryForUser(self, userMail, workspace, description,
uId = self.userID

if projectName != None:
prjID = self.getProjectID(projectName, workspace)
prjID = self.get_project_id(projectName, workspace)
if start != None:
start = start.strftime('%Y-%m-%dT%H:%M:%SZ')

Expand All @@ -795,7 +799,7 @@ def getTimeEntryForUser(self, userMail, workspace, description,

def archiveProject(self, projectName, workspace, skipPrjQuery=False):
wsId = self.getWorkspaceID(workspace)
pID = self.getProjectID(projectName, workspace, skipPrjQuery=skipPrjQuery)
pID = self.get_project_id(projectName, workspace, skip_prj_query=skipPrjQuery)
url = "https://api.clockify.me/api/workspaces/%s/projects/%s/archive" % (wsId, pID)
rv = self._request(url, typ="GET")
if rv.status_code == 200:
Expand Down Expand Up @@ -841,7 +845,7 @@ def deleteEntry(self, entryID, workspace):

def deleteProject(self, projectName, workspace, skipPrjQuery=False):
wsId = self.getWorkspaceID(workspace)
projectID = self.getProjectID(projectName, workspace, skipPrjQuery)
projectID = self.get_project_id(projectName, workspace, skipPrjQuery)
url = self.url + "/workspaces/%s/projects/%s" % (wsId, projectID)
rv = self._request(url, typ="DELETE")
if rv.ok:
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONDA_ENV=clockify-automation

conda-create:
conda env create -f conda.yml --name $(CONDA_ENV)
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ Credits to Markus Proeller, [email protected].

## Setup

* Create virtual env: `python -m venv venv` and activate it: `. ./venv/bin/activate `.
* Install requirements: `pip install -r requirements.txt`.
* Create virtual env in conda, use `make conda-create` then activate the environment via `conda activate clockify-automation`
* Set proper values in `config.json`, use `config_example.json` as a base.
* Run it: `python main.py`

Expand Down
20 changes: 20 additions & 0 deletions conda.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: txmatching
channels:
- conda-forge
dependencies:
- autopep8=2.0.0
- pip=22.3.1
- python=3.10.5
- pip:
- arrow==0.17.0
- certifi==2020.12.5
- chardet==4.0.0
- click==7.1.2
- idna==2.10
- python-dateutil==2.8.1
- pytz==2020.5
- requests==2.25.1
- six==1.15.0
- slumber==0.7.1
- TogglPy==0.1.1
- urllib3==1.26.5
12 changes: 9 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def main():
)

clockify = ClockifyAPI(clockify_settings.token, clockify_settings.email, reqTimeout=1)
clockify.getProjects(workspace=clockify_settings.workspace)
clockify.getProjects(workspace_name=clockify_settings.workspace)

toggle_base_url = 'https://api.track.toggl.com/api/v9'

Expand Down Expand Up @@ -177,8 +177,14 @@ def main():

tags = [tag.strip() for tag in row['tags'] if tag.strip() != '']

# tag billable if there's a tag billable
billable = 'billable' in tags
# tag billable if there's a tag else set default for the project
project = clockify.get_project(row['project_name'], clockify_settings.workspace)
if 'billable' in tags:
billable = True
elif 'non-billable' in tags:
billable = False
else:
billable = project["billable"]
# remove billable and non-billable tags as we don't need them anymore
tags = [tag for tag in tags if tag not in {'non-billable', 'billable'}]

Expand Down

0 comments on commit 03c46b1

Please sign in to comment.