mirror of
git://git.acid.vegas/booster.git
synced 2024-11-22 07:46:37 +00:00
Initial commit
This commit is contained in:
commit
624276b818
15
LICENSE
Normal file
15
LICENSE
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (c) 2019, acidvegas <acid.vegas@acid.vegas>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
###### Requirments
|
||||||
|
* [Tweepy](http://pypi.python.org/pypi/tweepy)
|
||||||
|
|
||||||
|
###### Instructions
|
||||||
|
Register a Twitter account, and [sign up](http://dev.twitter.com/apps/new) for a new developer application.
|
||||||
|
|
||||||
|
Go to your new application settings "Keys and Access Tokens" tab.
|
||||||
|
|
||||||
|
Click the "Create Your Access Token" button on the bottom.
|
||||||
|
|
||||||
|
These will be used in the config to connect to your Twitter account.
|
||||||
|
|
||||||
|
Go to your new application settings "Permissions".
|
||||||
|
|
||||||
|
Change your access to "Read, Write and Access direct messages".
|
||||||
|
|
||||||
|
Edit your `config.py` and change the Twitter API settings.
|
||||||
|
|
||||||
|
###### Mirrors
|
||||||
|
- [acid.vegas](https://acid.vegas/booster) *(main)*
|
||||||
|
- [SuperNETs](https://git.supernets.org/acidvegas/booster)
|
||||||
|
- [GitHub](https://github.com/acidvegas/booster)
|
||||||
|
- [GitLab](https://gitlab.com/acidvegas/booster)
|
20
booster/booster.py
Normal file
20
booster/booster.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
|
||||||
|
# booster.py
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.dont_write_bytecode = True
|
||||||
|
|
||||||
|
import debug
|
||||||
|
|
||||||
|
debug.info()
|
||||||
|
if not debug.check_version(3):
|
||||||
|
debug.error_exit('Requires Python version 3 to run!')
|
||||||
|
if debug.check_privileges():
|
||||||
|
debug.error_exit('Do not run as admin/root!')
|
||||||
|
debug.check_imports()
|
||||||
|
debug.check_config()
|
||||||
|
import twitter
|
||||||
|
twitter.Booster().run()
|
||||||
|
debug.keep_alive()
|
26
booster/config.py
Normal file
26
booster/config.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
|
||||||
|
# config.py
|
||||||
|
|
||||||
|
# API Settings
|
||||||
|
consumer_key = 'CHANGEME'
|
||||||
|
consumer_secret = 'CHANGEME'
|
||||||
|
access_token = 'CHANGEME'
|
||||||
|
access_token_secret = 'CHANGEME'
|
||||||
|
|
||||||
|
# Boost Keywords
|
||||||
|
boost_keywords = ['500aday','autofollow','autofollowback','f4f','follow','follow4follow','followback','followtrain','instantfollow','instantfollowback','teamfollowback','wefollowback']
|
||||||
|
|
||||||
|
# Throttling
|
||||||
|
max_favorites = 75 # Only use up to 100 to avoid suspension.
|
||||||
|
max_follows = 75 # Only use up to 100 to avoid suspension.
|
||||||
|
max_messages = 750 # Only use up to 1000 to avoid suspension.
|
||||||
|
max_tweets = 750 # Only use up to 1000 to avoid suspension.
|
||||||
|
max_unfollows = 75 # Only use up to 100 to avoid suspension.
|
||||||
|
|
||||||
|
# Messaging
|
||||||
|
send_message = False # Send a message to anyone who follows you.
|
||||||
|
message = 'Thank you for following our Twitter account!'
|
||||||
|
|
||||||
|
# Where On Earth ID's (http://www.woeidlookup.com/)
|
||||||
|
woeid = 23424975 # United States
|
93
booster/debug.py
Normal file
93
booster/debug.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
|
||||||
|
# debug.py
|
||||||
|
|
||||||
|
import ctypes
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
import config
|
||||||
|
|
||||||
|
def action(msg):
|
||||||
|
print('%s | [#] - %s' % (get_time(), msg))
|
||||||
|
|
||||||
|
def alert(msg):
|
||||||
|
print('%s | [+] - %s' % (get_time(), msg))
|
||||||
|
|
||||||
|
def check_config():
|
||||||
|
for item in (config.consumer_key, config.consumer_secret, config.access_token, config.access_token_secret):
|
||||||
|
if item == 'CHANGEME':
|
||||||
|
error_exit('Edit your config file!')
|
||||||
|
|
||||||
|
def check_imports():
|
||||||
|
try:
|
||||||
|
import tweepy
|
||||||
|
except ImportError:
|
||||||
|
error_exit('Failed to import the Tweepy library! (http://pypi.python.org/pypi/tweepy)')
|
||||||
|
|
||||||
|
def check_privileges():
|
||||||
|
if check_windows():
|
||||||
|
if ctypes.windll.shell32.IsUserAnAdmin() != 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if os.getuid() == 0 or os.geteuid() == 0:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_version(major):
|
||||||
|
if sys.version_info.major == major:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def check_windows():
|
||||||
|
if os.name == 'nt':
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def clear():
|
||||||
|
if check_windows():
|
||||||
|
os.system('cls')
|
||||||
|
else:
|
||||||
|
os.system('clear')
|
||||||
|
|
||||||
|
def error(msg, reason=None):
|
||||||
|
if reason:
|
||||||
|
print('%s | [!] - %s (%s)' % (get_time(), msg, str(reason)))
|
||||||
|
else:
|
||||||
|
print('%s | [!] - %s' % (get_time(), msg))
|
||||||
|
|
||||||
|
def error_exit(msg):
|
||||||
|
raise SystemExit('%s | [!] - %s' % (get_time(), msg))
|
||||||
|
|
||||||
|
def get_time():
|
||||||
|
return time.strftime('%I:%M:%S')
|
||||||
|
|
||||||
|
def get_windows():
|
||||||
|
if os.name == 'nt':
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def info():
|
||||||
|
clear()
|
||||||
|
print(''.rjust(56, '#'))
|
||||||
|
print('#{0}#'.format(''.center(54)))
|
||||||
|
print('#{0}#'.format('Booster Twitter Bot'.center(54)))
|
||||||
|
print('#{0}#'.format('Developed by acidvegas in Python 3'.center(54)))
|
||||||
|
print('#{0}#'.format('https://acid.vegas/booster'.center(54)))
|
||||||
|
print('#{0}#'.format(''.center(54)))
|
||||||
|
print(''.rjust(56, '#'))
|
||||||
|
|
||||||
|
|
||||||
|
def keep_alive():
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
input('')
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
sys.exit()
|
23
booster/functions.py
Normal file
23
booster/functions.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
|
||||||
|
# functions.py
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import random
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
def get_day():
|
||||||
|
return datetime.datetime.today().weekday()
|
||||||
|
|
||||||
|
def get_source(url):
|
||||||
|
req = urllib.request.Request(url)
|
||||||
|
req.add_header('User-Agent', 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)')
|
||||||
|
source = urllib.request.urlopen(req, timeout=10)
|
||||||
|
charset = source.headers.get_content_charset()
|
||||||
|
if charset:
|
||||||
|
return source.read().decode(charset)
|
||||||
|
else:
|
||||||
|
return source.read().decode()
|
||||||
|
|
||||||
|
def random_int(min, max):
|
||||||
|
return random.randint(min, max)
|
168
booster/twitter.py
Normal file
168
booster/twitter.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# Booster Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/booster)
|
||||||
|
# twitter.py
|
||||||
|
|
||||||
|
import random
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
import tweepy
|
||||||
|
|
||||||
|
import config
|
||||||
|
import debug
|
||||||
|
import functions
|
||||||
|
|
||||||
|
class Booster(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.api = None
|
||||||
|
self.me = None
|
||||||
|
self.favorites = 0
|
||||||
|
self.max_favorites = config.max_favorites
|
||||||
|
self.follows = 0
|
||||||
|
self.max_follows = config.max_follows
|
||||||
|
self.messages = 0
|
||||||
|
self.max_messages = config.max_messages
|
||||||
|
self.tweets = 0
|
||||||
|
self.max_tweets = config.max_tweets
|
||||||
|
self.unfollows = 0
|
||||||
|
self.max_unfollows = config.max_unfollows
|
||||||
|
self.send_message = config.send_message
|
||||||
|
self.message = config.message
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.login()
|
||||||
|
threading.Thread(target=self.loop_boost).start()
|
||||||
|
threading.Thread(target=self.loop_favorite).start()
|
||||||
|
threading.Thread(target=self.loop_follow).start()
|
||||||
|
threading.Thread(target=self.loop_search).start()
|
||||||
|
# threading.Thread(target=self.loop_trend).start()
|
||||||
|
|
||||||
|
def login(self):
|
||||||
|
try:
|
||||||
|
auth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret)
|
||||||
|
auth.set_access_token(config.access_token, config.access_token_secret)
|
||||||
|
self.api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
|
||||||
|
self.me = self.api.me()
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error_exit('Failed to login to Twitter! ({0})'.format(str(ex)))
|
||||||
|
|
||||||
|
def loop_boost(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
if 'boost_tweet' in locals(): self.api.destroy_status(boost_tweet.id)
|
||||||
|
boost_tweet = self.api.update_status('RT for followers! #' + ' #'.join(config.boost_keywords))
|
||||||
|
self.tweets += 1
|
||||||
|
debug.alert('Re-posted boost tweet.')
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Error occured in the boost loop', ex)
|
||||||
|
finally:
|
||||||
|
random.shuffle(config.boost_keywords)
|
||||||
|
time.sleep(60*5)
|
||||||
|
|
||||||
|
def loop_favorite(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
for tweet in tweepy.Cursor(api.home_timeline, exclude_replies=True).items(50):
|
||||||
|
if tweet.user.screen_name != me.screen_name:
|
||||||
|
if not tweet.favorited:
|
||||||
|
if random.choice((True, False, False, False, False)):
|
||||||
|
api.create_favorite(tweet.id)
|
||||||
|
self.favorites += 1
|
||||||
|
debug.alert('Favorited a friends tweet!')
|
||||||
|
time.sleep(30)
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Error occured in the favorite loop!', ex)
|
||||||
|
finally:
|
||||||
|
time.sleep(60*15)
|
||||||
|
|
||||||
|
def loop_follow(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
followers = api.followers_ids(me.screen_name)
|
||||||
|
friends = api.friends_ids(me.screen_name)
|
||||||
|
non_friends = [friend for friend in followers if friend not in friends]
|
||||||
|
debug.action('Following back {0} supporters...'.format(len(non_friends)))
|
||||||
|
for follower in non_friends:
|
||||||
|
api.create_friendship(follower)
|
||||||
|
self.follows += 1
|
||||||
|
debug.alert('Followed back a follower!')
|
||||||
|
if self.follows >= self.max_follows:
|
||||||
|
break
|
||||||
|
if self.send_message:
|
||||||
|
api.send_direct_message(screen_name=follower, text=self.message)
|
||||||
|
time.sleep(30)
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Error occured in the follow loop!', ex)
|
||||||
|
finally:
|
||||||
|
time.sleep(60*15)
|
||||||
|
|
||||||
|
def loop_search(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
query = random.choice(config.boost_keywords)
|
||||||
|
for item in api.search(q='#' + query, count=50, lang='en', result_type='recent'):
|
||||||
|
if not item.user.following and not item.favorited:
|
||||||
|
try:
|
||||||
|
api.create_favorite(item.id)
|
||||||
|
api.create_friendship(item.user.screen_name)
|
||||||
|
self.favorites += 1
|
||||||
|
self.follows += 1
|
||||||
|
debug.alert('Followed a booster twitter!')
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Unknown error occured in the search loop!', ex)
|
||||||
|
time.sleep(30)
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Error occured in the search loop!', ex)
|
||||||
|
finally:
|
||||||
|
time.sleep(60*15)
|
||||||
|
|
||||||
|
def loop_trend(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
trends = self.api.trends_place(str(config.woeid))
|
||||||
|
hashtags = [x['name'] for x in trends[0]['trends'] if x['name'].startswith('#')]
|
||||||
|
for trend in hashtags:
|
||||||
|
for item in self.api.search(q=trend, count=5, lang='en', result_type='top'):
|
||||||
|
#self.api.update_status(item.tweet) # FIX THIS PART
|
||||||
|
time.sleep(30)
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Error occured in the trend loop!', ex)
|
||||||
|
finally:
|
||||||
|
time.sleep(60*15)
|
||||||
|
|
||||||
|
def loop_unfollow(self):
|
||||||
|
try:
|
||||||
|
followers = self.api.followers_ids(self.me.screen_name)
|
||||||
|
friends = self.api.friends_ids(self.me.screen_name)
|
||||||
|
non_friends = [friend for friend in friends if friend not in followers]
|
||||||
|
non_friends.reverse()
|
||||||
|
debug.action('Unfollowing {0} unsupporting friends...'.format(len(non_friends)))
|
||||||
|
for friend in non_friends:
|
||||||
|
self.api.destroy_friendship(friend)
|
||||||
|
self.unfollows += 1
|
||||||
|
debug.alert('Unfollowed an unsupporting friend!')
|
||||||
|
if self.unfollows == self.max_unfollows:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
time.sleep(60*functions.random_int(10,15))
|
||||||
|
except tweepy.TweepError as ex:
|
||||||
|
debug.error('Error occured in the unfollow loop!', ex)
|
||||||
|
finally:
|
||||||
|
self.unfollows = 0
|
||||||
|
|
||||||
|
def ratio_check(self):
|
||||||
|
if self.follows >= max_follows:
|
||||||
|
time.sleep(86400)
|
||||||
|
if me.friends_count >= 2000:
|
||||||
|
ratio = me.friends_count + (me.followers_count/10)
|
||||||
|
if me.friends_count >= ratio:
|
||||||
|
debug.action('Following to follower ratio is off! Starting the unfollow loop...')
|
||||||
|
unfollow_loop()
|
||||||
|
|
||||||
|
def stats(self):
|
||||||
|
debug.action('SceenName : ' + self.me.screen_name)
|
||||||
|
debug.action('Registered : ' + self.me.created_at)
|
||||||
|
debug.action('Favorites : ' + self.me.favourites_count)
|
||||||
|
debug.action('Following : ' + self.me.friends_count)
|
||||||
|
debug.action('Followers : ' + self.me.followers_count)
|
||||||
|
debug.action('Tweets : ' + self.me.statuses_count)
|
Loading…
Reference in New Issue
Block a user