def gotonline(self, presence): try: from_jid = sleekxmpp.JID(presence['from']).bare if misc.check_time(self, misc.data['stop'], from_jid) and misc.check_time(self, misc.data['quiet'], from_jid): self.send_presence(pto=presence['from'], pshow='', pnick=config.group_nick, pstatus=config.group_topic) else: self.send_presence(pto=presence['from'], pshow='dnd', pnick=config.group_nick, pstatus=config.group_topic) client_resource = sleekxmpp.JID(presence['from']).resource if client_resource.startswith('Talk.v') and client_resource[6:9] > '104': self.send_message(mto=presence['from'], mbody=_('Warning: You are probably using GTalk v%s version, which sends your data unsecurely. Please consider downgrading it to GTalk v104 or try third-party clients such as Pidgin.') % client_resource[6:9], mtype='chat') except Exception: pass
def _validate(self, context): """ Component validated """ # Ensure we do not provide the service at first self._controller = False # Compute the MUC domain self._muc_domain = sleekxmpp.JID(self._room).domain # Register to session events self._bot.add_event_handler("session_start", self.__on_start) self._bot.add_event_handler("session_end", self.__on_end) self._bot.add_event_handler("muc::{0}::got_online".format(self._room), self.__room_in) self._bot.add_event_handler("muc::{0}::got_offline".format(self._room), self.__room_out) # Register "XEP-0203: Delayed Delivery" plug-in self._bot.register_plugin("xep_0203") # Register to messages (loop back filtered by the bot) self._bot.set_message_callback(self.__on_message) # Connect to the server self._bot.connect(self._host, self._port, use_tls=False)
def exec(bot = False, msg = None, ReplyTo = None, auth = None, **kwargs): if not bot or not msg: return False #проверим пришли ли параметры if "param" in kwargs: param_list = kwargs['param'] else: param_list = () if param_list: #есть параметры. Первым должно быть имя чата room = param_list[0] message = ' '.join(param_list[1:]) toJID = sleekxmpp.JID(room + '@conference.jb.legionofdeath.ru') if message: reply = bot.make_message(toJID, message, mtype='groupchat') reply.send() #отчитаемся if not ReplyTo: reply = bot.make_message(msg['from']) else: reply = bot.make_message(ReplyTo) if message: reply['body'] = 'Сообщение отправлено в комнату ' + room else: reply['body'] = 'Пустые сообщения не отправляю.' reply['type'] = msg['type'] reply.send() return True
def report(self, msg, body): if msg['mucroom']: ReplyTo = sleekxmpp.JID(msg['mucroom']) else: ReplyTo = msg['from'] reply = self.make_message(ReplyTo, body, mtype=msg['type']) reply.send()
def _create_new_bot(self): """ Really (re)creates a new XMPP bot object """ # Clear & Start the thread pool self.__pool.clear() self.__pool.start() # Prepare the peer contact handler self.__contact = peer_contact.PeerContact(self._directory, None, __name__ + ".contact") if self._username: # Generate the bot full JID: resource is set to be peer's UUID bot_jid = sleekxmpp.JID(self._username) bot_jid.resource = self._directory.local_uid else: # Anonymous login bot_jid = None # Create the bot self._bot = HeraldBot(bot_jid, self._password, self._directory.local_uid) # Avoids bot's auto reconnection. # when disconnected event is captured, # we destroy the old bot and re-create a new one. self._bot.auto_reconnect = False # This avoids to wait too long between initial reattempts, i.e. if # the first server addresses (DNS records) aren't responding self._bot.reconnect_max_delay = 5 # Register to session events self._bot.add_event_handler("session_start", self._on_session_start) self._bot.add_event_handler("failed_auth", self._on_failed_auth) self._bot.add_event_handler("session_end", self._on_session_end) self._bot.add_event_handler("disconnected", self._on_disconnected) # Register the Multi-User Chat plug-in self._bot.register_plugin('xep_0045') # Register "XEP-0203: Delayed Delivery" plug-in self._bot.register_plugin("xep_0203") # Register to messages (loop back filtered by the bot) self._bot.set_message_callback(self.__on_message) # Connect to the server # set reattempt to True to try to reconnect to the server in case of # network problems or address errors. if not self._bot.connect(self._host, self._port, reattempt=True): _logger.error("Can't connect to the XMPP server at %s port %s", self._host, self._port)
def getnick(xmpp, nick_or_jid): if nick_or_jid in nick_table: return nick_or_jid elif isjidvalid(nick_or_jid) and nick_or_jid in xmpp.client_roster and xmpp.client_roster[nick_or_jid]['to']: nick = xmpp.client_roster[nick_or_jid]['name'] if nick: return nick else: return sleekxmpp.JID(nick_or_jid).user else: return None
def unsubscribe(self, presence): from_jid = sleekxmpp.JID(presence['from']).bare if from_jid in misc.data['stop'][from_jid]: del misc.data['stop'][from_jid] misc.save_data() from_nick = misc.getnick(self, from_jid) try: self.del_roster_item(from_jid) except Exception: pass sys.stderr.write('%s unsubscribed me.\n' % presence['from']) self.send_except(from_jid, _('%s has quited this group.') % from_nick)
def subscribed(self, presence): jid = sleekxmpp.JID(presence['from']).bare sys.stderr.write('I subcribed %s.\n' % presence['from']) while True: to_nick = int(random.random() * 90000 + 10000) if not misc.getnick(self, to_nick): break to_nick += 1 to_nick = 'Guest' + str(to_nick) self.update_roster(jid, name=to_nick) misc.add_nicktable(self, jid) self.send_message(mto=presence['from'], mbody=misc.replace_prefix(config.welcome_message, config.command_prefix[0]), mtype='chat') self.send_message(mto=presence['from'], mbody=misc.replace_prefix(_('You have been given a random nickname %s, please use /-nick to change your nickname.'), config.command_prefix[0]) % to_nick, mtype='chat') self.send_message(mto=presence['from'], mbody=misc.replace_prefix(_('For more help, type /-help'), config.command_prefix[0]), mtype='chat') self.send_except(jid, _('%s has joined this group.') % to_nick) self.send_presence(pto=jid, pshow='', pnick=config.group_nick, pstatus=config.group_topic)
def exec(bot=False, msg=None, ReplyTo=None, auth=None, **kwargs): if not bot or not msg: return False #проверим пришли ли параметры if "param" in kwargs: param_list = kwargs['param'] else: param_list = () if param_list: #есть параметры. нас интересует только первый name = param_list[0] + '@jb.legionofdeath.ru' try: result = bot.plugin['xep_0012'].get_last_activity(name) seconds = int(result['last_activity']['seconds']) if seconds == 0: textline = 'Пользователь ' + name + ' сейчас онлайн.' JID = sleekxmpp.JID(name) notify = bot.make_message(JID) notify['body'] = 'Тебя разыскивает ' + bot.JID_to_realJID( msg).bare notify['type'] = 'Normal' notify.send() else: textline = 'Пользователь ' + name + ' был онлайн ' + bot.one_day_delta_to_str( seconds) + '.' except IqError as err: textline = 'Ошибка при получении данных о ' + name except: pass else: textline = 'Не задано имя' if not ReplyTo: reply = bot.make_message(msg['from']) else: reply = bot.make_message(ReplyTo) reply['body'] = textline reply['type'] = msg['type'] reply.send() return True
def room_jid(self, room_name): """ Prepares a JID object for the given room in the current MUC domain :param room_name: The short name of a room :return: A JID object """ if self.__muc_service == "groupchat.google.com": # Special case: Google Talk requires a specific room name format # Make a MD5 hash of the full room name app_id = self._directory.get_local_peer().app_id full_name = "cohorte-{0}-{1}".format(app_id, room_name) md5 = hashlib.md5(to_bytes(full_name)).hexdigest() # Format the room name to be Google Talk-compatible room_name = "private-chat-{0}".format(str(uuid.UUID(md5))) return sleekxmpp.JID(local=room_name, domain=self.__muc_service)
def create_room(self, room, service, nick, config=None, callback=None, errback=None): """ Prepares the creation of a room. The callback is a method with two arguments: - room: Bare JID of the room - nick: Nick used to create the room The errback is a method with 4 arguments: - room: Bare JID of the room - nick: Nick used to create the room - condition: error category (XMPP specification or "not-owner") - text: description of the error :param room: Name of the room :param service: Name of the XMPP MUC service :param config: Configuration of the room :param callback: Method called back on success :param errback: Method called on error """ self.__logger.info("Creating room: %s", room) with self.__lock: # Format the room JID room_jid = sleekxmpp.JID(local=room, domain=service).bare if not self.__rooms: # First room to create: register to events self.__xmpp.add_event_handler("presence", self.__on_presence) # Store information self.__rooms[room_jid] = RoomData(room_jid, nick, config, callback, errback) # Send the presence, i.e. request creation of the room self.__muc.joinMUC(room_jid, nick)
def fire_group(self, group, peers, message): """ Fires a message to a group of peers :param group: Name of a group :param peers: Peers to communicate with :param message: Message to send :return: The list of reached peers """ # Special case for the main room if group == 'all': group_jid = self._room else: # Get the group JID group_jid = sleekxmpp.JID(local=group, domain=self._muc_domain) # Send the XMPP message self.__send_message("groupchat", group_jid, message) return peers
def check_nick(self, presence): if not self.censor: return if presence['muc']['nick'] != self.mucnick: jid = presence['muc']['jid'].bare module = getattr(self.plugins['storage'], 'muc_censor') correct_name = module.exec(bot=self, msg=None, ReplyTo=None, auth=None, param=(jid, )) if correct_name and correct_name != presence['muc']['nick']: #ругаемся что ник надо поправить ReplyTo = sleekxmpp.JID(presence['muc']['room']) reply = self.make_message(ReplyTo) reply['body'] = '' + presence['muc'][ 'nick'] + ' поменяй ник на ' + correct_name + '\nЕсли считаешь что ник корректный, обнови API ключ на http://dashboard.legionofdeath.ru' reply['type'] = 'groupchat' reply.send() #пробуем насильно поменять ник stanza = self.makePresence() x = ET.Element('{http://jabber.org/protocol/muc#user}x') itemXML = ET.Element( 'item', { 'affiliation': 'owner', 'jid': presence['muc']['jid'].full, 'role': 'moderator' }) x.append(itemXML) itemXML = ET.Element('status ', { 'code': '110', }) x.append(itemXML) itemXML = ET.Element('status ', { 'code': '210', }) x.append(itemXML) stanza.append(x)
def form_message(self, msg): if msg['form']['type'] == 'submit': #не нашел способа узнать что за форма, проверяю по наличию поля в форме if "Broadcast" in msg['form']['values']: items = msg['form']['values']['Group'].split(';') for item in items: toJID = sleekxmpp.JID(jid=item + '@broadcast.jb.legionofdeath.ru') #toJID = sleekxmpp.JID('*****@*****.**') reply = self.make_message( toJID, 'Broadcast from ' + self.JID_to_realJID(msg).bare + ' to ' + item + '\n' + msg['form']['values']['Broadcast'], mtype='normal') #reply = self.make_message(toJID, 'fgh', mtype='normal') reply.send() #отчитаемся о посылке бродкаста self.report( msg, 'Сделан бродкаст группе ' + msg['form']['values']['Group']) elif "GroupContent" in msg['form']['values']: group = msg['form']['values']['Group'] group_content = msg['form']['values']['GroupContent'] group_db = self.bases['group_db'] #если контент пустой, группу надо удалить if group_content: group_db.set_value_by_ID(group, group_content) self.report( msg, "Group " + group + " now set to <" + group_content + ">") else: group_db._db_base.__delitem__(group) self.report(msg, "Group " + group + " now deleted")
def cron(self, **kwargs): if "plugin" in kwargs: plugin = kwargs['plugin'] else: return module = getattr(self.plugins['storage'], plugin) body = module.exec(bot=self, msg=None, ReplyTo=None, auth=None, param=None) #получим список комнат куда спамить try: rooms = module.rooms() allrooms = False except: allrooms = True if not body: return body = '\n' + '*' * 40 + '\n' + body + '\n' + '*' * 40 #бежим по комнатам где сидим for room in self.plugin['xep_0045'].rooms: #print(allrooms) #print(rooms) if room == self.botroom + '@conference.jb.legionofdeath.ru': continue if not allrooms: if not room in rooms: continue ReplyTo = sleekxmpp.JID(room) reply = self.make_message(ReplyTo) reply['body'] = body reply['type'] = 'groupchat' reply.send()
else: logging.basicConfig(level=logging.INFO) logging.getLogger("sleekxmpp").setLevel(logging.WARNING) if not args.server and not args.jid: _logger.error("No JID nor server given. Abandon.") sys.exit(1) # Get the password if necessary _password = args.password if args.jid and not args.password: try: import getpass except ImportError: _logger.error("getpass() unavailable: give a password in " "command line") else: try: _password = getpass.getpass() except getpass.GetPassWarning: pass # Get the server from the JID, if necessary _server = args.server if not _server: import sleekxmpp _server = sleekxmpp.JID(args.jid).domain # Run the entry point main(_server, args.port, args.jid, _password, args.use_tls, args.use_ssl)
def main(argv=None): """ Entry point :param argv: Script arguments (None for sys.argv) :return: An exit code or None """ # Prepare arguments parser = argparse.ArgumentParser(prog="pelix.shell.xmpp", parents=[make_common_parser()], description="Pelix XMPP Shell") group = parser.add_argument_group("XMPP options") group.add_argument("-j", "--jid", dest="jid", help="Jabber ID") group.add_argument("--password", dest="password", help="JID password") group.add_argument("-s", "--server", dest="server", help="XMPP server host") group.add_argument("-p", "--port", dest="port", type=int, default=5222, help="XMPP server port") group.add_argument("--tls", dest="use_tls", action="store_true", help="Use a STARTTLS connection") group.add_argument("--ssl", dest="use_ssl", action="store_true", help="Use an SSL connection") # Parse them args = parser.parse_args(argv) # Handle common arguments init = handle_common_arguments(args) # Quiet down the SleekXMPP logger if not args.verbose: logging.getLogger("sleekxmpp").setLevel(logging.WARNING) if not args.server and not args.jid: _logger.error("No JID nor server given. Abandon.") sys.exit(1) # Get the password if necessary password = args.password if args.jid and args.password is None: try: import getpass except ImportError: _logger.error( "getpass() unavailable: give a password in command line") else: try: password = getpass.getpass() except getpass.GetPassWarning: pass # Get the server from the JID, if necessary server = args.server if not server: server = sleekxmpp.JID(args.jid).domain # Set the initial bundles bundles = [ 'pelix.ipopo.core', 'pelix.shell.core', 'pelix.shell.ipopo', 'pelix.shell.console', 'pelix.shell.xmpp' ] bundles.extend(init.bundles) # Use the utility method to create, run and delete the framework framework = pelix.framework.create_framework(remove_duplicates(bundles), init.properties) framework.start() # Instantiate a Remote Shell with use_ipopo(framework.get_bundle_context()) as ipopo: ipopo.instantiate( pelix.shell.FACTORY_XMPP_SHELL, "xmpp-shell", { "shell.xmpp.server": server, "shell.xmpp.port": args.port, "shell.xmpp.jid": args.jid, "shell.xmpp.password": password, "shell.xmpp.tls": args.use_tls, "shell.xmpp.ssl": args.use_ssl }) # Instantiate configured components init.instantiate_components(framework.get_bundle_context()) try: framework.wait_for_stop() except KeyboardInterrupt: framework.stop()
def exec(bot=False, msg=None, ReplyTo=None, auth=None, **kwargs): if not bot or not msg: return False #проверим пришли ли параметры if "param" in kwargs: param_list = kwargs['param'] else: param_list = () if param_list: #есть параметры. Первым должно быть имя группы, все остальное текст сообщения group = param_list[0] #получим список групп group_db = bot.bases['group_db'] item = group_db.get_value_by_ID(group).decode() bc_from = bot.JID_to_realJID(msg).bare bcmessage = ' '.join(param_list[1:]) if item: items = item.split(';') for item in items: toJID = sleekxmpp.JID(jid=item + '@broadcast.jb.legionofdeath.ru') reply = bot.make_message(toJID, 'Broadcast from ' + bc_from + ' to ' + group + '\n' + bcmessage, mtype='normal') reply.send() #отчитаемся if not ReplyTo: reply = bot.make_message(msg['from']) else: reply = bot.make_message(ReplyTo) reply['body'] = 'Сделан бродкаст группе ' + group reply['type'] = msg['type'] reply.send() else: if not ReplyTo: reply = bot.make_message(msg['from']) else: reply = bot.make_message(ReplyTo) reply['body'] = "Group <" + group + "> not found" reply['type'] = msg['type'] reply.send() else: #параметров не передали, откроем форму reply = bot.make_message(msg['from'], msubject='Broadcast') form = reply['form'] fields = collections.OrderedDict() #получим список групп group_db = bot.bases['group_db'] items = group_db.get_list() options = [] for item in items: options.append({ 'label': item.decode(), 'value': group_db.get_value_by_ID(item).decode() }) #print(item + group_db.get_value_by_ID(item)) fields['Group'] = { 'type': 'list-single', 'label': 'Group', 'options': options } #'options': [{'label': 'test', # 'value': 'test'}, # {'label': 'Fleet Commanders', # 'value': 'Fleet Commanders'}]} fields['Broadcast'] = { 'type': 'text-multi', 'label': 'Broadcast', 'value': 'New broadcast text\nhere' } form['fields'] = fields form['title'] = 'New broadcast' reply.send() return True
def JID_to_realJID(self, msg): if msg['from'].full in self.dict_of_real_JID: return sleekxmpp.JID(self.dict_of_real_JID[msg['from'].full]) else: return msg['from']
def subscribe(self, presence): sys.stderr.write('%s subscribed me.\n' % presence['from']) self.send_presence(pto=sleekxmpp.JID(presence['from']).bare, pshow='away', pnick=config.group_nick, pstatus=_('Not accepted subscription yet'))
def message(self, msg): """ Process incoming message stanzas. Be aware that this also includes MUC messages and error messages. It is usually a good idea to check the messages's type before processing or sending replies. Arguments: msg -- The received message stanza. See the documentation for stanza objects and the Message stanza to see how it may be used. """ #свои сообщения в групчатах сразу игнорим if msg['mucnick'] == self.nick or msg['mucnick'] == self.mucnick: return if msg['type'] in ('chat', 'normal', 'groupchat'): if 'die!' == msg['body']: self._disconnect() elif 'зло' == msg['body']: self.censor = True #получим первое слово сообщения temp_list = msg['body'].split(' ') command = temp_list[0] #проверим есть ли параметры param = None if len(temp_list) > 1: param = temp_list[1:] #будем сообщать о сообщениях боту в приват или о командах в конфах if msg['type'] in ('chat', 'normal') or ( msg['type'] == 'groupchat' and command in self.plugins['commands']): ReplyTo = sleekxmpp.JID(self.botroom + '@conference.jb.legionofdeath.ru') reply = self.make_message(ReplyTo) if msg['type'] in ('chat', 'normal'): textline = 'Личное сообщение от ' + msg[ 'from'].full + '\n' + msg['body'] else: textline = 'Команда в комнате ' + msg[ 'mucroom'] + ' от ' + msg[ 'from'].resource + '\n' + msg['body'] reply['body'] = textline reply['type'] = 'groupchat' reply.send() if command in self.plugins['commands']: module = getattr(self.plugins['storage'], command) #проверим команду на доступность всем try: secret = module.secret() except: secret = False #если сообщение из комнаты, заполним ReplyTo if msg['mucroom']: ReplyTo = sleekxmpp.JID(msg['mucroom']) else: ReplyTo = None admin = self.is_admin(self.JID_to_realJID(msg)) if secret and admin: module.exec(bot=self, msg=msg, ReplyTo=ReplyTo, auth=None, param=param) elif secret and (not admin): msg.reply("Access denied to command \n%(body)s" % msg).send() elif not secret: module.exec(bot=self, msg=msg, ReplyTo=ReplyTo, auth=None, param=param) else: pass #if not msg['type'] == 'groupchat': #pass #msg.reply("Thanks for sending\n%(body)s" % msg).send() return
def trigger(xmpp, msg): try: from_jid = msg['from'].bare cmd = msg['body'][1:].split() cmd[0] = cmd[0].lower() prefix = msg['body'][0] if not cmd: return if cmd[0] in ('names', 'name', 'list', 'la'): cmd[0] = 'ls' cmd.append('-a') elif cmd[0] in ('users', 'user', 'dir', 'lla', 'lal'): cmd[0] = 'ls' cmd.append('-la') elif cmd[0] in ('online', 'll'): cmd[0] = 'ls' cmd.append('-l') elif cmd[0] in ('man', 'info'): cmd[0] = 'help' elif cmd[0] in ('stat', 'whowas', 'dig', 'nslookup'): cmd[0] = 'whois' elif cmd[0] in ('iam', 'whoami'): cmd = ['whois', from_jid] elif cmd[0] in ('pm', 'dm', 'query', 'tell'): cmd[0] = 'msg' elif cmd[0] in ('test', 'traceroute', 'tracert', 'pong'): cmd[0] = 'ping' elif cmd[0] in ('poweroff', 'halt'): cmd[0] = 'shutdown' elif cmd[0] in ('restart', 'reboot'): cmd[0] = 'shutdown' cmd.append('-r') elif cmd[0] in ('rm', 'del', 'remove', 'delete'): cmd[0] = 'kick' elif cmd[0] in ('nickname', 'alias'): cmd[0] = 'nick' elif cmd[0] in ('mv', 'move', 'ren', 'rename'): cmd[0] = 'setnick' elif cmd[0] == 'run': cmd[0] = 'system' elif cmd[0] == 'quote': cmd[0] = 'say' elif cmd[0] == 'action': cmd[0] = 'me' elif cmd[0] in ('pause', 'sleep', 'delay'): cmd[0] = 'stop' elif cmd[0] == 'on': cmd = ['stop', 'off'] elif cmd[0] == 'off': cmd = ['stop', 'forever'] elif cmd[0] in ('log', 'history', 'hist'): cmd[0] = 'old' elif cmd[0] == 'mute': cmd[0] = 'quiet' elif cmd[0] in ('part', 'leave', 'exit', 'bye'): cmd[0] = 'quit' elif cmd[0] == 'about': cmd = ['help', ':about'] elif len(cmd[0]) > 4 and cmd[0].startswith('init'): cmd.insert(1, cmd[0][4:]) cmd[0] = 'init' if cmd[0] == 'say': if len(cmd) < 2: msg.reply( misc.replace_prefix(_('Error: /-say takes arguments.'), prefix)).send() elif misc.check_time(xmpp, misc.data['quiet'], from_jid): for l in msg['body'].split(None, 1)[1].splitlines(): xmpp.dispatch_message(from_jid, l) else: msg.reply(_('You have been quieted.')).send() return if cmd[0] == 'me': if len(cmd) < 2: msg.reply( misc.replace_prefix(_('Error: /-me takes arguments.'), prefix)).send() elif misc.check_time(xmpp, misc.data['quiet'], from_jid): from_nick = misc.getnick(xmpp, from_jid) for l in msg['body'].split(None, 1)[1].splitlines(): xmpp.send_except(None, '* %s %s' % (from_nick, l)) else: msg.reply(_('You have been quieted.')).send() return misc.cmd_log.append((time.time(), '%s: %s' % (from_jid, msg['body']))) if len(misc.cmd_log) > config.cmdlogsize: misc.cmd_log[len(misc.cmd_log) - config.cmdlogsize:] = [] if cmd[0] == 'eval': if from_jid in config.root: if len(cmd) > 1: msg.reply(str(eval(msg['body'].split(None, 1)[1]))).send() else: msg.reply( misc.replace_prefix( _('Error: /-eval takes arguments.'), prefix)).send() elif from_jid in config.admins: msg.reply(_('Error: Permission denied.')).send() else: msg.reply( misc.replace_prefix( _('Error: Unknown command. For help, type /-help'), prefix)).send() return if cmd[0] == 'exec': if from_jid in config.root: if len(cmd) > 1: exec(msg['body'].split(None, 1)[1]) msg.reply(_('Command executed.')).send() else: msg.reply( misc.replace_prefix( _('Error: /-exec takes arguments.'), prefix)).send() elif from_jid in config.admins: msg.reply(_('Error: Permission denied.')).send() else: msg.reply( misc.replace_prefix( _('Error: Unknown command. For help, type /-help'), prefix)).send() return if cmd[0] == 'system': if from_jid in config.root: if len(cmd) > 1: msg.reply('\n' + subprocess.Popen(msg['body'].split(None, 1)[1], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True).communicate()[0] .strip(b'\n').decode('utf-8', 'replace')).send() else: msg.reply( misc.replace_prefix( _('Error: /-system takes arguments.'), prefix)).send() elif from_jid in config.admins: msg.reply(_('Error: Permission denied.')).send() else: msg.reply( misc.replace_prefix( _('Error: Unknown command. For help, type /-help'), prefix)).send() return if cmd[0] == 'msg': if len(cmd) > 2: isAdmin = from_jid in config.admins success = 0 for to_jid in misc.find_users(xmpp, cmd[1], isAdmin): success = 1 if isAdmin or to_jid not in misc.data[ 'block'] or from_jid not in misc.data['block'][ to_jid]: xmpp.send_message( mto=to_jid, mbody='%s (%s): %s' % (misc.getnick(xmpp, from_jid), _('DM'), msg['body'].split(None, 2)[2]), mtype='chat') success = 2 else: xmpp.send_message( mto=from_jid, mbody=_('Error: %s has blocked your messages.') % misc.getnick(xmpp, to_jid), mtype='chat') if success == 2: msg.reply(_('Your message has been sent.')).send() elif success == 0: msg.reply( _('Error: User %s is not a member of this group.') % (cmd[1])).send() else: msg.reply( misc.replace_prefix( _('Error: /-msg takes exactly two arguments.'), prefix)).send() return if cmd[0] == 'help': if len(cmd) < 2: cmd.append('main') if from_jid in config.admins: cmd.append('admin') s = '' for i in cmd[1:]: i = i.lstrip(prefix) if i.startswith('-'): continue if i in help_msg: s += '\n\n' + misc.replace_prefix(help_msg[i], prefix).strip('\n') elif ':' + i in help_msg: s += '\n\n' + misc.replace_prefix(help_msg[':' + i], prefix).strip('\n') if len(s) > 1: s = s[1:] else: s = _('Error: No help message for %s.') % cmd[1] msg.reply(s).send() return if not cmd[0].startswith(':') and cmd[0] in help_msg: for i in cmd[1:]: if i == '--help': msg.reply('\n' + misc.replace_prefix( help_msg[cmd[0]], prefix).strip('\n')).send() return if cmd[0] == 'init': if len(cmd) == 2: if cmd[1] in ('S', 's'): cmd[1] = 'single' if from_jid in config.admins: xmpp.send_except( None, _('INIT: Switching to runlevel: %s') % cmd[1]) else: xmpp.send_message( mto=from_jid, mbody=_('INIT: Switching to runlevel: %s') % cmd[1], mtype='chat') if cmd[1] == '0': cmd[0] = 'shutdown' del cmd[1] elif cmd[1] == '6': cmd[0] = 'shutdown' cmd[1] = '-r' else: return elif len(cmd) == 1: msg.reply( misc.replace_prefix( _('Error: /-init must be run as PID 1.'), prefix)).send() return else: msg.reply( misc.replace_prefix( _('Error: /-init takes exactly one argument.'), perfix)).send() return if cmd[0] == 'quit': msg.reply(_('You have quited this group.')).send() if from_jid in misc.data['stop']: del misc.data['stop'][from_jid] misc.save_data() to_nick = misc.getnick(xmpp, from_jid) misc.del_nicktable(xmpp, from_jid) try: xmpp.del_roster_item(from_jid) except Exception: pass xmpp.send_except(from_jid, _('%s has quited this group.') % to_nick) return if cmd[0] == 'old': from_log = misc.msg_log arg = [] for i in cmd[1:]: if i.startswith('-'): if 'c' in i: if from_jid in config.admins: from_log = misc.cmd_log else: msg.reply(_('Error: Permission denied.')).send() return elif i: arg.append(i) try: if len(arg) >= 1: from_time = arg[0] if len(arg) >= 2: len_time = arg[1] else: len_time = from_time else: from_time = '25' len_time = from_time if from_time.isdigit(): from_time = int(from_time) else: from_time = misc.TimeUnit(from_time) if len_time.isdigit(): len_time = int(len_time) else: len_time = misc.TimeUnit(len_time) except ValueError: msg.reply(_('Error: Invalid time specification.')).send() return res = [] nowtime = time.time() try: if isinstance(from_time, misc.TimeUnit): res = from_log[bisect.bisect_left(from_log, ( nowtime - from_time, )):] if isinstance(len_time, misc.TimeUnit): res = res[:bisect.bisect(res, (nowtime - from_time + len_time, ))] else: res = res[:len_time] else: res = from_log[-from_time:] if isinstance(len_time, misc.TimeUnit): res = res[:bisect.bisect(res, (res[0][0] + len_time, ))] else: res = res[:len_time] res = res[:100] except IndexError: pass raise if res: sres = '' sres += '\n' + _('Start:\t%s') % misc.lctime(res[0][0]) for i in res: sres += '\n(%s) %s' % (time.strftime( "%T", time.localtime(i[0])), i[1]) sres += '\n' + _('End:\t%s') % misc.lctime(res[-1][0]) msg.reply(sres).send() else: msg.reply(_('No messages match your criteria.')).send() return if cmd[0] == 'stop': if len(cmd) > 1: to_time = ''.join(cmd[1:]) try: if to_time in ('ever', 'forever'): misc.data['stop'][from_jid] = None misc.save_data() elif to_time in ('off', 'never'): if from_jid in misc.data['stop']: del misc.data['stop'][from_jid] misc.save_data() try: if to_jid not in data[ 'stop'] and to_jid not in data['quiet']: xmpp.send_presence( pto=to_jid, pshow='', pnick=config.group_nick, pstatus=config.group_topic) except Exception: pass else: to_time = misc.TimeUnit(to_time) if to_time > 0: to_time = time.time() + misc.TimeUnit(to_time) misc.data['stop'][from_jid] = to_time elif from_jid in misc.data['stop']: del misc.data['stop'][from_jid] try: if to_jid not in data[ 'stop'] and to_jid not in data['quiet']: xmpp.send_presence( pto=to_jid, pshow='', pnick=config.group_nick, pstatus=config.group_topic) except Exception: pass misc.save_data() except ValueError: msg.reply(_('Error: Invalid time specification.')).send() return if not misc.check_time(xmpp, misc.data['stop'], from_jid): to_time = misc.data['stop'][from_jid] if to_time is None: msg.reply(_('You will never receive messages.')).send() else: msg.reply( _('You will not receive messages until %s.') % misc.lctime(to_time)).send() xmpp.send_presence(pto=from_jid, pshow='dnd', pnick=config.group_nick, pstatus=config.group_topic) else: msg.reply(_('You are currently receiving messages.')).send() return if cmd[0] == 'ping': if len(cmd) > 1: msg.reply('Pong: %s' % msg['body'].split(None, 1)[1]).send() else: msg.reply('Pong!').send() return if cmd[0] == 'shutdown': if from_jid in config.admins: misc.quiting = True quiet = False for i in cmd[1:]: if i.startswith('-'): if 'r' in i: misc.restarting = True if 'q' in i: quiet = True if misc.restarting: msg.reply(_('Restarting.')).send(now=True) if not quiet: xmpp.send_except( from_jid, _('Restarting by %s.') % misc.getnick(xmpp, from_jid)) raise SystemExit elif from_jid in config.root: msg.reply(_('Shutting down.')).send(now=True) if not quiet: xmpp.send_except( from_jid, _('Shutting down by %s.') % misc.getnick(xmpp, from_jid)) raise SystemExit else: misc.quiting = False msg.reply(_('Error: Permission denied.')).send() else: msg.reply(_('Error: Permission denied.')).send() return if cmd[0] == 'kick': if from_jid in config.admins: if len(cmd) <= 1: msg.reply( misc.replace_prefix( _('Error: /-kick takes at least one argument.'), prefix)).send() return if len(cmd) > 2: reason = msg['body'].split(None, 2)[2] else: reason = None success = False for to_jid in misc.find_users(xmpp, cmd[1], True): success = True sys.stderr.write('Kicking %s.' % to_jid) if reason: xmpp.send_message( mto=to_jid, mbody=_('You have been kicked by %s. (%s)') % (misc.getnick(xmpp, from_jid), reason), mtype='chat') else: xmpp.send_message( mto=to_jid, mbody=_('You have been kicked by %s.') % misc.getnick(xmpp, from_jid), mtype='chat') if to_jid in misc.data['stop']: del misc.data['stop'][to_jid] to_nick = misc.getnick(xmpp, to_jid) misc.del_nicktable(xmpp, to_jid) try: xmpp.del_roster_item(to_jid) except Exception: pass if reason: xmpp.send_except( to_jid, _('%s has been kicked by %s. (%s)') % (to_nick, misc.getnick(xmpp, from_jid), reason)) else: xmpp.send_except( to_jid, _('%s has been kicked by %s.') % (to_nick, misc.getnick(xmpp, from_jid))) sys.stderr.write('\n') if success: misc.save_data() else: msg.reply( _('Error: User %s is not a member of this group.') % (cmd[1])).send() else: msg.reply(_('Error: Permission denied.')).send() return if cmd[0] == 'quiet': if from_jid in config.admins: if len(cmd) <= 1: msg.reply( misc.replace_prefix( _('Error: /-quiet takes at least one argument.'), prefix)).send() return if len(cmd) > 2: to_time = ''.join(cmd[2:]) else: to_time = None try: if to_time in ('ever', 'forever', None): to_time = None elif to_time in ('off', 'never'): to_time = 'off' else: to_time = misc.TimeUnit(to_time) if to_time > 0: to_time = time.time() + misc.TimeUnit(to_time) else: to_time = 'off' except ValueError: msg.reply(_('Error: Invalid time specification.')).send() return success = False for to_jid in misc.find_users(xmpp, cmd[1], True): success = True sys.stderr.write('Quieting %s.' % to_jid) if to_jid in misc.data['quiet']: orig_time = misc.data['quiet'][to_jid] else: orig_time = 'off' if to_time != 'off': misc.data['quiet'][to_jid] = to_time else: if to_jid in misc.data['quiet']: del misc.data['quiet'][to_jid] try: if to_jid not in data[ 'stop'] and to_jid not in data['quiet']: xmpp.send_presence( pto=to_jid, pshow='', pnick=config.group_nick, pstatus=config.group_topic) except Exception: pass if orig_time == to_time: continue if to_time is None: xmpp.send_message( mto=to_jid, mbody=_('You have been quieted by %s.') % misc.getnick(xmpp, from_jid), mtype='chat') xmpp.send_presence(pto=to_jid, pshow='dnd', pnick=config.group_nick, pstatus=config.group_topic) elif to_time == 'off': xmpp.send_message( mto=to_jid, mbody=_('You have been stopped quieting by %s.') % misc.getnick(xmpp, from_jid), mtype='chat') xmpp.send_presence(pto=to_jid, pshow='', pnick=config.group_nick, pstatus=config.group_topic) else: xmpp.send_message( mto=to_jid, mbody=_('You have been quieted by %s until %s.') % (misc.getnick(xmpp, from_jid), misc.lctime(to_time)), mtype='chat') xmpp.send_presence(pto=to_jid, pshow='dnd', pnick=config.group_nick, pstatus=config.group_topic) to_nick = misc.getnick(xmpp, to_jid) if to_time is None: xmpp.send_except( to_jid, _('%s has been quieted by %s.') % (to_nick, misc.getnick(xmpp, from_jid))) elif to_time == 'off': xmpp.send_except( to_jid, _('%s has been stopped quieting by %s.') % (to_nick, misc.getnick(xmpp, from_jid))) else: xmpp.send_except( to_jid, _('%s has been quieted by %s until %s.') % (to_nick, misc.getnick( xmpp, from_jid), misc.lctime(to_time))) sys.stderr.write('\n') if success: misc.save_data() else: msg.reply( _('Error: User %s is not a member of this group.') % (cmd[1])).send() else: msg.reply(_('Error: Permission denied.')).send() return if cmd[0] == 'block': if len(cmd) > 1: isAdmin = from_jid in config.admins needsave = False for i in cmd[1:]: success = False for to_jid in misc.find_users(xmpp, i, isAdmin): success = True sys.stderr.write('Blocking %s by %s.' % (to_jid, from_jid)) if from_jid not in misc.data['block']: misc.data['block'][from_jid] = [] if to_jid not in misc.data['block'][from_jid]: needsave = True misc.data['block'][from_jid].append(to_jid) xmpp.send_message( mto=to_jid, mbody=_('You have been blocked by %s.') % misc.getnick(xmpp, from_jid), mtype='chat') xmpp.send_message( mto=from_jid, mbody= _('You will not receive messages from %s anymore.' ) % misc.getnick(xmpp, to_jid), mtype='chat') sys.stderr.write('\n') if not success: msg.reply( _('Error: User %s is not a member of this group.') % (cmd[1])).send() if needsave: misc.save_data() else: if from_jid in misc.data['block']: msg.reply( _('Your blocking list: %s') % ' '.join([ misc.getnick(xmpp, i) for i in misc.data['block'][from_jid] ])).send() else: msg.reply(_('Your blocking list is empty.')).send() return if cmd[0] == 'unblock': if len(cmd) > 1: if from_jid not in misc.data['block']: return isAdmin = from_jid in config.admins needsave = False for i in cmd[1:]: success = False for to_jid in misc.find_users(xmpp, i, isAdmin): success = True sys.stderr.write('Unblocking %s by %s.' % (to_jid, from_jid)) if to_jid in misc.data['block'][from_jid]: needsave = True misc.data['block'][from_jid].remove(to_jid) xmpp.send_message( mto=to_jid, mbody=_('You have been unblocked by %s.') % misc.getnick(xmpp, from_jid), mtype='chat') xmpp.send_message( mto=from_jid, mbody= _('You will receive messages from %s from now on.' ) % misc.getnick(xmpp, to_jid), mtype='chat') sys.stderr.write('\n') if not success: msg.reply( _('Error: User %s is not a member of this group.') % (cmd[1])).send() if needsave: if not misc.data['block'][from_jid]: del misc.data['block'][from_jid] misc.save_data() else: msg.reply( misc.replace_prefix( _('Error: /-unblock takes at least one argument.'), prefix)).send() return if cmd[0] == 'setnick': if len(cmd) == 3: if from_jid in config.admins: to_jid = misc.getjid(xmpp, cmd[1]) if to_jid: new_nick = cmd[2] if not misc.isnickvalid(new_nick): msg.reply(_('Nickname %s not vaild.') % new_nick).send() elif misc.getnick(xmpp, new_nick): msg.reply( _('Nickname %s is already in use.') % new_nick).send() else: old_nick = misc.getnick(xmpp, cmd[1]) misc.change_nicktable(xmpp, to_jid, new_nick) xmpp.update_roster(to_jid, name=new_nick) xmpp.send_except( None, _('%s is forced to changed its nick to %s.') % (old_nick, new_nick)) else: msg.reply( _('Error: User %s is not a member of this group.') % (cmd[1])).send() return elif misc.getjid(xmpp, cmd[1]) == from_jid: cmd[0] = 'nick' del cmd[1] else: msg.reply(_('Error: Permission denied.')).send() return else: msg.reply( misc.replace_prefix( _('Error: /-setnick takes exactly two arguments.'), prefix)).send() return if cmd[0] == 'nick': if len(cmd) == 1: msg.reply( _('Your current nickname is %s.') % misc.getnick(xmpp, from_jid)).send() elif len(cmd) >= 2: new_nick = cmd[1] for i in cmd[2:]: new_nick += i.capitalize() if not misc.isnickvalid(new_nick): msg.reply(_('Nickname %s not vaild.') % new_nick).send() elif misc.getnick(xmpp, new_nick): msg.reply(_('Nickname %s is already in use.') % new_nick).send() else: oldnick = misc.getnick(xmpp, from_jid) misc.change_nicktable(xmpp, from_jid, new_nick) xmpp.update_roster(from_jid, name=new_nick) xmpp.send_except( None, _('%s changed its nick to %s.') % (oldnick, new_nick)) else: msg.reply( misc.replace_prefix( _('Error: /-nick takes exactly one argument.'), prefix)).send() return if cmd[0] == 'ls': isAdmin = from_jid in config.admins option_a = False option_l = False glob = [] for i in cmd[1:]: if i.startswith('-'): if 'a' in i: option_a = True if 'l' in i: option_l = True else: glob.append(i) s = '' user_count = 0 for i in misc.find_users(xmpp, glob, isAdmin): to_resources = xmpp.client_roster[i].resources if option_a or to_resources: user_count += 1 s += '\n\t%s' % misc.getnick(xmpp, i) if option_l: if not misc.check_time(xmpp, misc.data['stop'], i): s += '\t' + _('<Stopped>') if to_resources: to_priority = -1 to_show = '' to_status = 'unavailable' for j in to_resources: if to_resources[j][ 'priority'] > to_priority or ( to_resources[j]['priority'] == to_priority and misc.compare_status( to_resources[j]['show'], to_status) >= 0): to_priority = to_resources[j]['priority'] to_show = to_resources[j]['show'] to_status = to_resources[j]['status'] s += '\t(%s)' % misc.get_status_name(to_show) if to_status: s += ' [%s]' % ' '.join(to_status.splitlines()) else: s += '\t(%s)' % _('unavailable') else: if isAdmin: s += '\t(%s)' % i s += '\n' + (_('Total %d') % user_count) msg.reply(s).send() return if cmd[0] == 'whois': isAdmin = from_jid in config.admins glob = [] for i in cmd[1:]: if not i.startswith('-'): glob.append(i) if not glob: msg.reply( misc.replace_prefix( _('Error: /-whois takes at least one argument.'), prefix)).send() return s = '' success = False for i in misc.find_users(xmpp, glob, isAdmin): success = True s += '\n\n' + _('Nickname:\t%s') % misc.getnick(xmpp, i) if isAdmin: s += '\n' + _('Jabber ID:\t%s') % i else: s += '\n' + _('Jabber ID:\t%s@%s') % ('*' * len( sleekxmpp.JID(i).user), sleekxmpp.JID(i).domain) if not misc.check_time(xmpp, misc.data['stop'], i): if misc.data['stop'][i] is None: s += '\n' + _('Not receiving messages.') else: s += '\n' + _('Not receiving messages until %s.' ) % misc.lctime(misc.data['stop'][i]) if i in misc.data['block']: s += '\n' + _('Blocking:\t%s') % ' '.join( [misc.getnick(xmpp, j) for j in misc.data['block'][i]]) if not misc.check_time(xmpp, misc.data['quiet'], i): if misc.data['quiet'][i] is None: s += '\n' + _('Quieted.') else: s += '\n' + _('Quieted until %s.') % misc.lctime( misc.data['quiet'][i]) blockby = [] for j in misc.data['block']: if i in misc.data['block'][j]: blockby.append(j) if blockby: s += '\n' + _('Blocked by:\t%s') % ' '.join( [misc.getnick(xmpp, j) for j in blockby]) to_resources = xmpp.client_roster[i].resources if to_resources: s += '\n' + _('Online resources:') for j in to_resources: s += '\n\t%s\t(%s)' % ( j, misc.get_status_name(to_resources[j]['show'])) if to_resources[j]['status']: s += '\t[%s]' % ' '.join( to_resources[j]['status'].splitlines()) if not success: s = '\n' + _( 'Error: User %s is not a member of this group.') % (cmd[1]) msg.reply(s[1:8192]).send() return msg.reply( misc.replace_prefix( _('Error: Unknown command. For help, type /-help'), prefix)).send() except SystemExit: raise except Exception as e: try: msg.reply( _('An error occured: %s: %s') % (e.__class__.__name__, e)).send() except Exception: pass