2
mirror of git://git.acid.vegas/dickserv.git synced 2024-12-26 16:46:38 +00:00

Initial commit

This commit is contained in:
Dionysus 2019-06-24 22:13:57 -04:00
commit 11ceb7fba6
No known key found for this signature in database
GPG Key ID: 05114B46832BDBDB
25 changed files with 1406 additions and 0 deletions

15
LICENSE Normal file
View 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.

51
README.md Normal file
View File

@ -0,0 +1,51 @@
###### Requirments
* [Python](https://www.python.org/downloads/) *(**Note:** This script was developed to be used with the latest version of Python.)*
* [PySocks](https://pypi.python.org/pypi/PySocks) *(**Optional:** For using the `proxy` setting.)*
* [beautifulsoup4](https://pypi.python.org/pypi/beautifulsoup4)
* [google-api-python-client](https://pypi.python.org/pypi/google-api-python-client)
###### Commands
| Command | Description |
| --- | --- |
| @dickserv | Information about the bot. |
| @dickserv help | Information about the commands. |
| coin \<cryptocurrency> | Get the USD value for \<cryptocurrency>. |
| date | Get the current date and time. |
| define \<word> | Get the definition of \<word>. |
| drug \<query> | Lookup information on \<drug> on tripsit. |
| g \<query> | Search Google for \<query>. |
| imdb \<query/ttid> [year] | Search \<query/ttid> on IMDb. |
| isup \<url> | Check if \<url> is up or not. |
| netsplit \<query> | Search for \<query> on NetSplit. |
| r \<subreddit> | Read top posts from \<subreddit> |
| talent | RIP DITTLE DIP DIP DIP DIP IT\'S YA BIRTHDAY!!1@11! |
| todo | Read your todo list. |
| todo add \<data> | Add \<data> to your todo list. |
| todo del \<num>| | Delete the \<num> todo result. |
| tpb \<query> | Searc \<query on ThePirateBay. |
| ud \<word> | Get the urban dictionary definition of \<word>. |
| uptime | Get the amount of time DickServ has been running. |
| w \<zip_code> | Get the weather for \<zip>. |
| wolfram \<ask> | Get the results of \<query> from WolframAlpha. |
| yt \<query> | Search \<query> on YouTube. |
###### Admin Commands (Private Message)
| Command | Description |
| --- | --- |
| config | View the config settings. |
| config \<setting> \<value> | Change \<setting> to \<value>. |
| ignore | View the ignore list. |
| ignore add \<ident> | Add a user to the ignore list. |
| ignore del \<ident> | Remove a user from the ignore list. |
| ignore reset | Remove all ignores. |
| off | Toggle the usage of the bot commands. |
| on | Toggle the usage of the bot commands. |
| todo | List all todos. |
| todo expire | Remove all expired todos. |
| todo reset | Remove all todos. |
###### Mirrors
- [acid.vegas](https://acid.vegas/dickserv) *(main)*
- [SuperNETs](https://git.supernets.org/acidvegas/dickserv)
- [GitHub](https://github.com/acidvegas/dickserv)
- [GitLab](https://gitlab.com/acidvegas/dickserv)

16
dickserv/core/commands.py Normal file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# commands.py
import cryptocurrency
import dictionary
import google
import imdb
import isup
import netsplit
import reddit
import tpb
import tripsit
import weather
import wolfram
import youtube

42
dickserv/core/config.py Normal file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# config.py
class connection:
server = 'irc.server.com'
port = 6697
ipv6 = False
ssl = True
ssl_verify = False
proxy = None
vhost = None
channel = '#chats'
key = None
class cert:
key = None
file = None
password = None
class ident:
nickname = 'DickServ'
username = 'dickserv'
realname = 'acid.vegas/dickserv'
class login:
network = None
nickserv = None
operator = None
class settings:
admin = 'user@host.name'
cmd_char = '.'
log = False
modes = None
class api:
google_api_key = 'CHANGEME' # https://console.developers.google.com/
google_cse_id = 'CHANGEME' # https://cse.google.com/
omdbapi_key = 'CHANGEME' # http://www.omdbapi.com/apikey.aspx
wolfram_api_key = 'CHANGEME' # http://products.wolframalpha.com/api/
wunderground_api_key = 'CHANGEME' # https://www.wunderground.com/weather/api/

213
dickserv/core/constants.py Normal file
View File

@ -0,0 +1,213 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# constants.py
# Control Characters
bold = '\x02'
color = '\x03'
italic = '\x1D'
underline = '\x1F'
reverse = '\x16'
reset = '\x0f'
# Color Codes
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'
# Events
PASS = 'PASS'
NICK = 'NICK'
USER = 'USER'
OPER = 'OPER'
MODE = 'MODE'
SERVICE = 'SERVICE'
QUIT = 'QUIT'
SQUIT = 'SQUIT'
JOIN = 'JOIN'
PART = 'PART'
TOPIC = 'TOPIC'
NAMES = 'NAMES'
LIST = 'LIST'
INVITE = 'INVITE'
KICK = 'KICK'
PRIVMSG = 'PRIVMSG'
NOTICE = 'NOTICE'
MOTD = 'MOTD'
LUSERS = 'LUSERS'
VERSION = 'VERSION'
STATS = 'STATS'
LINKS = 'LINKS'
TIME = 'TIME'
CONNECT = 'CONNECT'
TRACE = 'TRACE'
ADMIN = 'ADMIN'
INFO = 'INFO'
SERVLIST = 'SERVLIST'
SQUERY = 'SQUERY'
WHO = 'WHO'
WHOIS = 'WHOIS'
WHOWAS = 'WHOWAS'
KILL = 'KILL'
PING = 'PING'
PONG = 'PONG'
ERROR = 'ERROR'
AWAY = 'AWAY'
REHASH = 'REHASH'
DIE = 'DIE'
RESTART = 'RESTART'
SUMMON = 'SUMMON'
USERS = 'USERS'
WALLOPS = 'WALLOPS'
USERHOST = 'USERHOST'
ISON = 'ISON'
# Event Numerics
RPL_WELCOME = '001'
RPL_YOURHOST = '002'
RPL_CREATED = '003'
RPL_MYINFO = '004'
RPL_ISUPPORT = '005'
RPL_TRACELINK = '200'
RPL_TRACECONNECTING = '201'
RPL_TRACEHANDSHAKE = '202'
RPL_TRACEUNKNOWN = '203'
RPL_TRACEOPERATOR = '204'
RPL_TRACEUSER = '205'
RPL_TRACESERVER = '206'
RPL_TRACESERVICE = '207'
RPL_TRACENEWTYPE = '208'
RPL_TRACECLASS = '209'
RPL_STATSLINKINFO = '211'
RPL_STATSCOMMANDS = '212'
RPL_STATSCLINE = '213'
RPL_STATSILINE = '215'
RPL_STATSKLINE = '216'
RPL_STATSYLINE = '218'
RPL_ENDOFSTATS = '219'
RPL_UMODEIS = '221'
RPL_SERVLIST = '234'
RPL_SERVLISTEND = '235'
RPL_STATSLLINE = '241'
RPL_STATSUPTIME = '242'
RPL_STATSOLINE = '243'
RPL_STATSHLINE = '244'
RPL_LUSERCLIENT = '251'
RPL_LUSEROP = '252'
RPL_LUSERUNKNOWN = '253'
RPL_LUSERCHANNELS = '254'
RPL_LUSERME = '255'
RPL_ADMINME = '256'
RPL_ADMINLOC1 = '257'
RPL_ADMINLOC2 = '258'
RPL_ADMINEMAIL = '259'
RPL_TRACELOG = '261'
RPL_TRYAGAIN = '263'
RPL_NONE = '300'
RPL_AWAY = '301'
RPL_USERHOST = '302'
RPL_ISON = '303'
RPL_UNAWAY = '305'
RPL_NOWAWAY = '306'
RPL_WHOISUSER = '311'
RPL_WHOISSERVER = '312'
RPL_WHOISOPERATOR = '313'
RPL_WHOWASUSER = '314'
RPL_ENDOFWHO = '315'
RPL_WHOISIDLE = '317'
RPL_ENDOFWHOIS = '318'
RPL_WHOISCHANNELS = '319'
RPL_LIST = '322'
RPL_LISTEND = '323'
RPL_CHANNELMODEIS = '324'
RPL_NOTOPIC = '331'
RPL_TOPIC = '332'
RPL_INVITING = '341'
RPL_INVITELIST = '346'
RPL_ENDOFINVITELIST = '347'
RPL_EXCEPTLIST = '348'
RPL_ENDOFEXCEPTLIST = '349'
RPL_VERSION = '351'
RPL_WHOREPLY = '352'
RPL_NAMREPLY = '353'
RPL_LINKS = '364'
RPL_ENDOFLINKS = '365'
RPL_ENDOFNAMES = '366'
RPL_BANLIST = '367'
RPL_ENDOFBANLIST = '368'
RPL_ENDOFWHOWAS = '369'
RPL_INFO = '371'
RPL_MOTD = '372'
RPL_ENDOFINFO = '374'
RPL_MOTDSTART = '375'
RPL_ENDOFMOTD = '376'
RPL_YOUREOPER = '381'
RPL_REHASHING = '382'
RPL_YOURESERVICE = '383'
RPL_TIME = '391'
RPL_USERSSTART = '392'
RPL_USERS = '393'
RPL_ENDOFUSERS = '394'
RPL_NOUSERS = '395'
ERR_NOSUCHNICK = '401'
ERR_NOSUCHSERVER = '402'
ERR_NOSUCHCHANNEL = '403'
ERR_CANNOTSENDTOCHAN = '404'
ERR_TOOMANYCHANNELS = '405'
ERR_WASNOSUCHNICK = '406'
ERR_TOOMANYTARGETS = '407'
ERR_NOSUCHSERVICE = '408'
ERR_NOORIGIN = '409'
ERR_NORECIPIENT = '411'
ERR_NOTEXTTOSEND = '412'
ERR_NOTOPLEVEL = '413'
ERR_WILDTOPLEVEL = '414'
ERR_BADMASK = '415'
ERR_UNKNOWNCOMMAND = '421'
ERR_NOMOTD = '422'
ERR_NOADMININFO = '423'
ERR_FILEERROR = '424'
ERR_NONICKNAMEGIVEN = '431'
ERR_ERRONEUSNICKNAME = '432'
ERR_NICKNAMEINUSE = '433'
ERR_NICKCOLLISION = '436'
ERR_USERNOTINCHANNEL = '441'
ERR_NOTONCHANNEL = '442'
ERR_USERONCHANNEL = '443'
ERR_NOLOGIN = '444'
ERR_SUMMONDISABLED = '445'
ERR_USERSDISABLED = '446'
ERR_NOTREGISTERED = '451'
ERR_NEEDMOREPARAMS = '461'
ERR_ALREADYREGISTRED = '462'
ERR_NOPERMFORHOST = '463'
ERR_PASSWDMISMATCH = '464'
ERR_YOUREBANNEDCREEP = '465'
ERR_KEYSET = '467'
ERR_CHANNELISFULL = '471'
ERR_UNKNOWNMODE = '472'
ERR_INVITEONLYCHAN = '473'
ERR_BANNEDFROMCHAN = '474'
ERR_BADCHANNELKEY = '475'
ERR_BADCHANMASK = '476'
ERR_BANLISTFULL = '478'
ERR_NOPRIVILEGES = '481'
ERR_CHANOPRIVSNEEDED = '482'
ERR_CANTKILLSERVER = '483'
ERR_UNIQOPRIVSNEEDED = '485'
ERR_NOOPERHOST = '491'
ERR_UMODEUNKNOWNFLAG = '501'
ERR_USERSDONTMATCH = '502'

83
dickserv/core/database.py Normal file
View File

@ -0,0 +1,83 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# database.py
import os
import sqlite3
# Globals
db = sqlite3.connect(os.path.join('data', 'bot.db'), check_same_thread=False)
sql = db.cursor()
def check():
tables = sql.execute('SELECT name FROM sqlite_master WHERE type=\'table\'').fetchall()
if not len(tables):
sql.execute('CREATE TABLE IGNORE (IDENT TEXT NOT NULL);')
sql.execute('CREATE TABLE SETTINGS (SETTING TEXT NOT NULL, VALUE INTEGER NOT NULL);')
sql.execute('INSERT INTO SETTINGS (SETTING,VALUE) VALUES (?, ?)', ('max_results', 5))
sql.execute('INSERT INTO SETTINGS (SETTING,VALUE) VALUES (?, ?)', ('max_todo', 100))
sql.execute('INSERT INTO SETTINGS (SETTING,VALUE) VALUES (?, ?)', ('max_todo_per', 5))
sql.execute('INSERT INTO SETTINGS (SETTING,VALUE) VALUES (?, ?)', ('todo_expire', 7))
sql.execute('CREATE TABLE TODO (DATE TEXT NOT NULL, IDENT TEXT NOT NULL, DATA TEXT NOT NULL);')
db.commit()
class Ignore:
def add(ident):
sql.execute('INSERT INTO IGNORE (IDENT) VALUES (?)', (ident,))
db.commit()
def idents():
return list(item[0] for item in sql.execute('SELECT IDENT FROM IGNORE ORDER BY IDENT ASC').fetchall())
def remove(ident):
sql.execute('DELETE FROM IGNORE WHERE IDENT=?', (ident,))
db.commit()
def reset():
sql.execute('DROP TABLE IGNORE')
sql.execute('CREATE TABLE IGNORE (IDENT TEXT NOT NULL);')
db.commit()
class Settings:
def get(setting):
return sql.execute('SELECT VALUE FROM SETTINGS WHERE SETTING=?', (setting,)).fetchone()[0]
def read():
return sql.execute('SELECT SETTING,VALUE FROM SETTINGS ORDER BY SETTING ASC').fetchall()
def settings():
return list(item[0] for item in sql.execute('SELECT SETTING FROM SETTINGS').fetchall())
def update(setting, value):
sql.execute('UPDATE SETTINGS SET VALUE=? WHERE SETTING=?', (value, setting))
db.commit()
class Todo:
def add(date, ident, data):
sql.execute('INSERT INTO TODO (DATE,IDENT,DATA) VALUES (?,?,?)', (date, ident, data))
db.commit()
def expire_check():
todos = set(list(item[0] for item in sql.execute('SELECT DATE FROM TODO').fetchall()))
for date in todos:
if functions.timespan(date) > Settings.get('todo_expire'):
sql.execute('DELETE FROM TODO WHERE DATE=?', (date,))
db.commit()
def idents():
return list(item[0] for item in sql.execute('SELECT IDENT FROM TODO').fetchall())
def read(ident=None):
if ident:
return list(item[0] for item in sql.execute('SELECT DATA FROM TODO WHERE IDENT=?', (ident,)).fetchall())
else:
return sql.execute('SELECT DATE,IDENT,DATA FROM TODO ORDER BY DATE ASC, IDENT ASC, DATA ASC').fetchall()
def remove(ident, data):
sql.execute('DELETE FROM TODO WHERE IDENT=? AND DATA=?', (ident, data))
db.commit()
def reset():
sql.execute('DROP TABLE TODO')
sql.execute('CREATE TABLE TODO (DATE TEXT NOT NULL, IDENT TEXT NOT NULL, DATA TEXT NOT NULL);')
db.commit()

90
dickserv/core/debug.py Normal file
View File

@ -0,0 +1,90 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# debug.py
import ctypes
import logging
import os
import sys
import time
from logging.handlers import RotatingFileHandler
import config
def check_libs():
if config.connection.proxy:
try:
import socks
except ImportError:
error_exit('Missing \'socks\' module! (https://pypi.python.org/pypi/PySocks)')
try:
import bs4
except ImportError:
error_exit('Missing \'bs4\' module. (https://pypi.python.org/pypi/beautifulsoup4)')
try:
import googleapiclient.discovery
except ImportError:
error_exit('Missing \'google-api-python-client\' module. (https://pypi.python.org/pypi/google-api-python-client/)')
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:
logging.debug(f'[!] - {msg} ({reason})')
else:
logging.debug('[!] - ' + msg)
def error_exit(msg):
raise SystemExit('[!] - ' + msg)
def info():
clear()
logging.debug('#'*56)
logging.debug('#{0}#'.format(''.center(54)))
logging.debug('#{0}#'.format('DickServ IRC'.center(54)))
logging.debug('#{0}#'.format('Developed by acidvegas in Python'.center(54)))
logging.debug('#{0}#'.format('https://acid.vegas/dickserv'.center(54)))
logging.debug('#{0}#'.format(''.center(54)))
logging.debug('#'*56)
def irc(msg):
logging.debug('[~] - ' + msg)
def setup_logger():
stream_handler = logging.StreamHandler(sys.stdout)
if config.settings.log:
log_file = os.path.join(os.path.join('data','logs'), 'bot.log')
file_handler = RotatingFileHandler(log_file, maxBytes=256000, backupCount=3)
logging.basicConfig(level=logging.NOTSET, format='%(asctime)s | %(message)s', datefmt='%I:%M:%S', handlers=(file_handler,stream_handler))
else:
logging.basicConfig(level=logging.NOTSET, format='%(asctime)s | %(message)s', datefmt='%I:%M:%S', handlers=(stream_handler,))

View File

@ -0,0 +1,53 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# functions.py
import datetime
import random
import re
import time
def between(source, start, stop):
data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source)
if data:
return data.group(1)
else:
return False
def current_date():
return time.strftime('%A, %B %d, %Y - %I:%M %p')
def floatint(data):
if data.isdigit():
return int(data)
else:
return float(data)
def get_date():
return datetime.date.today().strftime('%m/%d/%Y')
def get_datetime(data):
return datetime.datetime.strptime(data, '%m/%d/%Y')
def luck(odds):
if random_int(1,odds) == 1:
return True
else:
return False
def random_int(min, max):
return random.randint(min, max)
def timespan(date):
delta = datetime.date(get_date()) - datetime.date(get_datetime(date))
return delta.days
def trim(data, max_length):
if len(data) > max_length:
return data[:max_length] + '...'
else:
return data
def uptime(start_time):
uptime = datetime.datetime(1,1,1) + datetime.timedelta(seconds=time.time() - start_time)
return f'{uptime.day-1} Days, {uptime.hour} Hours, {uptime.minute} Minutes, {uptime.second} Seconds'

63
dickserv/core/httplib.py Normal file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# httplib.py
import json
import os
import re
import urllib.parse
import urllib.request
from bs4 import BeautifulSoup
def clean_url(url):
for prefix in ('https://', 'http://', 'www.'):
if url.startswith(prefix):
url = url[len(prefix):]
if url[-1:] == '/':
url = url[:-1]
return url
def data_quote(data):
return urllib.parse.quote(data)
def data_encode(data):
return urllib.parse.urlencode(data)
def get_file(url):
return os.path.basename(url)
def get_json(url):
return json.loads(get_source(url))
def get_size(url):
content_length = int(get_url(url).getheader('content-length'))
for unit in ('B','KB','MB','GB','TB','PB','EB','ZB'):
if abs(content_length) < 1024.0:
return '{0:.2f}'.format(content_length) + unit
content_length /= 1024.0
return '{0:.2f}'.format(content_length) + 'YB'
def get_source(url):
source = get_url(url)
charset = source.headers.get_content_charset()
if charset:
return source.read().decode(charset)
else:
return source.read().decode()
def get_title(url):
source = get_source(url)
soup = BeautifulSoup(source, 'html.parser')
return ' '.join(soup.title.string.split())
def get_type(url):
return get_url(url).info().get_content_type()
def get_url(url):
req = urllib.request.Request(url)
req.add_header('User-Agent', 'DickServ/1.0')
return urllib.request.urlopen(req, timeout=10)
def parse_urls(data):
return re.compile('(?:http[s]?:\/\/|www.)(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', re.IGNORECASE).findall(data)

479
dickserv/core/irc.py Normal file
View File

@ -0,0 +1,479 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# irc.py
import socket
import time
import config
import constants
import database
import debug
import functions
import httplib
from commands import *
# Load optional modules
if config.connection.ssl:
import ssl
if config.connection.proxy:
import sock
def color(msg, foreground, background=None):
if foreground == 'random':
foreground = '{0:0>2}'.format(functions.random_int(2,13))
if background == 'random':
background = '{0:0>2}'.format(functions.random_int(2,13))
if background:
return f'\x03{foreground},{background}{msg}{constants.reset}'
else:
return f'\x03{foreground}{msg}{constants.reset}'
class IRC(object):
def __init__(self):
self.last = 0
self.slow = False
self.sock = None
self.start = 0
self.status = True
def connect(self):
try:
self.create_socket()
self.sock.connect((config.connection.server, config.connection.port))
self.register()
except socket.error as ex:
debug.error('Failed to connect to IRC server.', ex)
Events.disconnect()
else:
self.listen()
def create_socket(self):
family = socket.AF_INET6 if config.connection.ipv6 else socket.AF_INET
if config.connection.proxy:
proxy_server, proxy_port = config.connection.proxy.split(':')
self.sock = socks.socksocket(family, socket.SOCK_STREAM)
self.sock.setblocking(0)
self.sock.settimeout(15)
self.sock.setproxy(socks.PROXY_TYPE_SOCKS5, proxy_server, int(proxy_port))
else:
self.sock = socket.socket(family, socket.SOCK_STREAM)
if config.connection.vhost:
self.sock.bind((config.connection.vhost, 0))
if config.connection.ssl:
ctx = ssl.SSLContext()
if config.cert.file:
ctx.load_cert_chain(config.cert.file, config.cert.key, config.cert.password)
if config.connection.ssl_verify:
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.load_default_certs()
else:
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
self.sock = ctx.wrap_socket(self.sock)
def listen(self):
while True:
try:
data = self.sock.recv(1024).decode('utf-8')
for line in (line for line in data.split('\r\n') if line):
debug.irc(line)
if len(line.split()) >= 2:
Events.handle(line)
except (UnicodeDecodeError,UnicodeEncodeError):
pass
except Exception as ex:
debug.error('Unexpected error occured.', ex)
break
Events.disconnect()
def register(self):
if config.login.network:
Commands.raw('PASS ' + config.login.network)
Commands.raw(f'USER {config.ident.username} 0 * :{config.ident.realname}')
Commands.nick(config.ident.nickname)
class Commands:
def action(chan, msg):
Commands.sendmsg(chan, f'\x01ACTION {msg}\x01')
def error(target, data, reason=None):
if reason:
Commands.sendmsg(target, '[{0}] {1} {2}'.format(color('!', constants.red), data, color('({0})'.format(reason), constants.grey)))
else:
Commands.sendmsg(target, '[{0}] {1}'.format(color('!', constants.red), data))
def identify(nick, password):
Commands.sendmsg('nickserv', f'identify {nick} {password}')
def join_channel(chan, key=None):
Commands.raw(f'JOIN {chan} {key}') if key else Commands.raw('JOIN ' + chan)
def mode(target, mode):
Commands.raw(f'MODE {target} {mode}')
def nick(nick):
Commands.raw('NICK ' + nick)
def notice(target, msg):
Commands.raw(f'NOTICE {target} :{msg}')
def oper(user, password):
Commands.raw(f'OPER {user} {password}')
def raw(msg):
msg = msg.replace('\r','').replace('\n','')[:450]
DickServ.sock.send(bytes(msg + '\r\n', 'utf-8'))
def sendmsg(target, msg):
Commands.raw(f'PRIVMSG {target} :{msg}')
class Events:
def connect():
DickServ.start = time.time()
if config.settings.modes:
Commands.mode(config.ident.nickname, '+' + config.settings.modes)
if config.login.nickserv:
Commands.identify(config.ident.nickname, config.login.nickserv)
if config.login.operator:
Commands.oper(config.ident.username, config.login.operator)
Commands.join_channel(config.connection.channel, config.connection.key)
def disconnect():
DickServ.sock.close()
time.sleep(10)
DickServ.connect()
def kick(nick, chan, kicked):
if kicked == config.ident.nickname and chan == config.connection.channel:
time.sleep(3)
Commands.join_channel(chan, config.connection.key)
def message(nick, ident, chan, msg):
try:
if chan == config.connection.channel and (DickServ.status or ident == config.settings.admin):
if not msg.startswith(config.settings.cmd_char):
urls = httplib.parse_urls(msg)
if urls:
if time.time() - DickServ.last > 3:
DickServ.last = time.time()
Events.url(chan, urls[0])
elif msg == '@dickserv':
Commands.sendmsg(chan, constants.bold + 'DickServ IRC Bot - Developed by acidvegas in Python - https://acid.vegas/dickserv')
elif msg == '@dickserv help':
Commands.sendmsg(chan, 'https://git.supernets.org/acidvegas/dickserv#commands')
elif msg == 'h' and functions.luck(4):
Commands.sendmsg(chan, 'h')
elif 'qhat' in msg:
Commands.sendmsg(chan, 'Q:)')
elif ident not in database.Ignore.idents():
if time.time() - DickServ.last < 3 and ident != config.settings.admin:
if not DickServ.slow:
Commands.sendmsg(chan, color('Slow down nerd!', constants.red))
DickServ.slow = True
else:
DickServ.slow = False
args = msg.split()
argz = msg[len(args[0])+1:]
cmd = args[0][1:]
if len(args) == 1:
if cmd == 'date':
Commands.sendmsg(chan, functions.current_date())
elif cmd == 'talent':
if functions.luck(1000):
Commands.sendmsg(chan, color(f' !!! HOLY FUCKING SHIT {nick} ACHIEVED TALENT !!! ', 'random', 'random'))
Commands.sendmsg(chan, color(' !!! RIP DITTLE DIP DIP DIP DIP IT\'S YOUR BIRTHDAY !!! ', 'random', 'random'))
Commands.sendmsg(chan, color(f' !!! CAN WE HAVE A GOT DAMN MOMENT OF SILENCE FOR {nick} :) !!! ', 'random', 'random'))
Commands.sendmsg(chan, color(' !!! GOT DAMN XD THIS IS TOO CRAZY LIKE...DAMN HAHA. DAMN. !!! ', 'random', 'random'))
else:
Commands.sendmsg(chan, color('(^)', 'random'))
elif cmd == 'todo':
todos = database.Todo.read(ident)
if todos:
for item in todos:
Commands.notice(nick, '[{0}] {1}'.format(color(todos.index(item)+1, constants.pink), item))
else:
Commands.notice(nick, 'You have no saved todos.')
elif cmd == 'uptime':
Commands.sendmsg(chan, functions.uptime(DickServ.start))
elif len(args) == 2:
if cmd == 'coin':
api = cryptocurrency.get(args[1])
if api:
Commands.sendmsg(chan, '{0} {1} - ${2:,.2f}'.format(color(api['name'], constants.white), color('({0})'.format(api['symbol']), constants.grey), float(api['price_usd'])))
else:
Commands.error(chan, 'Invalid cryptocurrency name!')
elif cmd == 'drug':
api = tripsit.drug(args[1])
if api:
Commands.sendmsg(chan, '{0} - {1}'.format(color(api['name'], constants.yellow), api['desc']))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'define':
definition = dictionary.define(args[1])
if definition:
Commands.sendmsg(chan, '{0} - {1}: {2}'.format(color('Definition', constants.white, constants.blue), args[1].lower(), definition))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'isup':
Commands.sendmsg(chan, '{0} is {1}'.format(args[1], isup.check(args[1])))
elif cmd == 'r':
api = reddit.read(args[1])
if api:
data = list(api.keys())
for i in data:
count = str(data.index(i)+1)
Commands.sendmsg(chan, '[{0}] {1} [{2}|{3}/{4}|{5}]'.format(color(count, constants.pink), functions.trim(i, 100), color(str(api[i]['score']), constants.white), color('+' + str(api[i]['ups']), constants.green), color('-' + str(api[i]['downs']), constants.red), color(api[i]['comments'], constants.white)))
Commands.sendmsg(chan, ' - ' + color(api[i]['url'], constants.grey))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'w':
if args[1].isdigit():
api = weather.lookup(args[1])
if api:
Commands.sendmsg(chan, api)
else:
Commands.error(chan, 'No results found.')
else:
Commands.error(chan, 'Invalid arguments.')
if len(args) >= 2:
if cmd == 'g':
api = google.search(argz, database.Settings.get('max_results'))
if api:
for result in api:
count = api.index(result)+1
Commands.sendmsg(chan, '[{0}] {1}'.format(color(count, constants.pink), result['title']))
Commands.sendmsg(chan, ' - ' + color(result['link'], constants.grey))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'imdb':
api = imdb.search(argz)
if api:
Commands.sendmsg(chan, '{0} {1} {2} {3}'.format(color('Title :', constants.white), api['Title'], api['Year'], color(api['Rated'], constants.grey)))
Commands.sendmsg(chan, '{0} {1}{2}'.format(color('Link :', constants.white), constants.underline, color('https://imdb.com/title/' + api['imdbID'], constants.light_blue)))
Commands.sendmsg(chan, '{0} {1}'.format(color('Genre :', constants.white), api['Genre']))
if api['imdbRating'] == 'N/A':
Commands.sendmsg(chan, '{0} {1} 0/10'.format(color('Rating :', constants.white), color('★★★★★★★★★★', constants.grey)))
else:
Commands.sendmsg(chan, '{0} {1}{2} {3}/10'.format(color('Rating :', constants.white), color(''*round(float(api['imdbRating'])), constants.yellow), color(''*(10-round(float(api['imdbRating']))), constants.grey), api['imdbRating']))
Commands.sendmsg(chan, '{0} {1}'.format(color('Plot :', constants.white), api['Plot']))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'netsplit':
api = netsplit.search(argz)
if api:
data = list(api.keys())
for i in data:
count = str(data.index(i)+1)
Commands.sendmsg(chan, '[{0}] {1} {2} / {3}'.format(color(count, constants.pink), color(i, constants.light_blue), color('({0})'.format(api[i]['users']), constants.grey), color(api[i]['network'], constants.red)))
Commands.sendmsg(chan, color(' - ' + api[i]['topic'], constants.grey))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'todo' and len(args) >= 3:
if len(args) >= 3 and args[1] == 'add':
todos = database.Todo.read(ident)
if len(todos) <= database.Settings.get('max_todo_per') and len(database.Todo.read()) <= database.Settings.get('max_todo'):
argz = argz[4:]
if argz not in todos:
database.Todo.add(functions.get_date(), ident, argz)
Commands.notice(nick, 'Todo added to database!')
else:
Commands.notice(nick, 'Todo already in database!')
else:
Commands.notice(nick, 'Maximum todos reached!')
elif len(args) == 3 and args[1] == 'del':
num = args[2]
if num.isdigit():
num = int(num)
todos = database.Todo.read(ident)
if todos:
if num <= len(todos):
for item in todos:
count = todos.index(item)+1
if count == num:
database.Todo.remove(ident, item)
break
Commands.notice(nick, 'Todo removed from database!')
else:
Commands.notice(nick, 'Invalid number.')
else:
Commands.notice(nick, 'No todos found.')
else:
Commands.notice(nick, 'Invalid number.')
else:
Commands.notice(nick, 'Invalid arguments.')
elif cmd == 'tpb':
api = tpb.search(argz, database.Settings.get('max_results'))
if api:
data = list(api.keys())
for i in data:
count = str(data.index(i)+1)
Commands.sendmsg(chan, '[{0}] {1} [{2}/{3}]'.format(color(count, constants.pink), i, color(api[i]['seeders'], constants.green), color(api[i]['leechers'], constants.red)))
Commands.sendmsg(chan, ' - ' + color('http://thepiratebay.org' + api[i]['url'], constants.grey))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'ud':
definition = dictionary.urban(argz)
if definition:
Commands.sendmsg(chan, '{0}{1} - {2}: {3}'.format(color('urban', constants.white, constants.blue), color('DICTIONARY', constants.yellow, constants.black), argz, definition))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'wolfram':
results = wolfram.ask(argz)
if results:
Commands.sendmsg(chan, '{0}{1} - {2}'.format(color('Wolfram', constants.red), color('Alpha', constants.orange), results))
else:
Commands.error(chan, 'No results found.')
elif cmd == 'yt':
api = youtube.search(argz, database.Settings.get('max_results'))
if api:
data = list(api.keys())
for i in api.keys():
count = str(data.index(i)+1)
Commands.sendmsg(chan, '[{0}] {1}'.format(color(count, constants.pink), functions.trim(i, 75)))
Commands.sendmsg(chan, ' - ' + color(api[i], constants.grey))
else:
Commands.error(chan, 'No results found.')
DickServ.last = time.time()
except Exception as ex:
Commands.error(chan, 'Command threw an exception.', ex)
def nick_in_use():
debug.error('DickServ is already running or nick is in use.')
def private(nick, ident, msg):
try:
if ident == config.settings.admin_host:
args = msg.split()
cmd = args[0][1:]
if len(args) == 1:
if cmd == 'config':
settings = database.Settings.read()
Commands.sendmsg(nick, '[{0}]'.format(color('Settings', constants.purple)))
for setting in settings:
Commands.sendmsg(nick, '{0} = {1}'.format(color(setting[0], constants.yellow), color(setting[1], constants.grey)))
elif cmd == 'ignore':
ignores = database.Ignore.idents()
if ignores:
Commands.sendmsg(nick, '[{0}]'.format(color('Ignore List', constants.purple)))
for user in ignores:
Commands.sendmsg(nick, color(user, constants.yellow))
Commands.sendmsg(nick, '{0} {1}'.format(color('Total:', constants.light_blue), color(len(ignores), constants.grey)))
else:
Commands.error(nick, 'Ignore list is empty!')
elif cmd == 'off':
DickServ.status = False
Commands.sendmsg(nick, color('OFF', constants.red))
elif cmd == 'on':
DickServ.status = True
Commands.sendmsg(nick, color('ON', constants.green))
elif len(args) == 2:
if cmd == 'ignore' and args[1] == 'reset':
database.Ignore.reset()
elif cmd == 'todo' and args[1] == 'expire':
database.Todo.expire_check()
elif cmd == 'todo' and args[1] == 'reset':
database.Todo.reset()
elif len(args) == 3:
if cmd == 'config':
setting, value = args[1], args[2]
if functions.CheckString.number(value):
value = functions.floatint(value)
if value >= 0:
if setting in database.Settings.settings():
database.Settings.update(setting, value)
Commands.sendmsg(nick, 'Change setting for {0} to {1}.'.format(color(setting, constants.yellow), color(value, constants.grey)))
else:
Commands.error(nick, 'Invalid config variable.')
else:
Commands.error(nick, 'Value must be greater than or equal to zero.')
else:
Commands.error(nick, 'Value must be an integer or float.')
elif cmd == 'ignore':
if args[1] == 'add':
user_ident = args[2]
if user_ident not in database.Ignore.idents():
database.Ignore.add(nickname, user_ident)
Commands.sendmsg(nick, 'Ident {0} to the ignore list.'.format(color('added', constants.green)))
else:
Commands.error(nick, 'Ident is already on the ignore list.')
elif cmd == 'del':
user_ident = args[2]
if user_ident in database.Ignore.idents():
database.Ignore.remove(user_ident)
Commands.sendmsg(nick, 'Ident {0} from the ignore list.'.format(color('removed', constants.red)))
else:
Commands.error(nick, 'Ident does not exist in the ignore list.')
except Exception as ex:
Commands.error(nick, 'Command threw an exception.', ex)
def url(chan, url):
try:
if imdb.check(url):
id = imdb.check(url)
api = imdb.search(id)
if api:
Commands.sendmsg(chan, '{0} {1} {2} {3}'.format(color('Title :', constants.white), api['Title'], api['Year'], color(api['Rated'], constants.grey)))
Commands.sendmsg(chan, '{0} {1}{2}'.format(color('Link :', constants.white), constants.underline, color('https://imdb.com/title/' + api['imdbID'], constants.light_blue)))
Commands.sendmsg(chan, '{0} {1}'.format(color('Genre :', constants.white), api['Genre']))
if api['imdbRating'] == 'N/A':
Commands.sendmsg(chan, '{0} {1} 0/10'.format(color('Rating :', constants.white), color('★★★★★★★★★★', constants.grey)))
else:
Commands.sendmsg(chan, '{0} {1}{2} {3}/10'.format(color('Rating :', constants.white), color(''*round(float(api['imdbRating'])), constants.yellow), color(''*(10-round(float(api['imdbRating']))), constants.grey), api['imdbRating']))
Commands.sendmsg(chan, '{0} {1}'.format(color('Plot :', constants.white), api['Plot']))
elif reddit.check(url):
subreddit = reddit.check(url)[0]
post_id = reddit.check(url)[1]
api = reddit.post_info(subreddit, post_id)
if api:
Commands.sendmsg(chan, '[{0}] - {1} [{2}|{3}/{4}|{5}]'.format(color('reddit', constants.cyan), color(functions.trim(api['title'], 75), constants.white), color(api['score'], constants.white), color('+' + api['ups'], constants.green), color('-' + api['downs'], constants.red), color(api['num_comments'], constants.white)))
elif youtube.check(url):
api = youtube.video_info(youtube.check(url))
if api:
Commands.sendmsg(chan, '{0}{1} - {2} [{3}|{4}/{5}]'.format(color('You', constants.black, constants.white), color('Tube', constants.white, constants.red), functions.trim(api['title'], 75), color(api['views'], constants.white), color('+' + api['likes'], constants.green), color('-' + api['dislikes'], constants.red)))
Commands.sendmsg(chan, color(api['description'], constants.grey))
else:
url_type = httplib.get_type(url)
if url_type == 'text/html':
title = httplib.get_title(url)
Commands.sendmsg(chan, '[{0}] {1}'.format(color(url_type, constants.pink), color(title, constants.white)))
else:
file_name = httplib.get_file(url)
if file_name:
file_size = httplib.get_size(url)
Commands.sendmsg(chan, '[{0}] {1} [{2}]'.format(color(url_type, constants.pink), color(file_name, constants.white), color(file_size, constants.blue)))
except Exception as ex:
debug.error('Title Error', ex)
def handle(data):
args = data.split()
if data.startswith('ERROR :Closing Link:'):
raise Exception('Connection has closed.')
elif args[0] == 'PING':
Commands.raw('PONG ' + args[1][1:])
elif args[1] == constants.RPL_WELCOME:
Events.connect()
elif args[1] == constants.ERR_NICKNAMEINUSE:
Events.nick_in_use()
elif args[1] == constants.KICK:
nick = args[0].split('!')[0][1:]
chan = args[2]
kicked = args[3]
Events.kick(nick, chan, kicked)
elif args[1] == constants.PRIVMSG:
nick = args[0].split('!')[0][1:]
ident = args[0].split('!')[1]
chan = args[2]
msg = ' '.join(args[3:])[1:]
if chan == config.ident.nickname:
Events.private(nick, ident, msg)
else:
Events.message(nick, ident, chan, msg)
DickServ = IRC()

4
dickserv/data/cert/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

4
dickserv/data/logs/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

24
dickserv/dickserv.py Normal file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# dickserv.py
import os
import sys
sys.dont_write_bytecode = True
os.chdir(sys.path[0] or '.')
sys.path += ('core','modules')
import debug
debug.setup_logger()
debug.info()
if not debug.check_version(3):
debug.error_exit('Python 3 is required!')
if debug.check_privileges():
debug.error_exit('Do not run as admin/root!')
debug.check_libs()
import database
database.check()
import irc
irc.DickServ.connect()

View File

@ -0,0 +1,13 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# cryptocurrency.py
import httplib
def get(coin):
api = httplib.get_json('https://api.coinmarketcap.com/v1/ticker/?limit=500')
data = [item for item in api if (coin.lower() == item['id'] or coin.upper() == item['symbol'])]
if data:
return data[0]
else:
return False

View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# dictionary.py
import httplib
import functions
def define(word):
source = httplib.get_source('http://www.merriam-webster.com/dictionary/' + word.replace(' ', '%20'))
results = functions.between(source, f'<meta name="description" content="Define {word}: ', '">')
if results:
return results
else:
return False
def urban(word):
api = httplib.get_json('http://api.urbandictionary.com/v0/define?term=' + word.replace(' ', '+'))
if api['result_type'] != 'no_results':
definition = api['list'][0]['definition']
return definition
else:
return False

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# google.py
from googleapiclient.discovery import build
import config
def search(query, results):
service = build('customsearch', 'v1', developerKey=config.api.google_api_key, cache_discovery=False)
results = service.cse().list(q=query, cx=config.api.google_cse_id, num=results).execute()
return results['items']

31
dickserv/modules/imdb.py Normal file
View File

@ -0,0 +1,31 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# imdb.py
import re
import config
import httplib
def check(url):
found = re.match('^.*?imdb.com\/title\/tt([0-9A-Za-z]+).*?$', url, re.IGNORECASE)
if found:
return found.group(1)
else:
return False
def search(query):
if query.startswith('tt') and len(query) == 9:
api = httplib.get_json(f'http://omdbapi.com/?i={query}&apikey={config.api.omdbapi_key}')
else:
year = query.split()[-1]
if len(year) == 4 and year.isdigit():
query = query[:-5].replace(' ', '%20')
api = httplib.get_json(f'http://omdbapi.com/?t={query}&y={year}&apikey={config.api.omdbapi_key}')
else:
query = query.replace(' ', '%20')
api = httplib.get_json(f'http://omdbapi.com/?t={query}&apikey={config.api.omdbapi_key}')
if api['Response'] == 'True':
return api
else:
return False

16
dickserv/modules/isup.py Normal file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# isup.py
import httplib
def check(url):
source = httplib.get_source('http://isup.me/' + url)
if source.find('It\'s just you.') != -1:
return 'UP'
elif source.find('It\'s not just you!') != -1:
return 'DOWN'
elif source.find('Huh?') != -1:
return 'INVALID'
else:
return 'UNKNOWN'

View File

@ -0,0 +1,24 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# netsplit.py
import re
import functions
import httplib
def search(query):
channels = {}
source = httplib.get_source('http://irc.netsplit.de/channels/?chat=' + query.replace(' ','+'))
for i in ('&#8203;','<b>','</b>','<span style="color:#000000;">','<strong>','</strong>'):
source = source.replace(i, '')
channel_objects = re.findall('<div style="margin: 4px; padding: 0 0 15 0; text-align: left;">(.*?)</a></span></div>', source, re.IGNORECASE|re.MULTILINE)
for data in channel_objects:
channel = functions.between(data, '<span class="cs-channel">', '</span>')
network = functions.between(data, '<span class="cs-network">', '</span>')
users = functions.between(data, '<span class="cs-users">', ' &ndash; </span>')
topic = functions.between(data, '<span class="cs-topic">', '</span><br>')
if not topic:
topic = 'No channel topic set.'
channels[channel] = {'network':network,'users':users,'topic':topic}
return channels

View File

@ -0,0 +1,34 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# reddit.py
import re
import httplib
from database import Settings
def check(url):
found = re.match('^.*?reddit.com\/r\/(.*?)\/comments\/([0-9A-Za-z]+).*$', url, re.IGNORECASE)
if found:
return (found.group(1), found.group(2))
else:
return False
def post_info(subreddit, id):
api = httplib.get_json(f'https://www.reddit.com/r/{subreddit}/comments/{id}.json')
if 'error' not in api:
return api[0]['data']['children'][0]['data']
else:
return False
def read(subreddit):
api = httplib.get_json('https://www.reddit.com/r/{0}.json?limit={1}'.format(subreddit, Settings.get('max_results')))
data = [x['data'] for x in api['data']['children']]
if data:
results = {}
for item in data:
if not item['stickied']:
results[item['title']] = {'url':item['url'], 'score':item['score'], 'ups':item['ups'], 'downs':item['downs'], 'comments':item['num_comments']}
return results
else:
return False

23
dickserv/modules/tpb.py Normal file
View File

@ -0,0 +1,23 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# tpb.py
import re
import httplib
from database import Settings
def search(query, results):
url = 'https://thepiratebay.org/search/{0}/0/99/0'.format(query.replace(' ', '+'))
source = httplib.get_source(url)
torrents = re.findall('<a href="(.*?)" class="detLink".*>(.*?)</a>', source)
seeders = re.findall('\t\t</td>\n\t\t<td align="right">(.*?)</td>', source)
leechers = re.findall('<td align="right">(.*?)</td>\n\t</tr>', source)
if torrents:
data = {}
torrents = torrents[:results]
for i in range(len(torrents)):
data[torrents[i][1]] = {'seeders':seeders[i], 'leechers':leechers[i], 'url':torrents[i][0]}
return data
else:
return False

View File

@ -0,0 +1,12 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# tripsit.py
import httplib
def drug(query):
api = httplib.get_json('http://tripbot.tripsit.me/api/tripsit/getDrug?name=' + query.replace(' ','%20'))
if api['err'] != True:
return {'name':api['data'][0]['name'],'desc':api['data'][0]['properties']['summary']}
else:
return False

View File

@ -0,0 +1,19 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# weather.py
import httplib
import config
def lookup(zip_code):
api = httplib.get_json('http://api.wunderground.com/api/{0}/conditions/q/{1}.json'.format(config.api.wunderground_api_key, zip_code))
if 'error' not in api:
city = api['current_observation']['display_location']['city']
state = api['current_observation']['display_location']['state']
country = api['current_observation']['display_location']['country']
weather = api['current_observation']['weather']
temp = api['current_observation']['temp_f']
return 'The weather for {0}, {1}, {2} is {3} at {4} F'.format(city, state, country, weather, temp)
else:
return False

View File

@ -0,0 +1,23 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# wolfram.py
from xml.etree import ElementTree as etree
import config
import httplib
def ask(query):
params = httplib.data_encode({'input':query, 'appid':config.api.wolfram_api_key})
data = httplib.get_source('http://api.wolframalpha.com/v2/query?' + params)
results = {}
tree = etree.fromstring(data)
for e in tree.findall('pod'):
for item in [ef for ef in list(e) if ef.tag=='subpod']:
for it in [i for i in list(item) if i.tag=='plaintext']:
if it.tag=='plaintext':
results[e.get('title')] = it.text
if 'Result' in results:
return results['Result']
else:
return False

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
# DickServ IRC Bot - Developed by acidvegas in Python (https://acid.vegas/dickserv)
# youtube.py
import re
import config
import httplib
def check(url):
found = re.match('^.*?youtu(be)?\.([a-z])+\/(watch(.*?)(\?|\&)v=)?(.*?)(&(.)*)*$', url, re.IGNORECASE)
if found:
return found.group(6)
else:
return False
def video_info(id):
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
def search(query, results):
url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&key={0}&q={1}&maxResults={2}&type=video&regionCode=US&relevanceLanguage=en&safeSearch=none'.format(config.api.google_api_key, httplib.data_quote(query), results)
api = httplib.get_json(url)
results = {}
for item in api['items']:
title = item['snippet']['title']
url = 'https://www.youtube.com/watch?v=' + item['id']['videoId']
results[title] = url
return results