-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcurrent-task.60s.py
More file actions
executable file
·129 lines (98 loc) · 3.84 KB
/
Copy pathcurrent-task.60s.py
File metadata and controls
executable file
·129 lines (98 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/env python3
# By default use the system Python 3 installation.
# If Homebrew is installed, you can use the Homebrew Python 3 installation by
# replacing the default shebang line above with the following line (check
# `which python` and adjust the path as needed).
#!/usr/bin/env /opt/homebrew/opt/python@3.11/libexec/bin/python
# <xbar.title>Current Things Task</xbar.title>
# <xbar.version>v0.1</xbar.version>
# <xbar.author>Wes Vetter</xbar.author>
# <xbar.author.github>wesvetter</xbar.author.github>
# <xbar.desc>Shows the current task in Things</xbar.desc>
# <xbar.dependencies>python3</xbar.dependencies>
# The Python script may not work on legacy macOS versions (Big Sur or earlier),
# because it may not find the correct path to the Python executable. If that
# happens, use the shell script instead and specify the appropriate path to the
# Python executable (use `which python3` to find the path).
import os
import sys
import json
DEFAULT_AREA_NAME = 'Work'
DEFAULT_HIDDEN_LABEL = 'Hidden'
MAX_TITLE_LENGTH = 20
NO_TASKS_MESSAGE = '☑️'
try:
import things
except ImportError:
# Error: The 'things' package is not installed. Please install it using the following command:
print("pip install things.py")
exit()
def find_user_config():
"""
Looks for a JSON configuration file in the user's home directory.
"""
path_to_config_file = os.path.expanduser('~/.current-thing.json')
if not os.path.exists(path_to_config_file):
return {}
with open(path_to_config_file, 'r') as file:
return json.load(file)
def build_config():
"""
Builds the configuration dictionary.
"""
config = {
'hidden_label': DEFAULT_HIDDEN_LABEL,
'max_title_length': MAX_TITLE_LENGTH,
'no_tasks_message': NO_TASKS_MESSAGE,
'target_area_name': DEFAULT_AREA_NAME,
}
config.update(find_user_config())
return config
def find_all_todos_by_area_title(title):
"""
Finds all of the todos in the specified area, including those in projects.
"""
try:
target_area = [a for a in things.areas() if a.get('title') == title][0]
except IndexError:
raise Exception('Area not found: ' + title)
# Get all tasks in the target area.
area_tasks = things.tasks(area=target_area.get('uuid'))
# Get all projects in the target area.
area_projects = things.projects(area=target_area.get('uuid'))
# Get all todos of projects in the target area.
area_project_todos = [t for p in area_projects for t in things.todos(project=p.get('uuid'))]
# Add the project todos to the area tasks.
area_tasks.extend(area_project_todos)
return area_tasks
def truncate_title(title, max_length):
"""
Truncates the title to the specified length.
"""
if len(title) > max_length:
return title[:max_length] + '...'
else:
return title
def find_current_task():
"""
Finds the current task in Things, scoped by area.
"""
todays_tasks = things.today()
config = build_config()
# If no area is specified, then we'll just look at today's tasks.
if config.get('target_area_name') == None:
scoped_tasks = todays_tasks
else:
scoped_tasks = find_all_todos_by_area_title(config.get('target_area_name'))
# Find the intersection of today's tasks and the area's tasks.
todays_scoped_tasks = [t for t in todays_tasks if t in scoped_tasks]
# Filter out tasks with the hidden tag.
hidden_label = config.get('hidden_label')
todays_scoped_tasks = [t for t in todays_scoped_tasks if not t.get('tags') or not hidden_label in t.get('tags')]
if todays_scoped_tasks:
next_task = todays_scoped_tasks[0]
title = truncate_title(next_task['title'], config.get('max_title_length'))
print(title)
else:
print(config.get('no_tasks_message'))
find_current_task()