예제 #1
0
    def _load_task(self, row, parents_stack):
        task = models.Task(self.schedule)
        cells, unknown_cells = self._load_task_cells(row)

        task.index = row.row_number
        # task.slug is generated at the end of importing whole schedule

        # skip empty rows
        if not all([c in cells and cells[c]
                    for c in COLUMN_TASK_NAME, COLUMN_START, COLUMN_FINISH]):
            # skip load, task doesn't contain all needed info
            return
예제 #2
0
    def _parse_task_element(self, task, eTask):
        task.index = self.task_index
        self.task_index += 1
        task.slug = eTask.get('id')
        task.name = eTask.get('name').strip()

        notes = eTask.xpath('note')
        if notes:
            task.note = notes[0].text.strip()

        task.priority = int(eTask.get('priority'))
        task.milestone = eTask.get('milestone') == '1'

        p_complete_attr = eTask.xpath('./taskScenario[@scenarioId=\'actual\']')
        p_complete = float(p_complete_attr[0].get('complete'))
        if p_complete < 0:
            p_complete = 0.0
        task.p_complete = p_complete

        task.dStart = self._load_tjx_date(eTask, 'actual',
                                          'start') or self._load_tjx_date(
                                              eTask, 'plan', 'start')
        task.dFinish = self._load_tjx_date(eTask, 'actual',
                                           'end') or self._load_tjx_date(
                                               eTask, 'plan', 'end')

        if task.milestone:
            task.dFinish = task.dStart

        for eFlag in eTask.xpath('./flag'):
            task.flags.append(eFlag.text)

        link_el = eTask.xpath(
            'customAttribute[@id="PTask"]/referenceAttribute')
        if link_el:
            task.link = link_el[0].get('url')

        # add flags from task to global used tags
        task._schedule.used_flags |= set(task.flags)

        min_date = task.dStart
        max_date = task.dFinish

        for eSubTask in eTask.xpath('./task'):
            item_task = models.Task(self.schedule, task.level + 1)
            t_min_date, t_max_date = self._parse_task_element(
                item_task, eSubTask)
            min_date = min(min_date, t_min_date)
            max_date = max(max_date, t_max_date)

            task.tasks.append(item_task)
        return min_date, max_date
예제 #3
0
    def import_schedule(self):
        self.schedule = models.Schedule()

        tree = self._get_parsed_tree()
        el_proj = tree.xpath('/taskjuggler/project')[0]

        self.schedule.name = '%s %s' % (el_proj.get('name'),
                                        el_proj.get('version'))
        self.schedule.slug = el_proj.get('id')

        # import changelog/mtime from content of TJX
        self.schedule.changelog = self.get_handle_changelog()
        self.schedule.mtime = self.get_handle_mtime()

        min_date = datetime.datetime.max
        max_date = datetime.datetime.min

        for task in tree.xpath('/taskjuggler/taskList/task'):
            item_task = models.Task(self.schedule)
            self._parse_task_element(item_task, task)
            min_date = min(min_date, item_task.dStart)
            max_date = max(max_date, item_task.dFinish)
            self.schedule.tasks.append(item_task)

        if self.schedule.tasks:
            self.schedule.dStart = min_date
            self.schedule.dFinish = max_date
            self.schedule.name = self.schedule.tasks[0].name
        else:
            # try to load dates from project level
            tag = el_proj.xpath('start')[0].text
            start = datetime.datetime.fromtimestamp(float(tag))
            if start:
                self.schedule.dStart = start

            tag = el_proj.xpath('end')[0].text
            end = datetime.datetime.fromtimestamp(float(tag))
            if end:
                self.schedule.dFinish = end
        self.schedule.name = self.schedule.name.strip()

        return self.schedule
예제 #4
0
    def task_load_tjx_node(self, task, eTask):
        task.index = int(eTask.xpath('Index')[0].text)
        task.slug = eTask.get('Id')
        task.name = eTask.xpath('Name')[0].text.strip()

        notes = eTask.xpath('Note')
        if notes:
            task.note = notes[0].text.strip()

        task.priority = int(eTask.xpath('Priority')[0].text)
        task.p_complete = float(eTask.xpath('complete')[0].text)
        task.dStart = self._load_tjx_date(eTask, 'actual', 'start') or self._load_tjx_date(eTask, 'plan', 'start')
        task.dFinish = self._load_tjx_date(eTask, 'actual', 'end') or self._load_tjx_date(eTask, 'plan', 'end')

        # sanity check - if only tart defined and beyond plan finish
        task.dFinish = max(task.dFinish, task.dStart)
        task.milestone = eTask.xpath('Type')[0].text == 'Milestone'

        for eFlag in eTask.xpath('./Flag'):
            task.flags.append(eFlag.text)

        task._schedule.used_flags |= set(task.flags)

        ptask_el = eTask.xpath('./custom[@id="PTask"]')
        if ptask_el:
            task.link = ptask_el[0].get('url')

        min_date = task.dStart
        max_date = task.dFinish

        for eSubTask in eTask.xpath('./SubTasks/Task'):
            task_item = models.Task(task._schedule, task.level + 1)
            t_min_date, t_max_date = self.task_load_tjx_node(task_item,
                                                             eSubTask)
            min_date = min(min_date, t_min_date)
            max_date = max(max_date, t_max_date)

            task.tasks.append(task_item)

        return min_date, max_date
예제 #5
0
    def _load_tasks_level(self, level, eTask_list):
        return_tasks = []

        while eTask_list:
            eTask = eTask_list[0]
            task_level = int(eTask.xpath('OutlineLevel')[0].text)

            if task_level > level:
                # return tasks may be empty
                # since there could be no importable tasks yet
                if len(return_tasks):
                    return_tasks[-1].tasks = self._load_tasks_level(
                        task_level, eTask_list)
                else:
                    # remove task from list
                    eTask_list.pop(0)
                continue
            elif task_level < level:
                return return_tasks

            # process task
            task = models.Task(self.schedule, level=level)
            if self.task_load_msp_node(task, eTask):
                # update schedule start/end
                if self.schedule.dStart:
                    self.schedule.dStart = min(self.schedule.dStart,
                                               task.dStart)
                else:
                    self.schedule.dStart = task.dStart

                if self.schedule.dFinish:
                    self.schedule.dFinish = max(self.schedule.dFinish,
                                                task.dFinish)
                else:
                    self.schedule.dFinish = task.dFinish

                return_tasks.append(task)
            # remove task from list
            eTask_list.pop(0)
        return return_tasks
예제 #6
0
    def import_schedule(self):
        if not self.__class__.is_valid_source(self.handle):
            raise TJXImportException('Invalid TJX source', source=self.handle)

        self.schedule = models.Schedule()

        tree = self._get_parsed_tree()

        self.schedule.name = '%s %s' % (tree.xpath('Name')[0].text.strip(),
                                        tree.xpath('Version')[0].text)

        slug = str(tree.xpath('@Id')[0])
        if slug:
            self.schedule.slug = slug

        # look for same id as project, there might be more included root tasks
        eRoot_task = None
        eRoot_tasks = tree.xpath('Task[@Id = /Project/@Id]')
        if not len(eRoot_tasks):  # try whatever single root task
            eRoot_tasks = tree.xpath('Task')
            root_tasks_count = len(eRoot_tasks)
            if root_tasks_count == 1:
                eRoot_task = eRoot_tasks[0]
            elif root_tasks_count == 0:
                log.warning('Empty schedule %s ' % (self.handle,))
        else:
            eRoot_task = eRoot_tasks[0]

        if eRoot_task is not None:
            root_task_name = eRoot_task.xpath('Name')
            if root_task_name:
                self.schedule.name = root_task_name[0].text
        else:
            log.info('Can\'t find single root task in {} (found {} root '
                     'tasks)'.format(self.handle, len(eRoot_tasks)))

        self.schedule.name = self.schedule.name.strip()

        # import changelog/mtime from content of TJX
        self.schedule.changelog = self.get_handle_changelog()
        self.schedule.mtime = self.get_handle_mtime()

        min_date = datetime.datetime.max
        max_date = datetime.datetime.min

        for eTask in eRoot_tasks:
            task = models.Task(self.schedule, level=1)
            t_min_date, t_max_date = self.task_load_tjx_node(task, eTask)
            min_date = min(min_date, t_min_date)
            max_date = max(max_date, t_max_date)
            self.schedule.tasks.append(task)

        if self.schedule.tasks:
            self.schedule.dStart = min_date
            self.schedule.dFinish = max_date
        else:
            # try to load dates from project level
            start = self._load_tjx_date(tree, 'start')
            if start:
                self.schedule.dStart = start
            end = self._load_tjx_date(tree, 'end')
            if end:
                self.schedule.dFinish = end

        return self.schedule
예제 #7
0
    def import_schedule(self):
        self.schedule = models.Schedule()
        start_time = None

        options = ['--config=%s' % self.handle]
        server, user, password, workspace, project = rallySettings(options)

        rally = Rally(server, user, password, workspace=workspace, project=project)

        rally_iter = self.options['rally_iter']
        self.schedule.name = rally_iter.strip()
        query_criteria = 'Iteration.Name = "%s"' % rally_iter

        response = rally.get('Iteration', fetch=True,
                             query='Name = "%s"' % rally_iter)
        if response.errors:
            sys.stdout.write("\n".join(response.errors))
            sys.exit(1)

        for iteration in response:
            print 'Iteration: %s (starts %s)' % (iteration.Name, iteration.StartDate)
            start_time = datetime.datetime.combine(
                datetime.datetime.strptime(iteration.StartDate[:10], '%Y-%m-%d'),
                datetime.time(8))
            break

        response = rally.get('UserStory', fetch=True, query=query_criteria, order="Rank")

        if response.errors:
            sys.stdout.write("\n".join(response.errors))
            sys.exit(1)

        index = 1
        if not start_time:
            start_time = datetime.datetime.combine(datetime.date.today(), datetime.time(8))
        max_end_time = start_time
        self.schedule.dStart = start_time

        for story in response:
            print story.Name
            t = models.Task(self.schedule, level=1)
            t.index = index
            index += 1
            t.name = story.Name.strip()
            t.dStart = start_time

            max_st_end_time = start_time
            story.Tasks.sort(key=lambda x: x.TaskIndex)
            for task in story.Tasks:
                print '-- %s  |  %sh  |  %s' % (task.Name, task.Estimate, task.Owner.Name)
                t_in = models.Task(self.schedule, level=2)
                t_in.index = index
                index += 1
                t_in.name = task.Name.strip()
                t_in.dStart = start_time
                t_in.dFinish = start_time + datetime.timedelta(hours=float(task.Estimate))
                max_st_end_time = max(max_end_time, t_in.dFinish)

                # look for resource
                resource_id = None
                for r_id, resource in self.schedule.resources.items():
                    if resource == task.Owner.Name:
                        resource_id = r_id
                        break
                if not resource_id:
                    resource_id = len(self.schedule.resources) + 1
                    self.schedule.resources[resource_id] = str(task.Owner.Name)

                t_in.resource = resource_id

                t.tasks.append(t_in)
            print ''
            t.dFinish = max_st_end_time
            max_end_time = max(max_end_time, t.dFinish)
            self.schedule.tasks.append(t)

        self.schedule.dFinish = max_end_time
        return self.schedule
예제 #8
0
 def _prepare_inject_value(self):
     self.schedule = models.Schedule()
     self.task = models.Task(schedule=self.schedule)