def main(): repository_name = sys.argv[1] username = sys.argv[2] file_path = pathlib.Path(sys.argv[3]) incidents_path = append_to_path(file_path, '.INCIDENTS') password = getpass() repository = Github(username, password).get_repo(repository_name) with open(incidents_path, 'r') as stream: incidents = yaml.load(stream) print('Due to GitHub API limits, this will take ' + str(len(incidents) * 3 / 60) + ' minutes to complete.') response = input('Do you want to report these issues [y]/n? ') if len(response) == 0 or response[0].lower() == 'y': for incident in tqdm(incidents): issue_title = 'Misspelled word in ' + str(file_path) issue_comment = 'On line number ' + str(incident['line']) + \ ', the misspelled word "' + str(incident['twiddled']) + \ '" was found.' repository.create_issue(issue_title, issue_comment) time.sleep( 3 ) # rate-limit the requests so we don't run afoul of GitHub's API limits else: print('No issues reported')
def run(): # pull our repo access src_repo = Github(getenv('SRC_REPO_TOKEN')).get_repo( getenv('GITHUB_REPOSITORY')) dst_repo = Github(getenv('DST_REPO_TOKEN')).get_repo( getenv('DST_REPO')) # bounce to ekoparty-internal # pull the src issue src_issue_id = int(getenv('SRC_REPO_ISSUE')) src_issue = src_repo.get_issue(src_issue_id) # bounce a comment back to the src issue src_issue.create_comment( 'Thank you for submitting a staff report! This issue will be filed to the internal ekoparty2020 staff repo and triaged ASAP!' ) # bounce the issue through to the internal repo dst_repo.create_issue(title=src_issue.title, body=src_issue.body, labels=[dst_repo.get_label('Staff Report')]) # update the source issue title and make contents private src_issue.edit( title="This issue has been filed with staff internal repo! Thanks!", body='', state='closed') return 0
def _run(category: str = 'IT_트렌드'): """Post github issue Args: category: str = 'IT_트렌드' brunch category """ try: GITHUB_TOKEN = os.environ['GITHUB_TOKEN'] REPO_NAME = 'todays-brunch' CATEGORY = category issue_title = get_title(CATEGORY) issue_body = get_body(CATEGORY) if issue_body == '': print('There is no updated brunch.') sys.exit() repo = Github(GITHUB_TOKEN).get_user().get_repo(REPO_NAME) res = repo.create_issue(title=issue_title, body=issue_body) print('Success!') print(res) except Exception as e: print(e)
def submit_errors(self): if not (sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD and len(classes.ErrorViewer.errors) > 0): return gh_org = sickbeard.GIT_ORG or 'SiCKRAGETV' gh_repo = 'sickrage-issues' gh_issues = Github(login_or_token=sickbeard.GIT_USERNAME, password=sickbeard.GIT_PASSWORD, user_agent="SiCKRAGE").get_organization(gh_org).get_repo(gh_repo) try: # read log file if self.logFile and os.path.isfile(self.logFile): with ek.ek(open, self.logFile) as f: log_data = f.readlines() log_data = [line for line in reversed(log_data)] # parse and submit errors to issue tracker for curError in sorted(classes.ErrorViewer.errors, key=lambda error: error.time, reverse=True)[:500]: if not curError.title: continue pastebin_url = None regex = "^(%s)\s*([A-Z]+)\s*(.+?)\s*\:\:\s*(.*)$" % curError.time for i, x in enumerate(log_data): x = ek.ss(x) match = re.match(regex, x) if match: level = match.group(2) if reverseNames[level] == ERROR: paste_data = "".join(log_data[i:50]) pastebin_url = PastebinAPI().paste('f59b8e9fa1fc2d033e399e6c7fb09d19', paste_data) break message = u"### INFO\n" message += u"Python Version: **" + sys.version[:120] + "**\n" message += u"Operating System: **" + platform.platform() + "**\n" message += u"Branch: **" + sickbeard.BRANCH + "**\n" message += u"Commit: SiCKRAGETV/SickRage@" + sickbeard.CUR_COMMIT_HASH + "\n" if pastebin_url: message += u"Pastebin Log URL: " + pastebin_url + "\n" message += u"### ERROR\n" message += u"```\n" message += curError.message + "\n" message += u"```\n" message += u"---\n" message += u"_STAFF NOTIFIED_: @SiCKRAGETV/owners @SiCKRAGETV/moderators" issue = gh_issues.create_issue("[APP SUBMITTED]: " + curError.title, message) if issue: self.log('Your issue ticket #%s was submitted successfully!' % issue.number) # clear error from error list classes.ErrorViewer.errors.remove(curError) return issue except Exception as e: self.log(sickbeard.exceptions.ex(e), ERROR)
class RepoConnection(): """ helper class that connects to repo """ def __init__(self, token=None, name=None, **args): self.repo = Github(token).get_repo(name) def get_issues(self): issues = self.repo.get_issues() return issues def create_issue(self, title, body, label_name=None): if label_name is None: return self.repo.create_issue(title=title, body=body) else: try: label = self.repo.get_label(label_name) return self.repo.create_issue(title=title, body=body, labels=[label]) except BaseException: return self.repo.create_issue(title=title, body=body)
class GithubReport(BaseTracker): def __init__(self, repository, template, title=None): BaseTracker.__init__(self, template=title, title=title) self.repository = repository self.template = template self.ghapi = Github().get_repo(self.repository) @property def logged_in(self): try: gh.get_user().id return True except: return False def login(self, username, pwd): try: gh = Github(username, pwd) # This expression has no effect but will throw an exception if the authentication failed. gh.get_user().id self.ghapi = gh.get_repo(self.repository) return True except BadCredentialsException: return False def format_issue(self, issue): with open(self.template, 'r') as f: return Template(f.read()).substitute(self.decode_issue(issue)) def find_issue(self, issue): options = [] pages = self.ghapi.get_issues(state='open') idx = 0 while True: page = pages.get_page(idx) idx += 1 if not page: break for entry in page: ident = issue['id'].decode( 'utf-8', errors='ignore') if isinstance( issue['id'], bytes) else issue['id'] if all(word in entry.body for word in ident.split()): options.append(entry) return options def report_issue(self, report_details): return self.ghapi.create_issue(title=report_details['title'], body=report_details['body']) def __call__(self, issue): pass
class GithubTracker(BaseTracker): def __init__(self, repository): self.repository = repository self.ghapi = Github().get_repo(self.repository) self.gh = None @property def logged_in(self): try: self.gh.get_user().id return True except: return False def login(self, username, pwd): try: self.gh = Github(username, pwd) # This expression has no effect but will throw an exception if the authentication failed. self.gh.get_user().id self.ghapi = self.gh.get_repo(self.repository) return True except BadCredentialsException: return False def find_issue(self, query): options = [] pages = self.ghapi.get_issues(state='open') idx = 0 while True: page = pages.get_page(idx) idx += 1 if not page: break for entry in page: if all(word in entry.body for word in query.split()): options.append(entry) return options def report_issue(self, title, body): return self.ghapi.create_issue(title=title, body=body) def __call__(self, issue): pass def issue_url(self, issue): return issue.html_url
class GithubAction(object): def __init__(self, cluster_config): self.cluster_config = cluster_config self.token = cluster_config.github_user_token self.repo_name = cluster_config.github_repo self.app_name = cluster_config.github_app_name self.repo = Github(login_or_token=self.token).get_repo(self.repo_name) def _format_body_for_issue(self, issuer_node, issue_type, affect_node=None, affect_services=None): title = "[OpenLab HA HealthCheck][%s] Alarm" \ % datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") body = "Issuer Host Info:\n" \ "===============\n" \ " name: %(name)s\n" \ " role: %(role)s\n" \ " ip: %(ip)s\n" % { "name": issuer_node.name, "role": issuer_node.role, "ip": issuer_node.ip } body += "\nProblem:\n" \ "===============\n" if issue_type == 'service_down': body += "The service %(service_name)s on the node " \ "%(name)s (IP %(ip)s) is done.\n" % ( {'service_name': affect_services.name, 'name': affect_node.name, 'ip': affect_node.ip}) body += "\nSuggestion:\n" \ "===============\n" \ "ssh ubuntu@%s\n" \ "systemctl status %s\n" \ "journalctl -u %s\n" % ( affect_node.ip, affect_services.name, affect_services.name) elif issue_type == 'service_timeout': body += "The unnecessary service %(service_name)s on the node " \ "%(name)s (IP %(ip)s) is done for a long time.\n" % ( {'service_name': affect_services.name, 'name': affect_node.name, 'ip': affect_node.ip}) body += "\nSuggestion:\n" \ "===============\n" \ "ssh ubuntu@%s\n" \ "systemctl status %s\n" \ "journalctl -u %s\n" % ( affect_node.ip, affect_services.name, affect_services.name) elif issue_type == 'healthchecker_error': body += "The ha_healthchecker service on the node %(name)s (IP " \ "%(ip)s) is done.\n" % ( {'name': affect_node.name, 'ip': affect_node.ip}) body += "\nSuggestion:\n" \ "===============\n" \ "ssh ubuntu@%s\n" \ "systemctl status ha_healthchecker\n" \ "journalctl -u ha_healthchecker\n" elif issue_type == 'other_node_down': body += "The %(role)s node %(name)s (IP %(ip)s) is done.\n" % ( { 'role': affect_node.role, 'name': affect_node.name, 'ip': affect_node.ip }) body += "\nSuggestion:\n" \ "===============\n" \ "ssh ubuntu@%s\n" % affect_node.ip body += "Or try to login the cloud to check whether the " \ "resource exists.\n" elif issue_type == 'switch': body += "HA deployment already switch to slave deployment.\n" body += "Please use labkeeper new-slave command to re-create a new" \ "slave cluster.\n" body += "\nSuggestion:\n" \ "===============\n" \ "cd go-to-labkeeper-directory\n" \ "modify inventory file\n" \ "./deploy.py openlab-ha --action new-slave\n" return title, body def refresh(self, cluster_config): self.cluster_config = cluster_config self.app_name = cluster_config.github_app_name if (cluster_config.github_user_token != self.token or cluster_config.github_repo != self.repo_name): self.token = cluster_config.github_user_token self.repo_name = cluster_config.github_repo self.repo = Github(login_or_token=self.token).get_repo( self.repo_name) def create_issue(self, issuer_node, issue_type, affect_node=None, affect_services=None): title, body = self._format_body_for_issue( issuer_node, issue_type, affect_node=affect_node, affect_services=affect_services) self.repo.create_issue(title=title, body=body) def _get_login_page_authenticity_token(self, session): login_page = session.get('https://github.com/login') login_page_content = login_page.content.decode('utf-8') login_page_parser = LoginHTMLParser() login_page_parser.feed(login_page_content) login_page_parser.close() quoted_authenticity_token = parse.quote(login_page_parser.token) return quoted_authenticity_token def _get_github_app_page_authenticity_token(self, app_url, app_name, session): app_page = session.get(app_url) if app_page.status_code == 404: self.cluster_config.LOG.error("Not Found Github App: %s" % app_name) return app_page_content = app_page.content.decode('utf-8') app_page_parser = AppUpdateHTMLParser() app_page_parser.feed(app_page_content) quoted_authenticity_token = parse.quote(app_page_parser.token) return quoted_authenticity_token def update_github_app_webhook(self): session = requests.session() login_token = self._get_login_page_authenticity_token(session) login_info = ('authenticity_token=%(token)s&login=%(username)s&' 'password=%(password)s' % { 'token': login_token, 'username': self.cluster_config.github_user_name, 'password': self.cluster_config.github_user_password }) login_response = session.post('https://github.com/session', data=login_info) if (login_response.status_code == 200 and session.cookies._cookies['.github.com']['/']['logged_in'].value == 'yes'): self.cluster_config.LOG.info("Github app change: Success Login") else: self.cluster_config.LOG.error("Github app change: Fail Login") return app_url = 'https://github.com/settings/apps/%s' % self.app_name github_app_edit_token = self._get_github_app_page_authenticity_token( app_url, self.cluster_config.github_app_name, session) if not github_app_edit_token: return update_response = session.post( app_url, data="_method=put&authenticity_token=" + github_app_edit_token + "&integration%5Bhook_attributes%5D%5Burl%5D=http%3A%2F%2F" + self.cluster_config.dns_slave_public_ip + "%3A" + '80' + "%2Fapi%2Fconnection%2Fgithub%2Fpayload") if update_response.status_code == 200: self.cluster_config.LOG.info("Success Update Github APP: %s" % self.app_name) else: self.cluster_config.LOG.error("Fail Update Github APP: %s" % self.app_name)
site = 'https://okky.kr' res = urlopen(site + '/articles/gathering?offset=0&max=20&sort=id&order=desc') soup = BeautifulSoup(res, 'html.parser') article_list = soup.select('#list-article ul > li.list-group-item') issue_body = '' for row in article_list: title = row.select('h5 > a')[0] published_at = row.select('div.date-created span.timeago')[0].get_text() item = published_at + " " + str(title).replace( 'href="', 'href="' + site).replace("\n", "").replace( ' ', '').strip() + '<br/>\n' if '마감' not in str(title) and isDateInRange(published_at): issue_body += item else: print('[filtered] ', item) print('----------------------------------------------------------------------') issue_title = "스터디 모집 글 모음(%s)" % (today.strftime("%Y년 %m월 %d일 %H시")) print(issue_title) print(issue_body) GITHUB_TOKEN = os.environ['GITHUB_TOKEN'] REPO_NAME = "crawler-study-gathering" repo = Github(GITHUB_TOKEN).get_user().get_repo(REPO_NAME) if issue_body != '' and REPO_NAME == repo.name: res = repo.create_issue(title=issue_title, body=issue_body) print(res)
def open_issue_on_failure(body): repo = Github(bot_token).get_repo(repo_name) issues = repo.get_issues() if any(i.title == issue_title for i in issues): return repo.create_issue(issue_title, body)
class Logger(object): def __init__(self): self.logger = logging.getLogger('sickrage') self.loggers = [ logging.getLogger('sickrage'), logging.getLogger('tornado.general'), logging.getLogger('tornado.application'), #logging.getLogger('tornado.access'), ] self.consoleLogging = False self.fileLogging = False self.debugLogging = False self.logFile = None def initLogging(self, consoleLogging=False, fileLogging=False, debugLogging=False): self.logFile = self.logFile or os.path.join(sickbeard.LOG_DIR, 'sickrage.log') self.debugLogging = debugLogging self.consoleLogging = consoleLogging self.fileLogging = fileLogging # add a new logging level DB logging.addLevelName(DB, 'DB') # nullify root logger logging.getLogger().addHandler(NullHandler()) # set custom root logger for logger in self.loggers: if logger is not self.logger: logger.root = self.logger logger.parent = self.logger # set minimum logging level allowed for loggers for logger in self.loggers: logger.setLevel(DB) # console log handler if self.consoleLogging: console = logging.StreamHandler() console.setFormatter( CensoredFormatter('%(asctime)s %(levelname)s::%(message)s', '%H:%M:%S')) console.setLevel(INFO if not self.debugLogging else DEBUG) for logger in self.loggers: logger.addHandler(console) # rotating log file handler if self.fileLogging: rfh = logging.handlers.RotatingFileHandler(self.logFile, maxBytes=1024 * 1024, backupCount=5, encoding='utf-8') rfh.setFormatter( CensoredFormatter('%(asctime)s %(levelname)-8s %(message)s', '%Y-%m-%d %H:%M:%S')) rfh.setLevel(DEBUG) for logger in self.loggers: logger.addHandler(rfh) def log(self, msg, level=INFO, *args, **kwargs): meThread = threading.currentThread().getName() message = meThread + u" :: " + msg # pass exception information if debugging enabled if level == ERROR: self.logger.exception(message, *args, **kwargs) classes.ErrorViewer.add(classes.UIError(message)) #if sickbeard.GIT_AUTOISSUES: # self.submit_errors() else: self.logger.log(level, message, *args, **kwargs) def log_error_and_exit(self, error_msg, *args, **kwargs): self.log(error_msg, ERROR, *args, **kwargs) if not self.consoleLogging: sys.exit( error_msg.encode(sickbeard.SYS_ENCODING, 'xmlcharrefreplace')) else: sys.exit(1) def submit_errors(self): if not (sickbeard.GIT_USERNAME and sickbeard.GIT_PASSWORD and len(classes.ErrorViewer.errors) > 0): return gh_org = sickbeard.GIT_ORG or 'SiCKRAGETV' gh_repo = 'sickrage-issues' self.gh_issues = Github( login_or_token=sickbeard.GIT_USERNAME, password=sickbeard.GIT_PASSWORD, user_agent="SiCKRAGE").get_organization(gh_org).get_repo(gh_repo) try: # read log file if self.logFile and os.path.isfile(self.logFile): with ek.ek(open, self.logFile) as f: log_data = f.readlines() log_data = [line for line in reversed(log_data)] # parse and submit errors to issue tracker for curError in sorted(classes.ErrorViewer.errors, key=lambda error: error.time, reverse=True)[:500]: if not curError.title: continue pastebin_url = None regex = "^(%s)\s*([A-Z]+)\s*(.+?)\s*\:\:\s*(.*)$" % curError.time for i, x in enumerate(log_data): x = ek.ss(x) match = re.match(regex, x) if match: level = match.group(2) if reverseNames[level] == ERROR: paste_data = "".join(log_data[i:50]) pastebin_url = PastebinAPI().paste( 'f59b8e9fa1fc2d033e399e6c7fb09d19', paste_data) break message = u"### INFO\n" message += u"Python Version: **" + sys.version[:120] + "**\n" message += u"Operating System: **" + platform.platform( ) + "**\n" message += u"Branch: **" + sickbeard.BRANCH + "**\n" message += u"Commit: SiCKRAGETV/SickRage@" + sickbeard.CUR_COMMIT_HASH + "\n" if pastebin_url: message += u"Pastebin Log URL: " + pastebin_url + "\n" message += u"### ERROR\n" message += u"```\n" message += curError.message + "\n" message += u"```\n" message += u"---\n" message += u"_STAFF NOTIFIED_: @SiCKRAGETV/owners @SiCKRAGETV/moderators" issue = self.gh_issues.create_issue( "[APP SUBMITTED]: " + curError.title, message) if issue: self.log( 'Your issue ticket #%s was submitted successfully!' % issue.number) if not sickbeard.GIT_AUTOISSUES: ui.notifications.message( 'Your issue ticket #%s was submitted successfully!' % issue.number) # clear error from error list classes.ErrorViewer.errors.remove(curError) except Exception as e: self.log(sickbeard.exceptions.ex(e), ERROR)