def create_task(**kwargs): tw = TaskWarrior(data_location=(TWDFT_DATA_DIR), taskrc_location=TWDFTRC) verbose = kwargs.pop("verbose", False) open_card = kwargs.pop("open_card", False) inspectors = kwargs.pop("inspectors", False) test_task = Task(tw, **kwargs) test_task.save() if open_card: card_path = create_card( inspection_name=kwargs["description"], inspection_date=kwargs["inspection_date"], inspection_time=kwargs["inspection_time"], open_card=True, inspectors=inspectors, verbose=verbose, ) test_task["card_path"] = card_path[0] test_task["inspection_card_uuid"] = card_path[1] test_task.save() else: card_path = create_card( inspection_name=kwargs["description"], inspection_date=kwargs["inspection_date"], inspection_time=kwargs["inspection_time"], open_card=False, inspectors=inspectors, verbose=verbose, ) test_task["card_path"] = card_path[0] test_task["inspection_card_uuid"] = card_path[1] test_task.save()
def setUp(self): taskwarrior = TaskWarrior(data_location='tests/test_data/.task', create=True) Task(taskwarrior, description='test_yesterday', schedule='yesterday', estimate='20min').save() Task(taskwarrior, description='test_9:00_to_10:11', schedule='today+9hr', estimate='71min').save() Task(taskwarrior, description='test_14:00_to_16:00', schedule='today+14hr', estimate='2hr').save() Task(taskwarrior, description='test_16:10_to_16:34', schedule='today+16hr+10min', estimate='24min').save() Task(taskwarrior, description='test_tomorrow', schedule='tomorrow', estimate='24min').save() self.schedule = Schedule(tw_data_dir='tests/test_data/.task', tw_data_dir_create=True)
def __init__(self): self.tw = TaskWarrior() builder.add_from_file("gui/timeout.glade") self.wTimeout = builder.get_object("wTimeout") self.pbTimeout = builder.get_object("pbTimeout") self.wContinue = builder.get_object("wContinue") self.lsbReminders = builder.get_object("lsbReminders") self.bus = dbus.SessionBus() self.session_bus = self.bus.get_object('org.liloman.pomodoro', "/daemon") self.interface = dbus.Interface(self.session_bus, "org.liloman.pomodoroInterface") ################ # Set events # ################ self.btYes = builder.get_object("btYes") self.btYes.connect("clicked", self.onYesPressed) self.btNo = builder.get_object("btNo") self.btNo.connect("clicked", self.onNoPressed) self.wTimeout.connect("delete-event", self.onDeleteWindow) self.btBack = builder.get_object("btBackWork") self.btBack.connect("clicked", self.onBackWorkPressed) self.pbTimeout = builder.get_object("pbTimeout") DATEFORMAT = '%d/%m/%Y %H:%M' for task in self.tw.tasks.filter('+READY +reminder'): #get all fields in task task.refresh() self.addReminder(task['description'], task['due'].strftime(DATEFORMAT))
def __init__(self): # Load configuration self.config = Config() self.DEV_STATE = self.config.get('clubhouse', 'DevelopmentState') self.REVIEW_STATE = self.config.get('clubhouse', 'ReviewState') self.PRIORITIES = self.config.get('DEFAULT', 'Priorities', fallback=dict()) self.IGNORE_TAGS = self.config.get('taskwarrior', 'IgnoreTags', fallback=list()) # List of "post-development" workflow states defined by the user to match their Clubhouse workflow schema self.POSTDEV_STATES = self.config.get('clubhouse', 'PostDevWorkflowStates', fallback=list()) # Create ClubWarrior data directory os.makedirs(self.config.DATA_DIR, exist_ok=True) # Instantiate Clubhouse client self.cc = ClubhouseClient() # Instantiate TaskWarrior client self.tw = TaskWarrior(self.config.TASK_DIR)
def setUp(self): taskwarrior = TaskWarrior(data_location='tests/test_data/.task', create=True) Task(taskwarrior, description='test_yesterday', schedule='yesterday', estimate='20min').save() Task(taskwarrior, description='test_9:00_to_10:11', schedule='today+9hr', estimate='71min', project='test').save() Task(taskwarrior, description='test_14:00_to_16:00', schedule='today+14hr', estimate='2hr').save() Task(taskwarrior, description='test_tomorrow', schedule='tomorrow', estimate='24min').save() self.tasks = taskwarrior.tasks.filter(status='pending') self.schedule = Schedule(tw_data_dir='tests/test_data/.task', tw_data_dir_create=True) self.schedule.load_tasks()
def _get_task(self): tw = TaskWarrior(data_location=(TWDFT_DATA_DIR), taskrc_location=TWDFTRC) try: self._task = tw.tasks.pending().get(id=self._task_id) except Task.DoesNotExist: click.echo("That task ID does not exist. Sorry.") sys.exit(1)
def __init__(self, rc='~/.task'): self.tw = TaskWarrior(data_location=rc, create=True) name = dbus.service.BusName(self.bus_name, bus=dbus.SessionBus(), do_not_queue=True, replace_existing=False, allow_replacement=False) dbus.service.Object.__init__(self, name, '/daemon')
def __init__(self, default_rc, default_data, extra_warrior_defs): default_kwargs = dict( data_location=default_data, taskrc_location=default_rc, ) # Setup the store of TaskWarrior objects self.warriors = {'default': TaskWarrior(**default_kwargs)} for key in extra_warrior_defs.keys(): current_kwargs = default_kwargs.copy() current_kwargs.update(extra_warrior_defs[key]) self.warriors[key] = TaskWarrior(**current_kwargs) # Make sure context is not respected in any TaskWarrior for tw in self.warriors.values(): tw.overrides.update({'context': ''})
def __init__(self, rc = '~/.task'): self.tw = TaskWarrior(data_location=rc, create=True) try: name = dbus.service.BusName(self.bus_name, bus=dbus.SessionBus(),do_not_queue=True, replace_existing=False, allow_replacement=False ) dbus.service.Object.__init__(self, name, '/daemon') except dbus.exceptions.NameExistsException: print("Daemon is already running.") sys.exit(0)
def task_card_path(id) -> str: tw = TaskWarrior(data_location=(TWDFT_DATA_DIR), taskrc_location=TWDFTRC) try: task = tw.tasks.pending().get(id=id) except Task.DoesNotExist: click.echo("That task ID does not exist. Sorry.") sys.exit(1) card_path = task["card_path"] return card_path
def main() -> None: updator.BOT = Bot(sys.argv[1]) updator.USER = int(sys.argv[2]) global _tw _tw = TaskWarrior(data_location=sys.argv[3], taskrc_location=sys.argv[4], create=True) syncThread().start() chatThread().start()
def add(id_or_filter, type_, spec, comments): config = Config() tw = TaskWarrior(config.task_home) task = select_task(tw, id_or_filter) type_ = determine_type(type_, spec) if type_ == URL and not re.match(r"https?://", spec): spec = "http://" + spec annotation = "{}:{}".format(type_, spec) if comments: annotation = " ".join(comments) + " " + annotation task.add_annotation(annotation)
def __init__(self, rc = '~/.task'): self.tw = TaskWarrior(data_location=rc, create=True) self.status_icon = Gtk.StatusIcon() self.status_icon.set_from_file("images/iconStarted-0.png") self.status_icon.connect("popup-menu", self.right_click_event) self.status_icon.connect("activate", self.left_click_event) # systray daemon name = dbus.service.BusName(self.bus_name, bus=dbus.SessionBus(),do_not_queue=True, replace_existing=False, allow_replacement=False ) dbus.service.Object.__init__(self, name, '/systray') # client for daemon bus = dbus.SessionBus(private = True) daemon_client = bus.get_object('org.liloman.pomodoro', "/daemon") self.interface = dbus.Interface(daemon_client, "org.liloman.pomodoroInterface")
def generate_data(self): super(MultipleSourceTest, self).generate_data() self.extra_dir = tempfile.mkdtemp(dir='/tmp/') self.extra_tw = TaskWarrior(data_location=self.extra_dir, taskrc_location='/') extra_tasks = [ Task(self.extra_tw, **task_kwargs) for task_kwargs in self.extra_tasks ] self.extra_tasks = extra_tasks for task in self.extra_tasks: task.save()
def get_card_file(task_number): tw = TaskWarrior(data_location=(TWDFT_DATA_DIR), taskrc_location=TWDFTRC) target = "" try: task = tw.tasks.pending().get(id=task_number) except Task.DoesNotExist: click.echo("That task ID does not exist. Sorry.") sys.exit(1) uuid = task["inspection_card_uuid"] for f in os.listdir(CARDS_DIR): if uuid in f: target = os.path.join(CARDS_DIR, f) break if not target: raise RuntimeError( "Cannot find card for this task. Use task to delete.") return target, task
def pdf(config, task_number, destination_directory): """ Export the inspection card to a PDF file. Requires pandoc and wkhtmltopdf to be installed. """ tw = TaskWarrior(data_location=(TWDFT_DATA_DIR), taskrc_location=TWDFTRC) try: task = tw.tasks.pending().get(id=task_number) except Task.DoesNotExist: click.echo("That task ID does not exist. Sorry.") sys.exit(1) card_path = task["card_path"] clean_name = clean_site_name_for_path("_".join( [task["description"], task["inspection_date"]])) subprocess.run( f"pandoc {card_path} -f markdown -t html5 -o {destination_directory}/{clean_name}.pdf", shell=True, )
def generate_data(self): self.dir = tempfile.mkdtemp(dir='/tmp/') # Create an actual taskrc file where we can write later self.taskrc_path = os.path.join(self.dir, "taskrc") with open(self.taskrc_path, 'w') as f: f.write("#testing taskrc\n") self.tw = TaskWarrior(data_location=self.dir, taskrc_location=self.taskrc_path) new_tasks = [ Task(self.tw, **task_kwargs) for task_kwargs in self.tasks ] self.tasks = new_tasks for task in self.tasks: task.save()
def check_files(self): """Check if the required files, directories and settings are present.""" # Create a temporary taskwarrior instance to read the config taskwarrior = TaskWarrior( data_location=self.data_location, create=False, taskrc_location=self.taskrc_location, ) # Disable _forcecolor because it breaks tw config output taskwarrior.overrides.update({"_forcecolor": "off"}) # Check taskwarrior directory and taskrc if os.path.isdir(self.data_location) is False: raise TaskDirDoesNotExistError(".task directory not found") if os.path.isfile(self.taskrc_location) is False: raise TaskrcDoesNotExistError(".taskrc not found") # Check if required UDAs exist if taskwarrior.config.get("uda.estimate.type") is None: raise UDADoesNotExistError( ("uda.estimate.type does not exist " "in .taskrc") ) if taskwarrior.config.get("uda.estimate.label") is None: raise UDADoesNotExistError( ("uda.estimate.label does not exist " "in .taskrc") ) # Check sound file sound_file = self.home_dir + "/.taskschedule/hooks/drip.wav" if self.show_notifications and os.path.isfile(sound_file) is False: raise SoundDoesNotExistError( f"The specified sound file does not exist: {sound_file}" ) # Create user directory if it does not exist taskschedule_dir = self.home_dir + "/.taskschedule" hooks_directory = self.home_dir + "/.taskschedule/hooks" if not os.path.isdir(taskschedule_dir): os.mkdir(taskschedule_dir) if not os.path.isdir(hooks_directory): os.mkdir(hooks_directory)
def edit(config, task_number, inspectionstatus): """ Edit some element of an inspection task. """ tw = TaskWarrior(data_location=(TWDFT_DATA_DIR), taskrc_location=TWDFTRC) try: task = tw.tasks.pending().get(id=task_number) except Task.DoesNotExist: click.echo("That task ID does not exist. Sorry") return if inspectionstatus: task["inspection_status"] = inspectionstatus task.save() if config.verbose: click.echo( click.style( f"Changed inspection_status of {task} to " f"{inspectionstatus}", fg="yellow", ))
def _main(): args = get_args() if args.editor: editor = args.editor elif "EDITOR" in os.environ: editor = os.environ["EDITOR"] else: raise Exception("Set an editor") config = Config() path = os.path.join(config.task_attach_dir, "{}.{}".format(uuid.uuid4(), args.ext)) subprocess.run(editor + " " + path, shell=True, check=True) tw = TaskWarrior(config.task_home) task = select_task(tw, args.id_or_filter) annotation = "{}:{}".format(FILE, path) if args.comments: annotation = " ".join(args.comments) + " " + annotation task.add_annotation(annotation)
def test_screen_draw(self): taskwarrior = TaskWarrior( data_location=self.task_dir_path, create=True, taskrc_location=self.taskrc_path, ) Task( taskwarrior, description="test_yesterday", schedule="yesterday", estimate="20min", ).save() Task( taskwarrior, description="test_9:00_to_10:11", schedule="today+9hr", estimate="71min", project="test", ).save() self.screen.draw() self.screen.refresh_buffer() Task( taskwarrior, description="test_14:00_to_16:00", schedule="today+14hr", estimate="2hr", ).save() time.sleep(0.1) self.screen.draw() self.screen.refresh_buffer() Task( taskwarrior, description="test_tomorrow", schedule="tomorrow", estimate="24min", ).save() time.sleep(0.1) self.screen.draw() self.screen.refresh_buffer()
def load_tasks(self, scheduled_before=None, scheduled_after=None, scheduled='today', completed=True): """Retrieve today's scheduled tasks from taskwarrior.""" taskwarrior = TaskWarrior(self.tw_data_dir, self.tw_data_dir_create) scheduled_tasks = [] filtered_tasks = [] if scheduled_before is not None and scheduled_after is not None: filtered_tasks.extend( taskwarrior.tasks.filter(scheduled__before=scheduled_before, scheduled__after=scheduled_after, status='pending')) if completed: filtered_tasks.extend( taskwarrior.tasks.filter( scheduled__before=scheduled_before, scheduled__after=scheduled_after, status='completed')) else: filtered_tasks.extend( taskwarrior.tasks.filter(scheduled=scheduled, status='pending')) if completed: filtered_tasks.extend( taskwarrior.tasks.filter(scheduled=scheduled, status='completed')) for task in filtered_tasks: scheduled_task = ScheduledTask(task, self) scheduled_tasks.append(scheduled_task) scheduled_tasks.sort(key=lambda task: task.start) self.tasks = scheduled_tasks
def _main(): args = get_args() config = Config() tw = TaskWarrior(config.task_home) task = select_task(tw, args.id_or_filter) attachments = [ a for a in task["annotations"] if re.search(r"({}):\S+".format("|".join((FILE, URL, MAIL))), str(a)) ] if len(attachments) == 1: attachment = str(attachments[0]) elif len(attachments) > 1: menu = Menu(attachments) attachment = str(attachments[menu.show_and_pick()]) else: raise Exception("No valid attachments") file_beg = attachment.rfind("{}:".format(FILE)) url_beg = attachment.rfind("{}:".format(URL)) mail_beg = attachment.rfind("{}:".format(MAIL)) if file_beg >= 0: type_ = FILE spec = os.path.expandvars( os.path.expanduser(attachment[file_beg + len(FILE) + 1:])) elif url_beg >= 0: type_ = URL spec = attachment[url_beg + len(URL) + 1:] elif mail_beg >= 0: type_ = MAIL spec = attachment[mail_beg + len(MAIL) + 1:] else: raise Exception("wtf") cmd = args.cmd if args.cmd else get_default_cmd(config, type_) subprocess.run('{} "{}"'.format(cmd, spec), shell=True, check=True)
def main(): args = _usage() print(args) #path = os.environ["MDIR_LOGS"] + "/inotify/drive/log3" host = socket.gethostname() tw = TaskWarrior() if not args.push: tw.sync() drive_path = _get_drive_path() tsks = _get_tasks(tw, host, args.push) print(tsks) excluded_paths = {'LinkAppData/TaskWarrior'} s = _compact_changes(tsks) if not bool(s): print("no changes, exiting") return logger.debug(f"the final set is {s}") # ss = _get_relative_paths(s, drive_path) # logger.debug(f"the relative set is {ss}") _drive_sync(s, drive_path, args.push) _task_update(host, tsks, args.push) tw.sync()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.set_icon_from_file("images/taskwarrior.png") self.set_wmclass("HandyTask", "HandyTask") # This will be in the windows group and have the "win" prefix # max_action = Gio.SimpleAction.new_stateful("maximize", None, # GLib.Variant.new_boolean(False)) # max_action.connect("change-state", self.on_maximize_toggle) # self.add_action(max_action) self.header = Handy.HeaderBar() self.header.set_title("HandyTask") self.back_button = Gtk.Button.new_from_icon_name("go-previous", Gtk.IconSize.BUTTON) # self.back_button.set_label("<") # self.back_button.set_image( # Gtk.Image.new_from_icon_name("go-previous", Gtk.IconSize.BUTTON) # ) self.back_button.connect("clicked", self.on_detail_cancel_clicked) self.header.pack_start(self.back_button) # self.back_button.show() # self.refresh_button = Gtk.ToolButton() # self.refresh_button.set_icon_name("view-refresh") self.refresh_button = Gtk.Button.new_from_icon_name("view-refresh", Gtk.IconSize.BUTTON) self.refresh_button.show() self.refresh_button.connect("clicked", self.on_refresh_clicked) self.header.pack_end(self.refresh_button) self.new_button = Gtk.Button.new_from_icon_name("appointment-new", Gtk.IconSize.BUTTON) self.new_button.connect("clicked", self.on_new_clicked) self.new_button.show() self.header.pack_end(self.new_button) self.set_titlebar(self.header) self.header.show() self.set_show_menubar(False) # Keep it in sync with the actual state # self.connect("notify::is-maximized", # lambda obj, pspec: max_action.set_state( # GLib.Variant.new_boolean(obj.props.is_maximized))) # Allocate a universal taskwarrior instance self.tasks = TaskList(taskwarrior = TaskWarrior()) # Responsive Box -> Stack transition # If there's enough width, we show the sidebar as a box (adjacent fields) # If not (see set_size_request in each of the children), Handy.Leaflet # instead displays as a stack (one view at a time) self.multi_view = Handy.Leaflet(orientation = Gtk.Orientation.HORIZONTAL) self.add(self.multi_view) self.multi_view.show() # Allocate the task list view itself self.initial_selection = True self.task_view = TaskListView( tasks = self.tasks, toggle = self.on_done_toggled, on_select = self.on_select_task ) self.multi_view.add(self.task_view) self.task_view.show() self.multi_view.bind_property( "folded", self.back_button, "visible", GObject.BindingFlags.SYNC_CREATE ) self.multi_view.bind_property( "folded", self.new_button, "visible", GObject.BindingFlags.SYNC_CREATE ) # Allocate the task detail sidebar self.detail_view = TaskDetailView( on_save = self.on_detail_save_clicked, on_cancel = self.on_detail_cancel_clicked, on_update_date = self.on_update_date ) self.multi_view.add(self.detail_view) # self.detail_view.hide() self.detail_view.show() self.task_view.unselect()
from backports.functools_lru_cache import lru_cache # This is so you can use YYYY-MM-DD in TaskWarrior year = datetime.date.today().year month = datetime.date.today().month day = datetime.date.today().day today = date(year, month, day) # Here you can choose when you want to delete tasks. If due was -1 or -2, 4, 20 days whatever you want) yesterday = today - timedelta(days=1) # Uncomment the following if you first want to check! (see below) # with open(todo, 'w'): pass # Fill in your path to your Taskwarrior database tw = TaskWarrior('/PATH/TO/.task') # This filters tasks which are pending and due before yesterday and in the project: priv.bday which is the subproject 'bday' of the main project 'priv' for me. tasks = tw.tasks.pending().filter(due__before=yesterday, project='priv.bday') # WARNING this deletes the tasks If you want to check whether the script works I suggest you comment out the following and replace it with what's below for task in tasks: task.delete() # If you want to check before allowing tasks to be deleted use the below and check your CHECK.txt file after running the script. # CHECK = = "/PATH/TO/CHECK.txt" # for task in tasks: # begin = "[ ] " # end = "\n" # f = open(CHECK, "a+") # f.write(begin + str(task) + end)
def __init__(self, **config): super(TaskWarriorWidget, self).__init__(**config) self.add_defaults(self.defaults) self.tw = TaskWarrior()
class TaskWarriorWidget(ThreadedPollText): defaults = [ ("font", "Arial", "Font"), ("fontsize", None, "Pixel size. Calculated if None."), ("fontshadow", None, "font shadow color, default is None(no shadow)"), ("padding", None, "Padding. Calculated if None."), ("background", None, "Background colour"), ("foreground", "ffffff", "Foreground colour"), ("label_color", "#5555dd", "Color for the task label"), ('update_interval', 5, 'The update interval.'), ] TASK_RE = re.compile(r"#(\d+):\[\S+\] [\S ]+") OPTION_RE = re.compile(r'([\S]+):([\S]+)') TAG_RE = re.compile(r' \+([\S]+)') def __init__(self, **config): super(TaskWarriorWidget, self).__init__(**config) self.add_defaults(self.defaults) self.tw = TaskWarrior() def _configure(self, qtile, bar): super(TaskWarriorWidget, self)._configure(qtile, bar) self.layout = self.drawer.textlayout(self.text, self.foreground, self.font, self.fontsize, self.fontshadow, markup=True) def format_timer(self, task): delta = local_zone.localize(datetime.now()) - task['start'] hours, mins, seconds = str(delta).split(":", 3) total_active_time = re.sub(r'\D+', '', task['totalactivetime'] or '') if total_active_time and 'ongoing' not in task['tags']: total = timedelta(seconds=int(total_active_time)) total_hours, total_mins, total_seconds = str(total).split(":", 3) return "{hh}:{mm}|{hht}:{hhm}".format(hh=hours, mm=mins, hht=total_hours, hhm=total_mins) return "{hh}:{mm}".format(hh=hours, mm=mins) def poll(self): text = '' active_tasks = self.tw.tasks.filter('+ACTIVE') if active_tasks: task = active_tasks.get() time = self.format_timer(task) text = '<span weight="bold" color="{label_color}">Task:</span><span> {timer} [<i>#{id}</i>|{project}] {description}</span>'.format( timer=time, description=html.escape(task['description']), project=task['project'], label_color=self.label_color, id=task['id']) else: text = '(No current task) / O:<span color="#ffffff" weight="bold">{overdue_count}</span> | T:<span color="#ffffff" weight="bold">{today_count}</span> | B:<span color="#ffffff" weight="bold">{blocker_count}</span>'.format( blocker_count=len(self.tw.tasks.pending().filter('+BLOCKING')), overdue_count=len(self.tw.tasks.pending().filter('+OVERDUE')), today_count=len(self.tw.tasks.pending().filter('+DUETODAY'))) return text def button_press(self, x, y, button): if button == 1: active_tasks = self.tw.tasks.filter('+ACTIVE') if active_tasks: task = active_tasks.get() task.stop() else: tasks = "\n".join("#{id}:[{project}] {desc} | +{tags}".format( id=t['id'], project=t['project'], desc=t['description'], tags=" +".join(t['tags']) or "(untagged)") for t in sorted(self.tw.tasks.pending(), key=lambda x: x['urgency'], reverse=True)) cmd = 'dmenu -p "Start task? >" -fn "Iosevka-10" -sb "#DDDDDD" -sf "#000000" -nb "#000000" -i -l 10 -b' try: result = subprocess.run(cmd, input=tasks, stdout=subprocess.PIPE, check=True, universal_newlines=True, shell=True) selection = result.stdout match = self.TASK_RE.match(selection) if match: task_id = match.group(1) task = self.tw.tasks.get(id=task_id) task.start() else: options = dict(self.OPTION_RE.findall(selection)) tags = self.TAG_RE.findall(selection) descr = self.OPTION_RE.sub('', selection).strip() descr = self.TAG_RE.sub('', descr).strip() task = Task(self.tw, description=descr) if options: for k, v in options.items(): task[k] = v if tags: task['tags'] = tags task.save() task.start() except subprocess.CalledProcessError: pass elif button == 2: active_tasks = self.tw.tasks.filter('+ACTIVE') if active_tasks: task = active_tasks.get() if 'ongoing' not in task['tags']: task.done() else: task.stop() elif button == 3: self.tw.execute_command(['sync']) super(TaskWarriorWidget, self).button_press(x, y, button)
import sys import os from tasklib import TaskWarrior time_attributes = ('wait', 'scheduled') def is_new_local_recurrence_child_task(task): # Do not affect tasks not spun by recurrence if not task['parent']: return False # Newly created recurrence tasks actually have # modified field copied from the parent, thus # older than entry field (until their ID is generated) if (task['modified'] - task['entry']).total_seconds() < 0: return True tw = TaskWarrior(data_location=os.path.dirname(os.path.dirname(sys.argv[0]))) tw.overrides.update(dict(recurrence="no", hooks="no")) def hook_shift_recurrence(task): if is_new_local_recurrence_child_task(task): parent = tw.tasks.get(uuid=task['parent']['uuid']) parent_due_shift = task['due'] - parent['due'] for attr in time_attributes: if parent[attr]: task[attr] = parent[attr] + parent_due_shift
else: try: date1 = datetime.strptime(sys.argv[1], '%Y-%m-%d') date2 = datetime.strptime(sys.argv[2], '%Y-%m-%d') if date2 <= date1: sys.exit("Bad arguments. Second date must be later than first") else: pushdate=date1 while pushdate < date2: dates.append(pushdate) pushdate+=timedelta(days=1) except: sys.exit("Bad date format on date arguments, must be YYYY-MM-DD.") import time from tasklib import Task, TaskWarrior db=TaskWarrior() for date in dates: [wait, scheduled, due, until] = ajrSalat.getSawmTime(date, usrconfig.coords, ((time.mktime(time.localtime()) - time.mktime(time.gmtime())) / 60 / 60), method=usrconfig.methodName, dst=time.localtime().tm_isdst, waitpad=usrconfig.sawmWaitpad, untilpad=usrconfig.sawmUntilpad) sawm_task = Task(db, description=usrconfig.sawmDesc, project=usrconfig.sawmProject, wait=wait[0:19], scheduled=scheduled[0:19], due=due[0:19], until=until[0:19], priority='H', tags=usrconfig.sawmTags) #[0:19] index for tasklib as it cannot process fractional seconds by way of the taskwarrior calc function sawm_task.save()