def get_user_status(self, user, status): if user not in self.users: return img = self.frame.get_status_image(status) if img == self.usersmodel.get_value(self.users[user], 0): return if status == 1: action = _("%s has gone away") else: action = _("%s has returned") if not self.frame.np.network_filter.is_user_ignored( user) and not self.frame.np.network_filter.is_user_ip_ignored( user): append_line(self.RoomLog, action % user, self.tag_log) if user in self.tag_users: color = get_user_status_color(status) update_tag_visuals(self.tag_users[user], color) self.usersmodel.set_value(self.users[user], 0, GObject.Value(GObject.TYPE_OBJECT, img)) self.usersmodel.set_value(self.users[user], 5, status)
def read_private_log(self): # Read log file config = self.frame.np.config.sections log = os.path.join(config["logging"]["privatelogsdir"], clean_file(self.user.replace(os.sep, "-")) + ".log") try: numlines = int(config["logging"]["readprivatelines"]) except Exception: numlines = 15 try: with open(log, 'r', encoding='utf-8') as lines: # Only show as many log lines as specified in config lines = deque(lines, numlines) for line in lines: append_line(self.ChatScroll, line, self.tag_hilite, timestamp_format="", username=self.user, usertag=self.tag_hilite) except IOError: pass GLib.idle_add(scroll_bottom, self.ChatScroll.get_parent())
def login(self): timestamp_format = config.sections["logging"]["private_timestamp"] append_line(self.ChatScroll, _("--- reconnected ---"), self.tag_hilite, timestamp_format=timestamp_format) self.update_tags()
def rejoined(self, users): # Update user list with an inexpensive sorting function self.usersmodel.set_default_sort_func(lambda *args: -1) self.usersmodel.set_sort_column_id(-1, Gtk.SortType.ASCENDING) for userdata in users: username = userdata.username if username in self.users: self.usersmodel.remove(self.users[username]) self.add_user_row(userdata) self.UserList.set_sensitive(True) # Reinitialize sorting after loop is complet self.usersmodel.set_sort_column_id(2, Gtk.SortType.ASCENDING) self.usersmodel.set_default_sort_func(lambda *args: -1) # Spit this line into chat log append_line(self.ChatScroll, _("--- reconnected ---"), self.tag_hilite) # Update user count self.count_users() # Build completion list self.set_completion_list(list(self.chatrooms.completion_list)) # Update all username tags in chat log for user in self.tag_users: self.get_user_tag(user)
def on_set_room_wall_message(self, widget): result = widget.get_text() widget.set_text("") config = self.frame.np.config.sections room_name = self.room.room self.frame.np.queue.put(slskmessages.RoomTickerSet(room_name, result)) self.RoomWallList.get_buffer().set_text("") login = config["server"]["login"] if result: append_line(self.RoomWallList, "[%s] %s" % (login, result), showstamp=False, scroll=False) tickers = self.room.tickers.get_tickers() append_line(self.RoomWallList, "%s" % ("\n".join([ "[%s] %s" % (user, msg) for (user, msg) in tickers if not user == login ])), showstamp=False, scroll=False)
def append_log_lines(self, log, numlines, encoding='utf-8'): with open(log, 'r', encoding=encoding) as lines: # Only show as many log lines as specified in config lines = deque(lines, numlines) for line in lines: append_line(self.ChatScroll, line, self.tag_hilite, timestamp_format="", username=self.user, usertag=self.tag_hilite)
def conn_close(self): timestamp_format = config.sections["logging"]["private_timestamp"] append_line(self.ChatScroll, _("--- disconnected ---"), self.tag_hilite, timestamp_format=timestamp_format) self.status = -1 self.offlinemessage = False self.update_tags()
def show(self): tickers = self.room.tickers.get_tickers() append_line( self.RoomWallList, "%s" % ("\n".join(["[%s] %s" % (user, msg) for (user, msg) in tickers])), showstamp=False, scroll=False) self.room_wall_dialog.show()
def send_message(self, text, bytestring=False): if not self.chats.connected: return user_text = self.frame.np.pluginhandler.outgoing_private_chat_event( self.user, text) if user_text is None: return (u, text) = user_text my_username = config.sections["server"]["login"] if text[:4] == "/me ": line = "* %s %s" % (my_username, text[4:]) usertag = tag = self.tag_me else: if text == self.chats.CTCP_VERSION: line = "CTCP VERSION" else: line = text tag = self.tag_local usertag = self.tag_my_username line = "[%s] %s" % (my_username, line) timestamp_format = config.sections["logging"]["private_timestamp"] append_line(self.ChatScroll, line, tag, timestamp_format=timestamp_format, username=my_username, usertag=usertag) if self.Log.get_active(): timestamp_format = config.sections["logging"]["log_timestamp"] log.write_log(config.sections["logging"]["privatelogsdir"], self.user, line, timestamp_format) if bytestring: payload = text else: payload = auto_replace(text) if self.PeerPrivateMessages.get_active(): # not in the soulseek protocol self.frame.np.send_message_to_peer( self.user, slskmessages.PMessageUser(None, my_username, payload)) else: self.frame.np.queue.append( slskmessages.MessageUser(self.user, payload)) self.frame.np.pluginhandler.outgoing_private_chat_notification( self.user, text)
def show_user_info(self, descr, has_pic, pic, totalupl, queuesize, slotsavail, uploadallowed): self.conn = None self._descr = descr self.image_pixbuf = None self.descr.get_buffer().set_text("") append_line(self.descr, descr, self.tag_local, showstamp=False, scroll=False) self.uploads.set_text(_("Total uploads allowed: %i") % totalupl) self.queuesize.set_text(_("Queue size: %i") % queuesize) if slotsavail: slots = _("Yes") else: slots = _("No") self.slotsavail.set_text(_("Slots free: %s") % slots) if uploadallowed == 0: allowed = _("No one") elif uploadallowed == 1: allowed = _("Everyone") elif uploadallowed == 2: allowed = _("Users in list") elif uploadallowed == 3: allowed = _("Trusted Users") else: allowed = _("unknown") self.AcceptUploads.set_text(_("%s") % allowed) if has_pic and pic is not None: try: import gc loader = GdkPixbuf.PixbufLoader() loader.write(pic) loader.close() self.image_pixbuf = loader.get_pixbuf() self.image.set_from_pixbuf(self.image_pixbuf) del pic, loader gc.collect() self.actual_zoom = 0 self.SavePicture.set_sensitive(True) except TypeError: name = tempfile.NamedTemporaryFile(delete=False) with open(name, "w") as f: f.write(pic) self.image.set_from_file(name) os.remove(name)
def conn_close(self): append_line(self.ChatScroll, _("--- disconnected ---"), self.tag_hilite) self.usersmodel.clear() self.UserList.set_sensitive(False) self.users.clear() self.count_users() if not self.AutoJoin.get_active( ) and self.room in config.sections["columns"]["chat_room"]: del config.sections["columns"]["chat_room"][self.room] for tag in self.tag_users.values(): update_tag_visuals(tag, "useroffline") self.tickers.set_ticker([])
def show_user(self, msg, *args): if msg is None: return self.conn = None self._descr = msg.descr self.image_pixbuf = None self.descr.get_buffer().set_text("") append_line(self.descr, msg.descr, self.tag_local, showstamp=False, scroll=False) self.uploads.set_text(_("Total uploads allowed: %i") % msg.totalupl) self.queuesize.set_text(_("Queue size: %i") % msg.queuesize) if msg.slotsavail: slots = _("Yes") else: slots = _("No") self.slotsavail.set_text(_("Slots free: %s") % slots) if msg.uploadallowed == 0: allowed = _("No one") elif msg.uploadallowed == 1: allowed = _("Everyone") elif msg.uploadallowed == 2: allowed = _("Users in list") elif msg.uploadallowed == 3: allowed = _("Trusted Users") else: allowed = _("unknown") self.AcceptUploads.set_text(_("%s") % allowed) if msg.has_pic and msg.pic is not None: self.load_picture(msg.pic) self.info_bar.set_visible(False) self.set_finished()
def user_joined_room(self, userdata): username = userdata.username if username in self.users: return # Add to completion list, and completion drop-down self.entry.add_completion(username) if not self.frame.np.network_filter.is_user_ignored( username ) and not self.frame.np.network_filter.is_user_ip_ignored(username): append_line(self.RoomLog, _("%s joined the room") % username, self.tag_log) self.frame.np.pluginhandler.user_join_chatroom_notification( self.room, username) self.add_user_row(userdata) self.get_user_tag(username) self.count_users()
def _append_log_lines(self, path, numlines, encoding='utf-8'): with open(path, 'r', encoding=encoding) as lines: # Only show as many log lines as specified in config lines = deque(lines, numlines) for line in lines: # Try to parse line for username if len(line) > 20 and line[10].isspace() and line[11].isdigit( ) and line[20] in ("[", "*"): if line[20] == "[" and line[20:].find("] ") != -1: namepos = line[20:].find("] ") user = line[21:20 + namepos].strip() self.get_user_tag(user) usertag = self.tag_users[user] else: user = None usertag = None if user == config.sections["server"]["login"]: tag = self.tag_local elif line[20] == "*": tag = self.tag_me elif line[20 + namepos:].upper().find( config.sections["server"]["login"].upper()) > -1: tag = self.tag_hilite else: tag = self.tag_remote else: user = None tag = None usertag = None line = re.sub(r"\\s\\s+", " ", line) if user != config.sections["server"]["login"]: append_line(self.ChatScroll, censor_chat(line), tag, username=user, usertag=usertag, timestamp_format="", scroll=False) else: append_line(self.ChatScroll, line, tag, username=user, usertag=usertag, timestamp_format="", scroll=False) if lines: append_line(self.ChatScroll, _("--- old messages above ---"), self.tag_hilite)
def user_left_room(self, username): if username not in self.users: return # Remove from completion list, and completion drop-down if username not in (i[0] for i in config.sections["server"]["userlist"]): self.entry.remove_completion(username) if not self.frame.np.network_filter.is_user_ignored( username ) and not self.frame.np.network_filter.is_user_ip_ignored(username): append_line(self.RoomLog, _("%s left the room") % username, self.tag_log) self.frame.np.pluginhandler.user_leave_chatroom_notification( self.room, username) self.usersmodel.remove(self.users[username]) del self.users[username] self.get_user_tag(username) self.count_users()
def show_message(self, text, newmessage=True, timestamp=None): self.create_tags() if text[:4] == "/me ": line = "* %s %s" % (self.user, self.frame.censor_chat(text[4:])) speech = line[2:] tag = self.tag_me else: line = "[%s] %s" % (self.user, self.frame.censor_chat(text)) speech = self.frame.censor_chat(text) tag = self.tag_remote timestamp_format = self.frame.np.config.sections["logging"]["private_timestamp"] if not newmessage and not self.offlinemessage: append_line( self.ChatScroll, _("* Message(s) sent while you were offline. Timestamps are reported by the server and can be off."), self.tag_hilite, timestamp_format=timestamp_format ) self.offlinemessage = 1 if newmessage and self.offlinemessage: self.offlinemessage = False if not newmessage: # The timestamps from the server are off by a lot, so we'll only use them when this is an offline message # Also, they are in UTC so we need to correct them if daylight: timestamp -= (3600 * daylight) else: timestamp += altzone append_line(self.ChatScroll, line, self.tag_hilite, timestamp=timestamp, timestamp_format=timestamp_format, username=self.user, usertag=self.tag_username) else: append_line(self.ChatScroll, line, tag, timestamp_format=timestamp_format, username=self.user, usertag=self.tag_username) if self.Log.get_active(): timestamp_format = self.frame.np.config.sections["logging"]["log_timestamp"] write_log(self.frame.np.config.sections["logging"]["privatelogsdir"], self.user, line, timestamp_format) autoreply = self.frame.np.config.sections["server"]["autoreply"] if self.frame.away and not self.autoreplied and autoreply: self.send_message("[Auto-Message] %s" % autoreply) self.autoreplied = 1 self.frame.notifications.new_tts( self.frame.np.config.sections["ui"]["speechprivate"] % { "user": self.frame.notifications.tts_clean(self.user), "message": self.frame.notifications.tts_clean(speech) } )
def say_chat_room(self, msg, text, public=False): user = msg.user if self.frame.np.network_filter.is_user_ignored(user): return if self.frame.np.network_filter.is_user_ip_ignored(user): return text = re.sub("\\s\\s+", " ", text) login = config.sections["server"]["login"] if user == login: tag = self.tag_local elif text.upper().find(login.upper()) > -1: tag = self.tag_hilite else: tag = self.tag_remote self.show_notification(login, user, text, tag) if text[:4] == "/me ": if public: line = "%s | * %s %s" % (msg.room, user, text[4:]) else: line = "* %s %s" % (user, text[4:]) speech = line[2:] tag = self.tag_me else: if public: line = "%s | [%s] %s" % (msg.room, user, text) else: line = "[%s] %s" % (user, text) speech = text line = "\n-- ".join(line.split("\n")) if self.Log.get_active(): timestamp_format = config.sections["logging"]["log_timestamp"] log.write_log(config.sections["logging"]["roomlogsdir"], self.room, line, timestamp_format) self.get_user_tag(user) timestamp_format = config.sections["logging"]["rooms_timestamp"] if user != login: append_line(self.ChatScroll, censor_chat(line), tag, username=user, usertag=self.tag_users[user], timestamp_format=timestamp_format) if self.Speech.get_active(): self.frame.notifications.new_tts( config.sections["ui"]["speechrooms"] % { "room": self.room, "user": self.frame.notifications.tts_clean(user), "message": self.frame.notifications.tts_clean(speech) }) else: append_line(self.ChatScroll, line, tag, username=user, usertag=self.tag_users[user], timestamp_format=timestamp_format)
def login(self): timestamp_format = self.frame.np.config.sections["logging"]["private_timestamp"] append_line(self.ChatScroll, _("--- reconnected ---"), self.tag_hilite, timestamp_format=timestamp_format) self.change_colours()
def conn_close(self): timestamp_format = self.frame.np.config.sections["logging"]["private_timestamp"] append_line(self.ChatScroll, _("--- disconnected ---"), self.tag_hilite, timestamp_format=timestamp_format) self.status = -1 self.offlinemessage = 0 self.change_colours()
def on_enter(self, widget): text = widget.get_text() if not text: widget.set_text("") return if is_alias(text): import _thread _thread.start_new_thread(self.thread_alias, (text, )) widget.set_text("") return s = text.split(" ", 1) cmd = s[0] if len(s) == 2 and s[1]: realargs = args = s[1] else: args = self.user realargs = "" if cmd in ("/alias", "/al"): append_line(self.ChatScroll, add_alias(realargs), None, "") if self.frame.np.config.sections["words"]["aliases"]: self.frame.chatrooms.update_completions() self.frame.privatechats.update_completions() elif cmd in ("/unalias", "/un"): append_line(self.ChatScroll, unalias(realargs), None, "") if self.frame.np.config.sections["words"]["aliases"]: self.frame.chatrooms.update_completions() self.frame.privatechats.update_completions() elif cmd in ["/join", "/j"]: self.frame.np.queue.put(slskmessages.JoinRoom(args)) elif cmd in ["/w", "/whois", "/info"]: if args: self.frame.local_user_info_request(args) self.frame.on_user_info(None) elif cmd in ["/b", "/browse"]: if args: self.frame.browse_user(args) self.frame.on_user_browse(None) elif cmd == "/ip": if args: user = args self.frame.np.ip_requested.add(user) self.frame.np.queue.put(slskmessages.GetPeerAddress(user)) elif cmd == "/pm": if realargs: self.frame.privatechats.send_message(realargs, show_user=True) elif cmd in ["/m", "/msg"]: if realargs: s = realargs.split(" ", 1) user = s[0] if len(s) == 2: msg = s[1] else: msg = None self.frame.privatechats.send_message(user, msg) elif cmd in ["/s", "/search"]: if realargs: self.frame.searches.do_search(realargs, 0) self.frame.on_search(None) elif cmd in ["/us", "/usearch"]: if realargs: self.frame.searches.do_search(realargs, 3, [self.user]) self.frame.on_search(None) elif cmd in ["/rs", "/rsearch"]: if realargs: self.frame.searches.do_search(realargs, 1) self.frame.on_search(None) elif cmd in ["/bs", "/bsearch"]: if realargs: self.frame.searches.do_search(realargs, 2) self.frame.on_search(None) elif cmd in ["/ad", "/add", "/buddy"]: if args: self.frame.userlist.add_to_list(args) elif cmd in ["/rem", "/unbuddy"]: if args: self.frame.userlist.remove_from_list(args) elif cmd == "/ban": if args: self.frame.ban_user(args) elif cmd == "/ignore": if args: self.frame.ignore_user(args) elif cmd == "/ignoreip": if args: self.frame.ignore_ip(args) elif cmd == "/unban": if args: self.frame.unban_user(args) elif cmd == "/unignore": if args: self.frame.unignore_user(args) elif cmd == "/ctcpversion": if args: self.frame.privatechats.send_message(args, CTCP_VERSION, show_user=True, bytestring=True) elif cmd in ["/clear", "/cl"]: self.ChatScroll.get_buffer().set_text("") elif cmd in ["/a", "/away"]: self.frame.on_away(None) elif cmd in ["/q", "/quit", "/exit"]: self.frame.on_quit(None) return elif cmd in ["/c", "/close"]: self.on_close(None) elif cmd == "/now": self.display_now_playing() elif cmd == "/rescan": self.frame.on_rescan() elif cmd[: 1] == "/" and self.frame.np.pluginhandler.trigger_private_command_event( self.user, cmd[1:], args): pass elif cmd and cmd[:1] == "/" and cmd != "/me" and cmd[:2] != "//": log.add(_("Command %s is not recognized"), text) return else: if text[:2] == "//": text = text[1:] if self.chats.connected: self.send_message(text) widget.set_text("") return widget.set_text("")
def show_user(self, msg, folder=None, indeterminate_progress=False): if msg is None: return self.conn = None self._descr = msg.descr self.image_pixbuf = None self.descr.get_buffer().set_text("") append_line(self.descr, msg.descr, self.tag_local, showstamp=False, scroll=False) self.uploads.set_text(_("Total uploads allowed: %i") % msg.totalupl) self.queuesize.set_text(_("Queue size: %i") % msg.queuesize) if msg.slotsavail: slots = _("Yes") else: slots = _("No") self.slotsavail.set_text(_("Slots free: %s") % slots) if msg.uploadallowed == 0: allowed = _("No one") elif msg.uploadallowed == 1: allowed = _("Everyone") elif msg.uploadallowed == 2: allowed = _("Users in list") elif msg.uploadallowed == 3: allowed = _("Trusted Users") else: allowed = _("unknown") self.AcceptUploads.set_text(_("%s") % allowed) if msg.has_pic and msg.pic is not None: try: import gc loader = GdkPixbuf.PixbufLoader() loader.write(msg.pic) loader.close() self.image_pixbuf = loader.get_pixbuf() self.image.set_from_pixbuf(self.image_pixbuf) del msg.pic, loader gc.collect() self.actual_zoom = 0 self.SavePicture.set_sensitive(True) except TypeError: import tempfile name = tempfile.NamedTemporaryFile(delete=False) with open(name, "w") as f: f.write(msg.pic) self.image.set_from_file(name) os.remove(name) self.info_bar.set_visible(False) self.set_finished()
def show(self): tickers = self.room.tickers.get_tickers() append_line(self.RoomWallList, "%s" % ("\n".join(["[%s] %s" % (user, msg) for (user, msg) in tickers])), showstamp=False, scroll=False) self.RoomWallDialog.present_with_time(Gdk.CURRENT_TIME)
def on_enter(self, widget): text = widget.get_text() if not text: widget.set_text("") return if is_alias(text): new_text = expand_alias(text) if not new_text: log.add(_('Alias "%s" returned nothing'), text) return if new_text[:2] == "//": new_text = new_text[1:] self.frame.np.queue.append( self.message_class(self.entity, auto_replace(new_text))) widget.set_text("") return s = text.split(" ", 1) cmd = s[0] # Remove empty items created by split, if command ended with a space, e.g. '/ctcpversion ' if len([i for i in s if i]) == 2: arg_self = args = s[1] else: if not self.is_chatroom: arg_self = self.entity else: arg_self = "" args = "" if cmd[: 1] == "/" and cmd[: 2] != "//" and cmd + " " not in self.command_list: log.add(_("Command %s is not recognized"), text) return if cmd in ("/alias", "/al"): append_line(self.textview, add_alias(args), None, "") if config.sections["words"]["aliases"]: self.frame.update_completions() elif cmd in ("/unalias", "/un"): append_line(self.textview, unalias(args), None, "") if config.sections["words"]["aliases"]: self.frame.update_completions() elif cmd in ("/w", "/whois", "/info"): if arg_self: self.frame.local_user_info_request(arg_self) self.frame.change_main_page("userinfo") elif cmd in ("/b", "/browse"): if arg_self: self.frame.browse_user(arg_self) self.frame.change_main_page("userbrowse") elif cmd == "/ip": if arg_self: self.frame.np.ip_requested.add(arg_self) self.frame.np.queue.append( slskmessages.GetPeerAddress(arg_self)) elif cmd == "/pm": if args: self.frame.privatechats.send_message(args, show_user=True) self.frame.change_main_page("private") elif cmd in ("/m", "/msg"): if args: s = args.split(" ", 1) user = s[0] if len(s) == 2: msg = s[1] else: msg = None self.frame.privatechats.send_message(user, msg, show_user=True) self.frame.change_main_page("private") elif cmd in ("/s", "/search"): if args: self.frame.SearchMethod.set_active(0) self.frame.SearchEntry.set_text(args) self.frame.on_search(self.frame.SearchEntry) self.frame.change_main_page("search") elif cmd in ("/us", "/usearch"): s = args.split(" ", 1) if len(s) == 2: self.frame.SearchMethod.set_active(3) self.frame.SearchEntry.set_text(s[1]) self.frame.UserSearchEntry.set_text(s[0]) self.frame.on_search(self.frame.SearchEntry) self.frame.change_main_page("search") elif cmd in ("/rs", "/rsearch"): if args: self.frame.SearchMethod.set_active(2) self.frame.SearchEntry.set_text(args) self.frame.on_search(self.frame.SearchEntry) self.frame.change_main_page("search") elif cmd in ("/bs", "/bsearch"): if args: self.frame.SearchMethod.set_active(1) self.frame.SearchEntry.set_text(args) self.frame.on_search(self.frame.SearchEntry) self.frame.change_main_page("search") elif cmd in ("/j", "/join"): if args: self.frame.np.queue.append(slskmessages.JoinRoom(args)) elif cmd in ("/l", "/leave", "/p", "/part"): if args: self.frame.np.queue.append(slskmessages.LeaveRoom(args)) else: self.frame.np.queue.append(slskmessages.LeaveRoom(self.entity)) elif cmd in ("/ad", "/add", "/buddy"): if args: self.frame.userlist.add_to_list(args) elif cmd in ("/rem", "/unbuddy"): if args: self.frame.userlist.remove_from_list(args) elif cmd == "/ban": if args: self.frame.np.network_filter.ban_user(args) elif cmd == "/ignore": if args: self.frame.np.network_filter.ignore_user(args) elif cmd == "/ignoreip": if args: self.frame.np.network_filter.ignore_ip(args) elif cmd == "/unban": if args: self.frame.np.network_filter.unban_user(args) elif cmd == "/unignore": if args: self.frame.np.network_filter.unignore_user(args) elif cmd == "/ctcpversion": if arg_self: self.frame.privatechats.send_message( arg_self, self.frame.privatechats.CTCP_VERSION, show_user=True, bytestring=True) elif cmd in ("/clear", "/cl"): self.textview.get_buffer().set_text("") elif cmd in ("/a", "/away"): self.frame.on_away() elif cmd in ("/q", "/quit", "/exit"): self.frame.on_quit() return # Avoid gsignal warning elif cmd in ("/c", "/close"): self.frame.privatechats.users[self.entity].on_close() elif cmd == "/now": self.frame.np.now_playing.display_now_playing( callback=self.send_message) elif cmd == "/rescan": # Rescan public shares if needed if not config.sections["transfers"][ "friendsonly"] and config.sections["transfers"]["shared"]: self.frame.on_rescan() # Rescan buddy shares if needed if config.sections["transfers"]["enablebuddyshares"]: self.frame.on_buddy_rescan() elif cmd in ("/tick", "/t"): self.frame.np.queue.append( slskmessages.RoomTickerSet(self.entity, args)) elif cmd == "/tickers": self.frame.chatrooms.joinedrooms[self.entity].show_tickers() elif cmd == "/toggle": if args: self.frame.np.pluginhandler.toggle_plugin(args) if config.sections["words"]["commands"]: self.frame.update_completions() elif cmd[: 1] == "/" and self.is_chatroom and self.frame.np.pluginhandler.trigger_public_command_event( self.entity, cmd[1:], args): pass elif cmd[: 1] == "/" and not self.is_chatroom and self.frame.np.pluginhandler.trigger_private_command_event( self.entity, cmd[1:], args): pass else: if text[:2] == "//": text = text[1:] self.send_message(text) self.entry.set_text("")