Skip to content

Commit 18a1d55

Browse files
Merge pull request #11 from mschmidtkorth/develop
Fix search working without hierarchy levels Add allow no due date
2 parents 4274845 + ef9d5a8 commit 18a1d55

File tree

5 files changed

+76
-36
lines changed

5 files changed

+76
-36
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ _backup/*
77
setup.py
88
automatedTests.py
99
DO_NOT_COMMIT.md
10-
workflow/.alfredversionchecked
10+
workflow/.alfredversionchecked
11+
*.code-workspace

createTask.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def main(wf):
2222
query = wf.args[0]
2323
else:
2424
query = None
25-
25+
2626
taskParameters = json.loads(query)
2727
createTask(taskParameters['inputName'], taskParameters['inputContent'], taskParameters['inputDue'], taskParameters['inputPriority'], taskParameters['inputTags'], taskParameters['inputList'])
2828

@@ -40,16 +40,20 @@ def createTask(inputName, inputContent, inputDue, inputPriority, inputTags, inpu
4040
'''
4141
if DEBUG > 0:
4242
log.debug('[ Calling API to create task ]')
43-
43+
4444
if not inputList:
4545
inputListId = getConfigValue(confNames['confList'])
4646
else:
4747
# Get value of first key in dictionary {Name, Id} by converting to List. The dict will always contain a single list name+Id the user specified.
4848
inputListId = next(iter(inputList.items()))[1] # Get value for first key of dict
49-
50-
inputDue = datetime.datetime.strptime(str(inputDue)[:len(inputDue) - 10], '%Y-%m-%d %H:%M') # Convert String to datetime. Remove seconds.milliseconds (e.g. :26.614286) from string
51-
inputDueMs = (inputDue - datetime.datetime.fromtimestamp(0)).total_seconds() * 1000.0 # Convert datetime into ms. Use fromtimestamp() to get local timezone instead of utcfromtimestamp()
52-
49+
50+
log.debug(inputDue)
51+
log.debug(inputDue)
52+
log.debug(inputDue)
53+
if inputDue != 'None':
54+
inputDue = datetime.datetime.strptime(str(inputDue)[:len(inputDue) - 10], '%Y-%m-%d %H:%M') # Convert String to datetime. Remove seconds.milliseconds (e.g. :26.614286) from string
55+
inputDueMs = (inputDue - datetime.datetime.fromtimestamp(0)).total_seconds() * 1000.0 # Convert datetime into ms. Use fromtimestamp() to get local timezone instead of utcfromtimestamp()
56+
5357
url = 'https://api.clickup.com/api/v2/list/' + inputListId + '/task'
5458
params = None
5559
headers = {}
@@ -58,16 +62,17 @@ def createTask(inputName, inputContent, inputDue, inputPriority, inputTags, inpu
5862
data = {}
5963
data['name'] = inputName
6064
data['content'] = inputContent
61-
data['due_date'] = int(inputDueMs)
62-
data['due_date_time'] = True # Translated into true
65+
if inputDue != 'None':
66+
data['due_date'] = int(inputDueMs)
67+
data['due_date_time'] = True # Translated into true
6368
data['priority'] = inputPriority if inputPriority != None else None # Translated into 'null'
6469
data['tags'] = inputTags
65-
70+
6671
if DEBUG > 1:
6772
log.debug(url)
6873
log.debug(headers)
6974
log.debug(data)
70-
75+
7176
try:
7277
import json
7378
request = web.post(url, params = params, data = json.dumps(data), headers = headers)
@@ -80,7 +85,7 @@ def createTask(inputName, inputContent, inputDue, inputPriority, inputTags, inpu
8085
result = request.json()
8186
if DEBUG > 1:
8287
log.debug('Response: ' + str(result))
83-
88+
8489
# If user pressed 'opt' (optInput == true), we do not want to show a notification, as the task is opened in the browser
8590
hasUserNotPressedOpt = 'optInput' not in os.environ or os.environ['optInput'] == 'false'
8691
if getConfigValue(confNames['confNotification']) == 'true' and (hasUserNotPressedOpt):

getTasks.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ def getTasks():
3232
url = 'https://api.clickup.com/api/v2/team/' + getConfigValue(confNames['confTeam']) + '/task'
3333
params = {}
3434

35-
if 'space' in getConfigValue(confNames['confHierarchyLimit']):
36-
params['space_ids[]'] = getConfigValue(confNames['confSpace']) # Use [] instead of %5B%5D
37-
if 'folder' in getConfigValue(confNames['confHierarchyLimit']):
38-
params['project_ids[]'] = getConfigValue(confNames['confProject'])
39-
if 'list' in getConfigValue(confNames['confHierarchyLimit']):
40-
params['list_ids[]'] = getConfigValue(confNames['confList'])
35+
if getConfigValue(confNames['confHierarchyLimit']):
36+
if 'space' in getConfigValue(confNames['confHierarchyLimit']):
37+
params['space_ids[]'] = getConfigValue(confNames['confSpace']) # Use [] instead of %5B%5D
38+
if 'folder' in getConfigValue(confNames['confHierarchyLimit']):
39+
params['project_ids[]'] = getConfigValue(confNames['confProject'])
40+
if 'list' in getConfigValue(confNames['confHierarchyLimit']):
41+
params['list_ids[]'] = getConfigValue(confNames['confList'])
4142
params['order_by'] = 'due_date'
4243
# Differentiates between listing all Alfred-created tasks and searching for all tasks (any)
4344
if DEBUG > 0 and len(wf.args) > 1 and wf.args[1] == 'search':

info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,7 @@ Uses fuzzy search instead of Alfred filtering.</string>
11601160
<key>variablesdontexport</key>
11611161
<array/>
11621162
<key>version</key>
1163-
<string>1.0.2</string>
1163+
<string>1.0.3</string>
11641164
<key>webaddress</key>
11651165
<string>https://github.com/mschmidtkorth/alfred-clickup-msk/</string>
11661166
</dict>

main.py

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
isDoNotDisplayCreate = False
3636
isCustomTagEntered = False
3737

38+
3839
def retrieveLabelsFromAPI():
3940
'''Retrieves list of available Labels from ClickUp.
4041
'''
@@ -125,10 +126,13 @@ def getPriorities(input):
125126
filteredItems = wf.filter(input, allLabelTitles)
126127
for item in filteredItems:
127128
hasFoundMatch = True
128-
wf3.add_item(title = item.split(' ')[1], valid = False,
129+
wf3.add_item(
130+
title = item.split(' ')[1],
131+
valid = False,
129132
#arg = 'cu ' + query.replace(input, '') + str(priority) + ' ',
130133
autocomplete = query.replace(input, '') + item.split(' ')[0] + ' ',
131-
icon = './prio' + item.split(' ')[0] + '.png')
134+
icon = './prio' + item.split(' ')[0] + '.png'
135+
)
132136
if hasFoundMatch:
133137
wf3.send_feedback()
134138

@@ -190,10 +194,13 @@ def getLists(input, doPrintResults):
190194
global hasFoundMatch
191195
for item in filteredItems:
192196
hasFoundMatch = True
193-
wf3.add_item(title = item, valid = False,
197+
wf3.add_item(
198+
title = item,
199+
valid = False,
194200
#arg = 'cu ' + query.replace(input, '') + item + ' ',
195201
autocomplete = query.replace(input, '') + item + ' ',
196-
icon = './note.png')
202+
icon = './note.png'
203+
)
197204
if doPrintResults and hasFoundMatch:
198205
wf3.send_feedback()
199206
else: # Even when nothing is entered, we need to fill our dictionaries.
@@ -319,12 +326,16 @@ def formatNotificationText(inputContent, inputDue, inputTags, inputPriority, ava
319326
notificationBracketClose = ')'
320327
if inputPriority != None and hasTags:
321328
notificationSeparator = ', '
329+
if inputDue and inputDue != 'None':
330+
inputDue = emoji.emojize(':calendar:') + formatDate(inputDue)
331+
else:
332+
inputDue = ''
322333

323334
br = ''
324335
if lineBreaks:
325336
br = '\n'
326337

327-
return inputContent + (' ' if inputContent != '' else '') + br + emoji.emojize(':calendar:') + formatDate(inputDue) + notificationBracketOpen + notificationPriority + notificationSeparator + notificationTag + ' ' + (emoji.emojize(':spiral_notepad:') + str(next(iter(availableListsIdName))) if availableListsIdName != None else '') + notificationBracketClose
338+
return inputContent + (' ' if inputContent != '' else '') + br + inputDue + notificationBracketOpen + notificationPriority + notificationSeparator + notificationTag + ' ' + (emoji.emojize(':spiral_notepad:') + str(next(iter(availableListsIdName))) if availableListsIdName != None else '') + notificationBracketClose
328339

329340

330341
def formatDate(dateTime):
@@ -411,6 +422,7 @@ def getDueFromInput(query):
411422
inputMinHourDayWeek = ''
412423
passedDue = ''
413424
isUseDefault = True
425+
isNoDueDate = False
414426
hasTime = len(query.split(' @', 2)) > 1
415427
hasDefault = (getConfigValue(confNames['confDue']) != None and getConfigValue(confNames['confDue']) != '')
416428
if hasTime or hasDefault:
@@ -426,19 +438,24 @@ def getDueFromInput(query):
426438
passedDue = getConfigValue(confNames['confDue']) if isUseDefault else query.split(' @')[1][1:].split(' ')[0]
427439
log.debug('passedDue: ' + str(passedDue))
428440

429-
inputMinHourDayWeek = getConfigValue(confNames['confDue'])[0] if isUseDefault else query.split(' @', 2)[1][0] # First character: m, h, d, w
441+
inputMinHourDayWeek = ''
442+
if (isUseDefault and getConfigValue(confNames['confDue'])):
443+
inputMinHourDayWeek = getConfigValue(confNames['confDue'])[0]
444+
elif len(query.split(' @', 2)[1]) > 0:
445+
inputMinHourDayWeek = query.split(' @', 2)[1][0] # First character: m, h, d, w
430446
if DEBUG > 1:
431447
log.debug('inputMinHourDayWeek: ' + str(inputMinHourDayWeek))
432448

433-
isDefaultInteger = int(getConfigValue(confNames['confDue'])[1:])
449+
isDefaultInteger = getConfigValue(confNames['confDue']) and int(getConfigValue(confNames['confDue'])[1:])
434450
if hasTime:
435451
isInputInteger = timeValue.isnumeric() #query.split(' @', 2)[1].strip()[1:].isnumeric()
436452
if isUseDefault and isDefaultInteger:
437453
inputDue = int(getConfigValue(confNames['confDue'])[1:])
438454
elif isInputInteger:
439455
inputDue = int(timeValue) #int(query.split(' @', 2)[1].strip()[1:])
440456
else: # Invalid input
441-
inputDue = 2
457+
inputDue = 0 # No longer default of 2h - can now be set via configuration if desired, if not no due date will be added
458+
isNoDueDate = True
442459
inputMinHourDayWeek = 'h'
443460

444461
if inputMinHourDayWeek == 'm':
@@ -450,12 +467,16 @@ def getDueFromInput(query):
450467
elif inputMinHourDayWeek == 'w':
451468
inputDue *= 1000 * 60 * 60 * 24 * 7
452469
else:
453-
inputDue = 2 * 1000 * 60 * 60 # Default in 2 hours if no other value specified and no default context variable specified
470+
inputDue = 0 # No longer default of 2h if no other value specified and no default context variable specified - can now be set via configuration if desired, if not no due date will be added
471+
isNoDueDate = True
454472
inputDue = datetime.datetime.now() + datetime.timedelta(milliseconds = inputDue) # Add to whatever buffer has been selected
455473
if DEBUG > 1:
456474
log.debug('inputDue: ' + str(inputDue))
457475

458-
return inputDue
476+
if isNoDueDate:
477+
return None
478+
else:
479+
return inputDue
459480

460481

461482
def getListFromInput(query):
@@ -500,6 +521,7 @@ def getPriorityFromInput(query):
500521

501522
return inputPriority
502523

524+
503525
def main(wf):
504526
global query
505527
# Check if there is a user input
@@ -519,10 +541,14 @@ def main(wf):
519541
if DEBUG > 0:
520542
log.debug('Attempted to define additional description.')
521543
isDoNotDisplayCreate = True
522-
wf3.add_item(title = 'Description already defined.', subtitle = 'Please remove the second \':\' defining a content.', valid = False,
544+
wf3.add_item(
545+
title = 'Description already defined.',
546+
subtitle = 'Please remove the second \':\' defining a content.',
547+
valid = False,
523548
# arg = 'cu ' + query + ' ',
524549
autocomplete = query + ' ',
525-
icon = ICON_WARNING)
550+
icon = ICON_WARNING
551+
)
526552
wf3.send_feedback()
527553

528554
# Evaluate input for labels
@@ -568,10 +594,14 @@ def main(wf):
568594
if DEBUG > 0:
569595
log.debug('Attempted to define additional priority.')
570596
isDoNotDisplayCreate = True
571-
wf3.add_item(title = 'Priority already defined.', subtitle = 'Please remove the second \'!\' defining a priority.', valid = False,
597+
wf3.add_item(
598+
title = 'Priority already defined.',
599+
subtitle = 'Please remove the second \'!\' defining a priority.',
600+
valid = False,
572601
#arg = 'cu ' + query + ' ',
573602
autocomplete = query + ' ',
574-
icon = ICON_WARNING)
603+
icon = ICON_WARNING
604+
)
575605
wf3.send_feedback()
576606

577607
# Evaluate input for lists
@@ -606,10 +636,14 @@ def main(wf):
606636
if DEBUG > 0:
607637
log.debug('Attempted to define additional list.')
608638
isDoNotDisplayCreate = True
609-
wf3.add_item(title = 'List already defined.', subtitle = 'Please remove the second \'+\' defining a list.', valid = False,
639+
wf3.add_item(
640+
title = 'List already defined.',
641+
subtitle = 'Please remove the second \'+\' defining a list.',
642+
valid = False,
610643
# arg = 'cu ' + query + ' ',
611644
autocomplete = query + ' ',
612-
icon = ICON_WARNING)
645+
icon = ICON_WARNING
646+
)
613647
wf3.send_feedback()
614648

615649
# Extract different parts from input
@@ -620,7 +654,6 @@ def main(wf):
620654
inputList = getListFromInput(query)
621655
inputPriority = getPriorityFromInput(query)
622656

623-
624657
# Show 'Create Task' if user has completed their input - and no previous list item has been generated (JSON garbage).
625658
inputEndsWithCommand = query[-2:] == ' #' or query[-2:] == ' !' or query[-2:] == ' +'
626659
# log.debug('createListItemNotification - conditions: ')

0 commit comments

Comments
 (0)