diff --git a/CHANGELOG.mkdn b/CHANGELOG.mkdn index b974184..6ada8ac 100644 --- a/CHANGELOG.mkdn +++ b/CHANGELOG.mkdn @@ -28,7 +28,8 @@ CHANGELOG * Advanced Mode: Alter IRC user mode - Kiooeht [evacipatedBox] * Logviewer chum search - Kiooeht [evacipatedBox] * Logviewer log search - Kiooeht [evacipatedBox] -* Set server and port from command line - Kiooeht [evacipated] +* Set server and port from command line - Kiooeht [evacipatedBox] +* Invite-only memos, invite chums to memos - Kiooeht [evacipatedBox] * Bug fixes * Logviewer updates - Kiooeht [evacipatedBox] * Memo scrollbar thing - Kiooeht [evacipatedBox] diff --git a/irc.py b/irc.py index 2b63a13..5bbd7ed 100644 --- a/irc.py +++ b/irc.py @@ -221,17 +221,27 @@ class PesterIRC(QtCore.QThread): helpers.names(self.cli, c) except socket.error: self.setConnectionBroken() + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString) + def inviteChum(self, handle, channel): + h = unicode(handle) + c = unicode(channel) + try: + helpers.invite(self.cli, h, c) + except socket.error: + self.setConnectionBroken() moodUpdated = QtCore.pyqtSignal(QtCore.QString, Mood) colorUpdated = QtCore.pyqtSignal(QtCore.QString, QtGui.QColor) messageReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) memoReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString) noticeReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) + inviteReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) timeCommand = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString) namesReceived = QtCore.pyqtSignal(QtCore.QString, PesterList) channelListReceived = QtCore.pyqtSignal(PesterList) nickCollision = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) myHandleChanged = QtCore.pyqtSignal(QtCore.QString) + chanInviteOnly = QtCore.pyqtSignal(QtCore.QString) connected = QtCore.pyqtSignal() userPresentUpdate = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString) @@ -387,6 +397,11 @@ class PesterHandler(DefaultCommandHandler): def umodeis(self, server, handle, modes): self.parent.mainwindow.modes = modes + def invite(self, sender, you, channel): + handle = sender.split('!')[0] + self.parent.inviteReceived.emit(handle, channel) + def inviteonlychan(self, server, handle, channel, msg): + self.parent.chanInviteOnly.emit(channel) def getMood(self, *chums): chumglub = "GETMOOD " diff --git a/memos.py b/memos.py index dad7b54..36e3949 100644 --- a/memos.py +++ b/memos.py @@ -373,8 +373,12 @@ class PesterMemo(PesterConvo): self.logchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self) self.connect(self.logchum, QtCore.SIGNAL('triggered()'), self, QtCore.SLOT('openChumLogs()')) + self.invitechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self) + self.connect(self.invitechum, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('inviteChums()')) self.optionsMenu.addAction(self.quirksOff) self.optionsMenu.addAction(self.logchum) + self.optionsMenu.addAction(self.invitechum) self.timeslider = TimeSlider(QtCore.Qt.Horizontal, self) self.timeinput = TimeInput(self.timeslider, self) @@ -656,6 +660,24 @@ class PesterMemo(PesterConvo): for n in self.mainwindow.namesdb[self.channel]: self.addUser(n) + @QtCore.pyqtSlot(QtCore.QString) + def closeInviteOnly(self, channel): + c = unicode(channel) + if c == self.channel: + self.disconnect(self.mainwindow, QtCore.SIGNAL('inviteOnlyChan(QString)'), + self, QtCore.SLOT('closeInviteOnly(QString)')) + if self.parent(): + print self.channel + i = self.parent().tabIndices[self.channel] + self.parent().tabClose(i) + else: + self.close() + msgbox = QtGui.QMessageBox() + msgbox.setText("%s: Invites only!" % (c)) + msgbox.setInformativeText("This channel is invite-only. You must get an invitation from someone on the inside before entering.") + msgbox.setStandardButtons(QtGui.QMessageBox.Ok) + ret = msgbox.exec_() + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString) def userPresentChange(self, handle, channel, update): h = unicode(handle) @@ -916,6 +938,17 @@ class PesterMemo(PesterConvo): self.mainwindow.chumList.pesterlogviewer.raise_() self.mainwindow.chumList.pesterlogviewer.activateWindow() + @QtCore.pyqtSlot() + def inviteChums(self): + if not hasattr(self, 'invitechums'): + self.invitechums = None + if not self.invitechums: + (chum, ok) = QtGui.QInputDialog.getText(self, "Invite to Char", "Enter the chumhandle of the user you'd like to invite:") + if ok: + chum = unicode(chum) + self.mainwindow.inviteChum.emit(chum, self.channel) + self.invitechums = None + @QtCore.pyqtSlot() def sendtime(self): me = self.mainwindow.profile() diff --git a/menus.py b/menus.py index 8015a44..ea9b23e 100644 --- a/menus.py +++ b/menus.py @@ -990,6 +990,7 @@ class PesterMemoList(QtGui.QDialog): self.orjoinlabel = QtGui.QLabel("OR MAKE A NEW MEMO:") self.newmemo = QtGui.QLineEdit(channel, self) self.secretChannel = QtGui.QCheckBox("HIDDEN CHANNEL?", self) + self.inviteChannel = QtGui.QCheckBox("INVITATION ONLY?", self) self.timelabel = QtGui.QLabel("TIMEFRAME:") self.timeslider = TimeSlider(QtCore.Qt.Horizontal, self) @@ -1016,6 +1017,7 @@ class PesterMemoList(QtGui.QDialog): layout_right.addWidget(self.orjoinlabel) layout_right.addWidget(self.newmemo) layout_right.addWidget(self.secretChannel) + layout_right.addWidget(self.inviteChannel) layout_right.addWidget(self.timelabel) layout_right.addWidget(self.timeslider) layout_right.addWidget(self.timeinput) diff --git a/oyoyo/helpers.py b/oyoyo/helpers.py index c58f3a0..7ecab79 100644 --- a/oyoyo/helpers.py +++ b/oyoyo/helpers.py @@ -76,7 +76,7 @@ def quit(cli, msg='gone'): cli._end = 1 def user(cli, username, realname=None): - cli.send("USER", realname or username, cli.host, cli.host, + cli.send("USER", realname or username, cli.host, cli.host, realname or username) _simple = ( @@ -84,6 +84,7 @@ _simple = ( 'part', 'nick', 'notice', + 'invite', ) def _addsimple(): import sys @@ -106,6 +107,6 @@ def _addNumerics(): m = sys.modules[__name__] for num, name in ircevents.numeric_events.iteritems(): setattr(m, name, numericcmd(num, name)) - + _addNumerics() diff --git a/parsetools.py b/parsetools.py index 051adbf..711508b 100644 --- a/parsetools.py +++ b/parsetools.py @@ -492,7 +492,7 @@ def themeChecker(theme): "convo/text/closememo", "convo/text/kickedmemo", \ "main/chums/userlistcolor", "main/defaultwindow/style", \ "main/chums/moods", "main/chums/moods/chummy/icon", "main/menus/help/help", \ - "main/menus/help/calsprite", "main/menus/help/nickserv"] + "main/menus/help/calsprite", "main/menus/help/nickserv", "main/menus/rclickchumlist/invitechum"] for n in needs: try: diff --git a/pesterchum.py b/pesterchum.py index f60db5a..86f4222 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -1404,7 +1404,7 @@ class PesterWindow(MovingWindow): except ThemeException, (inst): print "Caught: "+inst.parameter themeWarning = QtGui.QMessageBox(self) - themeWarning.setText("Theme Error: %s\nFalling back..." % (inst)) + themeWarning.setText("Theme Error: %s" % (inst)) themeWarning.exec_() self.theme = pesterTheme("pesterchum") @@ -1712,7 +1712,7 @@ class PesterWindow(MovingWindow): self.connect(self.tabmemo, QtCore.SIGNAL('windowClosed()'), self, QtCore.SLOT('memoTabsClosed()')) - def newMemo(self, channel, timestr, secret=False): + def newMemo(self, channel, timestr, secret=False, invite=False): if channel == "#pesterchum": return if self.memos.has_key(channel): @@ -1727,6 +1727,8 @@ class PesterWindow(MovingWindow): else: memoWindow = PesterMemo(channel, timestr, self, None) # connect signals + self.connect(self, QtCore.SIGNAL('inviteOnlyChan(QString)'), + memoWindow, QtCore.SLOT('closeInviteOnly(QString)')) self.connect(memoWindow, QtCore.SIGNAL('messageSent(QString, QString)'), self, QtCore.SIGNAL('sendMessage(QString, QString)')) self.connect(memoWindow, QtCore.SIGNAL('windowClosed(QString)'), @@ -1743,6 +1745,8 @@ class PesterWindow(MovingWindow): if self.secret: self.secret = True self.setChannelMode.emit(channel, "+s", "") + if invite: + self.setChannelMode.emit(channel, "+i", "") memoWindow.sendTimeInfo() memoWindow.show() @@ -1887,7 +1891,7 @@ class PesterWindow(MovingWindow): themeChecker(theme) except ThemeException, (inst): themeWarning = QtGui.QMessageBox(self) - themeWarning.setText("Theme Error: %s\nFalling back..." % (inst)) + themeWarning.setText("Theme Error: %s" % (inst)) themeWarning.exec_() theme = pesterTheme("pesterchum") return @@ -2014,6 +2018,19 @@ class PesterWindow(MovingWindow): m = unicode(msg) if self.convos.has_key(h): self.newMessage(h, m) + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString) + def deliverInvite(self, handle, channel): + msgbox = QtGui.QMessageBox() + msgbox.setText("You're invited!") + msgbox.setInformativeText("%s has invited you to the memo: %s\nWould you like to join them?" % (handle, channel)) + msgbox.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) + ret = msgbox.exec_() + if ret == QtGui.QMessageBox.Ok: + self.newMemo(unicode(channel), "+0:00") + @QtCore.pyqtSlot(QtCore.QString) + def chanInviteOnly(self, channel): + print "Invite only: %s" % channel + self.inviteOnlyChan.emit(channel) @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString) def timeCommand(self, chan, handle, command): (c, h, cmd) = (unicode(chan), unicode(handle), unicode(command)) @@ -2226,10 +2243,11 @@ class PesterWindow(MovingWindow): selectedmemo = self.memochooser.selectedmemo() time = unicode(self.memochooser.timeinput.text()) secret = self.memochooser.secretChannel.isChecked() + invite = self.memochooser.inviteChannel.isChecked() if newmemo: channel = "#"+unicode(newmemo).replace(" ", "_") channel = re.sub(r"[^A-Za-z0-9#_]", "", channel) - self.newMemo(channel, time, secret=secret) + self.newMemo(channel, time, secret=secret, invite=invite) elif selectedmemo: channel = "#"+unicode(selectedmemo.target) self.newMemo(channel, time) @@ -2701,6 +2719,8 @@ class PesterWindow(MovingWindow): leftChannel = QtCore.pyqtSignal(QtCore.QString) setChannelMode = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString) channelNames = QtCore.pyqtSignal(QtCore.QString) + inviteChum = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) + inviteOnlyChan = QtCore.pyqtSignal(QtCore.QString) closeSignal = QtCore.pyqtSignal() reconnectIRC = QtCore.pyqtSignal() @@ -2811,6 +2831,8 @@ class MainProgram(QtCore.QObject): 'setChannelMode(QString, QString, QString)'), ('channelNames(QString)', 'channelNames(QString)'), + ('inviteChum(QString, QString)', + 'inviteChum(QString, QString)'), ('reconnectIRC()', 'reconnectIRC()') ] # IRC --> Main window @@ -2825,6 +2847,8 @@ class MainProgram(QtCore.QObject): 'deliverMemo(QString, QString, QString)'), ('noticeReceived(QString, QString)', 'deliverNotice(QString, QString)'), + ('inviteReceived(QString, QString)', + 'deliverInvite(QString, QString)'), ('nickCollision(QString, QString)', 'nickCollision(QString, QString)'), ('myHandleChanged(QString)', @@ -2836,7 +2860,9 @@ class MainProgram(QtCore.QObject): ('channelListReceived(PyQt_PyObject)', 'updateChannelList(PyQt_PyObject)'), ('timeCommand(QString, QString, QString)', - 'timeCommand(QString, QString, QString)') + 'timeCommand(QString, QString, QString)'), + ('chanInviteOnly(QString)', + 'chanInviteOnly(QString)') ] def connectWidgets(self, irc, widget): self.connect(irc, QtCore.SIGNAL('finished()'), diff --git a/themes/enamel/style.js b/themes/enamel/style.js index 8d812b6..4bbb56f 100644 --- a/themes/enamel/style.js +++ b/themes/enamel/style.js @@ -49,7 +49,8 @@ "banuser": "Ban User", "opuser": "Make OP", "voiceuser": "Give Voice", - "quirksoff": "Quirks Off" + "quirksoff": "Quirks Off", + "invitechum": "Invite Chum" } }, "chums": { "style": "text-align: center; border:0px; background-image:url($path/chumbg.png); background-color: #ffe400; background-repeat: no-repeat; color: white; font-family: 'Century Gothic';selection-background-color:#646464; font-size:18px; ", diff --git a/themes/gold/style.js b/themes/gold/style.js index 87104b0..d67fbc1 100644 --- a/themes/gold/style.js +++ b/themes/gold/style.js @@ -52,7 +52,8 @@ "banuser": "Ban User", "opuser": "Make OP", "voiceuser": "Give Voice", - "quirksoff": "Quirks Off" + "quirksoff": "Quirks Off", + "invitechum": "Invite Chum" } }, "chums": { "style": "border:0px; background-image:url($path/chumbg.png); background-color: rgb(110,110,110); background-repeat: no-repeat; color: white; font-family: 'Arial';selection-background-color:#646464; font-size:14px; ", diff --git a/themes/pesterchum/style.js b/themes/pesterchum/style.js index 7bba32e..3f93859 100644 --- a/themes/pesterchum/style.js +++ b/themes/pesterchum/style.js @@ -52,7 +52,8 @@ "banuser": "BAN USER", "opuser": "MAKE OP", "voiceuser": "GIVE VOICE", - "quirksoff": "QUIRKS OFF" + "quirksoff": "QUIRKS OFF", + "invitechum": "INVITE CHUM" } }, "chums": { "style": "border:2px solid yellow; background-color: black;color: white;font: bold;font-family: 'Courier';selection-background-color:#646464; ", diff --git a/themes/trollian/style.js b/themes/trollian/style.js index 9c47752..fc78ef9 100644 --- a/themes/trollian/style.js +++ b/themes/trollian/style.js @@ -51,7 +51,8 @@ "banuser": "Ban", "opuser": "Promote", "voiceuser": "Let Speak", - "quirksoff": "Quirks Off" } + "quirksoff": "Quirks Off", + "invitechum": "Invite Chump" } }, "chums": { "style": "font-size: 12px; background: white; border:0px; font-family: 'Arial';selection-background-color:rgb(200,200,200); ", "scrollbar": { "style" : "background-color:#c2c2c2;", diff --git a/themes/typewriter/style.js b/themes/typewriter/style.js index d84fad0..80c9aa5 100644 --- a/themes/typewriter/style.js +++ b/themes/typewriter/style.js @@ -52,7 +52,8 @@ "banuser": "Expel User", "opuser": "Promote", "voiceuser": "Let Speak", - "quirksoff": "Quirks Off" + "quirksoff": "Quirks Off", + "invitechum": "Invite User" } }, "chums": { "style": "border:0px; background-color: white; font: bold;font-family: 'Courier';selection-background-color: black; ",