| @@ -29,25 +29,56 @@ class Stars(Command): | |||||
| """Get the number of stargazers for a given GitHub repository.""" | """Get the number of stargazers for a given GitHub repository.""" | ||||
| name = "stars" | name = "stars" | ||||
| commands = ["stars", "stargazers"] | commands = ["stars", "stargazers"] | ||||
| API_URL = "https://api.github.com/repos/{repo}" | |||||
| API_REPOS = "https://api.github.com/repos/{repo}" | |||||
| API_USERS = "https://api.github.com/users/{user}/repos" | |||||
| EXAMPLE = "!stars earwig/earwigbot" | EXAMPLE = "!stars earwig/earwigbot" | ||||
| def process(self, data): | def process(self, data): | ||||
| if not data.args: | if not data.args: | ||||
| msg = "Which repository should I look up? Example: \x0306{0}\x0F." | |||||
| msg = "Which GitHub repository or user should I look up? Example: \x0306{0}\x0F." | |||||
| self.reply(data, msg.format(self.EXAMPLE)) | self.reply(data, msg.format(self.EXAMPLE)) | ||||
| return | return | ||||
| repo = data.args[0] | |||||
| info = self.get_repo(repo) | |||||
| if info is None: | |||||
| arg = data.args[0] | |||||
| if "/" in arg: | |||||
| self.handle_repo(data, arg) | |||||
| else: | |||||
| self.handle_user(data, arg) | |||||
| def handle_repo(self, data, arg): | |||||
| """Handle !stars <user>/<repo>.""" | |||||
| repo = self.get_repo(arg) | |||||
| if repo is None: | |||||
| self.reply(data, "Repository not found. Is it private?") | self.reply(data, "Repository not found. Is it private?") | ||||
| return | |||||
| count = int(repo["stargazers_count"]) | |||||
| plural = "" if count == 1 else "s" | |||||
| msg = "\x0303{0}\x0F has \x02{1}\x0F stargazer{2}: {3}" | |||||
| self.reply(data, msg.format( | |||||
| repo["full_name"], count, plural, repo["html_url"])) | |||||
| def handle_user(self, data, arg): | |||||
| """Handle !stars <user>.""" | |||||
| repos = self.get_user_repos(arg) | |||||
| if repos is None: | |||||
| self.reply(data, "User not found.") | |||||
| return | |||||
| star_count = sum(repo["stargazers_count"] for repo in repos) | |||||
| star_plural = "" if star_count == 1 else "s" | |||||
| repo_plural = "" if len(repos) == 1 else "s" | |||||
| if len(repos) > 0: | |||||
| name = repos[0]["owner"]["login"] | |||||
| url = repos[0]["owner"]["html_url"] | |||||
| else: | else: | ||||
| count = int(info["stargazers_count"]) | |||||
| plural = "" if count == 1 else "s" | |||||
| msg = "\x0303{0}\x0F has \x02{1}\x0F stargazer{2}: {3}" | |||||
| self.reply(data, msg.format( | |||||
| info["full_name"], count, plural, info["html_url"])) | |||||
| name = arg | |||||
| url = "https://github.com/{0}".format(name) | |||||
| msg = "\x0303{0}\x0F has \x02{1}\x0F stargazer{2} across {3} repo{4}: {5}" | |||||
| self.reply(data, msg.format( | |||||
| name, star_count, star_plural, len(repos), repo_plural, url)) | |||||
| def get_repo(self, repo): | def get_repo(self, repo): | ||||
| """Return the API JSON dump for a given repository. | """Return the API JSON dump for a given repository. | ||||
| @@ -55,10 +86,24 @@ class Stars(Command): | |||||
| Return None if the repo doesn't exist or is private. | Return None if the repo doesn't exist or is private. | ||||
| """ | """ | ||||
| try: | try: | ||||
| query = urlopen(self.API_URL.format(repo=repo)).read() | |||||
| query = urlopen(self.API_REPOS.format(repo=repo)).read() | |||||
| except HTTPError: | except HTTPError: | ||||
| return None | return None | ||||
| res = loads(query) | res = loads(query) | ||||
| if res and "id" in res and not res["private"]: | if res and "id" in res and not res["private"]: | ||||
| return res | return res | ||||
| return None | return None | ||||
| def get_user_repos(self, user): | |||||
| """Return the API JSON dump for a given user's repositories. | |||||
| Return None if the user doesn't exist. | |||||
| """ | |||||
| try: | |||||
| query = urlopen(self.API_USERS.format(user=user)).read() | |||||
| except HTTPError: | |||||
| return None | |||||
| res = loads(query) | |||||
| if res and isinstance(res, list): | |||||
| return res | |||||
| return None | |||||