def __init__(self, option, name=None, parent=None, user=None): StatsGroup.__init__(self, "custom", name, parent, user) for section in Config().sections(kind="items"): self.stats.append( ItemStats(option=section, parent=self, name=Config().item(section, "header")))
def test_Config_email_missing(): config = Config("[general]\n") with pytest.raises(did.base.ConfigError): config.email == "*****@*****.**" config = Config("[missing]") with pytest.raises(did.base.ConfigError): config.email == "*****@*****.**"
def __init__(self, option, name=None, parent=None, user=None): StatsGroup.__init__(self, option, name, parent, user) try: api = Config().item(option, 'api') except ConfigError: api = None for wiki, url in Config().section(option, skip=['type', 'api']): self.stats.append( WikiChanges(option=wiki, parent=self, url=url, api=api, name="Updates on {0}".format(wiki)))
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)), ]
def __init__(self, option, name=None, parent=None, user=None): StatsGroup.__init__(self, option, name, parent, user) config = dict(Config().section(option)) # Check Sentry url if "url" not in config: raise ConfigError("No url set in the [{0}] section".format(option)) # Check Sentry organization if "organization" not in config: raise ConfigError( "No organization set in the [{0}] section".format(option)) # Check Sentry token if "token" not in config: raise ConfigError( "No token set in the [{0}] section".format(option)) # Set up the Sentry API sentry = SentryAPI(config=config) # Construct the list of stats self.stats = [ ResolvedIssues(sentry=sentry, option=option + '-resolved', parent=self), CommentedIssues(sentry=sentry, option=option + '-commented', parent=self), ]
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)), ]
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)), ]
def load(): """ Check available plugins and attempt to import them """ # Code is based on beaker-client's command.py script plugins = [] for filename in os.listdir(PLUGINS_PATH): if not filename.endswith(".py") or filename.startswith("_"): continue if not os.path.isfile(os.path.join(PLUGINS_PATH, filename)): continue plugin = filename[:-3] if plugin in FAILED_PLUGINS: # Skip loading plugins that already failed before continue try: __import__(PLUGINS.__name__, {}, {}, [plugin]) plugins.append(plugin) log.debug("Successfully imported {0} plugin".format(plugin)) except (ImportError, SyntaxError) as error: # Give a warning only when the plugin is configured message = "Failed to import {0} plugin ({1})".format(plugin, error) if Config().sections(kind=plugin): log.warn(message) else: log.debug(message) FAILED_PLUGINS.append(plugin) return plugins
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), ]
def __init__(self, option, name=None, parent=None, user=None): super(GoogleStatsGroup, self).__init__(option, name, parent, user) config = dict(Config().section(option)) client_id = config["client_id"] client_secret = config["client_secret"] storage = config.get("storage") if storage is not None: storage = os.path.expanduser(storage) try: apps = [app.lower() for app in split(config["apps"])] except KeyError: apps = DEFAULT_APPS http = authorized_http(client_id, client_secret, apps, storage) self.calendar = GoogleCalendar(http) self.tasks = GoogleTasks(http) self.stats = [ GoogleEventsOrganized( option=option + "-events-organized", parent=self), GoogleEventsAttended( option=option + "-events-attended", parent=self), GoogleTasksCompleted( option=option + "-tasks-completed", parent=self), ]
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)), ]
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), ]
def __init__(self, option, name=None, parent=None): # Prepare sorted item content from the config section items = Config().section(option, skip=["type", "header", "order"]) self._items = [ "{0}{1}".format(value, "" if "-" in value else " - ") for _, value in sorted(items, key=lambda x: x[0]) ] Stats.__init__(self, option, name, parent)
def __init__(self, option, name=None, parent=None, user=None): StatsGroup.__init__(self, option, name, parent, user) for wiki, url in Config().section(option): self.stats.append( WikiChanges(option=wiki, parent=self, url=url, name="Updates on {0}".format(wiki)))
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))
def detect(): """ Detect available plugins and return enabled/configured stats Yields tuples of the form (section, statsgroup) sorted by the default StatsGroup order which maybe overriden in the config file. The 'section' is the name of the configuration section as well as the option used to enable those particular stats. """ # Load plugins and config plugins = load() config = Config() # Make sure that all sections have a valid plugin type defined for section in config.sections(): if section == 'general': continue try: type_ = config.item(section, 'type') except ConfigError: raise ConfigError( "Plugin type not defined in section '{0}'.".format(section)) if type_ not in plugins: raise ConfigError( "Invalid plugin type '{0}' in section '{1}'.".format( type_, section)) # Detect classes inherited from StatsGroup and return them sorted stats = [] for plugin in plugins: module = getattr(PLUGINS, plugin) for object_name in dir(module): statsgroup = getattr(module, object_name) # Filter out anything except for StatsGroup descendants if (not isinstance(statsgroup, (type, types.ClassType)) or not issubclass(statsgroup, StatsGroup) or statsgroup is StatsGroup or statsgroup is EmptyStatsGroup): continue # Search config for sections with type matching the plugin, # use order provided there or class default otherwise for section in config.sections(kind=plugin): try: order = int(config.item(section, "order")) except ConfigError: order = statsgroup.order except ValueError: log.warn("Invalid {0} stats order: '{1}'".format( section, config.item(section, "order"))) order = statsgroup.order stats.append((section, statsgroup, order)) log.info("Found {0}, an instance of {1}, order {2}".format( section, statsgroup.__name__, order)) # Custom stats are handled with a single instance if statsgroup.__name__ == "CustomStats": break for section, statsgroup, _ in sorted(stats, key=lambda x: x[2]): yield section, statsgroup
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)), ]
def __init__(self, option, name=None, parent=None, user=None): StatsGroup.__init__(self, option, name, parent, user) # Check config for required fields config = dict(Config().section(option)) for field in ['url', 'organization', 'token']: if field not in config: raise ConfigError( "No {0} set in the [{1}] section".format(field, option)) # Set up the Sentry API and construct the list of stats self.sentry = Sentry(config=config, stats=self) self.stats = [ ResolvedIssues(option=option + '-resolved', parent=self), CommentedIssues(option=option + '-commented', parent=self), ]
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)), ]
def __init__(self, option, name=None, parent=None, user=None): """ Process config, prepare investigator, construct stats """ # Check Request Tracker instance url and custom prefix super(BitlyStats, self).__init__(option, name, parent, user) config = dict(Config().section(option)) try: self.token = config["token"] except KeyError: raise ConfigError("No token in the [{0}] section".format(option)) self.bitly = Bitly(parent=self) # Construct the list of stats self.stats = [ SavedLinks(option=option + "-saved", parent=self), ]
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), ]
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)), ]
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)), ]
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), ]
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)), ]
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)), ]
def test_Config_email(): config = Config("[general]\nemail = [email protected]\n") assert config.email == "*****@*****.**"
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" 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)) # Token elif self.auth_type == "token": if "token" in config: self.token = config["token"] elif "token_file" in config: file_path = os.path.expanduser(config["token_file"]) with open(file_path) as token_file: self.token = token_file.read().strip() else: raise ReportError( "The `token` or `token_file` key must be set " "in the [{0}] section.".format(option)) if "token_expiration" in config or "token_name" in config: try: self.token_expiration = int(config["token_expiration"]) self.token_name = config["token_name"] except KeyError: raise ReportError( "The ``token_name`` and ``token_expiration`` " "must be set at the same time in " "[{0}] section.".format(option)) except ValueError: raise ReportError( "The ``token_expiration`` must contain number, used in " "[{0}] section.".format(option)) else: self.token_expiration = self.token_name = None 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 # Make sure we have project set self.project = config.get("project", None) if "use_scriptrunner" in config: self.use_scriptrunner = distutils.util.strtobool( config["use_scriptrunner"]) else: self.use_scriptrunner = True if not self.use_scriptrunner and not self.project: raise ReportError( "When scriptrunner is disabled with 'use_scriptrunner=False', " "'project' has to be defined for each JIRA section.") 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 = [ 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)), ]
def test_User(): from did.base import User assert User # No email provided try: user = User("") except ConfigError: pass else: raise RuntimeError("No exception for missing email") # Invalid email address try: user = User("bad-email") except ConfigError: pass else: raise RuntimeError("No exception for invalid email") # Short email format user = User("*****@*****.**") assert user.email == "*****@*****.**" assert user.login == "some" assert user.name == None assert str(user) == "*****@*****.**" # Full email format user = User("Some Body <*****@*****.**>") assert user.email == "*****@*****.**" assert user.login == "some" assert user.name == "Some Body" assert str(user) == "Some Body <*****@*****.**>" # Invalid alias definition try: user = User("[email protected]; bad-alias", stats="bz") except ConfigError: pass else: raise RuntimeError("No exception for invalid alias definition") # Custom email alias user = User("[email protected]; bz: [email protected]", stats="bz") assert user.email == "*****@*****.**" assert user.login == "bugzilla" # Custom login alias user = User("[email protected]; bz: bzlogin", stats="bz") assert user.login == "bzlogin" # Custom email alias in config section Config(config="[bz]\ntype = bugzilla\nemail = [email protected]") user = User("*****@*****.**", stats="bz") assert user.email == "*****@*****.**" assert user.login == "bugzilla" # Custom login alias in config section Config(config="[bz]\ntype = bugzilla\nlogin = bzlogin") user = User("*****@*****.**", stats="bz") assert user.login == "bzlogin" # User cloning user = User("[email protected]; bz: bzlogin") clone = user.clone("bz") assert clone.login == "bzlogin"
def test_Config_width(): config = Config("[general]\n") assert config.width == did.base.MAX_WIDTH config = Config("[general]\nwidth = 123\n") assert config.width == 123