Пример #1
0
def test_add_inactive_project(cli, data_dir):
    project = Project(1, 'test project', Project.STATUS_FINISHED)
    project.activities = [Activity(2, 'test activity', 0)]
    p = ProjectsDb(str(data_dir))
    p.update([project])

    output = cli('project', ['alias', 'test project'], input='test_alias')

    assert "No active project matches your search string" in output
Пример #2
0
def test_add_inactive_project(cli, data_dir):
    project = Project(1, 'test project', Project.STATUS_FINISHED)
    project.activities = [Activity(2, 'test activity', 0)]
    p = ProjectsDb(str(data_dir))
    p.update([project])

    output = cli('project', ['alias', 'test project'], input='test_alias')

    assert "No active project matches your search string" in output
Пример #3
0
    def test_add_inactive_project(self):
        project = Project(1, 'test project', Project.STATUS_FINISHED)
        project.activities = [Activity(2, 'test activity', 0)]
        p = ProjectsDb(self.taxi_dir)
        p.update([project])

        output = self.run_project_command(['alias', 'test project'],
                                          input='test_alias')

        self.assertIn("No active project matches your search string", output)
Пример #4
0
    def test_add_single_choice(self):
        project = Project(1, 'test project', Project.STATUS_ACTIVE)
        project.activities = [Activity(2, 'test activity', 0)]
        p = ProjectsDb(self.taxi_dir)
        p.update([project])

        self.run_project_command(['alias', 'test project'], input='test_alias')

        with open(self.config_file, 'r') as f:
            self.assertIn('test_alias = 1/2\n', f.readlines())
Пример #5
0
    def test_add_inactive_project(self):
        project = Project(1, 'test project', Project.STATUS_FINISHED)
        project.activities = [Activity(2, 'test activity', 0)]
        p = ProjectsDb(self.taxi_dir)
        p.update([project])

        output = self.run_project_command(['alias', 'test project'],
                                          input='test_alias')

        self.assertIn("No active project matches your search string", output)
Пример #6
0
    def test_add_single_choice(self):
        project = Project(1, 'test project', Project.STATUS_ACTIVE)
        project.activities = [Activity(2, 'test activity', 0)]
        p = ProjectsDb(self.taxi_dir)
        p.update([project])

        self.run_project_command(['alias', 'test project'], input='test_alias')

        with open(self.config_file, 'r') as f:
            self.assertIn('test_alias = 1/2\n', f.readlines())
Пример #7
0
    def get_projects(self):
        p = Project(self.name,
                    self.name,
                    Project.STATUS_ACTIVE,
                    description=self.name)

        a = Activity(0, "No activity")
        p.add_activity(a)
        p.aliases[self.name] = a.id

        return [p]
Пример #8
0
def test_add_single_choice(cli, data_dir, config):
    project = Project(1, 'test project', Project.STATUS_ACTIVE)
    project.activities = [Activity(2, 'test activity', 0)]
    p = ProjectsDb(str(data_dir))
    p.update([project])

    cli('project', ['alias', 'test project'], input='test_alias')

    with open(config.path, 'r') as f:
        lines = f.readlines()

    assert 'test_alias = 1/2\n' in lines
Пример #9
0
def test_add_single_choice(cli, data_dir, config):
    project = Project(1, 'test project', Project.STATUS_ACTIVE)
    project.activities = [Activity(2, 'test activity', 0)]
    p = ProjectsDb(str(data_dir))
    p.update([project])

    cli('project', ['alias', 'test project'], input='test_alias')

    with open(config.path, 'r') as f:
        lines = f.readlines()

    assert 'test_alias = 1/2\n' in lines
Пример #10
0
    def test_add_multiple_choices(self):
        p1 = Project(1, 'test project', Project.STATUS_ACTIVE)
        p1.activities = [Activity(2, 'test activity', 0)]
        p2 = Project(2, 'test project 2', Project.STATUS_ACTIVE)
        p2.activities = [Activity(3, 'test activity 2', 0)]
        p = ProjectsDb(self.taxi_dir)
        p.update([p1, p2])

        self.run_project_command(['alias', 'test project'],
                                 input='1\ntest_alias')

        with open(self.config_file, 'r') as f:
            self.assertIn('test_alias = 2/3\n', f.readlines())
Пример #11
0
def test_project_status(cli, config, data_dir):
    config.set_dict({
        'test_aliases': {
            'alias_not_started': '0/0',
            'alias_active': '1/0',
            'alias_finished': '2/0',
            'alias_cancelled': '3/0',
        }
    })
    projects_db = ProjectsDb(str(data_dir))

    project_not_started = Project(0, 'not started project',
                                  Project.STATUS_NOT_STARTED)
    project_not_started.backend = 'test'
    project_not_started.activities.append(Activity(0, 'activity', 0))
    project_active = Project(1, 'active project', Project.STATUS_ACTIVE)
    project_active.backend = 'test'
    project_active.activities.append(Activity(0, 'activity', 0))
    project_finished = Project(2, 'finished project',
                               Project.STATUS_FINISHED)
    project_finished.backend = 'test'
    project_finished.activities.append(Activity(0, 'activity', 0))
    project_cancelled = Project(3, 'cancelled project',
                                Project.STATUS_CANCELLED)
    project_cancelled.backend = 'test'
    project_cancelled.activities.append(Activity(0, 'activity', 0))
    projects_db.update([
        project_not_started, project_active, project_finished,
        project_cancelled
    ])

    cli('clean-aliases', ['--yes'])

    settings = Settings(config.path)
    assert list(settings.get_aliases().keys()) == ['alias_active']
Пример #12
0
def test_add_multiple_choices(cli, data_dir, config):
    p1 = Project(1, 'test project', Project.STATUS_ACTIVE)
    p1.activities = [Activity(2, 'test activity', 0)]
    p2 = Project(2, 'test project 2', Project.STATUS_ACTIVE)
    p2.activities = [Activity(3, 'test activity 2', 0)]
    p = ProjectsDb(str(data_dir))
    p.update([p1, p2])

    cli('project', ['alias', 'test project'], input='1\ntest_alias')

    with open(config.path, 'r') as f:
        lines = f.readlines()

    assert 'test_alias = 2/3\n' in lines
Пример #13
0
    def get_projects(self):
        projects_list = []

        for (project, activities) in self.projects.iteritems():
            p = Project(project, 'foo', 1, 'bar', '1000')
            p.start_date = None
            p.end_date = None

            for activity in activities:
                p.add_activity(activity)

            projects_list.append(p)

        return projects_list
Пример #14
0
    def get_projects(self):
        projects_list = []

        for project_name, count in self.settings.config.items('tempo_projects'):
            project_name = project_name.upper()
            p = Project(self.get_project_hash(project_name), project_name, Project.STATUS_ACTIVE)
            for i in range(1, int(count) + 1):
                name = f'{project_name}-{i}'
                a = Activity(i, name, 0)
                p.add_activity(a)
                p.aliases[name] = a.id

            projects_list.append(p)

        return projects_list
Пример #15
0
 def setUp(self):
     super(ShowCommandTestCase, self).setUp()
     self.projects_db = ProjectsDb(self.taxi_dir)
     projects_list = []
     project = Project(42, 'not started project',
                       Project.STATUS_NOT_STARTED)
     project.backend = 'test'
     project.activities.append(Activity(1, 'activity 1', 0))
     project.activities.append(Activity(2, 'activity 2', 0))
     projects_list.append(project)
     project = Project(123, 'my project', Project.STATUS_ACTIVE)
     project.backend = 'test'
     project.activities.append(Activity(456, 'my activity', 0))
     projects_list.append(project)
     self.projects_db.update(projects_list)
Пример #16
0
    def overwrite_alias(self, alias, mapping, retry=True):
        mapping_name = Project.tuple_to_str(mapping)

        if retry:
            choices = 'y/n/R(etry)'
            default_choice = 'r'
            choice_regexp = r'^[ynr]$'
        else:
            choices = 'y/N'
            default_choice = 'n'
            choice_regexp = r'^[yn]$'

        s = (u"The alias `%s` is already mapped to `%s`.\nDo you want to "
             "overwrite it [%s]? " % (alias, mapping_name, choices))

        overwrite = terminal.select_string(
            s, choice_regexp, re.I, default_choice
        )

        if overwrite == 'n':
            return False
        elif overwrite == 'y':
            return True

        return None
Пример #17
0
    def get_projects(self):
        projects_list = []

        for project_name, count in self.settings.config.items('jira_projects'):
            project_name = project_name.upper()
            p = Project(project_name, f"[JIRA] {project_name}", Project.STATUS_ACTIVE,
                    description=f"JIRA Project {project_name} (created by backend {self.name})"
            )
            for i in range(1, int(count) + 1):
                name = f"{project_name}-{i}"
                a = Activity(i, name)
                p.add_activity(a)
                p.aliases[name] = a.id

            projects_list.append(p)

        return projects_list
Пример #18
0
def projects_db(data_dir):
    projects_db = ProjectsDb(str(data_dir))
    projects_list = []

    project = Project(42, 'not started project',
                      Project.STATUS_NOT_STARTED)
    project.backend = 'test'
    projects_list.append(project)

    project = Project(43, 'active project',
                      Project.STATUS_ACTIVE)
    project.backend = 'test'
    project.activities.append(Activity(1, 'activity 1', 0))
    project.activities.append(Activity(2, 'activity 2', 0))
    projects_list.append(project)

    project = Project(44, '2nd active project',
                      Project.STATUS_ACTIVE)
    project.backend = 'test'
    project.activities.append(Activity(1, 'activity 1', 0))
    projects_list.append(project)

    projects_db.update(projects_list)

    return projects_db
Пример #19
0
    def get_projects(self):
        projects_url = self.get_api_url('/projects/')

        try:
            response = self._session.get(projects_url)
            projects = response.json()
        except ValueError:
            raise TaxiException(
                "Unexpected response from the server (%s).  Check your "
                "credentials" % response.content)
        projects_list = []
        date_attrs = (('start_date', 'startdate'), ('end_date', 'enddate'))

        for project in projects['data']:
            p = Project(int(project['id']), project['name'],
                        Project.STATUS_ACTIVE, project['description'],
                        project['budget'])

            for date_attr, proj_date in date_attrs:
                try:
                    date = datetime.strptime(project[proj_date],
                                             '%Y-%m-%d').date()
                except (ValueError, TypeError):
                    date = None

                setattr(p, date_attr, date)

            for activity in project['activities']:
                a = Activity(int(activity['id']), activity['name'],
                             activity['rate'])
                p.add_activity(a)

                if activity['alias']:
                    p.aliases[activity['alias']] = activity['id']

            projects_list.append(p)

        return projects_list
Пример #20
0
    def get_projects(self):
        projects_list = []

        p = Project(self.instance.upper(),
                    f"[{self.name}] {self.instance}",
                    Project.STATUS_ACTIVE,
                    description=f"{self.name} Project {self.instance}")

        r = requests.get(f"https://{self.hostname}/2.0/pr_project",
                         headers={
                             'Accept': 'application/json',
                             'Authorization': f"Bearer {self.api_key}"
                         })
        response = r.json()

        if r.status_code != 200:
            raise Exception(
                f"[{self.name}] API error: HTTP {r.status_code} - {response['message']}"
            )

        for project in response:
            name = f"{self.instance.upper()}-{project['id']}"

            # @todo Ideally, we should have a [bexio_active_project_states] configuration that lists only active
            # projects and filter here again against /2.0/pr_project_state
            if project['end_date'] is not None:
                if datetime.datetime.strptime(
                        project['end_date'],
                        '%Y-%m-%d %H:%M:%S') < datetime.datetime.today():
                    continue

            a = Activity(project['id'], project['name'])
            p.add_activity(a)
            p.aliases[name] = a.id

        projects_list.append(p)

        return projects_list
Пример #21
0
    def setUp(self):
        super(ProjectCommandTestCase, self).setUp()
        self.projects_db = ProjectsDb(self.taxi_dir)
        projects_list = []

        project = Project(42, 'not started project',
                          Project.STATUS_NOT_STARTED)
        project.backend = 'test'
        projects_list.append(project)

        project = Project(43, 'active project', Project.STATUS_ACTIVE)
        project.backend = 'test'
        project.activities.append(Activity(1, 'activity 1', 0))
        project.activities.append(Activity(2, 'activity 2', 0))
        projects_list.append(project)

        project = Project(44, '2nd active project', Project.STATUS_ACTIVE)
        project.backend = 'test'
        project.activities.append(Activity(1, 'activity 1', 0))
        projects_list.append(project)

        self.projects_db.update(projects_list)
Пример #22
0
def projects_db(data_dir):
    projects_db = ProjectsDb(str(data_dir))
    projects_list = []

    project = Project(42, 'not started project', Project.STATUS_NOT_STARTED)
    project.backend = 'test'
    projects_list.append(project)

    project = Project(43, 'active project', Project.STATUS_ACTIVE)
    project.backend = 'test'
    project.activities.append(Activity(1, 'activity 1', 0))
    project.activities.append(Activity(2, 'activity 2', 0))
    projects_list.append(project)

    project = Project(44, '2nd active project', Project.STATUS_ACTIVE)
    project.backend = 'test'
    project.activities.append(Activity(1, 'activity 1', 0))
    projects_list.append(project)

    projects_db.update(projects_list)

    return projects_db
Пример #23
0
    def get_projects(self):
        projects = self._request(path='/projects')
        activities_dict = self.get_activities()

        projects_list = []

        for project in projects:
            project = project['project']

            if not project['code']:
                continue

            p = Project(
                    int(project['id']), project['name'],
                    {
                        True: Project.STATUS_ACTIVE,
                        False: Project.STATUS_FINISHED
                    }[project['active']],
                    project['notes'],
                    project['budget']
            )

            if project['starts_on']:
                p.start_date = arrow.get(project['starts_on']).date()

            if project['ends_on']:
                p.start_date = arrow.get(project['ends_on']).date()

            activities = self._request(path='/projects/%s/task_assignments' % project['id'])

            for activity in activities:
                activity = activity['task_assignment']
                try:
                    a = Activity(int(activity['id']),
                                 activities_dict[activity['task_id']]['name'],
                                 activity['hourly_rate'])
                    p.add_activity(a)
                except ValueError:
                    logger.warn(
                        "Cannot import activity %s for project %s because "
                        "activity id is not an int" % (activity, p.id)
                    )

                activity_alias = '%s_%s' % (
                    project['code'],
                    slugify(activities_dict[activity['task_id']]['name'],
                            separator='_')
                )
                p.aliases[activity_alias] = activity['id']

            projects_list.append(p)

        return projects_list
Пример #24
0
    def test_add_multiple_choices(self):
        p1 = Project(1, 'test project', Project.STATUS_ACTIVE)
        p1.activities = [Activity(2, 'test activity', 0)]
        p2 = Project(2, 'test project 2', Project.STATUS_ACTIVE)
        p2.activities = [Activity(3, 'test activity 2', 0)]
        p = ProjectsDb(self.taxi_dir)
        p.update([p1, p2])

        self.run_project_command(['alias', 'test project'],
                                 input='1\ntest_alias')

        with open(self.config_file, 'r') as f:
            self.assertIn('test_alias = 2/3\n', f.readlines())
Пример #25
0
    def _add_alias(self, alias_name, mapping):
        project_activity = Project.str_to_tuple(mapping)

        if project_activity is None:
            raise UsageError("The mapping must be in the format xxxx/yyyy")

        if self.settings.activity_exists(alias_name):
            existing_mapping = self.settings.get_aliases()[alias_name]
            confirm = self.view.overwrite_alias(alias_name, existing_mapping,
                                                False)

            if not confirm:
                return

        self.settings.add_alias(alias_name, project_activity[0],
                                project_activity[1])
        self.settings.write_config()

        self.view.alias_added(alias_name, project_activity)
Пример #26
0
def test_add_multiple_choices(cli, data_dir, config):
    p1 = Project(1, 'test project', Project.STATUS_ACTIVE)
    p1.activities = [Activity(2, 'test activity', 0)]
    p2 = Project(2, 'test project 2', Project.STATUS_ACTIVE)
    p2.activities = [Activity(3, 'test activity 2', 0)]
    p = ProjectsDb(str(data_dir))
    p.update([p1, p2])

    cli('project', ['alias', 'test project'], input='1\ntest_alias')

    with open(config.path, 'r') as f:
        lines = f.readlines()

    assert 'test_alias = 2/3\n' in lines
Пример #27
0
    def run(self):
        # 2 arguments, add a new alias
        if self.mode == self.MODE_ADD_ALIAS:
            self._add_alias(self.alias, self.mapping)
        # 1 argument, display the alias or the project id/activity id tuple
        elif self.mode == self.MODE_SHOW_MAPPING:
            mapping = Project.str_to_tuple(self.alias)

            if mapping is not None:
                for m in self.settings.search_aliases(mapping):
                    self.view.mapping_detail(m, self.projects_db.get(m[1][0]))
            else:
                self.mode = self.MODE_LIST_ALIASES

        # No argument, display the mappings
        if self.mode == self.MODE_LIST_ALIASES:
            for m in self.settings.search_mappings(self.alias):
                self.view.alias_detail(
                    m,
                    self.projects_db.get(m[1][0]) if m[1] is not None else None
                )
Пример #28
0
    def test_project_status(self):
        projects_db = ProjectsDb(self.taxi_dir)

        project_not_started = Project(0, 'not started project',
                                      Project.STATUS_NOT_STARTED)
        project_not_started.backend = 'test'
        project_not_started.activities.append(Activity(0, 'activity', 0))
        project_active = Project(1, 'active project', Project.STATUS_ACTIVE)
        project_active.backend = 'test'
        project_active.activities.append(Activity(0, 'activity', 0))
        project_finished = Project(2, 'finished project',
                                   Project.STATUS_FINISHED)
        project_finished.backend = 'test'
        project_finished.activities.append(Activity(0, 'activity', 0))
        project_cancelled = Project(3, 'cancelled project',
                                    Project.STATUS_CANCELLED)
        project_cancelled.backend = 'test'
        project_cancelled.activities.append(Activity(0, 'activity', 0))
        projects_db.update([
            project_not_started, project_active, project_finished,
            project_cancelled
        ])

        self.run_command('clean-aliases', args=['--yes'])

        settings = Settings(self.config_file)
        self.assertEqual(list(settings.get_aliases().keys()), ['alias_active'])
Пример #29
0
    def alias_added(self, alias, mapping):
        mapping_name = Project.tuple_to_str(mapping)

        self.msg(u"The following alias has been added to your configuration "
                 "file: %s = %s" % (alias, mapping_name))
Пример #30
0
def test_project_status(cli, config, data_dir):
    config.set_dict({
        'test_aliases': {
            'alias_not_started': '0/0',
            'alias_active': '1/0',
            'alias_finished': '2/0',
            'alias_cancelled': '3/0',
        }
    })
    projects_db = ProjectsDb(str(data_dir))

    project_not_started = Project(0, 'not started project',
                                  Project.STATUS_NOT_STARTED)
    project_not_started.backend = 'test'
    project_not_started.activities.append(Activity(0, 'activity', 0))
    project_active = Project(1, 'active project', Project.STATUS_ACTIVE)
    project_active.backend = 'test'
    project_active.activities.append(Activity(0, 'activity', 0))
    project_finished = Project(2, 'finished project', Project.STATUS_FINISHED)
    project_finished.backend = 'test'
    project_finished.activities.append(Activity(0, 'activity', 0))
    project_cancelled = Project(3, 'cancelled project',
                                Project.STATUS_CANCELLED)
    project_cancelled.backend = 'test'
    project_cancelled.activities.append(Activity(0, 'activity', 0))
    projects_db.update([
        project_not_started, project_active, project_finished,
        project_cancelled
    ])

    cli('clean-aliases', ['--yes'])

    settings = Settings(config.path)
    assert list(settings.get_aliases().keys()) == ['alias_active']
Пример #31
0
    def get_projects(self):
        projects_url = self.get_full_url('project/all.json')

        response = self._session.get(projects_url).json()
        projects = response['command']['projects']['project']
        activities = response['command']['activities']['activity']
        activities_dict = {}

        for activity in activities:
            a = Activity(int(activity['id']), activity['name'],
                         activity['rate_eur'])
            activities_dict[a.id] = a

        projects_list = []
        i = 0

        for project in projects:
            p = Project(int(project['id']), project['name'],
                        project['status'], project['description'],
                        project['budget'])

            try:
                p.start_date = datetime.strptime(
                    project['startdate'], '%Y-%m-%d').date()
            except ValueError:
                p.start_date = None

            try:
                p.end_date = datetime.strptime(
                    project['enddate'], '%Y-%m-%d').date()
            except ValueError:
                p.end_date = None

            i += 1

            activities = project['activities']['activity']

            # Sometimes the activity list just contains an @attribute
            # element, in this case we skip it
            if isinstance(activities, dict):
                continue

            # If there's only 1 activity, this won't be a list but a simple
            # element
            if not isinstance(activities, list):
                activities = [activities]

            for activity in activities:
                try:
                    if int(activity) in activities_dict:
                        p.add_activity(activities_dict[int(activity)])
                except ValueError:
                    logger.warn(
                        "Cannot import activity %s for project %s because "
                        "activity id is not an int" % (activity, p.id)
                    )

            if 'activity_aliases' in project and project['activity_aliases']:
                for alias, mapping in project['activity_aliases'].items():
                    p.aliases[alias] = int(mapping)

            projects_list.append(p)

        return projects_list