def test_make_shift_smaller(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' self.storage_task.save_task(task1) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=10)) plan1.exclude = [0, 1, 3, 4] plan1.tid = 1 self.storage_plan.save_plan(plan1) new_shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=3)) args = {Plan.Field.plan_id: 1, Plan.Field.shift: new_shift} success = self.storage_plan.edit_plan(args) self.assertEqual(success, True) plans = self.storage_plan.get_plans(plan_id=1)[0] plan1.plan_id = 1 plan1.shift = new_shift plan1.exclude = [0, 10] self.assertEqual(plans, plan1)
def test_recalculate_exclude_when_start_time_shifted_backward(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' task1.supposed_start_time = utils.datetime_to_milliseconds( datetime.datetime.today()) self.storage_task.save_task(task1) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=2)) plan1.exclude = [0, 1, 3, 4] plan1.tid = 1 self.storage_plan.save_plan(plan1) new_time = utils.datetime_to_milliseconds(datetime.datetime.today() - datetime.timedelta(days=4)) self.storage_task.edit_task({ Task.Field.tid: 1, Task.Field.supposed_start_time: new_time }) start_time_shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=4)) success = self.storage_plan.recalculate_exclude_when_start_time_shifted( 1, -start_time_shift) self.assertEqual(success, True) plan = self.storage_plan.get_plans(plan_id=1)[0] plan1.plan_id = 1 plan1.exclude = [2, 3, 5, 6] self.assertEqual(plan, plan1)
def test_get_plans_for_common_tid(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' task2 = Task() task2.pid = 1 task2.title = 'Title 2' self.storage_task.save_task(task1) self.storage_task.save_task(task2) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=3)) plan1.exclude = [3, 5] plan1.tid = 2 plan2 = Plan() plan2.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=4)) plan2.exclude = [2, 8] plan2.tid = 1 self.storage_plan.save_plan(plan1) self.storage_plan.save_plan(plan2) plans = self.storage_plan.get_plans(common_tid=1) self.assertEqual(len(plans), 1) plan2.plan_id = 2 self.assertEqual(plans[0], plan2)
def test_remove_task_when_its_common_for_plan(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' task1.supposed_start_time = utils.datetime_to_milliseconds( datetime.datetime.today()) task2 = Task() task2.pid = 1 task2.title = 'Title 2' task2.supposed_start_time = utils.datetime_to_milliseconds( datetime.datetime.today()) self.storage_task.save_task(task1) self.storage_task.save_task(task2) plan1 = Plan() plan1.shift = utils.create_shift_in_millis(datetime.timedelta(days=2)) plan1.exclude = [0, 1, 3, 4] plan1.tid = 1 self.storage_plan.save_plan(plan1) success = self.storage_task.remove_task(1) self.assertEqual(success, True) tasks = self.storage_task.get_tasks() self.assertEqual(len(tasks), 1) task2.tid = 2 self.assertEqual(tasks[0], task2) plans = self.storage_plan.get_plans() self.assertEqual(len(plans), 0)
def test_plans_edit_repeat(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' self.storage_task.save_task(task1) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=3)) plan1.exclude = [] plan1.tid = 1 self.storage_plan.save_plan(plan1) task2 = Task() task2.pid = 1 task2.title = 'Title 2' self.storage_task.save_task(task2) success = self.storage_plan.edit_plan_repeat(1, 8, 2) self.assertEqual(success, True) plan_in_db = self.storage_plan.get_plans(1)[0] plan1.plan_id = 1 plan1.exclude.append(8) self.assertEqual(plan_in_db, plan1)
def get_tasks(self, filter): task = Task() task.tid = 1 task.status = Status.PENDING task.supposed_start_time = utils.datetime_to_milliseconds(datetime.datetime.today()) task.supposed_end_time = utils.shift_datetime_in_millis(datetime.datetime.today(), datetime.timedelta(days=2)) task.notificate_supposed_start=False return [task]
def test_is_before_time(self): task = Task() task.supposed_start_time = utils.datetime_to_milliseconds( datetime.datetime.today()) task.supposed_end_time = utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=3)) time_range = (utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=5)), utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=8))) is_before = task.is_before_time(time_range) self.assertEqual(is_before, True)
def test_is_time_overlap_fully(self): task = Task() task.supposed_start_time = utils.datetime_to_milliseconds( datetime.datetime.today()) task.supposed_end_time = utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=6)) time_range = (utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=0)), utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=6))) is_overlap = task.is_time_overlap_fully(time_range) self.assertEqual(is_overlap, True)
def test_exclude_delete_type(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' self.storage_task.save_task(task1) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=3)) plan1.exclude = [] plan1.tid = 1 self.storage_plan.save_plan(plan1) self.storage_plan.delete_plan_repeat(1, 8) exclude_type = self.storage_plan.get_exclude_type(1, 8) self.assertEqual(exclude_type, Plan.PlanExcludeKind.DELETED)
def get_tasks(self, filter): tid = getattr(filter, '_tid', None) if tid is not None and tid == 1: task = Task() task.tid = 1 task.status = Status.PENDING task.supposed_start_time = utils.datetime_to_milliseconds(datetime.datetime.today()) task.supposed_end_time = utils.shift_datetime_in_millis(datetime.datetime.today(), datetime.timedelta(days=2)) task.notificate_supposed_start=False return [task] if tid is not None and tid == 2: task = Task() task.tid = 2 task.status = Status.PENDING task.supposed_start_time = utils.shift_datetime_in_millis(datetime.datetime.today(), datetime.timedelta(days=9)) task.supposed_end_time = utils.shift_datetime_in_millis(datetime.datetime.today(), datetime.timedelta(days=11)) task.notificate_deadline=True return [task] return []
def test_save_plan(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' task2 = Task() task2.pid = 1 task2.title = 'Title 2' self.storage_task.save_task(task1) self.storage_task.save_task(task2) plan = Plan() plan.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=3)) plan.exclude = [3, 5] plan.tid = 2 success = self.storage_plan.save_plan(plan) self.assertEqual(success, True)
def test_remove_plan(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' self.storage_task.save_task(task1) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=10)) plan1.exclude = [0, 1, 3, 4] plan1.tid = 1 self.storage_plan.save_plan(plan1) success = self.storage_plan.remove_plan(1) self.assertEqual(success, True) plans = self.storage_plan.get_plans(plan_id=1) self.assertEqual(plans, [])
def test_plans_restore_repeat(self): task1 = Task() task1.pid = 1 task1.title = 'Title 1' self.storage_task.save_task(task1) plan1 = Plan() plan1.shift = utils.datetime_to_milliseconds( datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(days=3)) plan1.exclude = [3, 5] plan1.tid = 1 self.storage_plan.save_plan(plan1) self.storage_plan.delete_plan_repeat(1, 8) success = self.storage_plan.restore_plan_repeat(1, 8) self.assertEqual(success, True) plan_in_database = self.storage_plan.get_plans(plan_id=1)[0] plan1.plan_id = 1 self.assertEqual(plan_in_database, plan1)
def test_shift_task_forward(self): task = Task() task.supposed_start_time = utils.datetime_to_milliseconds( datetime.datetime.today()) task.supposed_end_time = utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=4)) shift_time = utils.create_shift_in_millis(datetime.timedelta(days=4)) task.shift_time(shift_time) test_start_time = utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=4)) test_end_time = utils.shift_datetime_in_millis( datetime.datetime.today(), datetime.timedelta(days=8)) if test_start_time - task.supposed_start_time == 1: test_start_time -= 1 if test_end_time - task.supposed_end_time == 1: test_end_time -= 1 self.assertEqual(task.supposed_start_time, test_start_time) self.assertEqual(task.supposed_end_time, test_end_time) self.assertEqual(task.deadline_time, None)
def home(controller, request): if request.session.get('parent_task') is not None: request.session.pop('parent_task') now = lib_utils.datetime_to_milliseconds(lib_utils.now()) TaskController(controller).find_overdue_tasks(now) if request.method == "POST": up_status = request.POST.get('status_up') if up_status is not None: status, tid = tuple(up_status.split(',')) status = Status.to_str(Status.raise_status( Status.from_str(status))) parts = tid.split('_') repeat = None plan_id = None if len(parts) == 1: tid = int(tid) if len(parts) == 3: tid = int(parts[0]) plan_id = int(parts[1]) repeat = int(parts[2]) if repeat is None: TaskController(controller).edit_task(tid, status=status) else: PlanController(controller).edit_repeat_by_number(plan_id, repeat, status=status) down_status = request.POST.get('status_down') if down_status is not None: status, tid = tuple(down_status.split(',')) status = Status.to_str( Status.downgrade_status(Status.from_str(status))) parts = tid.split('_') repeat = None plan_id = None if len(parts) == 1: tid = int(tid) if len(parts) == 3: tid = int(parts[0]) plan_id = int(parts[1]) repeat = int(parts[2]) if repeat is None: TaskController(controller).edit_task(tid, status=status) else: PlanController(controller).edit_repeat_by_number(plan_id, repeat, status=status) add_subtask = request.POST.get('add_subtask') if add_subtask is not None: request.session['parent_task'] = add_subtask return HttpResponseRedirect(reverse('core:add_task')) time_range = (lib_utils.datetime_to_milliseconds(lib_utils.today()), lib_utils.shift_datetime_in_millis( lib_utils.today(), datetime.timedelta(days=1))) tasks = [] tasks += TaskController(controller).get_overdue_tasks(now) tasks += TaskController(controller).fetch_tasks(time_range=time_range) tasks += TaskController(controller).fetch_tasks(timeless=True) for i, task in enumerate(tasks): for j in range(len(tasks) - 1, i, -1): if task.tid == tasks[j].tid and task.status == Status.OVERDUE: del tasks[j] tasks = filter_status(tasks) visual_tasks = [ VisualTaskData.from_lib_task(controller, task) for task in tasks ] return render(request, 'core/home.html', {'tasks': visual_tasks})
def _task_change_common(controller, request, on_task_changed, plan_id=None, repeat=None, initial_task=None): def to_utc(datetime_object): if datetime_object is not None: return datetime_object.replace(tzinfo=None) def timestamp_to_display(timestamp): if timestamp is not None: return datetime.datetime.utcfromtimestamp( timestamp / 1000.0).strftime('%d-%m-%Y %H:%M') projects = ProjectController(controller).fetch_projects() visual_projects = [ VisualProjectData.from_lib_project(controller, project) for project in projects ] VisualProjectData.normalize_visual_names(visual_projects, controller) if request.method == "POST": form = TaskForm(data=request.POST) cancel_parent = request.POST.get('cancel_parent') if cancel_parent is not None: request.session.pop('parent_task') elif form.is_valid(): title = form.cleaned_data.get('title') description = form.cleaned_data.get('description') priority = form.cleaned_data.get('priority') supposed_start = form.cleaned_data.get('supposed_start') supposed_end = form.cleaned_data.get('supposed_end') deadline = form.cleaned_data.get('deadline') project_pid = int(form.cleaned_data.get('project')) shift_milliseconds = 0 plan_minute = form.cleaned_data.get('plan_minute') if plan_minute is not None: plan_minute = int(plan_minute) shift_milliseconds += plan_minute * 60000 plan_hour = form.cleaned_data.get('plan_hour') if plan_hour is not None: plan_hour = int(plan_hour) shift_milliseconds += plan_hour * 60 * 60000 plan_day = form.cleaned_data.get('plan_day') if plan_day is not None: plan_day = int(plan_day) shift_milliseconds += plan_day * 24 * 60 * 60000 plan_month = form.cleaned_data.get('plan_month') if plan_month is not None: plan_month = int(plan_month) shift_milliseconds += plan_month * 30 * 24 * 60 * 60000 plan_year = form.cleaned_data.get('plan_year') if plan_year is not None: plan_year = int(plan_year) shift_milliseconds += plan_year * 365 * 30 * 24 * 60 * 60000 print('t', supposed_end) supposed_start = to_utc(supposed_start) supposed_end = to_utc(supposed_end) deadline = to_utc(deadline) print('t', supposed_end) supposed_start = lib_utils.datetime_to_milliseconds(supposed_start) supposed_end = lib_utils.datetime_to_milliseconds(supposed_end) deadline = lib_utils.datetime_to_milliseconds(deadline) print('t', timestamp_to_display(supposed_end)) on_task_changed(title, description, priority, supposed_start, supposed_end, deadline, project_pid, shift_milliseconds) return HttpResponseRedirect( reverse('core:project_tasks', args=[project_pid])) else: form = TaskForm() if initial_task is not None: form.fields['title'].initial = initial_task.title form.fields['description'].initial = initial_task.description form.fields['priority'].initial = Priority.to_str( initial_task.priority) supposed_start = VisualTaskData.timestamp_to_display( initial_task.supposed_start_time) supposed_end = VisualTaskData.timestamp_to_display( initial_task.supposed_end_time) deadline = VisualTaskData.timestamp_to_display( initial_task.deadline_time) form.fields['supposed_start'].initial = supposed_start form.fields['supposed_end'].initial = supposed_end form.fields['deadline'].initial = deadline form.fields['project'].initial = str(initial_task.pid) plans = PlanController(controller).get_plan_for_common_task( initial_task.tid) if plans is not None and len(plans) != 0: years, months, days, hours, minutes = VisualPlanData.parse_shift( plans[0].shift) if minutes != 0: form.fields['plan_minute'].initial = minutes if hours != 0: form.fields['plan_hour'].initial = hours if days != 0: form.fields['plan_day'].initial = days if months != 0: form.fields['plan_month'].initial = months if years != 0: form.fields['plan_year'].initial = years else: pid = request.session.get('pid') if pid is not None: form.fields['project'].initial = str(pid) else: for project in projects: if project.name == Project.default_project_name: form.fields['project'].initial = str(project.pid) break parent_task = None if initial_task is None: parent_tid = request.session.get('parent_task') if parent_tid is not None: lib_task = TaskController(controller).fetch_tasks(tid=parent_tid) if lib_task is not None and len(lib_task) != 0: parent_task = VisualTaskData.from_lib_task( controller, lib_task[0]) else: if request.session.get('parent_task') is not None: request.session.pop('parent_task') return render( request, 'core/add_task.html', { 'form': form, 'projects': visual_projects, 'parent_task': parent_task, 'repeat': repeat })
def get_tasks(self, filter): task = Task() task.tid = 1 task.supposed_start_time = utils.datetime_to_milliseconds(datetime.datetime.today()) task.supposed_end_time = utils.shift_datetime_in_millis(datetime.datetime.today(), datetime.timedelta(days=3)) return [task]
def search(controller, request): def to_utc(datetime_object): if datetime_object is not None: return datetime_object.replace(tzinfo=None) if request.session.get('parent_task') is not None: request.session.pop('parent_task') projects = ProjectController(controller).fetch_projects() visual_projects = [ VisualProjectData.from_lib_project(controller, project) for project in projects ] VisualProjectData.normalize_visual_names(visual_projects, controller) if request.method == "POST": up_status = request.POST.get('status_up') if up_status is not None: status, tid = tuple(up_status.split(',')) status = Status.to_str(Status.raise_status( Status.from_str(status))) parts = tid.split('_') repeat = None plan_id = None if len(parts) == 1: tid = int(tid) if len(parts) == 3: tid = int(parts[0]) plan_id = int(parts[1]) repeat = int(parts[2]) if repeat is None: TaskController(controller).edit_task(tid, status=status) else: PlanController(controller).edit_repeat_by_number(plan_id, repeat, status=status) down_status = request.POST.get('status_down') if down_status is not None: status, tid = tuple(down_status.split(',')) status = Status.to_str( Status.downgrade_status(Status.from_str(status))) parts = tid.split('_') repeat = None plan_id = None if len(parts) == 1: tid = int(tid) if len(parts) == 3: tid = int(parts[0]) plan_id = int(parts[1]) repeat = int(parts[2]) if repeat is None: TaskController(controller).edit_task(tid, status=status) else: PlanController(controller).edit_repeat_by_number(plan_id, repeat, status=status) add_subtask = request.POST.get('add_subtask') if add_subtask is not None: request.session['parent_task'] = add_subtask return HttpResponseRedirect(reverse('core:add_task')) form = TaskSearchForm(data=request.POST) if form.is_valid(): title = form.cleaned_data.get('title') if len(title) == 0: title = None description = form.cleaned_data.get('description') if len(description) == 0: description = None priority_list = form.cleaned_data.get('priority') if len(priority_list) == 0: priority_list = None else: priority_list = [ Priority.from_str(priority) for priority in priority_list ] status_list = form.cleaned_data.get('status') if len(status_list) == 0: status_list = None else: status_list = [ Status.from_str(status) for status in status_list ] supposed_start = form.cleaned_data.get('supposed_start') supposed_end = form.cleaned_data.get('supposed_end') deadline = form.cleaned_data.get('deadline') project_pid = request.POST.getlist('project') form.projects = project_pid supposed_start = to_utc(supposed_start) supposed_end = to_utc(supposed_end) deadline = to_utc(deadline) supposed_start = lib_utils.datetime_to_milliseconds(supposed_start) supposed_end = lib_utils.datetime_to_milliseconds(supposed_end) deadline = lib_utils.datetime_to_milliseconds(deadline) time_range = utils.get_time_range(supposed_start, supposed_end, deadline) print('TEST', time_range) timeless = form.cleaned_data.get('timeless') if timeless == 'true': timeless = True else: timeless = None if project_pid is None or len(project_pid) == 0: tasks = TaskController(controller).fetch_tasks( title=title, description=description, priority=priority_list, status=status_list, time_range=time_range, timeless=timeless) else: project_pid = [int(p) for p in project_pid] tasks = [] for p in project_pid: tasks += TaskController(controller).fetch_tasks( pid=p, title=title, description=description, priority=priority_list, status=status_list, time_range=time_range, timeless=timeless) else: tasks = TaskController(controller).fetch_tasks() else: form = TaskSearchForm() tasks = TaskController(controller).fetch_tasks() tasks = list(reversed(tasks)) visual_tasks = [ VisualTaskData.from_lib_task(controller, task) for task in tasks ] return render(request, 'core/search.html', { 'form': form, 'tasks': visual_tasks, 'projects': visual_projects })