1
+ import argparse
2
+ import logging
3
+ import tweepy
4
+ import time
5
+ import os
6
+ import sys
7
+ import json
8
+ import stdiomask
9
+
10
+ from typing import Any , Dict , List , Optional , Tuple
11
+ from styles import in_color , styled_input
12
+ from bots .getUser import getUser
13
+ from bots .followfollowers import follow_followers
14
+ from bots .favRetweet import retweet
15
+ from bots .autoreply import check_mentions
16
+
17
+ auth_keys = {
18
+ 'TWITTER_CONSUMER_KEY' : '' ,
19
+ 'TWITTER_CONSUMER_SECRET' : '' ,
20
+ 'TWITTER_ACCESS_TOKEN' : '' ,
21
+ 'TWITTER_ACCESS_TOKEN_SECRET' : '' ,
22
+ }
23
+
24
+ # Basic config needs to be called atleast once, to set the level properly.
25
+ logging .basicConfig ()
26
+ # Set the level to INFO to write all logs with level >= info to stdout.
27
+ logging .root .setLevel (logging .INFO )
28
+ # Get the logger object
29
+ logger = logging .getLogger ()
30
+
31
+
32
+ def read_keys_from_env_vars () -> bool :
33
+ global auth_keys
34
+ logger .info (' Searching for Authentication keys in Environment varibales...' )
35
+ time .sleep (1 )
36
+ for key in auth_keys :
37
+ auth_keys [key ] = os .getenv (auth_keys [key ])
38
+ if auth_keys [key ] is None :
39
+ logger .error (f' Key─ { key } not found in environment variables. Select other method for authentication.\n ' )
40
+ time .sleep (1 )
41
+ return False
42
+ logger .info (' All Authentication keys found.' )
43
+ return True
44
+
45
+ def read_keys_from_user () -> None :
46
+ global auth_keys
47
+ logger .info (' Please Enter the following authentication keys to login...' )
48
+ time .sleep (0.5 )
49
+ for key in auth_keys :
50
+ if key .endswith ('_SECRET' ):
51
+ auth_keys [key ] = stdiomask .getpass (in_color ('blue' , f"{ key } -> " ), mask = "*" )
52
+ else :
53
+ auth_keys [key ] = styled_input (f"{ key } -> " )
54
+
55
+ def read_keys_from_file () -> None :
56
+ global auth_keys
57
+ print ('Please ensure that your JSON file is in curent working directory.' )
58
+ filename = styled_input ('Enter the filename ─ ' )
59
+ filename = filename + '.json'
60
+ if os .path .exists (f"./{ filename } " ):
61
+ file = open (filename )
62
+ db = json .load (file )
63
+ if db .keys () == auth_keys .keys ():
64
+ auth_keys = db
65
+ logger .info (' All Authentication keys found.\n ' )
66
+ return None
67
+ else :
68
+ logger .error (' File missing some keys. Please re-check the file.\n ' )
69
+ read_keys_from_file ()
70
+ return None
71
+ else :
72
+ logger .error ('Incorrect path. Please try again.\n ' )
73
+ read_keys_from_file ()
74
+ return None
75
+
76
+ def get_authentication_method_and_verify () -> Any :
77
+ global auth_keys
78
+ print ('Please select an authentication method:' )
79
+ print ('\t [1] Get authentication keys from my Environment variables.' )
80
+ print ('\t [2] Get authentication keys from an input file.' )
81
+ print ('\t [3] Let me input the authentication keys myself.\n ' )
82
+ auth_method = input ('Enter your choice ─ ' )
83
+ while auth_method not in ['1' , '2' , '3' ]:
84
+ print ('You have entered an incorrect input. Please enter a valid choice.' )
85
+ auth_method = input ('Enter your choice ─ ' )
86
+
87
+ if auth_method == '1' :
88
+ keys = read_keys_from_env_vars ()
89
+ if not keys :
90
+ return False
91
+ elif auth_method == '2' :
92
+ read_keys_from_file ()
93
+ elif auth_method == '3' :
94
+ read_keys_from_user ()
95
+ else :
96
+ logger .error (' An error occured. Please restart TwiBot.' )
97
+ sys .exit (0 )
98
+
99
+ logger .info (' Authenticating...' )
100
+
101
+ auth = tweepy .OAuthHandler (auth_keys ['TWITTER_CONSUMER_KEY' ],
102
+ auth_keys ['TWITTER_CONSUMER_SECRET' ])
103
+ auth .set_access_token (auth_keys ['TWITTER_ACCESS_TOKEN' ],
104
+ auth_keys ['TWITTER_ACCESS_TOKEN_SECRET' ])
105
+
106
+ api = tweepy .API (auth , wait_on_rate_limit = True ,
107
+ wait_on_rate_limit_notify = True )
108
+
109
+ return api
110
+
111
+
112
+ def print_welcome_header (slow : bool = True ) -> None :
113
+ os .system ('cls' if os .name == 'nt' else 'clear' )
114
+ print (in_color ('purple' , '────────────────────────────────────────────────────────────' ))
115
+ print (in_color ('purple' , ' Welcome to TwiBot' ))
116
+ print (in_color ('purple' , '────────────────────────────────────────────────────────────\n ' ))
117
+ if slow :
118
+ time .sleep (1 )
119
+
120
+ def get_feature_choice () -> str :
121
+ print ('Twibot can do the following for you. Please select an option:' )
122
+ print ('\t [1] Search twitter for a user.' )
123
+ print ('\t [2] Follow-back all your followers.' )
124
+ print ('\t [3] Search and re-tweet a tweet.' )
125
+ print ('\t [4] Autoreply to tweets mentioning you, or some keyword.\n ' )
126
+
127
+ choice = input ('Enter your choice ─ ' )
128
+ while choice not in ['1' , '2' , '3' , '4' ]:
129
+ print ('You have entered an incorrect input. Please enter a valid choice.' )
130
+ choice = input ('Enter your choice ─ ' )
131
+
132
+ return choice
133
+
134
+ def main ():
135
+ """
136
+ Launch TwiBot.
137
+ """
138
+ print_welcome_header (slow = True )
139
+
140
+ api = get_authentication_method_and_verify ()
141
+ while not api :
142
+ api = get_authentication_method_and_verify ()
143
+
144
+ try :
145
+ response = api .verify_credentials ()
146
+ except Exception as e :
147
+ logger .error ("Error creating API. Bad Authentication data" , exc_info = True )
148
+ sys .exit (0 )
149
+
150
+ print (in_color ('green' , "Authentication OK ─ API created...\n " ))
151
+ time .sleep (1.5 )
152
+
153
+ print_welcome_header (slow = False )
154
+ choice = get_feature_choice ()
155
+
156
+ if choice == '1' :
157
+ getUser (api )
158
+ elif choice == '2' :
159
+ follow_followers (api )
160
+ elif choice == '3' :
161
+ retweet (api )
162
+ elif choice == '4' :
163
+ check_mentions (api )
164
+
165
+
166
+ if __name__ == '__main__' :
167
+ main ()
0 commit comments