예제 #1
0
파일: github.py 프로젝트: AloisMahdal/did
    def search(self, query):
        """ Perform GitHub query """
        result = []
        url = self.url + "/" + query + f"&per_page={PER_PAGE}"

        while True:
            # Fetch the query
            log.debug(f"GitHub query: {url}")
            try:
                response = requests.get(url, headers=self.headers)
                log.debug(f"Response headers:\n{response.headers}")
            except requests.exceptions.RequestException as error:
                log.debug(error)
                raise ReportError(f"GitHub search on {self.url} failed.")

            # Parse fetched json data
            try:
                data = json.loads(response.text)["items"]
                result.extend(data)
            except requests.exceptions.JSONDecodeError as error:
                log.debug(error)
                raise ReportError(f"GitHub JSON failed: {response.text}.")

            # Update url to the next page, break if no next page provided
            if 'next' in response.links:
                url = response.links['next']['url']
            else:
                break

        log.debug("Result: {0} fetched".format(listed(len(result), "item")))
        log.data(pretty(result))
        return result
예제 #2
0
    def __init__(self, option, name=None, parent=None, user=None):
        """ Process config, prepare investigator, construct stats """

        # Check Request Tracker instance url and custom prefix
        StatsGroup.__init__(self, option, name, parent, user)
        config = dict(Config().section(option))
        try:
            self.url = config["url"]
        except KeyError:
            raise ReportError(
                "No url in the [{0}] section".format(option))
        try:
            self.prefix = config["prefix"]
        except KeyError:
            raise ReportError(
                "No prefix set in the [{0}] section".format(option))

        # Save Ticket class as attribute to allow customizations by
        # descendant class and set up the RequestTracker investigator
        self.ticket = Ticket
        self.request_tracker = RequestTracker(parent=self)
        # Construct the list of stats
        self.stats = [
            ReportedTickets(option=option + "-reported", parent=self),
            ResolvedTickets(option=option + "-resolved", parent=self),
            ]
예제 #3
0
 def __init__(self, option, name=None, parent=None, user=None):
     name = "Tickets in {0}".format(option)
     StatsGroup.__init__(self, option, name, parent, user)
     # Initialize the server proxy
     config = dict(Config().section(option))
     if "url" not in config:
         raise ReportError(
             "No trac url set in the [{0}] section".format(option))
     self.url = re.sub("/rpc$", "", config["url"])
     self.proxy = xmlrpc.client.ServerProxy(self.url + "/rpc")
     # Make sure we have prefix set
     if "prefix" not in config:
         raise ReportError(
             "No prefix set in the [{0}] section".format(option))
     self.prefix = config["prefix"]
     # Create the list of stats
     self.stats = [
         TracCreated(option=option + "-created",
                     parent=self,
                     name="Tickets created in {0}".format(option)),
         TracAccepted(option=option + "-accepted",
                      parent=self,
                      name="Tickets accepted in {0}".format(option)),
         TracUpdated(option=option + "-updated",
                     parent=self,
                     name="Tickets updated in {0}".format(option)),
         TracClosed(option=option + "-closed",
                    parent=self,
                    name="Tickets closed in {0}".format(option)),
     ]
예제 #4
0
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config["url"]
     except KeyError:
         raise ReportError(
             "No GitLab url set in the [{0}] section".format(option))
     # Check authorization token
     try:
         self.token = config["token"]
     except KeyError:
         raise ReportError(
             "No GitLab token set in the [{0}] section".format(option))
     # Check SSL verification
     try:
         self.ssl_verify = bool(
             distutils.util.strtobool(config["ssl_verify"]))
     except KeyError:
         self.ssl_verify = GITLAB_SSL_VERIFY
     if not self.ssl_verify:
         requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
     self.gitlab = GitLab(self.url, self.token, self.ssl_verify)
     # Create the list of stats
     self.stats = [
         IssuesCreated(option=option + "-issues-created",
                       parent=self,
                       name="Issues created on {0}".format(option)),
         IssuesCommented(option=option + "-issues-commented",
                         parent=self,
                         name="Issues commented on {0}".format(option)),
         IssuesClosed(option=option + "-issues-closed",
                      parent=self,
                      name="Issues closed on {0}".format(option)),
         MergeRequestsCreated(
             option=option + "-merge-requests-created",
             parent=self,
             name="Merge requests created on {0}".format(option)),
         MergeRequestsCommented(
             option=option + "-merge-requests-commented",
             parent=self,
             name="Issues commented on {0}".format(option)),
         MergeRequestsApproved(
             option=option + "-merge-requests-approved",
             parent=self,
             name="Merge requests approved on {0}".format(option)),
         MergeRequestsClosed(
             option=option + "-merge-requests-closed",
             parent=self,
             name="Merge requests closed on {0}".format(option)),
     ]
예제 #5
0
    def get(self, path):
        """ Perform a GET request with GSSAPI authentication """
        # Generate token
        service_name = gssapi.Name('HTTP@{0}'.format(self.url.netloc),
                                   gssapi.NameType.hostbased_service)
        ctx = gssapi.SecurityContext(usage="initiate", name=service_name)
        data = b64encode(ctx.step()).decode()

        # Make the connection
        connection = httplib.HTTPSConnection(self.url.netloc, 443)
        log.debug("GET {0}".format(path))
        connection.putrequest("GET", path)
        connection.putheader("Authorization", "Negotiate {0}".format(data))
        connection.putheader("Referer", self.url_string)
        connection.endheaders()

        # Perform the request, convert response into lines
        response = connection.getresponse()
        if response.status != 200:
            raise ReportError(
                "Failed to fetch tickets: {0}".format(response.status))
        lines = response.read().decode("utf8").strip().split("\n")[1:]
        log.debug("Tickets fetched:")
        log.debug(pretty(lines))
        return lines
예제 #6
0
파일: confluence.py 프로젝트: stepnem/did
 def session(self):
     """ Initialize the session """
     if self._session is None:
         self._session = requests.Session()
         log.debug("Connecting to {0}".format(self.auth_url))
         # Disable SSL warning when ssl_verify is False
         if not self.ssl_verify:
             requests.packages.urllib3.disable_warnings(
                 InsecureRequestWarning)
         if self.auth_type == "basic":
             basic_auth = (self.auth_username, self.auth_password)
             response = self._session.get(self.auth_url,
                                          auth=basic_auth,
                                          verify=self.ssl_verify)
         else:
             gssapi_auth = HTTPSPNEGOAuth(mutual_authentication=DISABLED)
             response = self._session.get(self.auth_url,
                                          auth=gssapi_auth,
                                          verify=self.ssl_verify)
         try:
             response.raise_for_status()
         except requests.exceptions.HTTPError as error:
             log.error(error)
             raise ReportError(
                 "Confluence authentication failed. Try kinit.")
     return self._session
예제 #7
0
    def __init__(self, option, name=None, parent=None, user=None):
        StatsGroup.__init__(self, option, name, parent, user)
        self.config = dict(Config().section(option))
        if 'url' not in self.config:
            raise IOError(
                'No gerrit URL set in the [{0}] section'.format(option))
        self.repo_url = self.config['url']
        log.debug('repo_url = {0}'.format(self.repo_url))

        if "prefix" not in self.config:
            raise ReportError(
                "No prefix set in the [{0}] section".format(option))

        self.server_features = []
        if self.config.get('wip', True) == True:
            self.server_features.append('wip')

        self.stats = [
            AbandonedChanges(option=option + '-abandoned', parent=self),
            MergedChanges(option=option + '-merged', parent=self),
            SubmitedChanges(option=option + '-submitted', parent=self),
            WIPChanges(option=option + '-wip', parent=self),
            #AddedPatches(option=option + '-added-patches', parent=self),
            ReviewedChanges(option=option + '-reviewed', parent=self),
        ]
예제 #8
0
파일: jira.py 프로젝트: AloisMahdal/did
 def search(query, stats):
     """ Perform issue search for given stats instance """
     log.debug("Search query: {0}".format(query))
     issues = []
     # Fetch data from the server in batches of MAX_RESULTS issues
     for batch in range(MAX_BATCHES):
         response = stats.parent.session.get(
             "{0}/rest/api/latest/search?{1}".format(
                 stats.parent.url, urllib.parse.urlencode({
                     "jql": query,
                     "fields": "summary,comment",
                     "maxResults": MAX_RESULTS,
                     "startAt": batch * MAX_RESULTS})))
         data = response.json()
         if not response.ok:
             try:
                 error = " ".join(data["errorMessages"])
             except KeyError:
                 error = "unknown"
             raise ReportError(
                 f"Failed to fetch jira issues for query '{query}'. "
                 f"The reason was '{response.reason}' "
                 f"and the error was '{error}'.")
         log.debug("Batch {0} result: {1} fetched".format(
             batch, listed(data["issues"], "issue")))
         log.data(pretty(data))
         issues.extend(data["issues"])
         # If all issues fetched, we're done
         if len(issues) >= data["total"]:
             break
     # Return the list of issue objects
     return [Issue(issue, prefix=stats.parent.prefix) for issue in issues]
예제 #9
0
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config["url"]
     except KeyError:
         raise ReportError(
             "No github url set in the [{0}] section".format(option))
     # Check authorization token
     try:
         self.token = config["token"]
     except KeyError:
         self.token = None
     self.github = GitHub(self.url, self.token)
     # Create the list of stats
     self.stats = [
         IssuesCreated(
             option=option + "-issues-created", parent=self,
             name="Issues created on {0}".format(option)),
         IssuesClosed(
             option=option + "-issues-closed", parent=self,
             name="Issues closed on {0}".format(option)),
         PullRequestsCreated(
             option=option + "-pull-requests-created", parent=self,
             name="Pull requests created on {0}".format(option)),
         PullRequestsClosed(
             option=option + "-pull-requests-closed", parent=self,
             name="Pull requests closed on {0}".format(option)),
         PullRequestsReviewed(
             option=option + "-pull-requests-reviewed", parent=self,
             name="Pull requests reviewed on {0}".format(option)),
         ]
예제 #10
0
파일: redmine.py 프로젝트: psss/did
 def __init__(self, option, name=None, parent=None, user=None):
     name = "Redmine activity on {0}".format(option)
     super(RedmineStats, self).__init__(option=option,
                                        name=name,
                                        parent=parent,
                                        user=user)
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config["url"]
     except KeyError:
         raise ReportError(
             "No Redmine url set in the [{0}] section".format(option))
     try:
         self.activity_days = datetime.timedelta(config["activity_days"])
     except KeyError:
         # 30 is value of activity_days_default
         self.activity_days = datetime.timedelta(30)
     # Create the list of stats
     self.stats = [
         RedmineActivity(option="{0}-activity".format(option),
                         parent=self,
                         name="Redmine activity on {0}".format(option)),
     ]
예제 #11
0
    def get(self, path):
        """ Perform a GET request with Kerberos authentication """
        # Prepare Kerberos ticket granting ticket """
        _, ctx = kerberos.authGSSClientInit(
            'HTTP@{0}'.format(self.url.netloc))
        kerberos.authGSSClientStep(ctx, "")
        tgt = kerberos.authGSSClientResponse(ctx)

        # Make the connection
        connection = httplib.HTTPSConnection(self.url.netloc, 443)
        log.debug("GET {0}".format(path))
        connection.putrequest("GET", path)
        connection.putheader("Authorization", "Negotiate {0}".format(tgt))
        connection.putheader("Referer", self.url_string)
        connection.endheaders()

        # Perform the request, convert response into lines
        response = connection.getresponse()
        if response.status != 200:
            raise ReportError(
                "Failed to fetch tickets: {0}".format(response.status))
        lines = response.read().decode("utf8").strip().split("\n")[1:]
        log.debug("Tickets fetched:")
        log.debug(pretty(lines))
        return lines
예제 #12
0
 def session(self):
     """ Initialize the session """
     if self._session is None:
         self._session = requests.Session()
         log.debug("Connecting to {0}".format(self.auth_url))
         if self.auth_type == 'basic':
             data = {
                 "username": self.auth_username,
                 "password": self.auth_password
             }
             headers = {
                 "Content-type": "application/json",
                 "Accept": "application/json"
             }
             response = self._session.get(self.auth_url,
                                          headers=headers,
                                          data=data)
         else:
             gssapi_auth = HTTPSPNEGOAuth(mutual_authentication=DISABLED)
             response = self._session.get(self.auth_url, auth=gssapi_auth)
         try:
             response.raise_for_status()
         except requests.exceptions.HTTPError as error:
             log.error(error)
             raise ReportError('Jira authentication failed. Try kinit.')
     return self._session
예제 #13
0
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config['url']
     except KeyError:
         raise ReportError(
             'No Pagure url set in the [{0}] section'.format(option))
     # Check authorization token
     try:
         self.token = config['token']
     except KeyError:
         self.token = None
     self.pagure = Pagure(self.url, self.token)
     # Create the list of stats
     self.stats = [
         IssuesCreated(option=option + '-issues-created',
                       parent=self,
                       name='Issues created on {0}'.format(option)),
         IssuesClosed(option=option + '-issues-closed',
                      parent=self,
                      name='Issues closed on {0}'.format(option)),
         PullRequestsCreated(
             option=option + '-pull-requests-created',
             parent=self,
             name='Pull requests created on {0}'.format(option)),
         # FIXME: Blocked by https://pagure.io/pagure/issue/4329
         #            PullRequestsClosed(
         #                option=option + '-pull-requests-closed', parent=self,
         #                name='Pull requests closed on {0}'.format(option)),
     ]
예제 #14
0
 def get_user(self, username):
     query = 'users?username={0}'.format(username)
     result = self._get_gitlab_api_json(query)
     try:
         return result[0]
     except IndexError:
         raise ReportError(
             "Unable to find user '{0}' on GitLab.".format(username))
예제 #15
0
파일: trello.py 프로젝트: psss/did
    def __init__(self, option, name=None, parent=None, user=None):
        name = "Trello updates for {0}".format(option)
        super(TrelloStatsGroup, self).__init__(option=option,
                                               name=name,
                                               parent=parent,
                                               user=user)

        # map appropriate API methods to Classes
        filter_map = {
            'Boards': {},
            'Lists': {},
            'Cards': {
                'commentCard': TrelloCardsCommented,
                'updateCard': TrelloCardsUpdated,
                'updateCard:closed': TrelloCardsClosed,
                'updateCard:idList': TrelloCardsMoved,
                'createCard': TrelloCardsCreated
            },
            'Checklists': {
                'updateCheckItemStateOnCard': TrelloCheckItem
            }
        }
        self._session = None
        self.url = "https://trello.com/1"
        config = dict(Config().section(option))

        positional_args = ['apikey', 'token']
        if (not set(positional_args).issubset(set(config.keys()))
                and "user" not in config):
            raise ReportError(
                "No ({0}) or 'user' set in the [{1}] section".format(
                    listed(positional_args, quote="'"), option))

        optional_args = ["board_links", "apikey", "token"]
        for arg in optional_args:
            if arg not in config:
                config[arg] = ""

        # Skip API instance initialization when building options
        if self.options is None:
            trello = None
        else:
            trello = TrelloAPI(stats=self, config=config)

        try:
            filters = split(config["filters"])
        except KeyError:
            filters = DEFAULT_FILTERS
        for filt_group in sorted(filter_map):
            for filt in sorted(filter_map[filt_group]):
                if filters != [""] and filt not in filters:
                    continue
                self.stats.append(filter_map[filt_group][filt](trello=trello,
                                                               filt=filt,
                                                               option=option +
                                                               "-" + filt,
                                                               parent=self))
예제 #16
0
파일: jira.py 프로젝트: AloisMahdal/did
 def session(self):
     """ Initialize the session """
     if self._session is None:
         self._session = requests.Session()
         log.debug("Connecting to {0}".format(self.auth_url))
         # Disable SSL warning when ssl_verify is False
         if not self.ssl_verify:
             requests.packages.urllib3.disable_warnings(
                 InsecureRequestWarning)
         if self.auth_type == 'basic':
             basic_auth = (self.auth_username, self.auth_password)
             response = self._session.get(
                 self.auth_url, auth=basic_auth, verify=self.ssl_verify)
         elif self.auth_type == "token":
             self.session.headers["Authorization"] = f"Bearer {self.token}"
             response = self._session.get(
                 "{0}/rest/api/2/myself".format(self.url),
                 verify=self.ssl_verify)
         else:
             gssapi_auth = HTTPSPNEGOAuth(mutual_authentication=DISABLED)
             response = self._session.get(
                 self.auth_url, auth=gssapi_auth, verify=self.ssl_verify)
         try:
             response.raise_for_status()
         except requests.exceptions.HTTPError as error:
             log.error(error)
             raise ReportError(
                 "Jira authentication failed. Check credentials or kinit.")
         if self.token_expiration:
             response = self._session.get(
                 "{0}/rest/pat/latest/tokens".format(self.url),
                 verify=self.ssl_verify)
             try:
                 response.raise_for_status()
                 token_found = None
                 for token in response.json():
                     if token["name"] == self.token_name:
                         token_found = token
                         break
                 if token_found is None:
                    raise ValueError(
                         f"Can't check validity for the '{self.token_name}' "
                         f"token as it doesn't exist.")
                 from datetime import datetime
                 expiring_at = datetime.strptime(
                     token_found["expiringAt"], r"%Y-%m-%dT%H:%M:%S.%f%z")
                 delta = (
                     expiring_at.astimezone() - datetime.now().astimezone())
                 if delta.days < self.token_expiration:
                     log.warn(
                         f"Jira token '{self.token_name}' "
                         f"expires in {delta.days} days.")
             except (requests.exceptions.HTTPError,
                     KeyError, ValueError) as error:
                 log.warn(error)
     return self._session
예제 #17
0
파일: gitlab.py 프로젝트: thrix/did
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config["url"]
     except KeyError:
         raise ReportError(
             "No GitLab url set in the [{0}] section".format(option))
     # Check authorization token
     try:
         self.token = config["token"]
     except KeyError:
         raise ReportError(
             "No GitLab token set in the [{0}] section".format(option))
     self.gitlab = GitLab(self.url, self.token)
     # Create the list of stats
     self.stats = [
         IssuesCreated(option=option + "-issues-created",
                       parent=self,
                       name="Issues created on {0}".format(option)),
         IssuesCommented(option=option + "-issues-commented",
                         parent=self,
                         name="Issues commented on {0}".format(option)),
         IssuesClosed(option=option + "-issues-closed",
                      parent=self,
                      name="Issues closed on {0}".format(option)),
         MergeRequestsCreated(
             option=option + "-merge-requests-created",
             parent=self,
             name="Merge requests created on {0}".format(option)),
         MergeRequestsCommented(
             option=option + "-merge-requests-commented",
             parent=self,
             name="Issues commented on {0}".format(option)),
         MergeRequestsClosed(
             option=option + "-merge-requests-closed",
             parent=self,
             name="Merge requests closed on {0}".format(option)),
     ]
예제 #18
0
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check Bugzilla instance url
     try:
         self.url = config["url"]
     except KeyError:
         raise ReportError(
             "No bugzilla url set in the [{0}] section".format(option))
     # Make sure we have prefix set
     try:
         self.prefix = config["prefix"]
     except KeyError:
         raise ReportError(
             "No prefix set in the [{0}] section".format(option))
     # Check for customized list of resolutions
     try:
         self.resolutions = [
             resolution.lower()
             for resolution in split(config["resolutions"])
         ]
     except KeyError:
         self.resolutions = DEFAULT_RESOLUTIONS
     # Save Bug class as attribute to allow customizations by
     # descendant class and set up the Bugzilla investigator
     self.bug = Bug
     self.bugzilla = Bugzilla(parent=self)
     # Construct the list of stats
     self.stats = [
         FiledBugs(option=option + "-filed", parent=self),
         PatchedBugs(option=option + "-patched", parent=self),
         PostedBugs(option=option + "-posted", parent=self),
         FixedBugs(option=option + "-fixed", parent=self),
         ReturnedBugs(option=option + "-returned", parent=self),
         VerifiedBugs(option=option + "-verified", parent=self),
         CommentedBugs(option=option + "-commented", parent=self),
         SubscribedBugs(option=option + "-subscribed", parent=self),
         ClosedBugs(option=option + "-closed", parent=self),
     ]
예제 #19
0
    def get_data(self):
        """ Get organization activity in JSON representation """
        url = self.url + "organizations/" + self.organization + "/activity/"
        headers = {'Authorization': 'Bearer {0}'.format(self.token)}
        request = urllib2.Request(url, None, headers)
        log.debug("Getting activity data from server.")
        try:
            response = urllib2.urlopen(request)
        except urllib2.URLError as e:
            log.error("An error encountered while getting data from server.")
            log.debug(e)
            raise ReportError("Could not get data. {0}.".format(str(e)))

        return json.load(response)
예제 #20
0
 def _fetch_activities(self):
     """ Get organization activity, handle pagination """
     activities = []
     # Prepare url of the first page
     url = '{0}/organizations/{1}/activity/'.format(
         self.url, self.organization)
     while url:
         # Fetch one page of activities
         try:
             log.debug('Fetching activity data: {0}'.format(url))
             response = requests.get(url, headers=self.headers)
             if not response.ok:
                 log.error(response.text)
                 raise ReportError('Failed to fetch Sentry activities.')
             data = response.json()
             log.data("Response headers:\n{0}".format(
                 pretty(response.headers)))
             log.debug("Fetched {0}.".format(listed(len(data), 'activity')))
             log.data(pretty(data))
             for activity in [Activity(item) for item in data]:
                 # We've reached the last page, older records not relevant
                 if activity.created < self.stats.options.since.date:
                     return activities
                 # Store only relevant activites (before until date)
                 if activity.created < self.stats.options.until.date:
                     log.details("Activity: {0}".format(activity))
                     activities.append(activity)
         except requests.RequestException as error:
             log.debug(error)
             raise ReportError(
                 'Failed to fetch Sentry activities from {0}'.format(url))
         # Check for possible next page
         try:
             url = NEXT_PAGE.search(response.headers['Link']).groups()[0]
         except AttributeError:
             url = None
     return activities
예제 #21
0
 def search(query, parent, options):
     """ Perform Trac search """
     # Extend the default max number of tickets to be fetched
     query = "{0}&max={1}".format(query, MAX_TICKETS)
     log.debug("Search query: {0}".format(query))
     try:
         result = parent.proxy.ticket.query(query)
     except xmlrpc.client.Fault as error:
         log.error("An error encountered, while searching for tickets.")
         raise ReportError(error)
     except xmlrpc.client.ProtocolError as error:
         log.debug(error)
         log.error("Trac url: {0}".format(parent.url))
         raise ReportError(
             "Unable to contact Trac server. Is the url above correct?")
     log.debug("Search result: {0}".format(result))
     # Fetch tickets and their history using multicall
     multicall = xmlrpc.client.MultiCall(parent.proxy)
     for ticket_id in sorted(result):
         multicall.ticket.get(ticket_id)
         multicall.ticket.changeLog(ticket_id)
     log.debug("Fetching trac tickets and their history")
     result = list(multicall())
     tickets = result[::2]
     changelogs = result[1::2]
     # Print debugging info
     for ticket, changelog in zip(tickets, changelogs):
         log.debug("Fetched ticket #{0}".format(ticket[0]))
         log.debug(pretty(ticket))
         log.debug("Changelog:")
         log.debug(pretty(changelog))
     # Return the list of ticket objects
     return [
         Trac(ticket, changelg, parent=parent, options=options)
         for ticket, changelg in zip(tickets, changelogs)
     ]
예제 #22
0
파일: bodhi.py 프로젝트: psss/did
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config['url']
     except KeyError:
         raise ReportError(
             'No Bodhi url set in the [{0}] section'.format(option))
     self.bodhi = Bodhi(self.url)
     # Create the list of stats
     self.stats = [
         UpdatesCreated(option=option + '-updates-created',
                        parent=self,
                        name='Updates created on {0}'.format(option)),
     ]
예제 #23
0
 def search(self, query):
     """ Perform GitHub query """
     url = self.url + "/" + query
     log.debug("GitHub query: {0}".format(url))
     try:
         request = urllib.request.Request(url, headers=self.headers)
         response = urllib.request.urlopen(request)
         log.debug("Response headers:\n{0}".format(
             str(response.info()).strip()))
     except urllib.error.URLError as error:
         log.debug(error)
         raise ReportError("GitHub search on {0} failed.".format(self.url))
     result = json.loads(response.read())["items"]
     log.debug("Result: {0} fetched".format(listed(len(result), "item")))
     log.data(pretty(result))
     return result
예제 #24
0
파일: jira.py 프로젝트: theute/did
 def session(self):
     """ Initialize the session """
     if self._session is None:
         self._session = requests.Session()
         log.debug("Connecting to {0}".format(self.auth_url))
         if self.auth_type == 'basic':
             basic_auth = (self.auth_username, self.auth_password)
             response = self._session.get(self.auth_url, auth=basic_auth)
         else:
             gssapi_auth = HTTPSPNEGOAuth(mutual_authentication=DISABLED)
             response = self._session.get(self.auth_url, auth=gssapi_auth)
         try:
             response.raise_for_status()
         except requests.exceptions.HTTPError as error:
             log.error(error)
             raise ReportError('Jira authentication failed. Try kinit.')
     return self._session
예제 #25
0
 def search(self, query, options):
     """ Perform Bugzilla search """
     query["query_format"] = "advanced"
     query["limit"] = "0"
     log.debug("Search query:")
     log.debug(pretty(query))
     # Fetch bug info
     try:
         result = self.server.query(query)
     except xmlrpc.client.Fault as error:
         # Ignore non-existent users (this is necessary for users with
         # several email aliases to allow them using --merge/--total)
         if "not a valid username" in str(error):
             log.debug(error)
             return []
         # Otherwise suggest to bake bugzilla cookies
         log.error("An error encountered, while searching for bugs.")
         log.debug(error)
         raise ReportError(
             "Have you baked cookies using the 'bugzilla login' command?")
     log.debug("Search result:")
     log.debug(pretty(result))
     bugs = dict((bug.id, bug) for bug in result)
     # Fetch bug history
     log.debug("Fetching bug history")
     result = self.server._proxy.Bug.history({'ids': list(bugs.keys())})
     log.debug(pretty(result))
     history = dict((bug["id"], bug["history"]) for bug in result["bugs"])
     # Fetch bug comments
     log.debug("Fetching bug comments")
     result = self.server._proxy.Bug.comments({'ids': list(bugs.keys())})
     log.debug(pretty(result))
     comments = dict((int(bug), data["comments"])
                     for bug, data in list(result["bugs"].items()))
     # Create bug objects
     return [
         self.parent.bug(bugs[id],
                         history[id],
                         comments[id],
                         parent=self.parent) for id in bugs
     ]
예제 #26
0
파일: zammad.py 프로젝트: psss/did
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     config = dict(Config().section(option))
     # Check server url
     try:
         self.url = config["url"]
     except KeyError:
         raise ReportError(
             "No zammad url set in the [{0}] section".format(option))
     # Check authorization token
     try:
         self.token = config["token"]
     except KeyError:
         self.token = None
     self.zammad = Zammad(self.url, self.token)
     # Create the list of stats
     self.stats = [
         TicketsUpdated(option=option + "-tickets-updated",
                        parent=self,
                        name="Tickets updated on {0}".format(option)),
     ]
예제 #27
0
    def __init__(self, option, name=None, parent=None, user=None):
        StatsGroup.__init__(self, option, name, parent, user)
        self.config = dict(Config().section(option))
        if 'url' not in self.config:
            raise IOError(
                'No gerrit URL set in the [{0}] section'.format(option))
        self.repo_url = self.config['url']
        log.debug('repo_url = {0}'.format(self.repo_url))

        if "prefix" not in self.config:
            raise ReportError(
                "No prefix set in the [{0}] section".format(option))

        self.stats = [
            AbandonedChanges(option=option + '-abandoned', parent=self),
            MergedChanges(option=option + '-merged', parent=self),
            SubmitedChanges(option=option + '-submitted', parent=self),
            PublishedDrafts(option=option + '-drafts', parent=self),
            #AddedPatches(option=option + '-added-patches', parent=self),
            ReviewedChanges(option=option + '-reviewed', parent=self),
        ]
예제 #28
0
 def search(self, query, pagination, result_field):
     """ Perform Pagure query """
     result = []
     url = "/".join((self.url, query))
     while url:
         log.debug("Pagure query: {0}".format(url))
         try:
             response = requests.get(url, headers=self.headers)
             log.data("Response headers:\n{0}".format(response.headers))
         except requests.RequestException as error:
             log.error(error)
             raise ReportError("Pagure search {0} failed.".format(self.url))
         data = response.json()
         objects = data[result_field]
         log.debug("Result: {0} fetched".format(listed(
             len(objects), "item")))
         log.data(pretty(data))
         # FIXME later: Work around https://pagure.io/pagure/issue/4057
         if not objects:
             break
         result.extend(objects)
         url = data[pagination]['next']
     return result
예제 #29
0
파일: jira.py 프로젝트: thrix/did
 def __init__(self, option, name=None, parent=None, user=None):
     StatsGroup.__init__(self, option, name, parent, user)
     self._session = None
     # Make sure there is an url provided
     config = dict(Config().section(option))
     if "url" not in config:
         raise ReportError(
             "No Jira url set in the [{0}] section".format(option))
     self.url = config["url"].rstrip("/")
     # Optional authentication url
     if "auth_url" in config:
         self.auth_url = config["auth_url"]
     else:
         self.auth_url = self.url + "/step-auth-gss"
     # Authentication type
     if "auth_type" in config:
         if config["auth_type"] not in AUTH_TYPES:
             raise ReportError(
                 "Unsupported authentication type: {0}"
                 .format(config["auth_type"]))
         self.auth_type = config["auth_type"]
     else:
         self.auth_type = "gss"
     # Authentication credentials
     if self.auth_type == "basic":
         if "auth_username" not in config:
             raise ReportError(
                 "`auth_username` not set in the [{0}] section"
                 .format(option))
         self.auth_username = config["auth_username"]
         if "auth_password" not in config:
             raise ReportError(
                 "`auth_password` not set in the [{0}] section"
                 .format(option))
         self.auth_password = config["auth_password"]
     else:
         if "auth_username" in config:
             raise ReportError(
                 "`auth_username` is only valid for basic authentication"
                 + " (section [{0}])".format(option))
         if "auth_password" in config:
             raise ReportError(
                 "`auth_password` is only valid for basic authentication"
                 + " (section [{0}])".format(option))
     # Make sure we have project set
     if "project" not in config:
         raise ReportError(
             "No project set in the [{0}] section".format(option))
     self.project = config["project"]
     # Check for custom prefix
     self.prefix = config["prefix"] if "prefix" in config else None
     # Create the list of stats
     self.stats = [
         JiraCreated(
             option=option + "-created", parent=self,
             name="Issues created in {0}".format(option)),
         JiraUpdated(
             option=option + "-updated", parent=self,
             name="Issues updated in {0}".format(option)),
         JiraResolved(
             option=option + "-resolved", parent=self,
             name="Issues resolved in {0}".format(option)),
         ]
예제 #30
0
파일: confluence.py 프로젝트: stepnem/did
    def __init__(self, option, name=None, parent=None, user=None):
        StatsGroup.__init__(self, option, name, parent, user)
        self._session = None
        # Make sure there is an url provided
        config = dict(Config().section(option))
        if "url" not in config:
            raise ReportError(
                "No Confluence url set in the [{0}] section".format(option))
        self.url = config["url"].rstrip("/")
        # Optional authentication url
        if "auth_url" in config:
            self.auth_url = config["auth_url"]
        else:
            self.auth_url = self.url + "/step-auth-gss"
        # Authentication type
        if "auth_type" in config:
            if config["auth_type"] not in AUTH_TYPES:
                raise ReportError(
                    "Unsupported authentication type: {0}".format(
                        config["auth_type"]))
            self.auth_type = config["auth_type"]
        else:
            self.auth_type = "gss"
        # Authentication credentials
        if self.auth_type == "basic":
            if "auth_username" not in config:
                raise ReportError(
                    "`auth_username` not set in the [{0}] section".format(
                        option))
            self.auth_username = config["auth_username"]
            if "auth_password" in config:
                self.auth_password = config["auth_password"]
            elif "auth_password_file" in config:
                file_path = os.path.expanduser(config["auth_password_file"])
                with open(file_path) as password_file:
                    self.auth_password = password_file.read().strip()
            else:
                raise ReportError(
                    "`auth_password` or `auth_password_file` must be set "
                    "in the [{0}] section".format(option))
        else:
            if "auth_username" in config:
                raise ReportError(
                    "`auth_username` is only valid for basic authentication" +
                    " (section [{0}])".format(option))
            if "auth_password" in config or "auth_password_file" in config:
                raise ReportError(
                    "`auth_password` and `auth_password_file` are only valid "
                    "for basic authentication (section [{0}])".format(option))
        # SSL verification
        if "ssl_verify" in config:
            try:
                self.ssl_verify = distutils.util.strtobool(
                    config["ssl_verify"])
            except Exception as error:
                raise ReportError(
                    "Error when parsing 'ssl_verify': {0}".format(error))
        else:
            self.ssl_verify = SSL_VERIFY

        self.login = config.get("login", None)
        # Check for custom prefix
        self.prefix = config["prefix"] if "prefix" in config else None
        # Create the list of stats
        self.stats = [
            PageCreated(option=option + "-pages",
                        parent=self,
                        name="Pages created in {}".format(option)),
            CommentAdded(option=option + "-comments",
                         parent=self,
                         name="Comments added in {}".format(option)),
        ]