From 6b112d023e337a6ed296b42502a1928e2055ecbe Mon Sep 17 00:00:00 2001 From: Emmanuel Arias Date: Sun, 11 Jun 2017 09:05:53 +0200 Subject: [PATCH] merging PR #550: Re Reopen #443 according to #364 - Twitter Api Working https://github.com/chaosbot/Chaos/pull/550: Re Reopen #443 according to #364 - Twitter Api Working Description: Fix encryptation problems, regenerate twitter keys @PlasmaPower :white_check_mark: PR passed with a vote of 6 for and 0 against, a weighted total of 6.0 and a threshold of 6.0, and a current meritocracy review. Vote record: @Leigende: 1 @PlasmaPower: 1 @andrewda: 1 @eamanu: 1 @kylerschin: 1 @rudehn: 1 --- .gitignore | 1 + chaos.py | 17 +++++++++++++- cron/__init__.py | 4 ++-- cron/poll_pull_requests.py | 17 ++++++++++++-- encryption.py | 2 +- requirements.txt | 4 +++- settings.py | 15 +++++++++++++ twitter_api/Twitter.py | 14 ++++++++++++ twitter_api/__init__.py | 17 ++++++++++++++ twitter_api/misc.py | 42 +++++++++++++++++++++++++++++++++++ twitter_keys/access_secret | 1 + twitter_keys/access_token | Bin 0 -> 256 bytes twitter_keys/consumer_key | 2 ++ twitter_keys/consumer_secret | 2 ++ 14 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 twitter_api/Twitter.py create mode 100644 twitter_api/__init__.py create mode 100644 twitter_api/misc.py create mode 100644 twitter_keys/access_secret create mode 100644 twitter_keys/access_token create mode 100644 twitter_keys/consumer_key create mode 100644 twitter_keys/consumer_secret diff --git a/.gitignore b/.gitignore index e0cf39e3..fd7037d0 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ server/issue_commands_ran.json .migrated ansible/*.retry db.sqlite +*privkey diff --git a/chaos.py b/chaos.py index e48844a6..ebe24a4f 100644 --- a/chaos.py +++ b/chaos.py @@ -11,6 +11,7 @@ import schedule import cron import shutil +import datetime # this import must happen before any github api stuff gets imported. it sets # up caching on the api functions so we don't run out of api requests @@ -27,6 +28,11 @@ # Currently imported just for the sideeffect (not currently being used) import encryption # noqa: F401 +# To make post in Twitter +import twitter_api as ta +# import twitter_api.misc +# import twitter_api.Twitter + class LessThanFilter(logging.Filter): """ @@ -69,12 +75,21 @@ def main(): api = gh.API(settings.GITHUB_USER, settings.GITHUB_SECRET) + # Api Twitter + api_twitter = ta.API_TWITTER(settings.TWITTER_API_KEYS_FILE) + log.info("checking if I crashed before...") + ta.Twitter.PostTwitter(datetime.datetime.ctime(datetime.datetime.now()) + + " - checking if I crashed before...", + api_twitter.GetApi()) # check if chaosbot is not on the tip of the master branch check_for_prev_crash(api, log) log.info("starting up and entering event loop") + ta.Twitter.PostTwitter(datetime.datetime.ctime(datetime.datetime.now()) + + " - starting up and entering event loop", + api_twitter.GetApi()) os.system("pkill uwsgi") @@ -86,7 +101,7 @@ def main(): "--daemonize", "/root/workspace/Chaos/log/uwsgi.log"]) # Schedule all cron jobs to be run - cron.schedule_jobs(api) + cron.schedule_jobs(api, api_twitter) log.info("Setting description to {desc}".format(desc=settings.REPO_DESCRIPTION)) github_api.repos.set_desc(api, settings.URN, settings.REPO_DESCRIPTION) diff --git a/cron/__init__.py b/cron/__init__.py index dc1bde42..eef55681 100644 --- a/cron/__init__.py +++ b/cron/__init__.py @@ -6,9 +6,9 @@ from .poll_issue_close_stale import poll_issue_close_stale -def schedule_jobs(api): +def schedule_jobs(api, api_twitter): schedule.every(settings.PULL_REQUEST_POLLING_INTERVAL_SECONDS).seconds.do( - lambda: poll_pull_requests(api)) + lambda: poll_pull_requests(api, api_twitter)) schedule.every(settings.ISSUE_COMMENT_POLLING_INTERVAL_SECONDS).seconds.do( lambda: poll_read_issue_comments(api)) schedule.every(settings.ISSUE_CLOSE_STALE_INTERVAL_SECONDS).seconds.do( diff --git a/cron/poll_pull_requests.py b/cron/poll_pull_requests.py index fa7a19af..4fdeafe2 100644 --- a/cron/poll_pull_requests.py +++ b/cron/poll_pull_requests.py @@ -4,16 +4,19 @@ import sys from os.path import join, abspath, dirname from lib.db.models import MeritocracyMentioned +import datetime import settings import github_api as gh +from twitter_api import Twitter as tw + THIS_DIR = dirname(abspath(__file__)) __log = logging.getLogger("pull_requests") -def poll_pull_requests(api): +def poll_pull_requests(api, api_twitter): __log.info("looking for PRs") # get voting window @@ -93,7 +96,6 @@ def poll_pull_requests(api): if is_approved: __log.info("PR %d status: will be approved", pr_num) - gh.prs.post_accepted_status( api, settings.URN, pr, seconds_since_updated, voting_window, votes, vote_total, threshold, meritocracy_satisfied) @@ -104,13 +106,24 @@ def poll_pull_requests(api): try: sha = gh.prs.merge_pr(api, settings.URN, pr, votes, vote_total, threshold, meritocracy_satisfied) + message_twitter = datetime.datetime.ctime( + datetime.datetime.now()) +\ + " - PR {pr_num} approved for merging".format(pr_num=pr_num) + tw.PostTwitter(message_twitter, api_twitter) # some error, like suddenly there's a merge conflict, or some # new commits were introduced between finding this ready pr and # merging it + # Make a tweet except gh.exceptions.CouldntMerge: __log.info("couldn't merge PR %d for some reason, skipping", pr_num) gh.issues.label_issue(api, settings.URN, pr_num, ["can't merge"]) + message_twitter = datetime.datetime.ctime( + datetime.datetime.now()) +\ + "Couldn't merge PR {pr_num} for some reason, \ + skipping".format(pr_num=pr_num) + + tw.PostTwitter(message_twitter, api_twitter) continue gh.comments.leave_accept_comment( diff --git a/encryption.py b/encryption.py index 45be7a6c..ef96cba4 100644 --- a/encryption.py +++ b/encryption.py @@ -45,4 +45,4 @@ def decrypt(ciphertext): return decrypt -decrypt = create_decryptor("/etc/privkey", "server/pubkey.txt") +decrypt = create_decryptor("privkey", "server/pubkey.txt") diff --git a/requirements.txt b/requirements.txt index 182aac9a..ec09bb5f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -24,6 +24,8 @@ sh==1.12.13 six==1.10.0 flake8==3.3.0 unidiff==0.5.4 +python-twitter==3.3 +pymysql hug==2.3.0 uWSGI==2.0.15 -peewee +peewee \ No newline at end of file diff --git a/settings.py b/settings.py index af2844ca..40e674d1 100644 --- a/settings.py +++ b/settings.py @@ -38,6 +38,21 @@ HOMEPAGE = "http://chaosthebot.com" +# To Twitter Posts +_twitter_api_keys = 'api_twitter.keys' + +# Look for local Keys first +_twitter_api_keys_file = join(THIS_DIR, _twitter_api_keys) + +# fall back to system twitter keys +if not exists(_twitter_api_keys): + _twitter_api_keys_file = join('/etc/', _twitter_api_keys) + +if exists(_twitter_api_keys_file): + TWITTER_API_KEYS_FILE = _twitter_api_keys_file +else: + TWITTER_API_KEYS_FILE = None + # TEST SETTING PLEASE IGNORE TEST = False diff --git a/twitter_api/Twitter.py b/twitter_api/Twitter.py new file mode 100644 index 00000000..5e753404 --- /dev/null +++ b/twitter_api/Twitter.py @@ -0,0 +1,14 @@ +import logging + +log = logging.getLogger("twitter") + + +def PostTwitter(message, api_twitter): + if len(message) > 140: + print('Post has more of 140 chars') + api = api_twitter + try: + api.PostUpdate(message) + except: + log.exception("Failed to post to Twitter") + return 0 diff --git a/twitter_api/__init__.py b/twitter_api/__init__.py new file mode 100644 index 00000000..1d7b1e2e --- /dev/null +++ b/twitter_api/__init__.py @@ -0,0 +1,17 @@ +from . import misc +import twitter + + +__all__ = ["misc", "twitter"] + + +class API_TWITTER(): + def __init__(self, path): + self.__twitter_keys = misc.GetKeys(path) + self.__api = twitter.Api(consumer_key=str(self.__twitter_keys['consumer_key']), + consumer_secret=str(self.__twitter_keys['consumer_secret']), + access_token_key=str(self.__twitter_keys['access_token']), + access_token_secret=str(self.__twitter_keys['access_secret'])) + + def GetApi(self): + return self.__api diff --git a/twitter_api/misc.py b/twitter_api/misc.py new file mode 100644 index 00000000..1d2a7cc8 --- /dev/null +++ b/twitter_api/misc.py @@ -0,0 +1,42 @@ +from encryption import decrypt + + +def GetKeys(twitter_keys_path): + consumer_key = '' + consumer_secret = '' + access_token = '' + access_secret = '' + PATH = 'twitter_keys/' + l_files = ['consumer_key', 'consumer_secret', 'access_token', 'access_secret'] + + for k in l_files: + f = open(PATH + k, 'rb') + key = f.read() + if (k == 'consumer_key'): + consumer_key = decrypt(key) + if (k == 'consumer_secret'): + consumer_secret = decrypt(key) + if (k == 'access_token'): + access_token = decrypt(key) + if (k == 'access_secret'): + access_secret = decrypt(key) + f.close() + """ + for k in keys: + try: + values = k.split('\n')[0].split('=')[1].strip() + if(k.split('\n')[0].split('=')[0].strip() == 'consumer_key'): + consumer_key = decrypt(values) + elif(k.split('\n')[0].split('=')[0].strip() == 'consumer_secret'): + consumer_secret = decrypt(values) + elif(k.split('\n')[0].split('=')[0].strip() == 'access_token'): + access_token = decrypt(values) + elif(k.split('\n')[0].split('=')[0].strip() == 'access_secret'): + access_secret = decrypt(values) + except IndexError: + # Maybe there are a '\n' between keys + continue + + """ + return {'consumer_key': consumer_key, 'consumer_secret': consumer_secret, + 'access_token': access_token, 'access_secret': access_secret} diff --git a/twitter_keys/access_secret b/twitter_keys/access_secret new file mode 100644 index 00000000..4e13c567 --- /dev/null +++ b/twitter_keys/access_secret @@ -0,0 +1 @@ +WÈ]p\E}3N|f${j&c4%fCIe}C[/ucf6Hyު6Mա\8@ܸH|ą1/C 4cnNORQm|h[f(bYD7}G(z-Lr)Þ"FJ]JNvinRxW}?:iׅv˸zH8FVom?I_cCH@z3&>|x80h5u2sTx5NG(*b~ z%HFLQ?c+Y}7ChNtEk$DMZR;JV^(rQL@Ov_P0Kptt%^K7{Iv{7oSO=pLOm-4b)rGJL zI%4OhGBg^&GrBY0hkriu74Q~6T&}NFAz9;4=Z{hf*u7%ajN&Cl zfA(TW3_B0vjz1GRl?^BBGY$wSq3A00a@YL?P"Y#|=@l%c@_f''Pp +46}kl \ No newline at end of file