def test_creation(self): """ Test generating objects of each type.""" test_task = Task(datetime.now(), 6) test_timeperiod = TimePeriod(datetime.now(), datetime.now()) assert test_task.as_dict()['object_type'] == 'Task' assert test_timeperiod.as_dict()['object_type'] == 'TimePeriod'
def timeperiods(session): TimePeriod.delete_all() TimePeriod(datetime(2010, 10, 10, 12, 00), datetime(2010, 10, 10, 12, 30)).save() tz = pytz.timezone("US/Pacific") aware1 = tz.localize(datetime(2010, 10, 11, 12, 00)) aware2 = tz.localize(datetime(2010, 10, 11, 12, 30)) TimePeriod(aware1, aware2).save() return session
def test_timeperiods(self, timeperiods): """ Test time periods.""" tps = TimePeriod.get_all() assert len(tps) == 2 assert "10 October 2010 - 12 30" in tps[0].__repr__() assert tps[1].available startdate = datetime(2010, 10, 10, 11, 00) enddate = datetime(2010, 12, 10, 12, 00) unassigned = TimePeriod.unassigned_in_range(startdate, enddate) assert "10 October 2010 - 12 30" in unassigned.__repr__() assert "2010-10-10" in unassigned.as_event()['start']['dateTime']
def test_assignments(self, tasks, timeperiods): """ Check manual assignments.""" tps = TimePeriod.get_all() tasks = Task.get_all() assert tps[0].available and tps[1].available tps[0].task = tasks[0] tps[1].task = tasks[1] tps[0].save() tps[1].save() assert not tps[0].available and not tps[1].available assert len(TimePeriod.get_assigned()) == 2 assert "test1" in tps[0].as_event()['description'] tasks[0].reset_assignments() assert tps[0].available and not tps[1].available
def get_work_blocks(calendar_id=INPUT_CAL_ID): """ Gets free work blocks as defined in a Google calendar.""" credentials = get_credentials(CAL_CREDS_FILENAME, CAL_SCOPES) http = credentials.authorize(httplib2.Http()) service = discovery.build('calendar', 'v3', http=http) now = datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time events_result = service.events().list(calendarId=calendar_id, timeMin=now, maxResults=30, singleEvents=True, orderBy='startTime').execute() events = events_result.get('items', []) time_periods = [] for event in events: # Create a new time period object # First deal with timezones start_timezone = pytz.timezone(event['start']['timeZone']) end_timezone = pytz.timezone(event['start']['timeZone']) # Convert UTC times into timezone aware times startdt = parser.parse(event['start']['dateTime']) \ .replace(tzinfo=pytz.utc).astimezone(start_timezone) enddt = parser.parse(event['end']['dateTime']) \ .replace(tzinfo=pytz.utc).astimezone(end_timezone) time_periods.append(TimePeriod(startdt, enddt)) return time_periods
def test_duration(self): """ Test getting duration of a time period.""" test_timeperiod = TimePeriod( datetime(2010, 10, 10, 12, 00), datetime(2010, 10, 10, 12, 30) ) assert test_timeperiod.duration == 30
def test_schedule_tasks(self, tasks, timeperiods): """ Test scheduling a task.""" tps = TimePeriod.get_all() tasks = Task.get_all() assert tps[0] not in tasks[0].timeperiods rt = schedule_task(tasks[0], datetime(2010, 10, 9, 12, 00)) assert rt == 0 assert tps[0] in tasks[0].timeperiods
def run(): """ Run program.""" # Clear initial data Task.delete_all() TimePeriod.delete_all() # Clear output calendar clear_events() # Get tasks from Google spreadsheet tasks = get_tasks_from_sheet() # Get working blocks from Input Google calendar wb = get_work_blocks() # Save data for t in tasks: t.save() for w in wb: w.save() # Schedule tasks errors = schedule_all() # Upload scheduled time periods to Output Google calendar assigned_tps = TimePeriod.get_assigned() events = [a_tp.as_event() for a_tp in assigned_tps] posted_events = post_assigned_time(events) # Return errors and posted events return (errors, posted_events)
def schedule_task(task, startdate=datetime.now()): """ Schedule a single task. """ # Initialise variable to store amount of time to assign runningtime = task.esttimemins*(1-(task.progress/100.0)) # Get all available timeperiods with a datetime > startdate # And an enddate < duedate available_tp = TimePeriod.unassigned_in_range(startdate, task.due) while available_tp and runningtime > 0: if runningtime >= available_tp.duration: # Assign task to time period available_tp.task = task available_tp.save() # Reduce running time runningtime = runningtime - available_tp.duration available_tp = TimePeriod.unassigned_in_range(startdate, task.due) else: # time period duration is longer than task duration # We need to adjust the statement below to work with timedeltas new_enddatetime = ( available_tp.startdatetime + timedelta(seconds=runningtime*60) ) original_enddatetime = available_tp.enddatetime # Split time period into two periods available_tp.enddatetime = new_enddatetime new_tp_2 = TimePeriod(new_enddatetime, original_enddatetime) # Assign first time period to task available_tp.task = task available_tp.save() new_tp_2.save() # Set next available time period as time period 2 available_tp = TimePeriod.unassigned_in_range(startdate, task.due) runningtime = 0 return runningtime