Added hateserv bot (not finished)

This commit is contained in:
Dionysus 2023-05-29 02:34:34 -04:00
parent 6ff2ef8a88
commit f159c37f8f
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
2 changed files with 329 additions and 0 deletions

113
hateserv/api.py Normal file
View File

@ -0,0 +1,113 @@
#!/usr/bin/env python
# hateserv irc bot - developed by acidvegas in python (https://git.acid.vegas/hateserv)
import http.client
import json
import re
import urllib.parse
from googleapiclient.discovery import build # https://pypi.org/project/google-api-python-client/
#import tweepy # https://pypi.org/project/tweepy/
# API Keys
google_api_key = 'redacted' # https://console.developers.google.com/
google_cse_id = 'redacted' # https://cse.google.com/
twitter_bearer_token = 'redacted'
twitter_access_token = 'redacted'
twitter_access_token_secret = 'redacted'
twitter_client_id = 'redacted'
twitter_client_secret = 'redacted'
twitter_api_key = 'redacted'
twitter_api_secret = 'redacted'
def between(source, start, stop):
data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source)
return data.group(1) if data else False
def geturl(url, endpoint, headers={}):
conn = http.client.HTTPSConnection(url, timeout=15)
conn.request('GET', endpoint, headers=headers)
response = conn.getresponse().read()
conn.close()
return response
def google(query):
service = build('customsearch', 'v1', developerKey=google_api_key, cache_discovery=False).cse()
results = service.list(q=query, cx=google_cse_id, num=10).execute()
return results['items'] if results else False
def netsplit(option, query):
if option == 'channels':
data = str(geturl('netsplit.de', '/channels/?chat='+query))
for i in ('&#8203;','<b>','</b>','<span style="color:#000000;">','<strong>','</strong>','<span class="cs-no-topic">'):
data = data.replace(i, '')
results = re.findall('<div class="cs-result">(.*?)</div>', data, re.IGNORECASE|re.MULTILINE)
if results:
channels = list()
for item in results:
channel = between(item, '<span class="cs-channel">', '</span>')
network = between(item, '<span class="cs-network">', '</span>')
users = between(item, ' - ', ' users - ')
if '<span class="cs-details">current topic:' in item:
topic = between(item, '<span class="cs-details">current topic:&nbsp;</span>', '<br>').replace('</span>','')
else:
topic = 'no topic set for channel'
channels.append({'channel':channel, 'network':network, 'users':users, 'topic':topic})
return channels
else:
return False
elif option == 'networks':
data = str(geturl('netsplit.de', '/networks/'))
results = re.findall('<a class="competitor" href="/networks/(.*?)/" title=', data, re.IGNORECASE|re.MULTILINE)
return results if results else False
def reddit(option, subreddit, id=None):
if option == 'post':
data = json.loads(geturl('www.reddit.com', f'/r/{subreddit}/comments/{id}.json', headers={'Accept':'application/json','User-Agent':'HateServ/1.0'}))
return data[0]['data']['children'][0]['data'] if 'error' not in data else False
elif option == 'subreddit':
data = json.loads(geturl('www.reddit.com', f'/r/{subreddit}.json?limit=20', headers={'Accept':'application/json','User-Agent':'HateServ/1.0'}))
posts = [item['data'] for item in data['data']['children'] if not item['data']['stickied']]
return posts[:10] if posts else None
def github(option, query):
if option == 'search':
data = json.loads(geturl('api.github.com', '/search/repositories?q='+query, headers={'Accept':'application/vnd.github.v3+json','User-Agent':'HateServ/1.0'}))
return data['items'][:10] if data['items'] else False
elif option == 'repo':
return json.loads(geturl('api.github.com', '/repos/'+query, headers={'Accept':'application/vnd.github.v3+json','User-Agent':'HateServ/1.0'}))
elif option == 'user':
return json.loads(geturl('api.github.com', '/users/'+query, headers={'Accept':'application/vnd.github.v3+json','User-Agent':'HateServ/1.0'}))
def youtube(option, query, api_key):
if option == 'video':
api = httplib.get_json(f'https://www.googleapis.com/youtube/v3/videos?key={config.api.google_api_key}&part=snippet,statistics&id={id}')
if api['items']:
api = api['items'][0]
data = {}
data['channel'] = api['snippet']['channelTitle']
data['description'] = ' '.join(api['snippet']['description'].split())
data['dislikes'] = api['statistics']['dislikeCount']
data['likes'] = api['statistics']['likeCount']
data['title'] = api['snippet']['title']
data['views'] = api['statistics']['viewCount']
return data
else:
return False
elif option == 'search':
service = build('youtube', 'v3', developerKey=api_key).search()
results = service.list(part='id', type='video', q=query, maxResults=10).execute()
return results['items'] if results else False
def twitter(data):
# auth = tweepy.OAuthHandler(twitter_consumer_key, twitter_consumer_secret)
# auth.set_access_token(twitter_access_token, twitter_access_secret)
# api = tweepy.API(auth)
# api.update_status(data)
pass
def unreal():
pass
def anope():
pass

216
hateserv/hateserv.py Normal file
View File

@ -0,0 +1,216 @@
#!/usr/bin/env python
# hateserv irc bot - developed by acidvegas in python (https://git.acid.vegas/hateserv)
import json
import random
import re
import socket
import ssl
import time
import urllib.request
import api
# Config
admin = 'acidvegas!~stillfree@most.dangerous.motherfuck'
server = 'irc.supernets.org'
channel = '#dev'
nickname = 'HateServ'
username = 'H'
realname = 'SuperNETs HATE Services'
nickserv_password = 'simps0nsfan22'
operator_password = 'EatMYsh0rts39'
# Colors & Control Characters
bold = '\x02'
underline = '\x1F'
reset = '\x0f'
white = '00'
black = '01'
blue = '02'
green = '03'
red = '04'
brown = '05'
purple = '06'
orange = '07'
yellow = '08'
light_green = '09'
cyan = '10'
light_cyan = '11'
light_blue = '12'
pink = '13'
grey = '14'
light_grey = '15'
def color(msg, foreground, background=None):
return f'\x03{foreground},{background}{msg}{reset}' if background else f'\x03{foreground}{msg}{reset}'
def debug(data):
print('{0} | [~] - {1}'.format(time.strftime('%I:%M:%S'), data))
def error(data, reason=None):
print('{0} | [!] - {1} ({2})'.format(time.strftime('%I:%M:%S'), data, str(reason))) if reason else print('{0} | [!] - {1}'.format(time.strftime('%I:%M:%S'), data))
def irc_error(chan, data, reason=None):
sendmsg(chan, '[{0}] {1}'.format(color('error', red), data, color(f'({reason})', grey))) if reason else sendmsg(chan, '[{0}] {1}'.format(color('error', red), data))
def raw(msg):
msg = msg.replace('\r\n',' ')
sock.send(bytes(msg[:510] + '\r\n', 'utf-8'))
def sendmsg(target, msg):
raw(f'PRIVMSG {target} :{msg}')
def trim(data, max_length):
return data[:max_length] + '...' if len(data) > max_length else data
def urlcheck(msg):
url = re.compile('(?:http[s]?:\/\/|http[s]?:\/\/www.)(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', re.IGNORECASE).findall(msg)
if url:
url = url[0]
try:
if (check := re.match('^.*?github.com\/([0-9A-Za-z]+\/[0-9A-Za-z]+).*?', url, re.IGNORECASE)):
data = api.github('repo', check.group(1))
if data:
if not data['description']:
data['description'] = 'no description available'
sendmsg(channel, '{0} {1} {2} [{3}:{4}|{5}:{6}|{7}:{8}]'.format(color(' GitHub ', black, grey), data['full_name'], color('('+data['description']+')', grey), color('Stars', purple), data['stargazers_count'], color('Watch', purple), data['watchers'], color('Forks', purple), data['forks']))
elif (check := re.match('^.*?github.com\/([0-9A-Za-z]+)', url, re.IGNORECASE)):
data = api.github('user', check.group(1))
if data:
data['bio'] = data['bio'].replace('\r\n','') if data['bio'] else ''
sendmsg(channel, '{0} {1} {2} {3} [{4}:{5}|{6}:{7}]'.format(color(' GitHub ', black, grey), data['login'], color('('+data['name']+')', grey), data['bio'], color('Repos', purple), data['public_repos'], color('Followers', purple), data['followers']))
elif (check := re.match('^.*?reddit.com\/r\/(.*?)\/comments\/([0-9A-Za-z]+).*$', url, re.IGNORECASE)):
data = api.reddit('post', check.group(1), check.group(2))
sendmsg(channel, '[{0}] - {1} [{2}/{3}|{4}]'.format(color('reddit', cyan), color(trim(data['title'], 300), white), color('+' + str(data['ups']), green), color('-' + str(data['downs']), red), color(str(data['num_comments']), white)))
elif (check := re.match('^.*?youtu(be)?\.([a-z])+\/(watch(.*?)(\?|\&)v=)?(.*?)(&(.)*)*$', url, re.IGNORECASE)):
pass
else:
source = urllib.request.urlopen(url, timeout=10)
title = re.compile(r'<title.*?>(.+?)</title>', re.I | re.M | re.S | re.U).search(source.read().decode('utf-8'))
if title:
title = title.group(1).replace('\n',' ')
if len(title) > 100:
title = title[:100] + '...'
type = source.info().get_content_type()
sendmsg(channel, f'[{type}] {title}')
except Exception as ex:
error('failed to get parse url title', ex)
def event_message(chan, nick, ident, msg):
args = msg.split()
if not msg.startswith('.'):
urlcheck(msg)
if msg == '@hateserv':
sendmsg(channel, 'hateserv irc bot for supernets - developed by acidvegas in python (https://git.acid.vegas/hateserv)')
elif msg in ('melp','.melp','melp?','.melp?'):
sendmsg(chan, '\x01ACTION explodes\x01')
else:
if ident == admin:
if msg == '.massjoin':
raw('WHO * n%nc')
elif args[0] == '.t':
content = msg[3:]
if len(content) < 240:
api.twitter('tweet', content)
sendmsg(chan, '\x01ACTION whispers "{content}" into Elon Musks ear...\x01')
else:
irc_error(chan, 'tweet too long (max: 240)')
if msg == '.talent':
if random.randint(1,5000) == 1337:
for i in range(100):
sendmsg(chan, nick + ': ' + color(' RIP-DIDDLE-DIP-DIP-DIP-DIP IT\'S YOUR BIRTHDAY !!! ', random.randint(2,13), random.randint(2,13)))
else:
sendmsg(chan, color('(^)', random.randint(2,13)))
elif args[0] == '.g':
query = ' '.join(args[1:])
results = api.google(query)
if results:
for item in results:
sendmsg(chan, '[{0}] {1}'.format(color(str(results.index(item)+1).zfill(2), pink), trim(item['title'], 300)))
sendmsg(chan, ' '*5 + underline + color(item['link'], light_blue))
else:
irc_error(chan, 'no results found')
elif args[0] == '.gh':
query = ' '.join(args[1:]).replace(' ','%20')
results = api.github('search',query)
if results:
for item in results:
if not item['description']:
item['description'] = 'no description'
sendmsg(chan, '[{0}] {1}/{2}{3}{4} {5}'.format(color(str(results.index(item)+1).zfill(2), pink), item['owner']['login'], bold, item['name'], reset, color('('+item['description']+')', grey)))
sendmsg(chan, ' '*5 + underline + color(item['html_url'], light_blue))
elif args[0] == '.netsplit' and len(args) >= 2:
query = ' '.join(args[1:])
results = api.netsplit('channels', query)
if results:
for item in results:
sendmsg(chan, '[{0}] {1} on {2} {3}'.format(color(str(results.index(item)+1).zfill(2), pink), color(item['channel'], purple), color(item['network'], yellow), color('('+item['users']+')', grey)))
sendmsg(chan, ' '*5 + color(trim(item['topic'], 300), light_blue))
else:
irc_error(chan, 'no results found')
elif args[0] == '.r' and len(args) == 2:
query = args[1]
results = api.reddit('subreddit', query)
if results:
for item in results:
sendmsg(chan, '[{0}] {1} [{2}/{3}|{4}]'.format(color(str(results.index(item)+1).zfill(2), pink), trim(item['title'], 300), color('+' + str(item['ups']), green), color('-' + str(item['downs']), red), color(item['num_comments'], white)))
sendmsg(chan, ' '*5 + underline + color(item['url'], light_blue))
else:
irc_error(chan, 'no results found')
elif args[0] == '.yt':
query = ' '.join(args[1:])
results = api.youtube('search', query)
if results:
for result in results:
sendmsg(chan, '[{0}] {1}'.format(color(str(results.index(item)+1).zfill(2), pink), trim(item['snippet']['title'], 300)))
sendmsg(chan, ' '*5 + underline + color('https://www.youtube.com/watch?v='+item['id']['videoId'], light_blue))
while True:
try:
sock = ssl.wrap_socket(socket.socket())
sock.connect((server, 6697))
raw(f'USER {username} 0 * :{realname}')
raw('NICK ' + nickname)
while True:
try:
data = sock.recv(1024).decode('utf-8')
for line in (line for line in data.split('\r\n') if len(line.split()) >= 2):
debug(line)
args = line.split()
if line.startswith('ERROR :Closing Link:'):
raise Exception('Connection has closed.')
elif args[0] == 'PING':
raw('PONG ' + args[1][1:])
elif args[1] == '001': #RPL_WELCOME
raw(f'MODE {nickname} +B')
raw(f'PRIVMSG NickServ IDENTIFY {nickname} {nickserv_password}')
raw(f'OPER hates {operator_password}')
raw('JOIN ' + channel)
last = 5
elif args[1] == '354' and len(args) == 5: #RPL_WHOSPCRPL
nick = args[4]
if nick not in (nickname,'AI','BLACKHOLE','BotServ','ChanServ','EliManning','fraud','Global','HostServ','IRCCEX','NickServ','OperServ','THEGAME'):
raw(f'SAJOIN {nick} {channel}')
elif args[1] == 'JOIN' and len(args) == 3:
nick = args[0].split('!')[0][1:]
chan = args[2][1:]
elif args[1] == 'PRIVMSG' and len(args) >= 4:
ident = args[0][1:]
chan = args[2]
nick = args[0].split('!')[0][1:].lower()
msg = ' '.join(args[3:])[1:]
if chan == channel:
try:
event_message(chan, nick, ident, msg)
except Exception as ex:
irc_error(chan, 'unknown error occured', ex)
elif chan == nickname and ident == admin and msg.startswith('.raw '):
raw(msg[5:])
except (UnicodeDecodeError, UnicodeEncodeError):
pass
except Exception as ex:
error('fatal error occured', ex)
sock.close()
finally:
time.sleep(15)