from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from textblob import TextBlob
import re
from tweepy import Stream
from tweepy import API
from tweepy import Cursor
import numpy as np
import pandas as pd
from twitter_credentials import *
import matplotlib.pyplot as plt
class TwitterClient():
    def __init__(self,twitter_user=None):
        self.auth=TwitterAuthenticator().authenticate_twitter_app()
        self.twitter_client = API(self.auth)
        self.twitter_user=twitter_user
    def get_twitter_client_api(self):
        return self.twitter_client
    def get_user_timeline_tweets(self,num_tweets):
        tweets=[]
        for tweet in Cursor(self.twitter_client.user_timeline,id=self.twitter_user).items(num_tweets):
            tweets.append(tweet)
        return tweets
    def get_friend_list(self,num_friends):
        friend_list=[]
        for friend in Cursor(self.twitter_client.friends).items(num_friends):
            friend_list.append(friend)
        return friend_list
    def get_home_timeline_tweets(self, num_tweets):
        home_timeline_tweets=[]
        for tweet in Cursor(self.twitter_client.home_timeline).items(num_tweets):
            home_timeline_tweets.append(tweet)
        return home_timeline_tweets

class TwitterAuthenticator():
    def  authenticate_twitter_app(self):
        auth = OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET)           
        auth.set_access_token(ACCESS_TOKEN,ACCESS_TOKEN_SECRET)
        return auth

class TwitterStreamer():
    def __init__(self):
        self.twitter_authenticator=TwitterAuthenticator()

    def stream_tweets(self,fetched_tweets_filename,hash_tag_list,out):
        listener = TwitterListener(fetched_tweets_filename)
        auth = self.twitter_authenticator.authenticate_twitter_app()
        stream = Stream(auth, listener)
        stream.filter(track=hash_tag_list)
        timeout=out

class TwitterListener(StreamListener):
    def __init__(self,fetched_tweets_filename):
        self.fetched_tweets_filename=fetched_tweets_filename

    def on_data(self, data):
        try:
           print(data)
           with open(self.fetched_tweets_filename,'a') as tf:
               tf.write(data)
           return True
        except BaseException as e:
           print("ERROR on_data %s" % str(e))
        return True

    def on_error(self, status):
        if status==420:
            return False
       
        print(status)
class TweetAnalyzer():
    def tweets_to_data_frame(self,tweets):
        df=pd.DataFrame(data=[tweet.text for tweet in tweets],columns=['Tweets'])
        df['id']=np.array([tweet.id for tweet in tweets])
        df['length']=np.array([len(tweet.text) for tweet in tweets]) 
        df['date']=np.array([tweet.created_at for tweet in tweets])
        df['source']=np.array([tweet.source for tweet in tweets]) 
        df['likes']=np.array([tweet.favorite_count for tweet in tweets])
        df['retweets']=np.array([tweet.retweet_count for tweet in tweets])
        return df
    def clean_tweet(self, tweet):
        return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", tweet).split())
    def analyze_sentiment(self, tweet):
        analysis = TextBlob(self.clean_tweet(tweet))
        if analysis.sentiment.polarity > 0:
         return 1
        elif analysis.sentiment.polarity == 0:
         return 
        else:
         return -1

if __name__ == '__main__':
    twitter_client=TwitterClient()
    api=twitter_client.get_twitter_client_api()
    tweets=api.user_timeline(screen_name="narendramodi",count=2)
    #print(tweets)
    tweet_analyzer=TweetAnalyzer()
    st=TwitterStreamer()
    df=tweet_analyzer.tweets_to_data_frame(tweets)
    print(df.head(2))
    x=TwitterAuthenticator()
    auth=x.authenticate_twitter_app()
    y=API(auth,wait_on_rate_limit=True)
    tweetstest=[]
    for tweet in Cursor(y.search,q="#coronavirus",count=10).items(20):
        tweetstest.append(tweet)
    df2=tweet_analyzer.tweets_to_data_frame(tweetstest)
    df2['sentiment']=np.array([tweet_analyzer.analyze_sentiment(tweet) for tweet in df2['Tweets']])
    print(df2.head(20))
