mirror of
https://github.com/krislamo/Flea
synced 2024-12-16 11:10:34 +00:00
Added logging functionality
Added logging of all sent/received data and errors. Passwords are censored from the terminal and log file. Fixed case-sensitivity of the Control nick and channel.
This commit is contained in:
parent
80e6787d50
commit
037052d1c7
23
Flea.py
23
Flea.py
@ -15,10 +15,27 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
import traceback
|
import traceback
|
||||||
|
import sys
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import core.main
|
import core.main
|
||||||
except:
|
|
||||||
traceback.print_exc()
|
except KeyboardInterrupt:
|
||||||
input()
|
print "\nGoodbye!"
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
except SystemExit:
|
||||||
|
raise
|
||||||
|
|
||||||
|
except:
|
||||||
|
# Print error, save it to error.txt
|
||||||
|
# then wait to be closed.
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
errorfile = open("error.txt", 'a')
|
||||||
|
traceback.print_exc(None, errorfile)
|
||||||
|
errorfile.close()
|
||||||
|
|
||||||
|
raw_input()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
# Built-in to Python 2.7
|
# Built-in to Python 2.7
|
||||||
import socket
|
import socket
|
||||||
|
import re
|
||||||
|
|
||||||
class irc:
|
class irc:
|
||||||
debug = False
|
|
||||||
|
|
||||||
|
debug = False
|
||||||
|
log = False
|
||||||
config = {}
|
config = {}
|
||||||
pack = {}
|
pack = {}
|
||||||
sock = socket.socket()
|
sock = socket.socket()
|
||||||
@ -79,10 +81,22 @@ class irc:
|
|||||||
return packet
|
return packet
|
||||||
|
|
||||||
|
|
||||||
# Basic message function to send any data
|
# Basic message function to send and log any data
|
||||||
def msg(self, message):
|
def msg(self, message):
|
||||||
self.sock.send(message+"\r\n")
|
self.sock.send(message+"\r\n")
|
||||||
if self.debug: print ">>> "+message
|
|
||||||
|
# Match messages containing private information
|
||||||
|
# then censors it to output to the terminal and log
|
||||||
|
pattern = r"^PRIVMSG NickServ :IDENTIFY *"
|
||||||
|
if re.search(pattern, message):
|
||||||
|
message = "PRIVMSG NickServ :IDENTIFY ****"
|
||||||
|
|
||||||
|
output = ">>> "+message
|
||||||
|
|
||||||
|
if self.debug:
|
||||||
|
print output
|
||||||
|
if self.log:
|
||||||
|
self.log.write(output+"\n")
|
||||||
|
|
||||||
def User(self, nick, mode, unused, owner):
|
def User(self, nick, mode, unused, owner):
|
||||||
self.msg("USER "+nick+' '+mode+' '+unused+" :"+owner)
|
self.msg("USER "+nick+' '+mode+' '+unused+" :"+owner)
|
||||||
|
64
core/main.py
64
core/main.py
@ -58,7 +58,14 @@ class ImportRollback:
|
|||||||
__builtin__.__import__ = self.newImport
|
__builtin__.__import__ = self.newImport
|
||||||
|
|
||||||
|
|
||||||
def PluginsImport():
|
# Print and log to logfile
|
||||||
|
def prntlog(message, logfile):
|
||||||
|
print message
|
||||||
|
if logfile:
|
||||||
|
logfile.write(message+"\n")
|
||||||
|
|
||||||
|
|
||||||
|
def PluginsImport(log=False):
|
||||||
# Get root of Flea
|
# Get root of Flea
|
||||||
current = os.getcwd()
|
current = os.getcwd()
|
||||||
# Path to /plugins/ under /Flea/
|
# Path to /plugins/ under /Flea/
|
||||||
@ -76,7 +83,7 @@ def PluginsImport():
|
|||||||
|
|
||||||
# Only import directory plugins (no single files)
|
# Only import directory plugins (no single files)
|
||||||
if os.path.isdir(plugins+item):
|
if os.path.isdir(plugins+item):
|
||||||
print "[Plugins] Initializing "+item
|
prntlog("[Plugins] Initializing "+item, log)
|
||||||
plugin = __import__(item+".main")
|
plugin = __import__(item+".main")
|
||||||
plugin_list.append(plugin)
|
plugin_list.append(plugin)
|
||||||
|
|
||||||
@ -87,7 +94,6 @@ def PluginsImport():
|
|||||||
return plugin_list
|
return plugin_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
# Create irclib irc object
|
# Create irclib irc object
|
||||||
@ -96,14 +102,22 @@ def main():
|
|||||||
# Parse main settings.conf file
|
# Parse main settings.conf file
|
||||||
irc.config = cfgParser("settings.conf")
|
irc.config = cfgParser("settings.conf")
|
||||||
|
|
||||||
|
# If logging is enabled, open log file.
|
||||||
|
if irc.config["logging"]:
|
||||||
|
log = open("log.txt", 'a')
|
||||||
|
irc.log = log
|
||||||
|
else:
|
||||||
|
log = False
|
||||||
|
|
||||||
# Keep track of modules for a rollback
|
# Keep track of modules for a rollback
|
||||||
importctrl = ImportRollback()
|
importctrl = ImportRollback()
|
||||||
|
|
||||||
# Import /plugins/
|
# Import /plugins/
|
||||||
if irc.config["plugins"]:
|
if irc.config["plugins"]:
|
||||||
plugins = PluginsImport()
|
plugins = PluginsImport(log)
|
||||||
|
|
||||||
if not plugins:
|
if not plugins:
|
||||||
print "[Plugins] Failed to load."
|
prntlog("[Plugins] Failed to load.", log)
|
||||||
|
|
||||||
# Set debug to true/false inside irc() object
|
# Set debug to true/false inside irc() object
|
||||||
irc.debug = irc.config["debug"]
|
irc.debug = irc.config["debug"]
|
||||||
@ -115,15 +129,18 @@ def main():
|
|||||||
irc.sock = ssl.wrap_socket(irc.sock)
|
irc.sock = ssl.wrap_socket(irc.sock)
|
||||||
|
|
||||||
# Connect to IRC server
|
# Connect to IRC server
|
||||||
irc.sock.connect((irc.config["host"], irc.config["port"]))
|
host = irc.config["host"]
|
||||||
print "Connecting to "+irc.config["host"]+':'+str(irc.config["port"])
|
port = irc.config["port"]
|
||||||
|
|
||||||
|
irc.sock.connect((host, port))
|
||||||
|
prntlog("Connecting to "+host+':'+str(port), log)
|
||||||
|
|
||||||
# Display SSL information to the user
|
# Display SSL information to the user
|
||||||
ssl_info = irc.sock.cipher()
|
ssl_info = irc.sock.cipher()
|
||||||
if ssl_info != None:
|
if ssl_info != None:
|
||||||
print "[SSL] Cipher: "+ssl_info[0]
|
prntlog("[SSL] Cipher: "+ssl_info[0], log)
|
||||||
print "[SSL] Version: "+ssl_info[1]
|
prntlog("[SSL] Version: "+ssl_info[1], log)
|
||||||
print "[SSL] Bits: "+str(ssl_info[2])
|
prntlog("[SSL] Bits: "+str(ssl_info[2]), log)
|
||||||
|
|
||||||
# Send User/Nick message to establish user on the server
|
# Send User/Nick message to establish user on the server
|
||||||
irc.User(irc.config["ident"], irc.config["mode"],
|
irc.User(irc.config["ident"], irc.config["mode"],
|
||||||
@ -145,8 +162,9 @@ def main():
|
|||||||
|
|
||||||
# If no incoming data exists then connection has closed
|
# If no incoming data exists then connection has closed
|
||||||
if len(tmpdata) == 0:
|
if len(tmpdata) == 0:
|
||||||
input("Connection closed.")
|
print "Connection closed."
|
||||||
sys.exit()
|
raw_input()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
# Split data to easily deal with it
|
# Split data to easily deal with it
|
||||||
data = tmpdata.split("\r\n")
|
data = tmpdata.split("\r\n")
|
||||||
@ -157,14 +175,17 @@ def main():
|
|||||||
# Ignore empty lines
|
# Ignore empty lines
|
||||||
if len(line) > 0:
|
if len(line) > 0:
|
||||||
|
|
||||||
# Print line, parse it and respond
|
# Print/log line, parse it and respond
|
||||||
print line
|
prntlog(line, log)
|
||||||
irc.pack = irc.Parser(line)
|
irc.pack = irc.Parser(line)
|
||||||
|
|
||||||
# Run all plugins main() function
|
# Run all plugins main() function
|
||||||
|
wait = ''
|
||||||
if irc.config["plugins"]:
|
if irc.config["plugins"]:
|
||||||
for plugin in plugins:
|
for plugin in plugins:
|
||||||
plugin.main.main(irc)
|
wait = plugin.main.main(irc)
|
||||||
|
if wait == "QUIT":
|
||||||
|
break
|
||||||
|
|
||||||
# Ping Pong, keep the connection alive.
|
# Ping Pong, keep the connection alive.
|
||||||
if irc.pack["cmd"] == "PING":
|
if irc.pack["cmd"] == "PING":
|
||||||
@ -183,5 +204,18 @@ def main():
|
|||||||
irc.Identify(irc.config["password"])
|
irc.Identify(irc.config["password"])
|
||||||
irc.Join(irc.config["channel"])
|
irc.Join(irc.config["channel"])
|
||||||
|
|
||||||
|
if log: log.flush()
|
||||||
|
|
||||||
|
# Wait for QUIT to be returned from any plugin's main() function
|
||||||
|
if wait == "QUIT":
|
||||||
|
# Quit, close connection and logfile.
|
||||||
|
irc.Quit("Fleabot https://github.com/Kris619/Flea")
|
||||||
|
irc.sock.close()
|
||||||
|
if log: log.close()
|
||||||
|
|
||||||
|
print "Press the [ENTER] key to close."
|
||||||
|
raw_input()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# An IRC bot named Flea
|
||||||
|
# Copyright (C) 2016 Kris Lamoureux
|
||||||
|
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
# Init
|
# Init
|
||||||
@ -11,7 +27,7 @@ def chkcontrol(irc):
|
|||||||
global access
|
global access
|
||||||
global queue
|
global queue
|
||||||
|
|
||||||
nick = irc.pack["nick"]
|
nick = irc.pack["nick"].lower()
|
||||||
|
|
||||||
for person in access:
|
for person in access:
|
||||||
if nick == person:
|
if nick == person:
|
||||||
@ -33,13 +49,14 @@ def main(irc):
|
|||||||
|
|
||||||
# Set control channel
|
# Set control channel
|
||||||
controlchan = irc.config["channel"]
|
controlchan = irc.config["channel"]
|
||||||
|
controlusr = irc.config["control"]
|
||||||
|
|
||||||
# NOTICEs are used to "control" Flea
|
# NOTICEs are used to "control" Flea
|
||||||
if irc.pack["cmd"] == "NOTICE":
|
if irc.pack["cmd"] == "NOTICE":
|
||||||
|
|
||||||
# Nick must match the nick in settings
|
# Nick must match the nick in settings
|
||||||
# e.g. control = Kris
|
# e.g. control = Kris
|
||||||
if irc.pack["nick"] == irc.config["control"]:
|
if irc.pack["nick"].lower() == controlusr.lower():
|
||||||
|
|
||||||
# Split message by spaces, for functions with
|
# Split message by spaces, for functions with
|
||||||
# required parameters. e.g. "<cmd> <param1> <param2>"
|
# required parameters. e.g. "<cmd> <param1> <param2>"
|
||||||
@ -67,13 +84,10 @@ def main(irc):
|
|||||||
if chkcontrol(irc):
|
if chkcontrol(irc):
|
||||||
irc.Notice("You already have access to Control.",
|
irc.Notice("You already have access to Control.",
|
||||||
irc.pack["nick"])
|
irc.pack["nick"])
|
||||||
else:
|
|
||||||
noaccess(irc)
|
|
||||||
|
|
||||||
if irc.pack["text"] == "quit":
|
if irc.pack["text"] == "quit":
|
||||||
if chkcontrol(irc):
|
if chkcontrol(irc):
|
||||||
irc.Quit("Fleabot https://github.com/Kris619/Flea")
|
return "QUIT"
|
||||||
quit()
|
|
||||||
else:
|
else:
|
||||||
noaccess(irc)
|
noaccess(irc)
|
||||||
|
|
||||||
@ -81,32 +95,34 @@ def main(irc):
|
|||||||
elif irc.pack["cmd"] == "307":
|
elif irc.pack["cmd"] == "307":
|
||||||
if irc.pack["text"] == "is identified for this nick":
|
if irc.pack["text"] == "is identified for this nick":
|
||||||
|
|
||||||
|
usernick = irc.pack["params"][1]
|
||||||
|
|
||||||
# Check if Nick is in the queue for access list
|
# Check if Nick is in the queue for access list
|
||||||
if queue.count(irc.pack["params"][1]) == 1:
|
if queue.count(usernick) == 1:
|
||||||
|
|
||||||
# Remove Nick from queue
|
# Remove Nick from queue
|
||||||
queue.remove(irc.pack["params"][1])
|
queue.remove(usernick)
|
||||||
|
|
||||||
# Check if user is set to control in settings
|
# Check if user is set to control in settings
|
||||||
# e.g. control = Kris
|
# e.g. control = Kris
|
||||||
if irc.pack["params"][1] == irc.config["control"]:
|
if usernick.lower() == controlusr.lower():
|
||||||
|
|
||||||
|
|
||||||
# Is control user inside the control channel?
|
# Is control user inside the control channel?
|
||||||
if chans[controlchan].count(irc.pack["params"][1]) == 1:
|
if chans[controlchan.lower()].count(usernick) == 1:
|
||||||
|
|
||||||
# Grant access
|
# Grant access
|
||||||
access.append(irc.pack["params"][1])
|
access.append(usernick)
|
||||||
|
|
||||||
print irc.pack["params"][1]+" added to Access"
|
print usernick+" added to Access"
|
||||||
|
|
||||||
irc.Notice(
|
irc.Notice(
|
||||||
"You have been given access to Control.",
|
"You have been given access to Control.",
|
||||||
irc.pack["params"][1])
|
usernick)
|
||||||
else:
|
else:
|
||||||
irc.Notice(
|
irc.Notice(
|
||||||
"You are not in the Control channel: "+controlchan,
|
"You are not in the Control channel: "+controlchan,
|
||||||
irc.pack["params"][1])
|
usernick)
|
||||||
|
|
||||||
# Keep track of users in every channel
|
# Keep track of users in every channel
|
||||||
# "353" lists users to a channel
|
# "353" lists users to a channel
|
||||||
@ -137,7 +153,7 @@ def main(irc):
|
|||||||
if irc.pack["nick"] == irc.config["nick"]:
|
if irc.pack["nick"] == irc.config["nick"]:
|
||||||
# Create channel user list if it doesn't exist
|
# Create channel user list if it doesn't exist
|
||||||
if chans.keys().count(irc.pack["text"]) == 0:
|
if chans.keys().count(irc.pack["text"]) == 0:
|
||||||
chans[irc.pack["text"]] = []
|
chans[irc.pack["text"].lower()] = [irc.pack["text"]]
|
||||||
|
|
||||||
# Another user joined
|
# Another user joined
|
||||||
else:
|
else:
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
debug = true
|
debug = true
|
||||||
|
logging = false
|
||||||
plugins = true
|
plugins = true
|
||||||
|
|
||||||
host = irc.example.net
|
host = irc.example.net
|
||||||
|
Loading…
Reference in New Issue
Block a user