Initalize repo

This commit is contained in:
BaerbelBox
2022-03-31 15:21:47 +02:00
parent 557f3e9b31
commit 7cf65ef092
98 changed files with 15860 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
import _thread
import queue
import socket
import time
from threading import Condition
from FaustBot.Communication.JoinObservable import JoinObservable
from FaustBot.Communication.KickObservable import KickObservable
from FaustBot.Communication.LeaveObservable import LeaveObservable
from FaustBot.Communication.MagicNumberObservable import MagicNumberObservable
from FaustBot.Communication.NickChangeObservable import NickChangeObservable
from FaustBot.Communication.NoticeObservable import NoticeObservable
from FaustBot.Communication.PingObservable import PingObservable
from FaustBot.Communication.PrivmsgObservable import PrivmsgObservable
from FaustBot.Model.ConnectionDetails import ConnectionDetails
from FaustBot.StringBuffer import StringBuffer
class Connection(object):
send_queue = queue.Queue()
details = None
irc = None
def sender(self):
while True:
msg = self.send_queue.get()
if msg[-1] != b'\n':
msg = msg + b'\n'
self.irc.send(msg)
time.sleep(1)
def send_channel(self, text):
"""
Send to channel
:return:
"""
self.raw_send("PRIVMSG " + self.details.get_channel() + " :" + text[0:])
def send_to_user(self, user, text):
"""
Send to user
:return:
"""
self.raw_send('PRIVMSG ' + user + ' :' + text)
def send_back(self, text, data):
"""
Send message to the channel the command got received in
:param message:
:param data: needed because of concurrency, there can't be a global variable holding where messages came from
:return:
"""
if data['channel'] == self.details.get_nick():
self.send_to_user(data['nick'], text)
else:
self.send_channel(text)
def raw_send(self, message):
self.send_queue.put(message.encode() + '\r\n'.encode())
def receive(self):
"""
receive from Network
"""
try:
data = self.irc.recv(4096)
if len(data) == 0:
return False
except socket.timeout:
return False
data = data.decode('UTF-8', errors='replace')
#print('received: \n' + data)
data_lines = self._receiver_buffer.append(data)
if data is None:
return False
# print('splited: ')
for data in data_lines:
# print(data)
data = data.rstrip()
self.data = data
splited = data.split(' ')
if not len(splited) >= 2:
continue
command = splited[1]
# print(command)
if data.split(' ')[0] == 'PING':
self.ping_observable.input(data, self)
elif command == 'JOIN':
self.join_observable.input(data, self)
elif command == 'PART' or command == 'QUIT':
self.leave_observable.input(data, self)
elif command == 'KICK':
self.kick_observable.input(data, self)
elif command == 'NICK':
self.nick_change_observable.input(data, self)
elif command == 'NOTICE':
self.notice_observable.input(data, self)
elif command == 'PRIVMSG':
self.priv_msg_observable.input(data, self)
else:
try:
int(command)
self.magic_number_observable.input(data, self)
except Exception:
pass
return True
def is_idented(self, user: str):
self.send_to_user('NickServ', 'ACC ' + user)
with self.condition_lock:
while user not in self.idented_look_up:
self.condition_lock.wait()
is_idented = self.idented_look_up[user]
del self.idented_look_up[user]
return is_idented
def is_op(self, user):
"""
Checks wether the given user is an op in this connections' channel or not.
:param user: the user to check
:return: return true if the user is an op, else false
"""
# add call to raw send with WHO
# manualy receive data until answer received
# then evaluate and return
# this way we'll block the bot until is_op is finished
return False
def last_data(self):
return self.data
def establish(self):
"""
establish the connection
"""
self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.irc.connect((self.details.get_server(), self.details.get_port()))
#print(self.irc.recv(512))
self.irc.send("NICK ".encode() + self.details.get_nick().encode() + "\r\n".encode())
self.irc.send("USER botty botty botty :Botty \n".encode())
self.irc.send("JOIN ".encode() + self.details.get_channel().encode() + '\r\n'.encode())
self.irc.send("WHO ".encode() + self.details.get_channel().encode() + '\r\n'.encode())
self.irc.send("MODE ".encode()+self.details.get_nick().encode()+" -R".encode()+'\r\n'.encode())
if (self.details.get_pwd() != ''):
self.send_to_user("NICKSERV","identify "+self.details.get_nick()+" " +self.details.get_pwd()+' ')
_thread.start_new_thread(self.sender, ())
def __init__(self, set_details: ConnectionDetails):
self.details = set_details
self.ping_observable = PingObservable()
self.priv_msg_observable = PrivmsgObservable()
self.join_observable = JoinObservable()
self.leave_observable = LeaveObservable()
self.kick_observable = KickObservable()
self.nick_change_observable = NickChangeObservable()
self.notice_observable = NoticeObservable()
self.magic_number_observable = MagicNumberObservable()
self.condition_lock = Condition()
self.idented_look_up = {}
self.data = None
self._receiver_buffer = StringBuffer()

View File

@@ -0,0 +1,9 @@
__author__ = 'Daniela'
class DebugPrint(object):
def print(self, message):
"""
:param message: What to print to debug output
:return:
"""

View File

@@ -0,0 +1,24 @@
import _thread
from FaustBot.Communication.Observable import Observable
class JoinObservable(Observable):
def input(self, raw_data, connection):
# ":nick!user@host" "JOIN" "#channel"
# additional ignored arguments are put into "ign". This could be used
# for http://ircv3.net/specs/extensions/extended-join-3.1.html in the
# future.
prefix, cmd, channel, *ign = raw_data.split(' ')
hostmask = prefix.lstrip(':')
nick, userhost = hostmask.split('!')
user, host = userhost.split('@')
data = {'raw': raw_data, 'nick': nick, 'user': user, 'host': host,
'channel': channel, 'raw_nick': hostmask}
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_join, (observer, data, connection))

View File

@@ -0,0 +1,20 @@
import _thread
from FaustBot.Communication.Observable import Observable
class KickObservable(Observable):
def input(self, raw_data, connection):
data = {}
print(raw_data)
data['raw'] = raw_data
data['op'] = raw_data.split('!')[0][1:]
data['channel'] = raw_data.split('KICK ')[1].split(' :')[0].split(' ')[0]
data['nick'] = raw_data.split('KICK ')[1].split(' :')[0].split(' ')[1]
data['raw_op'] = raw_data.split(' KICK')[0][1:]
data['reason'] = raw_data.split('KICK ')[1].split(' :')[1]
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_kick, (observer, data, connection))

View File

@@ -0,0 +1,18 @@
import _thread
from FaustBot.Communication.Observable import Observable
class LeaveObservable(Observable):
def input(self, raw_data, connection):
data = {}
leave_or_part = "PART" if raw_data.find('PART') != -1 else "QUIT"
data['raw'] = raw_data
data['nick'] = raw_data.split('!')[0][1:]
data['channel'] = raw_data.split(leave_or_part + ' ')[1].split(' :')[0]
data['raw_nick'] = raw_data.split(' ' + leave_or_part)[0][1:]
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_leave, (observer, data, connection))

View File

@@ -0,0 +1,21 @@
import _thread
from FaustBot.Communication.Observable import Observable
class MagicNumberObservable(Observable):
def input(self, raw_data, connection):
data = {}
data['raw'] = raw_data
prefix, numeric, rest = data['raw'].split(' ',2)
data['number'] = numeric
data['arguments'] = rest
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
try:
_thread.start_new_thread(observer.__class__.update_on_magic_number, (observer, data, connection))
except Exception:
import traceback
print (traceback.format_exc())

View File

@@ -0,0 +1,14 @@
import _thread
from FaustBot.Communication.Observable import Observable
class NickChangeObservable(Observable):
def input(self, raw_data, connection):
data = {'raw': raw_data, 'old_nick': raw_data.split('!')[0][1:],
'new_nick': raw_data.split('NICK ')[1].split(':')[1], 'raw_nick': raw_data.split(' NICK')[0][1:]}
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_nick_change, (observer, data, connection))

View File

@@ -0,0 +1,14 @@
import _thread
from FaustBot.Communication.Observable import Observable
class NoticeObservable(Observable):
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_notice, (observer, data, connection))
def input(self, raw_data, connection):
data = {'raw_data': raw_data, 'nick': raw_data.split('!')[0][1:], 'raw_nick': raw_data.split(' NOTICE ')[0][1:],
'message': raw_data.split(':')[2]}
self.notify_observers(data, connection)

View File

@@ -0,0 +1,23 @@
class Observable(object):
def __init__(self):
self._observers = []
def add_observer(self, observer):
self._observers.append(observer)
print("appended(" + str(observer.__class__) + ")")
def get_observer(self):
return self._observers
# data has to be a dictionary matching the structure of the query
def notify_observers(self, data, connection):
# here implement some data handling. Fill self._data with the data received
raise NotImplementedError("Some Observable doesn't know what to do with its input data")
def input(self, raw_data, connection):
# here implement some data handling. Fill self._data with the data received
raise NotImplementedError("Some Observable doesn't know what to do with its input data")
def rm_observer(self, observer):
self._observers.remove(observer)

View File

@@ -0,0 +1,20 @@
import _thread
from FaustBot.Communication.Observable import Observable
class PingObservable(Observable):
def input(self, raw_data, connection):
data = {'raw': raw_data, 'server': ''}
if raw_data.find('PING') == 0:
data['server'] = raw_data.split('PING ')[1]
else:
return
# hier kann noch gecheckt werden, ob data wirklich ein server ist, der ping haben will, oder sonstwas
# finde heraus, wer zurückgepingt werden muss, und ob das überhaupt ein ping-request ist oder ein user sich
# einen spass erlaubt hat
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_ping, (observer, data, connection))

View File

@@ -0,0 +1,37 @@
import _thread
from FaustBot.Communication.Observable import Observable
from FaustBot import Modules
from FaustBot.Model.BlockedUsers import BlockProvider
class PrivmsgObservable(Observable):
def __init__(self):
Observable.__init__(self)
self.user_list = None
def define_user_list(self, user_list):
self.user_list = user_list
def input(self, raw_data, connection):
data = {'raw': raw_data, 'nick': raw_data.split('!')[0][1:],
'channel': raw_data.split('PRIVMSG ')[1].split(' :')[0],
'raw_nick': raw_data.split(' PRIVMSG')[0][1:]}
# 12 = :<raw_nick> PRIVMSG <channel> :<message>
data['message'] = raw_data[data['raw_nick'].__len__() + data['channel'].__len__() + 12:]
data['command'] = 'irgendwas, das mit . oder .. anfängt oder so... oder das sollen module checken?'
if self.user_list is None:
return
if data['nick'] not in self.user_list.userList.keys():
return
blocklist = BlockProvider()
if blocklist.is_blocked(data['nick']):
self.notify_whitelisted_observers(data, connection)
return
self.notify_observers(data, connection)
def notify_observers(self, data, connection):
for observer in self._observers:
_thread.start_new_thread(observer.__class__.update_on_priv_msg, (observer, data, connection))
def notify_whitelisted_observers(self,data,connection):
for observer in self._observers:
if observer.__class__.__name__ in ['ActivityObserver']:
_thread.start_new_thread(observer.__class__.update_on_priv_msg, (observer, data, connection))

View File

@@ -0,0 +1 @@
__author__ = 'Pups'