diff --git a/LICENSE b/LICENSE
@@ -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.
diff --git a/README.md b/README.md
@@ -0,0 +1,24 @@
+###### Requirments
+* [FeedParser](http://pypi.python.org/pypi/feedparser)
+* [Tweepy](http://pypi.python.org/pypi/tweepy)
+* [ndg-httpsclient](http://pypi.python.org/pypi/ndg-httpsclient) *(Install only if you are getting an "InsecurePlatformWarning" error.)*
+
+###### 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".
+
+Register a [CoinURL](http://coinurl.com/) account and get your [api key](http://coinurl.com/profile-api.php).
+The random number you will see after "uuid" is your unique user id that will be use in the config.
+
+Edit your `config.py` and change the Twitter & CoinURL API settings.
+
+###### Mirrors
+- [acid.vegas](https://acid.vegas/chir.py) *(main)*
+- [SuperNETs](https://git.supernets.org/acidvegas/chir.py)
+- [GitHub](https://github.com/acidvegas/chir.py)
+- [GitLab](https://gitlab.com/acidvegas/chir.py)
diff --git a/chir.py/chir.py b/chir.py/chir.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+# Chir.py Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/chir.py)
+# chir.py
+
+import sys
+
+sys.dont_write_bytecode = True
+
+import debug
+
+debug.info()
+if not debug.check_version(3):
+ debug.error_exit('Chir.py requires Python version 3 to run!')
+if not debug.get_windows():
+ if debug.check_root():
+ debug.error_exit('Do not run Chir.py as root!')
+debug.check_imports()
+debug.check_config()
+import twitter
+twitter.login()
+twitter.main_loop()
+debug.keep_alive()
+\ No newline at end of file
diff --git a/chir.py/config.py b/chir.py/config.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# Chir.py Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/chir.py)
+# config.py
+
+# API Settings
+coinurl_uuid = 'CHANGEME'
+twitter_consumer_key = 'CHANGEME'
+twitter_consumer_secret = 'CHANGEME'
+twitter_access_token = 'CHANGEME'
+twitter_access_token_secret = 'CHANGEME'
+
+# Keywords & News Sources (DO NOT EDIT)
+boost_keywords = ('500aday','autofollow','autofollowback','f4f','follow','follow4follow','followback','followtrain','teamfollowback','wefollowback')
+
+news_feeds = {
+ 'baseball' : 'https://sports.yahoo.com/mlb/rss.xml',
+ 'basketball' : 'https://sports.yahoo.com/nba/rss.xml',
+ 'boxing' : 'https://sports.yahoo.com/box/rss.xml',
+ 'football' : 'https://sports.yahoo.com/nfl/rss.xml',
+ 'golf' : 'https://sports.yahoo.com/golf/rss.xml',
+ 'hockey' : 'https://sports.yahoo.com/nhl/rss.xml',
+ 'mma' : 'https://sports.yahoo.com/mma/rss.xml',
+ 'nascar' : 'https://sports.yahoo.com/nascar/rss.xml',
+ 'soccer' : 'https://sports.yahoo.com/soccer/rss.xml',
+ 'tennis' : 'https://sports.yahoo.com/tennis/rss.xml'
+}
+
+news_keywords = {
+ 'baseball' : ('baseball','mlb','homerun','worldseries','springtraining','angels','astros','athletics','bluejays','braves','brewers','cardinals','cubs','diamondbacks','dodgers','giants','indians','mariners','marlins','mets','nationals','orioles','padres','phillies','pirates','rangers','rays','redsox','reds','rockies','royals','tigers','twins','whitesox','yankees'),
+ 'basketball' : ('basketball','finals','nba','76ers','blazers','bucks','bulls','cavaliers','celtics','clippers','grizzlies','hawks','heat','hornets','jazz','kings','knicks','lakers','magic','mavericks','nets','nuggets','pacers','pistons','raptors','rockets','spurs','suns','thunder','timberwolves','warriors','wizards'),
+ 'boxing' : ('boxing','fightnight'),
+ 'football' : ('football','madden','nfl','superbowl','touchdown','49ers','bears','bengals','bills','broncos','browns','bucaneers','cardinals','chargers','cheifs','colts','cowboys','dolphins','eagles','falcons','giants','jaguars','jets','lions','packers','panthers','patriots','raiders','rams','ravens','redskins','saints','seahawks','steelers','texans','titans','vikings'),
+ 'golf' : ('fedexcup','owgr','pga','pgachampionship','pgatour'),
+ 'hockey' : ('hockey','nhl','worldcup','avalanche','blackhawks','bluejackets','blues','bruins','canadiens','canucks','capitals','coyotes','devils','ducks','flames','flyers','hurricanes','islanders','jets','kings','lightning','mapleleafs','oilers','panthers','penguins','predators','rangers','redwings','sabres','senators','sharks','stars','wild'),
+ 'mma' : ('bellator','martialarts','mixedmartialarts','mma','ufc','wsof'),
+ 'nascar' : ('buschseries','campingworldtruckseries','daytona500','iracing','nascar','sprintcup','sprintseries','winstoncup','winstoncupseries','xfinityseries'),
+ 'soccer' : ('fifa','soccer','worldcup'),
+ 'tennis' : ('atp','atpworldtour','masters1000','tennis','usopen')
+}
diff --git a/chir.py/debug.py b/chir.py/debug.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+# Chir.py Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/chir.py)
+# debug.py
+
+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.coinurl_uuid, config.twitter_consumer_key, config.twitter_consumer_secret, config.twitter_access_token, config.twitter_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)')
+ try:
+ import feedparser
+ except ImportError:
+ error_exit('Failed to import the FeedParser library! (http://pypi.python.org/pypi/feedparser)')
+
+def check_root():
+ 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('#' + ''.center(54) + '#')
+ print('#' + 'Chir.py Twitter Bot'.center(54) + '#')
+ print('#' + 'Developed by acidvegas in Python '.center(54) + '#')
+ print('#' + 'https://acid.vegas/chir.py'.center(54) + '#')
+ print('#' + ''.center(54) + '#')
+ print(''.rjust(56, '#'))
+
+def keep_alive():
+ try:
+ while True:
+ input('')
+ except KeyboardInterrupt:
+ sys.exit()
diff --git a/chir.py/functions.py b/chir.py/functions.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+# Chir.py Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/chir.py)
+# functions.py
+
+import random
+import re
+import urllib.request
+
+import feedparser
+
+import config
+import debug
+
+def coinurl(url):
+ source = urllib.request.urlopen('https://coinurl.com/api.php?uuid=%s&url=%s' % (config.coinurl_uuid, url))
+ charset = source.headers.get_content_charset()
+ if charset : return source.read().decode(charset)
+ else : return source.read().decode()
+
+def get_news(): # This is very sloppy and needs some work.
+ news_list = list()
+ sport = random.choice(list(config.news_feeds.keys()))
+ sport_news = feedparser.parse(config.news_feeds[sport])
+ sport_keywords = config.news_keywords[sport]
+ for item in sport_news.entries:
+ description = strip_html(item.summary)
+ if ') -- ' in description:
+ cutoff = description.split(') -- ')[0]
+ description = description.split(cutoff)[1]
+ if ') - ' in description:
+ cutoff = description.split(') - ')[0]
+ description = description.split(cutoff)[1]
+ description = description.replace('*', '')
+ description = description.replace('\'', '')
+ description = description.replace('"', '')
+ description = description.replace('--', '-')
+ description = description.replace(' ', ' ')
+ for word in sport_keywords:
+ if word in description.lower():
+ description = re.sub(word, '#' + word, description, flags=re.IGNORECASE)
+ if len(description) > 118:
+ description = description[:118]
+ split = description.split()
+ description = description.split(split[len(split)-1])[0][:-1] + '... '
+ try:
+ link = coinurl(item.link)
+ except Exception as ex:
+ debug.error('Error occured creating PPC link!', ex)
+ else:
+ description = description + ' ' + link
+ news_list.append(description)
+ return news_list
+
+def strip_html(source):
+ return re.compile(r'<.*?>').sub('', source)
diff --git a/chir.py/twitter.py b/chir.py/twitter.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# Chir.py Twitter Bot - Developed by acidvegas in Python (https://acid.vegas/chir.py)
+# twitter.py
+
+import random
+import threading
+import time
+
+import tweepy
+
+import config
+import debug
+import functions
+
+api = None
+me = None
+
+def login():
+ global api, me
+ try:
+ auth = tweepy.OAuthHandler(config.consumer_key, config.consumer_secret)
+ auth.set_access_token(config.access_token, config.access_token_secret)
+ api = tweepy.API(auth, wait_on_rate_limit=True, wait_on_rate_limit_notify=True)
+ me = api.me()
+ except tweepy.TweepError:
+ debug.error_exit('Failed to login to Twitter!')
+
+def stats():
+ debug.action('SceenName\t: %s' % me.screen_name)
+ debug.action('Registered\t: %s' % me.created_at)
+ debug.action('Favorites\t: %s' % me.favourites_count)
+ debug.action('Following\t: %s' % me.friends_count)
+ debug.action('Followers\t: %s' % me.followers_count)
+ debug.action('Tweets\t\t: %s' % me.statuses_count)
+
+class boost_loop(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ def run(self):
+ while True:
+ try:
+ if 'boost_tweet' in locals(): api.destroy_status(boost_tweet.id)
+ boost_tweet = api.update_status('Support our Twitter! #' + ' #'.join(config.boost))
+ 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)
+ time.sleep(60*5)
+
+class favorite_loop(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ def run(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)
+ 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)
+
+class follow_loop(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ def run(self):
+ while True:
+ try:
+ followers = api.followers_ids(me.screen_name)
+ friends = api.friends_ids(me.screen_name)
+ if me.friends_count / me.followers_count == 3:
+ debug.action('Following to follower ratio is off! Starting the unfollow loop...')
+ unfollow_loop()
+ for follower in followers:
+ if not follower in friends:
+ api.create_friendship(follower)
+ api.send_direct_message(screen_name=follower, text='Thanks for following our Twitter. Be sure to share us with your friends & keep up with the latest sports news!')
+ debug.alert('Followed back a follower!')
+ time.sleep(30)
+ except tweepy.TweepError as ex:
+ debug.error('Error occured in the follow loop!', ex)
+ finally:
+ time.sleep(60*15)
+
+def main_loop():
+ boost_loop().start()
+ favorite_loop().start()
+ follow_loop().start()
+ news_loop().start()
+ search_loop().start()
+
+class news_loop(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ def run(self):
+ while True:
+ try:
+ news = functions.get_news()
+ tweets = list()
+ for item in tweepy.Cursor(api.user_timeline, exclude_replies=True).items(50):
+ tweets.append(item.text.split('... ')[0])
+ time.sleep(2)
+ for item in news:
+ split = item.split('... ')[0]
+ if split not in tweets:
+ api.update_status(item)
+ debug.alert('A tweet has been posted.')
+ time.sleep(60*5)
+ except tweepy.TweepError as ex:
+ debug.error('Error occured in the news loop', ex)
+ finally:
+ time.sleep(60*15)
+
+class search_loop(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ def run(self):
+ query_keywords = list()
+ for item in config.news_keywords:
+ query_keywords = query_keywords + list(config.news_keywords[item])
+ query_keywords = query_keywords + config.boost_keywords
+ while True:
+ try:
+ query = random.choice(query_keywords)
+ for item in api.search(q='#' + query, count=50, lang='en', result_type='mixed'):
+ if not item.user.following and not item.favorited:
+ try:
+ api.create_favorite(item.id)
+ api.create_friendship(item.user.screen_name)
+ debug.alert('Followed a similar 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 unfollow_loop():
+ try:
+ followers = api.followers_ids(me.screen_name)
+ friends = api.friends_ids(me.screen_name)
+ for friend in friends:
+ if friend not in followers:
+ api.destroy_friendship(friend)
+ debug.alert('Unfollowed an unsupporting friend!')
+ time.sleep(30)
+ except tweepy.TweepError as ex:
+ debug.error('Error occured in the unfollow loop!', ex)
| | | | | | |