def main(arguments=None): """ Parse options, gather stats and show the results Takes optional parameter ``arguments`` which can be either command line string or list of options. This is very useful for testing purposes. Function returns a tuple of the form:: ([user_stats], team_stats) with the list of all gathered stats objects. """ try: # Parse options, initialize gathered stats options, header = Options().parse(arguments) gathered_stats = [] # Check for user email addresses (command line or config) emails = options.emails or did.base.Config().email emails = utils.split(emails, separator=re.compile(r"\s*,\s*")) users = [did.base.User(email=email) for email in emails] # Print header and prepare team stats object for data merging utils.eprint(header) team_stats = UserStats(options=options) if options.merge: utils.header("Total Report") utils.item("Users: {0}".format(len(users)), options=options) # Check individual user stats for user in users: if options.merge: utils.item(user, 1, options=options) else: utils.header(user) user_stats = UserStats(user=user, options=options) user_stats.check() team_stats.merge(user_stats) gathered_stats.append(user_stats) # Display merged team report if options.merge or options.total: if options.total: utils.header("Total Report") team_stats.show() # Return all gathered stats objects return gathered_stats, team_stats except did.base.ConfigFileError as error: utils.info( "Create at least a minimum config file {0}:\n{1}".format( did.base.Config.path(), did.base.Config.example().strip() ) ) raise except kerberos.GSSError as error: log.debug(error) raise did.base.ConfigError("Kerberos authentication failed. Try kinit.")
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 main(arguments=None): """ Parse options, gather stats and show the results Takes optional parameter ``arguments`` which can be either command line string or list of options. This is very useful for testing purposes. Function returns a tuple of the form:: ([user_stats], team_stats) with the list of all gathered stats objects. """ try: # Parse options, initialize gathered stats options, header = Options().parse(arguments) gathered_stats = [] # Check for user email addresses (command line or config) emails = options.emails or did.base.Config().email emails = utils.split(emails, separator=re.compile(r"\s*,\s*")) users = [did.base.User(email=email) for email in emails] # Print header and prepare team stats object for data merging utils.eprint(header) team_stats = UserStats(options=options) if options.merge: utils.header("Total Report") utils.item("Users: {0}".format(len(users)), options=options) # Check individual user stats for user in users: if options.merge: utils.item(user, 1, options=options) else: utils.header(user) user_stats = UserStats(user=user, options=options) user_stats.check() team_stats.merge(user_stats) gathered_stats.append(user_stats) # Display merged team report if options.merge or options.total: if options.total: utils.header("Total Report") team_stats.show() # Return all gathered stats objects return gathered_stats, team_stats except did.base.ConfigFileError as error: utils.info("Create at least a minimum config file {0}:\n{1}".format( did.base.Config.path(), did.base.Config.example().strip())) raise except kerberos.GSSError as error: log.debug(error) raise did.base.ConfigError( "Kerberos authentication failed. Try kinit.")
def __init__(self, stats, config): self.stats = stats self.key = config['apikey'] self.token = config['token'] self.username = config['user'] if "user" in config else "me" self.board_links = split(config['board_links']) self.board_ids = self.board_links_to_ids()
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 __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 filter_map: for filt in 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 parse(self, arguments=None): """ Parse the options. """ # Split arguments if given as string and run the parser if arguments is not None: self.arguments = arguments if (self.arguments is not None and isinstance(self.arguments, basestring)): self.arguments = self.arguments.split() # Otherwise properly decode command line arguments if self.arguments is None: self.arguments = [arg.decode("utf-8") for arg in sys.argv[1:]] (opt, arg) = self.parser.parse_args(self.arguments) self.opt = opt self.arg = arg self.check() # Enable --all if no particular stat or group selected opt.all = not any([ getattr(opt, stat.dest) or getattr(opt, group.dest) for group in self.sample_stats.stats for stat in group.stats]) # Detect email addresses and split them on comma if not opt.emails: opt.emails = did.base.Config().email opt.emails = utils.split(opt.emails, separator=re.compile(r"\s*,\s*")) if not opt.emails: raise ConfigError("No email given. Use --email or create config.") # Time period handling if opt.since is None and opt.until is None: opt.since, opt.until, period = did.base.Date.period(arg) else: opt.since = did.base.Date(opt.since or "1993-01-01") opt.until = did.base.Date(opt.until or "today") # Make the 'until' limit inclusive opt.until.date += delta(days=1) period = "given date range" # Validate the date range if not opt.since.date < opt.until.date: raise RuntimeError( "Invalid date range ({0} to {1})".format( opt.since, opt.until.date - delta(days=1))) print(u"Status report for {0} ({1} to {2}).".format( period, opt.since, opt.until.date - delta(days=1))) # Finito log.debug("Gathered options:") log.debug('options = {0}'.format(opt)) return opt
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") 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.stats = [ GoogleEventsOrganized( option=option + "-events-organized", parent=self), GoogleEventsAttended( option=option + "-events-attended", 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 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) 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), ClosedBugs(option=option + "-closed", parent=self), ]