Exemplo n.º 1
0
def auth_redmine(username, password):
    redmine = Redmine('http://ticket.wise-paas.com', username=username, password=password)
    try:
        redmine.auth()
        return "ok"
    except Exception as e:
        return "auth failed: " + str(e)
    def sync_data_from_redmine(self):
        params = self.env['ir.config_parameter'].sudo()
        if not any([params.get_param('redmine_timesheet.redmine_api_key'),
                    params.get_param('redmine_timesheet.redmine_url')]):
            raise UserError(_('Please set redmine api credentials'))

        try:
            from redminelib import Redmine
        except ImportError:
            raise UserError(_('Missing python dependency, check https://python-redmine.com/'))

        redmine = Redmine(params.get_param('redmine_timesheet.redmine_url'),
                          key=params.get_param('redmine_timesheet.redmine_api_key'))
        try:
            redmine.auth()
        except Exception as e:
            raise UserError(_(e))

        _logger.info('Connect with Redmine')

        for project in list(redmine.project.all()):
            proj_obj = self._get_or_create_project(project)
            _logger.info("Project: {} - been find in odoo ".format(proj_obj.name))

            for task in self._get_tasks_from_project(project):
                task_obj = self._get_or_create_task(task, proj_obj)
                _logger.info(u"Task: {} - been find in odoo ".format(task_obj.name))

                for time_entry in self._get_time_entrys_from_task(task):
                    self._get_or_create_timesheet(task_obj, time_entry, proj_obj)
Exemplo n.º 3
0
    def set_key(self, bot: Bot, update: Update, session: Session):
        tg_user = update.message.from_user

        user = find_user(session, tg_user.id)
        if user is None:
            update.message.reply_text(m.NOT_FOUND_USER)
            return tg.ConversationHandler.END

        try:
            redmine = Redmine(url=self.config.redmine_host,
                              key=update.message.text)
            redmine.auth()
        except AuthError:
            update.message.reply_text(m.INVALID_REDMINE_KEY)

            user.redmine_user.key = ''

            session.add(user.redmine_user)
            session.commit()
            return tg.ConversationHandler.END

        user.redmine_user.key = update.message.text

        session.add(user.redmine_user)
        session.commit()

        update.message.reply_text(m.DONE_REDMINE_SETTINGS)
        update.message.reply_text(m.WELCOME_MESSAGES)

        return tg.ConversationHandler.END
Exemplo n.º 4
0
    def check_authkey(self, authkey):
        """Check authorization key.

        :param string authkey: Authorization key to check
        :return: True if authorization key is correct
        """
        redmine = Redmine(url=self.url, key=authkey)
        try:
            redmine.auth()
            return True
        except AuthError:
            return False
Exemplo n.º 5
0
def auth_user(username, password, teste=True, verify=True):
    url = URLHM if teste else URL
    fiscaliza = Redmine(
        url, username=username, password=password, requests={"verify": verify}
    )
    try:
        fiscaliza.auth()
        return fiscaliza

    except ConnectionError:
        console.print(
            "[bold red] Sem resposta do Servidor. Verifique: Conexão com a Internet | VPN  | Fiscaliza fora do ar"
        )
Exemplo n.º 6
0
    def get_all_time_entry(self, user, spent_on=None):
        """Get all time entry from redmine for user.

        :param tracktime.models.User user:
        :param spent_on:
        :rtype: list

        """
        redmine = Redmine(url=self.url, key=user.authkey)
        try:
            time_entries = list()
            r_user_id = redmine.auth().id
            r_time_entries = redmine.time_entry.filter(user_id=r_user_id,
                                                       spent_on=spent_on)
            for r_time_entry in r_time_entries:
                if 'issue' in dir(r_time_entry):
                    time_entry = TimeEntry(id=r_time_entry.id,
                                           user=user,
                                           issue_id=r_time_entry.issue.id,
                                           spent_on=r_time_entry.spent_on,
                                           hours=r_time_entry.hours,
                                           comments=r_time_entry.comments)
                    time_entries.append(time_entry)
            return time_entries
        except AuthError:
            return list()
Exemplo n.º 7
0
    def spent_on(self, bot, update, user_data, session):
        tg_message = update.callback_query.message

        user_data['spent_on'] = dt.datetime.strptime(
            update.callback_query.data, '%Y-%m-%d').date()

        user = find_user(session, update.effective_user.id)
        if user is None or user.redmine_user.empty():
            tg_message.reply_text(m.NOT_FOUND_USER)
            return tg.ConversationHandler.END

        redmine = Redmine(url=self.config.redmine_host,
                          key=user.redmine_user.key)

        issues = self.config.redmine_general_issue
        for issue in redmine.auth().issues:
            issues[issue.id] = issue.subject
        user_data['issues'] = issues

        buttons = [
            InlineKeyboardButton(name, callback_data=str(id))
            for id, name in issues.items()
        ]
        reply_markup = InlineKeyboardMarkup(build_menu(buttons, n_cols=1))
        bot.edit_message_text(m.SET_ISSUE.format(
            self.track_task_to_str(user_data)),
                              chat_id=tg_message.chat.id,
                              message_id=tg_message.message_id,
                              reply_markup=reply_markup)
        return SET_ISSUE
    def _check_redmine_authorization(self, vals):
        _logger.info(self.env['ir.config_parameter'].sudo().get_param(
            'redmine_timesheet.redmine_url'))
        try:
            from redminelib import Redmine
        except ImportError:
            raise UserError(
                _('Missing python dependency, check https://python-redmine.com/'
                  ))

        redmine = Redmine(vals.get('redmine_url'),
                          key=vals.get('redmine_api_key'))

        try:
            redmine.auth()
        except Exception as e:
            raise UserError(_(e))
Exemplo n.º 9
0
class RedmineWrapper(object):

    redmine: Redmine = None

    def connect(self, user, pswd):
        self.redmine = Redmine("https://redmine.sparc-npo.ru",
                               username=user,
                               password=pswd,
                               requests={'verify': False})
        try:
            auth = self.redmine.auth()
        except AuthError:
            raise Exception('Invalid login or password provided')

    def getIssues(self, projectname, versionname):
        projects = [
            project for project in self.redmine.project.all()
            if project.name == projectname
        ]  # Все проекты с заданным именем
        if not projects: return None

        versions = [
            list(project.versions.filter(name=versionname))
            for project in projects
        ]  # Все версии с заданным именем для каждого из найденных проектов
        versions = list(
            chain(*versions)
        )  # слияние всех найденных версий в один общий список. Если получилась не одна, значит что-то не так
        if len(versions) != 1: return None

        versionid = versions[0].id

        issues = []
        for resource in self.redmine.issue.filter(fixed_version_id=versionid,
                                                  status_id='*'):
            issue = ParseResource(resource)
            issues.append(issue)
        issues.sort(key=lambda issue: (issue.Result, issue.Weight),
                    reverse=True)
        return issues
Exemplo n.º 10
0
class RedMineManager:
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.__valid_redmine_login = None
        self.projects_list = None
        self.all_projects = None
        self.issues_dict = None
        self.redmine = Redmine(constants.REDMINE_URL,
                               username=self.username,
                               password=self.password)

    def validate_login(self):
        """
        Validates the login credentials of the user.
        """
        is_user_valid = None
        try:
            if self.redmine.auth():
                self.__valid_redmine_login = True
                is_user_valid = True
        except Exception as error:
            print(error)
        return is_user_valid

    def get_projects(self):
        """
        Gets the list of projects.
        :return: projects_list: A list of names of all the projects.
        """
        if self.__valid_redmine_login:
            self.all_projects = self.redmine.project.all()
            self.projects_list = [
                project.name for project in self.all_projects
            ]
            projects_list = self.projects_list
            return projects_list

    def get_project_trackers(self, project_name):
        """
        Gets all the trackers added to the project in redmine.
        :param project_name: Name of the project.
        :return: trackers_list: List of all the trackers in the project.
        """
        if self.__valid_redmine_login:
            trackers_list = []
            all_projects = self.redmine.project.all()
            for project in all_projects:
                if project.name == project_name:
                    for tracker in project.trackers:
                        trackers_list.append(tracker.name)
                    break
            return trackers_list

    def total_projects_count(self):
        """
        Gets the total number of projects.
        :return: total_projects: A total count of all the projects.
        """
        total_projects = str(len(self.get_projects()))
        return total_projects

    def get_issues(self):
        """
        Gets all the issues created by the user.
        :return: issues_dict: A dictionary that contains issues created by the user along with some of its information.
        """
        if self.__valid_redmine_login:
            self.issues_dict = {}
            for issue in self.redmine.issue.all():
                issue_dict = {
                    'subject': issue.subject,
                    'status': str(issue.status),
                    'priority': str(issue.priority),
                    'description': issue.description
                }
                self.issues_dict[issue.id] = issue_dict
        issues_dict = self.issues_dict
        return issues_dict

    def total_issues_count(self):
        """
        Gets the total number of issues created by the user.
        :return: total_issues: A total count of all the issues.
        """
        if self.__valid_redmine_login:
            total_issues = str(len(self.get_issues()))
            return total_issues

    def total_issues_resolved_count(self):
        """
        Gets the total number of issues whose status is resolved.
        :return: total_resolved: A total count of issues whose status is resolved.
        """
        if self.__valid_redmine_login:
            total_resolved = 0
            for issue_key in self.issues_dict:
                if self.issues_dict[issue_key][
                        'status'] == constants.RESOLVED_STATUS:
                    total_resolved += 1
            total_resolved = str(total_resolved)
            return total_resolved

    def total_issues_pending_count(self):
        """
        Gets the total number of issues whose status is not resolved.
        :return: total_pending: A total count of issues whose status is not resolved.
        """
        if self.__valid_redmine_login:
            total_pending = 0
            for issue_key in self.issues_dict:
                if self.issues_dict[issue_key][
                        'status'] != constants.RESOLVED_STATUS:
                    total_pending += 1
            total_pending = str(total_pending)
            return total_pending

    def create_new_issue(self, project_name, tracker_name, subject,
                         description, priority_id):
        """
        Creates a new issue in redmine.
        :param project_name: Name of the project.
        :param tracker_name: Name of the tracker.
        :param subject: Subject of the issue.
        :param description: Description of the issue.
        :param priority_id: Priority ID for the issue.
        """
        if self.__valid_redmine_login:
            for project in self.all_projects:
                if project.name == project_name:
                    self.redmine.issue.create(project_id=project.id,
                                              tracker_name=tracker_name,
                                              subject=subject,
                                              description=description,
                                              priority_id=priority_id)
                    break

    def clear_data_on_logout(self):
        """
        Reassigns variables to None.
        """
        self.projects_list = None
        self.issues_dict = None
        self.redmine = None
        self.__valid_redmine_login = None
Exemplo n.º 11
0
class Redmine(Tracker):
    def __init__(self, url, token=None, login=None,
                 password=None):
        if token is None and (login is None or password is None):
            raise AttributeError
        self.api = None  # type: RedmineLib
        if token is None:
            self.api = RedmineLib(url, username=login.encode('utf-8'), password=password.encode('utf-8'))
        else:
            self.api = RedmineLib(url, key=token)
        self.auth = self.__is_auth()

    def __is_auth(self) -> bool:
        try:
            auth = self.api.auth()
        except AuthError:
            auth = None
        return auth is not None

    @staticmethod
    def as_dict(obj):
        return obj.__dict__.get('_decoded_attrs')

    def res_to_list(self, res) -> List[Any]:
        return [self.as_dict(item) for item in res if res is not None and item is not None]

    def __get_project(self, id_or_code):
        if self.auth:
            try:
                project = self.api.project.get(id_or_code)
            except ResourceNotFoundError:
                return None
            return Project(id=project.id, code=project.identifier, name=project.name)

    def __filter_activities(self, filter) -> Optional[List[Activity]]:
        if self.auth:
            try:
                activities = self.api.time_entry.filter(**filter)
            except ResourceNotFoundError:
                return None
            result = []
            for item in activities:
                item = self.as_dict(item)
                comment = item.get('comments') or ''
                if comment == '':
                    comment = None
                result.append(
                    Activity(date=dt.datetime.strptime(item.get('spent_on'), '%Y-%m-%d').date(),
                             time=item.get('hours'),
                             id=item.get('id'),
                             user_id=item.get('user').get('id'),
                             task_id=item.get('issue').get('id'),
                             category_id=item.get('activity').get('id'),
                             project_id=item.get('project').get('id'),
                             comment=comment))
            return result

    ######################################### Tracker interface ########################################################

    def get_tracker_type(self) -> Optional[str]:
        """
        Возвращает тип трекера
        """
        return 'redmine'

    def is_auth(self) -> bool:
        """
        Проверяет, авторизован ли пользователь на трекере
        """
        return self.auth

    def get_api_key(self) -> Optional[str]:
        """
        Получает api_key пользователя для трекера, если трекер имеет такую возможность
        :return: возвращает api_key или None
        """
        if self.auth:
            return self.api.auth().api_key

    def get_user_id(self) -> Optional[int]:
        """
        Получает id пользователя на трекере, если он авторизован
        :return: возвращает user_id или None
        """
        if self.auth:
            return self.api.auth().id

    def list_categories(self) -> Optional[List[Category]]:
        """
        Запрашивает список категорий активностей у трекера
        :return: возвращает список категорий или None
        """
        if self.auth:
            categories = self.api.enumeration.filter(resource='time_entry_activities')
            categories = self.res_to_list(categories)
            return [Category(id=category['id'], name=category['name'], default=category.get('is_default', False)) for
                    category in categories]

    def list_projects(self) -> Optional[List[Project]]:
        """
        Запрашивает список проектов у трекера
        :return: возвращает список проектов или None
        """
        if self.auth:
            projects = self.api.project.all()
            return [Project(id=project.id, code=project.identifier, name=project.name) for project in projects]

    def get_project_by_id(self, project_id: int) -> Optional[Project]:
        """
        Запрашивает у трекера проект по id
        :param project_id: id запрашиваемого проекта
        :return: возвращает Project или None
        """
        return self.__get_project(project_id)

    def get_project_by_code(self, project_code: str) -> Optional[Project]:
        """
        Запрашивает у трекера проект по коду
        :param project_code: code запрашиваемого проекта
        :return: возвращает Project или None
        """
        return self.__get_project(project_code)

    def get_project_by_name(self, project_name: str) -> Optional[Project]:
        """
        Запрашивает у трекера проект по имени
        :param project_name: name запрашиваемого проекта
        :return: возвращает Project или None
        """
        if self.auth:
            for project in self.list_projects():
                if project.name == project_name:
                    return project

    def get_task_by_id(self, task_id: int) -> Optional[Task]:
        """
        Запрашивает у трекера задачу по id, если задачи поддерживаются трекером
        :param task_id: id запрашиваемой задачи
        :return: возвращает Task или None
        """
        if self.auth:
            try:
                task = self.api.issue.get(task_id)
            except (ResourceNotFoundError, ForbiddenError):
                return None
            return Task(id=task.id, name=task.subject, project_id=task.project.id, project_name=task.project.name,
                        tracker_name=task.tracker.name, status=task.status.name)

    def list_tasks_in_project(self, project_id: int, all: bool = False) -> Optional[List[Task]]:
        """
        Запрашивает у трекера список задач по id проекта, если задачи поддерживаются трекером
        :param project_id: id проекта
        :param all: возвращать все задачи. По-умолчанию возвращает только открытые
        :return: возвращает список задач или None
        """
        if self.auth:
            try:
                if all:
                    tasks = self.api.issue.filter(project_id=project_id, status_id='*')
                else:
                    tasks = self.api.issue.filter(project_id=project_id)
            except ResourceNotFoundError:
                return None
            return [Task(id=task.id, name=task.subject, project_id=task.project.id, status=task.status.name) for task in
                    tasks]

    def list_activities_in_date(self, date: dt.date, user_id: int = None) -> Optional[List[Activity]]:
        """
        Запрашивает у трекера список активностей по дате
        :param user_id:
        :param date: дата
        :return: возвращает список активностей или None
        """
        return self.list_activities_in_date_interval(date, date, user_id)

    def list_activities_in_date_interval(self, date_start: dt.date, date_end: dt.date, user_id: int = None) -> Optional[
        List[Activity]]:
        """
        Запрашивает у трекера список активностей в интервале дат
        :param user_id:
        :param date_start: начальная дата
        :param date_end: конечная дата
        :return: возвращает список активностей или None
        """
        return self.__filter_activities({'from_date': date_start, 'to_date': date_end, 'user_id': user_id})

    def list_activities_in_task(self, task_id: int) -> Optional[List[Activity]]:
        """
        Запрашивает у трекера список активностей по id задачи, если задачи поддерживаются трекером
        :param task_id: id задачи
        :return: возвращает список активностей или None
        """
        return self.__filter_activities({'issue_id': task_id})

    def list_activities_in_project(self, project_id: int) -> Optional[List[Activity]]:
        """
        Запрашивает у трекера список активностей по id проекта
        :param project_id: id проекта
        :return: возвращает список активностей или None
        """
        return self.__filter_activities({'project_id': project_id})

    def new_activity(self, activity: Activity) -> Optional[int]:
        """
        Создает новую активность на трекере
        :param activity: активность
        :return: возвращает activity_id созданной активности, или None, в случае неудачи
        """
        time_entry = self.api.time_entry.new()
        time_entry.issue_id = activity.task_id
        time_entry.spent_on = activity.date
        time_entry.hours = activity.time
        time_entry.activity_id = activity.category_id
        time_entry.comments = activity.comment
        time_entry.save()
        return time_entry.id

    ######################################### end Tracker interface ####################################################

    def get_all_projects(self):
        return self.api.project.all()

    def get_all_tasks(self):
        return self.api.issue.all()

    def get_api(self):
        return self.api