CoolFace
Apppublic

team6/roast

sourceHugging Faceupdated 4y agoView on Hugging Face
0likes
main.py217 linesDownload Raw Back to root
1import logging2import os3import re4import time5import traceback6from threading import Thread7from pathlib import Path8 9import openai10import pandas as pd11import requests12import tweepy13from huggingface_hub import upload_file14import gradio as gr15logger = logging.getLogger()16logging.basicConfig(level=logging.INFO)17logger.setLevel(logging.INFO)18 19bot_user_id = 161210681509699993620bot_user_name = "RoastOrToastGPT"21 22persistent_storage_repo_id = "team6/roast-history"23persistent_storage_file_name = "history.csv"24persistent_storage_file_url = (25    f"https://huggingface.co/datasets/{persistent_storage_repo_id}/resolve/main/{persistent_storage_file_name}"26)27 28# will be used to remove the @roastortoastgpt from the tweet text (case insensitive)29pattern_at_mention = re.compile(re.escape("@roastortoastgpt"), re.IGNORECASE)30 31print(persistent_storage_file_url)32 33openai_key = os.environ.get("openai_api_key")34consumer_key = os.environ.get("consumer_key")35consumer_secret_key = os.environ.get("consumer_secret_key")36access_token = os.environ.get("access_token")37access_token_secret = os.environ.get("access_token_secret")38bearer_token = os.environ.get("bearer_token")39hf_token = os.environ.get("hf_token")40 41client = tweepy.Client(42    bearer_token=bearer_token,43    consumer_key=consumer_key,44    consumer_secret=consumer_secret_key,45    access_token=access_token,46    access_token_secret=access_token_secret,47    wait_on_rate_limit=True,48)49 50 51def response(text):52    openai.api_key = openai_key53    response = openai.Completion.create(54        engine="text-davinci-002",55        prompt=text,56        temperature=0.9,57        max_tokens=60,58        top_p=1,59        frequency_penalty=0,60        presence_penalty=1.0,61    )62 63    return response.choices[0].text.strip()64 65 66def roast(text):67    return response(68        f"Humorously mock, humiliate and hurt the user's feelings with a well-timed joke, diss or comeback based on the info.\n\nInfo: {text}\n\nResponse:"69    )70 71 72def toast(text):73    return response(74        f"Give the user a genuine and unique compliment to make them feel good about themselves based on the info in a good style manner.\n\nInfo: {text}\n\nResponse:"75    )76 77 78def reply_to_mentions():79    df = pd.read_csv(persistent_storage_file_url)80    last_tweet_id = df.iloc[-1]["id"]81 82    # List of unique conversation ids that we've already responded to.83    # This is to prevent us from responding to the same conversation twice.84    all_convo_ids = df["conversation_id"].unique().tolist()85 86    # get the mentions. These are both direct mentions and replies to our tweets87    mentions = client.get_users_mentions(88        id=bot_user_id,89        expansions=["author_id", "in_reply_to_user_id", "referenced_tweets.id"],90        tweet_fields=["conversation_id"],91        since_id=last_tweet_id,92    )93 94    # if there are no new mentions, return95    if mentions.data is None:96        # log it97        logger.info("No new mentions found")98        return99 100    data_to_add = {"id": [], "conversation_id": []}101    # otherwise, iterate through the mentions and respond to them102    # we iterate through the mentions in reverse order so that we respond to the oldest mentions first103    for mention in reversed(mentions.data):104 105        if mention.author_id == bot_user_id:106            # don't respond to our own tweets107            logger.info(f"Skipping {mention.id} as it is from the bot")108            continue109 110        if mention.in_reply_to_user_id == bot_user_id:111            # don't respond to our own tweets112            logger.info(f"Skipping {mention.id} as the tweet to roast is from the bot")113            continue114 115        if not mention.referenced_tweets:116            logger.info(f"Skipping {mention.id} as it is not a reply")117            continue118 119        # if we've already responded to this conversation, skip it120        # also should catch the case where we've already responded to this tweet (though that shouldn't happen)121        if mention.conversation_id in all_convo_ids:122            logger.info(f"Skipping {mention.id} as we've already responded to this conversation")123            continue124 125        logger.info(f"Responding to {mention.id}, which said {mention.text}")126 127        tweet_to_roast_id = mention.referenced_tweets[0].id128        tweet_to_roast = client.get_tweet(tweet_to_roast_id)129        text_to_roast = tweet_to_roast.data.text130 131        mention_text = mention.text132        mention_text = pattern_at_mention.sub("", mention_text)133        logger.info(f"Mention Text: {mention_text}")134 135        if "roast" in mention_text.lower():136            logger.info(f"Roasting {mention.id}")137            text_out = roast(text_to_roast)138        elif "toast" in mention_text.lower():139            logger.info(f"Toasting {mention.id}")140            text_out = toast(text_to_roast)141        else:142            logger.info(f"Skipping {mention.id} as it is not a roast or toast")143            continue144 145        # Quote tweet the tweet to roast146        logger.info(f"Quote tweeting {tweet_to_roast_id} with response: {text_out}")147        quote_tweet_response = client.create_tweet(148            text=text_out,149            quote_tweet_id=tweet_to_roast_id,150        )151        print("QUOTE TWEET RESPONSE", quote_tweet_response.data)152        response_quote_tweet_id = quote_tweet_response.data.get("id")153        logger.info(f"Response Quote Tweet ID: {response_quote_tweet_id}")154        response_quote_tweet_url = f"https://twitter.com/{bot_user_name}/status/{response_quote_tweet_id}"155        logger.info(f"Response Quote Tweet URL: {response_quote_tweet_url}")156 157        # reply to the mention with the link to the response tweet158        logger.info(f"Responding to: {mention.id}")159        response_reply = client.create_tweet(160            text=f"Here's my response: {response_quote_tweet_url}",161            in_reply_to_tweet_id=mention.id,162        )163        response_reply_id = response_reply.data.get("id")164        logger.info(f"Response Reply ID: {response_reply_id}")165 166        # add the mention to the history167        data_to_add["id"].append(mention.id)168        data_to_add["conversation_id"].append(mention.conversation_id)169 170        # add a line break to the log171        logger.info("-" * 100)172 173    # update the history df and upload it to the persistent storage repo174    if len(data_to_add["id"]) == 0:175        logger.info("No new mentions to add to the history")176        return177 178    logger.info(f"Adding {len(data_to_add['id'])} new mentions to the history")179 180    df_to_add = pd.DataFrame(data_to_add)181    df = pd.concat([df, df_to_add], ignore_index=True)182    df.to_csv(persistent_storage_file_name, index=False)183    upload_file(184        repo_id=persistent_storage_repo_id,185        path_or_fileobj=persistent_storage_file_name,186        path_in_repo=persistent_storage_file_name,187        repo_type="dataset",188        token=hf_token,189    )190 191 192def main():193    logger.info("Starting up...")194 195    while True:196        try:197            # Dummy request to keep the Hugging Face Space awake198            # Not really working as far as I can tell199            # logger.info("Pinging Hugging Face Space...")200            # requests.get("https://team6-roast.hf.space/", timeout=5)201            logger.info("Replying to mentions...")202            reply_to_mentions()203        except Exception as e:204            logger.error(e)205            traceback.print_exc()206 207        logger.info("Sleeping for 30 seconds...")208        time.sleep(30)209 210with gr.Blocks() as demo:211    gr.Markdown(Path('README.md').read_text())212 213thread = Thread(target=main, daemon=True)214 215if __name__ == "__main__":216    thread.start()217    demo.launch()