diff --git a/nextaction.py b/nextaction.py index 0d96210..21333ba 100755 --- a/nextaction.py +++ b/nextaction.py @@ -11,6 +11,14 @@ from datetime import datetime +def is_item_visible(item): + """Returns true if the item is visible.""" + for attr in ['is_deleted', 'is_archived', 'in_history', 'checked']: + if item[attr] == 1: + return False + return True + + def get_subitems(items, parent_item=None): """Search a flat item list for child items.""" result_items = [] @@ -20,6 +28,8 @@ def get_subitems(items, parent_item=None): else: required_indent = 1 for item in items: + if not is_item_visible(item): + continue if parent_item: if not found and item['id'] != parent_item['id']: continue @@ -131,14 +141,22 @@ def remove_label(item, label): # Get all items for the project, sort by the item_order field. items = sorted(api.items.all(lambda x: x['project_id'] == project['id']), key=lambda x: x['item_order']) + # Tracks whether the first visible item at the root of the project has been found. + root_first_found = False + project_has_next_action = False + for item in items: + if not is_item_visible(item): + continue + # If its too far in the future, remove the next_action tag and skip if args.hide_future > 0 and 'due_date_utc' in item.data and item['due_date_utc'] is not None: due_date = datetime.strptime(item['due_date_utc'], '%a %d %b %Y %H:%M:%S +0000') future_diff = (due_date - datetime.utcnow()).total_seconds() if future_diff >= (args.hide_future * 86400): remove_label(item, label_id) + root_first_found = True continue item_type = get_item_type(item) @@ -147,12 +165,19 @@ def remove_label(item, label): logging.debug('Identified %s as %s type', item['content'], item_type) if item_type or len(child_items) > 0: + + # If the project is serial and there is a next action, + # remove the next_action from all children. + if project_type == 'serial' and project_has_next_action: + for child_item in child_items: + remove_label(child_item, label_id) # Process serial tagged items - if item_type == 'serial': + elif item_type == 'serial': + first_found = False for child_item in child_items: - first_found = False - if child_item['checked'] == 0 and not first_found: + if is_item_visible(child_item) and not first_found: add_label(child_item, label_id) + project_has_next_action = True first_found = True else: remove_label(child_item, label_id) @@ -163,13 +188,16 @@ def remove_label(item, label): # Remove the label from the parent remove_label(item, label_id) + root_first_found = True # Process items as per project type on indent 1 if untagged else: if item['indent'] == 1: if project_type == 'serial': - if item['item_order'] == 1: + if is_item_visible(item) and not root_first_found: add_label(item, label_id) + root_first_found = True + project_has_next_action = True else: remove_label(item, label_id) elif project_type == 'parallel':